diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/CREDITS linux.17p18/CREDITS
--- linux.vanilla/CREDITS	Sun Jun 11 21:44:08 2000
+++ linux.17p18/CREDITS	Fri Aug  4 15:20:29 2000
@@ -371,7 +371,7 @@
 S: USA
 
 N: Juan Jose Ciarlante
-W: http://juanjox.linuxhq.com/
+W: http://juanjox.kernelnotes.org/
 E: jjciarla@raiz.uncu.edu.ar
 E: jjo@mendoza.gov.ar
 D: Network driver alias support
@@ -645,6 +645,10 @@
 S: San Jose, California 95131
 S: USA
 
+N: Kumar Gala
+E: kumar.gala@motorola.com
+D: AltiVec PowerPC support
+
 N: Nigel Gamble
 E: nigel@nrg.org
 E: nigel@sgi.com
@@ -812,6 +816,7 @@
 E: benh@mipsys.com
 D: PowerMac booter (BootX)
 D: Additional PowerBook support
+D: Apple "Core99" machines support (ibook,g4,...)
 S: 22, rue des Marguettes
 S: 75012 Paris
 S: France
@@ -978,9 +983,10 @@
 S: USA
 
 N: Dave Jones
+E: davej@suse.de
 E: dave@powertweak.com
 E: djones2@glam.ac.uk
-W: http://linux.powertweak.com
+W: http://powertweak.sourceforge.net
 D: Userspace PCI bridge tuning (Powertweak).
 D: Centaur/IDT Winchip/Winchip 2 tweaks.
 D: Misc clean ups and other random hacking.
@@ -1339,6 +1345,15 @@
 D: XF86_8514
 D: cfdisk (curses based disk partitioning program)
 
+N: Torben Mathiasen
+E: tmm@image.dk
+E: torben.mathiasen@compaq.com
+D: Maintainer of ThunderLAN driver.
+D: Fixes for TLAN running Full Duplex, and other kernel hacks.
+S: Bremensgade 29, st.th
+S: 2300 Copenhagen S
+S: Denmark
+
 N: Mike McLagan
 E: mike.mclagan@linux.org
 W: http://www.invlogic.com/~mmclagan
@@ -1632,6 +1647,13 @@
 E: ken@halcyon.com
 D: CDROM driver "sonycd535" (Sony CDU-535/531)
 
+N: Matt Porter
+E: mporter@phx.mcd.mot.com
+D: Motorola PowerPC PReP support
+S: 2900 S. Diable Way
+S: Tempe, Arizona 85282
+S: USA
+
 N: Frederic Potter 
 E: Frederic.Potter@masi.ibp.fr 
 D: Some PCI kernel support
@@ -2103,7 +2125,7 @@
 
 N: Geert Uytterhoeven
 E: geert@linux-m68k.org
-W: http://www.cs.kuleuven.ac.be/~geert/
+W: http://home.tvd.be/cr26864/
 P: 1024/EC4A1EE1 8B 88 38 35 88 1E 95 A1  CD 9E AE DC 4B 4A 2F 41
 D: m68k/Amiga and PPC/CHRP Longtrail coordinator
 D: Frame buffer device and XF68_FBDev maintainer
@@ -2157,10 +2179,10 @@
 N: Tim Waugh
 E: tim@cyberelk.demon.co.uk
 D: Co-architect of the parallel-port sharing system
-S: 34 Bladon Close
+S: 17 Curling Vale
 S: GUILDFORD
 S: Surrey
-S: GU1 1TY
+S: GU2 7PJ
 S: United Kingdom
 
 N: Juergen Weigert
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/Changes linux.17p18/Documentation/Changes
--- linux.vanilla/Documentation/Changes	Sun Jun 11 21:44:08 2000
+++ linux.17p18/Documentation/Changes	Tue Aug  1 07:59:02 2000
@@ -268,7 +268,7 @@
 ipfwadm.
 
    To use masq forwarding you will need to obtain "ipmasqadm,"
-available from http://juanjox.linuxhq.com/ .
+available from http://juanjox.kernelnotes.org/ .
 
    DHCP clients for 2.0 do not work with the new networking code in the
 2.2 kernel.  You will need to upgrade your dhcpcd / dhcpclient.
@@ -523,14 +523,14 @@
 ========
 
 The 2.9.1.0.25 release:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
+ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/binutils-2.9.1.0.25.tar.gz
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
+ftp://ftp.valinux.com/pub/support/hjl/binutils/2.9.1/release.binutils-2.9.1.0.25
 
 The 2.9.5.0.16 release:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/binutils/binutils-2.9.5.0.16.tar.bz2
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
+ftp://ftp.valinux.com/pub/support/hjl/binutils/release.binutils-2.9.5.0.16
 
 Bin86
 =====
@@ -543,11 +543,11 @@
 =====
 
 The egcs-1.1.2 release:
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-alpha.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-glibc.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-libc5.x86.tar.bz2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/egcs-1.1.2-alpha.x86.tar.bz2
 Installation notes:
-ftp://ftp.varesearch.com/pub/support/hjl/gcc/egcs-1.1.2/release.egcs-1.1.2
+ftp://ftp.valinux.com/pub/support/hjl/gcc/egcs-1.1.2/release.egcs-1.1.2
 
 Gnu C 2.7.2.3 source:
 ftp://ftp.gnu.org/gnu/gcc/gcc-2.7.2.3.tar.gz
@@ -726,7 +726,7 @@
 ===========
 
 The 0.4.2 release:
-http://juanjox.linuxhq.com/ipmasqadm-0.4.2.tar.gz
+http://juanjox.kernelnotes.org/ipmasqadm-0.4.2.tar.gz
 
 DHCP clients
 ============
@@ -753,7 +753,7 @@
 =====
 
 The 2.1 release:
-http://www.cs.kuleuven.ac.be/~geert/bin/fbset-2.1.tar.gz
+http://home.tvd.be/cr26864/Linux/fbdev/
 
 PCI utils
 =========
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/Configure.help linux.17p18/Documentation/Configure.help
--- linux.vanilla/Documentation/Configure.help	Sun Jun 11 21:44:08 2000
+++ linux.17p18/Documentation/Configure.help	Mon Aug 14 20:12:31 2000
@@ -5,8 +5,8 @@
 #
 # Translations of this file available on the WWW:
 #
-#   - Japanese, by Tetsuyasu YAMADA (tetsu@cauchy.nslab.ntt.co.jp), at
-#     http://jf.gee.kyoto-u.ac.jp/JF/JF-ftp/euc/Configure.help.euc
+#   - Japanese, maintained by the JF Project (JF@linux.or.jp), at
+#     http://www.linux.or.jp/JF/JFdocs/Configure.help/
 #   - Russian, by kaf@linux.nevod.perm.su, at
 #     http://nevod.perm.su/service/linux/doc/kernel/Configure.help
 #   - French, by Pierre Tane (tanep@bigfoot.com), at
@@ -5755,6 +5755,34 @@
 
   If unsure, say N here.
 
+Cyclades-PC300 support
+CONFIG_PC300
+  This is a driver for the Cyclades-PC300 synchronous communication
+  boards. These boards provide synchronous serial interfaces to your
+  Linux box. All protocols supported by the HDLC generic driver
+  (currently synchronous PPP, Cisco HDLC and Frame Relay) are available
+  by default. If you wish to support other protocols, please select one
+  of the available options below this one.
+
+  If you want to compile this as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read Documentation/modules.txt. The module will be
+  called pc300.o.
+
+  If unsure, say N here.
+
+Cyclades-PC300 X.25 Support
+CONFIG_PC300_X25
+  Say Y to this option if you intend to use the Cyclades-PC300 to
+  provide X.25 interfaces to your Linux box.
+
+  IMPORTANT: Additional X.25 support must be enabled in the kernel
+  for this support to be functional (say Y to "CCITT X.25 Packet Layer"
+  and "LAPB Data Link Driver", in the "Networking Options"
+  configuration section).
+
+  If unsure, say N here.
+
 Ethernet (10 or 100Mbit)
 CONFIG_NET_ETHERNET
   Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
@@ -7560,13 +7588,17 @@
   The module will be called ntfs.o. If you want to compile it as a
   module, say M here and read Documentation/modules.txt.
 
-NTFS read-write support (experimental)
+NTFS read-write support (DANGEROUS)
 CONFIG_NTFS_RW
-  If you say Y here, you will (hopefully) be able to write to NTFS
-  file systems as well as read from them. The read-write support
-  in NTFS is far from being complete and is not well tested. If you
+  If you say Y here, you will (maybe) be able to write to NTFS file
+  systems as well as read from them. The read-write support in
+  NTFS is far from being complete and is not well tested. If you
   enable this, back up your NTFS volume first since it may get
-  damaged.
+  damaged. Also, make sure to run chkdsk from within Microsoft
+  Windows NT after having performed any writes to a NTFS partition
+  from Linux to detect any problems as early as possible.
+  Please note that write support is limited to Windows NT4 and
+  earlier versions.
 
   If unsure, say N.
 
@@ -9751,6 +9783,12 @@
 
   Say Y unless you have 16MB or less RAM or a PCI sound card.
 
+Crystal SoundFusion (CS461x)
+CONFIG_SOUND_FUSION
+  This module drives the Crystal SoundFusion devices (CS46xx series) when
+  wired as native sound drivers with AC97 codecs. If this driver does not
+  work try the CS4232 driver.
+
 Support for Aztech Sound Galaxy (non-PnP) cards
 CONFIG_SOUND_SGALAXY
   This module initializes the older non Plug and Play sound galaxy
@@ -10234,6 +10272,11 @@
   be able to use its on-board audio.  Read Documentation/sound/visws
   for more info on this driver's capabilities.
 
+Creative EMU10K1 based PCI sound cards
+CONFIG_SOUND_EMU10K1
+  Say Y or M if you have a PCI sound card using the EMU10K1
+  chipset, such as the Creative SBLive! or SB PCI512.
+
 Ensoniq ES1370 based PCI sound cards
 CONFIG_SOUND_ES1370
   Say Y or M if you have a PCI sound card utilizing the Ensoniq
@@ -11404,16 +11447,35 @@
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt.
 
-BMAC (G3 ethernet) support
+Use AAUI port instead of TP by default
+CONFIG_MACE_AAUI_PORT
+  Some Apple machines (notably the Apple Network Server) which use the
+  MACE ethernet chip have an Apple AUI port (small 15-pin connector),
+  instead of an 8-pin RJ45 connector for twisted-pair ethernet.  Say
+  Y here if you have such a machine.  If unsure, say N.
+
+BMAC (G3/G4 ethernet) support
 CONFIG_BMAC
-  Say Y for support of BMAC Ethernet interfaces. These are used on G3
-  computers. 
+  Say Y for support of BMAC and BMAC+ Ethernet interfaces. These
+  are used on G3 and G4 computers (Apple Power Macintoshes and
+  PowerBooks).
 
   This driver is also available as a module called bmac.o ( = code
   which can be inserted in and removed from the running kernel
   whenever you want). If you want to compile it as a module, say M
   here and read Documentation/modules.txt.
 
+GMAC (Core99 ethernet) support
+CONFIG_GMAC
+  Say Y for support of the GMAC Ethernet interfaces. This interface
+  is used on some Apple G4 PowerMacs (recent ones), new iMacs, iBooks
+  and PowerBook 2000 (aka "Pismo").
+
+  This driver is also available as a module called gmac.o ( = code
+  which can be inserted in and removed from the running kernel
+  whenever you want). If you want to compile it as a module, say M
+  here and read Documentation/modules.txt.
+
 Video For Linux
 CONFIG_VIDEO_DEV
   Support for audio/video capture and overlay devices and FM radio
@@ -12287,6 +12349,17 @@
 
   If you do not have any Quicknet telephony cards, you can safely
   ignore this option.
+
+Toshiba Laptop support
+CONFIG_TOSHIBA	
+  If you intend to run this the kernel on a Toshiba portable say yes
+  here. This adds a driver to safely access the System Management
+  Mode of the CPU on Toshiba portables. The System Management Mode
+  is used to set the BIOS and power saving options on Toshiba portables.
+
+  For information on utilities to make use of this driver see the
+  Toshiba Linux utilities website at:
+  http://www.buzzard.org.uk/toshiba/
  
 CPiA Video For Linux
 CONFIG_VIDEO_CPIA
@@ -12314,6 +12387,20 @@
 CONFIG_VIDEO_CPIA_PP_DMA
   This will use DMA if possible to reduce CPU usage.  If in doubt,
   say Y here.
+
+7-Segment Display support
+CONFIG_DISPLAY7SEG
+  This is the driver for the digital display and LED present on
+  Sun Microsystems CompactPCI models CP1400 and CP1500.
+
+  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 display7seg.o. If you want to compile it 
+  as a module, say M here and read Documentation/modules.txt.
+
+  If you do not have a CompactPCI model CP1400 or CP1500, or 
+  another UltraSPARC-IIi-cEngine boardset with digital display,
+  you should say N to this option.
    
 #
 # A couple of things I keep forgetting:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/Debugging390.txt linux.17p18/Documentation/Debugging390.txt
--- linux.vanilla/Documentation/Debugging390.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/Debugging390.txt	Tue Aug  1 07:59:03 2000
@@ -520,9 +520,46 @@
 }
 
 
+New compiler changes
+====================
+
+main(int argc,char *argv[])
+{
+  4004fc:	90 7f f0 1c       	stm	%r7,%r15,28(%r15)
+  400500:	a7 d5 00 04       	bras	%r13,400508 <main+0xc>
+  400504:	00 40 04 f4       	.long	0x004004f4 
+  # compiler now puts constant pool in code to so it saves an instruction 
+  400508:	18 0f             	lr	%r0,%r15
+  40050a:	a7 fa ff a0       	ahi	%r15,-96
+  40050e:	50 00 f0 00       	st	%r0,0(%r15)
+	return(test(5));
+  400512:	58 10 d0 00       	l	%r1,0(%r13)
+  400516:	a7 28 00 05       	lhi	%r2,5
+  40051a:	0d e1             	basr	%r14,%r1
+  # compiler adds 1 extra instruction to epilogue this is done to
+  # avoid processor pipeline stalls owing to data dependencies on g5 &
+  # above as register 14 in the old code was needed directly after being loaded 
+  # by the lm	%r11,%r15,140(%r15) for the br %14.
+  40051c:	58 40 f0 98       	l	%r4,152(%r15)
+  400520:	98 7f f0 7c       	lm	%r7,%r15,124(%r15)
+  400524:	07 f4             	br	%r4
+}
+
+Hartmut ( our compiler developer ) also has been threatening to take out the
+stack backchain in optimised code as this also causes pipeline stalls, you
+have been warned.
+
+
+
 Compiling programs for debugging on Linux for S390
 ==================================================
-Make sure that the gcc is compiling & linking with the -g flag on.
+Make sure that the gcc is compiling & linking with the -g flag on
+this generates plain old gnu stabs, don't use
+-ggdb, -gxcoff+ or any other silly option these other options more than
+likely don't work ( we haven't tested them ), -gstabs is supposed to add
+extra extensions to the debugging info for debugging c++ we haven't got
+round to testing this yet.
+
 This is typically done adding/appending the flags -g to the 
 CFLAGS & LDFLAGS variables Makefile of the program concerned.
 
@@ -695,6 +732,39 @@
 6) If debugging under VM go down to that section in the document for more info.
 
 
+I now have a tool which takes the pain out of --adjust-vma
+& you are able to do something like
+make /arch/s390/kernel/traps.lst
+& it automatically generates the correctly relocated entries for
+the text segment in traps.lst.
+
+Add the following lines to you Rules.make
+%.lst: %.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+	$(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
+
+Copy the code snippet below into the scripts directory in a file called makelst
+it is'nt very pretty but it works & dont forget to chmod 755 makelst
+to make it an executable.
+#	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+#	$(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
+#
+#    Copyright (C) 2000 IBM Corporation
+#    Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 
+#
+
+t1=`$3 --syms $2/$1.o | grep .text | grep " F " | head -n 1`
+t2=`echo $t1 | gawk '{ print $6 }'`
+t3=`grep $t2 $2/System.map`
+t4=`echo $t3 | gawk '{ print $1 }'`
+t5=`echo $t1 | gawk '{ print $1 }'`
+t6=`echo $t4 - $t5 | sed s/a/A/ | sed s/b/B/ | sed s/c/C/ | sed s/d/D/ | sed s/e/E/ | sed s/f/F/`
+t7=`( echo  ibase=16 ; echo $t6 ) | bc`
+$3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst
+
+
+
+
 strace:
 -------
 Q. What is it ?
@@ -941,6 +1011,9 @@
 e.g.
 TR BR INTO 0 is often quite useful if a program is getting awkward & deciding
 to branch to 0 & crashing as this will stop at the address before in jumps to 0.
+TR I R <address range> RUN cmd d g
+single steps a range of addresses but stays running &
+displays the gprs on each step.
 
 
 
@@ -992,6 +1065,9 @@
 because there are thousands of these routines & VM can only set 255 breakpoints
 at a time so you nearly had to spend as long pruning the file down as you would 
 entering the msg's by hand ),however, the trick might be useful for a single object file.
+On linux'es 3270 emulator x3270 there is a very useful option under the file ment
+Save Screens In File this is very good of keeping a copy of traces. 
+
 
 
 Tracing Program Exceptions
@@ -1436,9 +1512,9 @@
 VM guest so he can ftp the logfile back to his own machine.I'll do a small bit of this & give you
  a look at the output.
 
-1) Spool stdout to VM guest linux4's reader
-SP PRT TO * 
-2) Fill linux4's reader with the trace
+1) Spool stdout to VM reader
+SP PRT TO (another vm guest ) or * for the local vm guest
+2) Fill the reader with the trace
 TR IO 7c08-7c09 INST INT CCW PRT RUN
 3) Start up linux 
 i 00c  
@@ -1775,7 +1851,9 @@
 
 LDD
 ===
-This is a program which lists the shared libraries which a library needs.
+This is a program which lists the shared libraries which a library needs,
+Note you also get the relocations of the shared library text segments which
+help when using objdump --source.
 e.g.
  ldd ./gdb
 outputs
@@ -1783,6 +1861,21 @@
 libm.so.6 => /lib/libm.so.6 (0x4005e000)
 libc.so.6 => /lib/libc.so.6 (0x40084000)
 /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
+
+
+Debugging shared libraries
+==========================
+Most programs use shared libraries, however it can be very painful
+when you single step instruction into a function like printf for the 
+first time & you end up in functions like _dl_runtime_resolve this is
+the ld.so doing lazy binding, lazy binding is a concept in ELF where 
+shared library functions are not loaded into memory unless they are 
+actually used, great for saving memory but a pain to debug.
+To get around this either relink the program -static or exit gdb type 
+export LD_BIND_NOW=true this will stop lazy binding & restart the gdb'ing 
+the program in question.
+ 
+
 
 Debugging modules
 =================
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/README.DAC960 linux.17p18/Documentation/README.DAC960
--- linux.vanilla/Documentation/README.DAC960	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/README.DAC960	Tue Aug  1 19:11:11 2000
@@ -1,11 +1,11 @@
-	   Mylex DAC960/DAC1100 PCI RAID Controller Driver for Linux
+   Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-			Version 2.2.5 for Linux 2.2.14
-			Version 2.0.5 for Linux 2.0.38
+			Version 2.2.7 for Linux 2.2.16
+			Version 2.4.7 for Linux 2.4.0
 
 			      PRODUCTION RELEASE
 
-				23 January 2000
+				 1 August 2000
 
 			       Leonard N. Zubkoff
 			       Dandelion Digital
@@ -18,30 +18,35 @@
 
 Mylex, Inc. designs and manufactures a variety of high performance PCI RAID
 controllers.  Mylex Corporation is located at 34551 Ardenwood Blvd., Fremont,
-California 94555, USA and can be reached at 510/796-6100 or on the World Wide
-Web at http://www.mylex.com.  Mylex RAID Technical Support can be reached by
-electronic mail at support@mylex.com (for eXtremeRAID 1100 and older DAC960
-models) or techsup@mylex.com (for AcceleRAID models), by voice at 510/608-2400,
-or by FAX at 510/745-7715.  Contact information for offices in Europe and Japan
-is available on the Web site.
+California 94555, USA and can be reached at 510.796.6100 or on the World Wide
+Web at http://www.mylex.com.  Mylex Technical Support can be reached by
+electronic mail at support@mylex.com, by voice at 510.608.2400, or by FAX at
+510.745.7715.  Contact information for offices in Europe and Japan is available
+on their Web site.
 
 The latest information on Linux support for DAC960 PCI RAID Controllers, as
 well as the most recent release of this driver, will always be available from
 my Linux Home Page at URL "http://www.dandelion.com/Linux/".  The Linux DAC960
-driver supports all current DAC960 PCI family controllers including the
-AcceleRAID models, as well as the eXtremeRAID 1100; see below for a complete
-list.  For simplicity, in most places this documentation refers to DAC960
-generically rather than explicitly listing all the models.
-
-Bug reports should be sent via electronic mail to "lnz@dandelion.com".  Please
-include with the bug report the complete configuration messages reported by the
-driver at startup, along with any subsequent system messages relevant to the
-controller's operation, and a detailed description of your system's hardware
-configuration.
-
-Please consult the DAC960 RAID controller documentation for detailed
-information regarding installation and configuration of the controllers.  This
-document primarily provides information specific to the Linux DAC960 support.
+driver supports all current Mylex PCI RAID controllers including the new
+eXtremeRAID 2000/3000 and AcceleRAID 352/170 models which have an entirely new
+firmware interface from the older eXtremeRAID 1100, AcceleRAID 150/200/250, and
+DAC960PJ/PG/PU/PD/PL.  See below for a complete controller list as well as
+minimum firmware version requirements.  For simplicity, in most places this
+documentation refers to DAC960 generically rather than explicitly listing all
+the supported models.
+
+Driver bug reports should be sent via electronic mail to "lnz@dandelion.com".
+Please include with the bug report the complete configuration messages reported
+by the driver at startup, along with any subsequent system messages relevant to
+the controller's operation, and a detailed description of your system's
+hardware configuration.  Driver bugs are actually quite rare; if you encounter
+problems with disks being marked offline, for example, please contact Mylex
+Technical Support as the problem is related to the hardware configuration
+rather than the Linux driver.
+
+Please consult the RAID controller documentation for detailed information
+regarding installation and configuration of the controllers.  This document
+primarily provides information specific to the Linux support.
 
 
 				DRIVER FEATURES
@@ -60,16 +65,18 @@
 from Linux while the system is operational.
 
 The DAC960 driver is architected to support up to 8 controllers per system.
-Each DAC960 controller can support up to 15 disk drives per channel, for a
-maximum of 45 drives on a three channel controller.  The drives installed on a
-controller are divided into one or more "Drive Groups", and then each Drive
-Group is subdivided further into 1 to 32 "Logical Drives".  Each Logical Drive
-has a specific RAID Level and caching policy associated with it, and it appears
-to Linux as a single block device.  Logical Drives are further subdivided into
-up to 7 partitions through the normal Linux and PC disk partitioning schemes.
-Logical Drives are also known as "System Drives", and Drive Groups are also
-called "Packs".  Both terms are in use in the Mylex documentation; I have
-chosen to standardize on the more generic "Logical Drive" and "Drive Group".
+Each DAC960 parallel SCSI controller can support up to 15 disk drives per
+channel, for a maximum of 60 drives on a four channel controller; the fibre
+channel eXtremeRAID 3000 controller supports up to 125 disk drives per loop for
+a total of 250 drives.  The drives installed on a controller are divided into
+one or more "Drive Groups", and then each Drive Group is subdivided further
+into 1 to 32 "Logical Drives".  Each Logical Drive has a specific RAID Level
+and caching policy associated with it, and it appears to Linux as a single
+block device.  Logical Drives are further subdivided into up to 7 partitions
+through the normal Linux and PC disk partitioning schemes.  Logical Drives are
+also known as "System Drives", and Drive Groups are also called "Packs".  Both
+terms are in use in the Mylex documentation; I have chosen to standardize on
+the more generic "Logical Drive" and "Drive Group".
 
 DAC960 RAID disk devices are named in the style of the Device File System
 (DEVFS).  The device corresponding to Logical Drive D on Controller C is
@@ -82,19 +89,41 @@
 Drive and 3 bits for the partition.
 
 
-		 SUPPORTED DAC960/DAC1100 PCI RAID CONTROLLERS
+	  SUPPORTED DAC960/AcceleRAID/eXtremeRAID PCI RAID CONTROLLERS
 
-The following list comprises the supported DAC960 and DAC1100 PCI RAID
-Controllers as of the date of this document.  It is recommended that anyone
-purchasing a Mylex PCI RAID Controller not in the following table contact the
-author beforehand to verify that it is or will be supported.  The eXtremeRAID
-2000, eXtremeRAID 3000, and AcceleRAID 352 have an entirely new firmware
-interface and are not yet supported by this driver.
+The following list comprises the supported DAC960, AcceleRAID, and eXtremeRAID
+PCI RAID Controllers as of the date of this document.  It is recommended that
+anyone purchasing a Mylex PCI RAID Controller not in the following table
+contact the author beforehand to verify that it is or will be supported.
+
+eXtremeRAID 3000
+	    1 Wide Ultra-2/LVD SCSI channel
+	    2 External Fibre FC-AL channels
+	    233MHz StrongARM SA 110 Processor
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
+	    32MB/64MB ECC SDRAM Memory
+
+eXtremeRAID 2000
+	    4 Wide Ultra-160 LVD SCSI channels
+	    233MHz StrongARM SA 110 Processor
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
+	    32MB/64MB ECC SDRAM Memory
+
+AcceleRAID 352
+	    2 Wide Ultra-160 LVD SCSI channels
+	    100MHz Intel i960RN RISC Processor
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
+	    32MB/64MB ECC SDRAM Memory
+
+AcceleRAID 170
+	    1 Wide Ultra-160 LVD SCSI channel
+	    100MHz Intel i960RM RISC Processor
+	    16MB/32MB/64MB ECC SDRAM Memory
 
 eXtremeRAID 1100 (DAC1164P)
 	    3 Wide Ultra-2/LVD SCSI channels
 	    233MHz StrongARM SA 110 Processor
-	    64 Bit PCI (backward compatible with 32 Bit PCI slots)
+	    64 Bit 33MHz PCI (backward compatible with 32 Bit PCI slots)
 	    16MB/32MB/64MB Parity SDRAM Memory with Battery Backup
 
 AcceleRAID 250 (DAC960PTL1)
@@ -135,6 +164,9 @@
 	    Intel i960 RISC Processor
 	    2MB/4MB/8MB/16MB/32MB DRAM Memory
 
+For the eXtremeRAID 2000/3000 and AcceleRAID 352/170, firmware version 6.00-01
+or above is required.
+
 For the eXtremeRAID 1100, firmware version 5.06-0-52 or above is required.
 
 For the AcceleRAID 250, 200, and 150, firmware version 4.06-0-57 or above is
@@ -165,16 +197,16 @@
 
 			      DRIVER INSTALLATION
 
-This distribution was prepared for Linux kernel version 2.2.14 or 2.0.38.
+This distribution was prepared for Linux kernel version 2.2.16 or 2.4.0.
 
 To install the DAC960 RAID driver, you may use the following commands,
 replacing "/usr/src" with wherever you keep your Linux kernel source tree:
 
   cd /usr/src
-  tar -xvzf DAC960-2.2.5.tar.gz (or DAC960-2.0.5.tar.gz)
+  tar -xvzf DAC960-2.2.7.tar.gz (or DAC960-2.4.7.tar.gz)
   mv README.DAC960 linux/Documentation
   mv DAC960.[ch] linux/drivers/block
-  patch -p0 < DAC960.patch (driver 2.0.5 only)
+  patch -p0 < DAC960.patch
   cd linux
   make config
   make depend
@@ -203,13 +235,13 @@
 drives using the BIOS Configuration Utility or DACCF.  Please note that since
 there are only at most 6 usable partitions on each logical drive, systems
 requiring more partitions should subdivide a drive group into multiple logical
-drives, each of which can have up to 6 partitions.  Also, note that with large
-disk arrays it is advisable to enable the 8GB BIOS Geometry (255/63) rather
-than accepting the default 2GB BIOS Geometry (128/32); failing to so do will
-cause the logical drive geometry to have more than 65535 cylinders which will
-make it impossible for FDISK to be used properly.  The 8GB BIOS Geometry can be
-enabled by configuring the DAC960 BIOS, which is accessible via Alt-M during
-the BIOS initialization sequence.
+drives, each of which can have up to 6 usable partitions.  Also, note that with
+large disk arrays it is advisable to enable the 8GB BIOS Geometry (255/63)
+rather than accepting the default 2GB BIOS Geometry (128/32); failing to so do
+will cause the logical drive geometry to have more than 65535 cylinders which
+will make it impossible for FDISK to be used properly.  The 8GB BIOS Geometry
+can be enabled by configuring the DAC960 BIOS, which is accessible via Alt-M
+during the BIOS initialization sequence.
 
 For maximum performance and the most efficient E2FSCK performance, it is
 recommended that EXT2 file systems be built with a 4KB block size and 16 block
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/cpqarray.txt linux.17p18/Documentation/cpqarray.txt
--- linux.vanilla/Documentation/cpqarray.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/cpqarray.txt	Tue Aug  1 07:59:03 2000
@@ -17,6 +17,7 @@
 	* SA 4200
 	* SA 4250ES
 	* SA 431
+	* RAID LC2 Controller
 
 It should also work with some really old Disk array adapters, but I am
 unable to test against these cards:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/fb/00-INDEX linux.17p18/Documentation/fb/00-INDEX
--- linux.vanilla/Documentation/fb/00-INDEX	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/fb/00-INDEX	Tue Aug  1 07:59:02 2000
@@ -1,8 +1,7 @@
 Index of files in Documentation/fb.  If you think something about frame
 buffer devices needs an entry here, needs correction or you've written one
 please mail me.
-				    Geert Uytterhoeven
-				    <Geert.Uytterhoeven@cs.kuleuven.ac.be>
+				Geert Uytterhoeven <geert@linux-m68k.org>
 
 00-INDEX
 	- this file
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/fb/framebuffer.txt linux.17p18/Documentation/fb/framebuffer.txt
--- linux.vanilla/Documentation/fb/framebuffer.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/fb/framebuffer.txt	Tue Aug  1 07:59:02 2000
@@ -1,7 +1,7 @@
 			The Frame Buffer Device
 			-----------------------
 
-Maintained by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+Maintained by Geert Uytterhoeven <geert@linux-m68k.org>
 Last revised: November 7, 1998
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/fb/internals.txt linux.17p18/Documentation/fb/internals.txt
--- linux.vanilla/Documentation/fb/internals.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/fb/internals.txt	Tue Aug  1 07:59:02 2000
@@ -2,7 +2,7 @@
 This is a first start for some documentation about frame buffer device
 internals.
 
-Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>, 21 July 1998
+Geert Uytterhoeven <geert@linux-m68k.org>, 21 July 1998
 
 --------------------------------------------------------------------------------
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/filesystems/ntfs.txt linux.17p18/Documentation/filesystems/ntfs.txt
--- linux.vanilla/Documentation/filesystems/ntfs.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/filesystems/ntfs.txt	Tue Aug  1 07:59:02 2000
@@ -4,10 +4,16 @@
 To mount an NTFS volume, use the filesystem type 'ntfs'. The driver
 currently works only in read-only mode, with no fault-tolerance
 supported.  If you enable the experimental write support, make sure
-you can recover from a complete loss of data. For ftdisk support,
-limited success was reported with volume sets on top of the md driver,
-although mirror and stripe sets should work as well - if the md
-driver can be talked into using the same layout as Windows NT.
+you can recover from a complete loss of data and also always run
+chkdsk from within Microsoft Windows NT after performing a write to
+a NTFS partition from Linux to detect any problems as early as 
+possible. For ftdisk support, limited success was reported with 
+volume sets on top of the md driver, although mirror and stripe 
+sets should work as well - if the md driver can be talked into 
+using the same layout as Windows NT.
+
+Please note that the experimental write support is limited to
+Windows NT4 and earlier versions.
 
 The ntfs driver supports the following mount options:
 iocharset=name      Character set to use when returning file names.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/i386/boot.txt linux.17p18/Documentation/i386/boot.txt
--- linux.vanilla/Documentation/i386/boot.txt	Thu Jan  1 01:00:00 1970
+++ linux.17p18/Documentation/i386/boot.txt	Tue Aug  1 07:59:02 2000
@@ -0,0 +1,394 @@
+		     THE LINUX/I386 BOOT PROTOCOL
+		     ----------------------------
+
+		    H. Peter Anvin <hpa@zytor.com>
+		 Updated as of protocol version 2.02
+
+On the i386 platform, the Linux kernel uses a rather complicated boot
+convention.  This has evolved partially due to historical aspects, as
+well as the desire in the early days to have the kernel itself be a
+bootable image, the complicated PC memory model and due to changed
+expectations in the PC industry caused by the effective demise of
+real-mode DOS as a mainstream operating system.
+
+Currently, four versions of the Linux/i386 boot protocol exist.
+
+Old kernels:	zImage/Image support only.  Some very early kernels
+		may not even support a command line.
+
+Protocol 2.00:	(Kernel 1.3.73) Added bzImage and initrd support, as
+		well as a formalized way to communicate between the
+		boot loader and the kernel.  setup.S made relocatable,
+		although the traditional setup area still assumed
+		writable.
+
+Protocol 2.01:	(Kernel 1.3.76) Added a heap overrun warning.
+
+Protocol 2.02:	(Kernel 2.4.0-test3-pre3) New command line protocol.
+		Lower the conventional memory ceiling.  No overwrite
+		of the traditional setup area, thus making booting
+		safe for systems which use the EBDA from SMM or 32-bit
+		BIOS entry points.  zImage deprecated but still
+		supported.
+
+
+**** MEMORY LAYOUT
+
+The traditional memory map for the kernel loader, used for Image or
+zImage kernels, typically looks like:
+
+	|			 |
+0A0000	+------------------------+
+	|  Reserved for BIOS	 |	Do not use.  Reserved for BIOS EBDA.
+09A000	+------------------------+
+	|  Stack/heap/cmdline	 |	For use by the kernel real-mode code.
+098000	+------------------------+	
+	|  Kernel setup		 |	The kernel real-mode code.
+090200	+------------------------+
+	|  Kernel boot sector    |	The kernel legacy boot sector.
+090000	+------------------------+
+	|  Protected-mode kernel |	The bulk of the kernel image.
+010000	+------------------------+
+	|  Boot loader		 |	<- Boot sector entry point 0000:7C00
+001000	+------------------------+
+	|  Reserved for MBR/BIOS |
+000800	+------------------------+
+	|  Typically used by MBR |
+000600	+------------------------+ 
+	|  BIOS use only	 |
+000000	+------------------------+
+
+
+When using bzImage, the protected-mode kernel was relocated to
+0x100000 ("high memory"), and the kernel real-mode block (boot sector,
+setup, and stack/heap) was made relocatable to any address between
+0x10000 and end of low memory.  Unfortunately, in protocols 2.00 and
+2.01 the command line is still required to live in the 0x9XXXX memory
+range, and that memory range is still overwritten by the early kernel.
+The 2.02 protocol fixes that.
+
+It is desirable to keep the "memory ceiling" -- the highest point in
+low memory touched by the boot loader -- as low as possible, since
+some newer BIOSes have begun to allocate some rather large amounts of
+memory, called the Extended BIOS Data Area, near the top of low
+memory.  The boot loader should use the "INT 12h" BIOS call to verify
+how much low memory is available.
+
+Unfortunately, if INT 12h reports that the amount of memory is too
+low, there is usually nothing the boot loader can do but to report an
+error to the user.  The boot loader should therefore be designed to
+take up as little space in low memory as it reasonably can.  For
+zImage or old bzImage kernels, which need data written into the
+0x90000 segment, the boot loader should make sure not to use memory
+above the 0x9A000 point; too many BIOSes will break above that point.
+
+
+**** THE REAL-MODE KERNEL HEADER
+
+In the following text, and anywhere in the kernel boot sequence, "a
+sector" refers to 512 bytes.  It is independent of the actual sector
+size of the underlying medium.
+
+The first step in loading a Linux kernel should be to load the
+real-mode code (boot sector and setup code) and then examine the
+following header at offset 0x01f1.  The real-mode code can total up to
+32K, although the boot loader may choose to load only the first two
+sectors (1K) and then examine the bootup sector size.
+
+The header looks like:
+
+Offset	Proto	Name		Meaning
+Size
+
+01F1/1	ALL	setup_sects	The size of the setup in sectors
+01F2/2	ALL	root_flags	If set, the root is mounted readonly
+01F4/2	ALL	syssize		DO NOT USE - for bootsect.S use only
+01F6/2	ALL	swap_dev	DO NOT USE - obsolete
+01F8/2	ALL	ram_size	DO NOT USE - for bootsect.S use only
+01FA/2	ALL	vid_mode	Video mode control
+01FC/2	ALL	root_dev	Default root device number
+01FE/2	ALL	boot_flag	0xAA55 magic number
+0200/2	2.00+	jump		Jump instruction
+0202/4	2.00+	header		Magic signature "HdrS"
+0206/2	2.00+	version		Boot protocol version supported
+0208/4	2.00+	realmode_swtch	Boot loader hook (see below)
+020C/4	2.00+	start_sys	Points to kernel version string
+0210/1	2.00+	type_of_loader	Boot loader identifier
+0211/1	2.00+	loadflags	Boot protocol option flags
+0212/2	2.00+	setup_move_size	Move to high memory size (used with hooks)
+0214/4	2.00+	code32_start	Boot loader hook (see below)
+0218/4	2.00+	ramdisk_image	initrd load address (set by boot loader)
+021C/4	2.00+	ramdisk_size	initrd size (set by boot loader)
+0220/4	2.00+	bootsect_kludge	DO NOT USE - for bootsect.S use only
+0224/4	2.01+	heap_end_ptr	Free memory after setup end
+0226/2	N/A	pad1		Unused
+0228/4	2.02+	cmd_line_ptr	32-bit pointer to the kernel command line
+
+For backwards compatibility, if the setup_sects field contains 0, the
+real value is 4.
+
+If the "HdrS" (0x53726448) magic number is not found at offset 0x202,
+the boot protocol version is "old".  Loading an old kernel, the
+following parameters should be assumed:
+
+	Image type = zImage
+	initrd not supported
+	Real-mode kernel must be located at 0x90000.
+
+Otherwise, the "version" field contains the protocol version,
+e.g. protocol version 2.01 will contain 0x0201 in this field.  When
+setting fields in the header, you must make sure only to set fields
+supported by the protocol version in use.
+
+Most boot loaders will simply load the kernel at its target address
+directly.  Such boot loaders do not need to worry about filling in
+most of the fields in the header.  The following fields should be
+filled out, however:
+
+  type_of_loader:
+	If your boot loader has an identifier assigned in
+	arch/i386/boot/setup.S, enter that value.  Otherwise, enter
+	0xFF here.
+
+  loadflags, heap_end_ptr:
+	If the protocol version is 2.01 or higher, enter the
+	offset limit of the setup heap into heap_end_ptr and set the
+	0x80 bit (CAN_USE_HEAP) of loadflags.  heap_end_ptr appears to
+	be relative to the start of setup (offset 0x0200).
+
+  setup_move_size: 
+	When using protocol 2.00 or 2.01, if the real mode
+	kernel is not loaded at 0x90000, it gets moved there later in
+	the loading sequence.  Fill in this field if you want
+	additional data (such as the kernel command line) moved in
+	addition to the real-mode kernel itself.
+
+  ramdisk_image, ramdisk_size:
+	If your boot loader has loaded an initial ramdisk (initrd),
+	set ramdisk_image to the 32-bit pointer to the ramdisk data
+	and the ramdisk_size to the size of the ramdisk data.
+
+	The initrd should typically be located as high in memory as
+	possible, as it may otherwise get overwritten by the early
+	kernel initialization sequence.  However, it must never be
+	located above address 0x3C000000 if you want all kernels to
+	read it.
+
+  cmd_line_ptr:
+	If the protocol version is 2.02 or higher, this is a 32-bit
+	pointer to the kernel command line.  The kernel command line
+	can be located anywhere between the end of setup and 0xA0000.
+	Fill in this field even if your boot loader does not support a
+	command line, in which case you can point this to an empty
+	string (or better yet, to the string "auto".)  If this field
+	is left at zero, the kernel will assume that your boot loader
+	does not support the 2.02 protocol.
+
+
+**** THE KERNEL COMMAND LINE
+
+The kernel command line has become an important way for the boot
+loader to communicate with the kernel.  Some of its options are also
+relevant to the boot loader itself, see "special command line options"
+below.
+
+The kernel command line is a null-terminated string up to 255
+characters long, plus the final null.
+
+If the boot protocol version is 2.02 or later, the address of the
+kernel command line is given by the header field cmd_line_ptr (see
+above.)
+
+If the protocol version is *not* 2.02 or higher, the kernel
+command line is entered using the following protocol:
+
+	At offset 0x0020 (word), "cmd_line_magic", enter the magic
+	number 0xA33F.
+
+	At offset 0x0022 (word), "cmd_line_offset", enter the offset
+	of the kernel command line (relative to the start of the
+	real-mode kernel).
+	
+	The kernel command line *must* be within the memory region
+	covered by setup_move_size, so you may need to adjust this
+	field.
+
+
+**** SAMPLE BOOT CONFIGURATION
+
+As a sample configuration, assume the following layout of the real
+mode segment:
+
+	0x0000-0x7FFF	Real mode kernel
+	0x8000-0x8FFF	Stack and heap
+	0x9000-0x90FF	Kernel command line
+
+Such a boot loader should enter the following fields in the header:
+
+	unsigned long base_ptr;	/* base address for real-mode segment */
+
+	if ( setup_sects == 0 ) {
+		setup_sects = 4;
+	}
+
+	if ( protocol >= 0x0200 ) {
+		type_of_loader = <type code>;
+		if ( loading_initrd ) {
+			ramdisk_image = <initrd_address>;
+			ramdisk_size = <initrd_size>;
+		}
+		if ( protocol >= 0x0201 ) {
+			heap_end_ptr = 0x9000 - 0x200;
+			loadflags |= 0x80; /* CAN_USE_HEAP */
+		}
+		if ( protocol >= 0x0202 ) {
+			cmd_line_ptr = base_ptr + 0x9000;
+		} else {
+			cmd_line_magic  = 0xA33F;
+			cmd_line_offset = 0x9000;
+			setup_move_size = 0x9100;
+		}
+	} else {
+		/* Very old kernel */
+
+		cmd_line_magic  = 0xA33F;
+		cmd_line_offset = 0x9000;
+
+		/* A very old kernel MUST have its real-mode code
+		   loaded at 0x90000 */
+
+		if ( base_ptr != 0x90000 ) {
+			/* Copy the real-mode kernel */
+			memcpy(0x90000, base_ptr, (setup_sects+1)*512);
+			/* Copy the command line */
+			memcpy(0x99000, base_ptr+0x9000, 256);
+
+			base_ptr = 0x90000;		 /* Relocated */
+		}
+
+		/* It is recommended to clear memory up to the 32K mark */
+		memset(0x90000 + (setup_sects-1)*512, 0,
+		       (64-setup_sects-1)*512);
+	}
+
+
+**** LOADING THE REST OF THE KERNEL
+
+The non-real-mode kernel starts at offset (setup_sects+1)*512 in the
+kernel file (again, if setup_sects == 0 the real value is 4.)  It
+should be loaded at address 0x10000 for Image/zImage kernels and
+0x100000 for bzImage kernels.
+
+The kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01
+bit (LOAD_HIGH) in the loadflags field is set:
+
+	is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01);
+	load_address = is_bzImage ? 0x100000 : 0x10000;
+
+Note that Image/zImage kernels can be up to 512K in size, and thus use
+the entire 0x10000-0x90000 range of memory.  This means it is pretty
+much a requirement for these kernels to load the real-mode part at
+0x90000.  bzImage kernels allow much more flexibility.
+
+
+**** SPECIAL COMMAND LINE OPTIONS
+
+If the command line provided by the boot loader is entered by the
+user, the user may expect the following command line options to work.
+They should normally not be deleted from the kernel command line even
+though not all of them are actually meaningful to the kernel.
+
+  vga=<mode>
+	<mode> here is either an integer (in C notation, either
+	decimal, octal, or hexadecimal) or one of the strings
+	"normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask"
+	(meaning 0xFFFD).  This value should be entered into the
+	vid_mode field, as it is used by the kernel before the command
+	line is parsed.
+
+  mem=<size>
+	<size> is an integer in C notation optionally followed by K, M
+	or G (meaning << 10, << 20 or << 30).  This specifies to the
+	kernel the memory size.  This affects the possible placement
+	of an initrd, since an initrd should be placed near end of
+	memory.
+
+  initrd=<file>
+	An initrd should be loaded.  The meaning of <file> is
+	obviously bootloader-dependent.
+
+In addition, some boot loaders add the following options to the
+user-specified command line:
+
+  BOOT_IMAGE=<file>
+	The boot image which was loaded.  Again, the meaning of <file>
+	is obviously bootloader-dependent.
+
+  auto
+	The kernel was booted without explicit user intervention.
+
+If these options are added by the boot loader, it is highly
+recommended that they are located *first*, before the user-specified
+or configuration-specified command line.  Otherwise, "init=/bin/sh"
+gets confused by the "auto" option.
+
+
+**** RUNNING THE KERNEL
+
+The kernel is started by jumping to the kernel entry point, which is
+located at *segment* offset 0x20 from the start of the real mode
+kernel.  This means that if you loaded your real-mode kernel code at
+0x90000, the kernel entry point is 9020:0000.
+
+At entry, ds = es = ss = fs = gs should point to the start of the
+real-mode kernel code (0x9000 if the code is loaded at 0x90000), and
+sp should be set up properly, normally pointing to the top of the
+heap.  In our example from above, we would do:
+
+	/* Note: in the case of the "old" kernel protocol, base_ptr must
+	   be == 0x90000 at this point; see the previous sample code */
+
+	seg = base_ptr >> 4;
+
+	cli();	/* Enter with interrupts disabled! */
+
+	/* Set up the real-mode kernel stack */
+	_SS = seg;
+	_SP = 0x9000;	/* Load SP right after loading SS! */
+
+	_DS = _ES = _FS = _GS = seg;
+	jmp_far(seg+0x20, 0);	/* Run the kernel */
+
+If your boot sector accesses a floppy drive, it is recommended to
+switch off the floppy motor before running the kernel, since the
+kernel boot leaves interrupts off and thus the motor will not be
+switched off, especially if the loaded kernel has the floppy driver as
+a demand-loaded module!
+
+
+**** ADVANCED BOOT TIME HOOKS
+
+If the boot loader runs in a particularly hostile environment (such as
+LOADLIN, which runs under DOS) it may be impossible to follow the
+standard memory location requirements.  Such a boot loader may use the
+following hooks that, if set, are invoked by the kernel at the
+appropriate time.  The use of these hooks should probably be
+considered an absolutely last resort!
+
+IMPORTANT: All the hooks are required to preserve %ebp, %esi and %edi
+across invocation.
+
+  realmode_swtch:
+	A 16-bit real mode far subroutine invoked immediately before
+	entering protected mode.  The default routine disables NMI, so
+	your routine should probably do so, too.
+
+  code32_start:
+	A 32-bit flat-mode routine *jumped* to immediately after the
+	transition to protected mode, but before the kernel is
+	uncompressed.  No segments, except CS, are set up; you should
+	set them up to KERNEL_DS (0x18) yourself.
+
+	After completing your hook, you should jump to the address
+	that was in this field before your boot loader overwrote it.
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/networking/tlan.txt linux.17p18/Documentation/networking/tlan.txt
--- linux.vanilla/Documentation/networking/tlan.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/networking/tlan.txt	Tue Aug  1 07:59:02 2000
@@ -1,4 +1,4 @@
-TLAN driver for Linux, version 1.2
+TLAN driver for Linux, version 1.3b
 README
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/proc.txt linux.17p18/Documentation/proc.txt
--- linux.vanilla/Documentation/proc.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/proc.txt	Fri Aug  4 15:33:40 2000
@@ -459,12 +459,6 @@
    encountered a peak in your usage of file handles and you don't need
    to increase the maximum.
 
-   However, there is still a per process limit of open files, which
-   unfortunatly can't be changed that easily. It is set to 1024 by
-   default. To change this you have to edit the files limits.h and
-   fs.h in the directory /usr/src/linux/include/linux. Change the
-   definition of NR_OPEN and recompile the kernel.
-
 inode-state, inode-nr and inode-max
    As with file handles, the kernel allocates the inode structures
    dynamically, but can't free them yet.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/serial-console.txt linux.17p18/Documentation/serial-console.txt
--- linux.vanilla/Documentation/serial-console.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/serial-console.txt	Tue Aug  1 07:59:03 2000
@@ -87,8 +87,8 @@
 
 6. Thanks
 
-   Thanks to Geert Uytterhoeven <Geert.Uytterhoeven@cs.kuleuven.ac.be>
-   for porting the patches from 2.1.4x to 2.1.6x for taking care of
-   the integration of these patches into m68k, ppc and alpha.
+   Thanks to Geert Uytterhoeven <geert@linux-m68k.org> for porting
+   the patches from 2.1.4x to 2.1.6x and for taking care of the
+   integration of these patches into m68k, ppc and alpha.
 
 Miquel van Smoorenburg <miquels@cistron.nl>, 21-Mar-1998
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/sound/README.ymfsb linux.17p18/Documentation/sound/README.ymfsb
--- linux.vanilla/Documentation/sound/README.ymfsb	Sun Jun 11 21:44:08 2000
+++ linux.17p18/Documentation/sound/README.ymfsb	Tue Aug  1 07:59:02 2000
@@ -9,7 +9,7 @@
   about YMF7xx cards.
 
   And this codes heavily based on Jeff Garzik <jgarzik@pobox.com>'s
-  VIA 82Cxxx driver (via82cxxx.c). I also respect him.
+  old VIA 82Cxxx driver (via82cxxx.c). I also respect him.
 
 
 DISCLIMER
@@ -24,61 +24,52 @@
 =================
 
   This code enables you to use your YMF724[A-F], YMF740[A-C], YMF744, YMF754
- cards. When enabled, your card acts as "SoundBlaster Pro" compatible card.
- It can only play 22.05kHz / 8bit / Stereo samples, control external MIDI
- port.
- If you want to use your card as recent "16-bit" card, you should wait for
- Alsa (or OSS) driver. Ofcource you can write native PCI driver for your
- cards :)
+ cards as "SoundBlaster Pro" compatible card. It can only play 22.05kHz /
+ 8bit / Stereo samples, control external MIDI port.
+ And it can handle AC'97 mixer of these cards.
+
+  If you want to use your card as recent "16-bit" card, you should use
+ Alsa or OSS/Linux driver. Ofcource you can write native PCI driver for
+ your cards :)
 
 
 INSTALL
 =======
 
-  This codes currently requires YAMAHA's header file: Hwmcode.h and
- 724hwmcode.c
- It can be found at alsa's ftp (or mirror) sites. 
-
-   ftp://ftp.alsa-project.org/pub/manuals/yamaha/pci/
-
- Hwmcode.h is contained in 754smpls.zip available at above URL.
+  First, it requires some sound driver modules in Linux kernel 
+ (soundcore.o , sound.o, sb.o and uart401.o), so you should enable
+ these modules at kernel configuration (please refer some other 
+ documentations for configuration of kernel).
+ And add the following line in /etc/modules.conf:
 
+  options sb support=1
 
-  To compile driver module, extract source archive and place above headers
- in the directory.
- And type 'make'. When it goes well, you will get ymfsb.o. 
- Copy it to /lib/modules/<kernel_version>/misc/ and do 'depmod -a'.
- Before modprobe, insert following line in /etc/modules.conf:
+ (NOTE: There are no need any configuration of sb modules)
 
-  # /etc/modules.conf
-  options sb support=1
+ To compile ymfsb module, type 'make'.
+ And copy it to /lib/modules/(kernel_version)/misc, type 'depmod -a'.
+ 
+  This module also requires /usr/src/linux/drivers/sound/ac97.[ch].
+ If your kernel doesn't have these files, you should upgrade your kernel.
 
 
 USAGE
 =====
 
- # modprobe ymfsb
+ # modprobe ymfsb (options)
 
 
-OPTIONS FOR MODULE
-==================
+OPTIONS FOR YMFSB
+=================
 
   io           : SB base address     (0x220, 0x240, 0x260, 0x280)
   synth_io     : OPL3 base address   (0x388, 0x398, 0x3a0, 0x3a8)
   dma          : DMA number          (0,1,3)
-  master_volume: AC'97 PCM out Vol   (0-100)
   spdif_out    : SPDIF-out flag      (0:disable 1:enable)
 
  These options will change in future...
 
 
-TODO
-====
-
- TOO LOT.
- Ofcource we have not to satisfy such a poor code like this :-<
-
-
 FREQUENCY
 =========
 
@@ -92,10 +83,6 @@
 
   %  mpg123 -r 21739 foo.mp3
 
- Ofcource it potentially contains sample-rate-conversion, and may destroy
- your sound. But you must remember that this card currently only handle
- samples up to 21.739kHz B-(
-
 
 SPDIF OUT
 =========
@@ -125,15 +112,12 @@
  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
 
-AVAILABILITY
-============
-
- The latest version of this driver may be available at:
-
-   http://member.nifty.ne.jp/Breeze/linux/index.html
+TODO
+====
+ * support for multiple cards
+   (set the different SB_IO,MPU_IO,OPL_IO for each cards)
 
- When the native DS-XG driver is available (from alsa, OSS, or else),
- this code will have to be expired.
+ * support for OPL (dmfm) : There will be no requirements... :-<
 
 
 AUTHOR
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/sound/TODO.ymfsb linux.17p18/Documentation/sound/TODO.ymfsb
--- linux.vanilla/Documentation/sound/TODO.ymfsb	Sun Jun 11 21:44:08 2000
+++ linux.17p18/Documentation/sound/TODO.ymfsb	Thu Jan  1 01:00:00 1970
@@ -1,7 +0,0 @@
-YMF_SB driver
-
-TODO:
- * support for multiple cards
-   (set the different SB_IO,MPU_IO,OPL_IO for each cards)
-
- * support for OPL (dmfm) : There will be no demand... :-<
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Documentation/sysctl/vm.txt linux.17p18/Documentation/sysctl/vm.txt
--- linux.vanilla/Documentation/sysctl/vm.txt	Fri Apr 21 12:45:49 2000
+++ linux.17p18/Documentation/sysctl/vm.txt	Wed Aug  9 22:29:31 2000
@@ -168,7 +168,7 @@
 
 This feature can be very useful because there are a lot of
 programs that malloc() huge amounts of memory "just-in-case"
-and don't much of it.
+and don't use much of it.
 
 Look at: mm/mmap.c::vm_enough_memory() for more information.
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/MAINTAINERS linux.17p18/MAINTAINERS
--- linux.vanilla/MAINTAINERS	Sun Jun 11 21:44:08 2000
+++ linux.17p18/MAINTAINERS	Tue Aug  1 08:00:29 2000
@@ -220,6 +220,12 @@
 W:	http://www.cyclades.com/
 S:	Supported
 
+CYCLADES PC300 DRIVER
+P:	Ivan Passos
+M:	ivan@cyclades.com
+W:	http://www.cyclades.com/
+S:	Supported
+
 DAMA SLAVE for AX.25
 P:	Joerg Reuter
 M:	jreuter@poboxes.com
@@ -262,6 +268,14 @@
 W:	http://www.dgii.com/linux/
 S:	Maintained
 
+DISK GEOMETRY AND PARTITION HANDLING
+P:     Andries Brouwer
+M:     aeb@veritas.com
+W:     http://www.win.tue.nl/~aeb/linux/Large-Disk.html
+W:     http://www.win.tue.nl/~aeb/linux/zip/zip-1.html
+W:     http://www.win.tue.nl/~aeb/partitions/partition_types-1.html
+S:     Maintained
+
 DISKQUOTA:
 P:	Marco van Wieringen
 M:	mvw@planets.elm.net
@@ -283,8 +297,9 @@
 COMPAQ SMART2 RAID DRIVER
 P:	Charles White	
 M:	Charles White <arrays@compaq.com>
-L:	compaqandlinux@yps.org	
-S:	Maintained
+L:	compaqandlinux@cpqlin.van-dijk.net
+W:	ftp.compaq.com/pub/products/drivers/linux
+S:	Supported
 
 DAC960 RAID DRIVER
 P:	Leonard N. Zubkoff
@@ -309,6 +324,13 @@
 M:	saw@saw.sw.com.sg
 S:	Maintained
 
+EMU10K1 SOUND DRIVER
+P:	Rui Sousa       
+M:	rsousa@grad.physics.sunysb.edu  
+L:	emu10k1-devel@opensource.creative.com
+W:	http://opensource.creative.com/
+S:	Maintained
+
 ETHEREXPRESS-16 NETWORK DRIVER
 P:	Philip Blundell
 M:	Philip.Blundell@pobox.com
@@ -579,12 +601,6 @@
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
-MOUSE AND MISC DEVICES [GENERAL]
-P:	Alessandro Rubini
-M:	rubini@ipvvis.unipv.it
-L:	linux-kernel@vger.rutgers.edu
-S:	Maintained
-
 MTRR AND SIMILAR SUPPORT [i386]
 P:	Richard Gooch
 M:	rgooch@atnf.csiro.au
@@ -652,6 +668,12 @@
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
+NTFS FILESYSTEM
+P:	Anton Altaparmakov
+M:	aia21@cus.cam.ac.uk
+L:	linux-kernel@vger.rutgers.edu
+S:	Odd Fixes
+
 OLYMPIC NETWORK DRIVER
 P:	Peter De Shrijver
 M:	p2@ace.ulyssis.sutdent.kuleuven.ac.be	
@@ -789,8 +811,8 @@
 S:	Maintained
 
 SMB FILESYSTEM
-P:	Andrew Tridgell
-M:	tridge@samba.org
+P:	Urban Widmark
+M:	urban@svenskatest.se
 W:	http://samba.org/
 L:	samba@samba.org
 S:	Maintained
@@ -864,6 +886,7 @@
 P:	Torben Mathiasen
 M:	torben.mathiasen@compaq.com
 L:	tlan@vuser.vu.union.edu
+W:	http://tlan.kernel.dk
 S:	Maintained
 
 TOKEN-RING NETWORK DRIVER
@@ -888,7 +911,7 @@
 
 UMSDOS FILESYSTEM
 P:	Matija Nalis
-M:	mnalis@jagor.srce.hr
+M:	mnalis-umsdos@voyager.hr
 L:	linux-kernel@vger.rutgers.edu
 S:	Maintained
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Makefile linux.17p18/Makefile
--- linux.vanilla/Makefile	Sun Jun 11 21:44:08 2000
+++ linux.17p18/Makefile	Wed Aug 16 21:00:02 2000
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 2
-SUBLEVEL = 16
-EXTRAVERSION = 
+SUBLEVEL = 17
+EXTRAVERSION = pre18
 
 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/)
 
@@ -22,7 +22,7 @@
 
 AS	=$(CROSS_COMPILE)as
 LD	=$(CROSS_COMPILE)ld
-CC	=$(CROSS_COMPILE)gcc -D__KERNEL__ -I$(HPATH)
+CC	=$(CROSS_COMPILE)cc -D__KERNEL__ -I$(HPATH)
 CPP	=$(CC) -E
 AR	=$(CROSS_COMPILE)ar
 NM	=$(CROSS_COMPILE)nm
@@ -325,13 +325,15 @@
 modules_install:
 	@( \
 	MODLIB=$(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE); \
+	mkdir -p $$MODLIB; \
+	rm -f $$MODLIB/build; \
+	ln -s `pwd` $$MODLIB/build; \
 	cd modules; \
 	MODULES=""; \
 	inst_mod() { These="`cat $$1`"; MODULES="$$MODULES $$These"; \
 		mkdir -p $$MODLIB/$$2; cp $$These $$MODLIB/$$2; \
 		echo Installing modules under $$MODLIB/$$2; \
 	}; \
-	mkdir -p $$MODLIB; \
 	\
 	if [ -f BLOCK_MODULES ]; then inst_mod BLOCK_MODULES block; fi; \
 	if [ -f NET_MODULES   ]; then inst_mod NET_MODULES   net;   fi; \
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/Rules.make linux.17p18/Rules.make
--- linux.vanilla/Rules.make	Fri Apr 21 12:47:18 2000
+++ linux.17p18/Rules.make	Tue Aug  1 08:00:41 2000
@@ -61,6 +61,9 @@
 %.o: %.s
 	$(AS) $(ASFLAGS) $(EXTRA_CFLAGS) -o $@ $<
 
+%.lst: %.c
+	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+	$(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
 #
 #
 #
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/config.in linux.17p18/arch/alpha/config.in
--- linux.vanilla/arch/alpha/config.in	Sun Jun 11 21:44:08 2000
+++ linux.17p18/arch/alpha/config.in	Tue Aug  1 07:59:03 2000
@@ -80,6 +80,10 @@
 	define_bool CONFIG_ALPHA_EV4 y
 	define_bool CONFIG_ALPHA_APECS y
 fi
+if [ "$CONFIG_ALPHA_CABRIOLET" = "y" ]
+then
+	define_bool CONFIG_ALPHA_EB64P y
+fi
 if [ "$CONFIG_ALPHA_EB164" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
 	-o "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_XLT" = "y" \
 	-o "$CONFIG_ALPHA_TAKARA" = "y" ]
@@ -149,22 +153,26 @@
 	define_bool CONFIG_ALPHA_IRONGATE y
 fi
 
+if [ "$CONFIG_ALPHA_JENSEN" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
+        -o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \
+        -o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
+        -o "$CONFIG_ALPHA_EIGER" = "y" ]
+then
+        define_bool CONFIG_ALPHA_SRM y
+fi
 if [ "$CONFIG_ALPHA_CABRIOLET" = "y" -o "$CONFIG_ALPHA_AVANTI" = "y" \
-	-o "$CONFIG_ALPHA_EB64P" = "y" -o "$CONFIG_ALPHA_JENSEN" = "y" \
-	-o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
-	-o "$CONFIG_ALPHA_MIKASA" = "y" -o "$CONFIG_ALPHA_ALCOR" = "y" \
-	-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_MIATA" = "y" \
-	-o "$CONFIG_ALPHA_NORITAKE" = "y" -o "$CONFIG_ALPHA_PC164" = "y" \
-	-o "$CONFIG_ALPHA_LX164" = "y" -o "$CONFIG_ALPHA_SX164" = "y" \
-	-o "$CONFIG_ALPHA_DP264" = "y" -o "$CONFIG_ALPHA_RAWHIDE" = "y" \
-	-o "$CONFIG_ALPHA_EIGER" = "y" -o "$CONFIG_ALPHA_NAUTILUS" = "y" ]
+        -o "$CONFIG_ALPHA_EB64P" = "y"  -o "$CONFIG_ALPHA_PC164" = "y" \
+        -o "$CONFIG_ALPHA_TAKARA" = "y" -o "$CONFIG_ALPHA_EB164" = "y" \
+        -o "$CONFIG_ALPHA_ALCOR" = "y"  -o "$CONFIG_ALPHA_MIATA" = "y" \
+        -o "$CONFIG_ALPHA_LX164" = "y"  -o "$CONFIG_ALPHA_SX164" = "y" \
+        -o "$CONFIG_ALPHA_NAUTILUS" = "y" ]
 then
   bool 'Use SRM as bootloader' CONFIG_ALPHA_SRM
-  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
-    if [ "$CONFIG_ALPHA_SRM" = "y" ]; then
-      bool '  Use SRM PCI setup' CONFIG_ALPHA_SRM_SETUP
-    fi
-  fi
+#  if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+#    if [ "$CONFIG_ALPHA_SRM" = "y" ]; then
+#      bool '  Use SRM PCI setup' CONFIG_ALPHA_SRM_SETUP
+#    fi
+#  fi
 fi
 if [ "$CONFIG_ALPHA_ALCOR" = "y" -o "$CONFIG_ALPHA_MIKASA" = "y" \
 	-o "$CONFIG_ALPHA_SABLE" = "y" -o "$CONFIG_ALPHA_NORITAKE" = "y" \
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/kernel/setup.c linux.17p18/arch/alpha/kernel/setup.c
--- linux.vanilla/arch/alpha/kernel/setup.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/alpha/kernel/setup.c	Tue Aug  1 07:59:03 2000
@@ -517,7 +517,7 @@
 	{
 		&eb64p_mv,
 		&cabriolet_mv,
-		NULL		/* AlphaPCI64 */
+		&cabriolet_mv		/* AlphaPCI64 */
 	};
 
 	static struct alpha_machine_vector *eb66_vecs[] __initlocaldata =
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/kernel/sys_cabriolet.c linux.17p18/arch/alpha/kernel/sys_cabriolet.c
--- linux.vanilla/arch/alpha/kernel/sys_cabriolet.c	Fri Apr 21 12:45:44 2000
+++ linux.17p18/arch/alpha/kernel/sys_cabriolet.c	Tue Aug  1 07:59:03 2000
@@ -286,7 +286,9 @@
 	pci_fixup:		cabriolet_pci_fixup,
 	kill_arch:		generic_kill_arch,
 };
+#ifndef CONFIG_ALPHA_EB64P
 ALIAS_MV(cabriolet)
+#endif
 #endif
 
 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_EB164)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/kernel/sys_eb64p.c linux.17p18/arch/alpha/kernel/sys_eb64p.c
--- linux.vanilla/arch/alpha/kernel/sys_eb64p.c	Fri Apr 21 12:45:44 2000
+++ linux.17p18/arch/alpha/kernel/sys_eb64p.c	Tue Aug  1 07:59:03 2000
@@ -26,6 +26,7 @@
 #include <asm/pgtable.h>
 #include <asm/core_apecs.h>
 #include <asm/core_lca.h>
+#include <asm/hwrpb.h>
 
 #include "proto.h"
 #include "irq.h"
@@ -74,7 +75,7 @@
 static void __init
 eb64p_init_irq(void)
 {
-#ifdef CONFIG_ALPHA_GENERIC
+#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_CABRIOLET)
 	/*
 	 * CABRIO SRM may not set variation correctly, so here we test
 	 * the high word of the interrupt summary register for the RAZ
@@ -82,9 +83,12 @@
 	 */
 	if (inw(0x806) != 0xffff) {
 		extern struct alpha_machine_vector cabriolet_mv;
-#if 1
-		printk("eb64p_init_irq: resetting for CABRIO\n");
-#endif
+
+		printk("Detected Cabriolet: correcting HWRPB.\n");
+
+		hwrpb->sys_variation |= 2L << 10;
+		hwrpb_update_checksum(hwrpb);
+
 		alpha_mv = cabriolet_mv;
 		alpha_mv.init_irq();
 		return;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/kernel/sys_mikasa.c linux.17p18/arch/alpha/kernel/sys_mikasa.c
--- linux.vanilla/arch/alpha/kernel/sys_mikasa.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/alpha/kernel/sys_mikasa.c	Tue Aug  1 07:59:03 2000
@@ -151,8 +151,9 @@
 	common_pci_fixup(mikasa_map_irq, common_swizzle);
 }
 
+#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
 static void
-mikasa_machine_check(unsigned long vector, unsigned long la_ptr,
+mikasa_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
 		     struct pt_regs * regs)
 {
 #define MCHK_NO_DEVSEL 0x205U
@@ -175,14 +176,14 @@
 		(la_ptr + mchk_header->sys_offset);
 
 #ifdef DEBUG
-	printk("mikasa_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+	printk("mikasa_apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n",
 	       vector, la_ptr);
 	printk("        pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
 	       regs->pc, mchk_header->size, mchk_header->proc_offset,
 	       mchk_header->sys_offset);
-	printk("mikasa_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
-	       apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
-	       mchk_sysdata->epic_pear);
+	printk("mikasa_apecs_machine_check: expected %d DCSR 0x%lx"
+	       " PEAR 0x%lx\n", apecs_mcheck_expected,
+	       mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear);
 	ptr = (unsigned long *)la_ptr;
 	for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
 		printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
@@ -213,7 +214,7 @@
 		wrmces(0x1f);
 		mb();
 		draina();
-		printk("mikasa_machine_check: HW correctable (0x%lx)\n",
+		printk("mikasa_apecs_machine_check: HW correctable (0x%lx)\n",
 		       vector);
 	}
 	else {
@@ -239,6 +240,7 @@
 #endif
 	}
 }
+#endif
 
 
 /*
@@ -252,7 +254,7 @@
 	DO_DEFAULT_RTC,
 	DO_APECS_IO,
 	DO_APECS_BUS,
-	machine_check:		mikasa_machine_check,
+	machine_check:		mikasa_apecs_machine_check,
 	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
 
 	nr_irqs:		32,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/kernel/sys_noritake.c linux.17p18/arch/alpha/kernel/sys_noritake.c
--- linux.vanilla/arch/alpha/kernel/sys_noritake.c	Fri Apr 21 12:45:44 2000
+++ linux.17p18/arch/alpha/kernel/sys_noritake.c	Tue Aug  1 07:59:03 2000
@@ -238,6 +238,97 @@
 	common_pci_fixup(noritake_map_irq, noritake_swizzle);
 }
 
+#if defined(CONFIG_ALPHA_GENERIC) || !defined(CONFIG_ALPHA_PRIMO)
+static void
+noritake_apecs_machine_check(unsigned long vector, unsigned long la_ptr,
+		     struct pt_regs * regs)
+{
+#define MCHK_NO_DEVSEL 0x205U
+#define MCHK_NO_TABT 0x204U
+
+	struct el_common *mchk_header;
+	struct el_apecs_procdata *mchk_procdata;
+	struct el_apecs_mikasa_sysdata_mcheck *mchk_sysdata;
+	unsigned long *ptr;
+	unsigned int code; /* workaround EGCS problem */
+	int i;
+
+	mchk_header = (struct el_common *)la_ptr;
+
+	mchk_procdata = (struct el_apecs_procdata *)
+		(la_ptr + mchk_header->proc_offset
+		 - sizeof(mchk_procdata->paltemp));
+
+	mchk_sysdata = (struct el_apecs_mikasa_sysdata_mcheck *)
+		(la_ptr + mchk_header->sys_offset);
+
+#ifdef DEBUG
+	printk("noritake_apecs_machine_check: vector=0x%lx la_ptr=0x%lx\n",
+	       vector, la_ptr);
+	printk("        pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+	       regs->pc, mchk_header->size, mchk_header->proc_offset,
+	       mchk_header->sys_offset);
+	printk("noritake_apecs_machine_check: expected %d DCSR 0x%lx"
+	       " PEAR 0x%lx\n", apecs_mcheck_expected,
+	       mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear);
+	ptr = (unsigned long *)la_ptr;
+	for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+		printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
+	}
+#endif
+
+	/*
+	 * Check if machine check is due to a badaddr() and if so,
+	 * ignore the machine check.
+	 */
+
+	code = mchk_header->code; /* workaround EGCS problem */
+
+	if (apecs_mcheck_expected &&
+	    (code == MCHK_NO_DEVSEL || code == MCHK_NO_TABT))
+	{
+		apecs_mcheck_expected = 0;
+		apecs_mcheck_taken = 1;
+		mb();
+		mb(); /* magic */
+		apecs_pci_clr_err();
+		wrmces(0x7);
+		mb();
+		draina();
+	}
+	else if (vector == 0x620 || vector == 0x630) {
+		/* Disable correctable from now on.  */
+		wrmces(0x1f);
+		mb();
+		draina();
+		printk("noritake_apecs_machine_check: HW correctable (0x%lx)\n",
+		       vector);
+	}
+	else {
+		printk(KERN_CRIT "NORITAKE APECS machine check:\n");
+		printk(KERN_CRIT "  vector=0x%lx la_ptr=0x%lx code=0x%x\n",
+		       vector, la_ptr, code);
+		printk(KERN_CRIT
+		       "  pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
+		       regs->pc, mchk_header->size, mchk_header->proc_offset,
+		       mchk_header->sys_offset);
+		printk(KERN_CRIT "  expected %d DCSR 0x%lx PEAR 0x%lx\n",
+		       apecs_mcheck_expected, mchk_sysdata->epic_dcsr,
+		       mchk_sysdata->epic_pear);
+
+		ptr = (unsigned long *)la_ptr;
+		for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
+			printk(KERN_CRIT " +%lx %lx %lx\n",
+			       i*sizeof(long), ptr[i], ptr[i+1]);
+		}
+#if 0
+		/* doesn't work with MILO */
+		show_regs(regs);
+#endif
+	}
+}
+#endif
+
 
 /*
  * The System Vectors
@@ -250,7 +341,7 @@
 	DO_DEFAULT_RTC,
 	DO_APECS_IO,
 	DO_APECS_BUS,
-	machine_check:		apecs_machine_check,
+	machine_check:		noritake_apecs_machine_check,
 	max_dma_address:	ALPHA_MAX_DMA_ADDRESS,
 
 	nr_irqs:		48,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/alpha/mm/fault.c linux.17p18/arch/alpha/mm/fault.c
--- linux.vanilla/arch/alpha/mm/fault.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/alpha/mm/fault.c	Tue Aug  1 07:59:03 2000
@@ -150,8 +150,8 @@
 	if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) {
 		unsigned long newpc;
 		newpc = fixup_exception(dpf_reg, fixup, regs->pc);
-#if 1
-		printk("%s: Exception at [<%lx>] (%lx) handled successfully.\n",
+#if 0
+		printk("%s: Exception at [<%lx>] (%lx)\n",
 		       current->comm, regs->pc, newpc);
 #endif
 		regs->pc = newpc;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/i386/config.in linux.17p18/arch/i386/config.in
--- linux.vanilla/arch/i386/config.in	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/i386/config.in	Tue Aug  1 07:59:04 2000
@@ -114,6 +114,7 @@
   bool '   Allow interrupts during APM BIOS calls' CONFIG_APM_ALLOW_INTS
   bool '   Use real mode APM BIOS call to power off' CONFIG_APM_REAL_MODE_POWER_OFF
 fi
+tristate 'Toshiba Laptop support' CONFIG_TOSHIBA
 
 endmenu
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/i386/kernel/Makefile linux.17p18/arch/i386/kernel/Makefile
--- linux.vanilla/arch/i386/kernel/Makefile	Fri Apr 21 12:45:45 2000
+++ linux.17p18/arch/i386/kernel/Makefile	Mon Aug 14 20:08:08 2000
@@ -14,7 +14,8 @@
 
 O_TARGET := kernel.o
 O_OBJS   := process.o signal.o entry.o traps.o irq.o vm86.o \
-            ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o
+            ptrace.o ioport.o ldt.o setup.o time.o sys_i386.o \
+	    bluesmoke.o
 OX_OBJS  := i386_ksyms.o
 MX_OBJS  :=
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/i386/kernel/bluesmoke.c linux.17p18/arch/i386/kernel/bluesmoke.c
--- linux.vanilla/arch/i386/kernel/bluesmoke.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/i386/kernel/bluesmoke.c	Mon Aug 14 21:21:11 2000
@@ -0,0 +1,107 @@
+/*
+ *	Machine Check Handler For PII/PIII
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <asm/processor.h> 
+#include <asm/msr.h>
+
+static int banks = 0;
+
+void mcheck_fault(void)
+{
+	int recover=1;
+	u32 alow, ahigh, high, low;
+	u32 mcgstl, mcgsth;
+	int i;
+	
+	rdmsr(0x17a, mcgstl, mcgsth);
+	if(mcgstl&(1<<0))	/* Recoverable ? */
+		recover=0;
+
+	printk(KERN_EMERG "CPU %d: Machine Check Exception: %08x%08x", smp_processor_id(), mcgstl, mcgsth);
+	
+	for(i=0;i<banks;i++)
+	{
+		rdmsr(0x401+i*4,low, high);
+		if(high&(1<<31))
+		{
+			if(high&(1<<29))
+				recover|=1;
+			if(high&(1<<25))
+				recover|=2;
+			printk(KERN_EMERG "Bank %d: %08x%08x", i, high, low);
+			high&=~(1<<31);
+			if(high&(1<<27))
+			{
+				rdmsr(0x402+i*4, alow, ahigh);
+				printk("[%08x%08x]", alow, ahigh);
+			}
+			if(high&(1<<26))
+			{
+				rdmsr(0x402+i*4, alow, ahigh);
+				printk(" at %08x%08x", 
+					high, low);
+			}
+			wrmsr(0x401+i*4, low, high);
+		}
+	}
+	
+	if(recover&2)
+		panic("CPU context corrupt");
+	if(recover&1)
+		panic("Unable to continue");
+	printk(KERN_EMERG "Attempting to continue.\n");
+	mcgstl&=~(1<<2);
+	wrmsr(0x17a,mcgstl, mcgsth);
+}
+
+
+/*
+ *	This has to be run for each processor
+ */
+ 
+void mcheck_init(void)
+{
+	u32 l, h;
+	int i;
+	struct cpuinfo_x86 *c;
+	static int done=0;
+
+	c=cpu_data+smp_processor_id();
+	
+	if(c->x86_vendor!=X86_VENDOR_INTEL)
+		return;
+	
+	if(!(c->x86_capability&X86_FEATURE_MCE))
+		return;
+		
+	if(!(c->x86_capability&X86_FEATURE_MCA))
+		return;
+		
+	/* Ok machine check is available */
+	
+	if(done==0)
+		printk(KERN_INFO "Intel machine check architecture supported.\n");
+	rdmsr(0x179, l, h);
+	if(l&(1<<8))
+		wrmsr(0x17b, 0xffffffff, 0xffffffff);
+	banks = l&0xff;
+	for(i=1;i<banks;i++)
+	{
+		wrmsr(0x400+4*i, 0xffffffff, 0xffffffff); 
+	}
+	for(i=0;i<banks;i++)
+	{
+		wrmsr(0x401+4*i, 0x0, 0x0); 
+	}
+	__asm__ __volatile__ (
+		"movl %%cr4, %%eax\n\t"
+		"orl $0x40, %%eax\n\t"
+		"movl %%eax, %%cr4\n\t" : : : "eax");
+	printk(KERN_INFO "Intel machine check reporting enabled on CPU#%d.\n", smp_processor_id());
+	done=1;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/i386/kernel/entry.S linux.17p18/arch/i386/kernel/entry.S
--- linux.vanilla/arch/i386/kernel/entry.S	Fri Apr 21 12:45:45 2000
+++ linux.17p18/arch/i386/kernel/entry.S	Mon Aug 14 20:57:30 2000
@@ -366,6 +366,11 @@
 	pushl $ SYMBOL_NAME(do_page_fault)
 	jmp error_code
 
+ENTRY(machine_check)
+	pushl $0
+	pushl $ SYMBOL_NAME(mcheck_fault)
+	jmp error_code
+
 ENTRY(spurious_interrupt_bug)
 	pushl $0
 	pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/i386/kernel/setup.c linux.17p18/arch/i386/kernel/setup.c
--- linux.vanilla/arch/i386/kernel/setup.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/i386/kernel/setup.c	Mon Aug 14 20:07:39 2000
@@ -27,6 +27,8 @@
  *	Added proper Cascades CPU and L2 cache detection for Cascades
  *	and 8-way type cache happy bunch from Intel:^)
  *	Dragan Stancevic <visitor@valinux.com>, May 2000
+ *
+ *	Transmeta CPU detection.  H. Peter Anvin <hpa@zytor.com>, May 2000
  */
 
 /*
@@ -436,8 +438,10 @@
 {
 	unsigned int n, dummy, *v, ecx, edx;
 
-	/* Actually we must have cpuid or we could never have
-	 * figured out that this was AMD from the vendor info :-).
+	/* 
+	 * Actually we must have cpuid or we could never have
+	 * figured out that this was AMD/Cyrix/Transmeta
+	 * from the vendor info :-).
 	 */
 
 	cpuid(0x80000000, &n, &dummy, &dummy, &dummy);
@@ -450,8 +454,9 @@
 	cpuid(0x80000004, &v[8], &v[9], &v[10], &v[11]);
 	c->x86_model_id[48] = 0;
 	
-	if(c->x86_vendor == X86_VENDOR_AMD)
+	switch(c->x86_vendor)
 	{
+	case X86_VENDOR_AMD:
 		/*  Set MTRR capability flag if appropriate  */
 		if(boot_cpu_data.x86 == 5) {
 			if((boot_cpu_data.x86_model == 9) ||
@@ -460,17 +465,34 @@
 				c->x86_capability |= X86_FEATURE_MTRR;
 		}
 
+		/* Fall through */
+
+	case X86_VENDOR_TRANSMETA:
+		/* Cache information */
 		if (n >= 0x80000005){
 			cpuid(0x80000005, &dummy, &dummy, &ecx, &edx);
 			printk("CPU: L1 I Cache: %dK  L1 D Cache: %dK\n",
 				ecx>>24, edx>>24);
 			c->x86_cache_size=(ecx>>24)+(edx>>24);
 		}
-		if (n >= 0x80000006){
+		if(boot_cpu_data.x86_vendor == X86_VENDOR_AMD &&
+			boot_cpu_data.x86 == 6 && 
+			boot_cpu_data.x86_model== 3 &&
+			boot_cpu_data.x86_mask == 0)
+		{
+			/* AMD errata T13 (order #21922) */
+			printk("CPU: L2 Cache: 64K\n");
+			c->x86_cache_size = 64;
+		}
+		else if (n >= 0x80000006){
 			cpuid(0x80000006, &dummy, &dummy, &ecx, &edx);
 			printk("CPU: L2 Cache: %dK\n", ecx>>16);
 			c->x86_cache_size = ecx>>16;
 		}
+		break;
+
+	default:		/* Cyrix */
+		break;
 	}
 	return 1;
 }
@@ -735,6 +757,70 @@
 	return;
 }
 
+__initfunc(static void transmeta_model(struct cpuinfo_x86 *c))
+{
+	unsigned int cap_mask, uk, max, dummy, n, ecx, edx;
+	unsigned int cms_rev1, cms_rev2;
+	unsigned int cpu_rev, cpu_freq, cpu_flags;
+	char cpu_info[65];
+
+	get_model_name(c);	/* Same as AMD/Cyrix */
+
+	/* Print CMS and CPU revision */
+	cpuid(0x80860000, &max, &dummy, &dummy, &dummy);
+	if ( max >= 0x80860001 ) {
+		cpuid(0x80860001, &dummy, &cpu_rev, &cpu_freq, &cpu_flags); 
+		printk("CPU: Processor revision %u.%u.%u.%u, %u MHz%s%s\n",
+		       (cpu_rev >> 24) & 0xff,
+		       (cpu_rev >> 16) & 0xff,
+		       (cpu_rev >> 8) & 0xff,
+		       cpu_rev & 0xff,
+		       cpu_freq,
+		       (cpu_flags & 1) ? " [recovery]" : "",
+		       (cpu_flags & 2) ? " [longrun]" : "");
+	}
+	if ( max >= 0x80860002 ) {
+		cpuid(0x80860002, &dummy, &cms_rev1, &cms_rev2, &dummy);
+		printk("CPU: Code Morphing Software revision %u.%u.%u-%u-%u\n",
+		       (cms_rev1 >> 24) & 0xff,
+		       (cms_rev1 >> 16) & 0xff,
+		       (cms_rev1 >> 8) & 0xff,
+		       cms_rev1 & 0xff,
+		       cms_rev2);
+	}
+	if ( max >= 0x80860006 ) {
+		cpuid(0x80860003,
+		      (void *)&cpu_info[0],
+		      (void *)&cpu_info[4],
+		      (void *)&cpu_info[8],
+		      (void *)&cpu_info[12]);
+		cpuid(0x80860004,
+		      (void *)&cpu_info[16],
+		      (void *)&cpu_info[20],
+		      (void *)&cpu_info[24],
+		      (void *)&cpu_info[28]);
+		cpuid(0x80860005,
+		      (void *)&cpu_info[32],
+		      (void *)&cpu_info[36],
+		      (void *)&cpu_info[40],
+		      (void *)&cpu_info[44]);
+		cpuid(0x80860006,
+		      (void *)&cpu_info[48],
+		      (void *)&cpu_info[52],
+		      (void *)&cpu_info[56],
+		      (void *)&cpu_info[60]);
+		cpu_info[64] = '\0';
+		printk("CPU: %s\n", cpu_info);
+	}
+
+	/* Unhide possibly hidden flags */
+	rdmsr(0x80860004, cap_mask, uk);
+	wrmsr(0x80860004, ~0, uk);
+	cpuid(0x00000001, &dummy, &dummy, &dummy, &c->x86_capability);
+	wrmsr(0x80860004, cap_mask, uk);
+}
+
+
 __initfunc(void get_cpu_vendor(struct cpuinfo_x86 *c))
 {
 	char *v = c->x86_vendor_id;
@@ -751,6 +837,10 @@
 		c->x86_vendor = X86_VENDOR_CENTAUR;
 	else if (!strcmp(v, "NexGenDriven"))
 		c->x86_vendor = X86_VENDOR_NEXGEN;
+	else if (!strcmp(v, "RiseRiseRise"))
+		c->x86_vendor = X86_VENDOR_RISE;
+	else if (!strcmp(v, "GenuineTMx86"))
+		c->x86_vendor = X86_VENDOR_TRANSMETA;
 	else
 		c->x86_vendor = X86_VENDOR_UNKNOWN;
 }
@@ -815,6 +905,20 @@
 	    c->cpuid_level < 0)
 		return;
 
+	/* It should be possible for the user to override this. */
+	if(c->cpuid_level > 0 && 
+	   (c->x86_vendor == X86_VENDOR_INTEL || c->x86_vendor == X86_VENDOR_TRANSMETA) &&
+	   c->x86_capability&(1<<18)) {
+		/* Disable processor serial number */
+		unsigned long lo,hi;
+		rdmsr(0x119,lo,hi);
+		lo |= 0x200000;
+		wrmsr(0x119,lo,hi);
+		printk(KERN_INFO "CPU serial number disabled.\n");
+	}
+
+	mcheck_init(c);
+	
 	if (c->x86_vendor == X86_VENDOR_CYRIX) {
 		cyrix_model(c);
 		return;
@@ -823,18 +927,9 @@
 	if (c->x86_vendor == X86_VENDOR_AMD && amd_model(c))
 		return;
 		
-	if (c->cpuid_level > 0 && c->x86_vendor == X86_VENDOR_INTEL)
-	{
-		if(c->x86_capability&(1<<18))
-		{
-			/* Disable processor serial number on Intel Pentium III 
-			   from code by Phil Karn */
-			unsigned long lo,hi;
-			rdmsr(0x119,lo,hi);
-			lo |= 0x200000;
-			wrmsr(0x119,lo,hi);
-			printk(KERN_INFO "Pentium-III serial number disabled.\n");
-		}
+	if (c->x86_vendor == X86_VENDOR_TRANSMETA) {
+		transmeta_model(c);
+		return;
 	}
 
 	if (c->cpuid_level > 1) {
@@ -928,7 +1023,7 @@
 	
 
 static char *cpu_vendor_names[] __initdata = {
-	"Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur" };
+	"Intel", "Cyrix", "AMD", "UMC", "NexGen", "Centaur", "Rise", "Transmeta" };
 
 
 __initfunc(void print_cpu_info(struct cpuinfo_x86 *c))
@@ -940,7 +1035,7 @@
 	else if (c->cpuid_level >= 0)
 		vendor = c->x86_vendor_id;
 
-	if (vendor)
+	if (vendor && strncmp(c->x86_model_id, vendor, strlen(vendor)))
 		printk("%s ", vendor);
 
 	if (!c->x86_model_id[0])
@@ -964,6 +1059,12 @@
 		/* Emulate MTRRs using Centaur's MCR. */
 		c->x86_capability |= X86_FEATURE_MTRR;
 
+		/* Disable TSC on C6 as per errata. */
+		if (c->x86_model ==4) {
+			printk ("Disabling bugged TSC.\n");
+			c->x86_capability &= ~X86_FEATURE_TSC;
+		}
+
 		/* Set 3DNow! on Winchip 2 and above. */
 		if (c->x86_model >=8)
 		    c->x86_capability |= X86_FEATURE_AMD3D;
@@ -1029,10 +1130,15 @@
 		    case X86_VENDOR_AMD:
 			if (c->x86 == 5 && c->x86_model == 6)
 				x86_cap_flags[10] = "sep";
-			x86_cap_flags[16] = "fcmov";
+			if (c->x86 < 6)
+				x86_cap_flags[16] = "fcmov";
+			x86_cap_flags[16] = "pat";
+			x86_cap_flags[22] = "mmxext";
+			x86_cap_flags[24] = "fxsr";
+			x86_cap_flags[30] = "3dnowext";
 			x86_cap_flags[31] = "3dnow";
 			break;
-
+																																										
 		    case X86_VENDOR_INTEL:
 			x86_cap_flags[6] = "pae";
 			x86_cap_flags[9] = "apic";
@@ -1050,8 +1156,8 @@
 			break;
 
 		    default:
-			/* Unknown CPU manufacturer. Transmeta ? :-) */
-			break;
+		        /* Unknown CPU manufacturer or no specal action needed */
+		        break;
 		}
 
 		sep_bug = c->x86_vendor == X86_VENDOR_INTEL &&
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/i386/kernel/traps.c linux.17p18/arch/i386/kernel/traps.c
--- linux.vanilla/arch/i386/kernel/traps.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/i386/kernel/traps.c	Mon Aug 14 21:15:52 2000
@@ -109,6 +109,7 @@
 asmlinkage void reserved(void);
 asmlinkage void alignment_check(void);
 asmlinkage void spurious_interrupt_bug(void);
+asmlinkage void machine_check(void);
 
 int kstack_depth_to_print = 24;
 
@@ -367,6 +368,9 @@
 
 	__asm__ __volatile__("movl %%db6,%0" : "=r" (condition));
 
+	/* Ensure the debug status register is visible to ptrace (or the process itself) */
+	tsk->tss.debugreg[6] = condition;
+
 	/* Mask out spurious TF errors due to lazy TF clearing */
 	if (condition & DR_STEP) {
 		/*
@@ -699,6 +703,7 @@
 	set_trap_gate(15,&spurious_interrupt_bug);
 	set_trap_gate(16,&coprocessor_error);
 	set_trap_gate(17,&alignment_check);
+	set_trap_gate(18,&machine_check);
 	set_system_gate(SYSCALL_VECTOR,&system_call);
 
 	/* set up GDT task & ldt entries */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/m68k/amiga/chipram.c linux.17p18/arch/m68k/amiga/chipram.c
--- linux.vanilla/arch/m68k/amiga/chipram.c	Fri Apr 21 12:45:46 2000
+++ linux.17p18/arch/m68k/amiga/chipram.c	Tue Aug  1 07:59:04 2000
@@ -1,8 +1,7 @@
 /*
 **  linux/amiga/chipram.c
 **
-**      Modified 03-May-94 by Geert Uytterhoeven
-**                           (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+**      Modified 03-May-94 by Geert Uytterhoeven <geert@linux-m68k.org>
 **          - 64-bit aligned allocations for full AGA compatibility
 */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/m68k/tools/amiga/dmesg.c linux.17p18/arch/m68k/tools/amiga/dmesg.c
--- linux.vanilla/arch/m68k/tools/amiga/dmesg.c	Fri Apr 21 12:45:46 2000
+++ linux.17p18/arch/m68k/tools/amiga/dmesg.c	Tue Aug  1 07:59:04 2000
@@ -3,8 +3,7 @@
  *					   in Chip RAM with the kernel command
  *					   line option `debug=mem'.
  *
- *  © Copyright 1996 by Geert Uytterhoeven
- *		       (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *  © Copyright 1996 by Geert Uytterhoeven <geert@linux-m68k.org>
  *
  *
  *  Usage:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/boot/Makefile linux.17p18/arch/ppc/boot/Makefile
--- linux.vanilla/arch/ppc/boot/Makefile	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/boot/Makefile	Tue Aug  1 07:59:04 2000
@@ -53,6 +53,9 @@
 
 OBJECTS := head.o misc.o ../coffboot/zlib.o
 CFLAGS = -O2 -DSTDC_HEADERS -fno-builtin -I$(TOPDIR)/include
+ifeq ($(CONFIG_SMP),y)
+CFLAGS += -D__SMP__
+endif
 OBJCOPY = $(CROSS_COMPILE)objcopy
 OBJCOPY_ARGS = -O elf32-powerpc
 
@@ -66,7 +69,7 @@
 zvmlinux.initrd: zvmlinux
 	$(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=initrd=ramdisk.image.gz \
+		--add-section=initrd=../coffboot/ramdisk.image.gz \
 		--add-section=image=../coffboot/vmlinux.gz \
 		zvmlinux.initrd.tmp zvmlinux.initrd
 	$(CC) $(CFLAGS) -DINITRD_OFFSET=`sh offset $(OBJDUMP) zvmlinux.initrd initrd` \
@@ -76,7 +79,7 @@
 		-c -o misc.o misc.c
 	$(LD) $(ZLINKFLAGS) -o zvmlinux.initrd.tmp $(OBJECTS)
 	$(OBJCOPY) $(OBJCOPY_ARGS) -R .comment \
-		--add-section=initrd=ramdisk.image.gz \
+		--add-section=initrd=../coffboot/ramdisk.image.gz \
 		--add-section=image=../coffboot/vmlinux.gz \
 		zvmlinux.initrd.tmp $@
 	rm zvmlinux.initrd.tmp
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/chrpboot/main.c linux.17p18/arch/ppc/chrpboot/main.c
--- linux.vanilla/arch/ppc/chrpboot/main.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/chrpboot/main.c	Tue Aug  1 07:59:04 2000
@@ -17,15 +17,16 @@
 #define get_32be(x)	(*(unsigned *)(x))
 
 #define RAM_START	0x00000000
-#define RAM_END		(8<<20)
+#define RAM_END		(64<<20)
 
-#define RAM_FREE	((unsigned long)(_end+0x1000)&~0xFFF)
+#define BOOT_START	((unsigned long)_start)
+#define BOOT_END	((unsigned long)(_end + 0xFFF) & ~0xFFF)
 #define PROG_START	0x00010000
 
 char *avail_ram;
 char *end_avail;
 
-extern char _end[];
+extern char _start[], _end[];
 extern char image_data[];
 extern int image_len;
 extern char initrd_data[];
@@ -39,26 +40,31 @@
     void *dst;
     unsigned char *im;
     unsigned initrd_start, initrd_size;
-    extern char _start;
-    
-    printf("chrpboot starting: loaded at 0x%x\n\r", &_start);
+
+    printf("chrpboot starting: loaded at 0x%x\n\r", _start);
 
     if (initrd_len) {
 	initrd_size = initrd_len;
 	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
 	a1 = initrd_start;
 	a2 = initrd_size;
-	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n\r", initrd_start,
-	       initrd_data,initrd_size);
+	claim(initrd_start, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+	       initrd_start, initrd_data, initrd_size);
 	memcpy((char *)initrd_start, initrd_data, initrd_size);
-	end_avail = (char *)initrd_start;
-    } else
-	end_avail = (char *) RAM_END;
+    }
     im = image_data;
     len = image_len;
+    /* try and claim our text/data in case of OF bugs */
+    claim(BOOT_START, BOOT_END - BOOT_START, 0);
+    /* claim 4MB starting at PROG_START */
+    claim(PROG_START, (4<<20) - PROG_START, 0);
     dst = (void *) PROG_START;
     if (im[0] == 0x1f && im[1] == 0x8b) {
-	avail_ram = (char *)RAM_FREE;
+	/* claim 512kB for scratch space */
+	avail_ram = (char *) claim(0, 512 << 10, 0x10);
+	end_avail = avail_ram + (512 << 10);
+	printf("avail_ram = %x\n", avail_ram);
 	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
 	gunzip(dst, 0x400000, im, &len);
 	printf("done %u bytes\n\r", len);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/chrpboot/misc.S linux.17p18/arch/ppc/chrpboot/misc.S
--- linux.vanilla/arch/ppc/chrpboot/misc.S	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/chrpboot/misc.S	Tue Aug  1 07:59:04 2000
@@ -9,7 +9,7 @@
 	.text
 
 /*
- * Use the BAT0 registers to map the 1st 8MB of RAM to 0x90000000.
+ * Use the BAT0 registers to map the 1st 8 or 64MB of RAM to 0x90000000.
  */
 	.globl	setup_bats
 setup_bats:
@@ -21,7 +21,7 @@
 	ori	4,4,4			/* set up BAT registers for 601 */
 	li	5,0x7f
 	b	5f
-4:	ori	4,4,0xff		/* set up BAT registers for 604 */
+4:	ori	4,4,0x7ff		/* set up BAT registers for 604 */
 	li	5,2
 	mtdbatu	3,4
 	mtdbatl	3,5
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/chrpboot/start.c linux.17p18/arch/ppc/chrpboot/start.c
--- linux.vanilla/arch/ppc/chrpboot/start.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/chrpboot/start.c	Tue Aug  1 07:59:04 2000
@@ -131,6 +131,29 @@
     return args.phandle;
 }
 
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	unsigned int virt;
+	unsigned int size;
+	unsigned int align;
+	void *ret;
+    } args;
+
+    args.service = "claim";
+    args.nargs = 3;
+    args.nret = 1;
+    args.virt = virt;
+    args.size = size;
+    args.align = align;
+    (*prom)(&args);
+    return args.ret;
+}
+
 int
 getprop(void *phandle, const char *name, void *buf, int buflen)
 {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/Makefile linux.17p18/arch/ppc/coffboot/Makefile
--- linux.vanilla/arch/ppc/coffboot/Makefile	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/coffboot/Makefile	Tue Aug  1 07:59:04 2000
@@ -3,32 +3,32 @@
 #
 # Paul Mackerras	January 1997
 
-HOSTCC	= gcc
 HOSTCFLAGS = -O -I$(TOPDIR)/include
 
 CC	= $(CROSS_COMPILE)gcc
 LD	= $(CROSS_COMPILE)ld
-CFLAGS	= -O -fno-builtin -I$(TOPDIR)/include
+CFLAGS	= $(CPPFLAGS) -O -fno-builtin
 OBJCOPY = $(CROSS_COMPILE)objcopy
-OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment \
-	--add-section=image=vmlinux.gz
-LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+OBJCOPY_ARGS = -O aixcoff-rs6000 -R .stab -R .stabstr -R .comment
+COFF_LD_ARGS = -e _start -T ld.script -Ttext 500000 -Tdata 510000 -Bstatic
+CHRP_LD_ARGS = -Ttext 0x00400000
 GZ = gzip -9
 
-OBJS = crt0.o start.o main.o misc.o string.o zlib.o
+COFFOBJS = coffcrt0.o start.o coffmain.o misc.o string.o zlib.o image.o
+CHRPOBJS = crt0.o start.o chrpmain.o misc.o string.o zlib.o image.o
 LIBS = $(TOPDIR)/lib/lib.a
 
-ifeq ($(CONFIG_ALL_PPC),y)
-# yes, we want to build pmac stuff
-CONFIG_PMAC = y
-endif
-
 ifeq ($(CONFIG_PPC64),y)
 MSIZE=.64
 else
 MSIZE=
 endif
 
+ifeq ($(CONFIG_ALL_PPC),y)
+# yes, we want to build pmac stuff
+CONFIG_PMAC = y
+endif
+
 ifeq ($(CONFIG_SMP),y)
 TFTPIMAGE=/tftpboot/zImage.pmac.smp$(MSIZE)
 else
@@ -39,39 +39,81 @@
 hack-coff: hack-coff.c
 	$(HOSTCC) $(HOSTCFLAGS) -o hack-coff hack-coff.c
 
+znetboot: vmlinux.coff zImage vmlinux.elf
+	cp vmlinux.coff $(TFTPIMAGE)
+	cp vmlinux.elf $(TFTPIMAGE).elf
+
+znetboot.initrd: vmlinux.coff.initrd vmlinux.elf.initrd
+	cp vmlinux.coff.initrd $(TFTPIMAGE)
+	cp vmlinux.elf.initrd $(TFTPIMAGE).elf
+
 floppy: zImage
 #	mount -t hfs /dev/fd0 /mnt
 #	cp vmlinux.coff /mnt
 #	umount /mnt
 
-znetboot: vmlinux.coff
-	cp vmlinux.coff $(TFTPIMAGE)
+coffboot: $(COFFOBJS) no_initrd.o ld.script
+	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) no_initrd.o $(LIBS)
 
-znetboot.initrd: vmlinux.coff.initrd
-	cp vmlinux.coff.initrd $(TFTPIMAGE)
+coffboot.initrd: $(COFFOBJS) initrd.o ld.script
+	$(LD) -o $@ $(COFF_LD_ARGS) $(COFFOBJS) initrd.o $(LIBS)
 
-coffboot: $(OBJS) ld.script
-	$(LD) -o coffboot $(LD_ARGS) $(OBJS) $(LIBS)
+piggyback: piggyback.c
+	$(HOSTCC) $(HOSTCFLAGS) -DKERNELBASE=$(KERNELBASE) -o piggyback piggyback.c
 
-zImage: vmlinux.coff
+mknote: mknote.c
+	$(HOSTCC) $(HOSTCFLAGS) -o mknote mknote.c
 
-zImage.initrd: vmlinux.coff.initrd
+image.o: piggyback vmlinux.gz
+	./piggyback image < vmlinux.gz | $(AS) -o image.o
 
-vmlinux.coff: coffboot hack-coff vmlinux.gz
+initrd.o: ramdisk.image.gz piggyback
+	./piggyback initrd < ramdisk.image.gz | $(AS) -o initrd.o
+
+vmlinux.coff: coffboot hack-coff
 	$(OBJCOPY) $(OBJCOPY_ARGS) coffboot $@
 	./hack-coff $@
 	ln -sf vmlinux.coff zImage
 
-vmlinux.coff.initrd: coffboot hack-coff vmlinux.gz ramdisk.image.gz
-	$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=initrd=ramdisk.image.gz \
-		coffboot $@
+vmlinux.coff.initrd: coffboot.initrd hack-coff
+	$(OBJCOPY) $(OBJCOPY_ARGS) coffboot.initrd $@
+	./hack-coff $@
+
+vmlinux.elf: $(CHRPOBJS) no_initrd.o mknote
+	$(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) no_initrd.o $(LIBS)
+	./mknote > note
+	$(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+vmlinux.elf.initrd: $(CHRPOBJS) initrd.o mknote
+	$(LD) $(CHRP_LD_ARGS) -o $@ $(CHRPOBJS) initrd.o $(LIBS)
+	./mknote > note
+	$(OBJCOPY) $@ $@ --add-section=.note=note -R .comment
+
+micoffboot: dummy.o
+	$(LD) -o $@ $(COFF_LD_ARGS) dummy.o $(LIBS)
+
+miboot.image: micoffboot hack-coff vmlinux.gz
+	$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=vmlinux.gz micoffboot $@
 	./hack-coff $@
 
+miboot.image.initrd: micoffboot hack-coff vmlinux.gz ramdisk.image.gz
+	$(OBJCOPY) $(OBJCOPY_ARGS) --add-section=image=vmlinux.gz \
+	--add-section=initrd=ramdisk.image.gz micoffboot $@
+	./hack-coff $@
+
+zImage: vmlinux.coff vmlinux.elf miboot.image
+
+zImage.initrd: vmlinux.coff.initrd vmlinux.elf.initrd miboot.image.initrd
+
 else
 znetboot: vmlinux.gz
 
 znetboot.initrd: vmlinux.gz
 
+miboot.image: vmlinux.gz
+
+miboot.image.initrd: vmlinux.gz
+
 coffboot: vmlinux.gz
 
 zImage: vmlinux.gz
@@ -92,5 +134,7 @@
 
 clean:
 	rm -f hack-coff coffboot zImage vmlinux.coff vmlinux.gz
+	rm -f mknote piggyback vmlinux.elf note
+	rm -f micoffboot miboot.image
 
 fastdep:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/chrpmain.c linux.17p18/arch/ppc/coffboot/chrpmain.c
--- linux.vanilla/arch/ppc/coffboot/chrpmain.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/chrpmain.c	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,209 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+void gunzip(void *, int, unsigned char *, int *);
+void stop_imac_ethernet(void);
+void stop_imac_usb(void);
+
+#define get_16be(x)	(*(unsigned short *)(x))
+#define get_32be(x)	(*(unsigned *)(x))
+
+#define RAM_START	0x00000000
+#define RAM_END		(8<<20)
+
+#define PROG_START	0x00010000
+
+char *avail_ram;
+char *end_avail;
+
+extern char _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+    extern char _start;
+    
+    printf("chrpboot starting: loaded at 0x%x\n", &_start);
+    if (initrd_len) {
+	initrd_size = initrd_len;
+	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+	       initrd_start, initrd_data, initrd_size);
+	memcpy((char *)initrd_start, initrd_data, initrd_size);
+    }
+    im = image_data;
+    len = image_len;
+    /* claim 3MB starting at PROG_START */
+    claim(PROG_START, 3 << 20, 0);
+    dst = (void *) PROG_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	/* claim 512kB for scratch space */
+	avail_ram = (char *) claim(0, 512 << 10, 0x10);
+	end_avail = avail_ram + (512 << 10);
+	printf("avail_ram = %x\n", avail_ram);
+	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	gunzip(dst, 3 << 20, im, &len);
+	printf("done %u bytes\n", len);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    stop_imac_ethernet();
+    stop_imac_usb();
+
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+    (*(void (*)())sa)(a1, a2, prom);
+
+    printf("returned?\n");
+
+    pause();
+}
+
+#define eieio()	asm volatile("eieio");
+
+void stop_imac_ethernet(void)
+{
+    void *macio, *enet;
+    unsigned int macio_addr[5], enet_reg[6];
+    int len;
+    volatile unsigned int *dbdma;
+
+    macio = finddevice("/pci/mac-io");
+    enet = finddevice("/pci/mac-io/ethernet");
+    if (macio == NULL || enet == NULL)
+	return;
+    len = getprop(macio, "assigned-addresses", macio_addr, sizeof(macio_addr));
+    if (len != sizeof(macio_addr))
+	return;
+    len = getprop(enet, "reg", enet_reg, sizeof(enet_reg));
+    if (len != sizeof(enet_reg))
+	return;
+    printf("macio base %x, dma at %x & %x\n",
+	   macio_addr[2], enet_reg[2], enet_reg[4]);
+
+    /* hope this is mapped... */
+    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[2]);
+    *dbdma = 0x80;	/* clear the RUN bit */
+    eieio();
+    dbdma = (volatile unsigned int *) (macio_addr[2] + enet_reg[4]);
+    *dbdma = 0x80;	/* clear the RUN bit */
+    eieio();
+}
+
+void stop_imac_usb(void)
+{
+    void *usb;
+    unsigned int usb_addr[5];
+    int len;
+    volatile unsigned int *usb_ctrl;
+
+    usb = finddevice("/pci/usb");
+    if (usb == NULL)
+	return;
+    len = getprop(usb, "assigned-addresses", usb_addr, sizeof(usb_addr));
+    if (len != sizeof(usb_addr))
+	return;
+    printf("usb base %x\n", usb_addr[2]);
+
+    usb_ctrl = (volatile unsigned int *) (usb_addr[2] + 8);
+    *usb_ctrl = 0x01000000;	/* cpu_to_le32(1) */
+    eieio();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = (size + 7) & -8;
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n");
+	pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	printf("bad gzipped data\n");
+	exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+	i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & COMMENT) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & HEAD_CRC) != 0)
+	i += 2;
+    if (i >= *lenp) {
+	printf("gunzip: ran out of data in header\n");
+	exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+	printf("inflateInit2 returned %d\n", r);
+	exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+	printf("inflate returned %d msg: %s\n", r, s.msg);
+	exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/coffcrt0.S linux.17p18/arch/ppc/coffboot/coffcrt0.S
--- linux.vanilla/arch/ppc/coffboot/coffcrt0.S	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/coffcrt0.S	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+	.text
+	.globl	_start
+_start:
+	.long	__start,0,0
+
+	.globl	__start
+__start:
+	lis	9,_start@h
+	lis	8,_etext@ha
+	addi	8,8,_etext@l
+1:	dcbf	0,9
+	icbi	0,9
+	addi	9,9,0x20
+	cmplwi	0,9,8
+	blt	1b
+	b	start
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/coffmain.c linux.17p18/arch/ppc/coffboot/coffmain.c
--- linux.vanilla/arch/ppc/coffboot/coffmain.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/coffmain.c	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,157 @@
+/*
+ * Copyright (C) Paul Mackerras 1997.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+#include "nonstdio.h"
+#include "zlib.h"
+
+extern void *finddevice(const char *);
+extern int getprop(void *, const char *, void *, int);
+extern char *claim(unsigned, unsigned, unsigned);
+void gunzip(void *, int, unsigned char *, int *);
+
+#define get_16be(x)	(*(unsigned short *)(x))
+#define get_32be(x)	(*(unsigned *)(x))
+
+#define RAM_START	0xc0000000
+#define PROG_START	RAM_START
+#define RAM_END		(RAM_START + 0x800000)	/* only 8M mapped with BATs */
+
+char *avail_ram;
+char *end_avail;
+
+extern char _start[], _end[];
+extern char image_data[];
+extern int image_len;
+extern char initrd_data[];
+extern int initrd_len;
+
+
+boot(int a1, int a2, void *prom)
+{
+    int ns, oh, i;
+    unsigned sa, len;
+    void *dst;
+    unsigned char *im;
+    unsigned initrd_start, initrd_size;
+    
+    printf("coffboot starting: loaded at 0x%x\n", _start);
+    setup_bats(RAM_START);
+    if (initrd_len) {
+	initrd_size = initrd_len;
+	initrd_start = (RAM_END - initrd_size) & ~0xFFF;
+	a1 = initrd_start;
+	a2 = initrd_size;
+	claim(initrd_start - RAM_START, RAM_END - initrd_start, 0);
+	printf("initial ramdisk moving 0x%x <- 0x%x (%x bytes)\n",
+	       initrd_start, initrd_data, initrd_size);
+	memcpy((char *)initrd_start, initrd_data, initrd_size);
+    }
+    im = image_data;
+    len = image_len;
+    /* claim 3MB starting at 0 */
+    claim(0, 3 << 20, 0);
+    dst = (void *) RAM_START;
+    if (im[0] == 0x1f && im[1] == 0x8b) {
+	/* claim 512kB for scratch space */
+	avail_ram = claim(0, 512 << 10, 0x10) + RAM_START;
+	end_avail = avail_ram + (512 << 10);
+	printf("avail_ram = %x\n", avail_ram);
+	printf("gunzipping (0x%x <- 0x%x:0x%0x)...", dst, im, im+len);
+	gunzip(dst, 3 << 20, im, &len);
+	printf("done %u bytes\n", len);
+    } else {
+	memmove(dst, im, len);
+    }
+
+    flush_cache(dst, len);
+    
+    sa = (unsigned long)PROG_START;
+    printf("start address = 0x%x\n", sa);
+
+#if 0
+    pause();
+#endif
+    (*(void (*)())sa)(a1, a2, prom);
+
+    printf("returned?\n");
+
+    pause();
+}
+
+void *zalloc(void *x, unsigned items, unsigned size)
+{
+    void *p = avail_ram;
+
+    size *= items;
+    size = (size + 7) & -8;
+    avail_ram += size;
+    if (avail_ram > end_avail) {
+	printf("oops... out of memory\n");
+	pause();
+    }
+    return p;
+}
+
+void zfree(void *x, void *addr, unsigned nb)
+{
+}
+
+#define HEAD_CRC	2
+#define EXTRA_FIELD	4
+#define ORIG_NAME	8
+#define COMMENT		0x10
+#define RESERVED	0xe0
+
+#define DEFLATED	8
+
+void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
+{
+    z_stream s;
+    int r, i, flags;
+
+    /* skip header */
+    i = 10;
+    flags = src[3];
+    if (src[2] != DEFLATED || (flags & RESERVED) != 0) {
+	printf("bad gzipped data\n");
+	exit();
+    }
+    if ((flags & EXTRA_FIELD) != 0)
+	i = 12 + src[10] + (src[11] << 8);
+    if ((flags & ORIG_NAME) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & COMMENT) != 0)
+	while (src[i++] != 0)
+	    ;
+    if ((flags & HEAD_CRC) != 0)
+	i += 2;
+    if (i >= *lenp) {
+	printf("gunzip: ran out of data in header\n");
+	exit();
+    }
+
+    s.zalloc = zalloc;
+    s.zfree = zfree;
+    r = inflateInit2(&s, -MAX_WBITS);
+    if (r != Z_OK) {
+	printf("inflateInit2 returned %d\n", r);
+	exit();
+    }
+    s.next_in = src + i;
+    s.avail_in = *lenp - i;
+    s.next_out = dst;
+    s.avail_out = dstlen;
+    r = inflate(&s, Z_FINISH);
+    if (r != Z_OK && r != Z_STREAM_END) {
+	printf("inflate returned %d msg: %s\n", r, s.msg);
+	exit();
+    }
+    *lenp = s.next_out - (unsigned char *) dst;
+    inflateEnd(&s);
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/crt0.S linux.17p18/arch/ppc/coffboot/crt0.S
--- linux.vanilla/arch/ppc/coffboot/crt0.S	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/coffboot/crt0.S	Tue Aug  1 07:59:04 2000
@@ -9,10 +9,6 @@
 	.text
 	.globl	_start
 _start:
-	.long	__start,0,0
-
-	.globl	__start
-__start:
 	lis	9,_start@h
 	lis	8,_etext@ha
 	addi	8,8,_etext@l
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/dummy.c linux.17p18/arch/ppc/coffboot/dummy.c
--- linux.vanilla/arch/ppc/coffboot/dummy.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/dummy.c	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,4 @@
+int main(void)
+{
+	return 0;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/misc.S linux.17p18/arch/ppc/coffboot/misc.S
--- linux.vanilla/arch/ppc/coffboot/misc.S	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/coffboot/misc.S	Tue Aug  1 07:59:04 2000
@@ -14,23 +14,26 @@
  */
 	.globl	setup_bats
 setup_bats:
-	mr	4,3
-	mfpvr	3
-	rlwinm	3,3,16,16,31		/* r3 = 1 for 601, 4 for 604 */
-	cmpi	0,3,1
+	mfpvr	5
+	rlwinm	5,5,16,16,31		/* r3 = 1 for 601, 4 for 604 */
+	cmpi	0,5,1
+	li	0,0
 	bne	4f
-	ori	4,4,4			/* set up BAT registers for 601 */
-	li	5,0x7f
-	mtibatu	3,4
-	mtibatl	3,5
-	isync
-	blr
-4:	ori	4,4,0xfe		/* set up BAT registers for 604 */
-	li	5,2
-	mtdbatl	3,5
-	mtdbatu	3,4
-	mtibatl	3,5
-	mtibatu	3,4
+	mtibatl	3,0			/* invalidate BAT first */
+	ori	3,3,4			/* set up BAT registers for 601 */
+	li	4,0x7f
+	mtibatu	3,3
+	mtibatl	3,4
+	b	5f
+4:	mtdbatu	3,0			/* invalidate BATs first */
+	mtibatu	3,0
+	ori	3,3,0xff		/* set up BAT registers for 604 */
+	li	4,2
+	mtdbatl	3,4
+	mtdbatu	3,3
+	mtibatl	3,4
+	mtibatu	3,3
+5:	sync
 	isync
 	blr
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/mknote.c linux.17p18/arch/ppc/coffboot/mknote.c
--- linux.vanilla/arch/ppc/coffboot/mknote.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/mknote.c	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) Cort Dougan 1999.
+ *
+ * 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.
+ *
+ * Generate a note section as per the CHRP specification.
+ *
+ */
+
+#include <stdio.h>
+
+#define PL(x) printf("%c%c%c%c", ((x)>>24)&0xff, ((x)>>16)&0xff, ((x)>>8)&0xff, (x)&0xff );
+
+int main(void)
+{
+/* header */
+	/* namesz */
+	PL(strlen("PowerPC")+1);
+	/* descrsz */
+	PL(6*4);
+	/* type */
+	PL(0x1275);
+	/* name */
+	printf("PowerPC"); printf("%c", 0);
+	
+/* descriptor */
+	/* real-mode */
+	PL(0xffffffff);
+	/* real-base */
+	PL(0x00c00000);
+	/* real-size */
+	PL(0xffffffff);
+	/* virt-base */
+	PL(0xffffffff);
+	/* virt-size */
+	PL(0xffffffff);
+	/* load-base */
+	PL(0x4000);
+	return 0;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/no_initrd.c linux.17p18/arch/ppc/coffboot/no_initrd.c
--- linux.vanilla/arch/ppc/coffboot/no_initrd.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/no_initrd.c	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,2 @@
+char initrd_data[1];
+int initrd_len = 0;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/piggyback.c linux.17p18/arch/ppc/coffboot/piggyback.c
--- linux.vanilla/arch/ppc/coffboot/piggyback.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/arch/ppc/coffboot/piggyback.c	Tue Aug  1 07:59:04 2000
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+extern long ce_exec_config[];
+
+main(int argc, char *argv[])
+{
+	int i, cnt, pos, len;
+	unsigned int cksum, val;
+	unsigned char *lp;
+	unsigned char buf[8192];
+	if (argc != 2)
+	{
+		fprintf(stderr, "usage: %s name <in-file >out-file\n",
+			argv[0]);
+		exit(1);
+	}
+	fprintf(stdout, "#\n");
+	fprintf(stdout, "# Miscellaneous data structures:\n");
+	fprintf(stdout, "# WARNING - this file is automatically generated!\n");
+	fprintf(stdout, "#\n");
+	fprintf(stdout, "\n");
+	fprintf(stdout, "\t.data\n");
+	fprintf(stdout, "\t.globl %s_data\n", argv[1]);
+	fprintf(stdout, "%s_data:\n", argv[1]);
+	pos = 0;
+	cksum = 0;
+	while ((len = read(0, buf, sizeof(buf))) > 0)
+	{
+		cnt = 0;
+		lp = (unsigned char *)buf;
+		len = (len + 3) & ~3;  /* Round up to longwords */
+		for (i = 0;  i < len;  i += 4)
+		{
+			if (cnt == 0)
+			{
+				fprintf(stdout, "\t.long\t");
+			}
+			fprintf(stdout, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+			val = *(unsigned long *)lp;
+			cksum ^= val;
+			lp += 4;
+			if (++cnt == 4)
+			{
+				cnt = 0;
+				fprintf(stdout, " # %x \n", pos+i-12);
+				fflush(stdout);
+			} else
+			{
+				fprintf(stdout, ",");
+			}
+		}
+		if (cnt)
+		{
+			fprintf(stdout, "0\n");
+		}
+		pos += len;
+	}
+	fprintf(stdout, "\t.globl %s_len\n", argv[1]);
+	fprintf(stdout, "%s_len:\t.long\t0x%x\n", argv[1], pos);
+	fflush(stdout);
+	fclose(stdout);
+	fprintf(stderr, "cksum = %x\n", cksum);
+	exit(0);
+}
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/coffboot/start.c linux.17p18/arch/ppc/coffboot/start.c
--- linux.vanilla/arch/ppc/coffboot/start.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/coffboot/start.c	Tue Aug  1 07:59:04 2000
@@ -33,7 +33,7 @@
     if (getprop(chosen_handle, "stdin", &stdin, sizeof(stdin)) != 4)
 	exit();
 
-    coffboot(a1, a2, promptr);
+    boot(a1, a2, promptr);
     for (;;)
 	exit();
 }
@@ -62,6 +62,25 @@
     return args.actual;
 }
 
+int writestring(void *f, char *ptr, int nb)
+{
+	int w = 0, i;
+	char *ret = "\r";
+
+	for (i = 0; i < nb; ++i) {
+		if (ptr[i] == '\n') {
+			if (i > w) {
+				write(f, ptr + w, i - w);
+				w = i;
+			}
+			write(f, ret, 1);
+		}
+	}
+	if (w < nb)
+		write(f, ptr + w, nb - w);
+	return nb;
+}
+
 int
 read(void *handle, void *ptr, int nb)
 {
@@ -130,6 +149,29 @@
     return args.phandle;
 }
 
+void *
+claim(unsigned int virt, unsigned int size, unsigned int align)
+{
+    struct prom_args {
+	char *service;
+	int nargs;
+	int nret;
+	unsigned int virt;
+	unsigned int size;
+	unsigned int align;
+	void *ret;
+    } args;
+
+    args.service = "claim";
+    args.nargs = 3;
+    args.nret = 1;
+    args.virt = virt;
+    args.size = size;
+    args.align = align;
+    (*prom)(&args);
+    return args.ret;
+}
+
 int
 getprop(void *phandle, const char *name, void *buf, int buflen)
 {
@@ -161,9 +203,7 @@
 {
     char ch = c;
 
-    if (c == '\n')
-	putc('\r', f);
-    return write(f, &ch, 1) == 1? c: -1;
+    return writestring(f, &ch, 1) == 1? c: -1;
 }
 
 int
@@ -177,7 +217,7 @@
 {
     int n = strlen(str);
 
-    return write(f, str, n) == n? 0: -1;
+    return writestring(f, str, n) == n? 0: -1;
 }
 
 int
@@ -190,7 +230,7 @@
 	case 1:
 	    return ch;
 	case -1:
-	    printk("read(stdin) returned -1\r\n");
+	    printk("read(stdin) returned -1\n");
 	    return -1;
 	}
     }
@@ -264,7 +304,7 @@
 	va_start(args, fmt);
 	n = vsprintf(sprint_buf, fmt, args);
 	va_end(args);
-	write(stdout, sprint_buf, n);
+	writestring(stdout, sprint_buf, n);
 }
 
 int
@@ -276,6 +316,6 @@
 	va_start(args, fmt);
 	n = vsprintf(sprint_buf, fmt, args);
 	va_end(args);
-	write(stdout, sprint_buf, n);
+	writestring(stdout, sprint_buf, n);
 	return n;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/common_defconfig linux.17p18/arch/ppc/common_defconfig
--- linux.vanilla/arch/ppc/common_defconfig	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/common_defconfig	Tue Aug  1 07:59:05 2000
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 
 #
@@ -16,6 +16,7 @@
 # CONFIG_GEMINI is not set
 # CONFIG_MBX is not set
 # CONFIG_SMP is not set
+CONFIG_ALTIVEC=y
 CONFIG_6xx=y
 
 #
@@ -23,7 +24,7 @@
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
 CONFIG_PCI=y
 # CONFIG_PCI_QUIRKS is not set
@@ -34,17 +35,17 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=y
 # CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
 CONFIG_VGA_CONSOLE=y
 CONFIG_FB=y
-CONFIG_FB_COMPAT_XPMAC=y
 CONFIG_PMAC_PBOOK=y
 CONFIG_MAC_KEYBOARD=y
 CONFIG_MAC_FLOPPY=y
 CONFIG_MAC_SERIAL=y
-# CONFIG_SERIAL_CONSOLE is not set
+# CONFIG_PPC_RTC is not set
 CONFIG_ADBMOUSE=y
 CONFIG_PROC_DEVICETREE=y
 # CONFIG_TOTALMP is not set
@@ -62,6 +63,10 @@
 #
 CONFIG_BLK_DEV_FD=y
 CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
 # CONFIG_BLK_DEV_HD_IDE is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_BLK_DEV_IDECD=y
@@ -70,21 +75,35 @@
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_VIA82C586 is not set
+CONFIG_BLK_DEV_CMD646=y
+# CONFIG_BLK_DEV_CS5530 is not set
+# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDE_PMAC=y
 CONFIG_BLK_DEV_IDEDMA_PMAC=y
 CONFIG_BLK_DEV_IDEDMA=y
 CONFIG_PMAC_IDEDMA_AUTO=y
 # CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_MD is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=4096
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_PARIDE_PARPORT=y
+CONFIG_PARIDE_PARPORT=m
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -96,22 +115,44 @@
 CONFIG_NETLINK=y
 # CONFIG_RTNETLINK is not set
 # CONFIG_NETLINK_DEV is not set
-# CONFIG_FIREWALL is not set
+CONFIG_FIREWALL=y
 # CONFIG_FILTER is not set
 CONFIG_UNIX=y
 CONFIG_INET=y
 CONFIG_IP_MULTICAST=y
 # CONFIG_IP_ADVANCED_ROUTER is not set
 # CONFIG_IP_PNP is not set
+CONFIG_IP_FIREWALL=y
+# CONFIG_IP_FIREWALL_NETLINK is not set
+CONFIG_IP_TRANSPARENT_PROXY=y
+CONFIG_IP_MASQUERADE=y
+
+#
+# Protocol-specific masquerading support will be built as modules.
+#
+# CONFIG_IP_MASQUERADE_ICMP is not set
+
+#
+# Protocol-specific masquerading support will be built as modules.
+#
+# CONFIG_IP_MASQUERADE_MOD is not set
 # CONFIG_IP_ROUTER is not set
 # CONFIG_NET_IPIP is not set
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
 CONFIG_IP_ALIAS=y
 CONFIG_SYN_COOKIES=y
+
+#
+# (it is safe to leave these untouched)
+#
 CONFIG_INET_RARP=y
 CONFIG_SKB_LARGE=y
 # CONFIG_IPV6 is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
 # CONFIG_X25 is not set
@@ -133,11 +174,19 @@
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
@@ -145,6 +194,7 @@
 #
 # SCSI low-level drivers
 #
+# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
 # CONFIG_SCSI_7000FASST is not set
 # CONFIG_SCSI_ACARD is not set
 # CONFIG_SCSI_AHA152X is not set
@@ -170,11 +220,13 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_SYM53C416 is not set
 # CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_NCR53C8XX=y
 CONFIG_SCSI_SYM53C8XX=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
@@ -182,7 +234,7 @@
 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT=y
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -210,6 +262,7 @@
 #
 # CONFIG_ARCNET is not set
 # CONFIG_DUMMY is not set
+# CONFIG_BONDING is not set
 # CONFIG_EQUALIZER is not set
 # CONFIG_ETHERTAP is not set
 # CONFIG_NET_SB1000 is not set
@@ -219,24 +272,25 @@
 #
 CONFIG_NET_ETHERNET=y
 CONFIG_MACE=y
+# CONFIG_MACE_AAUI_PORT is not set
 CONFIG_BMAC=y
+CONFIG_GMAC=y
 # CONFIG_NCR885E is not set
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_RTL8139 is not set
-# CONFIG_YELLOWFIN is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_EISA=y
 CONFIG_PCNET32=y
-# CONFIG_ACENIC is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
 # CONFIG_DM9102 is not set
 CONFIG_DE4X5=y
 # CONFIG_DEC_ELCP is not set
+# CONFIG_DEC_ELCP_OLD is not set
 # CONFIG_DGRS is not set
 # CONFIG_EEXPRESS_PRO100 is not set
 # CONFIG_LNE390 is not set
@@ -249,6 +303,14 @@
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
 # CONFIG_NET_POCKET is not set
+
+#
+# Ethernet (1000 Mbit)
+#
+# CONFIG_ACENIC is not set
+# CONFIG_HAMACHI is not set
+# CONFIG_YELLOWFIN is not set
+# CONFIG_SK98LIN is not set
 # CONFIG_FDDI is not set
 # CONFIG_HIPPI is not set
 
@@ -258,7 +320,12 @@
 # CONFIG_LTPC is not set
 # CONFIG_COPS is not set
 # CONFIG_IPDDP is not set
+# CONFIG_PLIP is not set
 CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
 # CONFIG_SLIP is not set
 # CONFIG_NET_RADIO is not set
 
@@ -276,7 +343,10 @@
 # CONFIG_HOSTESS_SV11 is not set
 # CONFIG_COSA is not set
 # CONFIG_SEALEVEL_4021 is not set
+# CONFIG_SYNCLINK_SYNCPPP is not set
+# CONFIG_LANMEDIA is not set
 # CONFIG_COMX is not set
+# CONFIG_HDLC is not set
 # CONFIG_DLCI is not set
 # CONFIG_SBNI is not set
 
@@ -286,6 +356,11 @@
 # CONFIG_HAMRADIO is not set
 
 #
+# IrDA (infrared) support
+#
+# CONFIG_IRDA is not set
+
+#
 # ISDN subsystem
 #
 # CONFIG_ISDN is not set
@@ -300,6 +375,7 @@
 #
 CONFIG_DUMMY_CONSOLE=y
 # CONFIG_FB_PM2 is not set
+CONFIG_FB_ATY=y
 CONFIG_FB_OF=y
 CONFIG_FB_CONTROL=y
 CONFIG_FB_PLATINUM=y
@@ -307,12 +383,12 @@
 CONFIG_FB_IMSTT=y
 CONFIG_FB_CT65550=y
 # CONFIG_FB_S3TRIO is not set
+CONFIG_FB_COMPAT_XPMAC=y
 CONFIG_FB_MATROX=y
-# CONFIG_FB_MATROX_MILLENIUM is not set
+CONFIG_FB_MATROX_MILLENIUM=y
 CONFIG_FB_MATROX_MYSTIQUE=y
 CONFIG_FB_MATROX_G100=y
-# CONFIG_FB_MATROX_MULTIHEAD is not set
-CONFIG_FB_ATY=y
+CONFIG_FB_MATROX_MULTIHEAD=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
 CONFIG_FBCON_CFB8=y
@@ -339,6 +415,7 @@
 # CONFIG_SERIAL_NONSTANDARD is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
+# CONFIG_PRINTER is not set
 CONFIG_MOUSE=y
 
 #
@@ -350,6 +427,11 @@
 CONFIG_PSMOUSE=y
 # CONFIG_82C710_MOUSE is not set
 # CONFIG_PC110_PAD is not set
+
+#
+# Joysticks
+#
+# CONFIG_JOYSTICK is not set
 # CONFIG_QIC02_TAPE is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_NVRAM=y
@@ -359,20 +441,16 @@
 # Video For Linux
 #
 # CONFIG_VIDEO_DEV is not set
-
-#
-# Joystick support
-#
-# CONFIG_JOYSTICK is not set
 # CONFIG_DTLK is not set
 
 #
 # Ftape, the floppy tape device driver
 #
 # CONFIG_FTAPE is not set
+# CONFIG_TOSHIBA is not set
 
 #
-# USB drivers - not for the faint of heart
+# Support for USB
 #
 # CONFIG_USB is not set
 
@@ -384,10 +462,10 @@
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 CONFIG_HFS_FS=y
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
 # CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
+CONFIG_VFAT_FS=m
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
@@ -427,6 +505,7 @@
 #
 # Native Language Support
 #
+CONFIG_NLS_DEFAULT="cp437"
 CONFIG_NLS_CODEPAGE_437=y
 # CONFIG_NLS_CODEPAGE_737 is not set
 # CONFIG_NLS_CODEPAGE_775 is not set
@@ -443,6 +522,10 @@
 # CONFIG_NLS_CODEPAGE_866 is not set
 # CONFIG_NLS_CODEPAGE_869 is not set
 # CONFIG_NLS_CODEPAGE_874 is not set
+# CONFIG_NLS_CODEPAGE_932 is not set
+# CONFIG_NLS_CODEPAGE_936 is not set
+# CONFIG_NLS_CODEPAGE_949 is not set
+# CONFIG_NLS_CODEPAGE_950 is not set
 # CONFIG_NLS_ISO8859_1 is not set
 # CONFIG_NLS_ISO8859_2 is not set
 # CONFIG_NLS_ISO8859_3 is not set
@@ -453,55 +536,17 @@
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_ISO8859_9 is not set
 # CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 
 #
 # Sound
 #
-CONFIG_SOUND=y
-CONFIG_DMASOUND=y
-# CONFIG_SOUND_CMPCI is not set
-# CONFIG_SOUND_ES1370 is not set
-# CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_MAESTRO is not set
-# CONFIG_SOUND_ESSSOLO1 is not set
-# CONFIG_SOUND_SONICVIBES is not set
-# CONFIG_SOUND_MSNDCLAS is not set
-# CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-CONFIG_SOUND_CS4232=m
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_NM256 is not set
-
-#
-# Additional low level sound drivers
-#
-# CONFIG_LOWLEVEL_SOUND is not set
+# CONFIG_SOUND is not set
 
 #
 # Kernel hacking
 #
-# CONFIG_MAGIC_SYSRQ is not set
+CONFIG_MAGIC_SYSRQ=y
 # CONFIG_KGDB is not set
 # CONFIG_XMON is not set
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/config.in linux.17p18/arch/ppc/config.in
--- linux.vanilla/arch/ppc/config.in	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/ppc/config.in	Tue Aug  1 07:59:05 2000
@@ -8,7 +8,7 @@
 comment 'Platform support'
 define_bool CONFIG_PPC y
 choice 'Processor type' \
-	"6xx/7xx		CONFIG_6xx \
+	"6xx/7xx/7400		CONFIG_6xx \
 	 860/821		CONFIG_8xx" 6xx/7xx
 
 choice 'Machine Type' \
@@ -21,6 +21,11 @@
 	 MBX		CONFIG_MBX" PowerMac
 
 bool 'Symmetric multi-processing support' CONFIG_SMP
+
+if [ "$CONFIG_6xx" = "y" ]; then
+  bool 'Altivec (G4) support' CONFIG_ALTIVEC
+fi
+
 if [ "$CONFIG_ALL_PPC" != "y" ];then
   define_bool CONFIG_MACH_SPECIFIC y
 fi
@@ -77,9 +82,6 @@
 
 bool 'Support for VGA Console' CONFIG_VGA_CONSOLE
 bool 'Support for frame buffer devices' CONFIG_FB
-if [ "$CONFIG_FB" = "y" ]; then
-  bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
-fi
 
 bool 'Power management support for Apple PowerBooks' CONFIG_PMAC_PBOOK
 bool 'Support for PowerMac keyboard' CONFIG_MAC_KEYBOARD
@@ -88,6 +90,7 @@
 if [ "$CONFIG_MAC_SERIAL" = "y" ]; then
    bool '   Support for console on serial port' CONFIG_SERIAL_CONSOLE
 fi
+tristate 'Support for /dev/rtc' CONFIG_PPC_RTC
 bool 'Support for PowerMac ADB mouse' CONFIG_ADBMOUSE
 bool 'Support for Open Firmware device tree in /proc' CONFIG_PROC_DEVICETREE
 bool 'Support for TotalImpact TotalMP' CONFIG_TOTALMP
@@ -151,6 +154,8 @@
 fi
 
 source net/ax25/Config.in
+
+source net/irda/Config.in
 
 mainmenu_option next_comment
 comment 'ISDN subsystem'
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/defconfig linux.17p18/arch/ppc/defconfig
--- linux.vanilla/arch/ppc/defconfig	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/defconfig	Tue Aug  1 07:59:05 2000
@@ -1,5 +1,5 @@
 #
-# Automatically generated by make menuconfig: don't edit
+# Automatically generated make config: don't edit
 #
 
 #
@@ -7,15 +7,16 @@
 #
 CONFIG_PPC=y
 CONFIG_6xx=y
+# CONFIG_PPC64 is not set
 # CONFIG_8xx is not set
-# CONFIG_PMAC is not set
+CONFIG_PMAC=y
 # CONFIG_PREP is not set
 # CONFIG_CHRP is not set
-CONFIG_ALL_PPC=y
+# CONFIG_ALL_PPC is not set
 # CONFIG_APUS is not set
-# CONFIG_GEMINI is not set
 # CONFIG_MBX is not set
 # CONFIG_SMP is not set
+CONFIG_MACH_SPECIFIC=y
 CONFIG_6xx=y
 
 #
@@ -23,7 +24,7 @@
 #
 CONFIG_EXPERIMENTAL=y
 CONFIG_MODULES=y
-CONFIG_MODVERSIONS=y
+# CONFIG_MODVERSIONS is not set
 CONFIG_KMOD=y
 CONFIG_PCI=y
 # CONFIG_PCI_QUIRKS is not set
@@ -34,10 +35,11 @@
 # CONFIG_BSD_PROCESS_ACCT is not set
 CONFIG_BINFMT_ELF=y
 CONFIG_KERNEL_ELF=y
-# CONFIG_BINFMT_MISC is not set
+CONFIG_BINFMT_MISC=m
 # CONFIG_BINFMT_JAVA is not set
-# CONFIG_PARPORT is not set
-CONFIG_VGA_CONSOLE=y
+CONFIG_PARPORT=m
+# CONFIG_PARPORT_PC is not set
+# CONFIG_VGA_CONSOLE is not set
 CONFIG_FB=y
 CONFIG_FB_COMPAT_XPMAC=y
 CONFIG_PMAC_PBOOK=y
@@ -50,7 +52,6 @@
 # CONFIG_TOTALMP is not set
 CONFIG_BOOTX_TEXT=y
 # CONFIG_MOTOROLA_HOTSWAP is not set
-# CONFIG_CMDLINE_BOOL is not set
 
 #
 # Plug and Play support
@@ -60,8 +61,12 @@
 #
 # Block devices
 #
-CONFIG_BLK_DEV_FD=y
+# CONFIG_BLK_DEV_FD is not set
 CONFIG_BLK_DEV_IDE=y
+
+#
+# Please see Documentation/ide.txt for help/info on IDE drives
+#
 # CONFIG_BLK_DEV_HD_IDE is not set
 CONFIG_BLK_DEV_IDEDISK=y
 CONFIG_BLK_DEV_IDECD=y
@@ -70,13 +75,25 @@
 # CONFIG_BLK_DEV_IDESCSI is not set
 # CONFIG_BLK_DEV_CMD640 is not set
 # CONFIG_BLK_DEV_RZ1000 is not set
-# CONFIG_BLK_DEV_IDEPCI is not set
-CONFIG_BLK_DEV_SL82C105=y
+CONFIG_BLK_DEV_IDEPCI=y
+CONFIG_BLK_DEV_IDEDMA=y
+# CONFIG_BLK_DEV_OFFBOARD is not set
+CONFIG_IDEDMA_AUTO=y
+# CONFIG_BLK_DEV_OPTI621 is not set
+# CONFIG_BLK_DEV_TRM290 is not set
+# CONFIG_BLK_DEV_NS87415 is not set
+# CONFIG_BLK_DEV_VIA82C586 is not set
+CONFIG_BLK_DEV_CMD646=y
+# CONFIG_BLK_DEV_SL82C105 is not set
 CONFIG_BLK_DEV_IDE_PMAC=y
 CONFIG_BLK_DEV_IDEDMA_PMAC=y
 CONFIG_BLK_DEV_IDEDMA=y
 CONFIG_PMAC_IDEDMA_AUTO=y
 # CONFIG_IDE_CHIPSETS is not set
+
+#
+# Additional Block Devices
+#
 CONFIG_BLK_DEV_LOOP=y
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_MD is not set
@@ -84,7 +101,7 @@
 CONFIG_BLK_DEV_INITRD=y
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_BLK_DEV_DAC960 is not set
-CONFIG_PARIDE_PARPORT=y
+CONFIG_PARIDE_PARPORT=m
 # CONFIG_PARIDE is not set
 # CONFIG_BLK_CPQ_DA is not set
 # CONFIG_BLK_DEV_HD is not set
@@ -108,10 +125,18 @@
 # CONFIG_NET_IPGRE is not set
 # CONFIG_IP_MROUTE is not set
 CONFIG_IP_ALIAS=y
-CONFIG_SYN_COOKIES=y
+# CONFIG_SYN_COOKIES is not set
+
+#
+# (it is safe to leave these untouched)
+#
 CONFIG_INET_RARP=y
 CONFIG_SKB_LARGE=y
 # CONFIG_IPV6 is not set
+
+#
+#  
+#
 # CONFIG_IPX is not set
 CONFIG_ATALK=m
 # CONFIG_X25 is not set
@@ -133,11 +158,19 @@
 # SCSI support
 #
 CONFIG_SCSI=y
+
+#
+# SCSI support type (disk, tape, CD-ROM)
+#
 CONFIG_BLK_DEV_SD=y
 CONFIG_CHR_DEV_ST=y
 CONFIG_BLK_DEV_SR=y
 CONFIG_BLK_DEV_SR_VENDOR=y
-CONFIG_CHR_DEV_SG=y
+# CONFIG_CHR_DEV_SG is not set
+
+#
+# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
+#
 # CONFIG_SCSI_MULTI_LUN is not set
 CONFIG_SCSI_CONSTANTS=y
 # CONFIG_SCSI_LOGGING is not set
@@ -155,7 +188,6 @@
 CONFIG_AIC7XXX_CMDS_PER_DEVICE=8
 CONFIG_AIC7XXX_PROC_STATS=y
 CONFIG_AIC7XXX_RESET_DELAY=15
-# CONFIG_SCSI_IPS is not set
 # CONFIG_SCSI_ADVANSYS is not set
 # CONFIG_SCSI_IN2000 is not set
 # CONFIG_SCSI_AM53C974 is not set
@@ -170,11 +202,12 @@
 # CONFIG_SCSI_GENERIC_NCR5380 is not set
 # CONFIG_SCSI_INITIO is not set
 # CONFIG_SCSI_INIA100 is not set
+# CONFIG_SCSI_PPA is not set
+# CONFIG_SCSI_IMM is not set
 # CONFIG_SCSI_NCR53C406A is not set
 # CONFIG_SCSI_SYM53C416 is not set
-# CONFIG_SCSI_SIM710 is not set
 # CONFIG_SCSI_NCR53C7xx is not set
-# CONFIG_SCSI_NCR53C8XX is not set
+CONFIG_SCSI_NCR53C8XX=y
 CONFIG_SCSI_SYM53C8XX=y
 CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8
 CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32
@@ -182,7 +215,7 @@
 # CONFIG_SCSI_NCR53C8XX_PROFILE is not set
 # CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set
 # CONFIG_SCSI_NCR53C8XX_PQS_PDS is not set
-# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set
+CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT=y
 # CONFIG_SCSI_PAS16 is not set
 # CONFIG_SCSI_PCI2000 is not set
 # CONFIG_SCSI_PCI2220I is not set
@@ -220,21 +253,21 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MACE=y
 CONFIG_BMAC=y
-# CONFIG_NCR885E is not set
+CONFIG_GMAC=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
 # CONFIG_NET_VENDOR_RACAL is not set
 # CONFIG_RTL8139 is not set
+# CONFIG_SIS900 is not set
 # CONFIG_YELLOWFIN is not set
 # CONFIG_NET_ISA is not set
 CONFIG_NET_EISA=y
-CONFIG_PCNET32=y
+# CONFIG_PCNET32 is not set
 # CONFIG_ACENIC is not set
 # CONFIG_AC3200 is not set
 # CONFIG_APRICOT is not set
 # CONFIG_CS89x0 is not set
-# CONFIG_DM9102 is not set
 CONFIG_DE4X5=y
 # CONFIG_DEC_ELCP is not set
 # CONFIG_DGRS is not set
@@ -244,7 +277,6 @@
 # CONFIG_NE2K_PCI is not set
 # CONFIG_TLAN is not set
 # CONFIG_VIA_RHINE is not set
-# CONFIG_SIS900 is not set
 # CONFIG_ES3210 is not set
 # CONFIG_EPIC100 is not set
 # CONFIG_ZNET is not set
@@ -258,7 +290,12 @@
 # CONFIG_LTPC is not set
 # CONFIG_COPS is not set
 # CONFIG_IPDDP is not set
+# CONFIG_PLIP is not set
 CONFIG_PPP=y
+
+#
+# CCP compressors for PPP are only built as modules.
+#
 # CONFIG_SLIP is not set
 # CONFIG_NET_RADIO is not set
 
@@ -276,9 +313,7 @@
 # CONFIG_HOSTESS_SV11 is not set
 # CONFIG_COSA is not set
 # CONFIG_SEALEVEL_4021 is not set
-# CONFIG_COMX is not set
 # CONFIG_DLCI is not set
-# CONFIG_SBNI is not set
 
 #
 # Amateur Radio support
@@ -304,14 +339,12 @@
 CONFIG_FB_CONTROL=y
 CONFIG_FB_PLATINUM=y
 CONFIG_FB_VALKYRIE=y
+CONFIG_FB_ATY=y
+CONFIG_FB_ATY128=y
 CONFIG_FB_IMSTT=y
 CONFIG_FB_CT65550=y
 # CONFIG_FB_S3TRIO is not set
-CONFIG_FB_MATROX=y
-# CONFIG_FB_MATROX_MILLENIUM is not set
-CONFIG_FB_MATROX_MYSTIQUE=y
-CONFIG_FB_MATROX_G100=y
-# CONFIG_FB_MATROX_MULTIHEAD is not set
+# CONFIG_FB_MATROX is not set
 CONFIG_FB_ATY=y
 # CONFIG_FB_VIRTUAL is not set
 # CONFIG_FBCON_ADVANCED is not set
@@ -334,22 +367,13 @@
 #
 CONFIG_VT=y
 CONFIG_VT_CONSOLE=y
-CONFIG_SERIAL=m
+# CONFIG_SERIAL is not set
 # CONFIG_SERIAL_EXTENDED is not set
 # CONFIG_SERIAL_NONSTANDARD is not set
 CONFIG_UNIX98_PTYS=y
 CONFIG_UNIX98_PTY_COUNT=256
-CONFIG_MOUSE=y
-
-#
-# Mice
-#
-# CONFIG_ATIXL_BUSMOUSE is not set
-# CONFIG_BUSMOUSE is not set
-# CONFIG_MS_BUSMOUSE is not set
-CONFIG_PSMOUSE=y
-# CONFIG_82C710_MOUSE is not set
-# CONFIG_PC110_PAD is not set
+# CONFIG_PRINTER is not set
+# CONFIG_MOUSE is not set
 # CONFIG_QIC02_TAPE is not set
 # CONFIG_WATCHDOG is not set
 CONFIG_NVRAM=y
@@ -384,10 +408,10 @@
 # CONFIG_ADFS_FS is not set
 # CONFIG_AFFS_FS is not set
 CONFIG_HFS_FS=y
-CONFIG_FAT_FS=y
-CONFIG_MSDOS_FS=y
+CONFIG_FAT_FS=m
+CONFIG_MSDOS_FS=m
 # CONFIG_UMSDOS_FS is not set
-CONFIG_VFAT_FS=y
+CONFIG_VFAT_FS=m
 CONFIG_ISO9660_FS=y
 # CONFIG_JOLIET is not set
 # CONFIG_MINIX_FS is not set
@@ -453,7 +477,7 @@
 # CONFIG_NLS_ISO8859_8 is not set
 # CONFIG_NLS_ISO8859_9 is not set
 # CONFIG_NLS_ISO8859_14 is not set
-# CONFIG_NLS_ISO8859_15 is not set
+CONFIG_NLS_ISO8859_15=y
 # CONFIG_NLS_KOI8_R is not set
 
 #
@@ -461,43 +485,13 @@
 #
 CONFIG_SOUND=y
 CONFIG_DMASOUND=y
-# CONFIG_SOUND_CMPCI is not set
 # CONFIG_SOUND_ES1370 is not set
 # CONFIG_SOUND_ES1371 is not set
-# CONFIG_SOUND_MAESTRO is not set
 # CONFIG_SOUND_ESSSOLO1 is not set
 # CONFIG_SOUND_SONICVIBES is not set
 # CONFIG_SOUND_MSNDCLAS is not set
 # CONFIG_SOUND_MSNDPIN is not set
-CONFIG_SOUND_OSS=y
-# CONFIG_SOUND_DMAP is not set
-# CONFIG_SOUND_PAS is not set
-# CONFIG_SOUND_SB is not set
-# CONFIG_SOUND_GUS is not set
-# CONFIG_SOUND_MPU401 is not set
-# CONFIG_SOUND_PSS is not set
-# CONFIG_SOUND_MSS is not set
-# CONFIG_SOUND_SSCAPE is not set
-# CONFIG_SOUND_TRIX is not set
-# CONFIG_SOUND_VIA82CXXX is not set
-# CONFIG_SOUND_MAD16 is not set
-# CONFIG_SOUND_WAVEFRONT is not set
-CONFIG_SOUND_CS4232=m
-# CONFIG_SOUND_OPL3SA2 is not set
-# CONFIG_SOUND_MAUI is not set
-# CONFIG_SOUND_SGALAXY is not set
-# CONFIG_SOUND_AD1816 is not set
-# CONFIG_SOUND_OPL3SA1 is not set
-# CONFIG_SOUND_SOFTOSS is not set
-# CONFIG_SOUND_YM3812 is not set
-# CONFIG_SOUND_VMIDI is not set
-# CONFIG_SOUND_UART6850 is not set
-# CONFIG_SOUND_NM256 is not set
-
-#
-# Additional low level sound drivers
-#
-# CONFIG_LOWLEVEL_SOUND is not set
+# CONFIG_SOUND_OSS is not set
 
 #
 # Kernel hacking
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/Makefile linux.17p18/arch/ppc/kernel/Makefile
--- linux.vanilla/arch/ppc/kernel/Makefile	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/Makefile	Tue Aug  1 07:59:04 2000
@@ -7,8 +7,13 @@
 #
 # Note 2! The CFLAGS definitions are now in the main makefile...
 
+# Once a gas that groks -mvec is generally available, we'll use it...
 .S.o:
+#ifdef CONFIG_ALTIVEC
+#	$(CC) $(CFLAGS) -D__ASSEMBLY__ -Wa,-mvec -c $< -o $*.o
+#else
 	$(CC) $(CFLAGS) -D__ASSEMBLY__ -c $< -o $*.o
+#endif
 
 O_TARGET := kernel.o
 OX_OBJS := ppc_ksyms.o setup.o
@@ -62,7 +67,8 @@
 		$(TOPDIR)/include/asm/ptrace.h
 	$(CC) ${CFLAGS} -S mk_defs.c
 	cp ppc_defs.head ppc_defs.h
-	grep '^#define' mk_defs.s >>ppc_defs.h
+	chmod 755 ppc_defs.h
+	grep '^#define' mk_defs.s >> ppc_defs.h
 	rm mk_defs.s
 
 find_name : find_name.c
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/apus_setup.c linux.17p18/arch/ppc/kernel/apus_setup.c
--- linux.vanilla/arch/ppc/kernel/apus_setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/apus_setup.c	Tue Aug  1 07:59:04 2000
@@ -42,7 +42,7 @@
 #include <asm/machdep.h>
 #include <asm/ide.h>
 
-#include "time.h"
+#include <asm/time.h>
 #include "local_irq.h"
 
 unsigned long apus_get_rtc_time(void);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/checks.c linux.17p18/arch/ppc/kernel/checks.c
--- linux.vanilla/arch/ppc/kernel/checks.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/checks.c	Tue Aug  1 07:59:04 2000
@@ -1,3 +1,4 @@
+#include <linux/config.h>
 #include <linux/errno.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/chrp_setup.c linux.17p18/arch/ppc/kernel/chrp_setup.c
--- linux.vanilla/arch/ppc/kernel/chrp_setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/chrp_setup.c	Tue Aug  1 07:59:04 2000
@@ -48,7 +48,7 @@
 #include <asm/adb.h>
 #include <asm/hydra.h>
 
-#include "time.h"
+#include <asm/time.h>
 #include "local_irq.h"
 #include "i8259.h"
 #include "open_pic.h"
@@ -488,6 +488,7 @@
 		ppc_md.kbd_init_hw       = pckbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
 		ppc_md.kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
+		ppc_md.SYSRQ_KEY	 = 0x54;
 #endif		
 	}
 	else
@@ -500,6 +501,7 @@
 		ppc_md.kbd_init_hw       = mackbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
 		ppc_md.kbd_sysrq_xlate	 = mackbd_sysrq_xlate;
+		ppc_md.SYSRQ_KEY	 = 0x69;
 #endif		
 	}
 #else
@@ -511,6 +513,7 @@
 	ppc_md.kbd_init_hw       = pckbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
 	ppc_md.kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
+	ppc_md.SYSRQ_KEY	 = 0x54;
 #endif
 #endif
 #endif
@@ -681,4 +684,9 @@
 	call_rtas( "display-character", 1, 1, NULL, '\r' );
 	while ( *s )
 		call_rtas( "display-character", 1, 1, NULL, *s++ );
+}
+
+void chrp_indicator(int x)
+{
+	call_rtas("set-indicator", 3, 1, NULL, 6, 0, x);
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/chrp_time.c linux.17p18/arch/ppc/kernel/chrp_time.c
--- linux.vanilla/arch/ppc/kernel/chrp_time.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/chrp_time.c	Tue Aug  1 07:59:04 2000
@@ -25,7 +25,7 @@
 #include <asm/processor.h>
 #include <asm/nvram.h>
 #include <asm/prom.h>
-#include "time.h"
+#include <asm/time.h>
 
 static int nvram_as1 = NVRAM_AS1;
 static int nvram_as0 = NVRAM_AS0;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/feature.c linux.17p18/arch/ppc/kernel/feature.c
--- linux.vanilla/arch/ppc/kernel/feature.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/feature.c	Tue Aug  1 07:59:04 2000
@@ -8,85 +8,182 @@
  *  as published by the Free Software Foundation; either version
  *  2 of the License, or (at your option) any later version.
  *
+ *  BenH: Changed implementation to work on multiple registers
+ * 	  polarity is also taken into account. Removed delay (now
+ * 	  responsibility of the caller). Added spinlocks.
+ *
  */
 #include <linux/types.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
+#include <asm/spinlock.h>
 #include <asm/errno.h>
 #include <asm/ohare.h>
+#include <asm/heathrow.h>
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/feature.h>
 
-#define MAX_FEATURE_REGS		2
 #undef DEBUG_FEATURE
 
-static u32 feature_bits_pbook[] = {
-	0,			/* FEATURE_null */
-	OH_SCC_RESET,		/* FEATURE_Serial_reset */
-	OH_SCC_ENABLE,		/* FEATURE_Serial_enable */
-	OH_SCCA_IO,		/* FEATURE_Serial_IO_A */
-	OH_SCCB_IO,		/* FEATURE_Serial_IO_B */
-	OH_FLOPPY_ENABLE,	/* FEATURE_SWIM3_enable */
-	OH_MESH_ENABLE,		/* FEATURE_MESH_enable */
-	OH_IDE_ENABLE,		/* FEATURE_IDE_enable */
-	OH_VIA_ENABLE,		/* FEATURE_VIA_enable */
-	OH_IDECD_POWER,		/* FEATURE_CD_power */
-	OH_BAY_RESET,		/* FEATURE_Mediabay_reset */
-	OH_BAY_ENABLE,		/* FEATURE_Mediabay_enable */
-	OH_BAY_PCI_ENABLE,	/* FEATURE_Mediabay_PCI_enable */
-	OH_BAY_IDE_ENABLE,	/* FEATURE_Mediabay_IDE_enable */
-	OH_BAY_FLOPPY_ENABLE,	/* FEATURE_Mediabay_floppy_enable */
-	0,			/* FEATURE_BMac_reset */
-	0,			/* FEATURE_BMac_IO_enable */
-	0,			/* FEATURE_Modem_Reset -> guess... */
-	OH_IDE_POWER,		/* FEATURE_IDE_DiskPower -> guess... */
-	OH_IDE_RESET		/* FEATURE_IDE_Reset (0 based) -> guess... */
+#define MAX_FEATURE_CONTROLLERS		2
+#define MAX_FEATURE_OFFSET		0x50
+#define FREG(c,r)			(&(((c)->reg)[(r)>>2]))
+
+typedef struct feature_bit {
+	int		reg;		/* reg. offset from mac-io base */
+	unsigned int	polarity;	/* 0 = normal, 1 = inverse */
+	unsigned int	mask;		/* bit mask */
+} fbit;
+
+/* I don't have an OHare machine to test with, so I left those as they
+ * were. Someone with such a machine chould check out what OF says and
+ * try too see if they match the heathrow ones and should be changed too
+ */
+static fbit feature_bits_ohare_pbook[] = {
+	{0x38,0,0},			/* FEATURE_null */
+	{0x38,0,OH_SCC_RESET},		/* FEATURE_Serial_reset */
+	{0x38,0,OH_SCC_ENABLE},		/* FEATURE_Serial_enable */
+	{0x38,0,OH_SCCA_IO},		/* FEATURE_Serial_IO_A */
+	{0x38,0,OH_SCCB_IO},		/* FEATURE_Serial_IO_B */
+	{0x38,0,OH_FLOPPY_ENABLE},	/* FEATURE_SWIM3_enable */
+	{0x38,0,OH_MESH_ENABLE},	/* FEATURE_MESH_enable */
+	{0x38,0,OH_IDE0_ENABLE},	/* FEATURE_IDE0_enable */
+	{0x38,1,OH_IDE0_RESET_N},	/* FEATURE_IDE0_reset */
+	{0x38,0,OH_IOBUS_ENABLE},	/* FEATURE_IOBUS_enable */
+	{0x38,1,OH_BAY_RESET_N},	/* FEATURE_Mediabay_reset */
+	{0x38,1,OH_BAY_POWER_N},	/* FEATURE_Mediabay_power */
+	{0x38,0,OH_BAY_PCI_ENABLE},	/* FEATURE_Mediabay_PCI_enable */
+	{0x38,0,OH_BAY_IDE_ENABLE},	/* FEATURE_IDE1_enable */
+	{0x38,1,OH_IDE1_RESET_N},	/* FEATURE_IDE1_reset */
+	{0x38,0,OH_BAY_FLOPPY_ENABLE},	/* FEATURE_Mediabay_floppy_enable */
+	{0x38,0,0},			/* FEATURE_BMac_reset */
+	{0x38,0,0},			/* FEATURE_BMac_IO_enable */
+	{0x38,0,0},			/* FEATURE_Modem_power */
+	{0x38,0,0},			/* FEATURE_Slow_SCC_PCLK */
+	{0x38,0,0},			/* FEATURE_Sound_Power */
+	{0x38,0,0},			/* FEATURE_Sound_CLK_Enable */
+	{0x38,0,0},			/* FEATURE_IDE2_enable */
+	{0x38,0,0},			/* FEATURE_IDE2_reset */
+	{0x38,0,0},			/* FEATURE_Mediabay_IDE_switch */
+	{0x38,0,0},			/* FEATURE_Mediabay_content */
 };
 
-/* assume these are the same as the ohare until proven otherwise */
-static u32 feature_bits_heathrow[] = {
-	0,			/* FEATURE_null */
-	OH_SCC_RESET,		/* FEATURE_Serial_reset */
-	OH_SCC_ENABLE,		/* FEATURE_Serial_enable */
-	OH_SCCA_IO,		/* FEATURE_Serial_IO_A */
-	OH_SCCB_IO,		/* FEATURE_Serial_IO_B */
-	OH_FLOPPY_ENABLE,	/* FEATURE_SWIM3_enable */
-	OH_MESH_ENABLE,		/* FEATURE_MESH_enable */
-	OH_IDE_ENABLE,		/* FEATURE_IDE_enable */
-	OH_VIA_ENABLE,		/* FEATURE_VIA_enable */
-	OH_IDECD_POWER,		/* FEATURE_CD_power */
-	OH_BAY_RESET,		/* FEATURE_Mediabay_reset */
-	OH_BAY_ENABLE,		/* FEATURE_Mediabay_enable */
-	OH_BAY_PCI_ENABLE,	/* FEATURE_Mediabay_PCI_enable */
-	OH_BAY_IDE_ENABLE,	/* FEATURE_Mediabay_IDE_enable */
-	OH_BAY_FLOPPY_ENABLE,	/* FEATURE_Mediabay_floppy_enable */
-	0x80000000,		/* FEATURE_BMac_reset */
-	0x60000000,		/* FEATURE_BMac_IO_enable */
-	0x02000000,		/* FEATURE_Modem_Reset -> guess...*/
-	OH_IDE_POWER,		/* FEATURE_IDE_DiskPower -> guess... */
-	OH_IDE_RESET		/* FEATURE_IDE_Reset (0 based) -> guess... */
+/* Those bits are from a PowerBook. It's possible that desktop machines
+ * based on heathrow need a different definition or some bits removed
+ */
+static fbit feature_bits_heathrow[] = {
+	{0x38,0,0},			/* FEATURE_null */
+	{0x38,0,HRW_RESET_SCC},		/* FEATURE_Serial_reset */
+	{0x38,0,HRW_SCC_ENABLE},	/* FEATURE_Serial_enable */
+	{0x38,0,HRW_SCCA_IO},		/* FEATURE_Serial_IO_A */
+	{0x38,0,HRW_SCCB_IO},		/* FEATURE_Serial_IO_B */
+	{0x38,0,HRW_SWIM_ENABLE},	/* FEATURE_SWIM3_enable */
+	{0x38,0,HRW_MESH_ENABLE},	/* FEATURE_MESH_enable */
+	{0x38,0,HRW_IDE0_ENABLE},	/* FEATURE_IDE0_enable */
+	{0x38,1,HRW_IDE0_RESET_N},	/* FEATURE_IDE0_reset */
+	{0x38,0,HRW_IOBUS_ENABLE},	/* FEATURE_IOBUS_enable */
+	{0x38,1,HRW_BAY_RESET_N},	/* FEATURE_Mediabay_reset */
+	{0x38,1,HRW_BAY_POWER_N},	/* FEATURE_Mediabay_power */
+	{0x38,0,HRW_BAY_PCI_ENABLE},	/* FEATURE_Mediabay_PCI_enable */
+	{0x38,0,HRW_BAY_IDE_ENABLE},	/* FEATURE_IDE1_enable */
+	{0x38,1,HRW_IDE1_RESET_N},	/* FEATURE_IDE1_reset */
+	{0x38,0,HRW_BAY_FLOPPY_ENABLE},	/* FEATURE_Mediabay_floppy_enable */
+	{0x38,0,HRW_BMAC_RESET},	/* FEATURE_BMac_reset */
+	{0x38,0,HRW_BMAC_IO_ENABLE},	/* FEATURE_BMac_IO_enable */
+	{0x38,1,HRW_MODEM_POWER_N},	/* FEATURE_Modem_power */
+	{0x38,0,HRW_SLOW_SCC_PCLK},	/* FEATURE_Slow_SCC_PCLK */
+	{0x38,1,HRW_SOUND_POWER_N},	/* FEATURE_Sound_Power */
+	{0x38,0,HRW_SOUND_CLK_ENABLE},	/* FEATURE_Sound_CLK_Enable */
+	{0x38,0,0},			/* FEATURE_IDE2_enable */
+	{0x38,0,0},			/* FEATURE_IDE2_reset */
+	{0x38,0,0},			/* FEATURE_Mediabay_IDE_switch */
+	{0x38,0,0},			/* FEATURE_Mediabay_content */
+};
+
+/*
+ * Those bits are from a 1999 G3 PowerBook, with a paddington chip.
+ * Mostly the same as the heathrow.
+ */
+static fbit feature_bits_paddington[] = {
+	{0x38,0,0},			/* FEATURE_null */
+	{0x38,0,0},			/* FEATURE_Serial_reset */
+	{0x38,0,HRW_SCC_ENABLE},	/* FEATURE_Serial_enable */
+	{0x38,0,HRW_SCCA_IO},		/* FEATURE_Serial_IO_A */
+	{0x38,0,HRW_SCCB_IO},		/* FEATURE_Serial_IO_B */
+	{0x38,0,HRW_SWIM_ENABLE},	/* FEATURE_SWIM3_enable */
+	{0x38,0,HRW_MESH_ENABLE},	/* FEATURE_MESH_enable */
+	{0x38,0,HRW_IDE0_ENABLE},	/* FEATURE_IDE0_enable */
+	{0x38,1,HRW_IDE0_RESET_N},	/* FEATURE_IDE0_reset */
+	{0x38,0,HRW_IOBUS_ENABLE},	/* FEATURE_IOBUS_enable */
+	{0x38,1,HRW_BAY_RESET_N},	/* FEATURE_Mediabay_reset */
+	{0x38,1,HRW_BAY_POWER_N},	/* FEATURE_Mediabay_power */
+	{0x38,0,HRW_BAY_PCI_ENABLE},	/* FEATURE_Mediabay_PCI_enable */
+	{0x38,0,HRW_BAY_IDE_ENABLE},	/* FEATURE_IDE1_enable */
+	{0x38,1,HRW_IDE1_RESET_N},	/* FEATURE_IDE1_reset */
+	{0x38,0,HRW_BAY_FLOPPY_ENABLE},	/* FEATURE_Mediabay_floppy_enable */
+	{0x38,0,HRW_BMAC_RESET},	/* FEATURE_BMac_reset */
+	{0x38,0,HRW_BMAC_IO_ENABLE},	/* FEATURE_BMac_IO_enable */
+	{0x38,1,PADD_MODEM_POWER_N},	/* FEATURE_Modem_power */
+	{0x38,0,HRW_SLOW_SCC_PCLK},	/* FEATURE_Slow_SCC_PCLK */
+	{0x38,1,HRW_SOUND_POWER_N},	/* FEATURE_Sound_Power */
+	{0x38,0,HRW_SOUND_CLK_ENABLE},	/* FEATURE_Sound_CLK_Enable */
+	{0x38,0,0},			/* FEATURE_IDE2_enable */
+	{0x38,0,0},			/* FEATURE_IDE2_reset */
+	{0x38,0,0},			/* FEATURE_Mediabay_IDE_switch */
+	{0x38,0,0},			/* FEATURE_Mediabay_content */
+};
+
+/* Those bits are for Core99 machines (iBook,G4,iMacSL/DV,Pismo,...).
+ */
+static fbit feature_bits_keylargo[] = {
+	{0x38,0,0},			/* FEATURE_null */
+	{0x38,0,0},			/* FEATURE_Serial_reset */
+	{0x38,0,0x00000054},		/* FEATURE_Serial_enable */
+	{0x38,0,0},			/* FEATURE_Serial_IO_A */
+	{0x38,0,0},			/* FEATURE_Serial_IO_B */
+	{0x38,0,0},			/* FEATURE_SWIM3_enable */
+	{0x38,0,0},			/* FEATURE_MESH_enable */
+	{0x3c,0,0},			/* FEATURE_IDE0_enable */
+ 	{0x3c,1,0x01000000},		/* FEATURE_IDE0_reset */
+	{0x38,0,0},			/* FEATURE_IOBUS_enable */
+	{0x34,1,0x00000200},		/* FEATURE_Mediabay_reset */
+	{0x34,1,0x00000400},		/* FEATURE_Mediabay_power */
+	{0x38,0,0},			/* FEATURE_Mediabay_PCI_enable */
+	{0x3c,0,0x0},			/* FEATURE_IDE1_enable */
+	{0x3c,1,0x08000000},		/* FEATURE_IDE1_reset */
+	{0x38,0,0},			/* FEATURE_Mediabay_floppy_enable */
+	{0x38,0,0},			/* FEATURE_BMac_reset */
+	{0x38,0,0},			/* FEATURE_BMac_IO_enable */
+	{0x40,1,0x02000000},		/* FEATURE_Modem_power */
+	{0x38,0,0},			/* FEATURE_Slow_SCC_PCLK */
+	{0x38,0,0},			/* FEATURE_Sound_Power */
+	{0x38,0,0},			/* FEATURE_Sound_CLK_Enable */
+	{0x38,0,0},			/* FEATURE_IDE2_enable */
+	{0x3c,1,0x40000000},		/* FEATURE_IDE2_reset */
+	{0x34,0,0x00001000},		/* FEATURE_Mediabay_IDE_switch */
+	{0x34,0,0x00000100},		/* FEATURE_Mediabay_content */
 };
 
 /* definition of a feature controller object */
-struct feature_controller
-{
-	u32*			bits;
+struct feature_controller {
+	fbit*			bits;
 	volatile u32*		reg;
 	struct device_node*	device;
+	spinlock_t		lock;
 };
 
 /* static functions */
 static void
-feature_add_controller(struct device_node *controller_device, u32* bits);
+feature_add_controller(struct device_node *controller_device, fbit* bits);
 
-static int
+static struct feature_controller*
 feature_lookup_controller(struct device_node *device);
 
 /* static varialbles */
-static struct feature_controller	controllers[MAX_FEATURE_REGS];
+static struct feature_controller	controllers[MAX_FEATURE_CONTROLLERS];
 static int				controller_count = 0;
 
 
@@ -96,18 +193,25 @@
 	struct device_node *np;
 
 	np = find_devices("mac-io");
-	while (np != NULL)
-	{
-		feature_add_controller(np, feature_bits_heathrow);
+	while (np != NULL) {
+		/* KeyLargo contains several (5 ?) FCR registers in mac-io,
+		 * plus some gpio's which could eventually be handled here.
+		 */
+		if (device_is_compatible(np, "Keylargo")) {
+			feature_add_controller(np, feature_bits_keylargo);
+		} else if (device_is_compatible(np, "paddington")) {
+			feature_add_controller(np, feature_bits_paddington);
+		} else {
+			feature_add_controller(np, feature_bits_heathrow);
+		}
 		np = np->next;
 	}
 	if (controller_count == 0)
 	{
 		np = find_devices("ohare");
-		if (np)
-		{
+		if (np) {
 			if (find_devices("via-pmu") != NULL)
-				feature_add_controller(np, feature_bits_pbook);
+				feature_add_controller(np, feature_bits_ohare_pbook);
 			else
 				/* else not sure; maybe this is a Starmax? */
 				feature_add_controller(np, NULL);
@@ -116,17 +220,26 @@
 
 	if (controller_count)
 		printk(KERN_INFO "Registered %d feature controller(s)\n", controller_count);
+
+#ifdef CONFIG_PMAC_PBOOK
+#ifdef CONFIG_DMASOUND_MODULE
+	/* On PowerBooks, we disable the sound chip when dmasound is a module */
+	if (controller_count && find_devices("via-pmu") != NULL) {
+		feature_clear(controllers[0].device, FEATURE_Sound_power);
+		feature_clear(controllers[0].device, FEATURE_Sound_CLK_enable);
+	}
+#endif	
+#endif
 }
 
 static void
-feature_add_controller(struct device_node *controller_device, u32* bits)
+feature_add_controller(struct device_node *controller_device, fbit* bits)
 {
 	struct feature_controller*	controller;
 	
-	if (controller_count >= MAX_FEATURE_REGS)
-	{
+	if (controller_count >= MAX_FEATURE_CONTROLLERS) {
 		printk(KERN_INFO "Feature controller %s skipped(MAX:%d)\n",
-			controller_device->full_name, MAX_FEATURE_REGS);
+			controller_device->full_name, MAX_FEATURE_CONTROLLERS);
 		return;
 	}
 	controller = &controllers[controller_count];
@@ -140,30 +253,32 @@
 	}
 
 	controller->reg		= (volatile u32 *)ioremap(
-		controller_device->addrs[0].address + OHARE_FEATURE_REG, 4);
+		controller_device->addrs[0].address, MAX_FEATURE_OFFSET);
 
 	if (bits == NULL) {
 		printk(KERN_INFO "Twiddling the magic ohare bits\n");
-		out_le32(controller->reg, STARMAX_FEATURES);
+		out_le32(FREG(controller,OHARE_FEATURE_REG), STARMAX_FEATURES);
 		return;
 	}
 
+	spin_lock_init(&controller->lock);
+	
 	controller_count++;
 }
 
-static int
+static struct feature_controller*
 feature_lookup_controller(struct device_node *device)
 {
 	int	i;
 	
 	if (device == NULL)
-		return -EINVAL;
+		return NULL;
 		
 	while(device)
 	{
 		for (i=0; i<controller_count; i++)
 			if (device == controllers[i].device)
-				return i;
+				return &controllers[i];
 		device = device->parent;
 	}
 
@@ -172,35 +287,38 @@
 		device->name);
 #endif
 	
-	return -ENODEV;
+	return NULL;
 }
 
 int
 feature_set(struct device_node* device, enum system_feature f)
 {
-	int		controller;
-	unsigned long	flags;
+	struct feature_controller*	controller;
+	unsigned long			flags;
+	unsigned long			value;
+	fbit*				bit;
 
 	if (f >= FEATURE_last)
 		return -EINVAL;	
 
 	controller = feature_lookup_controller(device);
-	if (controller < 0)
-		return controller;
+	if (!controller)
+		return -ENODEV;
+	bit = &controller->bits[f];
+	if (!bit->mask)
+		return -EINVAL;
 	
 #ifdef DEBUG_FEATURE
 	printk("feature: <%s> setting feature %d in controller @0x%x\n",
-		device->name, (int)f, (unsigned int)controllers[controller].reg);
+		device->name, (int)f, (unsigned int)controller->reg);
 #endif
 
-	save_flags(flags);
-	cli();
-	out_le32( controllers[controller].reg,
-		 in_le32(controllers[controller].reg) |
-		 controllers[controller].bits[f]);
-	(void)in_le32(controllers[controller].reg);
-	restore_flags(flags);
-	udelay(10);
+	spin_lock_irqsave(&controller->lock, flags);
+	value = in_le32(FREG(controller, bit->reg));
+	value = bit->polarity ? (value & ~bit->mask) : (value | bit->mask);
+	out_le32(FREG(controller, bit->reg), value);
+	(void)in_le32(FREG(controller, bit->reg));
+	spin_unlock_irqrestore(&controller->lock, flags);
 	
 	return 0;
 }
@@ -208,29 +326,32 @@
 int
 feature_clear(struct device_node* device, enum system_feature f)
 {
-	int		controller;
-	unsigned long	flags;
+	struct feature_controller*	controller;
+	unsigned long			flags;
+	unsigned long			value;
+	fbit*				bit;
 
 	if (f >= FEATURE_last)
 		return -EINVAL;	
 
 	controller = feature_lookup_controller(device);
-	if (controller < 0)
-		return controller;
+	if (!controller)
+		return -ENODEV;
+	bit = &controller->bits[f];
+	if (!bit->mask)
+		return -EINVAL;
 	
 #ifdef DEBUG_FEATURE
 	printk("feature: <%s> clearing feature %d in controller @0x%x\n",
-		device->name, (int)f, (unsigned int)controllers[controller].reg);
+		device->name, (int)f, (unsigned int)controller->reg);
 #endif
 
-	save_flags(flags);
-	cli();
-	out_le32( controllers[controller].reg,
-		 in_le32(controllers[controller].reg) &
-		 ~(controllers[controller].bits[f]));
-	(void)in_le32(controllers[controller].reg);
-	restore_flags(flags);
-	udelay(10);
+	spin_lock_irqsave(&controller->lock, flags);
+	value = in_le32(FREG(controller, bit->reg));
+	value = bit->polarity ? (value | bit->mask) : (value & ~bit->mask);
+	out_le32(FREG(controller, bit->reg), value);
+	(void)in_le32(FREG(controller, bit->reg));
+	spin_unlock_irqrestore(&controller->lock, flags);
 	
 	return 0;
 }
@@ -238,16 +359,29 @@
 int
 feature_test(struct device_node* device, enum system_feature f)
 {
-	int		controller;
+	struct feature_controller*	controller;
+	unsigned long			value;
+	fbit*				bit;
 
 	if (f >= FEATURE_last)
 		return -EINVAL;	
 
 	controller = feature_lookup_controller(device);
-	if (controller < 0)
-		return controller;
+	if (!controller)
+		return -ENODEV;
+	bit = &controller->bits[f];
+	if (!bit->mask)
+		return -EINVAL;
 	
-	return (in_le32(controllers[controller].reg) &
-		controllers[controller].bits[f]) != 0;
+#ifdef DEBUG_FEATURE
+	printk("feature: <%s> clearing feature %d in controller @0x%x\n",
+		device->name, (int)f, (unsigned int)controller->reg);
+#endif
+	/* If one feature contains several bits, all of them must be set
+	 * for value to be true, or all of them must be 0 if polarity is
+	 * inverse
+	 */
+	value = (in_le32(FREG(controller, bit->reg)) & bit->mask);
+	return bit->polarity ? (value == 0) : (value == bit->mask);
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/gemini_setup.c linux.17p18/arch/ppc/kernel/gemini_setup.c
--- linux.vanilla/arch/ppc/kernel/gemini_setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/gemini_setup.c	Tue Aug  1 07:59:04 2000
@@ -30,7 +30,7 @@
 #include <asm/m48t35.h>
 #include <asm/gemini.h>
 
-#include "time.h"
+#include <asm/time.h>
 #include "local_irq.h"
 #include "open_pic.h"
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/head.S linux.17p18/arch/ppc/kernel/head.S
--- linux.vanilla/arch/ppc/kernel/head.S	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/head.S	Wed Aug 16 21:41:39 2000
@@ -13,6 +13,7 @@
  *    Copyright (C) 1996 Paul Mackerras.
  *  MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net).
  *  Amiga/APUS changes by Jesper Skov (jskov@cygnus.co.uk).
+ *  AltiVec additions by Kumar Gala (kumar.gala@motorola.com).
  *
  *  This file contains the low-level support and setup for the
  *  PowerPC platform, including trap and interrupt dispatch.
@@ -82,6 +83,28 @@
 #define REST_16FPRS(n, base)	REST_8FPRS(n, base); REST_8FPRS(n+8, base)
 #define REST_32FPRS(n, base)	REST_16FPRS(n, base); REST_16FPRS(n+16, base)
 
+/*
+ * Once a version of gas that understands the AltiVec instructions
+ * is freely available, we can do this the normal way...  - paulus
+ */
+#define LVX(r,a,b)	.long	(31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(103<<1)
+#define STVX(r,a,b)	.long	(31<<26)+((r)<<21)+((a)<<16)+((b)<<11)+(231<<1)
+#define MFVSCR(r)	.long	(4<<26)+((r)<<11)+(770<<1)
+#define MTVSCR(r)	.long	(4<<26)+((r)<<11)+(802<<1)
+
+#define SAVE_VR(n,b,base)	li b,TSS_VR0+(16*(n)); STVX(n,b,base)
+#define SAVE_2VR(n,b,base)	SAVE_VR(n,b,base); SAVE_VR(n+1,b,base) 
+#define SAVE_4VR(n,b,base)	SAVE_2VR(n,b,base); SAVE_2VR(n+2,b,base) 
+#define SAVE_8VR(n,b,base)	SAVE_4VR(n,b,base); SAVE_4VR(n+4,b,base) 
+#define SAVE_16VR(n,b,base)	SAVE_8VR(n,b,base); SAVE_8VR(n+8,b,base)
+#define SAVE_32VR(n,b,base)	SAVE_16VR(n,b,base); SAVE_16VR(n+16,b,base)
+#define REST_VR(n,b,base)	li b,TSS_VR0+(16*(n)); LVX(n,b,base)
+#define REST_2VR(n,b,base)	REST_VR(n,b,base); REST_VR(n+1,b,base) 
+#define REST_4VR(n,b,base)	REST_2VR(n,b,base); REST_2VR(n+2,b,base) 
+#define REST_8VR(n,b,base)	REST_4VR(n,b,base); REST_4VR(n+4,b,base) 
+#define REST_16VR(n,b,base)	REST_8VR(n,b,base); REST_8VR(n+8,b,base) 
+#define REST_32VR(n,b,base)	REST_16VR(n,b,base); REST_16VR(n+16,b,base)
+
 #define SYNC \
 	sync; \
 	isync
@@ -651,7 +674,26 @@
 	STD_EXCEPTION(0xd00, SingleStep, SingleStepException)
 
 	STD_EXCEPTION(0xe00, Trap_0e, UnknownException)
+
+#ifndef CONFIG_ALTIVEC
 	STD_EXCEPTION(0xf00, Trap_0f, UnknownException)
+#else
+/*
+ * The Altivec unavailable trap is at 0x0f20.  Foo.
+ * We effectively remap it to 0x3000.
+ */
+	. = 0xf00
+	b	Trap_0f
+trap_0f_cont:
+	addi	r3,r1,STACK_FRAME_OVERHEAD
+	li	r20,MSR_KERNEL
+	bl	transfer_to_handler
+	.long	UnknownException
+	.long	int_return
+
+	. = 0xf20
+	b	AltiVecUnavailable
+#endif /* CONFIG_ALTIVEC */
 
 #ifndef CONFIG_8xx
 /*
@@ -1169,9 +1211,24 @@
 	STD_EXCEPTION(0x2f00, Trap_2f, UnknownException)
 
 	. = 0x3000
-#else
+#ifdef CONFIG_ALTIVEC
+AltiVecUnavailable:
+	EXCEPTION_PROLOG
+	bne	load_up_altivec		/* if from user, just load it up */
+	li	r20,MSR_KERNEL
+	bl	transfer_to_handler	/* if from kernel, take a trap */
+	.long	KernelAltiVec
+	.long	int_return
+
+/* here are the bits of trap 0xf00 which got displaced */
+Trap_0f:
+	EXCEPTION_PROLOG
+	b	trap_0f_cont
+#endif /* CONFIG_ALTIVEC */
+
+#else /* CONFIG_8xx */
 	. = 0x2000
-#endif
+#endif /* CONFIG_8xx */
 
 /*
  * This code finishes saving the registers to the exception frame
@@ -1493,6 +1550,7 @@
 	REST_GPR(20, r21)
 	REST_2GPRS(22, r21)
 	lwz	r21,GPR21(r21)
+	sync
 	rfi
 	
 #ifdef __SMP__
@@ -1632,6 +1690,135 @@
 #endif /* __SMP__ */
 	blr
 
+#ifdef CONFIG_ALTIVEC
+/* Note that the AltiVec support is closely modeled after the FP
+ * support.  Changes to one are likely to be applicable to the
+ * other!  */
+load_up_altivec:
+/*
+ * Disable AltiVec for the task which had AltiVec previously,
+ * and save its AltiVec registers in its thread_struct.
+ * Enables AltiVec for use in the kernel on return.
+ * On SMP we know the AltiVec units are free, since we give it up every
+ * switch.  -- Kumar
+ */
+	mfmsr	r5
+	oris	r5,r5,MSR_VEC@h
+	SYNC
+	mtmsr	r5			/* enable use of AltiVec now */
+	SYNC
+/*
+ * For SMP, we don't do lazy AltiVec switching because it just gets too
+ * horrendously complex, especially when a task switches from one CPU
+ * to another.  Instead we call giveup_altivec in switch_to.
+ */
+#ifndef __SMP__
+#ifndef CONFIG_APUS
+	lis	r6,-KERNELBASE@h
+#else
+	lis	r6,CYBERBASEp@h
+	lwz	r6,0(r6)
+#endif
+	addis	r3,r6,last_task_used_altivec@ha
+	lwz	r4,last_task_used_altivec@l(r3)
+	cmpi	0,r4,0
+	beq	1f
+	add	r4,r4,r6
+	addi	r4,r4,TSS	/* want TSS of last_task_used_altivec */
+	SAVE_32VR(0,r20,r4)
+	MFVSCR(vr0)
+	li	r20,TSS_VSCR
+	STVX(vr0,r20,r4)
+	lwz	r5,PT_REGS(r4)
+	add	r5,r5,r6
+	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	lis	r20,MSR_VEC@h
+	andc	r4,r4,r20	/* disable altivec for previous task */
+	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#endif /* __SMP__ */
+	/* enable use of AltiVec after return */
+	oris	r23,r23,MSR_VEC@h
+	mfspr	r5,SPRG3		/* current task's TSS (phys) */
+	li	r20,TSS_VSCR
+	LVX(vr0,r20,r5)
+	MTVSCR(vr0)
+	REST_32VR(0,r20,r5)
+#ifndef __SMP__
+	subi	r4,r5,TSS
+	sub	r4,r4,r6
+	stw	r4,last_task_used_altivec@l(r3)
+#endif /* __SMP__ */
+	/* restore registers and return */
+	lwz	r3,_CCR(r21)
+	lwz	r4,_LINK(r21)
+	mtcrf	0xff,r3
+	mtlr	r4
+	REST_GPR(1, r21)
+	REST_4GPRS(3, r21)
+	/* we haven't used ctr or xer */
+	mtspr	SRR1,r23
+	mtspr	SRR0,r22
+	REST_GPR(20, r21)
+	REST_2GPRS(22, r21)
+	lwz	r21,GPR21(r21)
+	SYNC
+	rfi
+
+/*
+ * AltiVec unavailable trap from kernel - print a message, but let
+ * the task use AltiVec in the kernel until it returns to user mode.
+ */
+KernelAltiVec:
+	lwz	r3,_MSR(r1)
+	oris	r3,r3,MSR_VEC@h
+	stw	r3,_MSR(r1)	/* enable use of AltiVec after return */
+	lis	r3,87f@h
+	ori	r3,r3,87f@l
+	mr	r4,r2		/* current */
+	lwz	r5,_NIP(r1)
+	bl	printk
+	b	int_return
+87:	.string	"AltiVec used in kernel  (task=%p, pc=%x)  \n"
+	.align	4
+
+/*
+ * giveup_altivec(tsk)
+ * Disable AltiVec for the task given as the argument,
+ * and save the AltiVec registers in its thread_struct.
+ * Enables AltiVec for use in the kernel on return.
+ */
+
+	.globl	giveup_altivec
+giveup_altivec:
+	mfmsr	r5
+	oris	r5,r5,MSR_VEC@h
+	SYNC
+	mtmsr	r5			/* enable use of AltiVec now */
+	SYNC
+	cmpi	0,r3,0
+	beqlr-				/* if no previous owner, done */
+	addi	r3,r3,TSS		/* want TSS of task */
+	lwz	r5,PT_REGS(r3)
+	cmpi	0,r5,0
+	SAVE_32VR(0, r4, r3)
+	MFVSCR(vr0)
+	li	r4,TSS_VSCR
+	STVX(vr0, r4, r3)
+	beq	1f
+	lwz	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+	lis	r3,MSR_VEC@h
+	andc	r4,r4,r3		/* disable AltiVec for previous task */
+	stw	r4,_MSR-STACK_FRAME_OVERHEAD(r5)
+1:
+#ifndef __SMP__
+	li	r5,0
+	lis	r4,last_task_used_altivec@ha
+	stw	r5,last_task_used_altivec@l(r4)
+#endif /* __SMP__ */
+	blr
+#endif /* CONFIG_ALTIVEC */
+
 #else  /* CONFIG_8xx */
 	.globl	giveup_fpu
 giveup_fpu:
@@ -1642,14 +1829,12 @@
  	addi	r4, r3, __secondary_start - _start
 	mfmsr	r3
 	andi.	r0,r3,MSR_DR|MSR_IR		/* MMU enabled? */
-	beq	1f
-	ori	r3,r3,MSR_DR|MSR_IR
-	xori	r3,r3,MSR_DR|MSR_IR
+	beqlr
+	andc	r3,r3,r0
 	mtspr	SRR0,r4
 	mtspr	SRR1,r3
-	sync
+	SYNC
 	rfi
-1:	blr
 
 /*
  * This code is jumped to from the startup code to copy
@@ -1660,10 +1845,6 @@
 	addi	r9,r9,0x6f58		/* translate source addr */
 	cmpw	r31,r9			/* (we have to on chrp) */
 	beq	7f
-#if 0 // still needed ? breaks on me if I don't disable this
-	rlwinm	r4,r4,0,8,31		/* translate source address */
-	add	r4,r4,r3		/* to region mapped with BATs */
-#endif	
 7:	addis	r9,r26,klimit@ha	/* fetch klimit */
 	lwz	r25,klimit@l(r9)
 	addis	r25,r25,-KERNELBASE@h
@@ -1773,7 +1954,7 @@
 	mfspr	r9,PVR
 	rlwinm	r9,r9,16,16,31
 	cmpi	0,r9,1
-	beq	4f			/* not needed for 601 */
+	beq	6f			/* not needed for 601 */
 	mfspr	r11,HID0
 	andi.	r0,r11,HID0_DCE
 	ori	r11,r11,HID0_ICE|HID0_DCE
@@ -1790,14 +1971,23 @@
 	cmpi	0,r9,4			/* check for 604 */
 	cmpi	1,r9,9			/* or 604e */
 	cmpi	2,r9,10			/* or mach5 */
+	cmpi	3,r9,8			/* check for 750 (G3) */
+	cmpi	4,r9,12			/* or 7400 (G4) */
 	cror	2,2,6
 	cror	2,2,10
 	bne	4f
 	ori	r11,r11,HID0_SIED|HID0_BHTE /* for 604[e], enable */
 	bne	2,5f
 	ori	r11,r11,HID0_BTCD
-5:	mtspr	HID0,r11		/* superscalar exec & br history tbl */
+	b	5f
 4:
+	cror	14,14,18
+	bne	3,6f
+	ori	r11,r11,HID0_SGE|HID0_BHTE|HID0_BTIC|HID0_ABE /* for g3/g4, enable */
+ 	li	r3,0
+ 	mtspr	ICTC,r3
+5:	mtspr	HID0,r11		/* superscalar exec & br history tbl */
+6:
 #endif /* CONFIG_8xx */
 #ifdef __SMP__
 	/* if we're the second cpu stack and r2 are different
@@ -1878,10 +2068,10 @@
 	li	r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
 	mtspr	SRR0,r4
 	mtspr	SRR1,r3
+	SYNC
 	rfi
 /* Load up the kernel context */
 2:
-	SYNC			/* Force all PTE updates to finish */
 	tlbia			/* Clear all TLB entries */
 	sync			/* wait for tlbia/tlbie to finish */
 #ifdef __SMP__
@@ -1938,6 +2128,7 @@
 #endif /* __SMP__ */
 	mtspr	SRR0,r3
 	mtspr	SRR1,r4
+	SYNC
 	rfi			/* enable MMU and jump to start_kernel */
 
 /*
@@ -2114,6 +2305,9 @@
 	mflr	r20		/* Return to switch caller */
 	mfmsr	r22
 	li	r0,MSR_FP	/* Disable floating-point */
+#ifdef CONFIG_ALTIVEC
+	oris	r0,r0,MSR_VEC@h
+#endif /* CONFIG_ALTIVEC */
 	andc	r22,r22,r0
 	stw	r20,_NIP(r1)
 	stw	r22,_MSR(r1)
@@ -2427,6 +2621,38 @@
 	blr
 
 /*
+ * Copy a whole page.  We use the dcbz instruction on the destination
+ * to reduce memory traffic (it eliminates the unnecessary reads of
+ * the destination into cache).  This requires that the destination
+ * is cacheable.
+ */
+_GLOBAL(copy_page)
+	li	r0,4096/CACHE_LINE_SIZE
+	mtctr	r0
+	addi	r3,r3,-4
+	addi	r4,r4,-4
+	li	r5,4
+1:	dcbz	r5,r3
+	lwz	r6,4(r4)
+	lwz	r7,8(r4)
+	lwz	r8,12(r4)
+	lwzu	r9,16(r4)
+	stw	r6,4(r3)
+	stw	r7,8(r3)
+	stw	r8,12(r3)
+	stwu	r9,16(r3)
+	lwz	r6,4(r4)
+	lwz	r7,8(r4)
+	lwz	r8,12(r4)
+	lwzu	r9,16(r4)
+	stw	r6,4(r3)
+	stw	r7,8(r3)
+	stw	r8,12(r3)
+	stwu	r9,16(r3)
+	bdnz	1b
+	blr
+
+/*
  * Flush entries from the hash table with VSIDs in the range
  * given.
  */
@@ -2604,7 +2830,6 @@
 	stw	r0,20(r1)
 	lis	r4,rtas_data@ha
 	lwz	r4,rtas_data@l(r4)
-	addis	r4,r4,-KERNELBASE@h
 	lis	r6,1f@ha	/* physical return address for rtas */
 	addi	r6,r6,1f@l
 	addis	r6,r6,-KERNELBASE@h
@@ -2624,6 +2849,7 @@
 	mtspr	SPRG2,r7
 	mtspr	SRR0,r8
 	mtspr	SRR1,r9
+	SYNC
 	rfi
 1:	addis	r9,r1,-KERNELBASE@h
 	lwz	r8,20(r9)	/* get return address */
@@ -2632,6 +2858,7 @@
 	mtspr	SPRG2,r0
 	mtspr	SRR0,r8
 	mtspr	SRR1,r9
+	SYNC
 	rfi			/* return to caller */
 #endif /* CONFIG_8xx */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/local_irq.h linux.17p18/arch/ppc/kernel/local_irq.h
--- linux.vanilla/arch/ppc/kernel/local_irq.h	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/local_irq.h	Tue Aug  1 07:59:05 2000
@@ -26,6 +26,7 @@
 struct irqdesc {
 	struct irqaction *action;
 	struct hw_interrupt_type *ctl;
+	int level;
 };
 
 extern struct irqdesc irq_desc[NR_IRQS];
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/mbx_setup.c linux.17p18/arch/ppc/kernel/mbx_setup.c
--- linux.vanilla/arch/ppc/kernel/mbx_setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/mbx_setup.c	Tue Aug  1 07:59:05 2000
@@ -41,7 +41,7 @@
 #include <asm/mbx.h>
 #include <asm/machdep.h>
 
-#include "time.h"
+#include <asm/time.h>
 #include "local_irq.h"
 
 static int mbx_set_rtc_time(unsigned long time);
@@ -454,6 +454,7 @@
 	ppc_md.kbd_init_hw       = pckbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
 	ppc_md.kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
+	ppc_md.SYSRQ_KEY	 = 0x54;
 #endif
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/misc.S linux.17p18/arch/ppc/kernel/misc.S
--- linux.vanilla/arch/ppc/kernel/misc.S	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/misc.S	Wed Aug 16 21:41:39 2000
@@ -275,10 +275,8 @@
 	stwcx.	r5,0,r3		/* Update with new value */
 	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
 	SMP_MB
-	cmpi	0,r5,0		/* Return 'true' IFF 0 */
-	li	r3,1
-	beqlr
-	li	r3,0
+	cntlzw	r3,r5
+	srwi	r3,r3,5
 	blr
 _GLOBAL(atomic_clear_mask)
 	SMP_WMB			/* wmb() */
@@ -406,48 +404,59 @@
 	blr	
 
 /*
- * Extended precision shifts
+ * Extended precision shifts.
+ * 
+ * Updated to be valid for shift counts from 0 to 63 inclusive.
+ * -- Gabriel
  *
  * R3/R4 has 64 bit value
  * R5    has shift count
  * result in R3/R4
  *
- *  ashrdi3:     XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
- *  ashldi3:     XXXYYY/ZZZAAA -> YYYZZZ/AAA000
- *  lshrdi3:     XXXYYY/ZZZAAA -> 000XXX/YYYZZZ
+ *  ashrdi3: arithmetic right shift (sign propagation)	    
+ *  lshrdi3: logical right shift	
+ *  ashldi3: left shift
  */
 _GLOBAL(__ashrdi3)
-	li	r6,32
-	sub	r6,r6,r5
-	slw	r7,r3,r6	/* isolate YYY */
-	srw	r4,r4,r5	/* isolate ZZZ */
-	or	r4,r4,r7	/* YYYZZZ */
-	sraw	r3,r3,r5	/* SSSXXX */
+	subfic	r6,r5,32	
+	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count
+	addi	r7,r5,32	# could be xori, or addi with -32
+	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count)
+	rlwinm	r8,r7,0,32	# t3 = (count < 32) ? 32 : 0
+	sraw	r7,r3,r7	# t2 = MSW >> (count-32)
+	or	r4,r4,r6	# LSW |= t1
+	slw	r7,r7,r8	# t2 = (count < 32) ? 0 : t2
+	sraw	r3,r3,r5	# MSW = MSW >> count
+	or	r4,r4,r7	# LSW |= t2
 	blr
 
 _GLOBAL(__ashldi3)
-	li	r6,32
-	sub	r6,r6,r5
-	srw	r7,r4,r6	/* isolate ZZZ */
-	slw	r4,r4,r5	/* AAA000 */
-	slw	r3,r3,r5	/* YYY--- */
-	or	r3,r3,r7	/* YYYZZZ */
+	subfic	r6,r5,32	
+	slw	r3,r3,r5	# MSW = count > 31 ? 0 : MSW << count
+	addi	r7,r5,32	# could be xori, or addi with -32
+	srw	r6,r4,r6	# t1 = count > 31 ? 0 : LSW >> (32-count)
+	slw	r7,r4,r7	# t2 = count < 32 ? 0 : LSW << (count-32)
+	or	r3,r3,r6	# MSW |= t1
+	slw	r4,r4,r5	# LSW = LSW << count
+	or	r3,r3,r7	# MSW |= t2
 	blr
 
 _GLOBAL(__lshrdi3)
-	li	r6,32
-	sub	r6,r6,r5
-	slw	r7,r3,r6        /* isolate YYY */
-	srw	r4,r4,r5        /* isolate ZZZ */
-	or	r4,r4,r7        /* YYYZZZ */
-	srw	r3,r3,r5        /* 000XXX */
+	subfic	r6,r5,32	
+	srw	r4,r4,r5	# LSW = count > 31 ? 0 : LSW >> count
+	addi	r7,r5,32	# could be xori, or addi with -32
+	slw	r6,r3,r6	# t1 = count > 31 ? 0 : MSW << (32-count)
+	srw	r7,r3,r7	# t2 = count < 32 ? 0 : MSW >> (count-32)
+	or	r4,r4,r6	# LSW |= t1
+	srw	r3,r3,r5	# MSW = MSW >> count
+	or	r4,r4,r7	# LSW |= t2 
 	blr
 
 _GLOBAL(abs)
-	cmpi	0,r3,0
-	bge	10f
-	neg	r3,r3
-10:	blr
+	srawi	r4,r3,31
+	xor	r3,r3,r4
+	sub	r3,r3,r4
+	blr
 
 _GLOBAL(_get_SP)
 	mr	r3,r1		/* Close enough */
@@ -480,6 +489,20 @@
 _GLOBAL(_get_PVR)
 	mfspr	r3,PVR
 	blr
+	
+_GLOBAL(_get_HID0)
+	mfspr	r3,HID0
+	blr
+
+_GLOBAL(_get_ICTC)
+	mfspr	r3,ICTC
+	blr
+
+_GLOBAL(_set_ICTC)
+	mtspr	ICTC,r3
+	blr
+
+	
 /*
 	L2CR functions
 	Copyright © 1997-1998 by PowerLogix R & D, Inc.
@@ -546,6 +569,8 @@
 	rlwinm	r4,r4,16,16,31
 	cmplwi	r4,0x0008
 	beq	thisIs750
+	cmplwi	r4,0x000c
+	beq thisIs750
 	li	r3,-1
 	blr
 	
@@ -640,9 +665,11 @@
 	mfspr	r3,PVR
 	rlwinm	r3,r3,16,16,31
 	cmplwi	r3,0x0008
+	beq	1f
+	cmplwi	r3,0x000c
 	li	r3,0
 	bnelr
-	
+1:	
 	/* Return the L2CR contents */
 	mfspr	r3,L2CR
 	blr
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/mk_defs.c linux.17p18/arch/ppc/kernel/mk_defs.c
--- linux.vanilla/arch/ppc/kernel/mk_defs.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/mk_defs.c	Tue Aug  1 07:59:05 2000
@@ -8,7 +8,7 @@
  * #defines from the assembly-language output.
  */
 
-#include <stddef.h>
+#include <linux/config.h>
 #include <linux/signal.h>
 #include <linux/sched.h>
 #include <linux/kernel.h>
@@ -48,6 +48,12 @@
 	DEFINE(NEED_RESCHED, offsetof(struct task_struct, need_resched));
 	DEFINE(TSS_FPR0, offsetof(struct thread_struct, fpr[0]));
 	DEFINE(TSS_FPSCR, offsetof(struct thread_struct, fpscr));
+#ifdef CONFIG_ALTIVEC
+	DEFINE(TSS_VR0, offsetof(struct thread_struct, vr[0]));
+	DEFINE(TSS_VRSAVE, offsetof(struct thread_struct, vrsave));
+	DEFINE(TSS_VSCR, offsetof(struct thread_struct, vscr));
+#endif /* CONFIG_ALTIVEC */
+
 	/* Interrupt register frame */
 	DEFINE(TASK_UNION_SIZE, sizeof(union task_union));
 	DEFINE(STACK_FRAME_OVERHEAD, STACK_FRAME_OVERHEAD);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/openpic.c linux.17p18/arch/ppc/kernel/openpic.c
--- linux.vanilla/arch/ppc/kernel/openpic.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/openpic.c	Tue Aug  1 07:59:05 2000
@@ -5,6 +5,12 @@
  *
  *  Fixed up IPI and restructured a bit
  *    Cort Dougan <cort@ppc.kernel.org>
+ *
+ *  Added initialisation code for Apple Core99 machines, tweaked a few things
+ *  to avoid bogus interrupts and to make sure the disable function exits with
+ *  the interrupt actually masked.
+ *    Benjamin Herrenschmidt <bh40@calva.net>
+ *  Todo: map interrupts to all available CPUs after the ack round
  * 
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License.  See the file COPYING in the main directory of this archive
@@ -21,10 +27,17 @@
 #include <asm/io.h>
 #include <asm/irq.h>
 #include "open_pic.h"
+#ifdef __powerpc__
+#include <asm/prom.h>
+#endif
 
 #define REGISTER_DEBUG
 #undef REGISTER_DEBUG
 
+#ifdef __powerpc__
+extern int use_of_interrupt_tree;
+#endif
+
 volatile struct OpenPIC *OpenPIC = NULL;
 u_int OpenPIC_NumInitSenses __initdata = 0;
 u_char *OpenPIC_InitSenses __initdata = NULL;
@@ -80,7 +93,7 @@
  *  I/O functions
  */
 #ifdef __i386__
-static inline u_int ld_le32(volatile u_int *addr)
+static inline u_int in_le32(volatile u_int *addr)
 {
 	return *addr;
 }
@@ -95,7 +108,7 @@
 {
 	u_int val;
 
-	val = ld_le32(addr);
+	val = in_le32(addr);
 #ifdef REGISTER_DEBUG
 	printk("openpic_read(0x%08x) = 0x%08x\n", (u_int)addr, val);
 #endif
@@ -142,6 +155,9 @@
 {
 	openpic_setfield(addr, OPENPIC_MASK);
 	/* wait until it's not in use */
+	/* BenH: Is this code really enough ? I would rather check the result
+	 *       and eventually retry ...
+	 */
 	while (openpic_read(addr) & OPENPIC_ACTIVITY);
 	openpic_writefield(addr, mask | OPENPIC_MASK, field | OPENPIC_MASK);
 }
@@ -149,6 +165,16 @@
 /*
  *  Initialize the OpenPIC
  */
+
+/* PoweMac note:
+ *
+ * With BootX, we consider the controller as beeing already initialized by MacOS
+ * and we only mask out interrupts.
+ * With OF booting, we initialize the interrupts that we find in the device tree,
+ * other ones are just masked out.
+ * Note: We might want to adjust priorities too.
+ */
+
 __initfunc(void openpic_init(int main_pic))
 {
 	u_int t, i;
@@ -179,13 +205,16 @@
 		      OPENPIC_FEATURE_LAST_SOURCE_SHIFT) + 1;
 	printk("OpenPIC Version %s (%d CPUs and %d IRQ sources) at %p\n", version,
 	       NumProcessors, NumSources, OpenPIC);
-	timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
-	printk("OpenPIC timer frequency is ");
-	if (timerfreq)
-		printk("%d Hz\n", timerfreq);
-	else
-		printk("not set\n");
-
+	/* Apple's OpenPIC is an IBM MPIC without the timer. */
+	if (_machine != _MACH_Pmac) {
+		timerfreq = openpic_read(&OpenPIC->Global.Timer_Frequency);
+		printk("OpenPIC timer frequency is ");
+		if (timerfreq)
+			printk("%d Hz\n", timerfreq);
+		else
+			printk("not set\n");
+	}
+	
 	if ( main_pic )
 	{
 		/* Initialize timer interrupts */
@@ -198,24 +227,60 @@
 	    
 		/* Initialize IPI interrupts */
 		for (i = 0; i < OPENPIC_NUM_IPI; i++) {
-			openpic_initipi(i, 10, OPENPIC_VEC_IPI+i);
+			openpic_initipi(i, 0/*10*/, OPENPIC_VEC_IPI+i);
 		}
 	    
-		/* Initialize external interrupts */
-		for (i = 0; i < NumSources; i++) {
-			/* Enabled, Priority 8 */
-			openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
-					i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1);
-			/* Processor 0 */
-			openpic_mapirq(i, 1<<0);
+		if (_machine != _MACH_Pmac) {
+			/* Initialize external interrupts */
+			for (i = 0; i < NumSources; i++) {
+			    /* Enabled, Priority 8 */
+			    openpic_initirq(i, 8, open_pic.irq_offset+i, 0,
+				i < OpenPIC_NumInitSenses ? OpenPIC_InitSenses[i] : 1);
+			    /* Processor 0 */
+			    openpic_mapirq(i, 1<<0);
+			}
+		} else {
+			/* Prevent any interrupt from occuring during initialisation.
+			 * Hum... I beleive this is not necessary, Apple does that in
+			 * Darwin's PowerExpress code.
+			 */
+			openpic_set_priority(0, 0xf);
+
+			/* First disable all interrupts and map them to CPU 0 */
+			for (i = 0; i < NumSources; i++) {
+				openpic_disable_irq(i);
+				openpic_mapirq(i, 1<<0);
+			}
+			
+			/* If we use the device tree, then lookup all interrupts and
+			 * initialize them according to sense infos found in the tree
+			 */
+			if (use_of_interrupt_tree) {
+				struct device_node* np = find_all_nodes();
+			    	while(np) {
+				    int j, pri;
+				    pri = strcmp(np->name, "programmer-switch") ? 2 : 7;
+				    for (j=0;j<np->n_intrs;j++) {
+    				    	openpic_initirq(	np->intrs[j].line,
+    				    				pri,
+    				    				np->intrs[j].line,
+    				    				np->intrs[j].sense,
+    				    				np->intrs[j].sense);
+    				    	irq_desc[np->intrs[j].line].level = np->intrs[j].sense;
+    				    }
+				    np = np->next;
+				}
+			} else {
+				/* Fixme: read level value from controller */
+				printk("openpic: WARNING, openpic running without interrupt tree\n");
+			}
 		}
-	    
+
 		/* Initialize the spurious interrupt */
 		openpic_set_spurious(OPENPIC_VEC_SPURIOUS);
 
 		/* Gemini has no i8259 */
-		if ( _machine != _MACH_gemini )
-		{
+		if (( _machine != _MACH_gemini ) && (_machine != _MACH_Pmac)) {
 			/* SIOint (8259 cascade) is special */
 			openpic_initirq(0, 8, open_pic.irq_offset, 1, 1);
 			openpic_mapirq(0, 1<<0);
@@ -225,6 +290,14 @@
 		}
 		openpic_set_priority(0, 0);
 		openpic_disable_8259_pass_through();
+
+		/* We ack pending interrupts to avoid blocking them */
+		if (_machine == _MACH_Pmac) {
+			for (i = 0; i < NumSources; i++) {
+				(void)openpic_irq(0);
+				openpic_eoi(0);
+			}
+		}
 	}
 }
 
@@ -281,6 +354,7 @@
 {
 	check_arg_cpu(cpu);
 	openpic_write(&OpenPIC->THIS_CPU.EOI, 0);
+	(void)openpic_read(&OpenPIC->THIS_CPU.EOI);
 }
 
 
@@ -428,12 +502,22 @@
 {
 	check_arg_irq(irq);
 	openpic_clearfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK);
+	/* make sure mask gets to controller before we return to user */
+	do {
+		mb();
+	} while(openpic_readfield(&OpenPIC->Source[irq].Vector_Priority,
+			OPENPIC_MASK));
 }
 
 void openpic_disable_irq(u_int irq)
 {
 	check_arg_irq(irq);
 	openpic_setfield(&OpenPIC->Source[irq].Vector_Priority, OPENPIC_MASK);
+	/* make sure mask gets to controller before we return to user */
+	do {
+		mb();
+	} while(!openpic_readfield(&OpenPIC->Source[irq].Vector_Priority,
+    			OPENPIC_MASK));
 }
 
 /*
@@ -452,10 +536,11 @@
 	check_arg_vec(vec);
 	openpic_safe_writefield(&OpenPIC->Source[irq].Vector_Priority,
 				OPENPIC_PRIORITY_MASK | OPENPIC_VECTOR_MASK |
-				OPENPIC_SENSE_POLARITY | OPENPIC_SENSE_LEVEL,
+				OPENPIC_POLARITY_MASK | OPENPIC_SENSE_MASK,
 				(pri << OPENPIC_PRIORITY_SHIFT) | vec |
-				(pol ? OPENPIC_SENSE_POLARITY : 0) |
-				(sense ? OPENPIC_SENSE_LEVEL : 0));
+				(pol ? OPENPIC_POLARITY_POSITIVE :
+			    		OPENPIC_POLARITY_NEGATIVE) |
+				(sense ? OPENPIC_SENSE_LEVEL : OPENPIC_SENSE_EDGE));
 }
 
 /*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/pci.c linux.17p18/arch/ppc/kernel/pci.c
--- linux.vanilla/arch/ppc/kernel/pci.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/pci.c	Tue Aug  1 07:59:05 2000
@@ -93,7 +93,7 @@
 
 	for (; node != 0;node = node->sibling) {
 		class_code = (unsigned int *) get_property(node, "class-code", 0);
-		if((*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
+		if(class_code && (*class_code >> 8) == PCI_CLASS_BRIDGE_PCI)
 			fix_intr(node->child, dev);
 		reg = (unsigned int *) get_property(node, "reg", 0);
 		if (reg == 0 || ((reg[0] >> 8) & 0xff) != dev->devfn)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/pmac_pci.c linux.17p18/arch/ppc/kernel/pmac_pci.c
--- linux.vanilla/arch/ppc/kernel/pmac_pci.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/pmac_pci.c	Tue Aug  1 07:59:05 2000
@@ -28,6 +28,18 @@
 struct bridge_data **bridges, *bridge_list;
 static int max_bus;
 
+struct uninorth_data {
+	struct device_node*	node;
+	volatile unsigned int*	cfg_addr;
+	volatile unsigned int*	cfg_data;
+};
+
+static struct uninorth_data uninorth_bridges[3];
+static int uninorth_count;
+static int uninorth_default = -1;
+ 
+
+
 static void add_bridges(struct device_node *dev, unsigned long *mem_ptr);
 
 /*
@@ -71,6 +83,161 @@
 	return 0;
 }
 
+/* This function only works for bus 0, uni-N uses a different mecanism for
+ * other busses (see below)
+ */
+#define UNI_N_CFA0(devfn, off)	\
+	((1 << (unsigned long)PCI_SLOT(dev_fn)) \
+	| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
+	| (((unsigned long)(off)) & 0xFCUL))
+
+/* This one is for type 1 config accesses */
+#define UNI_N_CFA1(bus, devfn, off)	\
+	((((unsigned long)(bus)) << 16) \
+	|(((unsigned long)(devfn)) << 8) \
+	|(((unsigned long)(off)) & 0xFCUL) \
+	|1UL)
+	
+
+/* We should really use RTAS here, unfortunately, it's not available with BootX.
+ * (one more reason for writing a beautiful OF booter). I'll do the RTAS stuff
+ * later, once I have something that works enough with BootX.
+ */
+__pmac static
+unsigned int
+uni_north_access_data(unsigned char bus, unsigned char dev_fn,
+				unsigned char offset)
+{
+	struct device_node *node, *bridge_node;
+	int bridge = uninorth_default;
+	unsigned int caddr;
+
+	if (bus == 0) {
+		if (PCI_SLOT(dev_fn) < 11) {
+			return 0;
+		}
+		/* We look for the OF device corresponding to this bus/devfn pair. If we
+		 * don't find it, we default to the external PCI */
+		bridge_node = NULL;
+		node = find_pci_device_OFnode(bus, dev_fn & 0xf8);
+		if (node) {
+                    /* note: we don't stop on the first occurence since we need to go
+                     * up to the root bridge */
+		    do {
+			if (!strcmp(node->type, "pci"))
+				bridge_node = node;
+			node=node->parent;
+		    } while (node);
+		}
+		if (bridge_node) {
+		    int i;
+		    for (i=0;i<uninorth_count;i++)
+			if (uninorth_bridges[i].node == bridge_node) {
+			    bridge = i;
+			    break;
+			}
+		}
+		caddr = UNI_N_CFA0(dev_fn, offset);
+	} else
+		caddr = UNI_N_CFA1(bus, dev_fn, offset);
+
+	if (bridge == -1) {
+		printk(KERN_WARNING "pmac_pci: no default bridge !\n");
+		return 0;
+	}
+		
+	/* Uninorth will return garbage if we don't read back the value ! */
+	out_le32(uninorth_bridges[bridge].cfg_addr, caddr);
+	(void)in_le32(uninorth_bridges[bridge].cfg_addr);
+	/* Yes, offset is & 7, not & 3 ! */
+	return (unsigned int)(uninorth_bridges[bridge].cfg_data) + (offset & 0x07);
+}
+
+__pmac
+int uni_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
+				  unsigned char offset, unsigned char *val)
+{
+	unsigned int addr;
+	
+	*val = 0xff;
+	addr = uni_north_access_data(bus, dev_fn, offset);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	*val = in_8((volatile unsigned char*)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+__pmac
+int uni_pcibios_read_config_word(unsigned char bus, unsigned char dev_fn,
+				  unsigned char offset, unsigned short *val)
+{
+	unsigned int addr;
+	
+	*val = 0xffff;
+	addr = uni_north_access_data(bus, dev_fn, offset);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	*val = in_le16((volatile unsigned short*)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+__pmac
+int uni_pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn,
+				   unsigned char offset, unsigned int *val)
+{
+	unsigned int addr;
+	
+	*val = 0xffff;
+	addr = uni_north_access_data(bus, dev_fn, offset);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	*val = in_le32((volatile unsigned int*)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+__pmac
+int uni_pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn,
+				   unsigned char offset, unsigned char val)
+{
+	unsigned int addr;
+	
+	addr = uni_north_access_data(bus, dev_fn, offset);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	out_8((volatile unsigned char *)addr, val);
+	(void)in_8((volatile unsigned char *)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+__pmac
+int uni_pcibios_write_config_word(unsigned char bus, unsigned char dev_fn,
+				   unsigned char offset, unsigned short val)
+{
+	unsigned int addr;
+	
+	addr = uni_north_access_data(bus, dev_fn, offset);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	out_le16((volatile unsigned short *)addr, val);
+	(void)in_le16((volatile unsigned short *)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+__pmac
+int uni_pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn,
+				    unsigned char offset, unsigned int val)
+{
+	unsigned int addr;
+	
+	addr = uni_north_access_data(bus, dev_fn, offset);
+	if (!addr)
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	out_le32((volatile unsigned int *)addr, val);
+	(void)in_le32((volatile unsigned int *)addr);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+
 __pmac
 int pmac_pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn,
 				  unsigned char offset, unsigned char *val)
@@ -360,6 +527,36 @@
 	       bp->io_base);
 }
 
+#define GRACKLE_PICR1_STG		0x00000040
+#define GRACKLE_PICR1_LOOPSNOOP		0x00000010
+
+/* N.B. this is called before bridges is initialized, so we can't
+   use grackle_pcibios_{read,write}_config_dword. */
+static inline void grackle_set_stg(struct bridge_data *bp, int enable)
+{
+	unsigned int val;
+
+	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+	val = in_le32((volatile unsigned int *)bp->cfg_data);
+	val = enable? (val | GRACKLE_PICR1_STG) :
+		(val & ~GRACKLE_PICR1_STG);
+	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+	out_le32((volatile unsigned int *)bp->cfg_data, val);
+}
+
+static inline void grackle_set_loop_snoop(struct bridge_data *bp, int enable)
+{
+	unsigned int val;
+
+	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+	val = in_le32((volatile unsigned int *)bp->cfg_data);
+	val = enable? (val | GRACKLE_PICR1_LOOPSNOOP) :
+		(val & ~GRACKLE_PICR1_LOOPSNOOP);
+	out_be32(bp->cfg_addr, GRACKLE_CFA(0, 0, 0xa8));
+	out_le32((volatile unsigned int *)bp->cfg_data, val);
+}
+
+
 __initfunc(unsigned long pmac_find_bridges(unsigned long mem_start, unsigned long mem_end))
 {
 	int bus;
@@ -411,21 +608,49 @@
 			printk(KERN_INFO "PCI buses %d..%d", bus_range[0],
 			       bus_range[1]);
 		printk(" controlled by %s at %x\n", dev->name, addr->address);
+		if (device_is_compatible(dev, "uni-north")) {
+			int i = uninorth_count++;
+			uninorth_bridges[i].cfg_addr = ioremap(addr->address + 0x800000, 0x1000);
+			uninorth_bridges[i].cfg_data = ioremap(addr->address + 0xc00000, 0x1000);
+			uninorth_bridges[i].node = dev;
+			/* XXX This is the bridge with the PCI expansion bus. This is also the
+			 * address of the bus that will receive type 1 config accesses and io
+			 * accesses. Appears to be correct for iMac DV and G4 Sawtooth too.
+			 * That means that we cannot do io cycles on the AGP bus nor the internal
+			 * ethernet/fw bus. Fortunately, they appear not to be needed on iMac DV
+			 * and G4 neither.
+			 */
+			if (addr->address == 0xf2000000)
+				uninorth_default = i;
+			else
+				continue;
+		}
 		bp = (struct bridge_data *) *mem_ptr;
 		*mem_ptr += sizeof(struct bridge_data);
-		if (strcmp(dev->name, "pci") != 0) {
-			bp->cfg_addr = (volatile unsigned int *)
-				ioremap(addr->address + 0x800000, 0x1000);
-			bp->cfg_data = (volatile unsigned char *)
-				ioremap(addr->address + 0xc00000, 0x1000);
-			bp->io_base = (void *) ioremap(addr->address, 0x10000);
-		} else {
-			/* XXX */
+		if (device_is_compatible(dev, "uni-north")) {
+			bp->cfg_addr = 0;
+			bp->cfg_data = 0;
+			/* is 0x10000 enough for io space ? */
+			bp->io_base = (void *)ioremap(addr->address, 0x10000);
+		} else if (strcmp(dev->name, "pci") == 0) {
+			/* XXX assume this is a mpc106 (grackle) */
 			bp->cfg_addr = (volatile unsigned int *)
 				ioremap(0xfec00000, 0x1000);
 			bp->cfg_data = (volatile unsigned char *)
 				ioremap(0xfee00000, 0x1000);
                         bp->io_base = (void *) ioremap(0xfe000000, 0x20000);
+                        if (machine_is_compatible("AAPL,PowerBook1998"))
+                        	grackle_set_loop_snoop(bp, 1);
+#if 0 			/* Disabled for now, HW problems ??? */
+			grackle_set_stg(bp, 1);
+#endif
+		} else {
+			/* a `bandit' or `chaos' bridge */
+			bp->cfg_addr = (volatile unsigned int *)
+				ioremap(addr->address + 0x800000, 0x1000);
+			bp->cfg_data = (volatile unsigned char *)
+				ioremap(addr->address + 0xc00000, 0x1000);
+			bp->io_base = (void *) ioremap(addr->address, 0x10000);
 		}
 		if (isa_io_base == 0)
 			isa_io_base = (unsigned long) bp->io_base;
@@ -468,7 +693,13 @@
 		if (pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin) ||
 		    !pin)
 			continue; /* No interrupt generated -> no fixup */
-                fix_intr(bp->node->child, dev);
+		/* We iterate all instances of uninorth for now */	
+		if (uninorth_count && dev->bus->number == 0) {
+			int i;
+			for (i=0;i<uninorth_count;i++)
+				fix_intr(uninorth_bridges[i].node->child, dev);
+		} else
+                	fix_intr(bp->node->child, dev);
 	}
 }
 
@@ -476,9 +707,17 @@
 void
 pmac_setup_pci_ptrs(void))
 {
-	if (find_devices("pci") != 0) {
-		/* looks like a G3 powermac */
-		set_config_access_method(grackle);
+	struct device_node* np;
+
+	np = find_devices("pci");
+	if (np != 0) {
+		if (device_is_compatible(np, "uni-north")) {
+			/* looks like an Core99 powermac */
+			set_config_access_method(uni);
+		} else {
+			/* looks like a G3 powermac */
+			set_config_access_method(grackle);
+		}
 	} else {
 		set_config_access_method(pmac);
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/pmac_pic.c linux.17p18/arch/ppc/kernel/pmac_pic.c
--- linux.vanilla/arch/ppc/kernel/pmac_pic.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/pmac_pic.c	Tue Aug  1 07:59:05 2000
@@ -4,6 +4,7 @@
 #include <linux/sched.h>
 #include <linux/signal.h>
 #include <linux/pci.h>
+#include <linux/openpic.h>
 #include <asm/pci-bridge.h>
 #include <asm/io.h>
 #include <asm/smp.h>
@@ -27,6 +28,7 @@
 
 static int max_irqs;
 static int max_real_irqs;
+static int has_openpic = 0;
 
 #define MAXCOUNT 10000000
 
@@ -104,6 +106,18 @@
         pmac_set_irq_mask(irq_nr);
 }
 
+static void pmac_openpic_mask_irq(unsigned int irq_nr)
+{
+	openpic_disable_irq(irq_nr);
+}
+
+static void pmac_openpic_unmask_irq(unsigned int irq_nr)
+{
+	openpic_enable_irq(irq_nr);
+}
+
+
+
 struct hw_interrupt_type pmac_pic = {
         " PMAC-PIC ",
         NULL,
@@ -126,6 +140,17 @@
 	0
 };
 
+struct hw_interrupt_type pmac_open_pic = {
+	" OpenPIC  ",
+	NULL,
+	NULL,
+	NULL,
+	pmac_openpic_unmask_irq,
+	pmac_openpic_mask_irq,
+	NULL,/*pmac_openpic_mask_irq,*/
+	0
+};
+
 static void gatwick_action(int cpl, void *dev_id, struct pt_regs *regs)
 {
 	int irq, bits;
@@ -196,6 +221,29 @@
         }
 #endif /* __SMP__ */
 
+	/* Yeah, I know, this could be a separate do_IRQ function */
+	if (has_openpic) {
+	    irq = openpic_irq(0);
+	    if (irq == OPENPIC_VEC_SPURIOUS) {
+                /* Spurious interrupts should never be ack'ed */
+                ppc_spurious_interrupts++;
+            } else {
+            	/* Can this happen ? (comes from CHRP code) */
+		if (irq < 0) {
+		    printk(KERN_DEBUG "Bogus interrupt %d from PC = %lx\n",
+                       irq, regs->nip);
+		    ppc_spurious_interrupts++;
+		} else {
+		    if (!irq_desc[irq].level)
+	                openpic_eoi(0);
+		    ppc_irq_dispatch_handler( regs, irq );
+		    if (irq_desc[irq].level)
+	                openpic_eoi(0);
+		}
+            }
+            return;
+	}
+
         for (irq = max_real_irqs - 1; irq > 0; irq -= 32) {
                 int i = irq >> 5;
                 bits = ld_le32(&pmac_irq_hw[i]->flag)
@@ -350,6 +398,36 @@
         struct device_node *irqctrler;
         volatile struct pmac_irq_hw *addr;
 	int second_irq;
+
+	/* We first try to detect Apple's new Core99 chipset, since mac-io
+	 * is quite different on those machines and contains an IBM MPIC2.
+	 */
+	irqctrler = find_type_devices("open-pic");
+	if (irqctrler != NULL) {
+	    printk("PowerMac using OpenPIC irq controller\n");
+	    if (irqctrler->n_addrs > 0) {
+#ifdef CONFIG_XMON
+		struct device_node* pswitch;
+#endif /* CONFIG_XMON */	
+		OpenPIC = (volatile struct OpenPIC *)
+			ioremap(irqctrler->addrs[0].address,
+			irqctrler->addrs[0].size);
+		for ( i = 0 ; i < NR_IRQS ; i++ ) {
+		    irq_desc[i].ctl = &pmac_open_pic;
+		    irq_desc[i].level = 0;
+		}
+		openpic_init(1);
+		has_openpic = 1;
+#ifdef CONFIG_XMON
+		pswitch = find_devices("programmer-switch");
+		if (pswitch && pswitch->n_intrs)
+			request_irq(pswitch->intrs[0].line, xmon_irq, 0,	
+				"NMI - XMON", 0);
+#endif	/* CONFIG_XMON */
+		return;
+	    }
+	    irqctrler = NULL;
+	}
 
 	/*
 	 * G3 powermacs and 1999 G3 PowerBooks have 64 interrupts,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/pmac_setup.c linux.17p18/arch/ppc/kernel/pmac_setup.c
--- linux.vanilla/arch/ppc/kernel/pmac_setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/pmac_setup.c	Tue Aug  1 07:59:05 2000
@@ -58,12 +58,13 @@
 #include <asm/ide.h>
 #include <asm/machdep.h>
 
-#include "time.h"
+#include <asm/time.h>
 #include "local_irq.h"
 #include "pmac_pic.h"
 
 #undef SHOW_GATWICK_IRQS
 
+void pmac_time_init(void);
 unsigned long pmac_get_rtc_time(void);
 int pmac_set_rtc_time(unsigned long nowtime);
 void pmac_read_rtc_time(void);
@@ -87,6 +88,7 @@
 extern char pckbd_unexpected_up(unsigned char keycode);
 extern void pckbd_leds(unsigned char leds);
 extern void pckbd_init_hw(void);
+extern void pmac_nvram_update(void);
 
 unsigned char drive_info;
 
@@ -95,11 +97,14 @@
 
 extern char saved_command_line[];
 
+extern int pmac_newworld;
+
 #define DEFAULT_ROOT_DEVICE 0x0801	/* sda1 - slightly silly choice */
 
 extern void zs_kgdb_hook(int tty_num);
 static void ohare_init(void);
 static void init_p2pbridge(void);
+static void init_uninorth(void);
 
 __pmac
 int
@@ -187,6 +192,10 @@
 			len += sprintf(buffer+len, "l2cr override\t: 0x%x\n", *l2cr);
 		}
 	}
+
+	/* Indicate newworld/oldworld */
+	len += sprintf(buffer+len, "pmac-generation\t: %s\n",
+		pmac_newworld ? "NewWorld" : "OldWorld");		
 	
 	return len;
 }
@@ -246,8 +255,10 @@
 		if (fp != 0) {
 			switch (_get_PVR() >> 16) {
 			case 4:		/* 604 */
+			case 8:		/* G3 */
 			case 9:		/* 604e */
 			case 10:	/* mach V (604ev5) */
+			case 12:	/* G4 */
 			case 20:	/* 620 */
 				loops_per_sec = *fp;
 				break;
@@ -266,9 +277,10 @@
 
 	*memory_start_p = pmac_find_bridges(*memory_start_p, *memory_end_p);
 	init_p2pbridge();
-
+	init_uninorth();
+	
 	/* Checks "l2cr-value" property in the registry */
-	if ( (_get_PVR() >> 16) == 8) {
+	if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) {
 		struct device_node *np = find_devices("cpus");		
 		if (np == 0)
 			np = find_type_devices("cpu");		
@@ -288,7 +300,6 @@
 		printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n",
 			ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000)
 				? "enabled" : "disabled");
-
 	feature_init();
 
 #ifdef CONFIG_KGDB
@@ -298,6 +309,8 @@
 	find_via_cuda();
 	find_via_pmu();
 
+	pmac_nvram_init();
+
 #ifdef CONFIG_DUMMY_CONSOLE
 	conswitchp = &dummy_con;
 #endif
@@ -355,6 +368,38 @@
 	}
 }
 
+__initfunc(static void init_uninorth(void))
+{
+	/* 
+	 * Turns OFF the gmac clock. The gmac driver will turn
+	 * it back ON when the interface is enabled. This save
+	 * power on portables.
+	 * 
+	 * Note: We could also try to turn OFF the PHY. Since this
+	 * has to be done by both the gmac driver and this code,
+	 * I'll probably end-up moving some of this out of the
+	 * modular gmac driver into a non-modular stub containing
+	 * some basic PHY management and power management stuffs
+	 */
+	struct device_node* uni_n = find_devices("uni-n");
+	struct device_node* gmac = find_devices("ethernet");
+	unsigned long* addr;
+	
+	if (!uni_n || uni_n->n_addrs < 1)
+		return;
+	addr = ioremap(uni_n->addrs[0].address, 0x300);
+
+	while(gmac) {
+		if (device_is_compatible(gmac, "gmac"))
+			break;
+		gmac = gmac->next;
+	}
+	if (gmac) {
+		*(addr + 8) &= ~0x00000002UL;
+		eieio();
+	}
+}
+
 extern char *bootpath;
 extern char *bootdevice;
 void *boot_host;
@@ -366,7 +411,6 @@
 pmac_init2(void))
 {
 	adb_init();
-	pmac_nvram_init();
 	media_bay_init();
 }
 
@@ -402,14 +446,13 @@
 #endif
 
 #ifdef CONFIG_BLK_DEV_IDE_PMAC
-extern int pmac_ide_count;
-extern struct device_node *pmac_ide_node[];
-static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
+
+extern kdev_t pmac_find_ide_boot(char *bootdevice, int n);
 
 __initfunc(kdev_t find_ide_boot(void))
 {
 	char *p;
-	int i, n;
+	int n;
 
 	if (bootdevice == NULL)
 		return 0;
@@ -418,18 +461,7 @@
 		return 0;
 	n = p - bootdevice;
 
-	/*
-	 * Look through the list of IDE interfaces for this one.
-	 */
-	for (i = 0; i < pmac_ide_count; ++i) {
-		char *name = pmac_ide_node[i]->full_name;
-		if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {
-			/* XXX should cope with the 2nd drive as well... */
-			return MKDEV(ide_majors[i], 0);
-		}
-	}
-
-	return 0;
+	return pmac_find_ide_boot(bootdevice, n);
 }
 #endif /* CONFIG_BLK_DEV_IDE_PMAC */
 
@@ -468,7 +500,7 @@
 	if (boot_dev == 0 || dev == boot_dev) {
 		ROOT_DEV = MKDEV(MAJOR(dev), MINOR(dev) + part);
 		boot_dev = NODEV;
-		printk(" (root)");
+		printk(" (root on %d)", part);
 	}
 }
 
@@ -477,6 +509,8 @@
 {
 	struct adb_request req;
 
+	pmac_nvram_update();
+	
 	switch (adb_hardware) {
 	case ADB_VIACUDA:
 		cuda_request(&req, NULL, 2, CUDA_PACKET,
@@ -497,6 +531,8 @@
 {
 	struct adb_request req;
 
+	pmac_nvram_update();
+	
 	switch (adb_hardware) {
 	case ADB_VIACUDA:
 		cuda_request(&req, NULL, 2, CUDA_PACKET,
@@ -515,7 +551,6 @@
 void
 pmac_halt(void)
 {
-   pmac_power_off();
 }
 
 
@@ -541,11 +576,15 @@
         return 0;
 }
 
+#if defined(CONFIG_BLK_DEV_IDE_PMAC)
+extern ide_ioreg_t pmac_ide_get_base(int index);
+#endif
+
 ide_ioreg_t
 pmac_ide_default_io_base(int index)
 {
 #if defined(CONFIG_BLK_DEV_IDE_PMAC)
-        return pmac_ide_regbase[index];
+        return pmac_ide_get_base(index);
 #else
 	return 0;
 #endif
@@ -611,7 +650,7 @@
 	ppc_md.power_off      = pmac_power_off;
 	ppc_md.halt           = pmac_halt;
 
-	ppc_md.time_init      = NULL;
+	ppc_md.time_init      = pmac_time_init;
 	ppc_md.set_rtc_time   = pmac_set_rtc_time;
 	ppc_md.get_rtc_time   = pmac_get_rtc_time;
 	ppc_md.calibrate_decr = pmac_calibrate_decr;
@@ -625,6 +664,7 @@
 	ppc_md.kbd_init_hw       = mackbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
 	ppc_md.kbd_sysrq_xlate	 = mackbd_sysrq_xlate;
+	ppc_md.SYSRQ_KEY	 = 0x69;
 #endif
 #endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/pmac_support.c linux.17p18/arch/ppc/kernel/pmac_support.c
--- linux.vanilla/arch/ppc/kernel/pmac_support.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/pmac_support.c	Tue Aug  1 07:59:05 2000
@@ -1,10 +1,19 @@
 /*
  * Miscellaneous procedures for dealing with the PowerMac hardware.
+ * Contains support for the nvram.
+ * 
+ *   Copyright (C) 2000 Paul Mackerras
+ *   Copyright (C) 2000 Benjamin Herrenschmidt
+ *
+ * ToDo: Handle type 0 and type 1 "NameRegistry" NVRAM properties. Those
+ *       contain, among other things, the brightness, video mode, etc...
  */
 #include <linux/kernel.h>
 #include <linux/stddef.h>
 #include <linux/reboot.h>
 #include <linux/nvram.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
 #include <asm/init.h>
 #include <asm/ptrace.h>
 #include <asm/io.h>
@@ -13,6 +22,39 @@
 #include <asm/prom.h>
 #include <asm/adb.h>
 #include <asm/pmu.h>
+#include <asm/machdep.h>
+#include <asm/nvram.h>
+
+#undef DEBUG
+
+#define NVRAM_SIZE		0x2000	/* 8kB of non-volatile RAM */
+
+#define CORE99_SIGNATURE	0x5a
+#define CORE99_ADLER_START	0x14
+
+/* Core99 nvram is a flash */
+#define CORE99_FLASH_STATUS_DONE	0x80
+#define CORE99_FLASH_STATUS_ERR		0x38
+#define CORE99_FLASH_CMD_ERASE_CONFIRM	0xd0
+#define CORE99_FLASH_CMD_ERASE_SETUP	0x20
+#define CORE99_FLASH_CMD_RESET		0xff
+#define CORE99_FLASH_CMD_WRITE_SETUP	0x40
+
+/* CHRP NVRAM header */
+struct chrp_header {
+	u8	signature;
+	u8	cksum;
+	u16	len;
+	char    name[12];
+	u8	data[0];
+};
+
+struct core99_header {
+	struct chrp_header hdr;
+	u32	adler;
+	u32	generation;
+	u32	reserved[2];
+};
 
 /*
  * Read and write the non-volatile RAM on PowerMacs and CHRP machines.
@@ -20,24 +62,217 @@
 static int nvram_naddrs;
 static volatile unsigned char *nvram_addr;
 static volatile unsigned char *nvram_data;
-static int nvram_mult;
+static int nvram_mult, is_core_99;
+static int core99_bank = 0;
+static int nvram_partitions[3];
+
+/* FIXME: kmalloc fails to allocate the image now that I had to move it
+ *        before time_init(). For now, I allocate a static buffer here
+ *        but it's a waste of space on all but core99 machines
+ */
+#if 0
+static char* nvram_image;
+#else
+__pmac static char nvram_image[NVRAM_SIZE];
+#endif
+
+extern int pmac_newworld;
+
+static u8
+chrp_checksum(struct chrp_header* hdr)
+{
+	u8 *ptr;
+	u16 sum = hdr->signature;
+	for (ptr = (u8 *)&hdr->len; ptr < hdr->data; ptr++)
+		sum += *ptr;
+	while (sum > 0xFF)
+		sum = (sum & 0xFF) + (sum>>8);
+	return sum;
+}
+
+static u32
+core99_calc_adler(u8 *buffer)
+{
+	int cnt;
+	u32 low, high;
+
+   	buffer += CORE99_ADLER_START;
+	low = 1;
+	high = 0;
+	for (cnt=0; cnt<(NVRAM_SIZE-CORE99_ADLER_START); cnt++) {
+		if ((cnt % 5000) == 0) {
+			high  %= 65521UL;
+			high %= 65521UL;
+		}
+		low += buffer[cnt];
+		high += low;
+	}
+	low  %= 65521UL;
+	high %= 65521UL;
+  
+	return (high << 16) | low;
+}
+
+static u32
+core99_check(u8* datas)
+{
+	struct core99_header* hdr99 = (struct core99_header*)datas;
+
+	if (hdr99->hdr.signature != CORE99_SIGNATURE) {
+#ifdef DEBUG
+		printk("Invalid signature\n");
+#endif		
+		return 0;
+	}
+	if (hdr99->hdr.cksum != chrp_checksum(&hdr99->hdr)) {
+#ifdef DEBUG
+		printk("Invalid checksum\n");
+#endif
+		return 0;
+	}
+	if (hdr99->adler != core99_calc_adler(datas)) {
+#ifdef DEBUG
+		printk("Invalid adler\n");
+#endif
+		return 0;
+	}
+	return hdr99->generation;
+}
+
+static int
+core99_erase_bank(int bank)
+{
+	int stat, i;
+	
+	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+	
+	out_8(base, CORE99_FLASH_CMD_ERASE_SETUP);
+	out_8(base, CORE99_FLASH_CMD_ERASE_CONFIRM);
+	do { stat = in_8(base); }
+	while(!(stat & CORE99_FLASH_STATUS_DONE));
+	out_8(base, CORE99_FLASH_CMD_RESET);
+	if (stat & CORE99_FLASH_STATUS_ERR) {
+		printk("nvram: flash error 0x%02x on erase !\n", stat);
+		return -ENXIO;
+	}
+	for (i=0; i<NVRAM_SIZE; i++)
+		if (base[i] != 0xff) {
+			printk("nvram: flash erase failed !\n");
+			return -ENXIO;
+		}
+	return 0;
+}
 
-#define NVRAM_SIZE	0x2000	/* 8kB of non-volatile RAM */
+static int
+core99_write_bank(int bank, u8* datas)
+{
+	int i, stat = 0;
+	
+	u8* base = (u8 *)nvram_data + core99_bank*NVRAM_SIZE;
+	
+	for (i=0; i<NVRAM_SIZE; i++) {
+		out_8(base+i, CORE99_FLASH_CMD_WRITE_SETUP);
+		out_8(base+i, datas[i]);
+		do { stat = in_8(base); }
+		while(!(stat & CORE99_FLASH_STATUS_DONE));
+		if (stat & CORE99_FLASH_STATUS_ERR)
+			break;
+	}
+	out_8(base, CORE99_FLASH_CMD_RESET);
+	if (stat & CORE99_FLASH_STATUS_ERR) {
+		printk("nvram: flash error 0x%02x on write !\n", stat);
+		return -ENXIO;
+	}
+	for (i=0; i<NVRAM_SIZE; i++)
+		if (base[i] != datas[i]) {
+			printk("nvram: flash write failed !\n");
+			return -ENXIO;
+		}
+	return 0;	
+}
 
+static void
+lookup_partitions(void)
+{
+	u8 buffer[17];
+	int i, offset;
+	struct chrp_header* hdr;
+
+	if (pmac_newworld) {
+		nvram_partitions[pmac_nvram_OF] = -1;
+		nvram_partitions[pmac_nvram_XPRAM] = -1;
+		nvram_partitions[pmac_nvram_NR] = -1;
+		hdr = (struct chrp_header *)buffer;
+	
+		offset = 0;
+		buffer[16] = 0;
+		do {
+			for (i=0;i<16;i++)
+				buffer[i] = nvram_read_byte(offset+i);
+			if (!strcmp(hdr->name, "common"))
+				nvram_partitions[pmac_nvram_OF] = offset + 0x10;
+			if (!strcmp(hdr->name, "APL,MacOS75")) {
+				nvram_partitions[pmac_nvram_XPRAM] = offset + 0x10;
+				nvram_partitions[pmac_nvram_NR] = offset + 0x110;
+			}
+			offset += (hdr->len * 0x10);
+		} while(offset < NVRAM_SIZE);
+	} else {
+		nvram_partitions[pmac_nvram_OF] = 0x1800;
+		nvram_partitions[pmac_nvram_XPRAM] = 0x1300;
+		nvram_partitions[pmac_nvram_NR] = 0x1400;
+	}	
+#ifdef DEBUG
+	printk("nvram: OF partition at 0x%x\n", nvram_partitions[pmac_nvram_OF]);
+	printk("nvram: XP partition at 0x%x\n", nvram_partitions[pmac_nvram_XPRAM]);
+	printk("nvram: NR partition at 0x%x\n", nvram_partitions[pmac_nvram_NR]);
+#endif	
+}
 
 __init
 void pmac_nvram_init(void)
 {
 	struct device_node *dp;
 
+	nvram_naddrs = 0;
+
 	dp = find_devices("nvram");
 	if (dp == NULL) {
 		printk(KERN_ERR "Can't find NVRAM device\n");
-		nvram_naddrs = 0;
 		return;
 	}
 	nvram_naddrs = dp->n_addrs;
-	if (_machine == _MACH_chrp && nvram_naddrs == 1) {
+	is_core_99 = device_is_compatible(dp, "nvram,flash");
+	printk("pmac nvram is core99: %d\n", is_core_99);
+	if (is_core_99) {
+		int i;
+		u32 gen_bank0, gen_bank1;
+		
+		if (nvram_naddrs < 1) {
+			printk(KERN_ERR "nvram: no address\n");
+			return;
+		}
+#if 0
+		nvram_image = kmalloc(NVRAM_SIZE, GFP_KERNEL);
+		if (!nvram_image) {
+			printk(KERN_ERR "nvram: can't allocate image\n");
+			return;
+		}
+#endif		
+		nvram_data = ioremap(dp->addrs[0].address, NVRAM_SIZE*2);
+#ifdef DEBUG
+		printk("nvram: Checking bank 0...\n");
+#endif
+		gen_bank0 = core99_check((u8 *)nvram_data);
+		gen_bank1 = core99_check((u8 *)nvram_data + NVRAM_SIZE);
+		core99_bank = (gen_bank0 < gen_bank1) ? 1 : 0;
+#ifdef DEBUG
+		printk("nvram: gen0=%d, gen1=%d\n", gen_bank0, gen_bank1);
+		printk("nvram: Active bank is: %d\n", core99_bank);
+#endif
+		for (i=0; i<NVRAM_SIZE; i++)
+			nvram_image[i] = nvram_data[i + core99_bank*NVRAM_SIZE];
+	} else if (_machine == _MACH_chrp && nvram_naddrs == 1) {
 		nvram_data = ioremap(dp->addrs[0].address, dp->addrs[0].size);
 		nvram_mult = 1;
 	} else if (nvram_naddrs == 1) {
@@ -46,15 +281,44 @@
 	} else if (nvram_naddrs == 2) {
 		nvram_addr = ioremap(dp->addrs[0].address, dp->addrs[0].size);
 		nvram_data = ioremap(dp->addrs[1].address, dp->addrs[1].size);
-	} else if (nvram_naddrs == 0 && adb_hardware == ADB_VIAPMU) {
+	} else if (nvram_naddrs == 0 && adb_controller->kind == ADB_VIAPMU) {
 		nvram_naddrs = -1;
 	} else {
 		printk(KERN_ERR "Don't know how to access NVRAM with %d addresses\n",
 		       nvram_naddrs);
 	}
+	lookup_partitions();
 }
 
-unsigned char nvram_read_byte(int addr)
+void
+pmac_nvram_update(void)
+{
+	struct core99_header* hdr99;
+	
+	if (!is_core_99 || !nvram_data || !nvram_image)
+		return;
+	if (!memcmp(nvram_image, (u8*)nvram_data + core99_bank*NVRAM_SIZE,
+		NVRAM_SIZE))
+		return;
+#ifdef DEBUG
+	printk("Updating nvram...\n");
+#endif
+	hdr99 = (struct core99_header*)nvram_image;
+	hdr99->generation++;
+	hdr99->hdr.signature = CORE99_SIGNATURE;
+	hdr99->hdr.cksum = chrp_checksum(&hdr99->hdr);
+	hdr99->adler = core99_calc_adler(nvram_image);
+	core99_bank = core99_bank ? 0 : 1;
+	if (core99_erase_bank(core99_bank)) {
+		printk("nvram: Error erasing bank %d\n", core99_bank);
+		return;
+	}
+	if (core99_write_bank(core99_bank, nvram_image))
+		printk("nvram: Error writing bank %d\n", core99_bank);
+}
+
+unsigned char
+nvram_read_byte(int addr)
 {
 	struct adb_request req;
 
@@ -67,6 +331,8 @@
 			pmu_poll();
 		return req.reply[1];
 	case 1:
+		if (is_core_99)
+			return nvram_image ? nvram_image[addr] : 0;
 		return nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult];
 	case 2:
 		*nvram_addr = addr >> 5;
@@ -76,7 +342,8 @@
 	return 0;
 }
 
-void nvram_write_byte(unsigned char val, int addr)
+void
+nvram_write_byte(unsigned char val, int addr)
 {
 	struct adb_request req;
 
@@ -89,6 +356,12 @@
 			pmu_poll();
 		break;
 	case 1:
+		if (is_core_99) {
+			if (!nvram_image)
+				return;
+			nvram_image[addr] = val;
+			break;
+		}
 		nvram_data[(addr & (NVRAM_SIZE - 1)) * nvram_mult] = val;
 		break;
 	case 2:
@@ -99,3 +372,32 @@
 	}
 	eieio();
 }
+
+int
+pmac_get_partition(int partition)
+{
+	return nvram_partitions[partition];
+}
+
+u8
+pmac_xpram_read(int xpaddr)
+{
+	int offset = nvram_partitions[pmac_nvram_XPRAM];
+	
+	if (offset < 0)
+		return 0;
+		
+	return nvram_read_byte(xpaddr + offset);
+}
+
+void
+pmac_xpram_write(int xpaddr, u8 data)
+{
+	int offset = nvram_partitions[pmac_nvram_XPRAM];
+	
+	if (offset < 0)
+		return;
+		
+	nvram_write_byte(xpaddr + offset, data);
+}
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/pmac_time.c linux.17p18/arch/ppc/kernel/pmac_time.c
--- linux.vanilla/arch/ppc/kernel/pmac_time.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/pmac_time.c	Fri Aug  4 15:27:32 2000
@@ -22,8 +22,9 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/pgtable.h>
+#include <asm/nvram.h>
 
-#include "time.h"
+#include <asm/time.h>
 
 /* Apparently the RTC stores seconds since 1 Jan 1904 */
 #define RTC_OFFSET	2082844800
@@ -49,11 +50,32 @@
 /* Bits in IFR and IER */
 #define T1_INT		0x40		/* Timer 1 interrupt */
 
-__pmac
+extern struct timezone sys_tz;
+
+__init
+void pmac_time_init(void)
+{
+	s32 delta = 0;
+	int dst;
+	
+	delta = ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x9)) << 16;
+	delta |= ((s32)pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xa)) << 8;
+	delta |= pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0xb);
+	if (delta & 0x00800000UL)
+		delta |= 0xFF000000UL;
+	dst = ((pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 0x8) & 0x80) != 0);
+	printk("GMT Delta read from XPRAM: %d minutes, DST: %s\n", delta/60,
+		dst ? "on" : "off");
+	sys_tz.tz_minuteswest = -delta/60;
+	/* I _suppose_ this is 0:off, 1:on */
+	sys_tz.tz_dsttime = dst;
+}
 
+__pmac
 unsigned long pmac_get_rtc_time(void)
 {
 	struct adb_request req;
+	int offset = sys_tz.tz_minuteswest * 60;
 
 	/* Get the time from the RTC */
 	if (adb_controller == 0)
@@ -70,7 +92,7 @@
 			printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
 			       req.reply_len);
 		return (req.reply[3] << 24) + (req.reply[4] << 16)
-			+ (req.reply[5] << 8) + req.reply[6] - RTC_OFFSET;
+			+ (req.reply[5] << 8) + req.reply[6] - RTC_OFFSET + offset;
 	case ADB_VIAPMU:
 		if (pmu_request(&req, NULL, 1, PMU_READ_RTC) < 0) {
 			printk("pmac_read_rtc_time: pmu_request failed\n");
@@ -82,7 +104,7 @@
 			printk(KERN_ERR "pmac_get_rtc_time: got %d byte reply\n",
 			       req.reply_len);
 		return (req.reply[1] << 24) + (req.reply[2] << 16)
-			+ (req.reply[3] << 8) + req.reply[4] - RTC_OFFSET;
+			+ (req.reply[3] << 8) + req.reply[4] - RTC_OFFSET + offset;
 	default:
 		return 0;
 	}
@@ -90,7 +112,51 @@
 
 int pmac_set_rtc_time(unsigned long nowtime)
 {
-	return 0;
+	struct adb_request req;
+	int dst, delta;
+
+	nowtime += RTC_OFFSET - sys_tz.tz_minuteswest * 60;
+
+	/* Set the time in the RTC */
+	if (adb_controller == 0)
+		return 0;
+	/* adb_controller->kind, not adb_hardware, since that doesn't
+	   get set until we call adb_init - paulus. */
+	switch (adb_controller->kind) {
+	case ADB_VIACUDA:
+		if (cuda_request(&req, NULL, 6, CUDA_PACKET, CUDA_SET_TIME,
+				 nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
+			return 0;
+		while (!req.complete)
+			cuda_poll();
+//		if (req.reply_len != 7)
+			printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
+			       req.reply_len);
+		break;
+	case ADB_VIAPMU:
+		if (pmu_request(&req, NULL, 5, PMU_SET_RTC,
+				nowtime >> 24, nowtime >> 16, nowtime >> 8, nowtime) < 0)
+			return 0;
+		while (!req.complete)
+			pmu_poll();
+		if (req.reply_len != 5)
+			printk(KERN_ERR "pmac_set_rtc_time: got %d byte reply\n",
+			       req.reply_len);
+		break;
+	default:
+		return 0;
+	}
+
+	/* write the timezone offset back into the xpram */
+	delta = sys_tz.tz_minuteswest * -60;
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 0x9, delta >> 16);
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 0xa, delta >> 8);
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 0xb, delta);
+	dst = pmac_xpram_read(PMAC_XPRAM_MACHINE_LOC + 8);
+	dst = sys_tz.tz_dsttime? (dst | 0x80): (dst & ~0x80);
+	pmac_xpram_write(PMAC_XPRAM_MACHINE_LOC + 8, dst);
+
+	return 1;
 }
 
 /*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/ppc-stub.c linux.17p18/arch/ppc/kernel/ppc-stub.c
--- linux.vanilla/arch/ppc/kernel/ppc-stub.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/ppc-stub.c	Tue Aug  1 07:59:05 2000
@@ -351,7 +351,7 @@
 
 static inline void set_msr(int msr)
 {
-	asm volatile("mfmsr %0" : : "r" (msr));
+	asm volatile("mtmsr %0" : : "r" (msr));
 }
 
 /* Set up exception handlers for tracing and breakpoints
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/ppc_asm.tmpl linux.17p18/arch/ppc/kernel/ppc_asm.tmpl
--- linux.vanilla/arch/ppc/kernel/ppc_asm.tmpl	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/ppc_asm.tmpl	Tue Aug  1 07:59:05 2000
@@ -64,3 +64,36 @@
 #define	fr29	29
 #define	fr30	30
 #define	fr31	31
+
+#define	vr0	0
+#define	vr1	1
+#define	vr2	2
+#define	vr3	3
+#define	vr4	4
+#define	vr5	5
+#define	vr6	6
+#define	vr7	7
+#define	vr8	8
+#define	vr9	9
+#define	vr10	10
+#define	vr11	11
+#define	vr12	12
+#define	vr13	13
+#define	vr14	14
+#define	vr15	15
+#define	vr16	16
+#define	vr17	17
+#define	vr18	18
+#define	vr19	19
+#define	vr20	20
+#define	vr21	21
+#define	vr22	22
+#define	vr23	23
+#define	vr24	24
+#define	vr25	25
+#define	vr26	26
+#define	vr27	27
+#define	vr28	28
+#define	vr29	29
+#define	vr30	30
+#define	vr31	31
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/ppc_htab.c linux.17p18/arch/ppc/kernel/ppc_htab.c
--- linux.vanilla/arch/ppc/kernel/ppc_htab.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/ppc_htab.c	Tue Aug  1 07:59:05 2000
@@ -547,7 +547,8 @@
 		"0.5", "1.0", "(reserved2)", "(reserved3)"
 	};
 
-	if ( (_get_PVR() >> 16) != 8) return -EFAULT;
+	if ( ((_get_PVR() >> 16) != 8) && ((_get_PVR() >> 16) != 12))
+		return -EFAULT;
 	
 	if ( /*!table->maxlen ||*/ (filp->f_pos && !write)) {
 		*lenp = 0;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/ppc_ksyms.c linux.17p18/arch/ppc/kernel/ppc_ksyms.c
--- linux.vanilla/arch/ppc/kernel/ppc_ksyms.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/ppc_ksyms.c	Tue Aug  1 07:59:05 2000
@@ -29,6 +29,8 @@
 #include <asm/spinlock.h>
 #include <asm/dma.h>
 #include <asm/machdep.h>
+#include <asm/nvram.h>
+#include <asm/time.h>
 
 /* Tell string.h we don't want memcpy etc. as cpp defines */
 #define EXPORT_SYMTAB_STROPS
@@ -45,10 +47,14 @@
 extern atomic_t ppc_n_lost_interrupts;
 extern void do_lost_interrupts(unsigned long);
 extern int do_signal(sigset_t *, struct pt_regs *);
-
-asmlinkage long long __ashrdi3(long long, int);
-asmlinkage long long __lshrdi3(long long, int);
-asmlinkage int abs(int);
+extern unsigned long mktime(unsigned int, unsigned int, unsigned int,
+                            unsigned int, unsigned int, unsigned int);
+extern void to_tm(int tim, struct rtc_time * tm);
+
+long long __ashrdi3(long long, int);
+long long __ashldi3(long long, int);
+long long __lshrdi3(long long, int);
+int abs(int);
 
 EXPORT_SYMBOL(clear_page);
 EXPORT_SYMBOL(do_signal);
@@ -152,6 +158,7 @@
 
 EXPORT_SYMBOL(start_thread);
 EXPORT_SYMBOL(kernel_thread);
+EXPORT_SYMBOL(init_mm);
 
 EXPORT_SYMBOL(__cli);
 EXPORT_SYMBOL(__sti);
@@ -164,6 +171,11 @@
 EXPORT_SYMBOL(enable_kernel_fp);
 EXPORT_SYMBOL(flush_icache_range);
 EXPORT_SYMBOL(xchg_u32);
+
+#ifdef CONFIG_ALTIVEC
+EXPORT_SYMBOL(giveup_altivec);
+#endif
+
 #ifdef __SMP__
 EXPORT_SYMBOL(__global_cli);
 EXPORT_SYMBOL(__global_sti);
@@ -200,6 +212,8 @@
 EXPORT_SYMBOL(find_phandle);
 EXPORT_SYMBOL(device_is_compatible);
 EXPORT_SYMBOL(machine_is_compatible);
+EXPORT_SYMBOL(find_pci_device_OFnode);
+EXPORT_SYMBOL(find_all_nodes);
 EXPORT_SYMBOL(get_property);
 EXPORT_SYMBOL(pci_io_base);
 EXPORT_SYMBOL(pci_device_loc);
@@ -210,14 +224,21 @@
 EXPORT_SYMBOL(note_scsi_host);
 #endif
 EXPORT_SYMBOL(kd_mksound);
-#ifdef CONFIG_PMAC
+/*#ifdef CONFIG_PMAC */
 EXPORT_SYMBOL(nvram_read_byte);
 EXPORT_SYMBOL(nvram_write_byte);
-#endif /* CONFIG_PMAC */
+EXPORT_SYMBOL(pmac_xpram_read);
+EXPORT_SYMBOL(pmac_xpram_write);
+/*#endif*/ /* CONFIG_PMAC */
+#ifdef CONFIG_PPC_RTC
+EXPORT_SYMBOL(mktime);
+EXPORT_SYMBOL(to_tm);
+#endif
 
 EXPORT_SYMBOL(abs);
 
 EXPORT_SYMBOL_NOVERS(__ashrdi3);
+EXPORT_SYMBOL_NOVERS(__ashldi3);
 EXPORT_SYMBOL_NOVERS(__lshrdi3);
 EXPORT_SYMBOL_NOVERS(memcpy);
 EXPORT_SYMBOL_NOVERS(memset);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/prep_pci.c linux.17p18/arch/ppc/kernel/prep_pci.c
--- linux.vanilla/arch/ppc/kernel/prep_pci.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/prep_pci.c	Tue Aug  1 07:59:05 2000
@@ -8,6 +8,7 @@
  */
 
 #include <linux/types.h>
+#include <linux/string.h>
 #include <linux/pci.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -36,7 +37,7 @@
 unsigned char *Motherboard_routes;
 void (*Motherboard_non0)(struct pci_dev *);
 
-void Mesquite_Map_Non0(struct pci_dev *);
+void Powerplus_Map_Non0(struct pci_dev *);
 
 /* Used for Motorola to store system config register */
 static unsigned long	*ProcInfo;
@@ -508,6 +509,51 @@
         13      /* Line 4 */
 };
 
+/* Motorola PowerPlus architecture PCI IRQ tables */
+/* Interrupt line values for INTA-D on primary/secondary MPIC inputs */
+
+struct powerplus_irq_list
+{
+	unsigned char primary[4];	/* INT A-D */
+	unsigned char secondary[4];	/* INT A-D */
+};
+
+/*
+ * For standard PowerPlus boards, bus 0 PCI INTs A-D are routed to
+ * OpenPIC inputs 9-12.  PCI INTs A-D from the on board P2P bridge
+ * are routed to OpenPIC inputs 5-8.  These values are offset by 
+ * 16 in the table to reflect the Linux kernel interrupt value.
+ */
+struct powerplus_irq_list Powerplus_pci_IRQ_list =
+{
+	{25, 26, 27, 28},
+	{21, 22, 23, 24}
+};
+
+/* 
+ * For the MCP750 (system slot board), bus 0 PCI INTs A-D are routed
+ * to OpenPIC inputs 8-11.  PCI INTs A-D from the on board P2P bridge
+ * are routed to OpenPIC inputs 12-15.  These values are offset by 16
+ * in the table to reflect the Linux kernel interrupt value.
+ */
+struct powerplus_irq_list Mesquite_pci_IRQ_list =
+{
+	{24, 25, 26, 27},
+	{28, 29, 30, 31}
+};
+
+/*
+ * This table represents the standard PCI swizzle defined in the
+ * PCI bus specification.
+ */ 
+static unsigned char prep_pci_intpins[4][4] =
+{
+        { 1, 2, 3, 4},  /* Buses 0, 4, 8, ... */
+        { 2, 3, 4, 1},  /* Buses 1, 5, 9, ... */
+        { 3, 4, 1, 2},  /* Buses 2, 6, 10 ... */
+        { 4, 1, 2, 3},  /* Buses 3, 7, 11 ... */
+};
+
 /* We have to turn on LEVEL mode for changed IRQ's */
 /* All PCI IRQ's need to be level mode, so this should be something
  * other than hard-coded as well... IRQ's are individually mappable
@@ -685,8 +731,7 @@
 #define MOT_RAVEN_PRESENT	0x1
 #define MOT_HAWK_PRESENT	0x2
 
-/* Keyboard present flag */
-int prep_kbd_present = 1;   /* Keyboard present by default */
+int mot_entry = -1;
 
 int MotMPIC = 0;
 int mot_multi = 0;
@@ -751,13 +796,17 @@
 		mot_multi = 1;
 	}
 
-	/* This is a hack.  If this is a 2300 or 2400 mot board then there is
-	 * no keyboard controller and we have to indicate that.
+	/*
+	 * If a Motorola MVME2300, 2400, or MCPN750 board is detected
+	 * disable keyboard controller initialization to avoid system
+	 * hangs.
 	 */
 	base_mod = inb(MOTOROLA_BASETYPE_REG);
 	if ((MotMPIC == MOT_HAWK_PRESENT) || (base_mod == 0xF9) ||
-	    (base_mod == 0xFA) || (base_mod == 0xE1))
-		prep_kbd_present = 0;
+	    (base_mod == 0xFA) || (base_mod == 0xE1)) {
+		ppc_md.kbd_leds	= NULL; 
+		ppc_md.kbd_init_hw = NULL; 
+	}
 
 	return 1;
 }
@@ -771,33 +820,35 @@
 	unsigned char	*map;
 	unsigned char	*routes;
 	void		(*map_non0_bus)(struct pci_dev *);	/* For boards with more than bus 0 devices. */
+	struct powerplus_irq_list *pci_irq_list; /* List of PCI MPIC inputs */
+	unsigned char	secondary_bridge_devfn;	/* devfn of secondary bus transparent bridge */
 } mot_info[] = {
-	{0x300, 0x00, 0x00, "MVME 2400",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x010, 0x00, 0x00, "Genesis",				Genesis_pci_IRQ_map,	Genesis_pci_IRQ_routes, NULL},
-	{0x020, 0x00, 0x00, "Powerstack (Series E)",		Comet_pci_IRQ_map,	Comet_pci_IRQ_routes,	NULL},
-	{0x040, 0x00, 0x00, "Blackhawk (Powerstack)",		Blackhawk_pci_IRQ_map,	Blackhawk_pci_IRQ_routes, NULL},
-	{0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)",	Omaha_pci_IRQ_map,	Omaha_pci_IRQ_routes,	NULL},
-	{0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)",	Utah_pci_IRQ_map,	Utah_pci_IRQ_routes,	NULL},
-	{0x0A0, 0x00, 0x00, "Powerstack (Series EX)",		Comet2_pci_IRQ_map,	Comet2_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)",		Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)",		Sitka_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC",	Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes,	Mesquite_Map_Non0},
-	{0x1E0, 0xF6, 0x80, "MTX Plus",				MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xF6, 0x81, "Dual MTX Plus",			MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xF9, 0x00, "MVME 2300",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFA, 0x00, "MVME 2300SC/2600",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL},
-	{0x000, 0x00, 0x00, "",					NULL,			NULL,	NULL}
+	{0x300, 0x00, 0x00, "MVME 2400",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x010, 0x00, 0x00, "Genesis",				Genesis_pci_IRQ_map,	Genesis_pci_IRQ_routes, Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x020, 0x00, 0x00, "Powerstack (Series E)",		Comet_pci_IRQ_map,	Comet_pci_IRQ_routes,	NULL, NULL, 0x00},
+	{0x040, 0x00, 0x00, "Blackhawk (Powerstack)",		Blackhawk_pci_IRQ_map,	Blackhawk_pci_IRQ_routes, NULL, NULL, 0x00},
+	{0x050, 0x00, 0x00, "Omaha (PowerStack II Pro3000)",	Omaha_pci_IRQ_map,	Omaha_pci_IRQ_routes,	NULL, NULL, 0x00},
+	{0x060, 0x00, 0x00, "Utah (Powerstack II Pro4000)",	Utah_pci_IRQ_map,	Utah_pci_IRQ_routes,	NULL, NULL, 0x00},
+	{0x0A0, 0x00, 0x00, "Powerstack (Series EX)",		Comet2_pci_IRQ_map,	Comet2_pci_IRQ_routes,	NULL, NULL, 0x00},
+	{0x1E0, 0xE0, 0x00, "Mesquite cPCI (MCP750)",		Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0x00},
+	{0x1E0, 0xE1, 0x00, "Sitka cPCI (MCPN750)",		Sitka_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xE2, 0x00, "Mesquite cPCI (MCP750) w/ HAC",	Mesquite_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Mesquite_pci_IRQ_list, 0xC0},
+	{0x1E0, 0xF6, 0x80, "MTX Plus",				MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0},
+	{0x1E0, 0xF6, 0x81, "Dual MTX Plus",			MTXplus_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0xA0},
+	{0x1E0, 0xF7, 0x80, "MTX wo/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xF7, 0x81, "Dual MTX wo/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xF8, 0x80, "MTX w/ Parallel Port",		MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xF8, 0x81, "Dual MTX w/ Parallel Port",	MTX_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xF9, 0x00, "MVME 2300",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFA, 0x00, "MVME 2300SC/2600",			Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFB, 0x00, "MVME 2600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFC, 0x00, "MVME 2600/2700 with MVME761",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFD, 0x80, "MVME 3600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFD, 0x81, "MVME 4600 with MVME712M",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFE, 0x80, "MVME 3600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFE, 0x81, "MVME 4600 with MVME761",		Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	Powerplus_Map_Non0, &Powerplus_pci_IRQ_list, 0x00},
+	{0x1E0, 0xFF, 0x00, "MVME 1600-001 or 1600-011",	Genesis2_pci_IRQ_map,	Raven_pci_IRQ_routes,	NULL, NULL, 0x00},
+	{0x000, 0x00, 0x00, "",					NULL,			NULL,	NULL, 0x00}
 };
 
 __initfunc(unsigned long prep_route_pci_interrupts(void))
@@ -812,7 +863,6 @@
 		unsigned char  cpu_type;
 		unsigned char  base_mod;
 		int	       entry;
-		int	       mot_entry = -1;
 
 		cpu_type = inb(MOTOROLA_CPUTYPE_REG) & 0xF0;
 		base_mod = inb(MOTOROLA_BASETYPE_REG);
@@ -989,91 +1039,91 @@
 	return 0;
 }
 
-static unsigned int pci_localpirqs[4] =
-{
-	24,
-	25,
-	26,
-	27
-};
-
-static unsigned int pci_remotepirqs[4] =
-{
-	28,
-	29,
-	30,
-	31
-};
-
-static unsigned int pci_remotedev = 0xc0;
-
+/*
+ * Remove a device from the kernel PCI device list based on its 
+ * devfn identifier.
+ */
+__initfunc(
 void
-Mesquite_Map_Non0(struct pci_dev *pdev)
+prep_exclude_pci_device(unsigned char devfn)
+)
 {
-	struct pci_bus  *pbus;          /* Parent Bus Structure Pointer */
-	unsigned int    devnum;         /* Accumulated Device Number */
-	unsigned int    irq;            /* IRQ Value */
-
-	/*
-	**    Device Interrupt Line register initialization.
-	**    The IRQ line number will be generated after
-	**    taking into account all the PCI-2-PCI bridge
-	**    devices between the device and the Host Bridge.
-	*/
-	devnum = PCI_SLOT(pdev->devfn);
-	pbus = pdev->bus;
+	struct pci_dev *dev, *pdev = NULL;
 
-	while ((pbus->parent)->primary != (pbus->parent)->secondary)
-	{
-	    devnum += PCI_SLOT((pbus->self)->devfn);
+	/* Walk the pci device list */
+	for(dev=pci_devices; dev; dev=dev->next) {
+		if (dev->devfn == devfn)
+		{
+			/*
+			 * If we find a matching device, adjust
+			 * the list to remove the device.
+			 */
+			if (pdev != NULL)
+				pdev->next = dev->next;
+			else
+				pci_devices = dev->next;
 
-	    pbus = pbus->parent;
+			break;
+		}
+		pdev = dev;
 	}
+}
 
-	devnum &= 0x03;
-
-	/*
-	**    By default, get the PCI local domain IRQ value.
-	*/
-	irq = pci_localpirqs[devnum];
-
-	/*
-	**    Determine if the device is located in the
-	**    remote domain or not. We must find the
-	**    domain's bridge device located on bus 0.
-	*/
-	pbus = pdev->bus;
+void
+Powerplus_Map_Non0(struct pci_dev *dev)
+{
+	struct pci_bus  *pbus;          /* Parent bus structure pointer */
+	struct pci_dev	*tdev;		/* Temporary device structure */
+        unsigned int    devnum;         /* Accumulated device number */
+        unsigned char   intline;        /* Linux interrupt value */
+	unsigned char	intpin;		/* PCI interrupt pin */
+ 
+	/* Check for valid PCI dev pointer */
+	if (dev == NULL) return;
+
+	/* Fill our temporary device, and get the device number */
+	*tdev = *dev;
+	devnum = PCI_SLOT(tdev->devfn);
+
+	/* Read the interrupt pin of the device and adjust for indexing */
+	pcibios_read_config_byte(tdev->bus->number, tdev->devfn,
+				PCI_INTERRUPT_PIN, &intpin);
 
-	while (pbus->primary != 0)
-	    pbus = pbus->parent;
+	/* If device doesn't request an interrupt, return */
+	if ( (intpin < 1) || (intpin > 4) )
+		return;
 
-	/*
-	**    Check the device/function of domain's bridge
-	**    device against the remote device/function.
-	**    If the same, then the device is located in
-	**    the remote domain. Thus, get the PCI remote
-	**    domain IRQ value.
-	*/
-	if ((pbus->self)->devfn == pci_remotedev)
-        irq = pci_remotepirqs[devnum];
+	intpin--;
 
-	/*
-	**    Validate the IRQ number.
-	*/
-	if (irq <= 255)
+	/* Walk up to bus 0, adjusting the interrupt pin for the standard
+	   PCI bus swizzle. */
+	do {
+		intpin = (prep_pci_intpins[devnum % 4][intpin]) - 1;
+		pbus = tdev->bus;        /* up one level */
+		tdev = pbus->self;
+		devnum = PCI_SLOT(tdev->devfn);
+	} while(tdev->bus->number);
+
+	/* Use the primary interrupt inputs by default */
+	intline = mot_info[mot_entry].pci_irq_list->primary[intpin];
+
+	/* If the board has secondary interrupt inputs, walk the bus and
+	   note the devfn of the bridge from bus 0.  If it is the same as
+	   the devfn of the bus bridge with secondary inputs, use those. */
+	if (mot_info[mot_entry].secondary_bridge_devfn)
 	{
-	    /*
-	    **    Set the device's Interrupt Line register
-	    **    to the IRQ number and save it in the
-	    **    device's structure.
-	    */
-
-	    pci_write_config_byte(pdev, PCI_INTERRUPT_LINE, (u8)irq);
-
-	    pdev->irq = irq;
-
+		pbus = dev->bus;
+ 
+		while (pbus->primary != 0)
+			pbus = pbus->parent;
+ 
+		if ((pbus->self)->devfn == mot_info[mot_entry].secondary_bridge_devfn)
+			intline = mot_info[mot_entry].pci_irq_list->secondary[intpin];
 	}
-	return;
+	
+	/* Write calculated interrupt value to header and device list */
+	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, (u8)intline);
+	dev->irq = intline;
 }
 
 int motopenpic_to_irq(int n)
@@ -1137,6 +1187,15 @@
 
 	prep_route_pci_interrupts();
 
+	/*
+	 * If MTX+, exclude the SL82C105 IDE controller so the driver
+	 * doesn't hang.
+	 */
+	if ( _prep_type == _PREP_Motorola )
+		if ( strstr(mot_info[mot_entry].name, "MTX Plus") )
+			/* On MTX+, SL82C105 is at IDSEL 0xb function 0x1 */
+			prep_exclude_pci_device(PCI_DEVFN(0xb, 0x1));
+
 	prep_pib_init();
 
 	printk("Setting PCI interrupts for a \"%s\"\n", Motherboard_map_name);
@@ -1150,7 +1209,7 @@
 		       motopenpic_to_irq(Motherboard_map[PCI_SLOT(dev->devfn)]);
 
 		    pcibios_write_config_byte(dev->bus->number, dev->devfn, 
-					      PCI_INTERRUPT_PIN, dev->irq);
+					      PCI_INTERRUPT_LINE, dev->irq);
 		} else {
 			if (Motherboard_non0 != NULL)
 				Motherboard_non0(dev);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/prep_setup.c linux.17p18/arch/ppc/kernel/prep_setup.c
--- linux.vanilla/arch/ppc/kernel/prep_setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/prep_setup.c	Tue Aug  1 07:59:05 2000
@@ -48,7 +48,7 @@
 #include <asm/raven.h>
 
 
-#include "time.h"
+#include <asm/time.h>
 #include "local_irq.h"
 #include "i8259.h"
 #include "open_pic.h"
@@ -607,6 +607,7 @@
 	int i;
 
 	if (OpenPIC != NULL) {
+		open_pic.irq_offset = 16;
 		for ( i = 16 ; i < 36 ; i++ )
 			irq_desc[i].ctl = &open_pic;
 		openpic_init(1);
@@ -857,6 +858,7 @@
 	ppc_md.kbd_init_hw       = pckbd_init_hw;
 #ifdef CONFIG_MAGIC_SYSRQ
 	ppc_md.kbd_sysrq_xlate	 = pckbd_sysrq_xlate;
+	ppc_md.SYSRQ_KEY	 = 0x54;
 #endif
 #endif
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/prep_time.c linux.17p18/arch/ppc/kernel/prep_time.c
--- linux.vanilla/arch/ppc/kernel/prep_time.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/prep_time.c	Tue Aug  1 07:59:05 2000
@@ -26,7 +26,7 @@
 #include <asm/prep_nvram.h>
 #include <asm/mk48t59.h>
 
-#include "time.h"
+#include <asm/time.h>
 
 /*
  * The motorola uses the m48t18 rtc (includes DS1643) whose registers
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/process.c linux.17p18/arch/ppc/kernel/process.c
--- linux.vanilla/arch/ppc/kernel/process.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/process.c	Tue Aug  1 07:59:05 2000
@@ -43,9 +43,11 @@
 #include <asm/mmu_context.h>
 
 int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpregs);
+int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs);
 extern unsigned long _get_SP(void);
 
 struct task_struct *last_task_used_math = NULL;
+struct task_struct *last_task_used_altivec = NULL;
 static struct vm_area_struct init_mmap = INIT_MMAP;
 static struct fs_struct init_fs = INIT_FS;
 static struct files_struct init_files = INIT_FILES;
@@ -79,6 +81,31 @@
 	return 1;
 }
 
+#ifdef CONFIG_ALTIVEC
+int
+dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
+{
+	if (regs->msr & MSR_VEC)
+		giveup_altivec(current);
+	memcpy(vrregs, &current->tss.vr[0], sizeof(*vrregs));
+	return 1;
+}
+
+void 
+enable_kernel_altivec(void)
+{
+#ifdef __SMP__
+	if (current->tss.regs && (current->tss.regs->msr & MSR_VEC))
+		giveup_altivec(current);
+	else
+		giveup_altivec(NULL);	/* just enable AltiVec for kernel - force */
+#else
+	giveup_altivec(last_task_used_altivec);
+#endif /* __SMP __ */
+	printk("MSR_VEC in enable_altivec_kernel\n");
+}
+#endif /* CONFIG_ALTIVEC */
+
 void
 enable_kernel_fp(void)
 {
@@ -194,22 +221,53 @@
 	_enable_interrupts(s);
 }
 
-void show_regs(struct pt_regs * regs)
+struct bits {
+	const char *name;
+	unsigned int bit;
+};
+
+void print_bits(unsigned int val, struct bits *bits)
+{
+	const char *sep = "";
+
+	printk("[");
+	for (; bits->bit != 0; ++bits) {
+		if (val & bits->bit) {
+			printk("%s", bits->name);
+			sep = ", ";
+		}
+	}
+	printk("]");
+}
+
+struct bits msr_bits[] = {
+	{"VEC", MSR_VEC},
+	{"EE", MSR_EE},
+	{"PR", MSR_PR},
+	{"FP", MSR_FP},
+	{"IR", MSR_IR},
+	{"DR", MSR_DR},
+	{"ME", MSR_ME},
+	{0, 0}
+};
+
+void show_regs(struct pt_regs *regs)
 {
 	int i;
 
 	printk("NIP: %08lX XER: %08lX LR: %08lX REGS: %p TRAP: %04lx\n",
 	       regs->nip, regs->xer, regs->link, regs,regs->trap);
-	printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
-	       regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
-	       regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
-	       regs->msr&MSR_IR ? 1 : 0,
-	       regs->msr&MSR_DR ? 1 : 0);
+	printk("MSR: %08lx ", regs->msr);
+	print_bits(regs->msr, msr_bits);
+	printk("\n");
 	printk("TASK = %p[%d] '%s' mm->pgd %p ",
 	       current, current->pid, current->comm, current->mm->pgd);
 	printk("Last syscall: %ld ", current->tss.last_syscall);
-	printk("\nlast math %p", last_task_used_math);
-	
+	if (last_task_used_math)
+		printk("\nlast math %p", last_task_used_math);
+	if (last_task_used_altivec)
+		printk("\nlast altivec %p", last_task_used_altivec);
+
 #ifdef __SMP__	
 	printk(" CPU: %d last CPU: %d", current->processor,current->last_processor);
 #endif /* __SMP__ */
@@ -256,12 +314,16 @@
 {
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = NULL;
 }
 
 void flush_thread(void)
 {
 	if (last_task_used_math == current)
 		last_task_used_math = NULL;
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = NULL;
 }
 
 void
@@ -319,6 +381,19 @@
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
 
+#ifdef CONFIG_ALTIVEC
+	/*
+	 * copy altiVec info - assume lazy altiVec switch
+	 * - kumar
+	 */
+	if (regs->msr & MSR_VEC)
+		giveup_altivec(current);
+
+	memcpy(&p->tss.vr, &current->tss.vr, sizeof(p->tss.vr));
+	p->tss.vscr = current->tss.vscr;
+	childregs->msr &= ~MSR_VEC;
+#endif /* CONFIG_ALTIVEC */
+
 	memcpy(&p->tss.fpr, &current->tss.fpr, sizeof(p->tss.fpr));
 	p->tss.fpscr = current->tss.fpscr;
 	childregs->msr &= ~MSR_FP;
@@ -380,6 +455,8 @@
 	shove_aux_table(sp);
 	if (last_task_used_math == current)
 		last_task_used_math = 0;
+	if (last_task_used_altivec == current)
+		last_task_used_altivec = 0;
 	current->tss.fpscr = 0;
 }
 
@@ -439,6 +516,10 @@
 		goto out;
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
+#ifdef CONFIG_ALTIVEC
+	if (regs->msr & MSR_VEC)
+		giveup_altivec(current);
+#endif /* CONFIG_ALTIVEC */ 
 	error = do_execve(filename, (char **) a1, (char **) a2, regs);
 	putname(filename);
 out:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/prom.c linux.17p18/arch/ppc/kernel/prom.c
--- linux.vanilla/arch/ppc/kernel/prom.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/prom.c	Tue Aug  1 07:59:05 2000
@@ -26,6 +26,7 @@
 #include <asm/bootx.h>
 #include <asm/system.h>
 #include <asm/gemini.h>
+#include <asm/linux_logo.h>
 
 /*
  * Properties whose value is longer than this get excluded from our
@@ -88,45 +89,50 @@
 char *of_stdout_device = 0;
 
 prom_entry prom = 0;
-ihandle prom_chosen = 0, prom_stdout = 0;
+ihandle prom_chosen = 0, prom_stdout = 0, prom_disp_node = 0;
 int prom_version = 0;
 
 extern char *klimit;
 char *bootpath = 0;
 char *bootdevice = 0;
 
-unsigned int rtas_data = 0;   /* virtual pointer */
+unsigned int rtas_data = 0;   /* physical pointer */
 unsigned int rtas_entry = 0;  /* physical pointer */
 unsigned int rtas_size = 0;
 unsigned int old_rtas = 0;
 
+/* Set for a newworld machine */
+int use_of_interrupt_tree = 0;
+int pmac_newworld = 0;
+
 static struct device_node *allnodes = 0;
 
+#ifdef CONFIG_BOOTX_TEXT
+
 static void clearscreen(void);
 static void flushscreen(void);
 
-#ifdef CONFIG_BOOTX_TEXT
-
 void drawchar(char c);
 void drawstring(const char *c);
-static void drawhex(unsigned long v);
+void drawhex(unsigned long v);
 static void scrollscreen(void);
 
 static void draw_byte(unsigned char c, long locX, long locY);
-static void draw_byte_32(unsigned char *bits, unsigned long *base);
-static void draw_byte_16(unsigned char *bits, unsigned long *base);
-static void draw_byte_8(unsigned char *bits, unsigned long *base);
-
-static long				g_loc_X;
-static long				g_loc_Y;
-static long				g_max_loc_X;
-static long				g_max_loc_Y;
+static void draw_byte_32(unsigned char *bits, unsigned long *base, int rb);
+static void draw_byte_16(unsigned char *bits, unsigned long *base, int rb);
+static void draw_byte_8(unsigned char *bits, unsigned long *base, int rb);
+
+/* We want those in the data section */
+static long				g_loc_X = 0;
+static long				g_loc_Y = 0;
+static long				g_max_loc_X = 0;
+static long				g_max_loc_Y = 0; 
 
 #define cmapsz	(16*256)
 
 static unsigned char vga_font[cmapsz];
 
-#endif
+#endif /* CONFIG_BOOTX_TEXT */
 
 
 static void *call_prom(const char *service, int nargs, int nret, ...);
@@ -136,15 +142,25 @@
 				  unsigned long, struct device_node ***);
 static unsigned long finish_node(struct device_node *, unsigned long,
 				 interpret_func *);
+static unsigned long finish_node_interrupts(struct device_node *, unsigned long);
 static unsigned long check_display(unsigned long);
 static int prom_next_node(phandle *);
 static void *early_get_property(unsigned long, unsigned long, char *);
 
+#ifdef CONFIG_BOOTX_TEXT
+static void setup_disp_fake_bi(ihandle dp);
+static void prom_welcome(boot_infos_t* bi, unsigned long phys);
+#endif
+
 extern void enter_rtas(void *);
 extern unsigned long reloc_offset(void);
 
 extern char cmd_line[512];	/* XXX */
 boot_infos_t *boot_infos = 0;	/* init it so it's in data segment not bss */
+#ifdef CONFIG_BOOTX_TEXT
+boot_infos_t *disp_bi = 0;
+boot_infos_t fake_bi = {0,};
+#endif
 
 /*
  * prom_init() is called very early on, before the kernel text
@@ -237,7 +253,7 @@
 	if (RELOC(prom_stdout) == 0)
 	{
 #ifdef CONFIG_BOOTX_TEXT
-		if (RELOC(boot_infos) != 0)
+		if (RELOC(disp_bi) != 0)
 			drawstring(msg);
 #endif
 		return;
@@ -258,6 +274,22 @@
 	}
 }
 
+void
+prom_print_hex(unsigned int v)
+{
+	char buf[16];
+	int i, c;
+
+	for (i = 0; i < 8; ++i) {
+		c = (v >> ((7-i)*4)) & 0xf;
+		c += (c >= 10)? ('a' - 10): '0';
+		buf[i] = c;
+	}
+	buf[i] = ' ';
+	buf[i+1] = 0;
+	prom_print(buf);
+}
+
 unsigned long smp_ibm_chrp_hack __initdata = 0;
 
 /*
@@ -273,6 +305,7 @@
 	phandle node;
 	char type[16], *path;
 #endif	
+	int chrp = 0;
 	unsigned long mem;
 	ihandle prom_rtas, prom_mmu, prom_op;
 	unsigned long offset = reloc_offset();
@@ -299,22 +332,19 @@
 		unsigned long space;
 		unsigned long ptr, x;
 		char *model;
-#ifdef CONFIG_BOOTX_TEXT
-		unsigned long flags;
-#endif		
 
 		RELOC(boot_infos) = PTRUNRELOC(bi);
 		if (!BOOT_INFO_IS_V2_COMPATIBLE(bi))
 			bi->logicalDisplayBase = 0;
-
-		clearscreen();
-
 #ifdef CONFIG_BOOTX_TEXT
 		RELOC(g_loc_X) = 0;
 		RELOC(g_loc_Y) = 0;
 		RELOC(g_max_loc_X) = (bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) / 8;
 		RELOC(g_max_loc_Y) = (bi->dispDeviceRect[3] - bi->dispDeviceRect[1]) / 16;
+		RELOC(disp_bi) = PTRUNRELOC(bi);
 		
+		clearscreen();
+
 		/* Test if boot-info is compatible. Done only in config CONFIG_BOOTX_TEXT since
 		   there is nothing much we can do with an incompatible version, except display
 		   a message and eventually hang the processor...
@@ -325,24 +355,10 @@
 		if (!BOOT_INFO_IS_COMPATIBLE(bi))
 			prom_print(RELOC(" !!! WARNING - Incompatible version of BootX !!!\n\n\n"));
 		
-		prom_print(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
-		prom_print(RELOC("\nstarted at       : 0x"));
-		drawhex(reloc_offset() + KERNELBASE);
-		prom_print(RELOC("\nlinked at        : 0x"));
-		drawhex(KERNELBASE);
-		prom_print(RELOC("\nframe buffer at  : 0x"));
-		drawhex((unsigned long)bi->dispDeviceBase);
-		prom_print(RELOC(" (phys), 0x"));
-		drawhex((unsigned long)bi->logicalDisplayBase);
-		prom_print(RELOC(" (log)"));
-		prom_print(RELOC("\nMSR              : 0x"));
-		__asm__ __volatile__ ("mfmsr %0" : "=r" ((flags)) : : "memory");
-		drawhex(flags);
-		prom_print(RELOC("\n\n"));
-#endif
-		/* Out of the #if/#endif since it flushes the clearscreen too */
+		prom_welcome(bi, phys);
 		flushscreen();
-		
+#endif /* CONFIG_BOOTX_TEXT */
+
 		/* New BootX enters kernel with MMU off, i/os are not allowed
 		   here. This hack will have been done by the boostrap anyway.
 		 */
@@ -420,12 +436,15 @@
 	    int sz;
 	    sz = (int)call_prom(RELOC("getprop"), 4, 1, prom_op, RELOC("model"), model, 64);
 	    if (sz > 0) {
-	    	char *c;
-		for (c = model; *c; c++)
-		    if (*c >= '0' && *c <= '9') {
-			RELOC(prom_version) = *c - '0';
-			break;
-		    }
+		if ( strncmp(model,RELOC("IBM"),3) ) {
+	    	    char *c;
+		    for (c = model; *c; c++)
+		        if (*c >= '0' && *c <= '9') {
+			    RELOC(prom_version) = *c - '0';
+			    break;
+		        }
+		} else
+		    chrp = 1;
 	    }
 	}
 	if (RELOC(prom_version) >= 3)
@@ -445,15 +464,6 @@
 		RELOC(bootdevice) = PTRUNRELOC(d);
 		mem = ALIGN(mem + strlen(d) + 1);
 	}
-
-	mem = check_display(mem);
-
-	prom_print(RELOC("copying OF device tree..."));
-	mem = copy_device_tree(mem, mem + (1<<20));
-	prom_print(RELOC("done\n"));
-
-
-	RELOC(klimit) = (char *) (mem - offset);
 	
 	prom_rtas = call_prom(RELOC("finddevice"), 1, 1, RELOC("/rtas"));
 	if (prom_rtas != (void *) -1) {
@@ -465,18 +475,14 @@
 			RELOC(rtas_data) = 0;
 		} else {
 			/*
-			 * We do _not_ want the rtas_data inside the klimit
-			 * boundry since it'll be squashed when we do the
-			 * relocate of the kernel on chrp right after prom_init()
-			 * in head.S.  So, we just pick a spot in memory.
-			 * -- Cort
+			 * Ask OF for some space for RTAS.
 			 */
-#if 0
-			mem = (mem + 4095) & -4096;
-			RELOC(rtas_data) = mem + KERNELBASE;
-			mem += RELOC(rtas_size);
-#endif
-			RELOC(rtas_data) = (6<<20) + KERNELBASE;
+			RELOC(rtas_data) = (unsigned int)
+				call_prom(RELOC("claim"), 3, 1, 0,
+					  RELOC(rtas_size), 0x1000);
+			prom_print(RELOC("rtas at "));
+			prom_print_hex(RELOC(rtas_data));
+			prom_print(RELOC("\n"));
 		}
 		prom_rtas = call_prom(RELOC("open"), 1, 1, RELOC("/rtas"));
 		{
@@ -488,7 +494,7 @@
 			prom_args.nret = 2;
 			prom_args.args[0] = RELOC("instantiate-rtas");
 			prom_args.args[1] = prom_rtas;
-			prom_args.args[2] = ((void *)(RELOC(rtas_data)-KERNELBASE));
+			prom_args.args[2] = (void *) RELOC(rtas_data);
 			RELOC(prom)(&prom_args);
 			if (prom_args.args[nargs] != 0)
 				i = 0;
@@ -502,6 +508,15 @@
 			prom_print(RELOC(" done\n"));
 	}
 
+	mem = check_display(mem);
+
+	prom_print(RELOC("copying OF device tree..."));
+	/* N.B. do this *after* any claims */
+	mem = copy_device_tree(mem, mem + (1<<20));
+	prom_print(RELOC("done\n"));
+
+	RELOC(klimit) = (char *) (mem - offset);
+
 	/* If we are already running at 0xc0000000, we assume we were loaded by
 	 * an OF bootloader which did set a BAT for us. This breaks OF translate
 	 * so we force phys to be 0
@@ -533,6 +548,11 @@
 	    }
 	}
 	    
+#ifdef CONFIG_BOOTX_TEXT
+	if (RELOC(prom_disp_node) != 0)
+		setup_disp_fake_bi(RELOC(prom_disp_node));
+#endif
+
 #ifdef CONFIG_SMP
 	/*
 	 * With CHRP SMP we need to use the OF to start the other
@@ -608,8 +628,8 @@
 		else
 			prom_print(RELOC("...failed\n"));
 	}
-#endif /* CONFIG_SMP */
 	
+#endif	
 	/* If OpenFirmware version >= 3, then use quiesce call */
 	if (RELOC(prom_version) >= 3) {
 	    prom_print(RELOC("Calling quiesce ...\n"));
@@ -618,9 +638,80 @@
 	    phys = offset + KERNELBASE;
 	}
 
+#ifdef CONFIG_BOOTX_TEXT
+	if (!chrp && RELOC(disp_bi)) {
+		RELOC(prom_stdout) = 0;
+		clearscreen();
+		prom_welcome(PTRRELOC(RELOC(disp_bi)), phys);
+	}
+#endif
+
+	prom_print(RELOC("booting...\n"));
 	return phys;
 }
 
+#ifdef CONFIG_BOOTX_TEXT
+__init static void
+prom_welcome(boot_infos_t* bi, unsigned long phys)
+{
+	unsigned long offset = reloc_offset();
+	unsigned long flags;
+	unsigned long pvr;
+	
+	prom_print(RELOC("Welcome to Linux, kernel " UTS_RELEASE "\n"));
+	prom_print(RELOC("\nstarted at       : 0x"));
+	drawhex(phys);
+	prom_print(RELOC("\nlinked at        : 0x"));
+	drawhex(KERNELBASE);
+	prom_print(RELOC("\nframe buffer at  : 0x"));
+	drawhex((unsigned long)bi->dispDeviceBase);
+	prom_print(RELOC(" (phys), 0x"));
+	drawhex((unsigned long)bi->logicalDisplayBase);
+	prom_print(RELOC(" (log)"));
+	prom_print(RELOC("\nMSR              : 0x"));
+	__asm__ __volatile__ ("mfmsr %0" : "=r" (flags));
+	drawhex(flags);
+	__asm__ __volatile__ ("mfspr %0, 287" : "=r" (pvr));
+	pvr >>= 16;
+	if (pvr > 1) {
+	    prom_print(RELOC("\nHID0             : 0x"));
+	    __asm__ __volatile__ ("mfspr %0, 1008" : "=r" (flags));
+	    drawhex(flags);
+	}
+	if (pvr == 8 || pvr == 12) {
+	    prom_print(RELOC("\nICTC             : 0x"));
+	    __asm__ __volatile__ ("mfspr %0, 1019" : "=r" (flags));
+	    drawhex(flags);
+	}
+	prom_print(RELOC("\n\n"));
+}
+
+void showvalue(char *str, unsigned long val)
+{
+	drawstring(str);
+	drawhex(val);
+	drawstring("\n");
+}
+#endif
+
+static int prom_set_color(ihandle ih, int i, int r, int g, int b)
+{
+	struct prom_args prom_args;
+	unsigned long offset = reloc_offset();
+
+	prom_args.service = RELOC("call-method");
+	prom_args.nargs = 6;
+	prom_args.nret = 1;
+	prom_args.args[0] = RELOC("color!");
+	prom_args.args[1] = ih;
+	prom_args.args[2] = (void *) i;
+	prom_args.args[3] = (void *) b;
+	prom_args.args[4] = (void *) g;
+	prom_args.args[5] = (void *) r;
+	RELOC(prom)(&prom_args);
+	return (int) prom_args.args[6];
+}
+
 /*
  * If we have a display that we don't know how to drive,
  * we will want to try to execute OF's open method for it
@@ -633,11 +724,32 @@
 static unsigned long
 check_display(unsigned long mem)
 {
+#ifdef CONFIG_FB
 	phandle node;
 	ihandle ih;
 	int i;
 	unsigned long offset = reloc_offset();
 	char type[16], *path;
+	static unsigned char default_colors[] = {
+		0x00, 0x00, 0x00,
+		0x00, 0x00, 0xaa,
+		0x00, 0xaa, 0x00,
+		0x00, 0xaa, 0xaa,
+		0xaa, 0x00, 0x00,
+		0xaa, 0x00, 0xaa,
+		0xaa, 0xaa, 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
+	};
+
+	RELOC(prom_disp_node) = 0;
 
 	for (node = 0; prom_next_node(&node); ) {
 		type[0] = 0;
@@ -660,6 +772,24 @@
 		}
 		prom_print(RELOC("... ok\n"));
 
+		if (RELOC(prom_disp_node) == 0)
+			RELOC(prom_disp_node) = node;
+
+		/* 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)
+				break;
+
+		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)
+				break;
+
 		/*
 		 * If this display is the device that OF is using for stdout,
 		 * move it to the front of the list.
@@ -676,9 +806,85 @@
 		if (RELOC(prom_num_displays) >= FB_MAX)
 			break;
 	}
+#endif /* CONFIG_FB */
 	return ALIGN(mem);
 }
 
+/* This function will enable the early boot text when doing OF booting. This
+ * way, xmon output should work too
+ */
+#ifdef CONFIG_BOOTX_TEXT
+__init
+static void
+setup_disp_fake_bi(ihandle dp)
+{
+	unsigned int len;
+	int width = 640, height = 480, depth = 8, pitch;
+	unsigned  address;
+	boot_infos_t* bi;
+	unsigned long offset = reloc_offset();
+	
+	prom_print(RELOC("Initing fake screen\n"));
+
+	len = 0;
+	call_prom(RELOC("getprop"), 4, 1, dp, RELOC("depth"), &len, sizeof(len));
+	if (len == 0)
+		prom_print(RELOC("Warning: assuming display depth = 8\n"));
+	else
+		depth = len;
+	width = len = 0;
+	call_prom(RELOC("getprop"), 4, 1, dp, RELOC("width"), &len, sizeof(len));
+	width = len;
+	if (width == 0) {
+		prom_print(RELOC("Failed to get width\n"));
+		return;
+	}
+	height = len = 0;
+	call_prom(RELOC("getprop"), 4, 1, dp, RELOC("height"), &len, sizeof(len));
+	height = len;
+	if (height == 0) {
+		prom_print(RELOC("Failed to get height\n"));
+		return;
+	}
+	pitch = len = 0;
+	call_prom(RELOC("getprop"), 4, 1, dp, RELOC("linebytes"), &len, sizeof(len));
+	pitch = len;
+	if (pitch == 0) {
+		prom_print(RELOC("Failed to get pitch\n"));
+		return;
+	}
+	if (pitch == 1)
+		pitch = 0x1000;
+	address = len = 0;
+	len = 0xfa000000;
+	call_prom(RELOC("getprop"), 4, 1, dp, RELOC("address"), &len, sizeof(len));
+	address = len;
+	if (address == 0) {
+		prom_print(RELOC("Failed to get address\n"));
+		return;
+	}
+#if 0
+	/* kludge for valkyrie */
+	if (strcmp(dp->name, "valkyrie") == 0) 
+	    address += 0x1000;
+#endif
+ 
+	RELOC(disp_bi) = &fake_bi;
+	bi = PTRRELOC((&fake_bi));
+	RELOC(g_loc_X) = 0;
+	RELOC(g_loc_Y) = 0;
+	RELOC(g_max_loc_X) = width / 8;
+	RELOC(g_max_loc_Y) = height / 16;
+	bi->logicalDisplayBase = (unsigned char *)address;
+	bi->dispDeviceBase = (unsigned char *)address;
+	bi->dispDeviceRowBytes = pitch;
+	bi->dispDeviceDepth = depth;
+	bi->dispDeviceRect[0] = bi->dispDeviceRect[1] = 0;
+	bi->dispDeviceRect[2] = width;
+	bi->dispDeviceRect[3] = height;
+}
+#endif
+
 __init
 static int
 prom_next_node(phandle *nodep)
@@ -814,6 +1020,18 @@
 {
 	unsigned long mem = (unsigned long) klimit;
 
+	/* All newworld machines and CHRP now use the interrupt tree */
+	struct device_node *np = allnodes;
+	while(np && (_machine == _MACH_Pmac)) {
+		if (get_property(np, "interrupt-parent", 0)) {
+			pmac_newworld = 1;
+			break;
+		}
+		np = np->allnext;
+	}
+	if ((_machine == _MACH_chrp) || (boot_infos == 0 && pmac_newworld))
+		use_of_interrupt_tree = 1;
+
 	mem = finish_node(allnodes, mem, NULL);
 	printk(KERN_INFO "device tree used %lu bytes\n",
 	       mem - (unsigned long) allnodes);
@@ -854,6 +1072,9 @@
 	if (ifunc != NULL) {
 		mem_start = ifunc(np, mem_start);
 	}
+	if (use_of_interrupt_tree) {
+		mem_start = finish_node_interrupts(np, mem_start);
+	}
 
 	/* the f50 sets the name to 'display' and 'compatible' to what we
 	 * expect for the name -- Cort
@@ -900,6 +1121,151 @@
 	return mem_start;
 }
 
+/* This routine walks the interrupt tree for a given device node and gather 
+ * all necessary informations according to the draft interrupt mapping
+ * for CHRP. The current version was only tested on Apple "Core99" machines
+ * and may not handle cascaded controllers correctly.
+ */
+__init
+static unsigned long
+finish_node_interrupts(struct device_node *np, unsigned long mem_start)
+{
+	/* Finish this node */
+	unsigned int *isizep, *asizep, *interrupts, *map, *map_mask, *reg;
+	phandle *parent;
+	struct device_node *node, *parent_node;
+	int l, isize, ipsize, asize, map_size, regpsize;
+
+	/* Currently, we don't look at all nodes with no "interrupts" property */
+	interrupts = (unsigned int *)get_property(np, "interrupts", &l);
+	if (interrupts == NULL)
+		return mem_start;
+	ipsize = l>>2;
+
+	reg = (unsigned int *)get_property(np, "reg", &l);
+	regpsize = l>>2;
+
+	/* We assume default interrupt cell size is 1 (bugus ?) */
+	isize = 1;
+	node = np;
+	
+	do {
+	    /* We adjust the cell size if the current parent contains an #interrupt-cells
+	     * property */
+	    isizep = (unsigned int *)get_property(node, "#interrupt-cells", &l);
+	    if (isizep)
+	    	isize = *isizep;
+
+	    /* We don't do interrupt cascade (ISA) for now, we stop on the first 
+	     * controller found
+	     */
+	    if (get_property(node, "interrupt-controller", &l)) {
+	    	int i,j;
+	    	np->intrs = (struct interrupt_info *) mem_start;
+		np->n_intrs = ipsize / isize;
+		mem_start += np->n_intrs * sizeof(struct interrupt_info);
+		for (i = 0; i < np->n_intrs; ++i) {
+		    np->intrs[i].line = *interrupts++;
+		    np->intrs[i].sense = 0;
+		    if (isize > 1)
+		        np->intrs[i].sense = *interrupts++;
+		    for (j=2; j<isize; j++)
+		    	interrupts++;
+		}
+		/*
+		 *  On the CHRP LongTrail, ISA interrupts are cascaded through
+		 *  the OpenPIC. For compatibility reasons, ISA interrupts are
+		 *  numbered 0-15 and OpenPIC interrupts start at 16.
+		 *  Hence we have to fixup the interrupt numbers for sources
+		 *  that are attached to the OpenPIC and thus have an
+		 *  interrupt-controller named `open-pic'.
+		 *
+		 *  FIXME: The name of the interrupt-controller node for the
+		 *         `ide' node has no name, although its parent is
+		 *         correctly specified in interrupt-map, so we check
+		 *         for a NULL name as well.
+		 */
+		if (_machine == _MACH_chrp &&
+		    ((node->name && !strcmp(node->name, "open-pic")) ||
+		     !node->name)) {
+		    for (i = 0; i < np->n_intrs; ++i)
+			np->intrs[i].line = openpic_to_irq(np->intrs[i].line);
+		}
+		return mem_start;
+	    }
+	    /* We lookup for an interrupt-map. This code can only handle one interrupt
+	     * per device in the map. We also don't handle #address-cells in the parent
+	     * I skip the pci node itself here, may not be necessary but I don't like it's
+	     * reg property.
+	     */
+	    if (np != node)
+	        map = (unsigned int *)get_property(node, "interrupt-map", &l);
+	     else
+	     	map = NULL;
+	    if (map && l) {
+	    	int i, found, temp_isize;
+	        map_size = l>>2;
+	        map_mask = (unsigned int *)get_property(node, "interrupt-map-mask", &l);
+	        asizep = (unsigned int *)get_property(node, "#address-cells", &l);
+	        if (asizep && l == sizeof(unsigned int))
+	            asize = *asizep;
+	        else
+	            asize = 0;
+	        found = 0;
+	        while(map_size>0 && !found) {
+	            found = 1;
+	            for (i=0; i<asize; i++) {
+	            	unsigned int mask = map_mask ? map_mask[i] : 0xffffffff;
+	            	if (!reg || (i>=regpsize) || ((mask & *map) != (mask & reg[i])))
+	           	    found = 0;
+	           	map++;
+	           	map_size--;
+	            }
+	            for (i=0; i<isize; i++) {
+	            	unsigned int mask = map_mask ? map_mask[i+asize] : 0xffffffff;
+	            	if ((mask & *map) != (mask & interrupts[i]))
+	            	    found = 0;
+	            	map++;
+	            	map_size--;
+	            }
+	            parent = *((phandle *)(map));
+	            map+=1; map_size-=1;
+	            parent_node = find_phandle(parent);
+	            temp_isize = isize;
+	            if (parent_node) {
+			isizep = (unsigned int *)get_property(parent_node, "#interrupt-cells", &l);
+	    		if (isizep)
+	    		    temp_isize = *isizep;
+	            }
+	            if (!found) {
+	            	map += temp_isize;
+	            	map_size-=temp_isize;
+	            }
+	        }
+	        if (found) {
+	            node = parent_node;
+	            reg = NULL;
+	            regpsize = 0;
+	            interrupts = (unsigned int *)map;
+	            ipsize = temp_isize*1;
+		    continue;
+	        }
+	    }
+	    /* We look for an explicit interrupt-parent.
+	     */
+	    parent = (phandle *)get_property(node, "interrupt-parent", &l);
+	    if (parent && (l == sizeof(phandle)) &&
+	    	(parent_node = find_phandle(*parent))) {
+	    	node = parent_node;
+	    	continue;
+	    }
+	    /* Default, get real parent */
+	    node = node->parent;
+	} while(node);
+
+	return mem_start;
+}
+
 /*
  * When BootX makes a copy of the device tree from the MacOS
  * Name Registry, it is in the format we use but all of the pointers
@@ -958,6 +1324,9 @@
 		mem_start += i * sizeof(struct address_range);
 	}
 
+	if (use_of_interrupt_tree)
+		return mem_start;
+
 	/*
 	 * If the pci host bridge has an interrupt-map property,
 	 * look for our node in it.
@@ -967,14 +1336,28 @@
 		get_property(np->parent, "interrupt-map", &ml)) != 0
 	    && (ip = (int *) get_property(np, "interrupts", &l)) != 0) {
 		unsigned int devfn = pci_addrs[0].addr.a_hi & 0xff00;
+		unsigned int cell_size;
+		struct device_node* np2;
+		/* This is hackish, but is only used for BootX booting */
+		cell_size = sizeof(struct pci_intr_map);
+		np2 = np->parent;
+		while(np2) {
+			if (device_is_compatible(np2, "uni-north")) {
+				cell_size += 4;
+				break;
+			}
+			np2 = np2->parent;
+		}
 		np->n_intrs = 0;
 		np->intrs = (struct interrupt_info *) mem_start;
-		for (i = 0; (ml -= sizeof(struct pci_intr_map)) >= 0; ++i) {
-			if (imp[i].addr.a_hi == devfn) {
-				np->intrs[np->n_intrs].line = imp[i].intr;
-				np->intrs[np->n_intrs].sense = 0;
+		for (i = 0; (ml -= cell_size) >= 0; ++i) {
+			if (imp->addr.a_hi == devfn) {
+				np->intrs[np->n_intrs].line = imp->intr;
+				np->intrs[np->n_intrs].sense = 0; /* FIXME */
 				++np->n_intrs;
 			}
+			imp = (struct pci_intr_map *)(((unsigned int)imp)
+				+ cell_size);
 		}
 		if (np->n_intrs == 0)
 			np->intrs = 0;
@@ -1031,6 +1414,9 @@
 		mem_start += i * sizeof(struct address_range);
 	}
 
+	if (use_of_interrupt_tree)
+		return mem_start;
+
 	ip = (int *) get_property(np, "AAPL,interrupts", &l);
 	if (ip == 0)
 		ip = (int *) get_property(np, "interrupts", &l);
@@ -1054,13 +1440,14 @@
 	struct reg_property *rp;
 	struct address_range *adr;
 	unsigned long base_address;
-	int i, l, *ip;
+	int i, l, keylargo, *ip;
 	struct device_node *db;
 
 	base_address = 0;
 	for (db = np->parent; db != NULL; db = db->parent) {
 		if (!strcmp(db->type, "mac-io") && db->n_addrs != 0) {
 			base_address = db->addrs[0].address;
+			keylargo = device_is_compatible(db, "Keylargo");
 			break;
 		}
 	}
@@ -1080,6 +1467,9 @@
 		mem_start += i * sizeof(struct address_range);
 	}
 
+	if (use_of_interrupt_tree)
+		return mem_start;
+
 	ip = (int *) get_property(np, "interrupts", &l);
 	if (ip == 0)
 		ip = (int *) get_property(np, "AAPL,interrupts", &l);
@@ -1088,9 +1478,15 @@
 		if (_machine == _MACH_Pmac) {
 			/* for the iMac */
 			np->n_intrs = l / sizeof(int);
+			/* Hack for BootX on Core99 */
+			if (keylargo)
+				np->n_intrs = np->n_intrs/2;
 			for (i = 0; i < np->n_intrs; ++i) {
 				np->intrs[i].line = *ip++;
-				np->intrs[i].sense = 0;
+				if (keylargo)
+					np->intrs[i].sense = *ip++;
+				else
+					np->intrs[i].sense = 0;
 			}
 		} else {
 			/* CHRP machines */
@@ -1130,6 +1526,9 @@
 		mem_start += i * sizeof(struct address_range);
 	}
 
+	if (use_of_interrupt_tree)
+		return mem_start;
+ 
 	ip = (int *) get_property(np, "interrupts", &l);
 	if (ip != 0) {
 		np->intrs = (struct interrupt_info *) mem_start;
@@ -1167,6 +1566,9 @@
 		mem_start += i * sizeof(struct address_range);
 	}
 
+	if (use_of_interrupt_tree)
+		return mem_start;
+
 	ip = (int *) get_property(np, "AAPL,interrupts", &l);
 	if (ip == 0)
 		ip = (int *) get_property(np, "interrupts", &l);
@@ -1223,6 +1625,49 @@
 	return head;
 }
 
+/* Finds a device node given its PCI bus number, device number
+ * and function number
+ */
+__openfirmware
+struct device_node *
+find_pci_device_OFnode(unsigned char bus, unsigned char dev_fn)
+{
+	struct device_node* np;
+	unsigned int *reg;
+	int l;
+	
+	for (np = allnodes; np != 0; np = np->allnext) {
+		char *pname = np->parent ?
+			(char *)get_property(np->parent, "name", &l) : 0;
+		if (pname && strcmp(pname, "mac-io") == 0)
+			continue;
+		reg = (unsigned int *) get_property(np, "reg", &l);
+		if (reg == 0 || l < sizeof(struct reg_property))
+			continue;
+		if (((reg[0] >> 8) & 0xff) == dev_fn && ((reg[0] >> 16) & 0xff) == bus)
+			break;
+	}
+	return np;
+}
+
+/*
+ * Returns all nodes linked together
+ */
+__openfirmware
+struct device_node *
+find_all_nodes(void)
+{
+	struct device_node *head, **prevp, *np;
+
+	prevp = &head;
+	for (np = allnodes; np != 0; np = np->allnext) {
+		*prevp = np;
+		prevp = &np->next;
+	}
+	*prevp = 0;
+	return head;
+}
+
 /* Checks if the given "compat" string matches one of the strings in
  * the device's "compatible" property
  */
@@ -1424,18 +1869,44 @@
 	prom_exit();
 }
 
-#ifdef CONFIG_XMON
+/* Indicates whether the root node has a given value in its
+ * compatible property.
+ */
+__openfirmware
+int
+machine_is_compatible(const char *compat)
+{
+	struct device_node *root;
+	
+	root = find_path_device("/");
+	if (root == 0)
+		return 0;
+	return device_is_compatible(root, compat);
+}
+
+
+#ifdef CONFIG_BOOTX_TEXT
+
+/* Here's a small text engine to use during early boot or for debugging purposes
+ * 
+ * todo:
+ * 
+ *  - build some kind of vgacon with it to enable early printk
+ *  - move to a separate file
+ *  - add a few video driver hooks to keep in sync with display
+ *    changes.
+ */
+
 __init
 void
 map_bootx_text(void)
 {
-	if (boot_infos == 0)
+	if (disp_bi == 0)
 		return;
-	boot_infos->logicalDisplayBase =
-		ioremap((unsigned long) boot_infos->dispDeviceBase,
-			boot_infos->dispDeviceRowBytes * boot_infos->dispDeviceRect[3]);
+	disp_bi->logicalDisplayBase =
+		ioremap((unsigned long) disp_bi->dispDeviceBase,
+			disp_bi->dispDeviceRowBytes * disp_bi->dispDeviceRect[3]);
 }
-#endif /* CONFIG_XMON */
 
 /* Calc the base address of a given point (x,y) */
 __pmac
@@ -1457,7 +1928,7 @@
 clearscreen(void)
 {
 	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(boot_infos));
+	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
 	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
 	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 					(bi->dispDeviceDepth >> 3)) >> 2;
@@ -1482,7 +1953,7 @@
 flushscreen(void)
 {
 	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(boot_infos));
+	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
 	unsigned long *base	= (unsigned long *)calc_base(bi, 0, 0);
 	unsigned long width 	= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
 					(bi->dispDeviceDepth >> 3)) >> 2;
@@ -1499,29 +1970,12 @@
 	}
 }
 
-/* Indicates whether the root node has a given value in its
- * compatible property.
- */
-__openfirmware
-int
-machine_is_compatible(const char *compat)
-{
-	struct device_node *root;
-	
-	root = find_path_device("/");
-	if (root == 0)
-		return 0;
-	return device_is_compatible(root, compat);
-}
-
-#ifdef CONFIG_BOOTX_TEXT
-
 __pmac
 static void
 scrollscreen(void)
 {
 	unsigned long offset		= reloc_offset();
-	boot_infos_t* bi		= PTRRELOC(RELOC(boot_infos));
+	boot_infos_t* bi		= PTRRELOC(RELOC(disp_bi));
 	unsigned long *src		= (unsigned long *)calc_base(bi,0,16);
 	unsigned long *dst		= (unsigned long *)calc_base(bi,0,0);
 	unsigned long width		= ((bi->dispDeviceRect[2] - bi->dispDeviceRect[0]) *
@@ -1589,7 +2043,7 @@
 }
 
 __pmac
-static void
+void
 drawhex(unsigned long v)
 {
 	static char hex_table[] = "0123456789abcdef";
@@ -1611,19 +2065,20 @@
 draw_byte(unsigned char c, long locX, long locY)
 {
 	unsigned long offset	= reloc_offset();
-	boot_infos_t* bi	= PTRRELOC(RELOC(boot_infos));
+	boot_infos_t* bi	= PTRRELOC(RELOC(disp_bi));
 	unsigned char *base	= calc_base(bi, locX << 3, locY << 4);
 	unsigned char *font	= &RELOC(vga_font)[((unsigned long)c) * 16];
+	int rb			= bi->dispDeviceRowBytes;
 	
 	switch(bi->dispDeviceDepth) {
 		case 32:
-			draw_byte_32(font, (unsigned long *)base);
+			draw_byte_32(font, (unsigned long *)base, rb);
 			break;
 		case 16:
-			draw_byte_16(font, (unsigned long *)base);
+			draw_byte_16(font, (unsigned long *)base, rb);
 			break;
 		case 8:
-			draw_byte_8(font, (unsigned long *)base);
+			draw_byte_8(font, (unsigned long *)base, rb);
 			break;
 		default:
 			break;
@@ -1661,10 +2116,8 @@
 
 __pmac
 static void
-draw_byte_32(unsigned char *font, unsigned long *base)
+draw_byte_32(unsigned char *font, unsigned long *base, int rb)
 {
-	unsigned long offset = reloc_offset();
-	boot_infos_t* bi		= PTRRELOC(RELOC(boot_infos));
 	int l, bits;	
 	int fg = 0xFFFFFFFFUL;
 	int bg = 0x00000000UL;
@@ -1681,19 +2134,18 @@
 		base[5] = (-((bits >> 2) & 1) & fg) ^ bg;
 		base[6] = (-((bits >> 1) & 1) & fg) ^ bg;
 		base[7] = (-(bits & 1) & fg) ^ bg;
-		base = (unsigned long *) ((char *)base + bi->dispDeviceRowBytes);
+		base = (unsigned long *) ((char *)base + rb);
 	}
 }
 
 __pmac
 static void
-draw_byte_16(unsigned char *font, unsigned long *base)
+draw_byte_16(unsigned char *font, unsigned long *base, int rb)
 {
-	unsigned long offset = reloc_offset();
-	boot_infos_t* bi		= PTRRELOC(RELOC(boot_infos));
 	int l, bits;	
 	int fg = 0xFFFFFFFFUL;
 	int bg = 0x00000000UL;
+	unsigned long offset = reloc_offset();
 	unsigned long *eb = RELOC(expand_bits_16);
 
 	for (l = 0; l < 16; ++l)
@@ -1703,19 +2155,18 @@
 		base[1] = (eb[(bits >> 4) & 3] & fg) ^ bg;
 		base[2] = (eb[(bits >> 2) & 3] & fg) ^ bg;
 		base[3] = (eb[bits & 3] & fg) ^ bg;
-		base = (unsigned long *) ((char *)base + bi->dispDeviceRowBytes);
+		base = (unsigned long *) ((char *)base + rb);
 	}
 }
 
 __pmac
 static void
-draw_byte_8(unsigned char *font, unsigned long *base)
+draw_byte_8(unsigned char *font, unsigned long *base, int rb)
 {
-	unsigned long offset = reloc_offset();
-	boot_infos_t* bi		= PTRRELOC(RELOC(boot_infos));
 	int l, bits;	
 	int fg = 0x0F0F0F0FUL;
 	int bg = 0x00000000UL;
+	unsigned long offset = reloc_offset();
 	unsigned long *eb = RELOC(expand_bits_8);
 
 	for (l = 0; l < 16; ++l)
@@ -1723,7 +2174,7 @@
 		bits = *font++;
 		base[0] = (eb[bits >> 4] & fg) ^ bg;
 		base[1] = (eb[bits & 0xf] & fg) ^ bg;
-		base = (unsigned long *) ((char *)base + bi->dispDeviceRowBytes);
+		base = (unsigned long *) ((char *)base + rb);
 	}
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/setup.c linux.17p18/arch/ppc/kernel/setup.c
--- linux.vanilla/arch/ppc/kernel/setup.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/setup.c	Tue Aug  1 07:59:05 2000
@@ -68,6 +68,13 @@
                       unsigned long r6,
                       unsigned long r7);
 
+#ifdef CONFIG_BOOTX_TEXT
+extern void map_bootx_text(void);
+#endif
+#ifdef CONFIG_XMON
+extern void xmon_map_scc(void);
+#endif
+
 extern boot_infos_t *boot_infos;
 extern char cmd_line[512];
 char saved_command_line[256];
@@ -256,6 +263,9 @@
 		case 10:
 			len += sprintf(len+buffer, "604ev5 (MachV)\n");
 			break;
+		case 12:
+			len += sprintf(len+buffer, "7400 (G4)\n");
+			break;
 		case 50:
 			len += sprintf(len+buffer, "821\n");
 		case 80:
@@ -456,11 +466,15 @@
 			char *p;
 			
 #ifdef CONFIG_BLK_DEV_INITRD
-			if (r3 - KERNELBASE < 0x800000
-			    && r4 != 0 && r4 != 0xdeadbeef) {
+			/* Removed check < 0x800000, yaboot loads the kernel at +16Mb
+			 * and the ramdisk _after_ the kernel */
+			if (r3 && r4 && r4 != 0xdeadbeef) {
+				if (r3 < KERNELBASE)
+					r3 += KERNELBASE;
 				initrd_start = r3;
 				initrd_end = r3 + r4;
 				ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0);
+				initrd_below_start_ok = 1;
 			}
 #endif
 			cmd_line[0] = 0;
@@ -538,7 +552,7 @@
 /* Checks "l2cr=xxxx" command-line option */
 void ppc_setup_l2cr(char *str, int *ints)
 {
-	if ( (_get_PVR() >> 16) == 8)
+	if ( ((_get_PVR() >> 16) == 8) || ((_get_PVR() >> 16) == 12) )
 	{
 		unsigned long val = simple_strtoul(str, NULL, 0);
 		printk(KERN_INFO "l2cr set to %lx\n", val);
@@ -564,14 +578,19 @@
 	extern unsigned long find_available_memory(void);
 	extern unsigned long *end_of_DRAM;
 
+#ifdef CONFIG_BOOTX_TEXT
+	map_bootx_text();
+#endif
+
 #ifdef CONFIG_XMON
-	extern void xmon_map_scc(void);
-	char *p;
+	{
+		char *p;
 
-	xmon_map_scc();
-	p = strstr(cmd_line, "xmon");
-	if (p != NULL && (p == cmd_line || p[-1] == ' '))
-		xmon(0);
+		xmon_map_scc();
+		p = strstr(cmd_line, "xmon");
+		if (p != NULL && (p == cmd_line || p[-1] == ' '))
+			xmon(0);
+	}
 #endif /* CONFIG_XMON */
  
 	/* reboot on panic */	
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/signal.c linux.17p18/arch/ppc/kernel/signal.c
--- linux.vanilla/arch/ppc/kernel/signal.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/signal.c	Tue Aug  1 07:59:05 2000
@@ -220,6 +220,10 @@
 		sr = (struct sigregs *) sigctx.regs;
 		if (regs->msr & MSR_FP )
 			giveup_fpu(current);
+#ifdef CONFIG_ALTIVEC
+		if (regs->msr & MSR_VEC)
+			giveup_altivec(current);
+#endif /* CONFIG_ALTIVEC */
 		if (copy_from_user(saved_regs, &sr->gp_regs,
 				   sizeof(sr->gp_regs)))
 			goto badframe;
@@ -268,6 +272,10 @@
 		goto badframe;
 	if (regs->msr & MSR_FP)
 		giveup_fpu(current);
+#ifdef CONFIG_ALTIVEC
+	if (regs->msr & MSR_VEC)
+		giveup_altivec(current);
+#endif /* CONFIG_ALTIVEC */
 	if (__copy_to_user(&frame->gp_regs, regs, GP_REGS_SIZE)
 	    || __copy_to_user(&frame->fp_regs, current->tss.fpr,
 			      ELF_NFPREG * sizeof(double))
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/smp.c linux.17p18/arch/ppc/kernel/smp.c
--- linux.vanilla/arch/ppc/kernel/smp.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/smp.c	Tue Aug  1 07:59:05 2000
@@ -7,7 +7,7 @@
  * deal of code from the sparc and intel versions.
  *
  * Support for PReP (Motorola MTX/MVME) SMP by Troy Benjegerdes
- * (troy@microux.com, hozer@drgw.net)
+ * (troy@blacklablinux.com, hozer@drgw.net)
  */
 
 #include <linux/kernel.h>
@@ -35,8 +35,8 @@
 #include <asm/io.h>
 #include <asm/prom.h>
 #include <asm/gemini.h>
-
-#include "time.h"
+#include <asm/residual.h>
+#include <asm/time.h>
 #include "open_pic.h"
 
 int first_cpu_booted = 0;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/syscalls.c linux.17p18/arch/ppc/kernel/syscalls.c
--- linux.vanilla/arch/ppc/kernel/syscalls.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/syscalls.c	Tue Aug  1 07:59:05 2000
@@ -199,6 +199,7 @@
 	struct file * file = NULL;
 	int ret = -EBADF;
 
+	down(&current->mm->mmap_sem);
 	lock_kernel();
 	if (!(flags & MAP_ANONYMOUS)) {
 		if (fd >= NR_OPEN || !(file = current->files->fd[fd]))
@@ -209,6 +210,7 @@
 	ret = do_mmap(file, addr, len, prot, flags, offset);
 out:
 	unlock_kernel();
+	up(&current->mm->mmap_sem);
 	return ret;
 }
 
@@ -246,9 +248,14 @@
 
 asmlinkage int sys_uname(struct old_utsname * name)
 {
-	if (name && !copy_to_user(name, &system_utsname, sizeof (*name)))
-		return 0;
-	return -EFAULT;
+	int err;
+	
+	if (!name)
+		return -EFAULT;
+	down(&uts_sem);
+	err = copy_to_user(name, &system_utsname, sizeof (*name));
+	up(&uts_sem);
+	return err ? -EFAULT : 0;
 }
 
 asmlinkage int sys_olduname(struct oldold_utsname * name)
@@ -260,6 +267,7 @@
 	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
 		return -EFAULT;
   
+  	down(&uts_sem);
 	error = __copy_to_user(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
 	error -= __put_user(0,name->sysname+__OLD_UTS_LEN);
 	error -= __copy_to_user(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
@@ -271,6 +279,7 @@
 	error -= __copy_to_user(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
 	error = __put_user(0,name->machine+__OLD_UTS_LEN);
 	error = error ? -EFAULT : 0;
+	up(&uts_sem);
 
 	return error;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/time.c linux.17p18/arch/ppc/kernel/time.c
--- linux.vanilla/arch/ppc/kernel/time.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/time.c	Tue Aug  1 07:59:05 2000
@@ -46,7 +46,7 @@
 #endif
 #include <asm/machdep.h>
 
-#include "time.h"
+#include <asm/time.h>
 
 void smp_local_timer_interrupt(struct pt_regs *);
 
@@ -106,6 +106,13 @@
 		if ( !smp_processor_id() )
 		{
 			do_timer(regs);
+#if 0
+	/* -- BenH -- I'm removing this for now since it can cause various
+	 *            troubles with local-time RTCs. Now that we have a
+	 *            /dev/rtc that uses ppc_md.set_rtc_time() on mac, it
+	 *            should be possible to program the RTC from userland
+	 *            in all cases.
+	 */
 			/*
 			 * update the rtc when needed
 			 */
@@ -119,6 +126,7 @@
 					/* do it again in 60 s */
 					last_rtc_update = xtime.tv_sec;
 			}
+#endif			
 		}
 	}
 #ifdef __SMP__
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/time.h linux.17p18/arch/ppc/kernel/time.h
--- linux.vanilla/arch/ppc/kernel/time.h	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/time.h	Thu Jan  1 01:00:00 1970
@@ -1,34 +0,0 @@
-/*
- * $Id: time.h,v 1.11.2.1 1999/08/27 04:20:35 cort Exp $
- * Common time prototypes and such for all ppc machines.
- *
- * Written by Cort Dougan (cort@cs.nmt.edu) to merge
- * Paul Mackerras' version and mine for PReP and Pmac.
- */
-
-#include <linux/mc146818rtc.h>
-
-/* time.c */
-extern unsigned decrementer_count;
-extern unsigned count_period_num;
-extern unsigned count_period_den;
-extern unsigned long mktime(unsigned int, unsigned int, unsigned int,
-			    unsigned int, unsigned int, unsigned int);
-extern void to_tm(int tim, struct rtc_time * tm);
-extern time_t last_rtc_update;
-
-int via_calibrate_decr(void);
-
-/* Accessor functions for the decrementer register. */
-static __inline__ unsigned int get_dec(void)
-{
-	unsigned int ret;
-
-	asm volatile("mfspr %0,22" : "=r" (ret) :);
-	return ret;
-}
-
-static __inline__ void set_dec(unsigned int val)
-{
-	asm volatile("mtspr 22,%0" : : "r" (val));
-}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/kernel/traps.c linux.17p18/arch/ppc/kernel/traps.c
--- linux.vanilla/arch/ppc/kernel/traps.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/kernel/traps.c	Tue Aug  1 07:59:05 2000
@@ -100,26 +100,27 @@
 			return;
 		}
 #endif
-		printk("Machine check in kernel mode.\n");
-		printk("Caused by (from msr): ");
-		printk("regs %p ",regs);
-		switch( regs->msr & 0x0000F000)
-		{
-		case (1<<12) :
-			printk("Machine check signal - probably due to mm fault\n"
-				"with mmu off\n");
+		printk("Machine check in kernel mode.  (regs at %p)\n", regs);
+		printk("Caused by (from srr1): ");
+		switch( regs->msr & 0x001F0000) {
+		case 0x100000:
+			printk("L2 data cache parity error\n");
 			break;
-		case (1<<13) :
+		case 0x80000:
+			printk("Machine check signal\n");
+			printk("(probably due to access of bad physical address\n");
+			break;
+		case 0x40000:
 			printk("Transfer error ack signal\n");
 			break;
-		case (1<<14) :
+		case 0x20000:
 			printk("Data parity signal\n");
 			break;
-		case (1<<15) :
+		case 0x10000:
 			printk("Address parity signal\n");
 			break;
 		default:
-			printk("Unknown values in msr\n");
+			printk("Unknown values in srr1\n");
 		}
 		show_regs(regs);
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/lib/string.S linux.17p18/arch/ppc/lib/string.S
--- linux.vanilla/arch/ppc/lib/string.S	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/lib/string.S	Tue Aug  1 07:59:05 2000
@@ -12,6 +12,11 @@
 #include <asm/processor.h>
 #include <asm/errno.h>
 
+CACHELINE_BYTES = 32
+LG_CACHELINE_BYTES = 5
+CACHELINE_MASK = 0x1f
+CACHELINE_WORDS = 8
+
 	.globl	strcpy
 strcpy:
 	addi	r5,r3,-1
@@ -82,7 +87,35 @@
 	andi.	r0,r6,3
 	add	r5,r0,r5
 	subf	r6,r0,r6
-	rlwinm	r0,r5,32-2,2,31
+#if 0	/* Clever, but breaks fb stuff -- paulus */
+/*
+ * Use dcbz on the complete cache lines in the destination if
+ * we are setting to zero.  This requires that the destination
+ * area is cacheable.  -- paulus
+ */
+	cmpwi	0,r4,0
+	bne	2f
+	clrlwi	r7,r6,32-LG_CACHELINE_BYTES
+	add	r8,r7,r5
+	srwi	r9,r8,LG_CACHELINE_BYTES
+	addic.	r9,r9,-1	/* total number of complete cachelines */
+	ble	2f
+	xori	r0,r7,CACHELINE_MASK & ~3
+	srwi.	r0,r0,2
+	beq	3f
+	mtctr	r0
+4:	stwu	r4,4(r6)
+	bdnz	4b
+3:	mtctr	r9
+	li	r7,4
+10:	dcbz	r7,r6
+	addi	r6,r6,CACHELINE_BYTES
+	bdnz	10b
+	clrlwi	r5,r8,32-LG_CACHELINE_BYTES
+	addi	r5,r5,4
+2:
+#endif
+	srwi	r0,r5,2
 	mtctr	r0
 	bdz	6f
 1:	stwu	r4,4(r6)
@@ -107,11 +140,94 @@
 memmove:
 	cmplw	0,r3,r4
 	bgt	backwards_memcpy
-	/* fall through */
+	b	forwards_memcpy
 
 	.globl	memcpy
 memcpy:
-	rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
+#if 0	/* Clever, but will probably break fb stuff -- paulus */
+/*
+ * This version uses dcbz on the complete cache lines in the
+ * destination area to reduce memory traffic.  This requires that
+ * the destination area is cacheable.
+ * We only use this version if the source and dest don't overlap.
+ * -- paulus.
+ */
+	add	r7,r3,r5		/* test if the src & dst overlap */
+	add	r8,r4,r5
+	cmplw	0,r4,r7
+	cmplw	1,r3,r8
+	crand	0,0,4			/* cr0.lt &= cr1.lt */
+	blt	forwards_memcpy		/* if regions overlap */
+
+	addi	r4,r4,-4
+	addi	r6,r3,-4
+	neg	r0,r3
+	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */
+	beq	58f
+
+	cmplw	0,r5,r0			/* is this more than total to do? */
+	blt	63f			/* if not much to do */
+	andi.	r8,r0,3			/* get it word-aligned first */
+	subf	r5,r0,r5
+	mtctr	r8
+	beq+	61f
+70:	lbz	r9,4(r4)		/* do some bytes */
+	stb	r9,4(r6)
+	addi	r4,r4,1
+	addi	r6,r6,1
+	bdnz	70b
+61:	srwi.	r0,r0,2
+	mtctr	r0
+	beq	58f
+72:	lwzu	r9,4(r4)		/* do some words */
+	stwu	r9,4(r6)
+	bdnz	72b
+
+58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+	clrlwi	r5,r5,32-LG_CACHELINE_BYTES
+	li	r11,4
+	mtctr	r0
+	beq	63f
+53:	dcbz	r11,r6
+	lwz	r7,4(r4)
+	lwz	r8,8(r4)
+	lwz	r9,12(r4)
+	lwzu	r10,16(r4)
+	stw	r7,4(r6)
+	stw	r8,8(r6)
+	stw	r9,12(r6)
+	stwu	r10,16(r6)
+	lwz	r7,4(r4)
+	lwz	r8,8(r4)
+	lwz	r9,12(r4)
+	lwzu	r10,16(r4)
+	stw	r7,4(r6)
+	stw	r8,8(r6)
+	stw	r9,12(r6)
+	stwu	r10,16(r6)
+	bdnz	53b
+
+63:	srwi.	r0,r5,2
+	mtctr	r0
+	beq	64f
+30:	lwzu	r0,4(r4)
+	stwu	r0,4(r6)
+	bdnz	30b
+
+64:	andi.	r0,r5,3
+	mtctr	r0
+	beq+	65f
+40:	lbz	r0,4(r4)
+	stb	r0,4(r6)
+	addi	r4,r4,1
+	addi	r6,r6,1
+	bdnz	40b
+65:	blr
+#endif
+
+	.global	forwards_memcpy
+forwards_memcpy:
+	srwi.	r7,r5,3
 	addi	r6,r3,-4
 	addi	r4,r4,-4
 	beq	2f			/* if less than 8 bytes to do */
@@ -218,106 +334,167 @@
 
 	.globl	__copy_tofrom_user
 __copy_tofrom_user:
-	srwi.	r7,r5,3
-	addi	r6,r3,-4
 	addi	r4,r4,-4
-	li	r3,0		/* success return value */
-	beq	2f		/* if less than 8 bytes to do */
-	andi.	r0,r6,3		/* get dest word aligned */
-	mtctr	r7
-	bne	5f
-1:	lwz	r7,4(r4)
-11:	lwzu	r8,8(r4)
-12:	stw	r7,4(r6)
-13:	stwu	r8,8(r6)
-	bdnz	1b
-	andi.	r5,r5,7
-2:	cmplwi	0,r5,4
-	blt	3f
-14:	lwzu	r0,4(r4)
-	addi	r5,r5,-4
-15:	stwu	r0,4(r6)
-3:	cmpwi	0,r5,0		/* do 1 byte at a time for the remainder */
-	beqlr
-	mtctr	r5
-	addi	r4,r4,3
-	addi	r6,r6,3
-4:	lbzu	r0,1(r4)
-16:	stbu	r0,1(r6)
-	bdnz	4b
-	blr
-5:	subfic	r0,r0,4		/* copy bytes until we have the */
-	mtctr	r0		/* destination 4-byte aligned */
-	subf	r5,r0,r5
-6:	lbz	r7,4(r4)
+	addi	r6,r3,-4
+	neg	r0,r3
+	andi.	r0,r0,CACHELINE_MASK	/* # bytes to start of cache line */
+	beq	58f
+
+	cmplw	0,r5,r0			/* is this more than total to do? */
+	blt	63f			/* if not much to do */
+	andi.	r8,r0,3			/* get it word-aligned first */
+	mtctr	r8
+	beq+	61f
+70:	lbz	r9,4(r4)		/* do some bytes */
+71:	stb	r9,4(r6)
 	addi	r4,r4,1
-17:	stb	r7,4(r6)
 	addi	r6,r6,1
-	bdnz	6b
-	srwi.	r7,r5,3
-	beq	2b
-	mtctr	r7
-	b	1b
-/* we come here on a fault in the 8-byte-at-a-time loop */
-88:	subi	r4,r4,8		/* compensate for the lwzu */
-98:	mfctr	r0
-	rlwimi	r5,r0,3,0,28	/* use the byte-at-a-time loop to */
-	b	3b		/* copy up to the byte at fault */
-/* here on a write fault in the single-word copy */
-96:	subi	r4,r4,4
-	b	3b
-/* here on a read fault in the initial single-byte copy */
-90:	mfctr	r3
-	add	r3,r3,r5
-	b	70f
-/* here on a read fault in the final single-byte copy */
-99:	mfctr	r3
-	subi	r6,r6,3
-/* clear out the rest of the destination: r3 bytes starting at 4(r6) */
-70:	li	r0,0
-	mr.	r5,r3
-	beq	76f
-71:	andi.	r4,r6,3
-	beq	72f
-77:	stb	r0,4(r6)
+	bdnz	70b
+61:	subf	r5,r0,r5
+	srwi.	r0,r0,2
+	mtctr	r0
+	beq	58f
+72:	lwzu	r9,4(r4)		/* do some words */
+73:	stwu	r9,4(r6)
+	bdnz	72b
+
+58:	srwi.	r0,r5,LG_CACHELINE_BYTES /* # complete cachelines */
+	clrlwi	r5,r5,32-LG_CACHELINE_BYTES
+	li	r11,4
+	mtctr	r0
+	beq	63f
+53:	dcbz	r11,r6
+10:	lwz	r7,4(r4)
+11:	lwz	r8,8(r4)
+12:	lwz	r9,12(r4)
+13:	lwzu	r10,16(r4)
+14:	stw	r7,4(r6)
+15:	stw	r8,8(r6)
+16:	stw	r9,12(r6)
+17:	stwu	r10,16(r6)
+20:	lwz	r7,4(r4)
+21:	lwz	r8,8(r4)
+22:	lwz	r9,12(r4)
+23:	lwzu	r10,16(r4)
+24:	stw	r7,4(r6)
+25:	stw	r8,8(r6)
+26:	stw	r9,12(r6)
+27:	stwu	r10,16(r6)
+	bdnz	53b
+
+63:	srwi.	r0,r5,2
+	mtctr	r0
+	beq	64f
+30:	lwzu	r0,4(r4)
+31:	stwu	r0,4(r6)
+	bdnz	30b
+
+64:	andi.	r0,r5,3
+	mtctr	r0
+	beq+	65f
+40:	lbz	r0,4(r4)
+41:	stb	r0,4(r6)
+	addi	r4,r4,1
 	addi	r6,r6,1
-	addic.	r5,r5,-1
-	bne	71b
-72:	srwi.	r7,r5,2
-	beq	73f
-	mtctr	r7
-74:	stwu	r0,4(r6)
-	bdnz	74b
-73:	andi.	r5,r5,3
-	beq	76f
-	mtctr	r5
-	addi	r6,r6,3
-75:	stbu	r0,1(r6)
-	bdnz	75b
-76:	blr
-/* here on a write fault in the initial single-byte copy */
-80:	mfctr	r3
-	add	r3,r3,r5
-	blr
-/* here on a write fault in the final single-byte copy */
-81:	mfctr	r3
+	bdnz	40b
+65:	li	r3,0
 	blr
 
+/* read fault, initial single-byte copy */
+100:	li	r4,0
+	b	90f
+/* write fault, initial single-byte copy */
+101:	li	r4,1
+90:	subf	r5,r8,r5
+	li	r3,0
+	b	99f
+/* read fault, initial word copy */
+102:	li	r4,0
+	b	91f
+/* write fault, initial word copy */
+103:	li	r4,1
+91:	li	r3,2
+	b	99f
+/* read fault in 2nd half of cacheline loop */
+106:	addi	r5,r5,-16
+/* read fault in 1st half of cacheline loop */
+104:	li	r4,0
+	b	92f
+/* write fault in 2nd half of cacheline loop */
+107:	addi	r5,r5,-16
+/* fault on dcbz (effectively a write fault) */
+/* or write fault in 1st half of cacheline loop */
+105:	li	r4,1
+92:	li	r3,LG_CACHELINE_BYTES
+	b	99f
+/* read fault in final word loop */
+108:	li	r4,0
+	b	93f
+/* write fault in final word loop */
+109:	li	r4,1
+93:	andi.	r5,r5,3
+	li	r3,2
+	b	99f
+/* read fault in final byte loop */
+110:	li	r4,0
+	b	94f
+/* write fault in final byte loop */
+111:	li	r4,1
+94:	li	r5,0
+	li	r3,0
+/*
+ * At this stage the number of bytes not copied is
+ * r5 + (ctr << r3), and r4 is 0 for read or 1 for write.
+ */
+99:	mfctr	r0
+	slw	r3,r0,r3
+	add	r3,r3,r5
+	cmpwi	0,r4,0
+	bne	120f
+/* for read fault, clear out the destination: r3 bytes starting at 4(r6) */
+	srwi.	r0,r3,2
+	li	r9,0
+	mtctr	r0
+	beq	113f
+112:	stwu	r9,4(r6)
+	bdnz	112b
+113:	andi.	r0,r3,3
+	mtctr	r0
+	beq	120f
+114:	stb	r9,4(r6)
+	addi	r6,r6,1
+	bdnz	114b
+120:	blr
+
 .section __ex_table,"a"
 	.align	2
-	.long	1b,98b
-	.long	11b,98b
-	.long	12b,88b
-	.long	13b,88b
-	.long	14b,3b
-	.long	15b,96b
-	.long	4b,99b
-	.long	16b,81b
-	.long	6b,90b
-	.long	17b,80b
-	.long	77b,76b
-	.long	74b,76b
-	.long	75b,76b
+	.long	70b,100b
+	.long	71b,101b
+	.long	72b,102b
+	.long	73b,103b
+	.long	53b,105b
+	.long	10b,104b
+	.long	11b,104b
+	.long	12b,104b
+	.long	13b,104b
+	.long	14b,105b
+	.long	15b,105b
+	.long	16b,105b
+	.long	17b,105b
+	.long	20b,106b
+	.long	21b,106b
+	.long	22b,106b
+	.long	23b,106b
+	.long	24b,107b
+	.long	25b,107b
+	.long	26b,107b
+	.long	27b,107b
+	.long	30b,108b
+	.long	31b,109b
+	.long	40b,110b
+	.long	41b,111b
+	.long	112b,120b
+	.long	114b,120b
 .text
 
 	.globl	__clear_user
@@ -334,7 +511,6 @@
 	andi.	r0,r6,3
 	add	r4,r0,r4
 	subf	r6,r0,r6
-	/*rlwinm	r0,r4,32-2,2,31*/
 	srwi	r0,r4,2
 	mtctr	r0
 	bdz	6f
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/mm/fault.c linux.17p18/arch/ppc/mm/fault.c
--- linux.vanilla/arch/ppc/mm/fault.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/mm/fault.c	Tue Aug  1 07:59:05 2000
@@ -71,7 +71,10 @@
 	       (error_code&0x80000000)?"I/O ":"",
 	       (regs->trap == 0x400)?"instr":"data"
 	       );*/
-	       
+
+	if (regs->trap == 0x400)
+		error_code &= 0x48200000;
+
 #if defined(CONFIG_XMON) || defined(CONFIG_KGDB)
 	if (debugger_fault_handler && regs->trap == 0x300) {
 		debugger_fault_handler(regs);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/mm/init.c linux.17p18/arch/ppc/mm/init.c
--- linux.vanilla/arch/ppc/mm/init.c	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/mm/init.c	Tue Aug  1 07:59:05 2000
@@ -416,7 +416,12 @@
 
 void iounmap(void *addr)
 {
-	/* XXX todo */
+	/* For support of dynamic hot swap on the cPCI bus this routine
+	   is now necessary.  This has been well tested on a Motorola
+	   MPC750 (Mesquite) processor board.  Johnnie Peters
+	*/
+	if (addr > high_memory && (unsigned long) addr < ioremap_bot)
+		return vfree((void *) (PAGE_MASK & (unsigned long) addr));
 }
 
 unsigned long iopa(unsigned long addr)
@@ -928,15 +933,21 @@
 				/* On the powerpc, no user access
 				   forces R/W kernel access */
 				f |= _PAGE_USER;
+			map_page(v, p, f);
+			v += PAGE_SIZE;
+			p += PAGE_SIZE;
+		}
+	}
+
 #else	/* CONFIG_8xx */
-            for (i = 0; i < phys_mem.n_regions; ++i) {
-                    v = (ulong)__va(phys_mem.regions[i].address);
-                    p = phys_mem.regions[i].address;
-                    for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) {
+	for (i = 0; i < phys_mem.n_regions; ++i) {
+		v = (ulong)__va(phys_mem.regions[i].address);
+		p = phys_mem.regions[i].address;
+		for (s = 0; s < phys_mem.regions[i].size; s += PAGE_SIZE) {
                         /* On the MPC8xx, we want the page shared so we
                          * don't get ASID compares on kernel space.
                          */
-                            f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
+			f = _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_SHARED;
 
                         /* I don't really need the rest of this code, but
                          * I grabbed it because I think the line:
@@ -946,14 +957,14 @@
                          * the MPC8xx, the PAGE_DIRTY takes care of that
                          * for us (along with the RW software state).
                          */
-                            if ((char *) v < _stext || (char *) v >= etext)
-                                    f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
-#endif /* CONFIG_8xx */
+			if ((char *) v < _stext || (char *) v >= etext)
+				f |= _PAGE_RW | _PAGE_DIRTY | _PAGE_HWWRITE;
 			map_page(v, p, f);
 			v += PAGE_SIZE;
 			p += PAGE_SIZE;
 		}
-	}	    
+	}
+#endif /* CONFIG_8xx */
 }
 
 /* This can get called from ioremap, so don't make it an initfunc, OK? */
@@ -1052,7 +1063,6 @@
 #endif /* CONFIG_GEMINI	*/
 	else /* prep */
 		end_of_DRAM = prep_find_end_of_memory();
-*(unsigned long *)(KERNELBASE) = 0xdeadbeef;	
         hash_init();
         _SDR1 = __pa(Hash) | (Hash_mask >> 10);
 	ioremap_base = 0xf8000000;
@@ -1252,8 +1262,8 @@
 #endif /* CONFIG_BLK_DEV_INITRD */
 #ifndef CONFIG_8xx		  
 			if ( !rtas_data ||
-			     addr < (rtas_data & PAGE_MASK) ||
-			     addr >= (rtas_data+rtas_size))
+			     addr < (rtas_data + KERNELBASE) ||
+			     addr >= (rtas_data + KERNELBASE + rtas_size))
 #endif /* CONFIG_8xx */
 				free_page(addr);
 	}
@@ -1314,6 +1324,7 @@
 	return ret;
 }
 #endif /* CONFIG_MBX */
+
 #ifndef CONFIG_8xx
 /*
  * On systems with Open Firmware, collect information about
@@ -1380,6 +1391,7 @@
 	if (boot_infos == 0) {
 		/* record which bits the prom is using */
 		get_mem_prop("available", &phys_avail);
+		remove_mem_piece(&phys_avail, __max_memory, ~__max_memory, 0);
 		prom_mem = phys_mem;
 		for (i = 0; i < phys_avail.n_regions; ++i)
 			remove_mem_piece(&prom_mem,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/pmac_defconfig linux.17p18/arch/ppc/pmac_defconfig
--- linux.vanilla/arch/ppc/pmac_defconfig	Fri Apr 21 12:45:47 2000
+++ linux.17p18/arch/ppc/pmac_defconfig	Tue Aug  1 07:59:05 2000
@@ -253,6 +253,7 @@
 CONFIG_NET_ETHERNET=y
 CONFIG_MACE=y
 CONFIG_BMAC=y
+CONFIG_GMAC=y
 # CONFIG_NET_VENDOR_3COM is not set
 # CONFIG_LANCE is not set
 # CONFIG_NET_VENDOR_SMC is not set
@@ -339,6 +340,7 @@
 CONFIG_FB_PLATINUM=y
 CONFIG_FB_VALKYRIE=y
 CONFIG_FB_ATY=y
+CONFIG_FB_ATY128=y
 CONFIG_FB_IMSTT=y
 CONFIG_FB_CT65550=y
 # CONFIG_FB_S3TRIO is not set
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/ppc/xmon/start.c linux.17p18/arch/ppc/xmon/start.c
--- linux.vanilla/arch/ppc/xmon/start.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/ppc/xmon/start.c	Tue Aug  1 07:59:05 2000
@@ -11,16 +11,30 @@
 #include <asm/prom.h>
 #include <asm/bootx.h>
 #include <asm/pmu.h>
+#include <asm/feature.h>
 
 static volatile unsigned char *sccc, *sccd;
 unsigned long TXRDY, RXRDY;
 extern void xmon_printf(const char *fmt, ...);
-extern void map_bootx_text(void);
 extern void drawchar(char);
 extern void drawstring(const char *str);
+static int xmon_expect(const char *str, unsigned int timeout);
 
 static int console = 0;
 static int use_screen = 0;
+static int via_modem = 0;
+static int xmon_use_sccb = 0;
+static struct device_node *macio_node;
+
+#define TB_SPEED	25000000
+
+static inline unsigned int readtb(void)
+{
+	unsigned int ret;
+
+	asm volatile("mftb %0" : "=r" (ret) :);
+	return ret;
+}
 
 void buf_access(void)
 {
@@ -36,17 +50,18 @@
 	if ( _machine == _MACH_Pmac )
 	{
 		struct device_node *np;
-		extern boot_infos_t *boot_infos;
 		unsigned long addr;
-
 #ifdef CONFIG_BOOTX_TEXT
-		if (boot_infos != 0 && find_via_pmu()) {
+		extern boot_infos_t *disp_bi;
+
+		/* needs to be hacked if xmon_printk is to be used
+ 		   from within find_via_pmu() */
+		if (!via_modem && disp_bi && find_via_pmu()) {
 			printk(KERN_INFO "xmon uses screen and keyboard\n");
 			use_screen = 1;
-			map_bootx_text();
-			return;
 		}
 #endif
+
 #ifdef CHRP_ESCC
 		addr = 0xc1013020;
 #else
@@ -57,18 +72,13 @@
 		
 		np = find_devices("mac-io");
 		if (np && np->n_addrs) {
-			addr = np->addrs[0].address + 0x13000;
-			/* use the B channel on the iMac, A channel on others */
-			if (addr >= 0xf0000000)
-				addr += 0x20; /* use A channel */
+			macio_node = np;
+			addr = np->addrs[0].address + 0x13020;
 		}
-		base = (volatile unsigned char *) ioremap(addr & PAGE_MASK, PAGE_SIZE);
+		base = (volatile unsigned char *)
+			ioremap(addr & PAGE_MASK, PAGE_SIZE);
 		sccc = base + (addr & ~PAGE_MASK);
-#ifdef CHRP_ESCC
-		sccd = sccc + (0xc1013030 - 0xc1013020);
-#else
-		sccd = sccc + (0xf3013030 - 0xf3013020);
-#endif
+		sccd = sccc + 0x10;
 	}
 	else
 	{
@@ -89,7 +99,7 @@
 xmon_write(void *handle, void *ptr, int nb)
 {
     char *p = ptr;
-    int i, ct;
+    int i, c, ct;
 
 #ifdef CONFIG_BOOTX_TEXT
     if (use_screen) {
@@ -101,19 +111,23 @@
 #endif
     if (!scc_initialized)
 	xmon_init_scc();
+    ct = 0;
     for (i = 0; i < nb; ++i) {
 	while ((*sccc & TXRDY) == 0)
 	    if (adb_hardware == ADB_VIAPMU)
 		pmu_poll();
+	c = p[i];
+	if (c == '\n' && !ct) {
+	    c = '\r';
+	    ct = 1;
+	    --i;
+	} else {
+	    if (console)
+		printk("%c", c);
+	    ct = 0;
+	}
 	buf_access();
-	if ( console && (*p != '\r'))
-		printk("%c", *p);
-	ct = 0;
-	if ( *p == '\n')
-		ct = 1;
-	*sccd = *p++;
-	if ( ct )
-		xmon_write(handle, "\r", 1);
+	*sccd = c;
     }
     return i;
 }
@@ -199,23 +213,30 @@
 	    if (adb_hardware == ADB_VIAPMU)
 		pmu_poll();
 	buf_access();
-#if 0	
-	if ( 0/*console*/ )
-		*p++ = ppc_md.kbd_getkeycode();
-	else
-#endif		
-		*p++ = *sccd;
+	*p++ = *sccd;
     }
     return i;
 }
 
+int
+xmon_read_poll(void)
+{
+	if ((*sccc & RXRDY) == 0) {
+		if (adb_hardware == ADB_VIAPMU)
+			pmu_poll();
+		return -1;
+	}
+	buf_access();
+	return *sccd;
+}
+
 static unsigned char scc_inittab[] = {
     13, 0,		/* set baud rate divisor */
     12, 1,
     14, 1,		/* baud rate gen enable, src=rtxc */
     11, 0x50,		/* clocks = br gen */
-    5,  0x6a,		/* tx 8 bits, assert RTS */
-    4,  0x44,		/* x16 clock, 1 stop */
+    5,  0xea,		/* tx 8 bits, assert DTR & RTS */
+    4,  0x46,		/* x16 clock, 1 stop */
     3,  0xc1,		/* rx enable, 8 bits */
 };
 
@@ -235,6 +256,21 @@
 	{
 		int i, x;
 
+		if (macio_node != 0) {
+			unsigned int t0;
+
+			feature_set(macio_node, FEATURE_Serial_enable);
+			if (via_modem) {
+				feature_set(macio_node, FEATURE_Modem_power);
+				t0 = readtb();
+				while (readtb() - t0 < 3*TB_SPEED)
+					eieio();
+			}
+		}
+		if (xmon_use_sccb) {
+			sccc -= 0x20;
+			sccd -= 0x20;
+		}
 		for (i = 20000; i != 0; --i) {
 			x = *sccc; eieio();
 		}
@@ -246,6 +282,18 @@
 		}
 	}
 	scc_initialized = 1;
+	if (via_modem) {
+		for (;;) {
+			xmon_write(0, "ATE1V1\r", 7);
+			if (xmon_expect("OK", 5)) {
+				xmon_write(0, "ATA\r", 4);
+				if (xmon_expect("CONNECT", 40))
+					break;
+			}
+			xmon_write(0, "+++", 3);
+			xmon_expect("OK", 3);
+		}
+	}
 }
 
 #if 0
@@ -317,6 +365,35 @@
 static char line[256];
 static char *lineptr;
 static int lineleft;
+
+int xmon_expect(const char *str, unsigned int timeout)
+{
+	int c;
+	unsigned int t0;
+
+	timeout *= TB_SPEED;
+	t0 = readtb();
+	do {
+		lineptr = line;
+		for (;;) {
+			c = xmon_read_poll();
+			if (c == -1) {
+				if (readtb() - t0 > timeout) {
+					printk("timeout\n");
+					return 0;
+				}
+				continue;
+			}
+			if (c == '\n')
+				break;
+			printk("%c", c);
+			if (c != '\r' && lineptr < &line[sizeof(line) - 1])
+				*lineptr++ = c;
+		}
+		*lineptr = 0;
+	} while (strstr(line, str) == NULL);
+	return 1;
+}
 
 int
 xmon_getchar(void)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/Makefile linux.17p18/arch/s390/Makefile
--- linux.vanilla/arch/s390/Makefile	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/Makefile	Tue Aug  1 07:59:05 2000
@@ -1,5 +1,5 @@
 
-# i386/Makefile
+# s390/Makefile
 #
 # 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
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/boot/Makefile linux.17p18/arch/s390/boot/Makefile
--- linux.vanilla/arch/s390/boot/Makefile	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/boot/Makefile	Tue Aug  1 07:59:05 2000
@@ -1,5 +1,5 @@
 #
-# Makefile for the linux i386-specific parts of the memory manager.
+# Makefile for the linux s390-specific parts of the memory manager.
 #
 # Note! Dependencies are done automagically by 'make dep', which also
 # removes any old dependencies. DON'T put your own dependencies here
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/defconfig linux.17p18/arch/s390/defconfig
--- linux.vanilla/arch/s390/defconfig	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/defconfig	Tue Aug  1 07:59:05 2000
@@ -26,8 +26,8 @@
 #
 CONFIG_FAST_IRQ=y
 CONFIG_IPL=y
-# CONFIG_IPL_TAPE is not set
-CONFIG_IPL_VM=y
+CONFIG_IPL_TAPE=y
+# CONFIG_IPL_VM is not set
 CONFIG_NET=y
 CONFIG_SYSVIPC=y
 # CONFIG_BSD_PROCESS_ACCT is not set
@@ -41,9 +41,9 @@
 # CONFIG_BLK_DEV_NBD is not set
 # CONFIG_BLK_DEV_MD is not set
 CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_SIZE=8192
 CONFIG_BLK_DEV_INITRD=y
-CONFIG_BLK_DEV_XPRAM=y
-CONFIG_BLK_DEV_INITRD=y
+CONFIG_BLK_DEV_XPRAM=m
 # CONFIG_MDISK is not set
 CONFIG_DASD=y
 CONFIG_DASD_ECKD=y
@@ -140,7 +140,8 @@
 #
 # CONFIG_CODA_FS is not set
 CONFIG_NFS_FS=y
-# CONFIG_NFSD is not set
+CONFIG_NFSD=y
+# CONFIG_NFSD_SUN is not set
 CONFIG_SUNRPC=y
 CONFIG_LOCKD=y
 # CONFIG_SMB_FS is not set
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/debug.c linux.17p18/arch/s390/kernel/debug.c
--- linux.vanilla/arch/s390/kernel/debug.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/debug.c	Tue Aug  1 07:59:05 2000
@@ -3,6 +3,7 @@
 #include <linux/errno.h>
 #include <linux/malloc.h>
 #include <asm/ebcdic.h>
+#include <asm/debug.h>
 
 #ifdef MODULE
 #include <linux/module.h>
@@ -10,9 +11,7 @@
 
 #include <asm/ebcdic.h>
 
-#include "debug.h"
-
-debug_info_t debug_areas[MAX_DEBUG_AREAS];
+debug_info_t debug_areas[MAX_DEBUG_AREAS] = { {NULL, },};
 debug_info_t *free_area = 0;
 static int initialized = 0;
 
@@ -38,6 +37,7 @@
   rc = free_area;
   free_area = *((debug_info_t **) rc);
 
+  memset(rc, 0, nr_areas * sizeof(debug_info_t));
   rc->areas = (debug_entry_t **) kmalloc (nr_areas *
 					  sizeof (debug_entry_t *),
 					  GFP_ATOMIC);
@@ -59,14 +59,16 @@
 	  goto nopages;
 	}
     }
-
   rc->page_order = page_order;
   rc->nr_areas = nr_areas;
   rc->name = kmalloc (strlen (name) + 1, GFP_ATOMIC);
   strncpy (rc->name, name, strlen (name));
+  ASCEBC(rc->name, strlen (name));
   rc->name[strlen (name)] = 0;
+
   rc->active_entry = kmalloc (nr_areas, GFP_ATOMIC);
   memset(rc->active_entry, 0, nr_areas * sizeof(int));
+  rc->level=3;
   printk (KERN_INFO "reserved %d areas of %d pages for debugging %s\n",
 	  nr_areas, 1 << page_order, name);
   goto exit;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/debug.h linux.17p18/arch/s390/kernel/debug.h
--- linux.vanilla/arch/s390/kernel/debug.h	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/debug.h	Thu Jan  1 01:00:00 1970
@@ -1,55 +0,0 @@
-
-#ifndef DEBUG_H
-#define DEBUG_H
-
-#include <asm/spinlock.h>
-
-#define MAX_DEBUG_AREAS 16
-
-#define STCK(x) asm volatile ("STCK %0":"=m" (x))
-
-typedef struct
-{
-  union
-  {
-    struct
-    {
-      unsigned long long cpuid:4;
-      unsigned long long clock:60;
-    }
-    fields;
-    unsigned long long stck;
-  }
-  id;
-  void *caller;
-  union
-  {
-    unsigned long tag;
-    char text[4];
-  }
-  tag;
-}
-debug_entry_t;
-
-typedef struct
-{
-  char *name;
-  int level;
-  int nr_areas;
-  int page_order;
-  debug_entry_t **areas;
-  int active_area;
-  int *active_entry;
-  spinlock_t lock;
-}
-debug_info_t;
-
-int debug_init (void);
-debug_info_t *debug_register (char *name, int pages_index, int nr_areas);
-void debug_unregister (debug_info_t * id, char *name);
-void debug_event (debug_info_t * id, int level, unsigned int tag);
-void debug_text_event (debug_info_t * id, int level, char tag[4]);
-void debug_exception (debug_info_t * id, int level, unsigned int tag);
-void debug_text_exception (debug_info_t * id, int level, char tag[4]);
-
-#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/entry.S linux.17p18/arch/s390/kernel/entry.S
--- linux.vanilla/arch/s390/kernel/entry.S	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/entry.S	Tue Aug  1 07:59:05 2000
@@ -300,7 +300,7 @@
         stosm   24(%r15),0x03     # reenable interrupts
         sr      %r0,%r0           # child returns 0
         st      %r0,SP_R2(%r15)   # store return value (change R2 on stack)
-#ifdef __SMP__
+#ifdef CONFIG_SMP
         l       %r1,BASED(.Lschedtail)
 	la      %r14,BASED(sysc_return)
         br      %r1               # call schedule_tail, return to sysc_return
@@ -787,7 +787,7 @@
 mcck_return:
         RESTORE_ALL
 
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 /*
  * Restart interruption handler, kick starter for additional CPUs
  */
@@ -862,6 +862,6 @@
 .Ltrace:       .long  syscall_trace
 .Lvfork:       .long  sys_vfork
 
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 .Lschedtail:   .long  schedule_tail
 #endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/head.S linux.17p18/arch/s390/kernel/head.S
--- linux.vanilla/arch/s390/kernel/head.S	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/head.S	Tue Aug  1 07:59:05 2000
@@ -5,8 +5,9 @@
  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  *    Author(s): Hartmut Penner (hp@de.ibm.com),
  *               Martin Schwidefsky (schwidefsky@de.ibm.com),
+ *               Rob van der Heij
  *
- * There are 4 different IPL methods
+ * There are 5 different IPL methods
  *  1) load the image directly into ram at address 0 and do an PSW restart
  *  2) linload will load the image from address 0x10000 to memory 0x10000
  *     and start the code thru LPSW 0x0008000080010000 (VM only, deprecated)
@@ -14,6 +15,7 @@
  *     and ipl from it
  *  4) generate the vm reader ipl header, move the generated image to the
  *     VM reader (use option NOH!) and do a ipl from reader (VM only)
+ *  5) direct call of start by the SALIPL loader
  *  We use the cpuid to distinguish between VM and native ipl
  *  params for kernel are pushed to 0x10400 (see setup.h)
  */
@@ -24,34 +26,7 @@
 
 #ifndef CONFIG_IPL
         .org   0
-        .long  0x00080000,0x80000000+iplstart  # Just a restart PSW
-
-iplstart:
-        l     %r12,.Lparm                      # pointer to parameter area
-#
-# find out memory size
-#
-        mvc   104(8,0),.Lpcmem0          # setup program check handler
-        slr   %r2,%r2
-        lhi   %r3,1
-        sll   %r3,20
-.Lloop0:
-        l     %r0,0(%r2)                 # test page
-        ar    %r2,%r3                    # add 1M
-        jnm   .Lloop0                    # r1 < 0x80000000 -> loop
-.Lchkmem0:
-        n     %r2,.L4malign0             # align to multiples of 4M
-        st    %r2,MEMORY_SIZE-PARMAREA(%r12)  # store memory size
-        slr   %r2,%r2
-        st    %r2,INITRD_SIZE-PARMAREA(%r12)  # null ramdisk
-        st    %r2,INITRD_START-PARMAREA(%r12)
-        j     start
-
-.Lparm: .long  PARMAREA
-.L4malign0:.long 0xffc00000
-        .align 8
-.Lpcmem0:.long  0x00080000,0x80000000 + .Lchkmem0
-
+        .long  0x00080000,0x80000000+startup   # Just a restart PSW
 #else
 #ifdef CONFIG_IPL_TAPE
 #define IPL_BS 1024
@@ -74,92 +49,6 @@
         .long  0x00080000,0x80000000+.Lioint   # io new psw
 
         .org   0x100
-iplstart:
-	l     %r1,0xb8                         # load ipl subchannel number
-        lhi   %r2,IPL_BS                       # load start address
-        bras  %r14,.Lloader                    # load rest of ipl image
-        st    %r1,__LC_IPLDEV                  # store ipl device number
-        l     %r12,.Lparm                      # pointer to parameter area
-
-#
-# find out memory size
-#
-        mvc   104(8,0),.Lpcmem0          # setup program check handler
-        slr   %r2,%r2
-        lhi   %r3,1
-        sll   %r3,20
-.Lloop0:
-        l     %r0,0(%r2)                 # test page
-        ar    %r2,%r3                    # add 1M
-        jnm   .Lloop0                    # r1 < 0x80000000 -> loop
-.Lchkmem0:
-        n     %r2,.L4malign0             # align to multiples of 4M
-        st    %r2,MEMORY_SIZE-PARMAREA(%r12)  # store memory size
-        c     %r2,.Lbigmem               # more than 64 MB of memory ?
-        jl    .Lmemok                    # if yes load ramdisk to 32 MB
-        mvc   INITRD_START-PARMAREA(4,%r12),.Lrdstart
-.Lmemok:
-
-#
-# load parameter file from tape
-#
- 	l     %r2,INITRD_START-PARMAREA(%r12)  # use ramdisk location as temp
-        bras  %r14,.Lloader                    # load parameter file
-        ltr   %r2,%r2                          # got anything ?
-        jz    .Lnopf
-	chi   %r2,895
-	jnh   .Lnotrunc
-	lhi   %r2,895
-.Lnotrunc:
-	l     %r4,INITRD_START-PARMAREA(%r12)
-        la    %r5,0(%r4,%r2)
-        lr    %r3,%r2
-.Lidebc:
-        tm    0(%r5),0x80                      # high order bit set ?
-        jo    .Ldocv                           #  yes -> convert from EBCDIC
-        ahi   %r5,-1
-        brct  %r3,.Lidebc
-        j     .Lnocv
-.Ldocv:
-        l     %r3,.Lcvtab
-        tr    0(256,%r4),0(%r3)                # convert parameters to ascii
-        tr    256(256,%r4),0(%r3)
-        tr    512(256,%r4),0(%r3)
-        tr    768(122,%r4),0(%r3)
-.Lnocv: la    %r3,COMMAND_LINE-PARMAREA(%r12)  # load adr. of command line
-	mvc   0(256,%r3),0(%r4)
-	mvc   256(256,%r3),256(%r4)
-	mvc   512(256,%r3),512(%r4)
-	mvc   768(122,%r3),768(%r4)
-        slr   %r0,%r0
-        j     .Lcntlp
-.Ldelspc:
-        ic    %r0,0(%r2,%r3)
-        chi   %r0,0x20                         # is it a space ?
-        je    .Lcntlp
-        ahi   %r2,1
-        j     .Leolp
-.Lcntlp:
-        brct  %r2,.Ldelspc
-.Leolp:
-        slr   %r0,%r0
-        stc   %r0,0(%r2,%r3)                   # terminate buffer
-.Lnopf:
-
-#
-# load ramdisk from tape
-#	
- 	l     %r2,INITRD_START-PARMAREA(%r12)  # load adr. of ramdisk
-        bras  %r14,.Lloader                    # load ramdisk
- 	st    %r2,INITRD_SIZE-PARMAREA(%r12)   # store size of ramdisk
-        ltr   %r2,%r2
-        jnz   .Lrdcont
-        st    %r2,INITRD_START-PARMAREA(%r12)  # no ramdisk found, null it
-.Lrdcont:
-#
-# everything loaded, go for it
-#
-        j     start
 #
 # subroutine for loading from tape
 # Paramters:	
@@ -173,32 +62,32 @@
         lctl  %c6,%c6,.Lcr6               
         slr   %r2,%r2
 .Lldlp:
-        lhi   %r6,3                            # 3 retries
+        la    %r6,3                            # 3 retries
 .Lssch:
         ssch  0(%r3)                           # load chunk of IPL_BS bytes
-        jnz   .Llderr
+        bnz   .Llderr
 .Lw4end:
-        bras  %r14,.Lwait4io
+        bas   %r14,.Lwait4io
         tm    8(%r5),0x82                      # do we have a problem ?
-        jnz   .Lrecov
+        bnz   .Lrecov
         slr   %r7,%r7
         icm   %r7,3,10(%r5)                    # get residual count
         lcr   %r7,%r7
-        ahi   %r7,IPL_BS                       # IPL_BS-residual=#bytes read
+        la    %r7,IPL_BS(%r7)                  # IPL_BS-residual=#bytes read
         ar    %r2,%r7                          # add to total size
         tm    8(%r5),0x01                      # found a tape mark ?
-        jnz   .Ldone
+        bnz   .Ldone
         l     %r0,.Lccwread+4                  # update CCW data addresses
         ar    %r0,%r7
         st    %r0,.Lccwread+4                
-        j     .Lldlp
+        b     .Lldlp
 .Ldone:
         l     %r14,.Lldret
         br    %r14                             # r2 contains the total size
 .Lrecov:
-        bras  %r14,.Lsense                     # do the sensing
-        brct  %r6,.Lssch                       # dec. retry count & branch
-        j     .Llderr
+        bas   %r14,.Lsense                     # do the sensing
+        bct   %r6,.Lssch                       # dec. retry count & branch
+        b     .Llderr
 #
 # Sense subroutine
 #
@@ -206,11 +95,11 @@
         st    %r14,.Lsnsret
         la    %r7,.Lorbsense              
         ssch  0(%r7)                           # start sense command
-        jnz   .Llderr
-        bras  %r14,.Lwait4io
+        bnz   .Llderr
+        bas   %r14,.Lwait4io
         l     %r14,.Lsnsret
         tm    8(%r5),0x82                      # do we have a problem ?
-        jnz   .Llderr
+        bnz   .Llderr
         br    %r14
 #
 # Wait for interrupt subroutine
@@ -219,13 +108,13 @@
         lpsw  .Lwaitpsw                 
 .Lioint:
         c     %r1,0xb8                         # compare subchannel number
-        jne   .Lwait4io
+        bne   .Lwait4io
         tsch  0(%r5)
         slr   %r0,%r0
         tm    8(%r5),0x82                      # do we have a problem ?
-        jnz   .Lwtexit
+        bnz   .Lwtexit
         tm    8(%r5),0x04                      # got device end ?
-        jz    .Lwait4io
+        bz    .Lwait4io
 .Lwtexit:
         br    %r14
 .Llderr:
@@ -249,18 +138,12 @@
 .Lcr6:  .long  0xff000000
         .align 8
 .Lcrash:.long  0x000a0000,0x00000000
-.Lpcmem0:.long  0x00080000,0x80000000 + .Lchkmem0
-.Lparm: .long  PARMAREA
-.L4malign0:.long 0xffc00000
-.Lbigmem:.long 0x04000000
-.Lrdstart:.long 0x02000000
 .Lldret:.long  0
 .Lsnsret: .long 0
-.Lcvtab:.long  _ebcasc                         # ebcdic to ascii table
-
-#endif  /* CONFIG_IPL_TAPE */
+#endif  /* CONFIG_IPL_NONE */
 
 #ifdef CONFIG_IPL_VM
+#define IPL_BS 0x730
         .org   0
         .long  0x00080000,0x80000000+iplstart  # The first 24 bytes are loaded
         .long  0x02000018,0x60000050           # by ipl to addresses 0-23.
@@ -287,103 +170,7 @@
         .long  0x02000690,0x60000050
         .long  0x020006e0,0x20000050
 
-
         .org   0xf0
-iplstart:
-	l     %r1,0xb8                         # load ipl subchannel number
-        lhi   %r2,0x730                        # load start address
-        bras  %r14,.Lloader                    # load rest of ipl image
-        st    %r1,__LC_IPLDEV                  # store ipl device number
-	l     %r12,.Lparm                      # pointer to parameter area
-
-#
-# find out memory size
-#
-        mvc   104(8,0),.Lpcmem0           # setup program check handler
-        slr   %r2,%r2
-        lhi   %r3,1
-        sll   %r3,20
-.Lloop0:
-        l     %r0,0(%r2)                 # test page
-        ar    %r2,%r3                    # add 1M
-        jnm   .Lloop0                    # r1 < 0x80000000 -> loop
-.Lchkmem0:
-        n     %r2,.L4malign0             # align to multiples of 4M
-        st    %r2,MEMORY_SIZE-PARMAREA(%r12)  # store memory size
-        c     %r2,.Lbigmem               # more than 64 MB of memory ?
-        jl    .Lmemok                    # if yes load ramdisk to 32 MB
-        mvc   INITRD_START-PARMAREA(4,%r12),.Lrdstart
-.Lmemok:
-
-#
-# load parameter file from reader
-#
-        l     %r2,INITRD_START-PARMAREA(%r12)  # use ramdisk location as temp
-        bras  %r14,.Lloader                    # load parameter file
-        ltr   %r2,%r2                          # got anything ?
-        jz    .Lnopf
-        chi   %r2,895
-        jnh   .Lnotrunc
-        lhi   %r2,895
-.Lnotrunc:
-        l     %r4,INITRD_START-PARMAREA(%r12)
-        la    %r5,0(%r4,%r2)
-        lr    %r3,%r2
-.Lidebc:
-        tm    0(%r5),0x80                      # high order bit set ?
-        jo    .Ldocv                           #  yes -> convert from EBCDIC
-        ahi   %r5,-1
-        brct  %r3,.Lidebc
-        j     .Lnocv
-.Ldocv:
-        l     %r3,.Lcvtab
-        tr    0(256,%r4),0(%r3)                # convert parameters to ascii
-        tr    256(256,%r4),0(%r3)
-        tr    512(256,%r4),0(%r3)
-        tr    768(122,%r4),0(%r3)
-.Lnocv: la    %r3,COMMAND_LINE-PARMAREA(%r12)  # load adr. of command line
-        mvc   0(256,%r3),0(%r4)
-        mvc   256(256,%r3),256(%r4)
-        mvc   512(256,%r3),512(%r4)
-        mvc   768(122,%r3),768(%r4)
-        slr   %r0,%r0
-        j     .Lcntlp
-.Ldelspc:
-        ic    %r0,0(%r2,%r3)
-        chi   %r0,0x20                         # is it a space ?
-        je    .Lcntlp
-        ahi   %r2,1
-        j     .Leolp
-.Lcntlp:
-        brct  %r2,.Ldelspc
-.Leolp:
-        slr   %r0,%r0
-        stc   %r0,0(%r2,%r3)                   # terminate buffer
-.Lnopf:
-
-#
-# load ramdisk from reader
-#	
-	l     %r2,INITRD_START-PARMAREA(%r12)  # load adr. of ramdisk
-        bras  %r14,.Lloader                    # load ramdisk
-	st    %r2,INITRD_SIZE-PARMAREA(%r12)   # store size of ramdisk
-        ltr   %r2,%r2
-        jnz   .Lrdcont
-        st    %r2,INITRD_START-PARMAREA(%r12)  # no ramdisk found, null it
-.Lrdcont:
-
-#
-# everything loaded, reset files in reader, then go for it
-#
-        stidp __LC_CPUID                       # store cpuid
-        lh    %r0,__LC_CPUID+4                 # get cpu version
-        chi   %r0,0x7490                       # running on P/390 ?
-        je   start                             #   no -> skip reset
-        la    %r2,.Lreset              
-        lhi   %r3,26
-        .long 0x83230008
-	j     start
-
 #
 # subroutine for loading cards from the reader
 #
@@ -394,29 +181,29 @@
         la    %r7,20
 .Linit:
         st    %r2,4(%r6)                       # initialize CCW data addresses
-        ahi   %r2,0x50
-        ahi   %r6,8
-        brct  7,.Linit
+        la    %r2,0x50(%r2)
+        la    %r6,8(%r6)
+        bct   7,.Linit
 
         lctl  %c6,%c6,.Lcr6                    # set IO subclass mask
 	slr   %r2,%r2
 .Lldlp:
         ssch  0(%r3)                           # load chunk of 1600 bytes
-        jnz   .Llderr
+        bnz   .Llderr
 .Lwait4irq:
         mvc   __LC_IO_NEW_PSW(8),.Lnewpsw      # set up IO interrupt psw
         lpsw  .Lwaitpsw              
 .Lioint:
         c     %r1,0xb8                         # compare subchannel number
-	jne   .Lwait4irq
+	bne   .Lwait4irq
 	tsch  0(%r5)
 
 	slr   %r0,%r0
 	ic    %r0,8(%r5)                       # get device status
 	chi   %r0,8                            # channel end ?
-	je    .Lcont
+	be    .Lcont
 	chi   %r0,12                           # channel end + device end ?
-	je    .Lcont
+	be    .Lcont
 
         l     %r0,4(%r5)
         s     %r0,8(%r3)                       # r0/8 = number of ccws executed
@@ -436,9 +223,9 @@
         ahi   %r0,0x640
         st    %r0,4(%r6)
         ahi   %r6,8
-        brct  7,.Lincr
+        bct   7,.Lincr
 
-        j     .Lldlp
+        b     .Lldlp
 .Llderr:
         lpsw  .Lcrash              
 
@@ -447,16 +234,7 @@
 .Lirb:	.long  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
 .Lcr6:  .long  0xff000000
 .Lloadp:.long  0,0
-.Lparm:	.long  PARMAREA
-.L4malign0:.long 0xffc00000
-.Lbigmem:.long 0x04000000
-.Lrdstart:.long 0x02000000
-.Lcvtab:.long  _ebcasc                         # ebcdic to ascii table
-.Lreset:.byte  0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
-        .byte  0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
-        .byte  0xc8,0xd6,0xd3,0xc4             # "change rdr all keep nohold"
         .align 8
-.Lpcmem0:.long  0x00080000,0x80000000 + .Lchkmem0
 .Lcrash:.long  0x000a0000,0x00000000
 .Lnewpsw:
         .long  0x00080000,0x80000000+.Lioint
@@ -468,28 +246,203 @@
         .long  0x02600050,0x00000000
         .endr
         .long  0x02200050,0x00000000
-	
-        .org   0x730     # end of the area loaded by the ipl channel program
 #endif  /* CONFIG_IPL_VM */
 
+iplstart:
+        lh    %r1,0xb8                         # test if subchannel number
+        bct   %r1,.Lnoload                     #  is valid
+	l     %r1,0xb8                         # load ipl subchannel number
+        la    %r2,IPL_BS                       # load start address
+        bas   %r14,.Lloader                    # load rest of ipl image
+        st    %r1,__LC_IPLDEV                  # store ipl device number
+        l     %r12,.Lparm                      # pointer to parameter area
+
+#
+# load parameter file from ipl device
+#
+ 	l     %r2,INITRD_START-PARMAREA(%r12)  # use ramdisk location as temp
+        bas   %r14,.Lloader                    # load parameter file
+        ltr   %r2,%r2                          # got anything ?
+        bz    .Lnopf
+	chi   %r2,895
+	bnh   .Lnotrunc
+	la    %r2,895
+.Lnotrunc:
+	l     %r4,INITRD_START-PARMAREA(%r12)
+        la    %r5,0(%r4,%r2)
+        lr    %r3,%r2
+.Lidebc:
+        tm    0(%r5),0x80                      # high order bit set ?
+        bo    .Ldocv                           #  yes -> convert from EBCDIC
+        ahi   %r5,-1
+        bct   %r3,.Lidebc
+        b     .Lnocv
+.Ldocv:
+        l     %r3,.Lcvtab
+        tr    0(256,%r4),0(%r3)                # convert parameters to ascii
+        tr    256(256,%r4),0(%r3)
+        tr    512(256,%r4),0(%r3)
+        tr    768(122,%r4),0(%r3)
+.Lnocv: la    %r3,COMMAND_LINE-PARMAREA(%r12)  # load adr. of command line
+	mvc   0(256,%r3),0(%r4)
+	mvc   256(256,%r3),256(%r4)
+	mvc   512(256,%r3),512(%r4)
+	mvc   768(122,%r3),768(%r4)
+        slr   %r0,%r0
+        b     .Lcntlp
+.Ldelspc:
+        ic    %r0,0(%r2,%r3)
+        chi   %r0,0x20                         # is it a space ?
+        be    .Lcntlp
+        ahi   %r2,1
+        b     .Leolp
+.Lcntlp:
+        brct  %r2,.Ldelspc
+.Leolp:
+        slr   %r0,%r0
+        stc   %r0,0(%r2,%r3)                   # terminate buffer
+.Lnopf:
+
+#
+# load ramdisk from ipl device
+#	
+ 	l     %r2,INITRD_START-PARMAREA(%r12)  # load adr. of ramdisk
+        bas   %r14,.Lloader                    # load ramdisk
+ 	st    %r2,INITRD_SIZE-PARMAREA(%r12)   # store size of ramdisk
+        ltr   %r2,%r2
+        bnz   .Lrdcont
+        st    %r2,INITRD_START-PARMAREA(%r12)  # no ramdisk found, null it
+.Lrdcont:
+
+#ifdef CONFIG_IPL_VM
+#
+# reset files in VM reader
+#
+        stidp __LC_CPUID                       # store cpuid
+        lh    %r0,__LC_CPUID+4                 # get cpu version
+        chi   %r0,0x7490                       # running on P/390 ?
+        be    start                            #   no -> skip reset
+        la    %r2,.Lreset              
+        lhi   %r3,26
+        .long 0x83230008
+#endif
+	
+#
+# everything loaded, go for it
+#
+.Lnoload:
+        l     %r1,.Lstartup
+        br    %r1
+
+.Lparm:	.long  PARMAREA
+.Lstartup: .long startup
+.Lcvtab:.long  _ebcasc                         # ebcdic to ascii table
+.Lreset:.byte  0xc3,0xc8,0xc1,0xd5,0xc7,0xc5,0x40,0xd9,0xc4,0xd9,0x40
+        .byte  0xc1,0xd3,0xd3,0x40,0xd2,0xc5,0xc5,0xd7,0x40,0xd5,0xd6
+        .byte  0xc8,0xd6,0xd3,0xc4             # "change rdr all keep nohold"
+
 #endif  /* CONFIG_IPL */
 
 #
+# SALIPL loader support. Based on a patch by Rob van der Heij.
+# This entry point is called directly from the SALIPL loader and
+# doesn't need a builtin ipl record.
+#
+        .org  0x800
+	.globl start
+start:
+	stm   %r0,%r15,0x07b0		# store registers
+	basr  %r12,%r0
+.base:
+	l     %r11,.parm
+	l     %r8,.cmd			# pointer to command buffer
+
+	ltr   %r9,%r9			# do we have SALIPL parameters?
+	bp    .sk8x8
+
+	mvc   0(64,%r8),0x00b0		# copy saved registers
+	xc    64(240-64,%r8),0(%r8)	# remainder of buffer
+	tr    0(64,%r8),.lowcase	
+	b     .gotr
+.sk8x8:
+	mvc   0(240,%r8),0(%r9)		# copy iplparms into buffer
+.gotr:
+	l     %r10,.tbl			# EBCDIC to ASCII table
+	tr    0(240,%r8),0(%r10)
+	stidp __LC_CPUID		# Are we running on VM maybe
+	cli   __LC_CPUID,0xff
+	bnz   .test
+	.long 0x83300060		# diag 3,0,x'0060' - storage size
+	b     .done
+.test:
+	mvc   0x68(8,0),.pgmnw		# set up pgm check handler
+	l     %r2,.fourmeg
+	lr    %r3,%r2
+	bctr  %r3,%r0			# 4M-1
+.loop:  iske  %r0,%r3
+	ar    %r3,%r2
+.pgmx:
+	sr    %r3,%r2
+	la    %r3,1(%r3)
+.done:
+	st    %r3,MEMORY_SIZE-PARMAREA(%r11)	
+	slr   %r0,%r0
+	st    %r0,INITRD_SIZE-PARMAREA(%r11)
+	st    %r0,INITRD_START-PARMAREA(%r11)
+	j     startup                   # continue with startup
+.tbl:	.long _ebcasc			# translate table
+.cmd:	.long COMMAND_LINE		# address of command line buffer
+.parm:	.long PARMAREA
+.fourmeg: .long 0x00400000      	# 4M
+.pgmnw:	.long 0x00080000,.pgmx
+.lowcase:
+	.byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 
+	.byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+	.byte 0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17 
+	.byte 0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f
+	.byte 0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27 
+	.byte 0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f
+	.byte 0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37 
+	.byte 0x38,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,0x3f
+	.byte 0x40,0x41,0x42,0x43,0x44,0x45,0x46,0x47 
+	.byte 0x48,0x49,0x4a,0x4b,0x4c,0x4d,0x4e,0x4f
+	.byte 0x50,0x51,0x52,0x53,0x54,0x55,0x56,0x57 
+	.byte 0x58,0x59,0x5a,0x5b,0x5c,0x5d,0x5e,0x5f
+	.byte 0x60,0x61,0x62,0x63,0x64,0x65,0x66,0x67 
+	.byte 0x68,0x69,0x6a,0x6b,0x6c,0x6d,0x6e,0x6f
+	.byte 0x70,0x71,0x72,0x73,0x74,0x75,0x76,0x77 
+	.byte 0x78,0x79,0x7a,0x7b,0x7c,0x7d,0x7e,0x7f
+
+	.byte 0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87 
+	.byte 0x88,0x89,0x8a,0x8b,0x8c,0x8d,0x8e,0x8f
+	.byte 0x90,0x91,0x92,0x93,0x94,0x95,0x96,0x97 
+	.byte 0x98,0x99,0x9a,0x9b,0x9c,0x9d,0x9e,0x9f
+	.byte 0xa0,0xa1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7 
+	.byte 0xa8,0xa9,0xaa,0xab,0xac,0xad,0xae,0xaf
+	.byte 0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7 
+	.byte 0xb8,0xb9,0xba,0xbb,0xbc,0xbd,0xbe,0xbf
+	.byte 0xc0,0x81,0x82,0x83,0x84,0x85,0x86,0x87	# .abcdefg 
+	.byte 0x88,0x89,0xca,0xcb,0xcc,0xcd,0xce,0xcf	# hi
+	.byte 0xd0,0x91,0x92,0x93,0x94,0x95,0x96,0x97 	# .jklmnop
+	.byte 0x98,0x99,0xda,0xdb,0xdc,0xdd,0xde,0xdf	# qr
+	.byte 0xe0,0xe1,0xa2,0xa3,0xa4,0xa5,0xa6,0xa7	# ..stuvwx
+	.byte 0xa8,0xa9,0xea,0xeb,0xec,0xed,0xee,0xef	# yz
+	.byte 0xf0,0xf1,0xf2,0xf3,0xf4,0xf5,0xf6,0xf7 
+	.byte 0xf8,0xf9,0xfa,0xfb,0xfc,0xfd,0xfe,0xff
+
+#
 # startup-code at 0x10000, running in real mode
-# this is called either by the ipl loader or directly by PSW restart or linload
+# this is called either by the ipl loader or directly by PSW restart
+# or linload or SALIPL
 #
         .org  0x10000
-        .globl start
-start:  basr  %r13,0                     # get base
+startup:basr  %r13,0                     # get base
 .LPG1:  lctl  %c0,%c15,.Lctl-.LPG1(%r13) # load all control registers
 	l     %r12,.Lparm1-.LPG1(%r13)   # pointer to parameter area
 
 #
-# find out memory size. That is done in the ipl loader too but for
-# ipl from dasd the size of the memory has to be detected too...
+# find out memory size.
 #
-        icm   %r0,15,MEMORY_SIZE-PARMAREA(%r12)
-        jnz   .Lsizeok
 	mvc   104(8,0),.Lpcmem-.LPG1(%r13) # setup program check handler
         slr   %r1,%r1
         lhi   %r2,1
@@ -497,23 +450,57 @@
 .Lloop:	
 	l     %r0,0(%r1)                 # test page
 	ar    %r1,%r2                    # add 1M
-	jnm   .Lloop                     # r1 < 0x80000000 -> loop
+	bnm   .Lloop-.LPG1(%r13)         # r1 < 0x80000000 -> loop
 .Lchkmem:
 	n     %r1,.L4malign-.LPG1(%r13)  # align to multiples of 4M
 	st    %r1,MEMORY_SIZE-PARMAREA(%r12)  # store memory size
 .Lsizeok:
 
 #
+# Now we have to move the ramdisk to a location approriate for the
+# memory size. If we have more than 64 MB of memory we move it to 32MB
+# to make room for the page tables set up by paging_init.
+#
+        l     %r1,MEMORY_SIZE-PARMAREA(%r12)
+        cl    %r1,.Lbigmem-.LPG1(%r13)   # memory < 64mb ?
+        bl    .Lnomove-.LPG1(%r13)       # if yes ramdisk @8MB is ok
+        icm   %r4,15,INITRD_START-PARMAREA(%r12)
+        bz    .Lnomove-.LPG1(%r13)
+	l     %r2,.Lrdstart-.LPG1(%r13)  # new address of ramdisk
+	st    %r2,INITRD_START-PARMAREA(%r12)
+        l     %r1,INITRD_SIZE-PARMAREA(%r12)
+	ar    %r2,%r1                    # we start moving at the end
+	ar    %r4,%r1                    #  because new location > old location
+.Lmove:	lr    %r0,%r2                    # new - old is the maximum we can move
+	sr    %r0,%r4                    #  because of overlapping
+	cr    %r0,%r1                    # we shouldn't move more than there is
+	bnh   .Lnoend-.LPG1(%r13)
+	lr    %r0,%r1
+.Lnoend:cl    %r0,.Lmaxchunk-.LPG1(%r13) # mvcl can move 2^24-1 in one go
+	bnh   .Lchunk-.LPG1(%r13)
+	l     %r0,.Lmaxchunk-.LPG1(%r13)
+.Lchunk:sr    %r2,%r0                    # make source & destination pointer
+	sr    %r4,%r0
+	lr    %r3,%r0                    # set source & destination length
+	lr    %r5,%r0
+	mvcl  %r2,%r4
+	sr    %r2,%r0                    # substract length again, since
+	sr    %r4,%r0                    #  mvcl added it to the pointers
+	sr    %r1,%r0                    # substract chunk size from length
+	bnz   .Lmove-.LPG1(%r13)
+.Lnomove:
+
+#
 # find out if we are running under VM
 #
         stidp  __LC_CPUID               # store cpuid
 	tm     __LC_CPUID,0xff          # running under VM ?
-	jno    .Lnovm
+	bno    .Lnovm-.LPG1(%r13)
         oi     MACHINE_FLAGS+3-PARMAREA(%r12),1    # set VM flag
 .Lnovm:
         lh     %r0,__LC_CPUID+4         # get cpu version
         chi    %r0,0x7490               # running on a P/390 ?
-        jne    .Lnop390
+        bne    .Lnop390-.LPG1(%r13)
         oi     MACHINE_FLAGS+3-PARMAREA(%r12),4    # set P/390 flag
 .Lnop390:
 
@@ -526,6 +513,7 @@
         adbr   %f0,%f2                  # test IEEE add instruction
         oi     MACHINE_FLAGS+3-PARMAREA(%r12),2    # set IEEE fpu flag
 .Lchkfpu:
+
 #
 # find out if we have the CSP instruction
 #
@@ -563,6 +551,9 @@
 .Lflt0: .double 0
 .Lparm1:.long  PARMAREA
 .L4malign:.long 0xffc00000
+.Lbigmem:.long 0x04000000
+.Lrdstart:.long 0x02000000
+.Lmaxchunk:.long  0x00ffffff
 
 #
 # params at 10400 (setup.h)
@@ -573,21 +564,12 @@
 	.long  0                        # MEMORY_SIZE
 	.long  0                        # MACHINE_FLAGS (bit 0:VM, bit 1:IEEE)
         .long  RAMDISK_ORIGIN           # INITRD_START
-        .long  0x800000                 # INITRD_SIZE
+        .long  RAMDISK_SIZE             # INITRD_SIZE
 	.word  0                        # RAMDISK_FLAGS
 
         .org   COMMAND_LINE
-#       .byte  "root=/dev/nfs rw nfsroot=9.164.160.7:/home/mschwide/nfsboot "
-#       .byte  "ip=9.164.147.12:9.164.160.7:9.164.147.1:255.255.255.0:vmlinux:tr0:off"
-#       .byte  "root=/dev/nfs nfsroot=9.164.160.7:/home/mschwide/nfsboot "
-#       .byte  "ip=9.164.181.228:9.164.160.7:9.164.181.1:255.255.224.0:vmlinux:tr0:off"
-#       .byte  "root=/dev/nfs nfsroot=9.164.160.7:/home/pasch/nfsboot "
-#       .byte  "ip=9.164.185.120:9.164.160.7:9.164.181.1:255.255.224.0:vmlinux:tr0:off"
-#       .byte  "mdisk=402:65536:1229,403:131072:2780 root=/dev/mnda ro"
-#       .byte  "root=/dev/nfs rw nfsroot=9.164.160.209:/usr/local/nfsboot "
-#       .byte  "ip=9.164.181.228:9.164.160.209:9.164.181.1:255.255.224.0:vmlinux:tr0:off"
     	.byte  "root=/dev/ram0 ro"
-#       .byte  0
+        .byte  0
 
 #
 # startup-code, running in virtual mode
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/irq.c linux.17p18/arch/s390/kernel/irq.c
--- linux.vanilla/arch/s390/kernel/irq.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/irq.c	Tue Aug  1 07:59:05 2000
@@ -86,7 +86,7 @@
 			continue;
 
 		p += sprintf(p, "%3d: ",i);
-#ifndef __SMP__
+#ifndef CONFIG_SMP
 		p += sprintf(p, "%10u ", kstat_irqs(i));
 #else
 		for (j=0; j<smp_num_cpus; j++)
@@ -107,7 +107,7 @@
 	} /* endfor */
 
 	p += sprintf(p, "NMI: %10u\n", atomic_read(&nmi_counter));
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 	p += sprintf(p, "IPI: %10u\n", atomic_read(&ipi_count));
 #endif
 
@@ -119,7 +119,7 @@
  * Global interrupt locks for SMP. Allow interrupts to come in on any
  * CPU, yet make cli/sti act globally to protect critical regions..
  */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 atomic_t global_irq_holder = ATOMIC_INIT(NO_PROC_ID);
 atomic_t global_irq_lock;
 atomic_t global_irq_count = ATOMIC_INIT(0);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/mathemu.c linux.17p18/arch/s390/kernel/mathemu.c
--- linux.vanilla/arch/s390/kernel/mathemu.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/s390/kernel/mathemu.c	Tue Aug  1 07:59:05 2000
@@ -17,6 +17,18 @@
 #include <asm/uaccess.h>
 #include <asm/mathemu.h>
 
+static void display_emulation_not_implemented(char *instr)
+{
+	struct pt_regs *regs=current->tss.regs;
+	printk("%s not implemented\n",instr);
+	printk("Process with %s instruction %s (pid: %d, stackpage=%08X)\n",
+	       instr,
+                current->comm, current->pid, 4096+(addr_t)current);
+	printk("%s's PSW:    %08lx %08lx\n",instr,
+                (unsigned long) regs->psw.mask,
+                (unsigned long) regs->psw.addr);
+}
+
 static void set_CC_df(__u64 val1,__u64 val2) {
         int rc;
         rc = __cmpdf2(val1,val2);
@@ -69,7 +81,7 @@
 }
 
 static void emu_axbr (int rx, int ry) {
-        printk("axbr emulation not implemented!\n");
+        display_emulation_not_implemented("axbr");
 }
 
 static void emu_cdb (int rx, __u64 val) {
@@ -109,15 +121,15 @@
 }
 
 static void emu_cfxbr (int rx, int ry, int mask) {
-        printk("cfxbr emulation not implemented!\n");
+        display_emulation_not_implemented("cfxbr");
 }
 
 static void emu_cxbr (int rx, int ry) {
-        printk("cxbr emulation not implemented!\n");
+        display_emulation_not_implemented("cxbr");
 }
 
 static void emu_cxfbr (int rx, int ry) {
-        printk("cxfbr emulation not implemented!\n");
+        display_emulation_not_implemented("cxfbr");
 }
 
 static void emu_ddb (int rx, __u64 val) {
@@ -143,51 +155,51 @@
 }
 
 static void emu_didbr (int rx, int ry, int mask) {
-        printk("didbr emulation not implemented!\n");
+        display_emulation_not_implemented("didbr");
 }
 
 static void emu_diebr (int rx, int ry, int mask) {
-        printk("diebr emulation not implemented!\n");
+        display_emulation_not_implemented("diebr");
 }
 
 static void emu_dxbr (int rx, int ry) {
-        printk("dxbr emulation not implemented!\n");
+        display_emulation_not_implemented("dxbr");
 }
 
 static void emu_efpc (int rx, int ry) {
-        printk("efpc emulation not implemented!\n");
+        display_emulation_not_implemented("efpc");
 }
 
 static void emu_fidbr (int rx, int ry, int mask) {
-        printk("fidbr emulation not implemented!\n");
+        display_emulation_not_implemented("fidbr");
 }
 
 static void emu_fiebr (int rx, int ry, int mask) {
-        printk("fiebr emulation not implemented!\n");
+        display_emulation_not_implemented("fiebr");
 }
 
 static void emu_fixbr (int rx, int ry, int mask) {
-        printk("fixbr emulation not implemented!\n");
+        display_emulation_not_implemented("fixbr");
 }
 
 static void emu_kdb (int rx, __u64 val) {
-        printk("kdb emulation not implemented!\n");
+        display_emulation_not_implemented("kdb");
 }
 
 static void emu_kdbr (int rx, int ry) {
-        printk("kdbr emulation not implemented!\n");
+        display_emulation_not_implemented("kdbr");
 }
 
 static void emu_keb (int rx, __u32 val) {
-        printk("keb emulation not implemented!\n");
+        display_emulation_not_implemented("keb");
 }
 
 static void emu_kebr (int rx, int ry) {
-        printk("kebr emulation not implemented!\n");
+        display_emulation_not_implemented("kebr");
 }
 
 static void emu_kxbr (int rx, int ry) {
-        printk("kxbr emulation not implemented!\n");
+        display_emulation_not_implemented("kxbr");
 }
 
 static void emu_lcdbr (int rx, int ry) {
@@ -203,7 +215,7 @@
 }
 
 static void emu_lcxbr (int rx, int ry) {
-        printk("lcxbr emulation not implemented!\n");
+        display_emulation_not_implemented("lcxbr");
 }
 
 static void emu_ldeb (int rx, __u32 val) {
@@ -216,7 +228,7 @@
 }
 
 static void emu_ldxbr (int rx, int ry) {
-        printk("ldxbr emulation not implemented!\n");
+        display_emulation_not_implemented("ldxbr");
 }
 
 static void emu_ledbr (int rx, int ry) {
@@ -225,19 +237,19 @@
 }
 
 static void emu_lexbr (int rx, int ry) {
-        printk("lexbr emulation not implemented!\n");
+        display_emulation_not_implemented("lexbr");
 }
 
 static void emu_lndbr (int rx, int ry) {
-        printk("lndbr emulation not implemented!\n");
+        display_emulation_not_implemented("lndbr");
 }
 
 static void emu_lnebr (int rx, int ry) {
-        printk("lnebr emulation not implemented!\n");
+        display_emulation_not_implemented("lnebr");
 }
 
 static void emu_lnxbr (int rx, int ry) {
-        printk("lnxbr emulation not implemented!\n");
+        display_emulation_not_implemented("lnxbr");
 }
 
 static void emu_lpdbr (int rx, int ry) {
@@ -251,7 +263,7 @@
 }
 
 static void emu_lpxbr (int rx, int ry) {
-        printk("lpxbr emulation not implemented!\n");
+        display_emulation_not_implemented("lpxbr");
 }
 
 static void emu_ltdbr (int rx, int ry) {
@@ -265,39 +277,39 @@
 }
 
 static void emu_ltxbr (int rx, int ry) {
-        printk("ltxbr emulation not implemented!\n");
+        display_emulation_not_implemented("ltxbr");
 }
 
 static void emu_lxdb (int rx, __u64 val) {
-        printk("lxdb emulation not implemented!\n");
+        display_emulation_not_implemented("lxdb");
 }
 
 static void emu_lxdbr (int rx, int ry) {
-        printk("lxdbr emulation not implemented!\n");
+        display_emulation_not_implemented("lxdbr");
 }
 
 static void emu_lxeb (int rx, __u32 val) {
-        printk("lxeb emulation not implemented!\n");
+        display_emulation_not_implemented("lxeb");
 }
 
 static void emu_lxebr (int rx, int ry) {
-        printk("lxebr emulation not implemented!\n");
+        display_emulation_not_implemented("lxebr");
 }
 
 static void emu_madb (int rx, __u64 val, int mask) {
-        printk("madb emulation not implemented!\n");
+        display_emulation_not_implemented("madb");
 }
 
 static void emu_madbr (int rx, int ry, int mask) {
-        printk(" emulation not implemented!\n");
+        display_emulation_not_implemented("madbr");
 }
 
 static void emu_maeb (int rx, __u32 val, int mask) {
-        printk("maeb emulation not implemented!\n");
+        display_emulation_not_implemented("maeb");
 }
 
 static void emu_maebr (int rx, int ry, int mask) {
-        printk("maebr emulation not implemented!\n");
+        display_emulation_not_implemented("maebr");
 }
 
 static void emu_mdb (int rx, __u64 val) {
@@ -312,11 +324,11 @@
 }
 
 static void emu_mdeb (int rx, __u32 val) {
-        printk("mdeb emulation not implemented!\n");
+        display_emulation_not_implemented("mdeb");
 }
 
 static void emu_mdebr (int rx, int ry) {
-        printk("mdebr emulation not implemented!\n");
+        display_emulation_not_implemented("mdebr");
 }
 
 static void emu_meeb (int rx, __u32 val) {
@@ -332,31 +344,31 @@
 }
 
 static void emu_msdb (int rx, __u64 val, int mask) {
-        printk("msdb emulation not implemented!\n");
+        display_emulation_not_implemented("msdb");
 }
 
 static void emu_msdbr (int rx, int ry, int mask) {
-        printk("msdbr emulation not implemented!\n");
+        display_emulation_not_implemented("msdbr");
 }
 
 static void emu_mseb (int rx, __u32 val, int mask) {
-        printk("mseb emulation not implemented!\n");
+        display_emulation_not_implemented("mseb");
 }
 
 static void emu_msebr (int rx, int ry, int mask) {
-        printk("msebr emulation not implemented!\n");
+        display_emulation_not_implemented("msebr");
 }
 
 static void emu_mxbr (int rx, int ry) {
-        printk("mxbr emulation not implemented!\n");
+        display_emulation_not_implemented("mxbr");
 }
 
 static void emu_mxdb (int rx, __u64 val) {
-        printk("mxdb emulation not implemented!\n");
+        display_emulation_not_implemented("mxdb");
 }
 
 static void emu_mxdbr (int rx, int ry) {
-        printk("mxdbr emulation not implemented!\n");
+        display_emulation_not_implemented("mxdbr");
 }
 
 static void emu_sdb (int rx, __u64 val) {
@@ -384,43 +396,43 @@
 }
 
 static void emu_sfpc (int rx, int ry) {
-        printk("sfpc emulation not implemented!\n");
+        display_emulation_not_implemented("sfpc");
 }
 
 static void emu_sqdb (int rx, __u64 val) {
-        printk("sqdb emulation not implemented!\n");
+        display_emulation_not_implemented("sqdb");
 }
 
 static void emu_sqdbr (int rx, int ry) {
-        printk("sqdbr emulation not implemented!\n");
+        display_emulation_not_implemented("sqdbr");
 }
 
 static void emu_sqeb (int rx, __u32 val) {
-        printk("sqeb emulation not implemented!\n");
+        display_emulation_not_implemented("sqeb");
 }
 
 static void emu_sqebr (int rx, int ry) {
-        printk("sqebr emulation not implemented!\n");
+        display_emulation_not_implemented("sqebr");
 }
 
 static void emu_sqxbr (int rx, int ry) {
-        printk("sqxbr emulation not implemented!\n");
+        display_emulation_not_implemented("sqxbr");
 }
 
 static void emu_sxbr (int rx, int ry) {
-        printk("sxbr emulation not implemented!\n");
+        display_emulation_not_implemented("sxbr");
 }
 
 static void emu_tcdb (int rx, __u64 val) {
-        printk("tcdb emulation not implemented!\n");
+        display_emulation_not_implemented("tcdb");
 }
 
 static void emu_tceb (int rx, __u32 val) {
-        printk("tceb emulation not implemented!\n");
+        display_emulation_not_implemented("tceb");
 }
 
 static void emu_tcxb (int rx, __u64 val) {
-        printk("tcxb emulation not implemented!\n");
+        display_emulation_not_implemented("tcxb");
 }
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/process.c linux.17p18/arch/s390/kernel/process.c
--- linux.vanilla/arch/s390/kernel/process.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/process.c	Tue Aug  1 07:59:05 2000
@@ -57,7 +57,7 @@
 
 static psw_t wait_psw;
 
-#ifndef __SMP__
+#ifndef CONFIG_SMP
 static
 #endif
 int cpu_idle(void *unused)
@@ -69,7 +69,12 @@
 	wait_psw.mask = _WAIT_PSW_MASK;
 	wait_psw.addr = (unsigned long) &&idle_wakeup | 0x80000000L;
 	while(1) {
+#ifdef CONFIG_SMP
+                if (atomic_read(&global_bh_lock) == 0 &&
+                    (bh_mask & bh_active)) {
+#else
                 if (bh_mask & bh_active) {
+#endif
                         do_bottom_half();
                         continue;
                 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/s390_ksyms.c linux.17p18/arch/s390/kernel/s390_ksyms.c
--- linux.vanilla/arch/s390/kernel/s390_ksyms.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/s390_ksyms.c	Tue Aug  1 07:59:05 2000
@@ -5,10 +5,17 @@
  */
 #include <linux/config.h>
 #include <linux/module.h>
+#include <asm/debug.h>
+#include <linux/genhd.h>
+#include <asm/ccwcache.h>
 #include <asm/irq.h>
 #include <asm/string.h>
 #include <asm/checksum.h>
 #include <asm/s390_ext.h>
+#include <asm/s390dyn.h>
+#include <asm/ebcdic.h>
+#include <asm/timex.h>
+#include <asm/delay.h>
 #if CONFIG_CHANDEV
 #include <asm/chandev.h>
 #endif
@@ -16,7 +23,6 @@
 #include <net/arp.h>
 #endif
 
-
 /*
  * I/O subsystem
  */
@@ -30,14 +36,29 @@
 EXPORT_SYMBOL(get_devno_by_irq);
 EXPORT_SYMBOL(get_irq_first);
 EXPORT_SYMBOL(get_irq_next);
+EXPORT_SYMBOL(read_conf_data);
+EXPORT_SYMBOL(read_dev_chars);
+EXPORT_SYMBOL(s390_request_irq_special);
+EXPORT_SYMBOL(s390_device_register);
+EXPORT_SYMBOL(s390_device_unregister);
+
+EXPORT_SYMBOL(ccw_alloc_request);
+EXPORT_SYMBOL(ccw_free_request);
 
-/*
- * External interrupts
- */
 EXPORT_SYMBOL(register_external_interrupt);
 EXPORT_SYMBOL(unregister_external_interrupt);
 
 /*
+ * debug feature
+ */
+EXPORT_SYMBOL(debug_register);
+EXPORT_SYMBOL(debug_unregister); 
+EXPORT_SYMBOL(debug_event);
+EXPORT_SYMBOL(debug_text_event);
+EXPORT_SYMBOL(debug_exception);
+EXPORT_SYMBOL(debug_text_exception);
+
+/*
  * memory management
  */
 EXPORT_SYMBOL(init_mm);
@@ -61,10 +82,18 @@
 EXPORT_SYMBOL_NOVERS(strtok);
 EXPORT_SYMBOL_NOVERS(strpbrk);
 
+EXPORT_SYMBOL_NOVERS(_ascebc_500);
+EXPORT_SYMBOL_NOVERS(_ebcasc_500);
+EXPORT_SYMBOL_NOVERS(_ascebc);
+EXPORT_SYMBOL_NOVERS(_ebcasc);
+EXPORT_SYMBOL_NOVERS(_ebc_tolower);
+EXPORT_SYMBOL_NOVERS(_ebc_toupper);
+
 /*
  * misc.
  */
-#ifdef __SMP__
+EXPORT_SYMBOL(__udelay);
+#ifdef CONFIG_SMP
 #include <asm/smplock.h>
 EXPORT_SYMBOL(__global_cli);
 EXPORT_SYMBOL(__global_sti);
@@ -73,17 +102,14 @@
 EXPORT_SYMBOL(global_bh_lock);
 EXPORT_SYMBOL(synchronize_bh);
 EXPORT_SYMBOL(kernel_flag);
+EXPORT_SYMBOL(smp_ctl_set_bit);
+EXPORT_SYMBOL(smp_ctl_clear_bit);
 #endif
 EXPORT_SYMBOL(kernel_thread);
 EXPORT_SYMBOL(csum_fold);
-#if CONFIG_CHANDEV
-EXPORT_SYMBOL(chandev_register_and_probe);
-EXPORT_SYMBOL(chandev_unregister);
-EXPORT_SYMBOL(chandev_initdevice);
-EXPORT_SYMBOL(chandev_initnetdevice);
-#endif
+EXPORT_SYMBOL(genhd_dasd_name);
+
 #if CONFIG_IP_MULTICAST
 /* Required for lcs gigibit ethernet multicast support */
 EXPORT_SYMBOL(arp_mc_map);
 #endif
-
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/s390io.c linux.17p18/arch/s390/kernel/s390io.c
--- linux.vanilla/arch/s390/kernel/s390io.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/s390io.c	Tue Aug  1 07:59:05 2000
@@ -49,7 +49,6 @@
 static spinlock_t sync_isc = SPIN_LOCK_UNLOCKED;
                                           // synchronous irq processing lock
 static psw_t      io_sync_wait;           // wait PSW for sync IO, prot. by sync_isc
-static psw_t      io_new_psw;             // save I/O new PSW, prot. by sync_isc
 static int        cons_dev          = -1; // identify console device
 static int        init_IRQ_complete = 0;
 static schib_t    init_schib;
@@ -340,7 +339,8 @@
 		{
 			s390irq_spin_unlock_irqrestore( irq, flags);
 
-			printk("free_irq() : error, dev_id does not match !");
+			printk( "free_irq(%04X) : error, "
+			        "dev_id does not match !", irq);
 
 		} /* endif */
 
@@ -349,7 +349,8 @@
 	{
 		s390irq_spin_unlock_irqrestore( irq, flags);
 
-		printk("free_irq() : error, no action block ... !");
+		printk( "free_irq(%04X) : error, "
+		        "no action block ... !\n", irq);
 
 	} /* endif */
 
@@ -906,7 +907,6 @@
 		if ( flag & DOIO_WAIT_FOR_INTERRUPT )
 		{
 			int              io_sub = -1;
-			__u32            io_parm;
          psw_t            io_new_psw;
          int              ccode;
 			uint64_t         time_start;    	
@@ -2504,15 +2504,7 @@
 				ioinfo[irq]->devstat.flag             |= DEVSTAT_FINAL_STATUS;
 				((devstat_t *)(action->dev_id))->flag |= DEVSTAT_FINAL_STATUS;
 
-				if ( ioinfo[irq]->ui.flags.newreq )
-				{
-					action->handler( irq, ioinfo[irq]->u_intparm );
-				}
-				else
-				{
-					((io_handler_func1_t)action->handler)( irq, action->dev_id, &regs );
-
-				} /* endif */
+				action->handler( irq, action->dev_id, &regs );
 
 				//
 				// reset intparm after final status or we will badly present unsolicited
@@ -2544,15 +2536,7 @@
 					 */
 					if ( ret )
 					{
-						if ( ioinfo[irq]->ui.flags.newreq )
-						{
-							action->handler( irq, ioinfo[irq]->u_intparm );
-						}
-						else
-						{
-							((io_handler_func1_t)action->handler)( irq, action->dev_id, &regs );
-
-						} /* endif */
+						action->handler( irq, action->dev_id, &regs );
 
 					} /* endif */
 
@@ -2573,23 +2557,14 @@
 					((devstat_t *)(action->dev_id))->flag |= DEVSTAT_PCI;
 					ioinfo[irq]->devstat.cstat &= ~SCHN_STAT_PCI;
 				}
-				else if ( actl & SCSW_ACTL_SUSPENDED )
+
+				if ( actl & SCSW_ACTL_SUSPENDED )
 				{
 					((devstat_t *)(action->dev_id))->flag |= DEVSTAT_SUSPENDED;
 
 				} /* endif */
 
-				if ( ioinfo[irq]->ui.flags.newreq )
-				{
-					action->handler( irq, ioinfo[irq]->u_intparm );
-				}
-				else
-				{
-					((io_handler_func1_t)action->handler)( irq,
-					                                       action->dev_id,
-					                                       &regs );
-
-				} /* endif */
+				action->handler( irq, action->dev_id, &regs );
 
 			} /* endif */
 
@@ -2672,15 +2647,7 @@
 
 		if ( !ioinfo[irq]->ui.flags.s_pend )
 		{
-			if ( ioinfo[irq]->ui.flags.newreq )
-			{
-				action->handler( irq, ioinfo[irq]->u_intparm );
-			}
-			else
-			{
-				((io_handler_func1_t)action->handler)( irq, action->dev_id, &regs );
-
-			} /* endif */
+			action->handler( irq, action->dev_id, &regs );
 
 		} /* endif */
 
@@ -3794,17 +3761,27 @@
 		pdi->devno = ioinfo[irq]->schib.pmcw.dev;
 		pdi->irq   = irq;
 
-		if ( ioinfo[irq]->ui.flags.oper )
+		if (     ioinfo[irq]->ui.flags.oper
+           && !ioinfo[irq]->ui.flags.unknown )
 		{
 			pdi->status = 0;
 			memcpy( &(pdi->sid_data),
 			        &ioinfo[irq]->senseid,
 			        sizeof( senseid_t));
 		}
+		else if ( ioinfo[irq]->ui.flags.unknown )
+		{
+			pdi->status = DEVSTAT_UNKNOWN_DEV;
+			memset( &(pdi->sid_data),
+			        '\0',
+			        sizeof( senseid_t));
+			pdi->sid_data.cu_type = 0xFFFF;
+
+		}
 		else
 		{
 			pdi->status = DEVSTAT_NOT_OPER;
-			memcpy( &(pdi->sid_data),
+			memset( &(pdi->sid_data),
 			        '\0',
 			        sizeof( senseid_t));
 			pdi->sid_data.cu_type = 0xFFFF;
@@ -3814,10 +3791,9 @@
 		if ( ioinfo[irq]->ui.flags.ready )
 			pdi->status |= DEVSTAT_DEVICE_OWNED;
 
-		return 0;
-
 	} /* endif */
 
+	return 0;
 }
 
 
@@ -3843,23 +3819,37 @@
 			if (    ioinfo[i] != INVALID_STORAGE_AREA
 			     && ioinfo[i]->schib.pmcw.dev == devno )
 			{
-				if ( ioinfo[i]->ui.flags.oper )
-				{
-					pdi->status = 0;
+
 					pdi->irq    = i;
 					pdi->devno  = devno;
 
+				if (    ioinfo[i]->ui.flags.oper
+                 && !ioinfo[i]->ui.flags.unknown )
+				{
+					pdi->status = 0;
+
 					memcpy( &(pdi->sid_data),
 					        &ioinfo[i]->senseid,
 					        sizeof( senseid_t));
 				}
+				else if ( ioinfo[i]->ui.flags.unknown )
+				{
+					pdi->status = DEVSTAT_UNKNOWN_DEV;
+
+					memset( &(pdi->sid_data),
+                       '\0',
+                       sizeof( senseid_t));
+
+					pdi->sid_data.cu_type = 0xFFFF;
+				}
 				else
 				{
 					pdi->status = DEVSTAT_NOT_OPER;
-					pdi->irq    = i;
-					pdi->devno  = devno;
 
-					memcpy( &(pdi->sid_data), '\0', sizeof( senseid_t));
+					memset( &(pdi->sid_data),
+                       '\0',
+                       sizeof( senseid_t));
+
 					pdi->sid_data.cu_type = 0xFFFF;
 
 				} /* endif */
@@ -3975,6 +3965,7 @@
 			else
 			{
 				ioinfo[irq]->ui.flags.syncio = 1; // global
+				ioinfo[irq]->ui.flags.unknown = 0;
 
 				memset( &ioinfo[irq]->senseid, '\0', sizeof( senseid_t));
 
@@ -4735,14 +4726,14 @@
 			        ioinfo[irq]->schib.pmcw.dev,
 			        irq);
 #endif
-			ioinfo[irq]->ui.flags.oper = 0;
+			ioinfo[irq]->ui.flags.unknown = 1;
 
 		} /* endif */
 
 		/*
 		 * Issue device info message if unit was operational .
 		 */
-		if ( ioinfo[irq]->ui.flags.oper )
+		if ( ioinfo[irq]->ui.flags.unknown )
 	{
 			if ( sid->dev_type != 0 )
       {
@@ -4766,7 +4757,7 @@
 
 	} /* endif */
 
-		if ( ioinfo[irq]->ui.flags.oper )
+		if ( ioinfo[irq]->ui.flags.unknown )
 			irq_ret = 0;
 		else
 			irq_ret = -ENODEV;
@@ -5524,6 +5515,7 @@
 
 
 /* added by Holger Smolinski for reipl support in reipl.S */
+extern void do_reipl (int);
 void 
 reipl ( int sch )
 {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/s390mach.c linux.17p18/arch/s390/kernel/s390mach.c
--- linux.vanilla/arch/s390/kernel/s390mach.c	Sun Jun 11 21:44:09 2000
+++ linux.17p18/arch/s390/kernel/s390mach.c	Tue Aug  1 07:59:05 2000
@@ -119,9 +119,9 @@
 
 	down( &s_sem[0]);
 
-	smp_ctl_clear_bit( 14, 25 );  // disable damage MCH 	
+	ctl_clear_bit( 14, 25 );  // disable damage MCH 	
 #if 1
-  	smp_ctl_set_bit( 14, 28 );		// enable channel report MCH
+  	ctl_set_bit( 14, 28 );		// enable channel report MCH
 #endif
 
 #ifdef S390_MACHCHK_DEBUG
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/setup.c linux.17p18/arch/s390/kernel/setup.c
--- linux.vanilla/arch/s390/kernel/setup.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/kernel/setup.c	Tue Aug  1 07:59:05 2000
@@ -43,6 +43,7 @@
 __u16 boot_cpu_addr;
 int cpus_initialized = 0;
 unsigned long cpu_initialized = 0;
+volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 
 /*
  * Setup options
@@ -75,6 +76,7 @@
 void cpu_init (void)
 {
         int nr = smp_processor_id();
+        int addr = hard_smp_processor_id();
 
         if (test_and_set_bit(nr,&cpu_initialized)) {
                 printk("CPU#%d ALREADY INITIALIZED!!!!!!!!!\n", nr);
@@ -86,7 +88,7 @@
          * Store processor id in lowcore (used e.g. in timer_interrupt)
          */
         asm volatile ("stidp %0": "=m" (S390_lowcore.cpu_data.cpu_id));
-        S390_lowcore.cpu_data.cpu_addr = hard_smp_processor_id();
+        S390_lowcore.cpu_data.cpu_addr = addr;
         S390_lowcore.cpu_data.cpu_nr = nr;
 
         /*
@@ -132,7 +134,7 @@
  * Reboot, halt and power_off routines for non SMP.
  */
 
-#ifndef __SMP__
+#ifndef CONFIG_SMP
 void machine_restart(char * __unused)
 {
   reipl(S390_lowcore.ipl_device); 
@@ -142,14 +144,14 @@
 {
         if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) 
                 cpcmd(vmhalt_cmd, NULL, 0);
-                disabled_wait(0);
+        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
         }
 
 void machine_power_off(void)
 {
         if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
                 cpcmd(vmpoff_cmd, NULL, 0);
-                disabled_wait(0);
+        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
         }
 #endif
 
@@ -190,6 +192,7 @@
          */
         cpu_init();
         boot_cpu_addr = S390_lowcore.cpu_data.cpu_addr;
+        __cpu_logical_map[0] = boot_cpu_addr;
 
         /*
          * print what head.S has found out about the machine 
@@ -259,11 +262,14 @@
 				delay = delay*60*1000000;
 				from++;
 			}
-			tod_wait(delay);
+			/* now wait for the requested amount of time */
+			udelay(delay);
                 }
                 cn = *(from++);
                 if (!cn)
                         break;
+                if (cn == '\n')
+                        cn = ' ';  /* replace newlines with space */
                 if (cn == ' ' && c == ' ')
                         continue;  /* remove additional spaces */
                 c = cn;
@@ -271,6 +277,7 @@
                         break;
                 *(to++) = c;
         }
+        if (c == ' ' && to > command_line) to--;
         *to = '\0';
         *cmdline_p = command_line;
         memory_end += PAGE_OFFSET;
@@ -298,12 +305,12 @@
 void print_cpu_info(struct cpuinfo_S390 *cpuinfo)
 {
    printk("cpu %d "
-#ifdef __SMP__
+#ifdef CONFIG_SMP
            "phys_idx=%d "
 #endif
            "vers=%02X ident=%06X machine=%04X unused=%04X\n",
            cpuinfo->cpu_nr,
-#ifdef __SMP__
+#ifdef CONFIG_SMP
            cpuinfo->cpu_addr,
 #endif
            cpuinfo->cpu_id.version,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/signal.c linux.17p18/arch/s390/kernel/signal.c
--- linux.vanilla/arch/s390/kernel/signal.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/kernel/signal.c	Tue Aug  1 07:59:05 2000
@@ -231,15 +231,12 @@
 asmlinkage int sys_rt_sigreturn(struct pt_regs *regs)
 {
 	rt_sigframe *frame = (rt_sigframe *)regs->gprs[15];
-	stack_t st;
 
 	if (sigreturn_common(regs,sizeof(rt_sigframe)))
 			goto badframe;
-	if (__copy_from_user(&st, &frame->uc.uc_stack, sizeof(st)))
-		goto badframe;
 	/* It is more difficult to avoid calling this function than to
 	   call it and ignore errors.  */
-	do_sigaltstack(&st, NULL, regs->gprs[15]);
+	do_sigaltstack(&frame->uc.uc_stack, NULL, regs->gprs[15]);
 	return regs->gprs[2];
 
 badframe:
@@ -359,6 +356,7 @@
 	err |= __put_user(sas_ss_flags(orig_sp),
 			  &frame->uc.uc_stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &frame->uc.uc_stack.ss_size);
+	err |= __put_user(&frame->sc,&frame->uc.sc);
 	regs->gprs[3] = (addr_t)&frame->info;
 	regs->gprs[4] = (addr_t)&frame->uc;
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/smp.c linux.17p18/arch/s390/kernel/smp.c
--- linux.vanilla/arch/s390/kernel/smp.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/kernel/smp.c	Tue Aug  1 07:59:05 2000
@@ -43,6 +43,7 @@
 extern int cpu_idle(void * unused);
 
 extern __u16 boot_cpu_addr;
+extern volatile int __cpu_logical_map[];
 
 /*
  * An array with a pointer the lowcore of every CPU.
@@ -53,7 +54,6 @@
 unsigned int     prof_multiplier[NR_CPUS];
 unsigned int     prof_counter[NR_CPUS];
 volatile int     cpu_number_map[NR_CPUS];
-volatile int     __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
 cycles_t         cacheflush_time=0;
 int              smp_threads_ready=0;      /* Set when the idlers are all forked. */
 unsigned long    ipi_count=0;              /* Number of IPIs delivered. */
@@ -107,7 +107,7 @@
         smp_send_stop();
         if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) 
                 cpcmd(vmhalt_cmd, NULL, 0);
-                disabled_wait(0);
+        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
         }
 
 void machine_halt(void)
@@ -124,7 +124,7 @@
         smp_send_stop();
         if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
                 cpcmd(vmpoff_cmd, NULL, 0);
-                disabled_wait(0);
+        signal_processor(smp_processor_id(), sigp_stop_and_store_status);
         }
 
 void machine_power_off(void)
@@ -417,7 +417,7 @@
 
 void smp_send_stop(void)
 {
-        smp_signal_others(sigp_stop, 0, TRUE, NULL);
+        smp_signal_others(sigp_stop_and_store_status, 0, TRUE, NULL);
 }
 
 /*
@@ -472,7 +472,6 @@
 {
         int curr_cpu;
 
-        __cpu_logical_map[0] = boot_cpu_addr;
         current->processor = 0;
         smp_num_cpus = 1;
         for (curr_cpu = 0;
@@ -498,11 +497,16 @@
 
 int __init start_secondary(void *cpuvoid)
 {
+        /* Setup the cpu */
         cpu_init();
+        /* Print info about this processor */
         print_cpu_info(&safe_get_cpu_lowcore(smp_processor_id()).cpu_data);
+        /* Wait for completion of smp startup */
         while (!atomic_read(&smp_commenced))
                 /* nothing */ ;
+        /* init per CPU 100 hz timer */
         init_100hz_timer();
+        /* cpu_idle will call schedule for us */
         return cpu_idle(NULL);
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/kernel/time.c linux.17p18/arch/s390/kernel/time.c
--- linux.vanilla/arch/s390/kernel/time.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/kernel/time.c	Tue Aug  1 07:59:05 2000
@@ -145,7 +145,7 @@
  * as well as call the "do_timer()" routine every clocktick
  */
 
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 extern __u16 boot_cpu_addr;
 #endif
 
@@ -160,7 +160,7 @@
  
         save_flags(flags);
         cli();
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 	if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr) {
 		write_lock(&xtime_lock);
 		last_timer_cc = S390_lowcore.jiffy_timer_cc;
@@ -177,7 +177,7 @@
  * profiling, except when we simulate SMP mode on a uniprocessor
  * system, in that case we have to call the local interrupt handler.
  */
-#ifdef __SMP__
+#ifdef CONFIG_SMP
         /* when SMP, do smp_local_timer_interrupt for *all* CPUs,
            but only do the rest for the boot CPU */
         smp_local_timer_interrupt(regs);
@@ -186,12 +186,12 @@
                 s390_do_profile(regs->psw.addr);
 #endif
 
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 	if(S390_lowcore.cpu_data.cpu_addr==boot_cpu_addr)
 #endif
 	{
 		do_timer(regs);
-#ifdef __SMP__
+#ifdef CONFIG_SMP
 		write_unlock(&xtime_lock);
 #endif
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/lib/delay.c linux.17p18/arch/s390/lib/delay.c
--- linux.vanilla/arch/s390/lib/delay.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/s390/lib/delay.c	Tue Aug  1 07:59:05 2000
@@ -20,25 +20,30 @@
 
 void __delay(unsigned long loops)
 {
+        /*
+         * To end the bloody studid and useless discussion about the
+         * BogoMips number I took the liberty to define the __delay
+         * function in a way that that resulting BogoMips number will
+         * yield the megahertz number of the cpu. The important function
+         * is udelay and that is done using the tod clock. -- martin.
+         */
 	__asm__ __volatile__(
-                "0: ahi  %0,-1\n"
-                "   jnm  0b"
-                : /* no outputs */ : "r" (loops) );
+                "0: brct %0,0b"
+                : /* no outputs */ : "r" (loops/2) );
 }
 
-inline void __const_udelay(unsigned long xloops)
+/*
+ * Waits for 'usecs' microseconds using the tod clock
+ */
+void __udelay(unsigned long usecs)
 {
+        uint64_t start_cc, end_cc;
 
-	__asm__("LR    3,%1\n\t"
-		"MR    2,%2\n\t"
-		"LR    %0,2\n\t"
-		: "=r" (xloops)
-		: "r" (xloops) , "r"  (loops_per_sec)
-		: "2" , "3");
-        __delay(xloops);
+        if (usecs == 0)
+                return;
+        asm volatile ("STCK %0" : "=m" (start_cc));
+        do {
+                asm volatile ("STCK %0" : "=m" (end_cc));
+        } while (((end_cc - start_cc)/4096) < usecs);
 }
 
-void __udelay(unsigned long usecs)
-{
-	__const_udelay(usecs * 0x000010c6);  /* 2**32 / 1000000 */
-}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/mm/fault.c linux.17p18/arch/s390/mm/fault.c
--- linux.vanilla/arch/s390/mm/fault.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/mm/fault.c	Tue Aug  1 07:59:05 2000
@@ -74,24 +74,14 @@
         down(&mm->mmap_sem);
 
         vma = find_vma(mm, address);
-        if (!vma) {
-	        printk("no vma for address %lX\n",address);
+        if (!vma)
                 goto bad_area;
-        }
         if (vma->vm_start <= address) 
                 goto good_area;
-        if (!(vma->vm_flags & VM_GROWSDOWN)) {
-                printk("VM_GROWSDOWN not set, but address %lX \n",address);
-                printk("not in vma %p (start %lX end %lX)\n",vma,
-                       vma->vm_start,vma->vm_end);
+        if (!(vma->vm_flags & VM_GROWSDOWN))
                 goto bad_area;
-        }
-        if (expand_stack(vma, address)) {
-                printk("expand of vma failed address %lX\n",address);
-                printk("vma %p (start %lX end %lX)\n",vma,
-                       vma->vm_start,vma->vm_end);
+        if (expand_stack(vma, address))
                 goto bad_area;
-        }
 /*
  * Ok, we have a good vm_area for this memory access, so
  * we can handle it..
@@ -104,13 +94,8 @@
                         break;
                 case 0x10:                                   /* not present*/
                 case 0x11:                                   /* not present*/
-                        if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE))) {
-                                printk("flags %X of vma for address %lX wrong \n",
-                                       vma->vm_flags,address);
-                                printk("vma %p (start %lX end %lX)\n",vma,
-                                       vma->vm_start,vma->vm_end);
+                        if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
                                 goto bad_area;
-                        }
                         break;
                 default:
                        printk("code should be 4, 10 or 11 (%lX) \n",error_code&0xFF);  
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/tools/dasdfmt/Makefile linux.17p18/arch/s390/tools/dasdfmt/Makefile
--- linux.vanilla/arch/s390/tools/dasdfmt/Makefile	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/tools/dasdfmt/Makefile	Tue Aug  1 07:59:05 2000
@@ -1,8 +1,8 @@
 all: dasdfmt
 
 dasdfmt: dasdfmt.c
-	$(CROSS_COMPILE)gcc -o $@ $^
-	$(STRIP) $@
+	$(CROSS_COMPILE)gcc -I$(HPATH) -o $@ $^
+	$(CROSS_COMPILE)strip $@
 
 clean:
 	rm -f dasdfmt
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/tools/dasdfmt/dasdfmt.8 linux.17p18/arch/s390/tools/dasdfmt/dasdfmt.8
--- linux.vanilla/arch/s390/tools/dasdfmt/dasdfmt.8	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/s390/tools/dasdfmt/dasdfmt.8	Tue Aug  1 07:59:05 2000
@@ -3,8 +3,7 @@
 .SH NAME
 dasdfmt \- formatting of DSAD (ECKD) disk drives.
 .SH SYNOPSIS
-\fBdasdfmt\fR [-tvyV] [-b \fIblockSize\fR] [\fIblockRange\fI]
-	\fIdiskSpec\fR
+\fBdasdfmt\fR [-tvyLV] [-b \fIblockSize\fR] [-l \fIdiskLabel\fR] \fIdiskSpec\fR
 .SH DESCRIPTION
 \fBdasdfmt\fR formats a DASD (ECKD) disk drive to prepare it
 for usage with Linux for S/390. \fBWARNING\fR: Incautious usage of
@@ -25,6 +24,10 @@
 Start formatting without further user-confirmation.
 
 .TP
+\fB-L\fR 
+Omit the writing of a disk label after formatting.
+
+.TP
 \fB-V\fR 
 Print version number and exit.
 
@@ -35,26 +38,17 @@
 it is \fBstrongly\fR recommended to use a \fIblockSize\fR of \fI4096\fR.
 
 .TP
-\fIblockRange\fR
-This parameter specifies the number of the first and last block to be
-formatted. If this parameter is \fBomitted\fR, formatting the \fBwhole\fR disk
-is assumed. The \fIblockRange\fR can be specified in two different formats:
-.sp
-	\fB-s\fR \fIstartBlock\fR \fB-e\fR \fIendBlock\fR
-.br
-or
-.br
-	\fB-r\fR \fIstartBlock\fR-\fIendBlock\fR
-.sp
-If \fIstartBlock\fR is omitted, block \fB0\fR is assumed. If
-\fIendBlock\fR is omitted, the last block of the disk is assumed.
+\fB-l\fR \fIdiskLabel\fR
+Specify the label to be written to disk after formatting. If no label is
+specified, a sensible default is used. \fIdiskLabel\fR is interpreted as
+ASCII string and is automatically converted to EBCDIC.
 
 .TP
 \fIdiskSpec\fR
 This parameter specified the device to be formatted. It also can be
 given in two variants:
 .sp
-	\fB-f\fR \fB/dev/dd\fR\fIX\fR
+	\fB-f\fR \fB/dev/dasd\fR\fIX\fR
 .br
 or
 .br
@@ -63,7 +57,7 @@
 The first form uses the commonly used
 .SM UNIX
 device notation where \fIX\fR is a single lowercase letter.
-The second form uses simply the VM vdev number.
+The second form uses simply the device number.
 
 .SH BUGS
 None so far ;-)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/tools/dasdfmt/dasdfmt.c linux.17p18/arch/s390/tools/dasdfmt/dasdfmt.c
--- linux.vanilla/arch/s390/tools/dasdfmt/dasdfmt.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/tools/dasdfmt/dasdfmt.c	Tue Aug  1 07:59:05 2000
@@ -12,6 +12,8 @@
  *   detect non-switch parameters ("dasdfmt -n 170 XY") and complain about them 
  */
 
+/* #define _LINUX_BLKDEV_H */
+
 #include <unistd.h>
 #include <stdio.h>
 #include <sys/types.h>
@@ -31,7 +33,8 @@
 #undef __KERNEL__
 
 #include <linux/fs.h>
-#include <linux/dasd.h>
+#include <asm/dasd.h>
+#include <linux/hdreg.h>
 
 #define EXIT_MISUSE 1
 #define EXIT_BUSY 2
@@ -39,9 +42,11 @@
 #define TEMPFILENAMECHARS 8  /* 8 characters are fixed in all temp filenames */
 #define SLASHDEV "/dev/"
 #define PROC_DASD_DEVICES "/proc/dasd/devices"
-#define PROC_MOUNTS "/proc/mounts"  /* _PATH_MOUNTED is /etc/mtab - maybe bad */
+/* _PATH_MOUNTED is /etc/mtab - /proc/mounts does not show root-fs correctly */
+#define PROC_MOUNTS _PATH_MOUNTED
 #define PROC_SWAPS "/proc/swaps"
 #define DASD_DRIVER_NAME "dasd"
+#define LABEL_LENGTH 10
 #define PROC_LINE_LENGTH 80
 #define ERR_LENGTH 80
 
@@ -73,19 +78,105 @@
 char *prog_name;/*="dasdfmt";*/
 char tempfilename[]=TEMPFILENAME;
 
+__u8 _ascebc[256] =
+{
+ /*00 NUL   SOH   STX   ETX   EOT   ENQ   ACK   BEL */
+     0x00, 0x01, 0x02, 0x03, 0x37, 0x2D, 0x2E, 0x2F,
+ /*08  BS    HT    LF    VT    FF    CR    SO    SI */
+ /*              ->NL                               */
+     0x16, 0x05, 0x15, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ /*10 DLE   DC1   DC2   DC3   DC4   NAK   SYN   ETB */
+     0x10, 0x11, 0x12, 0x13, 0x3C, 0x3D, 0x32, 0x26,
+ /*18 CAN    EM   SUB   ESC    FS    GS    RS    US */
+ /*                               ->IGS ->IRS ->IUS */
+     0x18, 0x19, 0x3F, 0x27, 0x22, 0x1D, 0x1E, 0x1F,
+ /*20  SP     !     "     #     $     %     &     ' */
+     0x40, 0x5A, 0x7F, 0x7B, 0x5B, 0x6C, 0x50, 0x7D,
+ /*28   (     )     *     +     ,     -    .      / */
+     0x4D, 0x5D, 0x5C, 0x4E, 0x6B, 0x60, 0x4B, 0x61,
+ /*30   0     1     2     3     4     5     6     7 */
+     0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
+ /*38   8     9     :     ;     <     =     >     ? */
+     0xF8, 0xF9, 0x7A, 0x5E, 0x4C, 0x7E, 0x6E, 0x6F,
+ /*40   @     A     B     C     D     E     F     G */
+     0x7C, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7,
+ /*48   H     I     J     K     L     M     N     O */
+     0xC8, 0xC9, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6,
+ /*50   P     Q     R     S     T     U     V     W */
+     0xD7, 0xD8, 0xD9, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6,
+ /*58   X     Y     Z     [     \     ]     ^     _ */
+     0xE7, 0xE8, 0xE9, 0xBA, 0xE0, 0xBB, 0xB0, 0x6D,
+ /*60   `     a     b     c     d     e     f     g */
+     0x79, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
+ /*68   h     i     j     k     l     m     n     o */
+     0x88, 0x89, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96,
+ /*70   p     q     r     s     t     u     v     w */
+     0x97, 0x98, 0x99, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6,
+ /*78   x     y     z     {     |     }     ~    DL */
+     0xA7, 0xA8, 0xA9, 0xC0, 0x4F, 0xD0, 0xA1, 0x07,
+ /*80*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*88*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*90*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*98*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*A8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*B8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*C8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*D8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E0        sz						*/
+     0x3F, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*E8*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F0*/
+     0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F,
+ /*F8*/
+     0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x3F, 0xFF
+};
+
+void convert_label(char *str)
+{
+	int i;
+	for (i=0;i<LABEL_LENGTH;i++) str[i]=_ascebc[str[i]];
+}
+
 void
 exit_usage(int exitcode)
 {
-	printf("Usage: %s [-htvyV] [-b <blocksize>] [<range>] <diskspec>\n\n",
-	       prog_name);
+#ifdef RANGE_FORMATTING
+	printf("Usage: %s [-htvyLV] [-l <label>] [-b <blocksize>] [<range>] " \
+		"<diskspec>\n\n",prog_name);
+#else /* RANGE_FORMATTING */
+	printf("Usage: %s [-htvyLV] [-l <label>] [-b <blocksize>] " \
+		"<diskspec>\n\n",prog_name);
+#endif /* RANGE_FORMATTING */
 	printf("       -t means testmode\n");
 	printf("       -v means verbose mode\n");
 	printf("       -V means print version\n");
+	printf("       -L means don't write disk label\n");
+	printf("       <label> is a label which is converted to EBCDIC and " \
+		"written to disk\n");
 	printf("       <blocksize> has to be power of 2 and at least 512\n");
+#ifdef RANGE_FORMATTING
 	printf("       <range> is either\n");
 	printf("           -s <start_track> -e <end_track>\n");
 	printf("       or\n");
 	printf("           -r <start_track>-<end_track>\n");
+#endif /* RANGE_FORMATTING */
 	printf("       and <diskspec> is either\n");
 	printf("           -f /dev/dasdX\n");
 	printf("       or\n");
@@ -108,9 +199,9 @@
 			PROC_DASD_DEVICES ": %s (do you have the /proc " \
 			"filesystem enabled?)\n",prog_name,strerror(errno));
 
-	fgets(line,sizeof(line),file); /* omit first line */
+	/*	fgets(line,sizeof(line),file); omit first line */ 
 	while (fgets(line,sizeof(line),file)!=NULL) {
-		rc=sscanf(line,"%X%d%d",&d,&ma_i,&mi_i);
+		rc=sscanf(line,"%X %*[(A-Z)] at (%d:%d)",&d,&ma_i,&mi_i);
 		ma=ma_i;
 		mi=mi_i;
 		if ( (rc==3) &&
@@ -255,6 +346,7 @@
 	char *str;
 	char output[60],o2[12];
 
+#ifdef RANGE_FORMATTING
 	i=params.start_unit;
 	do {
 		params.start_unit=i;
@@ -286,6 +378,7 @@
 			ASK_CHECK_PARAM(CHECK_END);
 		}
 	} while (rc!=1);
+#endif /* RANGE_FORMATTING */
 
 	i=params.blksize;
 	do {
@@ -364,12 +457,16 @@
 
 void
 do_format_dasd(char *dev_name,format_data_t format_params,int testmode,
-	int verbosity,int withoutprompt)
+	int verbosity,int writenolabel,int labelspec,
+	char *label,int withoutprompt)
 {
 	int fd,rc;
 	struct stat stat_buf;
 	kdev_t minor_no,major_no;
 	int devno;
+	int new_blksize;
+	unsigned int label_position;
+	struct hd_geometry new_geometry;
 	char inp_buffer[5]; /* to contain yes */
 
 	fd=open(dev_name,O_RDWR);
@@ -393,6 +490,10 @@
 	}
 	check_mounted(major_no, minor_no);
 	
+	if ((!writenolabel) && (!labelspec)) {
+		sprintf(label,"LNX1 x%04x",devno);
+	}
+	
 	if ( ((withoutprompt)&&(verbosity>=1)) ||
 		(!withoutprompt) ) {
 		get_xno_from_xno(&devno,&major_no,&minor_no,
@@ -402,6 +503,11 @@
 		printf("   Device number of device : 0x%x\n",devno);
 		printf("   Major number of device  : %u\n",major_no);
 		printf("   Minor number of device  : %u\n",minor_no);
+		printf("   Labelling device        : %s\n",(writenolabel)?
+			"no":"yes");
+		if (!writenolabel)
+			printf("   Disk label              : %s\n",label);
+#ifdef RANGE_FORMATTING
 		printf("   Start track             : %d\n" \
 			,format_params.start_unit);
 		printf("   End track               : ");
@@ -409,6 +515,7 @@
 			printf("last track of disk\n");
 		else
 			printf("%d\n",format_params.stop_unit);
+#endif /* RANGE_FORMATTING */
 		printf("   Blocksize               : %d\n" \
 			,format_params.blksize);
 		if (testmode) printf("Test mode active, omitting ioctl.\n");
@@ -439,6 +546,56 @@
 				"message:\n%s\n",prog_name,strerror(errno));
 		printf("Finished formatting the device.\n");
 
+		if (!writenolabel) {
+			if (verbosity>0)
+				printf("Retrieving disk geometry... ");
+
+			rc=ioctl(fd,HDIO_GETGEO,&new_geometry);
+			if (rc) {
+				ERRMSG("%s: the ioctl call to get geometry " \
+					"returned with the following error " \
+					"message:\n%s\n",prog_name,
+					strerror(errno));
+				goto reread;
+			}
+	
+
+			rc=ioctl(fd,BLKGETBSZ,&new_blksize);
+			if (rc) {
+				ERRMSG("%s: the ioctl call to get blocksize " \
+					"returned with the following error " \
+					"message:\n%s\n",prog_name,
+					strerror(errno));
+				goto reread;
+			}
+	
+			if (verbosity>0) printf("done\n");
+
+			label_position=new_geometry.start*new_blksize;
+	
+			if (verbosity>0) printf("Writing label... ");
+			convert_label(label);
+			rc=lseek(fd,label_position,SEEK_SET);
+			if (rc!=label_position) {
+				ERRMSG("%s: lseek on the device to %i " \
+					"failed with the following error " \
+					"message:\n%s\n",prog_name,
+					label_position,strerror(errno));
+				goto reread;
+			}
+			rc=write(fd,label,LABEL_LENGTH);
+			if (rc!=LABEL_LENGTH) {
+				ERRMSG("%s: writing the label only wrote %d " \
+					"bytes.\n",prog_name,rc);
+				goto reread;
+			}
+
+			sync();
+			sync();
+
+			if (verbosity>0) printf("done\n");
+		}
+ reread:
 		printf("Rereading the partition table... ");
 		rc=ioctl(fd,BLKRRPART,NULL);
 		if (rc) {
@@ -461,11 +618,13 @@
 	int verbosity;
 	int testmode;
 	int withoutprompt;
+	int writenolabel,labelspec;
 
 	char *dev_name;
 	int devno;
 	char *dev_filename,*devno_param_str,*range_param_str;
 	char *start_param_str,*end_param_str,*blksize_param_str;
+	char label[LABEL_LENGTH+1];
 	
 	format_data_t format_params;
 
@@ -474,7 +633,7 @@
 	char *endptr;
 
 	char c1,c2,cbuffer[6]; /* should be able to contain -end plus 1 char */
-	int i1,i2;
+	int i,i1,i2;
 	char *str;
 
 	int start_specified,end_specified,blksize_specified;
@@ -492,6 +651,11 @@
 	testmode=0;
 	verbosity=0;
 	withoutprompt=0;
+	writenolabel=0;
+	labelspec=0;
+	for (i=0;i<LABEL_LENGTH;i++) label[i]=' ';
+	label[LABEL_LENGTH]=0;
+
 	start_specified=end_specified=blksize_specified=0;
 	devfile_specified=devno_specified=range_specified=0;
 
@@ -500,7 +664,10 @@
 	/* avoid error message generated by getopt */
 	opterr=0;
 
-	while ( (oc=getopt(argc,argv,"r:s:e:b:n:f:hty?vV")) !=EOF) {
+#ifdef RANGE_FORMATTING
+	while ( (oc=getopt(argc,argv,"r:s:e:b:n:l:f:hLty?vV")) !=EOF) {
+#endif /* RANGE_FORMATTING */
+	while ( (oc=getopt(argc,argv,"b:n:l:f:hLty?vV")) !=EOF) {
 		switch (oc) {
 		case 'y':
 			withoutprompt=1;
@@ -525,6 +692,18 @@
 			printf("%s version 0.99\n",prog_name);
 			exit(0);
 
+		case 'l':
+			strncpy(label,optarg,LABEL_LENGTH);
+			if (strlen(optarg)<LABEL_LENGTH)
+				label[strlen(optarg)]=' ';
+			labelspec++;
+			break;
+
+		case 'L':
+			writenolabel++;
+			break;
+
+#ifdef RANGE_FORMATTING
 		case 's' :
 			start_param_str=optarg;
 			start_specified++;
@@ -535,6 +714,12 @@
 			end_specified++;
 			break;
 
+		case 'r' :
+			range_param_str=optarg;
+			range_specified++;
+			break;
+#endif /* RANGE_FORMATTING */
+
 		case 'b' :
 			blksize_param_str=optarg;
 			blksize_specified++;
@@ -549,10 +734,6 @@
 			dev_filename=optarg;
 			devfile_specified++;
 			break;
-		case 'r' :
-			range_param_str=optarg;
-			range_specified++;
-			break;
 		}
 	}
 
@@ -604,6 +785,8 @@
 	CHECK_SPEC_MAX_ONCE(start_specified,"start track");
 	CHECK_SPEC_MAX_ONCE(end_specified,"end track");
 	CHECK_SPEC_MAX_ONCE(blksize_specified,"blocksize");
+	CHECK_SPEC_MAX_ONCE(labelspec,"label");
+	CHECK_SPEC_MAX_ONCE(writenolabel,"omit-label-writing flag");
 
 	if (devno_specified)
 		PARSE_PARAM_INTO(devno,devno_param_str,16,"device number");
@@ -628,7 +811,7 @@
 
 	/******* issue the real command and reread part table *******/
 	do_format_dasd(dev_name,format_params,testmode,verbosity,
-		withoutprompt);
+		writenolabel,labelspec,label,withoutprompt);
 
 	/*************** cleanup ********************************/
 	if (strncmp(dev_name,TEMPFILENAME,TEMPFILENAMECHARS)==0) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/tools/hwc_cntl_key/hwc_cntl_key.c linux.17p18/arch/s390/tools/hwc_cntl_key/hwc_cntl_key.c
--- linux.vanilla/arch/s390/tools/hwc_cntl_key/hwc_cntl_key.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/tools/hwc_cntl_key/hwc_cntl_key.c	Tue Aug  1 07:59:05 2000
@@ -12,7 +12,7 @@
 #include <stdio.h>
 
 /* everything about the HWC terminal driver ioctl-commands */
-#include "../../../../drivers/s390/char/sclp_tty.h"
+#include "../../../../drivers/s390/char/hwc_tty.h"
 
 /* standard input, should be our HWC tty */
 #define DESCRIPTOR 0
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/s390/tools/silo/silo.c linux.17p18/arch/s390/tools/silo/silo.c
--- linux.vanilla/arch/s390/tools/silo/silo.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/s390/tools/silo/silo.c	Tue Aug  1 07:59:05 2000
@@ -57,7 +57,7 @@
 #define PRINT_LEVEL(x,y...) if ( silo_options.verbosity >= x ) printf(y)
 #define ERROR_LEVEL(x,y...) if ( silo_options.verbosity >= x ) fprintf(stderr,y)
 #define TOGGLE(x) ((x)=((x)?(0):(1)))
-#define GETARG(x) {int len=strlen(optarg);x=malloc(len);strncpy(x,optarg,len);PRINT_LEVEL(1,"%s set to %s\n",#x,optarg);}
+#define GETARG(x) {int len=strlen(optarg);x=malloc(len+1);strncpy(x,optarg,len+1);PRINT_LEVEL(1,"%s set to %s\n",#x,optarg);}
 
 #define ITRY(x) if ( (x) == -1 ) { ERROR_LEVEL(0,"%s (line:%d) '%s' returned %d='%s'\n", __FILE__,__LINE__,#x,errno,strerror(errno)); usage(); exit(1); }
 #define NTRY(x) if ( (x) == 0 ) { ERROR_LEVEL(0,"%s (line:%d) '%s' returned %d='%s'\n", __FILE__,__LINE__,#x,errno,strerror(errno)); usage(); exit(1); }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc/kernel/signal.c linux.17p18/arch/sparc/kernel/signal.c
--- linux.vanilla/arch/sparc/kernel/signal.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc/kernel/signal.c	Tue Aug  1 07:59:05 2000
@@ -1,4 +1,4 @@
-/*  $Id: signal.c,v 1.91.2.1 1999/06/14 00:36:13 davem Exp $
+/*  $Id: signal.c,v 1.91.2.2 2000/05/28 19:13:21 ecd Exp $
  *  linux/arch/sparc/kernel/signal.c
  *
  *  Copyright (C) 1991, 1992  Linus Torvalds
@@ -536,7 +536,7 @@
 
 static inline void
 new_setup_frame(struct k_sigaction *ka, struct pt_regs *regs,
-		int signo, sigset_t *oldset)
+		int signr, sigset_t *oldset)
 {
 	struct new_signal_frame *sf;
 	int sigframe_size, err;
@@ -583,7 +583,7 @@
 	
 	/* 3. signal handler back-trampoline and parameters */
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
-	regs->u_regs[UREG_I0] = signo;
+	regs->u_regs[UREG_I0] = signr;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 
 	/* 4. signal handler */
@@ -617,7 +617,7 @@
 
 static inline void
 new_setup_rt_frame(struct k_sigaction *ka, struct pt_regs *regs,
-		   int signo, sigset_t *oldset, siginfo_t *info)
+		   int signr, sigset_t *oldset, siginfo_t *info)
 {
 	struct rt_signal_frame *sf;
 	int sigframe_size;
@@ -650,20 +650,77 @@
 	} else {
 		err |= __put_user(0, &sf->fpu_save);
 	}
-	err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
-	
+
+	/* Update the siginfo structure.  Is this good?  */
+	if (info->si_code == 0) {
+		info->si_signo = signr;
+		info->si_errno = 0;
+
+		switch (signr) {
+		case SIGSEGV:
+		case SIGILL:
+		case SIGFPE:
+		case SIGBUS:
+		case SIGEMT:
+			info->si_code = current->tss.sig_desc;
+			info->si_addr = (void *)current->tss.sig_address;
+			info->si_trapno = 0;
+			break;
+		default:
+			break;
+		}
+	}
+
+	err = __put_user (info->si_signo, &sf->info.si_signo);
+	err |= __put_user (info->si_errno, &sf->info.si_errno);
+	err |= __put_user (info->si_code, &sf->info.si_code);
+	if (info->si_code < 0)
+		err |= __copy_to_user (sf->info._sifields._pad, info->_sifields._pad, SI_PAD_SIZE);
+	else {
+		int i = info->si_signo;
+		if (info->si_code == SI_USER)
+			i = SIGRTMIN;
+		switch (i) {
+		case SIGPOLL:
+			err |= __put_user (info->si_band, &sf->info.si_band);
+			err |= __put_user (info->si_fd, &sf->info.si_fd);
+			break;
+		case SIGCHLD:
+			err |= __put_user (info->si_pid, &sf->info.si_pid);
+			err |= __put_user (info->si_uid, &sf->info.si_uid);
+			err |= __put_user (info->si_status, &sf->info.si_status);
+			err |= __put_user (info->si_utime, &sf->info.si_utime);
+			err |= __put_user (info->si_stime, &sf->info.si_stime);
+			break;
+		case SIGSEGV:
+		case SIGILL:
+		case SIGFPE:
+		case SIGBUS:
+		case SIGEMT:
+			err |= __put_user ((long)info->si_addr, &sf->info.si_addr);
+			err |= __put_user (info->si_trapno, &sf->info.si_trapno);
+			break;
+		default:
+			err |= __put_user (info->si_pid, &sf->info.si_pid);
+			err |= __put_user (info->si_uid, &sf->info.si_uid);
+			break;
+		}
+	}
+
 	/* Setup sigaltstack */
 	err |= __put_user(current->sas_ss_sp, &sf->stack.ss_sp);
 	err |= __put_user(sas_ss_flags(regs->u_regs[UREG_FP]), &sf->stack.ss_flags);
 	err |= __put_user(current->sas_ss_size, &sf->stack.ss_size);
-	
+
+	err |= __copy_to_user(&sf->mask, &oldset->sig[0], sizeof(sigset_t));
+
 	err |= __copy_to_user(sf, (char *) regs->u_regs [UREG_FP],
 			      sizeof (struct reg_window));	
 	if (err)
 		goto sigsegv;
 
 	regs->u_regs[UREG_FP] = (unsigned long) sf;
-	regs->u_regs[UREG_I0] = signo;
+	regs->u_regs[UREG_I0] = signr;
 	regs->u_regs[UREG_I1] = (unsigned long) &sf->info;
 
 	regs->pc = (unsigned long) ka->sa.sa_handler;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc/kernel/sparc_ksyms.c linux.17p18/arch/sparc/kernel/sparc_ksyms.c
--- linux.vanilla/arch/sparc/kernel/sparc_ksyms.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc/kernel/sparc_ksyms.c	Tue Aug  1 08:13:45 2000
@@ -1,4 +1,4 @@
-/* $Id: sparc_ksyms.c,v 1.77.2.4 1999/09/28 16:47:30 davem Exp $
+/* $Id: sparc_ksyms.c,v 1.77.2.5 2000/07/17 18:44:26 jj Exp $
  * arch/sparc/kernel/ksyms.c: Sparc specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -82,10 +82,10 @@
 __EXPORT_SYMBOL(__sparc_dot_ ## sym, "." #sym)
 
 #define EXPORT_SYMBOL_PRIVATE(sym)				\
-extern int __sparc_priv_ ## sym (int) __asm__("__" ## #sym);	\
+extern int __sparc_priv_ ## sym (int) __asm__("__" #sym);	\
 const struct module_symbol __export_priv_##sym			\
 __attribute__((section("__ksymtab"))) =				\
-{ (unsigned long) &__sparc_priv_ ## sym, "__" ## #sym }
+{ (unsigned long) &__sparc_priv_ ## sym, "__" #sym }
 
 /* used by various drivers */
 EXPORT_SYMBOL(sparc_cpu_model);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/config.in linux.17p18/arch/sparc64/config.in
--- linux.vanilla/arch/sparc64/config.in	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/sparc64/config.in	Tue Aug  1 08:13:45 2000
@@ -1,4 +1,4 @@
-# $Id: config.in,v 1.67.2.5 1999/10/19 16:49:37 davem Exp $
+# $Id: config.in,v 1.67.2.11 2000/07/27 01:50:59 davem Exp $
 # For a description of the syntax of this configuration file,
 # see Documentation/kbuild/config-language.txt.
 #
@@ -87,6 +87,7 @@
     fi
   fi
   tristate 'SUNW,envctrl support' CONFIG_ENVCTRL
+  tristate '7-Segment Display support' CONFIG_DISPLAY7SEG
 fi
 endmenu
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/defconfig linux.17p18/arch/sparc64/defconfig
--- linux.vanilla/arch/sparc64/defconfig	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/sparc64/defconfig	Tue Aug  1 07:59:05 2000
@@ -30,8 +30,9 @@
 CONFIG_FB_PM2=y
 # CONFIG_FB_PM2_FIFO_DISCONNECT is not set
 CONFIG_FB_PM2_PCI=y
-# CONFIG_FB_MATROX is not set
 CONFIG_FB_ATY=y
+# CONFIG_FB_MATROX is not set
+# CONFIG_FB_ATY128 is not set
 CONFIG_FB_SBUS=y
 CONFIG_FB_CREATOR=y
 CONFIG_FB_CGSIX=y
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/ebus.c linux.17p18/arch/sparc64/kernel/ebus.c
--- linux.vanilla/arch/sparc64/kernel/ebus.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc64/kernel/ebus.c	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: ebus.c,v 1.36.2.4 1999/11/08 23:25:45 davem Exp $
+/* $Id: ebus.c,v 1.36.2.5 2000/07/27 01:50:59 davem Exp $
  * ebus.c: PCI to EBus bridge device.
  *
  * Copyright (C) 1997  Eddie C. Dost  (ecd@skynet.be)
@@ -44,6 +44,9 @@
 #ifdef CONFIG_ENVCTRL
 extern int envctrl_init(void);
 #endif
+#ifdef CONFIG_DISPLAY7SEG
+extern int d7s_init(void);
+#endif
 
 static inline unsigned long ebus_alloc(size_t size)
 {
@@ -423,6 +426,9 @@
 #endif
 #ifdef CONFIG_OBP_FLASH
 	flash_init();
+#endif
+#ifdef CONFIG_DISPLAY7SEG
+	d7s_init();
 #endif
 	clock_probe();
 	power_init();
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/ioctl32.c linux.17p18/arch/sparc64/kernel/ioctl32.c
--- linux.vanilla/arch/sparc64/kernel/ioctl32.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/sparc64/kernel/ioctl32.c	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: ioctl32.c,v 1.62.2.12 2000/05/27 04:46:26 davem Exp $
+/* $Id: ioctl32.c,v 1.62.2.13 2000/07/27 01:50:59 davem Exp $
  * ioctl32.c: Conversion between 32bit and 64bit native ioctls.
  *
  * Copyright (C) 1997  Jakub Jelinek  (jj@sunsite.mff.cuni.cz)
@@ -59,6 +59,7 @@
 #include <asm/envctrl.h>
 #include <asm/audioio.h>
 #include <asm/ethtool.h>
+#include <asm/display7seg.h>
 
 #include <linux/soundcard.h>
 
@@ -2167,7 +2168,7 @@
 	case _IOR('v' , BASE_VIDIOCPRIVATE+6, int):
 	case _IOR('v' , BASE_VIDIOCPRIVATE+7, int):
 
-	/* Little p (/dev/rtc, /dev/envctrl, etc.) */
+	/* Little p (/dev/rtc, /dev/envctrl, /dev/d7s, etc.) */
 	case RTCGET:
 	case RTCSET:
 	case ENVCTRL_RD_WARNING_TEMPERATURE:
@@ -2179,6 +2180,9 @@
 	case ENVCTRL_RD_ETHERNET_TEMPERATURE:
 	case ENVCTRL_RD_MTHRBD_TEMPERATURE:
 	case ENVCTRL_RD_CPU_VOLTAGE:
+	case D7SIOCWR:
+	/* case D7SIOCRD: Same value as ENVCTRL_RD_VOLTAGE_STATUS */
+	case D7SIOCTM:
 
 
 	/* Little m */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/power.c linux.17p18/arch/sparc64/kernel/power.c
--- linux.vanilla/arch/sparc64/kernel/power.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc64/kernel/power.c	Tue Aug  1 07:59:05 2000
@@ -1,4 +1,4 @@
-/* $Id: power.c,v 1.3.2.1 1999/08/31 18:21:23 davem Exp $
+/* $Id: power.c,v 1.3.2.2 2000/07/11 22:42:09 davem Exp $
  * power.c: Power management driver.
  *
  * Copyright (C) 1999 David S. Miller (davem@redhat.com)
@@ -54,7 +54,7 @@
 static int powerd(void *__unused)
 {
 	static char *envp[] = { "HOME=/", "TERM=linux", "PATH=/sbin:/usr/sbin:/bin:/usr/bin", NULL };
-	char *argv[] = { "/usr/bin/shutdown", "-h", "now", NULL };
+	char *argv[] = { "/sbin/shutdown", "-h", "now", NULL };
 
 	current->session = 1;
 	current->pgrp = 1;
@@ -69,7 +69,7 @@
 	}
 
 	/* Ok, down we go... */
-	if (execve("/usr/bin/shutdown", argv, envp) < 0) {
+	if (execve("/sbin/shutdown", argv, envp) < 0) {
 		printk("powerd: shutdown execution failed\n");
 		button_pressed = 0;
 		goto again;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/psycho.c linux.17p18/arch/sparc64/kernel/psycho.c
--- linux.vanilla/arch/sparc64/kernel/psycho.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/sparc64/kernel/psycho.c	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: psycho.c,v 1.85.2.9 2000/05/01 06:33:49 davem Exp $
+/* $Id: psycho.c,v 1.85.2.10 2000/06/14 07:41:19 davem Exp $
  * psycho.c: Ultra/AX U2P PCI controller support.
  *
  * Copyright (C) 1997 David S. Miller (davem@caipfs.rutgers.edu)
@@ -37,6 +37,12 @@
 unsigned long pci_dvma_v2p_hash[PCI_DVMA_HASHSZ];
 unsigned long pci_dvma_p2v_hash[PCI_DVMA_HASHSZ];
 
+/* If this is non-NULL it points to Sabre's DMA write-sync register
+ * which is used by drivers of devices behind bridges other than APB
+ * to synchronize DMA write streams with interrupt delivery.
+ */
+volatile u64 *pci_dma_wsync = NULL;
+
 #ifndef CONFIG_PCI
 
 int pcibios_present(void)
@@ -299,6 +305,8 @@
 		prom_printf("SABRE: Error, cannot map SABRE main registers.\n");
 		prom_halt();
 	}
+
+	pci_dma_wsync = &sabre->psycho_regs->pci_dma_wsync;
 
 	printk("PCI: Found SABRE, main regs at %p CTRL[%016lx]\n",
 	       sabre->psycho_regs, sabre->psycho_regs->control);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/rtrap.S linux.17p18/arch/sparc64/kernel/rtrap.S
--- linux.vanilla/arch/sparc64/kernel/rtrap.S	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc64/kernel/rtrap.S	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: rtrap.S,v 1.45 1998/11/09 15:33:29 davem Exp $
+/* $Id: rtrap.S,v 1.45.2.1 2000/07/28 02:10:55 davem Exp $
  * rtrap.S: Preparing for return from trap on Sparc V9.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -139,6 +139,14 @@
 		call			do_signal
 		 add			%sp, STACK_BIAS + REGWIN_SZ, %o1
 		clr			%l6
+
+		/* Signal delivery can change ptregs->tstate so we must
+		 * reload it into %l1 here.
+		 */
+		ldx			[%sp + PTREGS_OFF + PT_V9_TSTATE], %l1
+		sethi			%hi(0xf << 20), %l4
+		and			%l1, %l4, %l4
+		andn			%l1, %l4, %l1
 
 		/* We must not take any traps between here and the actual
 		 * return to user-space.  If we do we risk having windows
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/sparc64_ksyms.c linux.17p18/arch/sparc64/kernel/sparc64_ksyms.c
--- linux.vanilla/arch/sparc64/kernel/sparc64_ksyms.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/arch/sparc64/kernel/sparc64_ksyms.c	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: sparc64_ksyms.c,v 1.58.2.7 2000/05/27 04:46:26 davem Exp $
+/* $Id: sparc64_ksyms.c,v 1.58.2.8 2000/06/14 07:41:19 davem Exp $
  * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support.
  *
  * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu)
@@ -43,6 +43,7 @@
 #endif
 #ifdef CONFIG_PCI
 #include <asm/ebus.h>
+#include <asm/pbm.h>
 #endif
 #include <asm/a.out.h>
 #include <asm/svr4.h>
@@ -193,6 +194,7 @@
 EXPORT_SYMBOL(insb);
 EXPORT_SYMBOL(insw);
 EXPORT_SYMBOL(insl);
+EXPORT_SYMBOL(pci_dma_wsync);
 #endif
 
 /* Solaris/SunOS binary compatibility */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/kernel/sys_sparc32.c linux.17p18/arch/sparc64/kernel/sys_sparc32.c
--- linux.vanilla/arch/sparc64/kernel/sys_sparc32.c	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc64/kernel/sys_sparc32.c	Tue Aug  1 07:59:05 2000
@@ -1,4 +1,4 @@
-/* $Id: sys_sparc32.c,v 1.107.2.8 2000/02/28 04:09:49 davem Exp $
+/* $Id: sys_sparc32.c,v 1.107.2.9 2000/06/20 17:12:25 davem Exp $
  * sys_sparc32.c: Conversion between 32bit and 64bit native syscalls.
  *
  * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz)
@@ -2488,7 +2488,8 @@
 	 * the cmsg_len for MSG_TRUNC cases, we need not check that case either.
 	 */
 	ucmsg = (struct cmsghdr *) orig_cmsg_uptr;
-	while(((unsigned long)ucmsg) < ((unsigned long)kmsg->msg_control)) {
+	while(((unsigned long)ucmsg) <=
+	      (((unsigned long)kmsg->msg_control) - sizeof(struct cmsghdr))) {
 		struct cmsghdr32 *kcmsg32 = (struct cmsghdr32 *) wp;
 		int clen64, clen32;
 
@@ -3689,8 +3690,10 @@
 		err = nfs_getfh32_trans(karg, arg32);
 		break;
 	case NFSCTL_LOCKD:
-		/* No arguments, no translations... */
-		err = 0;
+		/* We still have to copy over the version
+		 * because nfsctl still checks that.
+		 */
+		err = get_user(karg->ca_version, &arg32->ca32_version);
 		break;
 	default:
 		err = -EINVAL;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/arch/sparc64/lib/blockops.S linux.17p18/arch/sparc64/lib/blockops.S
--- linux.vanilla/arch/sparc64/lib/blockops.S	Fri Apr 21 12:45:48 2000
+++ linux.17p18/arch/sparc64/lib/blockops.S	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: blockops.S,v 1.16.2.2 2000/03/03 23:50:32 davem Exp $
+/* $Id: blockops.S,v 1.16.2.4 2000/07/14 01:11:29 davem Exp $
  * blockops.S: UltraSparc block zero optimized routines.
  *
  * Copyright (C) 1996,1998 David S. Miller (davem@caip.rutgers.edu)
@@ -43,21 +43,23 @@
 	sethi		%hi(DCACHE_SIZE), %o1
 	add		%o0, %o3, %o0
 	add		%o0, %o1, %o1
-	sethi		%hi(TLBTEMP_ENT1), %o3
+	mov		TLBTEMP_ENT1, %o3
 	rdpr		%pstate, %g3
 	wrpr		%g3, PSTATE_IE, %pstate
 
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %o4
 	stxa		%g0, [%o4] ASI_DMMU
-	flush		%g6
+	sethi		%hi(empty_zero_page), %o4
+	flush		%o4
 
 	ldxa		[%o3] ASI_DTLB_TAG_READ, %o4
 
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %o5
 	stxa		%g0, [%o5] ASI_DMMU
-	flush		%g6
+	sethi		%hi(empty_zero_page), %o5
+	flush		%o5
 
 	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %o5
 	stxa		%o0, [%o2] ASI_DMMU
@@ -68,14 +70,16 @@
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %g5
 	stxa		%g0, [%g5] ASI_DMMU
-	flush		%g6
+	sethi		%hi(empty_zero_page), %g5
+	flush		%g5
 
 	ldxa		[%o3] ASI_DTLB_TAG_READ, %g5
 
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %g7
 	stxa		%g0, [%g7] ASI_DMMU
-	flush		%g6
+	sethi		%hi(empty_zero_page), %g7
+	flush		%g7
 
 	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g7
 	stxa		%o1, [%o2] ASI_DMMU
@@ -141,21 +145,23 @@
 	mov		TLB_TAG_ACCESS, %o2
 	sethi		%hi(TLBTEMP_BASE), %o3
 	add		%o0, %o3, %o0
-	sethi		%hi(TLBTEMP_ENT2), %o3
+	mov		TLBTEMP_ENT2, %o3
 	rdpr		%pstate, %g3
 	wrpr		%g3, PSTATE_IE, %pstate
 
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %g5
 	stxa		%g0, [%g5] ASI_DMMU
-	flush		%g6
+	sethi		%hi(empty_zero_page), %g5
+	flush		%g5
 
 	ldxa		[%o3] ASI_DTLB_TAG_READ, %g5
 
 	/* Spitfire Errata #32 workaround */
 	mov		0x8, %g7
 	stxa		%g0, [%g7] ASI_DMMU
-	flush		%g6
+	sethi		%hi(empty_zero_page), %g7
+	flush		%g7
 
 	ldxa		[%o3] ASI_DTLB_DATA_ACCESS, %g7
 	stxa		%o0, [%o2] ASI_DMMU
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/DAC960.c linux.17p18/drivers/block/DAC960.c
--- linux.vanilla/drivers/block/DAC960.c	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/DAC960.c	Tue Aug  1 19:11:11 2000
@@ -1,8 +1,8 @@
 /*
 
-  Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
+  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-  Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
+  Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
@@ -19,8 +19,8 @@
 */
 
 
-#define DAC960_DriverVersion			"2.2.5"
-#define DAC960_DriverDate			"23 January 2000"
+#define DAC960_DriverVersion			"2.2.7"
+#define DAC960_DriverDate			"1 August 2000"
 
 
 #include <linux/version.h>
@@ -55,7 +55,7 @@
 
 
 /*
-  DAC960_ActiveControllerCount is the number of Active DAC960 Controllers
+  DAC960_ActiveControllerCount is the number of active DAC960 Controllers
   detected.
 */
 
@@ -130,7 +130,7 @@
 */
 
 static boolean DAC960_Failure(DAC960_Controller_T *Controller,
-			      char *ErrorMessage)
+			      unsigned char *ErrorMessage)
 {
   DAC960_Error("While configuring DAC960 PCI RAID Controller at\n",
 	       Controller);
@@ -150,17 +150,128 @@
 
 
 /*
-  DAC960_ClearCommand clears critical fields of Command.
+  DAC960_CreateAuxiliaryStructures allocates and initializes the auxiliary
+  data structures for Controller.  It returns true on success and false on
+  failure.
 */
 
-static inline void DAC960_ClearCommand(DAC960_Command_T *Command)
+static boolean DAC960_CreateAuxiliaryStructures(DAC960_Controller_T *Controller)
 {
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  CommandMailbox->Words[0] = 0;
-  CommandMailbox->Words[1] = 0;
-  CommandMailbox->Words[2] = 0;
-  CommandMailbox->Words[3] = 0;
-  Command->CommandStatus = 0;
+  int CommandAllocationLength, CommandAllocationGroupSize;
+  int CommandsRemaining = 0, CommandIdentifier, CommandGroupByteCount;
+  void *AllocationPointer = NULL;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      CommandAllocationLength = offsetof(DAC960_Command_T, V1.EndMarker);
+      CommandAllocationGroupSize = DAC960_V1_CommandAllocationGroupSize;
+    }
+  else
+    {
+      CommandAllocationLength = offsetof(DAC960_Command_T, V2.EndMarker);
+      CommandAllocationGroupSize = DAC960_V2_CommandAllocationGroupSize;
+    }
+  Controller->CommandAllocationGroupSize = CommandAllocationGroupSize;
+  Controller->FreeCommands = NULL;
+  for (CommandIdentifier = 1;
+       CommandIdentifier <= Controller->DriverQueueDepth;
+       CommandIdentifier++)
+    {
+      DAC960_Command_T *Command;
+      if (--CommandsRemaining <= 0)
+	{
+	  CommandsRemaining =
+	    Controller->DriverQueueDepth - CommandIdentifier + 1;
+	  if (CommandsRemaining > CommandAllocationGroupSize)
+	    CommandsRemaining = CommandAllocationGroupSize;
+	  CommandGroupByteCount =
+	    CommandsRemaining * CommandAllocationLength;
+	  AllocationPointer = kmalloc(CommandGroupByteCount, GFP_ATOMIC);
+	  if (AllocationPointer == NULL)
+	    return DAC960_Failure(Controller, "AUXILIARY STRUCTURE CREATION");
+	  memset(AllocationPointer, 0, CommandGroupByteCount);
+	}
+      Command = (DAC960_Command_T *) AllocationPointer;
+      AllocationPointer += CommandAllocationLength;
+      Command->CommandIdentifier = CommandIdentifier;
+      Command->Controller = Controller;
+      Command->Next = Controller->FreeCommands;
+      Controller->FreeCommands = Command;
+      Controller->Commands[CommandIdentifier-1] = Command;
+    }
+  return true;
+}
+
+
+/*
+  DAC960_DestroyAuxiliaryStructures deallocates the auxiliary data
+  structures for Controller.
+*/
+
+static void DAC960_DestroyAuxiliaryStructures(DAC960_Controller_T *Controller)
+{
+  int i;
+  Controller->FreeCommands = NULL;
+  for (i = 0; i < Controller->DriverQueueDepth; i++)
+    {
+      DAC960_Command_T *Command = Controller->Commands[i];
+      if (Command != NULL &&
+	  (Command->CommandIdentifier
+	   % Controller->CommandAllocationGroupSize) == 1)
+	kfree(Command);
+      Controller->Commands[i] = NULL;
+    }
+  if (Controller->CombinedStatusBuffer != NULL)
+    {
+      kfree(Controller->CombinedStatusBuffer);
+      Controller->CombinedStatusBuffer = NULL;
+      Controller->CurrentStatusBuffer = NULL;
+    }
+  if (Controller->FirmwareType == DAC960_V1_Controller) return;
+  for (i = 0; i < DAC960_MaxLogicalDrives; i++)
+    if (Controller->V2.LogicalDeviceInformation[i] != NULL)
+      {
+	kfree(Controller->V2.LogicalDeviceInformation[i]);
+	Controller->V2.LogicalDeviceInformation[i] = NULL;
+      }
+  for (i = 0; i < DAC960_V2_MaxPhysicalDevices; i++)
+    {
+      if (Controller->V2.PhysicalDeviceInformation[i] != NULL)
+	{
+	  kfree(Controller->V2.PhysicalDeviceInformation[i]);
+	  Controller->V2.PhysicalDeviceInformation[i] = NULL;
+	}
+      if (Controller->V2.InquiryUnitSerialNumber[i] != NULL)
+	{
+	  kfree(Controller->V2.InquiryUnitSerialNumber[i]);
+	  Controller->V2.InquiryUnitSerialNumber[i] = NULL;
+	}
+    }
+}
+
+
+/*
+  DAC960_V1_ClearCommand clears critical fields of Command for DAC960 V1
+  Firmware Controllers.
+*/
+
+static inline void DAC960_V1_ClearCommand(DAC960_Command_T *Command)
+{
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  memset(CommandMailbox, 0, sizeof(DAC960_V1_CommandMailbox_T));
+  Command->V1.CommandStatus = 0;
+}
+
+
+/*
+  DAC960_V2_ClearCommand clears critical fields of Command for DAC960 V2
+  Firmware Controllers.
+*/
+
+static inline void DAC960_V2_ClearCommand(DAC960_Command_T *Command)
+{
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  memset(CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+  Command->V2.CommandStatus = 0;
 }
 
 
@@ -211,66 +322,181 @@
 
 
 /*
-  DAC960_QueueCommand queues Command.
+  DAC960_BA_QueueCommand queues Command for DAC960 BA Series Controllers.
 */
 
-static void DAC960_QueueCommand(DAC960_Command_T *Command)
+static void DAC960_BA_QueueCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
   void *ControllerBaseAddress = Controller->BaseAddress;
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  DAC960_CommandMailbox_T *NextCommandMailbox;
-  CommandMailbox->Common.CommandIdentifier = Command - Controller->Commands;
-  switch (Controller->ControllerType)
-    {
-    case DAC960_V5_Controller:
-      NextCommandMailbox = Controller->NextCommandMailbox;
-      DAC960_V5_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
-      if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
-	  Controller->PreviousCommandMailbox2->Words[0] == 0)
-	{
-	  if (Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V5_MemoryMailboxNewCommand(ControllerBaseAddress);
-	  else DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
-	}
-      Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
-      Controller->PreviousCommandMailbox1 = NextCommandMailbox;
-      if (++NextCommandMailbox > Controller->LastCommandMailbox)
-	NextCommandMailbox = Controller->FirstCommandMailbox;
-      Controller->NextCommandMailbox = NextCommandMailbox;
-      break;
-    case DAC960_V4_Controller:
-      NextCommandMailbox = Controller->NextCommandMailbox;
-      DAC960_V4_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
-      if (Controller->PreviousCommandMailbox1->Words[0] == 0 ||
-	  Controller->PreviousCommandMailbox2->Words[0] == 0)
-	{
-	  if (Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V4_MemoryMailboxNewCommand(ControllerBaseAddress);
-	  else DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
-	}
-      Controller->PreviousCommandMailbox2 = Controller->PreviousCommandMailbox1;
-      Controller->PreviousCommandMailbox1 = NextCommandMailbox;
-      if (++NextCommandMailbox > Controller->LastCommandMailbox)
-	NextCommandMailbox = Controller->FirstCommandMailbox;
-      Controller->NextCommandMailbox = NextCommandMailbox;
-      break;
-    case DAC960_V3_Controller:
-      while (DAC960_V3_MailboxFullP(ControllerBaseAddress))
-	udelay(1);
-      DAC960_V3_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
-      DAC960_V3_NewCommand(ControllerBaseAddress);
-      break;
-    }
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+    Controller->V2.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_BA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_BA_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V2.PreviousCommandMailbox2 =
+    Controller->V2.PreviousCommandMailbox1;
+  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+    NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+  Controller->V2.NextCommandMailbox = NextCommandMailbox;
 }
 
 
 /*
-  DAC960_ExecuteCommand executes Command and waits for completion.  It
-  returns true on success and false on failure.
+  DAC960_LP_QueueCommand queues Command for DAC960 LP Series Controllers.
+*/
+
+static void DAC960_LP_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandMailbox_T *NextCommandMailbox =
+    Controller->V2.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_LP_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V2.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V2.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_LP_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V2.PreviousCommandMailbox2 =
+    Controller->V2.PreviousCommandMailbox1;
+  Controller->V2.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V2.LastCommandMailbox)
+    NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+  Controller->V2.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_LA_QueueCommandDualMode queues Command for DAC960 LA Series
+  Controllers with Dual Mode Firmware.
+*/
+
+static void DAC960_LA_QueueCommandDualMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_LA_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_LA_QueueCommandSingleMode queues Command for DAC960 LA Series
+  Controllers with Single Mode Firmware.
+*/
+
+static void DAC960_LA_QueueCommandSingleMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_LA_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_PG_QueueCommandDualMode queues Command for DAC960 PG Series
+  Controllers with Dual Mode Firmware.
+*/
+
+static void DAC960_PG_QueueCommandDualMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_PG_MemoryMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_PG_QueueCommandSingleMode queues Command for DAC960 PG Series
+  Controllers with Single Mode Firmware.
+*/
+
+static void DAC960_PG_QueueCommandSingleMode(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandMailbox_T *NextCommandMailbox =
+    Controller->V1.NextCommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  DAC960_PG_WriteCommandMailbox(NextCommandMailbox, CommandMailbox);
+  if (Controller->V1.PreviousCommandMailbox1->Words[0] == 0 ||
+      Controller->V1.PreviousCommandMailbox2->Words[0] == 0)
+    DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
+  Controller->V1.PreviousCommandMailbox2 =
+    Controller->V1.PreviousCommandMailbox1;
+  Controller->V1.PreviousCommandMailbox1 = NextCommandMailbox;
+  if (++NextCommandMailbox > Controller->V1.LastCommandMailbox)
+    NextCommandMailbox = Controller->V1.FirstCommandMailbox;
+  Controller->V1.NextCommandMailbox = NextCommandMailbox;
+}
+
+
+/*
+  DAC960_PD_QueueCommand queues Command for DAC960 PD Series Controllers.
+*/
+
+static void DAC960_PD_QueueCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  CommandMailbox->Common.CommandIdentifier = Command->CommandIdentifier;
+  while (DAC960_PD_MailboxFullP(ControllerBaseAddress))
+    udelay(1);
+  DAC960_PD_WriteCommandMailbox(ControllerBaseAddress, CommandMailbox);
+  DAC960_PD_NewCommand(ControllerBaseAddress);
+}
+
+
+/*
+  DAC960_ExecuteCommand executes Command and waits for completion.
 */
 
-static boolean DAC960_ExecuteCommand(DAC960_Command_T *Command)
+static void DAC960_ExecuteCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
   Semaphore_T Semaphore = MUTEX_LOCKED;
@@ -279,227 +505,386 @@
   DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
   DAC960_QueueCommand(Command);
   DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-  if (!in_interrupt())
-    down(&Semaphore);
-  return Command->CommandStatus == DAC960_NormalCompletion;
+  if (in_interrupt()) return;
+  down(&Semaphore);
 }
 
 
 /*
-  DAC960_ExecuteType3 executes a DAC960 Type 3 Command and waits for
-  completion.  It returns true on success and false on failure.
+  DAC960_V1_ExecuteType3 executes a DAC960 V1 Firmware Controller Type 3
+  Command and waits for completion.  It returns true on success and false
+  on failure.
 */
 
-static boolean DAC960_ExecuteType3(DAC960_Controller_T *Controller,
-				   DAC960_CommandOpcode_T CommandOpcode,
-				   void *DataPointer)
+static boolean DAC960_V1_ExecuteType3(DAC960_Controller_T *Controller,
+				      DAC960_V1_CommandOpcode_T CommandOpcode,
+				      void *DataPointer)
 {
   DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  boolean Result;
-  DAC960_ClearCommand(Command);
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  DAC960_V1_ClearCommand(Command);
   Command->CommandType = DAC960_ImmediateCommand;
   CommandMailbox->Type3.CommandOpcode = CommandOpcode;
   CommandMailbox->Type3.BusAddress = Virtual_to_Bus(DataPointer);
-  Result = DAC960_ExecuteCommand(Command);
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V1.CommandStatus;
   DAC960_DeallocateCommand(Command);
-  return Result;
+  return (CommandStatus == DAC960_V1_NormalCompletion);
 }
 
 
 /*
-  DAC960_ExecuteType3D executes a DAC960 Type 3D Command and waits for
-  completion.  It returns true on success and false on failure.
+  DAC960_V1_ExecuteType3D executes a DAC960 V1 Firmware Controller Type 3D
+  Command and waits for completion.  It returns true on success and false
+  on failure.
 */
 
-static boolean DAC960_ExecuteType3D(DAC960_Controller_T *Controller,
-				    DAC960_CommandOpcode_T CommandOpcode,
-				    unsigned char Channel,
-				    unsigned char TargetID,
-				    void *DataPointer)
+static boolean DAC960_V1_ExecuteType3D(DAC960_Controller_T *Controller,
+				       DAC960_V1_CommandOpcode_T CommandOpcode,
+				       unsigned char Channel,
+				       unsigned char TargetID,
+				       void *DataPointer)
 {
   DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  boolean Result;
-  DAC960_ClearCommand(Command);
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  DAC960_V1_ClearCommand(Command);
   Command->CommandType = DAC960_ImmediateCommand;
   CommandMailbox->Type3D.CommandOpcode = CommandOpcode;
   CommandMailbox->Type3D.Channel = Channel;
   CommandMailbox->Type3D.TargetID = TargetID;
   CommandMailbox->Type3D.BusAddress = Virtual_to_Bus(DataPointer);
-  Result = DAC960_ExecuteCommand(Command);
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V1.CommandStatus;
   DAC960_DeallocateCommand(Command);
-  return Result;
+  return (CommandStatus == DAC960_V1_NormalCompletion);
 }
 
 
 /*
-  DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
-  the Error Status Register when the driver performs the BIOS handshaking.
-  It returns true for fatal errors and false otherwise.
+  DAC960_V2_GeneralInfo executes a DAC960 V2 Firmware General Information
+  Reading IOCTL Command and waits for completion.  It returns true on success
+  and false on failure.
 */
 
-static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
-					unsigned char ErrorStatus,
-					unsigned char Parameter0,
-					unsigned char Parameter1)
+static boolean DAC960_V2_GeneralInfo(DAC960_Controller_T *Controller,
+				     DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+				     void *DataPointer,
+				     unsigned int DataByteCount)
 {
-  switch (ErrorStatus)
-    {
-    case 0x00:
-      DAC960_Notice("Physical Drive %d:%d Not Responding\n",
-		    Controller, Parameter1, Parameter0);
-      break;
-    case 0x08:
-      if (Controller->DriveSpinUpMessageDisplayed) break;
-      DAC960_Notice("Spinning Up Drives\n", Controller);
-      Controller->DriveSpinUpMessageDisplayed = true;
-      break;
-    case 0x30:
-      DAC960_Notice("Configuration Checksum Error\n", Controller);
-      break;
-    case 0x60:
-      DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
-      break;
-    case 0x70:
-      DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
-      break;
-    case 0x90:
-      DAC960_Notice("Physical Drive %d:%d COD Mismatch\n",
-		    Controller, Parameter1, Parameter0);
-      break;
-    case 0xA0:
-      DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
-      break;
-    case 0xB0:
-      DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
-      break;
-    case 0xD0:
-      DAC960_Notice("New Controller Configuration Found\n", Controller);
-      break;
-    case 0xF0:
-      DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
-      return true;
-    default:
-      DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
-		   Controller, ErrorStatus);
-      return true;
-    }
-  return false;
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->Common.CommandControlBits
+			.DataTransferControllerToHost = true;
+  CommandMailbox->Common.CommandControlBits
+			.NoAutoRequestSense = true;
+  CommandMailbox->Common.DataTransferSize = DataByteCount;
+  CommandMailbox->Common.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentByteCount =
+    CommandMailbox->Common.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
 }
 
 
 /*
-  DAC960_EnableMemoryMailboxInterface enables the Memory Mailbox Interface.
+  DAC960_V2_ControllerInfo executes a DAC960 V2 Firmware Controller
+  Information Reading IOCTL Command and waits for completion.  It returns
+  true on success and false on failure.
 */
 
-static boolean DAC960_EnableMemoryMailboxInterface(DAC960_Controller_T
-						   *Controller)
+static boolean DAC960_V2_ControllerInfo(DAC960_Controller_T *Controller,
+					DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+					void *DataPointer,
+					unsigned int DataByteCount)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.DataTransferControllerToHost = true;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.NoAutoRequestSense = true;
+  CommandMailbox->ControllerInfo.DataTransferSize = DataByteCount;
+  CommandMailbox->ControllerInfo.ControllerNumber = 0;
+  CommandMailbox->ControllerInfo.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentByteCount =
+    CommandMailbox->ControllerInfo.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_LogicalDeviceInfo executes a DAC960 V2 Firmware Controller Logical
+  Device Information Reading IOCTL Command and waits for completion.  It
+  returns true on success and false on failure.
+*/
+
+static boolean DAC960_V2_LogicalDeviceInfo(DAC960_Controller_T *Controller,
+					   DAC960_V2_IOCTL_Opcode_T
+					     IOCTL_Opcode,
+					   unsigned short
+					     LogicalDeviceNumber,
+					   void *DataPointer,
+					   unsigned int DataByteCount)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->LogicalDeviceInfo.CommandControlBits
+				   .DataTransferControllerToHost = true;
+  CommandMailbox->LogicalDeviceInfo.CommandControlBits
+				   .NoAutoRequestSense = true;
+  CommandMailbox->LogicalDeviceInfo.DataTransferSize = DataByteCount;
+  CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+    LogicalDeviceNumber;
+  CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+				   .ScatterGatherSegments[0]
+				   .SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+				   .ScatterGatherSegments[0]
+				   .SegmentByteCount =
+    CommandMailbox->LogicalDeviceInfo.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_PhysicalDeviceInfo executes a DAC960 V2 Firmware Controller Physical
+  Device Information Reading IOCTL Command and waits for completion.  It
+  returns true on success and false on failure.
+*/
+
+static boolean DAC960_V2_PhysicalDeviceInfo(DAC960_Controller_T *Controller,
+					    DAC960_V2_IOCTL_Opcode_T
+					      IOCTL_Opcode,
+					    unsigned char Channel,
+					    unsigned char TargetID,
+					    unsigned char LogicalUnit,
+					    void *DataPointer,
+					    unsigned int DataByteCount)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .DataTransferControllerToHost = true;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .NoAutoRequestSense = true;
+  CommandMailbox->PhysicalDeviceInfo.DataTransferSize = DataByteCount;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit = LogicalUnit;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
+  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+				    .ScatterGatherSegments[0]
+				    .SegmentDataPointer =
+    Virtual_to_Bus(DataPointer);
+  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+				    .ScatterGatherSegments[0]
+				    .SegmentByteCount =
+    CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_DeviceOperation executes a DAC960 V2 Firmware Controller Device
+  Operation IOCTL Command and waits for completion.  It returns true on
+  success and false on failure.
+*/
+
+static boolean DAC960_V2_DeviceOperation(DAC960_Controller_T *Controller,
+					 DAC960_V2_IOCTL_Opcode_T IOCTL_Opcode,
+					 DAC960_V2_OperationDevice_T
+					   OperationDevice)
+{
+  DAC960_Command_T *Command = DAC960_AllocateCommand(Controller);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox->DeviceOperation.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->DeviceOperation.CommandControlBits
+				 .DataTransferControllerToHost = true;
+  CommandMailbox->DeviceOperation.CommandControlBits
+    				 .NoAutoRequestSense = true;
+  CommandMailbox->DeviceOperation.IOCTL_Opcode = IOCTL_Opcode;
+  CommandMailbox->DeviceOperation.OperationDevice = OperationDevice;
+  DAC960_ExecuteCommand(Command);
+  CommandStatus = Command->V2.CommandStatus;
+  DAC960_DeallocateCommand(Command);
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V1_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
+  for DAC960 V1 Firmware Controllers.
+*/
+
+static boolean DAC960_V1_EnableMemoryMailboxInterface(DAC960_Controller_T
+						      *Controller)
 {
   void *ControllerBaseAddress = Controller->BaseAddress;
-  DAC960_CommandMailbox_T *CommandMailboxesMemory;
-  DAC960_StatusMailbox_T *StatusMailboxesMemory;
-  DAC960_CommandMailbox_T CommandMailbox;
-  DAC960_CommandStatus_T CommandStatus;
+  DAC960_V1_CommandMailbox_T *CommandMailboxesMemory;
+  DAC960_V1_StatusMailbox_T *StatusMailboxesMemory;
+  DAC960_V1_CommandMailbox_T CommandMailbox;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  unsigned long MemoryMailboxPagesAddress;
+  unsigned long MemoryMailboxPagesOrder;
+  unsigned long MemoryMailboxPagesSize;
   void *SavedMemoryMailboxesAddress = NULL;
   short NextCommandMailboxIndex = 0;
   short NextStatusMailboxIndex = 0;
   int TimeoutCounter = 1000000, i;
-  if (Controller->ControllerType == DAC960_V5_Controller)
-    DAC960_V5_RestoreMemoryMailboxInfo(Controller,
+  MemoryMailboxPagesOrder = 0;
+  MemoryMailboxPagesSize =
+    DAC960_V1_CommandMailboxCount * sizeof(DAC960_V1_CommandMailbox_T) +
+    DAC960_V1_StatusMailboxCount * sizeof(DAC960_V1_StatusMailbox_T);
+  while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
+    MemoryMailboxPagesOrder++;
+  if (Controller->HardwareType == DAC960_LA_Controller)
+    DAC960_LA_RestoreMemoryMailboxInfo(Controller,
 				       &SavedMemoryMailboxesAddress,
 				       &NextCommandMailboxIndex,
 				       &NextStatusMailboxIndex);
-  else DAC960_V4_RestoreMemoryMailboxInfo(Controller,
+  else DAC960_PG_RestoreMemoryMailboxInfo(Controller,
 					  &SavedMemoryMailboxesAddress,
 					  &NextCommandMailboxIndex,
 					  &NextStatusMailboxIndex);
   if (SavedMemoryMailboxesAddress == NULL)
-    CommandMailboxesMemory =
-      (DAC960_CommandMailbox_T *) __get_free_pages(GFP_KERNEL, 1);
+    {
+      MemoryMailboxPagesAddress =
+	__get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
+      Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
+      CommandMailboxesMemory =
+	(DAC960_V1_CommandMailbox_T *) MemoryMailboxPagesAddress;
+    }
   else CommandMailboxesMemory = SavedMemoryMailboxesAddress;
-  memset(CommandMailboxesMemory, 0, PAGE_SIZE << 1);
-  Controller->FirstCommandMailbox = CommandMailboxesMemory;
-  CommandMailboxesMemory += DAC960_CommandMailboxCount - 1;
-  Controller->LastCommandMailbox = CommandMailboxesMemory;
-  Controller->NextCommandMailbox =
-    &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+  if (CommandMailboxesMemory == NULL) return false;
+  Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
+  memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+  Controller->V1.FirstCommandMailbox = CommandMailboxesMemory;
+  CommandMailboxesMemory += DAC960_V1_CommandMailboxCount - 1;
+  Controller->V1.LastCommandMailbox = CommandMailboxesMemory;
+  Controller->V1.NextCommandMailbox =
+    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
   if (--NextCommandMailboxIndex < 0)
-    NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
-  Controller->PreviousCommandMailbox1 =
-    &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+    NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+  Controller->V1.PreviousCommandMailbox1 =
+    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
   if (--NextCommandMailboxIndex < 0)
-    NextCommandMailboxIndex = DAC960_CommandMailboxCount - 1;
-  Controller->PreviousCommandMailbox2 =
-    &Controller->FirstCommandMailbox[NextCommandMailboxIndex];
+    NextCommandMailboxIndex = DAC960_V1_CommandMailboxCount - 1;
+  Controller->V1.PreviousCommandMailbox2 =
+    &Controller->V1.FirstCommandMailbox[NextCommandMailboxIndex];
   StatusMailboxesMemory =
-    (DAC960_StatusMailbox_T *) (CommandMailboxesMemory + 1);
-  Controller->FirstStatusMailbox = StatusMailboxesMemory;
-  StatusMailboxesMemory += DAC960_StatusMailboxCount - 1;
-  Controller->LastStatusMailbox = StatusMailboxesMemory;
-  Controller->NextStatusMailbox =
-    &Controller->FirstStatusMailbox[NextStatusMailboxIndex];
+    (DAC960_V1_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+  Controller->V1.FirstStatusMailbox = StatusMailboxesMemory;
+  StatusMailboxesMemory += DAC960_V1_StatusMailboxCount - 1;
+  Controller->V1.LastStatusMailbox = StatusMailboxesMemory;
+  Controller->V1.NextStatusMailbox =
+    &Controller->V1.FirstStatusMailbox[NextStatusMailboxIndex];
   if (SavedMemoryMailboxesAddress != NULL) return true;
   /* Enable the Memory Mailbox Interface. */
-  Controller->DualModeMemoryMailboxInterface = true;
+  Controller->V1.DualModeMemoryMailboxInterface = true;
   CommandMailbox.TypeX.CommandOpcode = 0x2B;
   CommandMailbox.TypeX.CommandIdentifier = 0;
   CommandMailbox.TypeX.CommandOpcode2 = 0x14;
   CommandMailbox.TypeX.CommandMailboxesBusAddress =
-    Virtual_to_Bus(Controller->FirstCommandMailbox);
+    Virtual_to_Bus(Controller->V1.FirstCommandMailbox);
   CommandMailbox.TypeX.StatusMailboxesBusAddress =
-    Virtual_to_Bus(Controller->FirstStatusMailbox);
+    Virtual_to_Bus(Controller->V1.FirstStatusMailbox);
   for (i = 0; i < 2; i++)
-    switch (Controller->ControllerType)
+    switch (Controller->HardwareType)
       {
-      case DAC960_V5_Controller:
+      case DAC960_LA_Controller:
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (!DAC960_V5_HardwareMailboxFullP(ControllerBaseAddress))
+	    if (!DAC960_LA_HardwareMailboxFullP(ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	DAC960_V5_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
-	DAC960_V5_HardwareMailboxNewCommand(ControllerBaseAddress);
+	DAC960_LA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+	DAC960_LA_HardwareMailboxNewCommand(ControllerBaseAddress);
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (DAC960_V5_HardwareMailboxStatusAvailableP(
+	    if (DAC960_LA_HardwareMailboxStatusAvailableP(
 		  ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	CommandStatus = DAC960_V5_ReadStatusRegister(ControllerBaseAddress);
-	DAC960_V5_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
-	DAC960_V5_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
-	if (CommandStatus == DAC960_NormalCompletion) return true;
-	Controller->DualModeMemoryMailboxInterface = false;
+	CommandStatus = DAC960_LA_ReadStatusRegister(ControllerBaseAddress);
+	DAC960_LA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+	DAC960_LA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+	if (CommandStatus == DAC960_V1_NormalCompletion) return true;
+	Controller->V1.DualModeMemoryMailboxInterface = false;
 	CommandMailbox.TypeX.CommandOpcode2 = 0x10;
 	break;
-      case DAC960_V4_Controller:
+      case DAC960_PG_Controller:
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (!DAC960_V4_HardwareMailboxFullP(ControllerBaseAddress))
+	    if (!DAC960_PG_HardwareMailboxFullP(ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	DAC960_V4_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
-	DAC960_V4_HardwareMailboxNewCommand(ControllerBaseAddress);
+	DAC960_PG_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+	DAC960_PG_HardwareMailboxNewCommand(ControllerBaseAddress);
 	while (--TimeoutCounter >= 0)
 	  {
-	    if (DAC960_V4_HardwareMailboxStatusAvailableP(
+	    if (DAC960_PG_HardwareMailboxStatusAvailableP(
 		  ControllerBaseAddress))
 	      break;
 	    udelay(10);
 	  }
 	if (TimeoutCounter < 0) return false;
-	CommandStatus = DAC960_V4_ReadStatusRegister(ControllerBaseAddress);
-	DAC960_V4_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
-	DAC960_V4_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
-	if (CommandStatus == DAC960_NormalCompletion) return true;
-	Controller->DualModeMemoryMailboxInterface = false;
+	CommandStatus = DAC960_PG_ReadStatusRegister(ControllerBaseAddress);
+	DAC960_PG_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+	DAC960_PG_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
+	if (CommandStatus == DAC960_V1_NormalCompletion) return true;
+	Controller->V1.DualModeMemoryMailboxInterface = false;
 	CommandMailbox.TypeX.CommandOpcode2 = 0x10;
 	break;
       default:
@@ -510,283 +895,165 @@
 
 
 /*
-  DAC960_DetectControllers detects DAC960 PCI RAID Controllers by interrogating
-  the PCI Configuration Space for Controller Type.
+  DAC960_V2_EnableMemoryMailboxInterface enables the Memory Mailbox Interface
+  for DAC960 V2 Firmware Controllers.
 */
 
-static void DAC960_DetectControllers(DAC960_ControllerType_T ControllerType)
+static boolean DAC960_V2_EnableMemoryMailboxInterface(DAC960_Controller_T
+						      *Controller)
 {
-  unsigned short VendorID = 0, DeviceID = 0;
-  unsigned int MemoryWindowSize = 0;
-  PCI_Device_T *PCI_Device = NULL;
-  switch (ControllerType)
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_CommandMailbox_T *CommandMailboxesMemory;
+  DAC960_V2_StatusMailbox_T *StatusMailboxesMemory;
+  DAC960_V2_CommandMailbox_T CommandMailbox;
+  DAC960_V2_CommandStatus_T CommandStatus = 0;
+  unsigned long MemoryMailboxPagesAddress;
+  unsigned long MemoryMailboxPagesOrder;
+  unsigned long MemoryMailboxPagesSize;
+  MemoryMailboxPagesOrder = 0;
+  MemoryMailboxPagesSize =
+    DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T) +
+    DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T) +
+    sizeof(DAC960_V2_HealthStatusBuffer_T);
+  while (MemoryMailboxPagesSize > PAGE_SIZE << MemoryMailboxPagesOrder)
+    MemoryMailboxPagesOrder++;
+  MemoryMailboxPagesAddress =
+    __get_free_pages(GFP_KERNEL, MemoryMailboxPagesOrder);
+  Controller->MemoryMailboxPagesAddress = MemoryMailboxPagesAddress;
+  CommandMailboxesMemory =
+    (DAC960_V2_CommandMailbox_T *) MemoryMailboxPagesAddress;
+  if (CommandMailboxesMemory == NULL) return false;
+  Controller->MemoryMailboxPagesOrder = MemoryMailboxPagesOrder;
+  memset(CommandMailboxesMemory, 0, MemoryMailboxPagesSize);
+  Controller->V2.FirstCommandMailbox = CommandMailboxesMemory;
+  CommandMailboxesMemory += DAC960_V2_CommandMailboxCount - 1;
+  Controller->V2.LastCommandMailbox = CommandMailboxesMemory;
+  Controller->V2.NextCommandMailbox = Controller->V2.FirstCommandMailbox;
+  Controller->V2.PreviousCommandMailbox1 = Controller->V2.LastCommandMailbox;
+  Controller->V2.PreviousCommandMailbox2 =
+    Controller->V2.LastCommandMailbox - 1;
+  StatusMailboxesMemory =
+    (DAC960_V2_StatusMailbox_T *) (CommandMailboxesMemory + 1);
+  Controller->V2.FirstStatusMailbox = StatusMailboxesMemory;
+  StatusMailboxesMemory += DAC960_V2_StatusMailboxCount - 1;
+  Controller->V2.LastStatusMailbox = StatusMailboxesMemory;
+  Controller->V2.NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+  Controller->V2.HealthStatusBuffer =
+    (DAC960_V2_HealthStatusBuffer_T *) (StatusMailboxesMemory + 1);
+  /* Enable the Memory Mailbox Interface. */
+  memset(&CommandMailbox, 0, sizeof(DAC960_V2_CommandMailbox_T));
+  CommandMailbox.SetMemoryMailbox.CommandIdentifier = 1;
+  CommandMailbox.SetMemoryMailbox.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox.SetMemoryMailbox.CommandControlBits.NoAutoRequestSense = true;
+  CommandMailbox.SetMemoryMailbox.FirstCommandMailboxSizeKB =
+    (DAC960_V2_CommandMailboxCount * sizeof(DAC960_V2_CommandMailbox_T)) >> 10;
+  CommandMailbox.SetMemoryMailbox.FirstStatusMailboxSizeKB =
+    (DAC960_V2_StatusMailboxCount * sizeof(DAC960_V2_StatusMailbox_T)) >> 10;
+  CommandMailbox.SetMemoryMailbox.SecondCommandMailboxSizeKB = 0;
+  CommandMailbox.SetMemoryMailbox.SecondStatusMailboxSizeKB = 0;
+  CommandMailbox.SetMemoryMailbox.RequestSenseSize = 0;
+  CommandMailbox.SetMemoryMailbox.IOCTL_Opcode = DAC960_V2_SetMemoryMailbox;
+  CommandMailbox.SetMemoryMailbox.HealthStatusBufferSizeKB = 1;
+  CommandMailbox.SetMemoryMailbox.HealthStatusBufferBusAddress =
+    Virtual_to_Bus(Controller->V2.HealthStatusBuffer);
+  CommandMailbox.SetMemoryMailbox.FirstCommandMailboxBusAddress =
+    Virtual_to_Bus(Controller->V2.FirstCommandMailbox);
+  CommandMailbox.SetMemoryMailbox.FirstStatusMailboxBusAddress =
+    Virtual_to_Bus(Controller->V2.FirstStatusMailbox);
+  switch (Controller->HardwareType)
     {
-    case DAC960_V5_Controller:
-      VendorID = PCI_VENDOR_ID_DEC;
-      DeviceID = PCI_DEVICE_ID_DEC_21285;
-      MemoryWindowSize = DAC960_V5_RegisterWindowSize;
+    case DAC960_BA_Controller:
+      while (DAC960_BA_HardwareMailboxFullP(ControllerBaseAddress))
+	udelay(1);
+      DAC960_BA_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+      DAC960_BA_HardwareMailboxNewCommand(ControllerBaseAddress);
+      while (!DAC960_BA_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+	udelay(1);
+      CommandStatus = DAC960_BA_ReadCommandStatus(ControllerBaseAddress);
+      DAC960_BA_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+      DAC960_BA_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
       break;
-    case DAC960_V4_Controller:
-      VendorID = PCI_VENDOR_ID_MYLEX;
-      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V4;
-      MemoryWindowSize = DAC960_V4_RegisterWindowSize;
+    case DAC960_LP_Controller:
+      while (DAC960_LP_HardwareMailboxFullP(ControllerBaseAddress))
+	udelay(1);
+      DAC960_LP_WriteHardwareMailbox(ControllerBaseAddress, &CommandMailbox);
+      DAC960_LP_HardwareMailboxNewCommand(ControllerBaseAddress);
+      while (!DAC960_LP_HardwareMailboxStatusAvailableP(ControllerBaseAddress))
+	udelay(1);
+      CommandStatus = DAC960_LP_ReadCommandStatus(ControllerBaseAddress);
+      DAC960_LP_AcknowledgeHardwareMailboxInterrupt(ControllerBaseAddress);
+      DAC960_LP_AcknowledgeHardwareMailboxStatus(ControllerBaseAddress);
       break;
-    case DAC960_V3_Controller:
-      VendorID = PCI_VENDOR_ID_MYLEX;
-      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960P_V3;
-      MemoryWindowSize = DAC960_V3_RegisterWindowSize;
+    default:
       break;
     }
-  while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
+  return (CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V1_ReadControllerConfiguration reads the Configuration Information
+  from DAC960 V1 Firmware Controllers and initializes the Controller structure.
+*/
+
+static boolean DAC960_V1_ReadControllerConfiguration(DAC960_Controller_T
+						     *Controller)
+{
+  DAC960_V1_Enquiry2_T Enquiry2;
+  DAC960_V1_Config2_T Config2;
+  int LogicalDriveNumber, Channel, TargetID;
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry,
+			      &Controller->V1.Enquiry))
+    return DAC960_Failure(Controller, "ENQUIRY");
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_Enquiry2, &Enquiry2))
+    return DAC960_Failure(Controller, "ENQUIRY2");
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_ReadConfig2, &Config2))
+    return DAC960_Failure(Controller, "READ CONFIG2");
+  if (!DAC960_V1_ExecuteType3(Controller, DAC960_V1_GetLogicalDriveInformation,
+			      &Controller->V1.LogicalDriveInformation))
+    return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
+  for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
+    for (TargetID = 0; TargetID < Enquiry2.MaxTargets; TargetID++)
+      if (!DAC960_V1_ExecuteType3D(Controller, DAC960_V1_GetDeviceState,
+				   Channel, TargetID,
+				   &Controller->V1.DeviceState
+						   [Channel][TargetID]))
+	return DAC960_Failure(Controller, "GET DEVICE STATE");
+  /*
+    Initialize the Controller Model Name and Full Model Name fields.
+  */
+  switch (Enquiry2.HardwareID.SubModel)
     {
-      DAC960_Controller_T *Controller = (DAC960_Controller_T *)
-	kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
-      DAC960_IO_Address_T IO_Address = 0;
-      DAC960_PCI_Address_T PCI_Address = 0;
-      unsigned char Bus = PCI_Device->bus->number;
-      unsigned char DeviceFunction = PCI_Device->devfn;
-      unsigned char Device = DeviceFunction >> 3;
-      unsigned char Function = DeviceFunction & 0x7;
-      unsigned char ErrorStatus, Parameter0, Parameter1;
-      unsigned int IRQ_Channel = PCI_Device->irq;
-      unsigned long BaseAddress0 = PCI_Device->base_address[0];
-      unsigned long BaseAddress1 = PCI_Device->base_address[1];
-      unsigned short SubsystemVendorID, SubsystemDeviceID;
-      int CommandIdentifier;
-      void *BaseAddress;
-      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_VENDOR_ID,
-			   &SubsystemVendorID);
-      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_ID,
-			   &SubsystemDeviceID);
-      switch (ControllerType)
-	{
-	case DAC960_V5_Controller:
-	  if (!(SubsystemVendorID == PCI_VENDOR_ID_MYLEX &&
-		SubsystemDeviceID == PCI_DEVICE_ID_MYLEX_DAC960P_V5))
-	    goto Ignore;
-	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
-	  break;
-	case DAC960_V4_Controller:
-	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
-	  break;
-	case DAC960_V3_Controller:
-	  IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
-	  PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
-	  break;
-	}
-      if (DAC960_ControllerCount == DAC960_MaxControllers)
-	{
-	  DAC960_Error("More than %d DAC960 Controllers detected - "
-		       "ignoring from Controller at\n",
-		       NULL, DAC960_MaxControllers);
-	  goto Ignore;
-	}
-      if (Controller == NULL)
-	{
-	  DAC960_Error("Unable to allocate Controller structure for "
-		       "Controller at\n", NULL);
-	  goto Ignore;
-	}
-      memset(Controller, 0, sizeof(DAC960_Controller_T));
-      Controller->ControllerNumber = DAC960_ControllerCount;
-      DAC960_Controllers[DAC960_ControllerCount++] = Controller;
-      DAC960_AnnounceDriver(Controller);
-      Controller->ControllerType = ControllerType;
-      Controller->IO_Address = IO_Address;
-      Controller->PCI_Address = PCI_Address;
-      Controller->Bus = Bus;
-      Controller->Device = Device;
-      Controller->Function = Function;
-      sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
-      /*
-	Map the Controller Register Window.
-      */
-      if (MemoryWindowSize < PAGE_SIZE)
-	MemoryWindowSize = PAGE_SIZE;
-      Controller->MemoryMappedAddress =
-	ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
-      Controller->BaseAddress =
-	Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
-      if (Controller->MemoryMappedAddress == NULL)
-	{
-	  DAC960_Error("Unable to map Controller Register Window for "
-		       "Controller at\n", Controller);
-	  goto Failure;
-	}
-      BaseAddress = Controller->BaseAddress;
-      switch (ControllerType)
-	{
-	case DAC960_V5_Controller:
-	  DAC960_V5_DisableInterrupts(BaseAddress);
-	  DAC960_V5_AcknowledgeHardwareMailboxStatus(BaseAddress);
-	  udelay(1000);
-	  while (DAC960_V5_InitializationInProgressP(BaseAddress))
-	    {
-	      if (DAC960_V5_ReadErrorStatus(BaseAddress, &ErrorStatus,
-					    &Parameter0, &Parameter1) &&
-		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
-					   Parameter0, Parameter1))
-		goto Failure;
-	      udelay(10);
-	    }
-	  if (!DAC960_EnableMemoryMailboxInterface(Controller))
-	    {
-	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
-			   "for Controller at\n", Controller);
-	      goto Failure;
-	    }
-	  DAC960_V5_EnableInterrupts(BaseAddress);
-	  break;
-	case DAC960_V4_Controller:
-	  DAC960_V4_DisableInterrupts(BaseAddress);
-	  DAC960_V4_AcknowledgeHardwareMailboxStatus(BaseAddress);
-	  udelay(1000);
-	  while (DAC960_V4_InitializationInProgressP(BaseAddress))
-	    {
-	      if (DAC960_V4_ReadErrorStatus(BaseAddress, &ErrorStatus,
-					    &Parameter0, &Parameter1) &&
-		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
-					   Parameter0, Parameter1))
-		goto Failure;
-	      udelay(10);
-	    }
-	  if (!DAC960_EnableMemoryMailboxInterface(Controller))
-	    {
-	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
-			   "for Controller at\n", Controller);
-	      goto Failure;
-	    }
-	  DAC960_V4_EnableInterrupts(BaseAddress);
-	  break;
-	case DAC960_V3_Controller:
-	  request_region(Controller->IO_Address, 0x80,
-			 Controller->FullModelName);
-	  DAC960_V3_DisableInterrupts(BaseAddress);
-	  DAC960_V3_AcknowledgeStatus(BaseAddress);
-	  udelay(1000);
-	  while (DAC960_V3_InitializationInProgressP(BaseAddress))
-	    {
-	      if (DAC960_V3_ReadErrorStatus(BaseAddress, &ErrorStatus,
-					    &Parameter0, &Parameter1) &&
-		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
-					   Parameter0, Parameter1))
-		goto Failure;
-	      udelay(10);
-	    }
-	  DAC960_V3_EnableInterrupts(BaseAddress);
-	  break;
-	}
-      /*
-	Acquire shared access to the IRQ Channel.
-      */
-      if (IRQ_Channel == 0)
-	{
-	  DAC960_Error("IRQ Channel %d illegal for Controller at\n",
-		       Controller, IRQ_Channel);
-	  goto Failure;
-	}
-      strcpy(Controller->FullModelName, "DAC960");
-      if (request_irq(IRQ_Channel, DAC960_InterruptHandler,
-		      SA_SHIRQ, Controller->FullModelName, Controller) < 0)
-	{
-	  DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
-		       Controller, IRQ_Channel);
-	  goto Failure;
-	}
-      Controller->IRQ_Channel = IRQ_Channel;
-      DAC960_ActiveControllerCount++;
-      for (CommandIdentifier = 0;
-	   CommandIdentifier < DAC960_MaxChannels;
-	   CommandIdentifier++)
-	{
-	  Controller->Commands[CommandIdentifier].Controller = Controller;
-	  Controller->Commands[CommandIdentifier].Next =
-	    Controller->FreeCommands;
-	  Controller->FreeCommands = &Controller->Commands[CommandIdentifier];
-	}
-      continue;
-    Failure:
-      if (IO_Address == 0)
-	DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
-		     "PCI Address 0x%X\n", Controller,
-		     Bus, Device, Function, PCI_Address);
-      else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
-			"0x%X PCI Address 0x%X\n", Controller,
-			Bus, Device, Function, IO_Address, PCI_Address);
-      if (Controller == NULL) break;
-      if (Controller->MemoryMappedAddress != NULL)
-	iounmap(Controller->MemoryMappedAddress);
-      DAC960_Controllers[Controller->ControllerNumber] = NULL;
-      if (Controller->IRQ_Channel > 0)
-	free_irq(IRQ_Channel, Controller);
-    Ignore:
-      kfree(Controller);
-    }
-}
-
-
-/*
-  DAC960_ReadControllerConfiguration reads the Configuration Information
-  from Controller and initializes the Controller structure.
-*/
-
-static boolean DAC960_ReadControllerConfiguration(DAC960_Controller_T
-						  *Controller)
-{
-  DAC960_Enquiry2_T Enquiry2;
-  DAC960_Config2_T Config2;
-  int LogicalDriveNumber, Channel, TargetID;
-  if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry,
-			   &Controller->Enquiry[0]))
-    return DAC960_Failure(Controller, "ENQUIRY");
-  if (!DAC960_ExecuteType3(Controller, DAC960_Enquiry2, &Enquiry2))
-    return DAC960_Failure(Controller, "ENQUIRY2");
-  if (!DAC960_ExecuteType3(Controller, DAC960_ReadConfig2, &Config2))
-    return DAC960_Failure(Controller, "READ CONFIG2");
-  if (!DAC960_ExecuteType3(Controller, DAC960_GetLogicalDriveInformation,
-			   &Controller->LogicalDriveInformation[0]))
-    return DAC960_Failure(Controller, "GET LOGICAL DRIVE INFORMATION");
-  for (Channel = 0; Channel < Enquiry2.ActualChannels; Channel++)
-    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
-      if (!DAC960_ExecuteType3D(Controller, DAC960_GetDeviceState,
-				Channel, TargetID,
-				&Controller->DeviceState[0][Channel][TargetID]))
-	return DAC960_Failure(Controller, "GET DEVICE STATE");
-  /*
-    Initialize the Controller Model Name and Full Model Name fields.
-  */
-  switch (Enquiry2.HardwareID.SubModel)
-    {
-    case DAC960_P_PD_PU:
-      if (Enquiry2.SCSICapability.BusSpeed == DAC960_Ultra)
+    case DAC960_V1_P_PD_PU:
+      if (Enquiry2.SCSICapability.BusSpeed == DAC960_V1_Ultra)
 	strcpy(Controller->ModelName, "DAC960PU");
       else strcpy(Controller->ModelName, "DAC960PD");
       break;
-    case DAC960_PL:
+    case DAC960_V1_PL:
       strcpy(Controller->ModelName, "DAC960PL");
       break;
-    case DAC960_PG:
+    case DAC960_V1_PG:
       strcpy(Controller->ModelName, "DAC960PG");
       break;
-    case DAC960_PJ:
+    case DAC960_V1_PJ:
       strcpy(Controller->ModelName, "DAC960PJ");
       break;
-    case DAC960_PR:
+    case DAC960_V1_PR:
       strcpy(Controller->ModelName, "DAC960PR");
       break;
-    case DAC960_PT:
+    case DAC960_V1_PT:
       strcpy(Controller->ModelName, "DAC960PT");
       break;
-    case DAC960_PTL0:
+    case DAC960_V1_PTL0:
       strcpy(Controller->ModelName, "DAC960PTL0");
       break;
-    case DAC960_PRL:
+    case DAC960_V1_PRL:
       strcpy(Controller->ModelName, "DAC960PRL");
       break;
-    case DAC960_PTL1:
+    case DAC960_V1_PTL1:
       strcpy(Controller->ModelName, "DAC960PTL1");
       break;
-    case DAC1164_P:
+    case DAC960_V1_1164P:
       strcpy(Controller->ModelName, "DAC1164P");
       break;
     default:
@@ -818,61 +1085,197 @@
       return false;
     }
   /*
-    Initialize the Controller Channels, Memory Size, and SAF-TE Enclosure
-    Management Enabled fields.
+    Initialize the Controller Channels, Targets, Memory Size, and SAF-TE
+    Enclosure Management Enabled fields.
   */
   Controller->Channels = Enquiry2.ActualChannels;
+  Controller->Targets = Enquiry2.MaxTargets;
   Controller->MemorySize = Enquiry2.MemorySize >> 20;
-  Controller->SAFTE_EnclosureManagementEnabled =
-    Enquiry2.FaultManagementType == DAC960_SAFTE;
+  Controller->V1.SAFTE_EnclosureManagementEnabled =
+    (Enquiry2.FaultManagementType == DAC960_V1_SAFTE);
   /*
     Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
-    Count, Maximum Blocks per Command, and Maximum Scatter/Gather Segments.
-    The Driver Queue Depth must be at most one less than the Controller Queue
-    Depth to allow for an automatic drive rebuild operation.
+    Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
+    Driver Scatter/Gather Limit.  The Driver Queue Depth must be at most one
+    less than the Controller Queue Depth to allow for an automatic drive
+    rebuild operation.
   */
-  Controller->ControllerQueueDepth = Controller->Enquiry[0].MaxCommands;
+  Controller->ControllerQueueDepth = Controller->V1.Enquiry.MaxCommands;
   Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
-  Controller->LogicalDriveCount = Controller->Enquiry[0].NumberOfLogicalDrives;
+  if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
+    Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
+  Controller->LogicalDriveCount =
+    Controller->V1.Enquiry.NumberOfLogicalDrives;
   Controller->MaxBlocksPerCommand = Enquiry2.MaxBlocksPerCommand;
-  Controller->MaxScatterGatherSegments = Enquiry2.MaxScatterGatherEntries;
+  Controller->ControllerScatterGatherLimit = Enquiry2.MaxScatterGatherEntries;
+  Controller->DriverScatterGatherLimit =
+    Controller->ControllerScatterGatherLimit;
+  if (Controller->DriverScatterGatherLimit > DAC960_V1_ScatterGatherLimit)
+    Controller->DriverScatterGatherLimit = DAC960_V1_ScatterGatherLimit;
   /*
     Initialize the Stripe Size, Segment Size, and Geometry Translation.
   */
-  Controller->StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
-			   >> (10 - DAC960_BlockSizeBits);
-  Controller->SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
-			    >> (10 - DAC960_BlockSizeBits);
+  Controller->V1.StripeSize = Config2.BlocksPerStripe * Config2.BlockFactor
+			      >> (10 - DAC960_BlockSizeBits);
+  Controller->V1.SegmentSize = Config2.BlocksPerCacheLine * Config2.BlockFactor
+			       >> (10 - DAC960_BlockSizeBits);
   switch (Config2.DriveGeometry)
     {
-    case DAC960_Geometry_128_32:
-      Controller->GeometryTranslationHeads = 128;
-      Controller->GeometryTranslationSectors = 32;
-      break;
-    case DAC960_Geometry_255_63:
-      Controller->GeometryTranslationHeads = 255;
-      Controller->GeometryTranslationSectors = 63;
+    case DAC960_V1_Geometry_128_32:
+      Controller->V1.GeometryTranslationHeads = 128;
+      Controller->V1.GeometryTranslationSectors = 32;
+      break;
+    case DAC960_V1_Geometry_255_63:
+      Controller->V1.GeometryTranslationHeads = 255;
+      Controller->V1.GeometryTranslationSectors = 63;
       break;
     default:
       return DAC960_Failure(Controller, "CONFIG2 DRIVE GEOMETRY");
     }
   /*
-    Initialize the Logical Drive Initial State.
+    Initialize the Logical Drive Initially Accessible flag.
   */
   for (LogicalDriveNumber = 0;
        LogicalDriveNumber < Controller->LogicalDriveCount;
        LogicalDriveNumber++)
-    Controller->LogicalDriveInitialState[LogicalDriveNumber] =
-      Controller->LogicalDriveInformation[0]
-		  [LogicalDriveNumber].LogicalDriveState;
-  Controller->LastRebuildStatus = DAC960_NoRebuildOrCheckInProgress;
+    if (Controller->V1.LogicalDriveInformation
+		       [LogicalDriveNumber].LogicalDriveState !=
+	DAC960_V1_LogicalDrive_Offline)
+      Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
+  Controller->V1.LastRebuildStatus = DAC960_V1_NoRebuildOrCheckInProgress;
   return true;
 }
 
 
 /*
-  DAC960_ReportControllerConfiguration reports the Configuration Information of
-  Controller.
+  DAC960_V2_ReadControllerConfiguration reads the Configuration Information
+  from DAC960 V2 Firmware Controllers and initializes the Controller structure.
+*/
+
+static boolean DAC960_V2_ReadControllerConfiguration(DAC960_Controller_T
+						     *Controller)
+{
+  DAC960_V2_ControllerInfo_T *ControllerInfo =
+    &Controller->V2.ControllerInformation;
+  unsigned short LogicalDeviceNumber = 0;
+  int ModelNameLength;
+  if (!DAC960_V2_ControllerInfo(Controller, DAC960_V2_GetControllerInfo,
+				ControllerInfo,
+				sizeof(DAC960_V2_ControllerInfo_T)))
+    return DAC960_Failure(Controller, "GET CONTROLLER INFO");
+  if (!DAC960_V2_GeneralInfo(Controller, DAC960_V2_GetHealthStatus,
+			     Controller->V2.HealthStatusBuffer,
+			     sizeof(DAC960_V2_HealthStatusBuffer_T)))
+    return DAC960_Failure(Controller, "GET HEALTH STATUS");
+  /*
+    Initialize the Controller Model Name and Full Model Name fields.
+  */
+  ModelNameLength = sizeof(ControllerInfo->ControllerName);
+  if (ModelNameLength > sizeof(Controller->ModelName)-1)
+    ModelNameLength = sizeof(Controller->ModelName)-1;
+  memcpy(Controller->ModelName, ControllerInfo->ControllerName,
+	 ModelNameLength);
+  ModelNameLength--;
+  while (Controller->ModelName[ModelNameLength] == ' ' ||
+	 Controller->ModelName[ModelNameLength] == '\0')
+    ModelNameLength--;
+  Controller->ModelName[++ModelNameLength] = '\0';
+  strcpy(Controller->FullModelName, "Mylex ");
+  strcat(Controller->FullModelName, Controller->ModelName);
+  /*
+    Initialize the Controller Firmware Version field.
+  */
+  sprintf(Controller->FirmwareVersion, "%d.%02d-%02d",
+	  ControllerInfo->FirmwareMajorVersion,
+	  ControllerInfo->FirmwareMinorVersion,
+	  ControllerInfo->FirmwareTurnNumber);
+  if (ControllerInfo->FirmwareMajorVersion == 6 &&
+      ControllerInfo->FirmwareMinorVersion == 0 &&
+      ControllerInfo->FirmwareTurnNumber < 1)
+    {
+      DAC960_Info("FIRMWARE VERSION %s DOES NOT PROVIDE THE CONTROLLER\n",
+		  Controller, Controller->FirmwareVersion);
+      DAC960_Info("STATUS MONITORING FUNCTIONALITY NEEDED BY THIS DRIVER.\n",
+		  Controller);
+      DAC960_Info("PLEASE UPGRADE TO VERSION 6.00-01 OR ABOVE.\n",
+		  Controller);
+    }
+  /*
+    Initialize the Controller Channels, Targets, and Memory Size.
+  */
+  Controller->Channels = ControllerInfo->NumberOfPhysicalChannelsPresent;
+  Controller->Targets =
+    ControllerInfo->MaximumTargetsPerChannel
+		    [ControllerInfo->NumberOfPhysicalChannelsPresent-1];
+  Controller->MemorySize = ControllerInfo->MemorySizeMB;
+  /*
+    Initialize the Controller Queue Depth, Driver Queue Depth, Logical Drive
+    Count, Maximum Blocks per Command, Controller Scatter/Gather Limit, and
+    Driver Scatter/Gather Limit.  The Driver Queue Depth must be at most one
+    less than the Controller Queue Depth to allow for an automatic drive
+    rebuild operation.
+  */
+  Controller->ControllerQueueDepth = ControllerInfo->MaximumParallelCommands;
+  Controller->DriverQueueDepth = Controller->ControllerQueueDepth - 1;
+  if (Controller->DriverQueueDepth > DAC960_MaxDriverQueueDepth)
+    Controller->DriverQueueDepth = DAC960_MaxDriverQueueDepth;
+  Controller->LogicalDriveCount = ControllerInfo->LogicalDevicesPresent;
+  Controller->MaxBlocksPerCommand =
+    ControllerInfo->MaximumDataTransferSizeInBlocks;
+  Controller->ControllerScatterGatherLimit =
+    ControllerInfo->MaximumScatterGatherEntries;
+  Controller->DriverScatterGatherLimit =
+    Controller->ControllerScatterGatherLimit;
+  if (Controller->DriverScatterGatherLimit > DAC960_V2_ScatterGatherLimit)
+    Controller->DriverScatterGatherLimit = DAC960_V2_ScatterGatherLimit;
+  /*
+    Initialize the Logical Device Information.
+  */
+  while (true)
+    {
+      DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
+	&Controller->V2.NewLogicalDeviceInformation;
+      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo;
+      DAC960_V2_PhysicalDevice_T PhysicalDevice;
+      if (!DAC960_V2_LogicalDeviceInfo(Controller,
+				       DAC960_V2_GetLogicalDeviceInfoValid,
+				       LogicalDeviceNumber,
+				       NewLogicalDeviceInfo,
+				       sizeof(DAC960_V2_LogicalDeviceInfo_T)))
+	break;
+      LogicalDeviceNumber = NewLogicalDeviceInfo->LogicalDeviceNumber;
+      if (LogicalDeviceNumber > DAC960_MaxLogicalDrives)
+	panic("DAC960: Logical Drive Number %d not supported\n",
+		       LogicalDeviceNumber);
+      if (NewLogicalDeviceInfo->DeviceBlockSizeInBytes != DAC960_BlockSize)
+	panic("DAC960: Logical Drive Block Size %d not supported\n",
+	      NewLogicalDeviceInfo->DeviceBlockSizeInBytes);
+      PhysicalDevice.Controller = 0;
+      PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
+      PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
+      PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
+      Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
+	PhysicalDevice;
+      if (NewLogicalDeviceInfo->LogicalDeviceState !=
+	  DAC960_V2_LogicalDevice_Offline)
+	Controller->LogicalDriveInitiallyAccessible[LogicalDeviceNumber] = true;
+      LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
+	kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+      if (LogicalDeviceInfo == NULL)
+	return DAC960_Failure(Controller, "LOGICAL DEVICE ALLOCATION");
+      Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
+	LogicalDeviceInfo;
+      memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
+	     sizeof(DAC960_V2_LogicalDeviceInfo_T));
+      LogicalDeviceNumber++;
+    }
+  return true;
+}
+
+
+/*
+  DAC960_ReportControllerConfiguration reports the Configuration Information
+  for Controller.
 */
 
 static boolean DAC960_ReportControllerConfiguration(DAC960_Controller_T
@@ -898,54 +1301,60 @@
 	      Controller, Controller->ControllerQueueDepth,
 	      Controller->MaxBlocksPerCommand);
   DAC960_Info("  Driver Queue Depth: %d, "
-	      "Maximum Scatter/Gather Segments: %d\n",
+	      "Scatter/Gather Limit: %d of %d Segments\n",
 	      Controller, Controller->DriverQueueDepth,
-	      Controller->MaxScatterGatherSegments);
-  DAC960_Info("  Stripe Size: %dKB, Segment Size: %dKB, "
-	      "BIOS Geometry: %d/%d\n", Controller,
-	      Controller->StripeSize,
-	      Controller->SegmentSize,
-	      Controller->GeometryTranslationHeads,
-	      Controller->GeometryTranslationSectors);
-  if (Controller->SAFTE_EnclosureManagementEnabled)
-    DAC960_Info("  SAF-TE Enclosure Management Enabled\n", Controller);
+	      Controller->DriverScatterGatherLimit,
+	      Controller->ControllerScatterGatherLimit);
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      DAC960_Info("  Stripe Size: %dKB, Segment Size: %dKB, "
+		  "BIOS Geometry: %d/%d\n", Controller,
+		  Controller->V1.StripeSize,
+		  Controller->V1.SegmentSize,
+		  Controller->V1.GeometryTranslationHeads,
+		  Controller->V1.GeometryTranslationSectors);
+      if (Controller->V1.SAFTE_EnclosureManagementEnabled)
+	DAC960_Info("  SAF-TE Enclosure Management Enabled\n", Controller);
+    }
   return true;
 }
 
 
 /*
-  DAC960_ReadDeviceConfiguration reads the Device Configuration Information by
-  requesting the SCSI Inquiry and SCSI Inquiry Unit Serial Number information
-  for each device connected to Controller.
+  DAC960_V1_ReadDeviceConfiguration reads the Device Configuration Information
+  for DAC960 V1 Firmware Controllers by requesting the SCSI Inquiry and SCSI
+  Inquiry Unit Serial Number information for each device connected to
+  Controller.
 */
 
-static boolean DAC960_ReadDeviceConfiguration(DAC960_Controller_T *Controller)
+static boolean DAC960_V1_ReadDeviceConfiguration(DAC960_Controller_T
+						 *Controller)
 {
-  DAC960_DCDB_T DCDBs[DAC960_MaxChannels], *DCDB;
-  Semaphore_T Semaphores[DAC960_MaxChannels], *Semaphore;
+  DAC960_V1_DCDB_T DCDBs[DAC960_V1_MaxChannels], *DCDB;
+  Semaphore_T Semaphores[DAC960_V1_MaxChannels], *Semaphore;
   unsigned long ProcessorFlags;
   int Channel, TargetID;
-  for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+  for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
     {
       for (Channel = 0; Channel < Controller->Channels; Channel++)
 	{
-	  DAC960_Command_T *Command = &Controller->Commands[Channel];
+	  DAC960_Command_T *Command = Controller->Commands[Channel];
 	  DAC960_SCSI_Inquiry_T *InquiryStandardData =
-	    &Controller->InquiryStandardData[Channel][TargetID];
+	    &Controller->V1.InquiryStandardData[Channel][TargetID];
 	  InquiryStandardData->PeripheralDeviceType = 0x1F;
 	  Semaphore = &Semaphores[Channel];
 	  *Semaphore = MUTEX_LOCKED;
 	  DCDB = &DCDBs[Channel];
-	  DAC960_ClearCommand(Command);
+	  DAC960_V1_ClearCommand(Command);
 	  Command->CommandType = DAC960_ImmediateCommand;
 	  Command->Semaphore = Semaphore;
-	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
-	  Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
+	  Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+	  Command->V1.CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
 	  DCDB->Channel = Channel;
 	  DCDB->TargetID = TargetID;
-	  DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
+	  DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
 	  DCDB->EarlyStatus = false;
-	  DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
+	  DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
 	  DCDB->NoAutomaticRequestSense = false;
 	  DCDB->DisconnectPermitted = true;
 	  DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
@@ -965,13 +1374,14 @@
 	}
       for (Channel = 0; Channel < Controller->Channels; Channel++)
 	{
-	  DAC960_Command_T *Command = &Controller->Commands[Channel];
+	  DAC960_Command_T *Command = Controller->Commands[Channel];
 	  DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
-	    &Controller->InquiryUnitSerialNumber[Channel][TargetID];
+	    &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
 	  InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
 	  Semaphore = &Semaphores[Channel];
 	  down(Semaphore);
-	  if (Command->CommandStatus != DAC960_NormalCompletion) continue;
+	  if (Command->V1.CommandStatus != DAC960_V1_NormalCompletion)
+	    continue;
 	  Command->Semaphore = Semaphore;
 	  DCDB = &DCDBs[Channel];
 	  DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
@@ -989,107 +1399,215 @@
 	  down(Semaphore);
 	}
     }
-  return true; 
+  return true;
+}
+
+
+/*
+  DAC960_V2_ReadDeviceConfiguration reads the Device Configuration Information
+  for DAC960 V2 Firmware Controllers by requesting the Physical Device
+  Information and SCSI Inquiry Unit Serial Number information for each
+  device connected to Controller.
+*/
+
+static boolean DAC960_V2_ReadDeviceConfiguration(DAC960_Controller_T
+						 *Controller)
+{
+  unsigned char Channel = 0, TargetID = 0, LogicalUnit = 0;
+  unsigned short PhysicalDeviceIndex = 0;
+  while (true)
+    {
+      DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
+	&Controller->V2.NewPhysicalDeviceInformation;
+      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo;
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
+      DAC960_Command_T *Command;
+      DAC960_V2_CommandMailbox_T *CommandMailbox;
+      if (!DAC960_V2_PhysicalDeviceInfo(Controller,
+					DAC960_V2_GetPhysicalDeviceInfoValid,
+					Channel,
+					TargetID,
+					LogicalUnit,
+					NewPhysicalDeviceInfo,
+					sizeof(DAC960_V2_PhysicalDeviceInfo_T)))
+	  break;
+      Channel = NewPhysicalDeviceInfo->Channel;
+      TargetID = NewPhysicalDeviceInfo->TargetID;
+      LogicalUnit = NewPhysicalDeviceInfo->LogicalUnit;
+      PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+	kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+      if (PhysicalDeviceInfo == NULL)
+	return DAC960_Failure(Controller, "PHYSICAL DEVICE ALLOCATION");
+      Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex] =
+	PhysicalDeviceInfo;
+      memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
+	     sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+      InquiryUnitSerialNumber = (DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
+	kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T), GFP_ATOMIC);
+      if (InquiryUnitSerialNumber == NULL)
+	return DAC960_Failure(Controller, "SERIAL NUMBER ALLOCATION");
+      Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex] =
+	InquiryUnitSerialNumber;
+      memset(InquiryUnitSerialNumber, 0,
+	     sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+      Command = DAC960_AllocateCommand(Controller);
+      CommandMailbox = &Command->V2.CommandMailbox;
+      DAC960_V2_ClearCommand(Command);
+      Command->CommandType = DAC960_ImmediateCommand;
+      CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10_Passthru;
+      CommandMailbox->SCSI_10.CommandControlBits
+			     .DataTransferControllerToHost = true;
+      CommandMailbox->SCSI_10.CommandControlBits
+			     .NoAutoRequestSense = true;
+      CommandMailbox->SCSI_10.DataTransferSize =
+	sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+      CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit = LogicalUnit;
+      CommandMailbox->SCSI_10.PhysicalDevice.TargetID = TargetID;
+      CommandMailbox->SCSI_10.PhysicalDevice.Channel = Channel;
+      CommandMailbox->SCSI_10.CDBLength = 6;
+      CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+      CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+      CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+      CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+      CommandMailbox->SCSI_10.SCSI_CDB[4] =
+	sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+      CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentDataPointer =
+	Virtual_to_Bus(InquiryUnitSerialNumber);
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentByteCount =
+	CommandMailbox->SCSI_10.DataTransferSize;
+      DAC960_ExecuteCommand(Command);
+      DAC960_DeallocateCommand(Command);
+      PhysicalDeviceIndex++;
+      LogicalUnit++;
+    }
+  return true;
+}
+
+
+/*
+  DAC960_SanitizeInquiryData sanitizes the Vendor, Model, Revision, and
+  Product Serial Number fields of the Inquiry Standard Data and Inquiry
+  Unit Serial Number structures.
+*/
+
+static void DAC960_SanitizeInquiryData(DAC960_SCSI_Inquiry_T
+					 *InquiryStandardData,
+				       DAC960_SCSI_Inquiry_UnitSerialNumber_T
+					 *InquiryUnitSerialNumber,
+				       unsigned char *Vendor,
+				       unsigned char *Model,
+				       unsigned char *Revision,
+				       unsigned char *SerialNumber)
+{
+  int SerialNumberLength, i;
+  if (InquiryStandardData->PeripheralDeviceType == 0x1F) return;
+  for (i = 0; i < sizeof(InquiryStandardData->VendorIdentification); i++)
+    {
+      unsigned char VendorCharacter =
+	InquiryStandardData->VendorIdentification[i];
+      Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
+		   ? VendorCharacter : ' ');
+    }
+  Vendor[sizeof(InquiryStandardData->VendorIdentification)] = '\0';
+  for (i = 0; i < sizeof(InquiryStandardData->ProductIdentification); i++)
+    {
+      unsigned char ModelCharacter =
+	InquiryStandardData->ProductIdentification[i];
+      Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
+		  ? ModelCharacter : ' ');
+    }
+  Model[sizeof(InquiryStandardData->ProductIdentification)] = '\0';
+  for (i = 0; i < sizeof(InquiryStandardData->ProductRevisionLevel); i++)
+    {
+      unsigned char RevisionCharacter =
+	InquiryStandardData->ProductRevisionLevel[i];
+      Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
+		     ? RevisionCharacter : ' ');
+    }
+  Revision[sizeof(InquiryStandardData->ProductRevisionLevel)] = '\0';
+  if (InquiryUnitSerialNumber->PeripheralDeviceType == 0x1F) return;
+  SerialNumberLength = InquiryUnitSerialNumber->PageLength;
+  if (SerialNumberLength >
+      sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
+    SerialNumberLength = sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
+  for (i = 0; i < SerialNumberLength; i++)
+    {
+      unsigned char SerialNumberCharacter =
+	InquiryUnitSerialNumber->ProductSerialNumber[i];
+      SerialNumber[i] =
+	(SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
+	 ? SerialNumberCharacter : ' ');
+    }
+  SerialNumber[SerialNumberLength] = '\0';
 }
 
 
 /*
-  DAC960_ReportDeviceConfiguration reports the Device Configuration Information
-  of Controller.
+  DAC960_V1_ReportDeviceConfiguration reports the Device Configuration
+  Information for DAC960 V1 Firmware Controllers.
 */
 
-static boolean DAC960_ReportDeviceConfiguration(DAC960_Controller_T *Controller)
+static boolean DAC960_V1_ReportDeviceConfiguration(DAC960_Controller_T
+						   *Controller)
 {
   int LogicalDriveNumber, Channel, TargetID;
   DAC960_Info("  Physical Devices:\n", Controller);
   for (Channel = 0; Channel < Controller->Channels; Channel++)
-    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+    for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
       {
 	DAC960_SCSI_Inquiry_T *InquiryStandardData =
-	  &Controller->InquiryStandardData[Channel][TargetID];
+	  &Controller->V1.InquiryStandardData[Channel][TargetID];
 	DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
-	  &Controller->InquiryUnitSerialNumber[Channel][TargetID];
-	DAC960_DeviceState_T *DeviceState =
-	  &Controller->DeviceState[Controller->DeviceStateIndex]
-				  [Channel][TargetID];
-	DAC960_ErrorTable_T *ErrorTable =
-	  &Controller->ErrorTable[Controller->ErrorTableIndex];
-	DAC960_ErrorTableEntry_T *ErrorEntry =
-	  &ErrorTable->ErrorTableEntries[Channel][TargetID];
+	  &Controller->V1.InquiryUnitSerialNumber[Channel][TargetID];
+	DAC960_V1_DeviceState_T *DeviceState =
+	  &Controller->V1.DeviceState[Channel][TargetID];
+	DAC960_V1_ErrorTableEntry_T *ErrorEntry =
+	  &Controller->V1.ErrorTable.ErrorTableEntries[Channel][TargetID];
 	char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
 	char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
 	char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
 	char SerialNumber[1+sizeof(InquiryUnitSerialNumber
 				   ->ProductSerialNumber)];
-	int i;
 	if (InquiryStandardData->PeripheralDeviceType == 0x1F) continue;
-	for (i = 0; i < sizeof(Vendor)-1; i++)
-	  {
-	    unsigned char VendorCharacter =
-	      InquiryStandardData->VendorIdentification[i];
-	    Vendor[i] = (VendorCharacter >= ' ' && VendorCharacter <= '~'
-			 ? VendorCharacter : ' ');
-	  }
-	Vendor[sizeof(Vendor)-1] = '\0';
-	for (i = 0; i < sizeof(Model)-1; i++)
-	  {
-	    unsigned char ModelCharacter =
-	      InquiryStandardData->ProductIdentification[i];
-	    Model[i] = (ModelCharacter >= ' ' && ModelCharacter <= '~'
-			? ModelCharacter : ' ');
-	  }
-	Model[sizeof(Model)-1] = '\0';
-	for (i = 0; i < sizeof(Revision)-1; i++)
-	  {
-	    unsigned char RevisionCharacter =
-	      InquiryStandardData->ProductRevisionLevel[i];
-	    Revision[i] = (RevisionCharacter >= ' ' && RevisionCharacter <= '~'
-			   ? RevisionCharacter : ' ');
-	  }
-	Revision[sizeof(Revision)-1] = '\0';
+	DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
+				   Vendor, Model, Revision, SerialNumber);
 	DAC960_Info("    %d:%d%s Vendor: %s  Model: %s  Revision: %s\n",
 		    Controller, Channel, TargetID, (TargetID < 10 ? " " : ""),
 		    Vendor, Model, Revision);
 	if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
+	  DAC960_Info("         Serial Number: %s\n", Controller, SerialNumber);
+	if (DeviceState->Present &&
+	    DeviceState->DeviceType == DAC960_V1_DiskType)
 	  {
-	    int SerialNumberLength = InquiryUnitSerialNumber->PageLength;
-	    if (SerialNumberLength >
-		sizeof(InquiryUnitSerialNumber->ProductSerialNumber))
-	      SerialNumberLength =
-		sizeof(InquiryUnitSerialNumber->ProductSerialNumber);
-	    for (i = 0; i < SerialNumberLength; i++)
-	      {
-		unsigned char SerialNumberCharacter =
-		  InquiryUnitSerialNumber->ProductSerialNumber[i];
-		SerialNumber[i] =
-		  (SerialNumberCharacter >= ' ' && SerialNumberCharacter <= '~'
-		   ? SerialNumberCharacter : ' ');
-	      }
-	    SerialNumber[SerialNumberLength] = '\0';
-	    DAC960_Info("         Serial Number: %s\n",
-			Controller, SerialNumber);
-	  }
-	if (DeviceState->Present && DeviceState->DeviceType == DAC960_DiskType)
-	  {
-	    if (Controller->DeviceResetCount[Channel][TargetID] > 0)
+	    if (Controller->V1.DeviceResetCount[Channel][TargetID] > 0)
 	      DAC960_Info("         Disk Status: %s, %d blocks, %d resets\n",
 			  Controller,
-			  (DeviceState->DeviceState == DAC960_Device_Dead
+			  (DeviceState->DeviceState == DAC960_V1_Device_Dead
 			   ? "Dead"
-			   : DeviceState->DeviceState == DAC960_Device_WriteOnly
-			   ? "Write-Only"
-			   : DeviceState->DeviceState == DAC960_Device_Online
-			   ? "Online" : "Standby"),
+			   : DeviceState->DeviceState
+			     == DAC960_V1_Device_WriteOnly
+			     ? "Write-Only"
+			     : DeviceState->DeviceState
+			       == DAC960_V1_Device_Online
+			       ? "Online" : "Standby"),
 			  DeviceState->DiskSize,
-			  Controller->DeviceResetCount[Channel][TargetID]);
+			  Controller->V1.DeviceResetCount[Channel][TargetID]);
 	    else
 	      DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
-			  (DeviceState->DeviceState == DAC960_Device_Dead
+			  (DeviceState->DeviceState == DAC960_V1_Device_Dead
 			   ? "Dead"
-			   : DeviceState->DeviceState == DAC960_Device_WriteOnly
-			   ? "Write-Only"
-			   : DeviceState->DeviceState == DAC960_Device_Online
-			   ? "Online" : "Standby"),
+			   : DeviceState->DeviceState
+			     == DAC960_V1_Device_WriteOnly
+			     ? "Write-Only"
+			     : DeviceState->DeviceState
+			       == DAC960_V1_Device_Online
+			       ? "Online" : "Standby"),
 			  DeviceState->DiskSize);
 	  }
 	if (ErrorEntry->ParityErrorCount > 0 ||
@@ -1108,17 +1626,16 @@
        LogicalDriveNumber < Controller->LogicalDriveCount;
        LogicalDriveNumber++)
     {
-      DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
-	&Controller->LogicalDriveInformation
-	   [Controller->LogicalDriveInformationIndex][LogicalDriveNumber];
+      DAC960_V1_LogicalDriveInformation_T *LogicalDriveInformation =
+	&Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
       DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks, %s\n",
 		  Controller, Controller->ControllerNumber, LogicalDriveNumber,
 		  LogicalDriveInformation->RAIDLevel,
-		  (LogicalDriveInformation->LogicalDriveState ==
-		     DAC960_LogicalDrive_Online
+		  (LogicalDriveInformation->LogicalDriveState
+		   == DAC960_V1_LogicalDrive_Online
 		   ? "Online"
-		   : LogicalDriveInformation->LogicalDriveState ==
-		     DAC960_LogicalDrive_Critical
+		   : LogicalDriveInformation->LogicalDriveState
+		     == DAC960_V1_LogicalDrive_Critical
 		     ? "Critical" : "Offline"),
 		  LogicalDriveInformation->LogicalDriveSize,
 		  (LogicalDriveInformation->WriteBack
@@ -1129,6 +1646,179 @@
 
 
 /*
+  DAC960_V2_ReportDeviceConfiguration reports the Device Configuration
+  Information for DAC960 V2 Firmware Controllers.
+*/
+
+static boolean DAC960_V2_ReportDeviceConfiguration(DAC960_Controller_T
+						   *Controller)
+{
+  int PhysicalDeviceIndex, LogicalDriveNumber;
+  DAC960_Info("  Physical Devices:\n", Controller);
+  for (PhysicalDeviceIndex = 0;
+       PhysicalDeviceIndex < DAC960_V2_MaxPhysicalDevices;
+       PhysicalDeviceIndex++)
+    {
+      DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
+	Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
+      DAC960_SCSI_Inquiry_T *InquiryStandardData =
+	(DAC960_SCSI_Inquiry_T *) &PhysicalDeviceInfo->SCSI_InquiryData;
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+	Controller->V2.InquiryUnitSerialNumber[PhysicalDeviceIndex];
+      char Vendor[1+sizeof(InquiryStandardData->VendorIdentification)];
+      char Model[1+sizeof(InquiryStandardData->ProductIdentification)];
+      char Revision[1+sizeof(InquiryStandardData->ProductRevisionLevel)];
+      char SerialNumber[1+sizeof(InquiryUnitSerialNumber->ProductSerialNumber)];
+      if (PhysicalDeviceInfo == NULL) break;
+      DAC960_SanitizeInquiryData(InquiryStandardData, InquiryUnitSerialNumber,
+				 Vendor, Model, Revision, SerialNumber);
+      DAC960_Info("    %d:%d%s Vendor: %s  Model: %s  Revision: %s\n",
+		  Controller,
+		  PhysicalDeviceInfo->Channel,
+		  PhysicalDeviceInfo->TargetID,
+		  (PhysicalDeviceInfo->TargetID < 10 ? " " : ""),
+		  Vendor, Model, Revision);
+      if (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers == 0)
+	DAC960_Info("         %sAsynchronous\n", Controller,
+		    (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+		     ? "Wide " :""));
+      else
+	DAC960_Info("         %sSynchronous at %d MB/sec\n", Controller,
+		    (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+		     ? "Wide " :""),
+		    (PhysicalDeviceInfo->NegotiatedSynchronousMegaTransfers
+		     * (PhysicalDeviceInfo->NegotiatedDataWidthBits == 16
+			? 2 : 1)));
+      if (InquiryUnitSerialNumber->PeripheralDeviceType != 0x1F)
+	DAC960_Info("         Serial Number: %s\n", Controller, SerialNumber);
+      if (PhysicalDeviceInfo->PhysicalDeviceState ==
+	  DAC960_V2_Device_Unconfigured)
+	continue;
+      DAC960_Info("         Disk Status: %s, %d blocks\n", Controller,
+		  (PhysicalDeviceInfo->PhysicalDeviceState
+		   == DAC960_V2_Device_Online
+		   ? "Online"
+		   : PhysicalDeviceInfo->PhysicalDeviceState
+		     == DAC960_V2_Device_WriteOnly
+		     ? "Write-Only"
+		     : PhysicalDeviceInfo->PhysicalDeviceState
+		       == DAC960_V2_Device_Dead
+		       ? "Dead" : "Standby"),
+		  PhysicalDeviceInfo
+		  ->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+      if (PhysicalDeviceInfo->ParityErrors == 0 &&
+	  PhysicalDeviceInfo->SoftErrors == 0 &&
+	  PhysicalDeviceInfo->HardErrors == 0 &&
+	  PhysicalDeviceInfo->MiscellaneousErrors == 0 &&
+	  PhysicalDeviceInfo->CommandTimeouts == 0 &&
+	  PhysicalDeviceInfo->Retries == 0 &&
+	  PhysicalDeviceInfo->Aborts == 0 &&
+	  PhysicalDeviceInfo->PredictedFailuresDetected == 0)
+	continue;
+      DAC960_Info("         Errors - Parity: %d, Soft: %d, "
+		  "Hard: %d, Misc: %d\n", Controller,
+		  PhysicalDeviceInfo->ParityErrors,
+		  PhysicalDeviceInfo->SoftErrors,
+		  PhysicalDeviceInfo->HardErrors,
+		  PhysicalDeviceInfo->MiscellaneousErrors);
+      DAC960_Info("                  Timeouts: %d, Retries: %d, "
+		  "Aborts: %d, Predicted: %d\n", Controller,
+		  PhysicalDeviceInfo->CommandTimeouts,
+		  PhysicalDeviceInfo->Retries,
+		  PhysicalDeviceInfo->Aborts,
+		  PhysicalDeviceInfo->PredictedFailuresDetected);
+    }
+  DAC960_Info("  Logical Drives:\n", Controller);
+  for (LogicalDriveNumber = 0;
+       LogicalDriveNumber < DAC960_MaxLogicalDrives;
+       LogicalDriveNumber++)
+    {
+      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+      unsigned char *ReadCacheStatus[] = { "Read Cache Disabled",
+					   "Read Cache Enabled",
+					   "Read Ahead Enabled",
+					   "Intelligent Read Ahead Enabled",
+					   "-", "-", "-", "-" };
+      unsigned char *WriteCacheStatus[] = { "Write Cache Disabled",
+					    "Logical Device Read Only",
+					    "Write Cache Enabled",
+					    "Intelligent Write Cache Enabled",
+					    "-", "-", "-", "-" };
+      unsigned char *GeometryTranslation;
+      if (LogicalDeviceInfo == NULL) continue;
+      switch(LogicalDeviceInfo->DriveGeometry)
+	{
+	case DAC960_V2_Geometry_128_32:
+	  GeometryTranslation = "128/32";
+	  break;
+	case DAC960_V2_Geometry_255_63:
+	  GeometryTranslation = "255/63";
+	  break;
+	default:
+	  GeometryTranslation = "Invalid";
+	  DAC960_Error("Illegal Logical Device Geometry %d\n",
+		       Controller, LogicalDeviceInfo->DriveGeometry);
+	  break;
+	}
+      DAC960_Info("    /dev/rd/c%dd%d: RAID-%d, %s, %d blocks\n",
+		  Controller, Controller->ControllerNumber, LogicalDriveNumber,
+		  LogicalDeviceInfo->RAIDLevel,
+		  (LogicalDeviceInfo->LogicalDeviceState
+		   == DAC960_V2_LogicalDevice_Online
+		   ? "Online"
+		   : LogicalDeviceInfo->LogicalDeviceState
+		     == DAC960_V2_LogicalDevice_Critical
+		     ? "Critical" : "Offline"),
+		  LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB);
+      DAC960_Info("                  Logical Device %s, BIOS Geometry: %s\n",
+		  Controller,
+		  (LogicalDeviceInfo->LogicalDeviceControl
+				     .LogicalDeviceInitialized
+		   ? "Initialized" : "Uninitialized"),
+		  GeometryTranslation);
+      if (LogicalDeviceInfo->StripeSize == 0)
+	{
+	  if (LogicalDeviceInfo->CacheLineSize == 0)
+	    DAC960_Info("                  Stripe Size: N/A, "
+			"Segment Size: N/A\n", Controller);
+	  else
+	    DAC960_Info("                  Stripe Size: N/A, "
+			"Segment Size: %dKB\n", Controller,
+			1 << (LogicalDeviceInfo->CacheLineSize - 2));
+	}
+      else
+	{
+	  if (LogicalDeviceInfo->CacheLineSize == 0)
+	    DAC960_Info("                  Stripe Size: %dKB, "
+			"Segment Size: N/A\n", Controller,
+			1 << (LogicalDeviceInfo->StripeSize - 2));
+	  else
+	    DAC960_Info("                  Stripe Size: %dKB, "
+			"Segment Size: %dKB\n", Controller,
+			1 << (LogicalDeviceInfo->StripeSize - 2),
+			1 << (LogicalDeviceInfo->CacheLineSize - 2));
+	}
+      DAC960_Info("                  %s, %s\n", Controller,
+		  ReadCacheStatus[
+		    LogicalDeviceInfo->LogicalDeviceControl.ReadCache],
+		  WriteCacheStatus[
+		    LogicalDeviceInfo->LogicalDeviceControl.WriteCache]);
+      if (LogicalDeviceInfo->SoftErrors > 0 ||
+	  LogicalDeviceInfo->CommandsFailed > 0 ||
+	  LogicalDeviceInfo->DeferredWriteErrors)
+	DAC960_Info("                  Errors - Soft: %d, Failed: %d, "
+		    "Deferred Write: %d\n", Controller,
+		    LogicalDeviceInfo->SoftErrors,
+		    LogicalDeviceInfo->CommandsFailed,
+		    LogicalDeviceInfo->DeferredWriteErrors);
+
+    }
+  return true;
+}
+
+
+/*
   DAC960_RegisterBlockDevice registers the Block Device structures
   associated with Controller.
 */
@@ -1167,7 +1857,7 @@
       Controller->MaxSectorsPerRequest[MinorNumber] =
 	Controller->MaxBlocksPerCommand;
       Controller->MaxSegmentsPerRequest[MinorNumber] =
-	Controller->MaxScatterGatherSegments;
+	Controller->DriverScatterGatherLimit;
     }
   Controller->GenericDiskInfo.part = Controller->DiskPartitions;
   Controller->GenericDiskInfo.sizes = Controller->PartitionSizes;
@@ -1250,37 +1940,485 @@
 
 
 /*
-  DAC960_InitializeController initializes Controller.
+  DAC960_GenericDiskInit is the Generic Disk Information Initialization
+  Function for the DAC960 Driver.
 */
 
-static void DAC960_InitializeController(DAC960_Controller_T *Controller)
+static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
 {
-  if (DAC960_ReadControllerConfiguration(Controller) &&
-      DAC960_ReportControllerConfiguration(Controller) &&
-      DAC960_ReadDeviceConfiguration(Controller) &&
-      DAC960_ReportDeviceConfiguration(Controller) &&
-      DAC960_RegisterBlockDevice(Controller))
-    {
-      /*
-	Initialize the Command structures.
-      */
-      DAC960_Command_T *Commands = Controller->Commands;
-      int CommandIdentifier;
-      Controller->FreeCommands = NULL;
-      for (CommandIdentifier = 0;
-	   CommandIdentifier < Controller->DriverQueueDepth;
-	   CommandIdentifier++)
-	{
-	  Commands[CommandIdentifier].Controller = Controller;
-	  Commands[CommandIdentifier].Next = Controller->FreeCommands;
-	  Controller->FreeCommands = &Commands[CommandIdentifier];
-	}
-      /*
-	Initialize the Monitoring Timer.
-      */
-      init_timer(&Controller->MonitoringTimer);
-      Controller->MonitoringTimer.expires =
-	jiffies + DAC960_MonitoringTimerInterval;
+  DAC960_Controller_T *Controller =
+    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
+  int LogicalDriveNumber;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    for (LogicalDriveNumber = 0;
+	 LogicalDriveNumber < Controller->LogicalDriveCount;
+	 LogicalDriveNumber++)
+      GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)]
+		      .nr_sects =
+	Controller->V1.LogicalDriveInformation
+		       [LogicalDriveNumber].LogicalDriveSize;
+  else
+    for (LogicalDriveNumber = 0;
+	 LogicalDriveNumber < DAC960_MaxLogicalDrives;
+	 LogicalDriveNumber++)
+      {
+	DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	  Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+	if (LogicalDeviceInfo != NULL)
+	  GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)]
+			  .nr_sects =
+	    LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+      }
+}
+
+
+/*
+  DAC960_ReportErrorStatus reports Controller BIOS Messages passed through
+  the Error Status Register when the driver performs the BIOS handshaking.
+  It returns true for fatal errors and false otherwise.
+*/
+
+static boolean DAC960_ReportErrorStatus(DAC960_Controller_T *Controller,
+					unsigned char ErrorStatus,
+					unsigned char Parameter0,
+					unsigned char Parameter1)
+{
+  switch (ErrorStatus)
+    {
+    case 0x00:
+      DAC960_Notice("Physical Device %d:%d Not Responding\n",
+		    Controller, Parameter1, Parameter0);
+      break;
+    case 0x08:
+      if (Controller->DriveSpinUpMessageDisplayed) break;
+      DAC960_Notice("Spinning Up Drives\n", Controller);
+      Controller->DriveSpinUpMessageDisplayed = true;
+      break;
+    case 0x30:
+      DAC960_Notice("Configuration Checksum Error\n", Controller);
+      break;
+    case 0x60:
+      DAC960_Notice("Mirror Race Recovery Failed\n", Controller);
+      break;
+    case 0x70:
+      DAC960_Notice("Mirror Race Recovery In Progress\n", Controller);
+      break;
+    case 0x90:
+      DAC960_Notice("Physical Device %d:%d COD Mismatch\n",
+		    Controller, Parameter1, Parameter0);
+      break;
+    case 0xA0:
+      DAC960_Notice("Logical Drive Installation Aborted\n", Controller);
+      break;
+    case 0xB0:
+      DAC960_Notice("Mirror Race On A Critical Logical Drive\n", Controller);
+      break;
+    case 0xD0:
+      DAC960_Notice("New Controller Configuration Found\n", Controller);
+      break;
+    case 0xF0:
+      DAC960_Error("Fatal Memory Parity Error for Controller at\n", Controller);
+      return true;
+    default:
+      DAC960_Error("Unknown Initialization Error %02X for Controller at\n",
+		   Controller, ErrorStatus);
+      return true;
+    }
+  return false;
+}
+
+
+/*
+  DAC960_DetectControllers detects Mylex DAC960/AcceleRAID/eXtremeRAID
+  PCI RAID Controllers by interrogating the PCI Configuration Space for
+  Controller Type.
+*/
+
+static void DAC960_DetectControllers(DAC960_HardwareType_T HardwareType)
+{
+  void (*InterruptHandler)(int, void *, Registers_T *) = NULL;
+  DAC960_FirmwareType_T FirmwareType = 0;
+  unsigned short VendorID = 0, DeviceID = 0;
+  unsigned int MemoryWindowSize = 0;
+  PCI_Device_T *PCI_Device = NULL;
+  switch (HardwareType)
+    {
+    case DAC960_BA_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_BA;
+      FirmwareType = DAC960_V2_Controller;
+      InterruptHandler = DAC960_BA_InterruptHandler;
+      MemoryWindowSize = DAC960_BA_RegisterWindowSize;
+      break;
+    case DAC960_LP_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_LP;
+      FirmwareType = DAC960_LP_Controller;
+      InterruptHandler = DAC960_LP_InterruptHandler;
+      MemoryWindowSize = DAC960_LP_RegisterWindowSize;
+      break;
+    case DAC960_LA_Controller:
+      VendorID = PCI_VENDOR_ID_DEC;
+      DeviceID = PCI_DEVICE_ID_DEC_21285;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_LA_InterruptHandler;
+      MemoryWindowSize = DAC960_LA_RegisterWindowSize;
+      break;
+    case DAC960_PG_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PG;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_PG_InterruptHandler;
+      MemoryWindowSize = DAC960_PG_RegisterWindowSize;
+      break;
+    case DAC960_PD_Controller:
+      VendorID = PCI_VENDOR_ID_MYLEX;
+      DeviceID = PCI_DEVICE_ID_MYLEX_DAC960_PD;
+      FirmwareType = DAC960_V1_Controller;
+      InterruptHandler = DAC960_PD_InterruptHandler;
+      MemoryWindowSize = DAC960_PD_RegisterWindowSize;
+      break;
+    }
+  while ((PCI_Device = pci_find_device(VendorID, DeviceID, PCI_Device)) != NULL)
+    {
+      DAC960_Controller_T *Controller = NULL;
+      DAC960_IO_Address_T IO_Address = 0;
+      DAC960_PCI_Address_T PCI_Address = 0;
+      unsigned char Bus = PCI_Device->bus->number;
+      unsigned char DeviceFunction = PCI_Device->devfn;
+      unsigned char Device = DeviceFunction >> 3;
+      unsigned char Function = DeviceFunction & 0x7;
+      unsigned char ErrorStatus, Parameter0, Parameter1;
+      unsigned int IRQ_Channel = PCI_Device->irq;
+      unsigned long BaseAddress0 = PCI_Device->base_address[0];
+      unsigned long BaseAddress1 = PCI_Device->base_address[1];
+      unsigned short SubsystemVendorID, SubsystemDeviceID;
+      void *BaseAddress;
+      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_VENDOR_ID,
+			   &SubsystemVendorID);
+      pci_read_config_word(PCI_Device, PCI_SUBSYSTEM_ID,
+			   &SubsystemDeviceID);
+      switch (HardwareType)
+	{
+	case DAC960_BA_Controller:
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_LP_Controller:
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_LA_Controller:
+	  if (!(SubsystemVendorID == PCI_VENDOR_ID_MYLEX &&
+		SubsystemDeviceID == PCI_DEVICE_ID_MYLEX_DAC960_LA))
+	    continue;
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_PG_Controller:
+	  PCI_Address = BaseAddress0 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	case DAC960_PD_Controller:
+	  IO_Address = BaseAddress0 & PCI_BASE_ADDRESS_IO_MASK;
+	  PCI_Address = BaseAddress1 & PCI_BASE_ADDRESS_MEM_MASK;
+	  break;
+	}
+      if (DAC960_ControllerCount == DAC960_MaxControllers)
+	{
+	  DAC960_Error("More than %d DAC960 Controllers detected - "
+		       "ignoring from Controller at\n",
+		       NULL, DAC960_MaxControllers);
+	  goto Failure;
+	}
+      Controller = (DAC960_Controller_T *)
+	kmalloc(sizeof(DAC960_Controller_T), GFP_ATOMIC);
+      if (Controller == NULL)
+	{
+	  DAC960_Error("Unable to allocate Controller structure for "
+		       "Controller at\n", NULL);
+	  goto Failure;
+	}
+      memset(Controller, 0, sizeof(DAC960_Controller_T));
+      Controller->ControllerNumber = DAC960_ControllerCount;
+      DAC960_Controllers[DAC960_ControllerCount++] = Controller;
+      DAC960_AnnounceDriver(Controller);
+      Controller->FirmwareType = FirmwareType;
+      Controller->HardwareType = HardwareType;
+      Controller->IO_Address = IO_Address;
+      Controller->PCI_Address = PCI_Address;
+      Controller->Bus = Bus;
+      Controller->Device = Device;
+      Controller->Function = Function;
+      sprintf(Controller->ControllerName, "c%d", Controller->ControllerNumber);
+      /*
+	Map the Controller Register Window.
+      */
+      if (MemoryWindowSize < PAGE_SIZE)
+	MemoryWindowSize = PAGE_SIZE;
+      Controller->MemoryMappedAddress =
+	ioremap_nocache(PCI_Address & PAGE_MASK, MemoryWindowSize);
+      Controller->BaseAddress =
+	Controller->MemoryMappedAddress + (PCI_Address & ~PAGE_MASK);
+      if (Controller->MemoryMappedAddress == NULL)
+	{
+	  DAC960_Error("Unable to map Controller Register Window for "
+		       "Controller at\n", Controller);
+	  goto Failure;
+	}
+      BaseAddress = Controller->BaseAddress;
+      switch (HardwareType)
+	{
+	case DAC960_BA_Controller:
+	  DAC960_BA_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_BA_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_BA_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_BA_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_BA_EnableInterrupts(Controller->BaseAddress);
+	  Controller->QueueCommand = DAC960_BA_QueueCommand;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V2_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V2_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V2_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V2_QueueReadWriteCommand;
+	  break;
+	case DAC960_LP_Controller:
+	  DAC960_LP_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_LP_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_LP_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_LP_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V2_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_LP_EnableInterrupts(Controller->BaseAddress);
+	  Controller->QueueCommand = DAC960_LP_QueueCommand;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V2_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V2_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V2_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V2_QueueReadWriteCommand;
+	  break;
+	case DAC960_LA_Controller:
+	  DAC960_LA_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_LA_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_LA_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_LA_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_LA_EnableInterrupts(Controller->BaseAddress);
+	  if (Controller->V1.DualModeMemoryMailboxInterface)
+	    Controller->QueueCommand = DAC960_LA_QueueCommandDualMode;
+	  else Controller->QueueCommand = DAC960_LA_QueueCommandSingleMode;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V1_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V1_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V1_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V1_QueueReadWriteCommand;
+	  break;
+	case DAC960_PG_Controller:
+	  DAC960_PG_DisableInterrupts(Controller->BaseAddress);
+	  DAC960_PG_AcknowledgeHardwareMailboxStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_PG_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_PG_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  if (!DAC960_V1_EnableMemoryMailboxInterface(Controller))
+	    {
+	      DAC960_Error("Unable to Enable Memory Mailbox Interface "
+			   "for Controller at\n", Controller);
+	      goto Failure;
+	    }
+	  DAC960_PG_EnableInterrupts(Controller->BaseAddress);
+	  if (Controller->V1.DualModeMemoryMailboxInterface)
+	    Controller->QueueCommand = DAC960_PG_QueueCommandDualMode;
+	  else Controller->QueueCommand = DAC960_PG_QueueCommandSingleMode;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V1_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V1_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V1_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V1_QueueReadWriteCommand;
+	  break;
+	case DAC960_PD_Controller:
+	  request_region(Controller->IO_Address, 0x80,
+			 Controller->FullModelName);
+	  DAC960_PD_DisableInterrupts(BaseAddress);
+	  DAC960_PD_AcknowledgeStatus(BaseAddress);
+	  udelay(1000);
+	  while (DAC960_PD_InitializationInProgressP(BaseAddress))
+	    {
+	      if (DAC960_PD_ReadErrorStatus(BaseAddress, &ErrorStatus,
+					    &Parameter0, &Parameter1) &&
+		  DAC960_ReportErrorStatus(Controller, ErrorStatus,
+					   Parameter0, Parameter1))
+		goto Failure;
+	      udelay(10);
+	    }
+	  DAC960_PD_EnableInterrupts(Controller->BaseAddress);
+	  Controller->QueueCommand = DAC960_PD_QueueCommand;
+	  Controller->ReadControllerConfiguration =
+	    DAC960_V1_ReadControllerConfiguration;
+	  Controller->ReadDeviceConfiguration =
+	    DAC960_V1_ReadDeviceConfiguration;
+	  Controller->ReportDeviceConfiguration =
+	    DAC960_V1_ReportDeviceConfiguration;
+	  Controller->QueueReadWriteCommand =
+	    DAC960_V1_QueueReadWriteCommand;
+	  break;
+	}
+      /*
+	Acquire shared access to the IRQ Channel.
+      */
+      if (IRQ_Channel == 0)
+	{
+	  DAC960_Error("IRQ Channel %d illegal for Controller at\n",
+		       Controller, IRQ_Channel);
+	  goto Failure;
+	}
+      strcpy(Controller->FullModelName, "DAC960");
+      if (request_irq(IRQ_Channel, InterruptHandler, SA_SHIRQ,
+		      Controller->FullModelName, Controller) < 0)
+	{
+	  DAC960_Error("Unable to acquire IRQ Channel %d for Controller at\n",
+		       Controller, IRQ_Channel);
+	  goto Failure;
+	}
+      Controller->IRQ_Channel = IRQ_Channel;
+      DAC960_ActiveControllerCount++;
+      Controller->InitialCommand.CommandIdentifier = 1;
+      Controller->InitialCommand.Controller = Controller;
+      Controller->Commands[0] = &Controller->InitialCommand;
+      Controller->FreeCommands = &Controller->InitialCommand;
+      Controller->ControllerDetectionSuccessful = true;
+      continue;
+    Failure:
+      if (IO_Address == 0)
+	DAC960_Error("PCI Bus %d Device %d Function %d I/O Address N/A "
+		     "PCI Address 0x%X\n", Controller,
+		     Bus, Device, Function, PCI_Address);
+      else DAC960_Error("PCI Bus %d Device %d Function %d I/O Address "
+			"0x%X PCI Address 0x%X\n", Controller,
+			Bus, Device, Function, IO_Address, PCI_Address);
+      if (Controller == NULL) break;
+      if (Controller->MemoryMappedAddress != NULL)
+	iounmap(Controller->MemoryMappedAddress);
+      if (Controller->IRQ_Channel > 0)
+	free_irq(IRQ_Channel, Controller);
+    }
+}
+
+
+/*
+  DAC960_SortControllers sorts the Controllers by PCI Bus and Device Number.
+*/
+
+static void DAC960_SortControllers(void)
+{
+  int ControllerNumber, LastInterchange, Bound, j;
+  LastInterchange = DAC960_ControllerCount-1;
+  while (LastInterchange > 0)
+    {
+      Bound = LastInterchange;
+      LastInterchange = 0;
+      for (j = 0; j < Bound; j++)
+	{
+	  DAC960_Controller_T *Controller1 = DAC960_Controllers[j];
+	  DAC960_Controller_T *Controller2 = DAC960_Controllers[j+1];
+	  if (Controller1->Bus > Controller2->Bus ||
+	      (Controller1->Bus == Controller2->Bus &&
+	       (Controller1->Device > Controller2->Device)))
+	    {
+	      Controller2->ControllerNumber = j;
+	      DAC960_Controllers[j] = Controller2;
+	      Controller1->ControllerNumber = j+1;
+	      DAC960_Controllers[j+1] = Controller1;
+	      LastInterchange = j;
+	    }
+	}
+    }
+  for (ControllerNumber = 0;
+       ControllerNumber < DAC960_ControllerCount;
+       ControllerNumber++)
+    {
+      DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
+      if (!Controller->ControllerDetectionSuccessful)
+	{
+	  DAC960_Controllers[ControllerNumber] = NULL;
+	  kfree(Controller);
+	}
+    }
+}
+
+
+/*
+  DAC960_InitializeController initializes Controller.
+*/
+
+static void DAC960_InitializeController(DAC960_Controller_T *Controller)
+{
+  if (DAC960_ReadControllerConfiguration(Controller) &&
+      DAC960_ReportControllerConfiguration(Controller) &&
+      DAC960_CreateAuxiliaryStructures(Controller) &&
+      DAC960_ReadDeviceConfiguration(Controller) &&
+      DAC960_ReportDeviceConfiguration(Controller) &&
+      DAC960_RegisterBlockDevice(Controller))
+    {
+      /*
+	Initialize the Monitoring Timer.
+      */
+      init_timer(&Controller->MonitoringTimer);
+      Controller->MonitoringTimer.expires =
+	jiffies + DAC960_MonitoringTimerInterval;
       Controller->MonitoringTimer.data = (unsigned long) Controller;
       Controller->MonitoringTimer.function = DAC960_MonitoringTimerFunction;
       add_timer(&Controller->MonitoringTimer);
@@ -1299,28 +2437,46 @@
   if (Controller->ControllerInitialized)
     {
       del_timer(&Controller->MonitoringTimer);
-      DAC960_Notice("Flushing Cache...", Controller);
-      DAC960_ExecuteType3(Controller, DAC960_Flush, NULL);
-      DAC960_Notice("done\n", Controller);
-      switch (Controller->ControllerType)
-	{
-	case DAC960_V5_Controller:
-	  if (!Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V5_SaveMemoryMailboxInfo(Controller);
-	  break;
-	case DAC960_V4_Controller:
-	  if (!Controller->DualModeMemoryMailboxInterface)
-	    DAC960_V4_SaveMemoryMailboxInfo(Controller);
-	  break;
-	case DAC960_V3_Controller:
-	  break;
+      if (Controller->FirmwareType == DAC960_V1_Controller)
+	{
+	  DAC960_Notice("Flushing Cache...", Controller);
+	  DAC960_V1_ExecuteType3(Controller, DAC960_V1_Flush, NULL);
+	  DAC960_Notice("done\n", Controller);
+	  switch (Controller->HardwareType)
+	    {
+	    case DAC960_LA_Controller:
+	      if (Controller->V1.DualModeMemoryMailboxInterface)
+		free_pages(Controller->MemoryMailboxPagesAddress,
+			   Controller->MemoryMailboxPagesOrder);
+	      else DAC960_LA_SaveMemoryMailboxInfo(Controller);
+	      break;
+	    case DAC960_PG_Controller:
+	      if (Controller->V1.DualModeMemoryMailboxInterface)
+		free_pages(Controller->MemoryMailboxPagesAddress,
+			   Controller->MemoryMailboxPagesOrder);
+	      else DAC960_PG_SaveMemoryMailboxInfo(Controller);
+	      break;
+	    case DAC960_PD_Controller:
+	      release_region(Controller->IO_Address, 0x80);
+	      break;
+	    default:
+	      break;
+	    }
+	}
+      else
+	{
+	  DAC960_Notice("Flushing Cache...", Controller);
+	  DAC960_V2_DeviceOperation(Controller, DAC960_V2_PauseDevice,
+				    DAC960_V2_RAID_Controller);
+	  DAC960_Notice("done\n", Controller);
+	  free_pages(Controller->MemoryMailboxPagesAddress,
+		     Controller->MemoryMailboxPagesOrder);
 	}
     }
   free_irq(Controller->IRQ_Channel, Controller);
   iounmap(Controller->MemoryMappedAddress);
-  if (Controller->IO_Address > 0)
-    release_region(Controller->IO_Address, 0x80);
   DAC960_UnregisterBlockDevice(Controller);
+  DAC960_DestroyAuxiliaryStructures(Controller);
   DAC960_Controllers[Controller->ControllerNumber] = NULL;
   kfree(Controller);
 }
@@ -1333,9 +2489,12 @@
 void DAC960_Initialize(void)
 {
   int ControllerNumber;
-  DAC960_DetectControllers(DAC960_V5_Controller);
-  DAC960_DetectControllers(DAC960_V4_Controller);
-  DAC960_DetectControllers(DAC960_V3_Controller);
+  DAC960_DetectControllers(DAC960_BA_Controller);
+  DAC960_DetectControllers(DAC960_LP_Controller);
+  DAC960_DetectControllers(DAC960_LA_Controller);
+  DAC960_DetectControllers(DAC960_PG_Controller);
+  DAC960_DetectControllers(DAC960_PD_Controller);
+  DAC960_SortControllers();
   if (DAC960_ActiveControllerCount == 0) return;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
@@ -1371,68 +2530,38 @@
 
 
 /*
-  DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
-  I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
-  this function should wait for a Command to become available if necessary.
-  This function returns true if an I/O Request was queued and false otherwise.
+  DAC960_V1_QueueReadWriteCommand prepares and queues a Read/Write Command for
+  DAC960 V1 Firmware Controllers.
 */
 
-static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
-				     boolean WaitForCommand)
+static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *Command)
 {
-  IO_Request_T **RequestQueuePointer =
-    &blk_dev[DAC960_MAJOR + Controller->ControllerNumber].current_request;
-  IO_Request_T *Request;
-  DAC960_Command_T *Command;
-  char *RequestBuffer;
-  while (true)
-    {
-      Request = *RequestQueuePointer;
-      if (Request == NULL || Request->rq_status == RQ_INACTIVE) return false;
-      Command = DAC960_AllocateCommand(Controller);
-      if (Command != NULL) break;
-      if (!WaitForCommand) return false;
-      DAC960_WaitForCommand(Controller);
-    }
-  DAC960_ClearCommand(Command);
-  if (Request->cmd == READ)
-    Command->CommandType = DAC960_ReadCommand;
-  else Command->CommandType = DAC960_WriteCommand;
-  Command->Semaphore = Request->sem;
-  Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
-  Command->BlockNumber =
-    Request->sector
-    + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
-  Command->BlockCount = Request->nr_sectors;
-  Command->SegmentCount = Request->nr_segments;
-  Command->BufferHeader = Request->bh;
-  RequestBuffer = Request->buffer;
-  Request->rq_status = RQ_INACTIVE;
-  *RequestQueuePointer = Request->next;
-  wake_up(&wait_for_request);
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_ClearCommand(Command);
   if (Command->SegmentCount == 1)
     {
-      DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
       if (Command->CommandType == DAC960_ReadCommand)
-	CommandMailbox->Type5.CommandOpcode = DAC960_Read;
-      else CommandMailbox->Type5.CommandOpcode = DAC960_Write;
+	CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
+      else CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
-      CommandMailbox->Type5.BusAddress = Virtual_to_Bus(RequestBuffer);
+      CommandMailbox->Type5.BusAddress = Virtual_to_Bus(Command->RequestBuffer);
     }
   else
     {
-      DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-      DAC960_ScatterGatherSegment_T
-	*ScatterGatherList = Command->ScatterGatherList;
+      DAC960_V1_ScatterGatherSegment_T
+	*ScatterGatherList = Command->V1.ScatterGatherList;
       BufferHeader_T *BufferHeader = Command->BufferHeader;
       char *LastDataEndPointer = NULL;
       int SegmentNumber = 0;
       if (Command->CommandType == DAC960_ReadCommand)
-	CommandMailbox->Type5.CommandOpcode = DAC960_ReadWithOldScatterGather;
+	CommandMailbox->Type5.CommandOpcode =
+	  DAC960_V1_ReadWithOldScatterGather;
       else
-	CommandMailbox->Type5.CommandOpcode = DAC960_WriteWithOldScatterGather;
+	CommandMailbox->Type5.CommandOpcode =
+	  DAC960_V1_WriteWithOldScatterGather;
       CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
       CommandMailbox->Type5.LD.LogicalDriveNumber = Command->LogicalDriveNumber;
       CommandMailbox->Type5.LogicalBlockAddress = Command->BlockNumber;
@@ -1453,7 +2582,97 @@
 	      ScatterGatherList[SegmentNumber].SegmentByteCount =
 		BufferHeader->b_size;
 	      LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
-	      if (SegmentNumber++ > Controller->MaxScatterGatherSegments)
+	      if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
+		panic("DAC960: Scatter/Gather Segment Overflow\n");
+	    }
+	  BufferHeader = BufferHeader->b_reqnext;
+	}
+      if (SegmentNumber != Command->SegmentCount)
+	panic("DAC960: SegmentNumber != SegmentCount\n");
+    }
+  DAC960_QueueCommand(Command);
+}
+
+
+/*
+  DAC960_V2_QueueReadWriteCommand prepares and queues a Read/Write Command for
+  DAC960 V2 Firmware Controllers.
+*/
+
+static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_ClearCommand(Command);
+  CommandMailbox->SCSI_10.CommandOpcode = DAC960_V2_SCSI_10;
+  CommandMailbox->SCSI_10.CommandControlBits.DataTransferControllerToHost =
+    (Command->CommandType == DAC960_ReadCommand);
+  CommandMailbox->SCSI_10.DataTransferSize =
+    Command->BlockCount << DAC960_BlockSizeBits;
+  CommandMailbox->SCSI_10.RequestSenseBusAddress =
+    Virtual_to_Bus(&Command->V2.RequestSense);
+  CommandMailbox->SCSI_10.PhysicalDevice =
+    Controller->V2.LogicalDriveToVirtualDevice[Command->LogicalDriveNumber];
+  CommandMailbox->SCSI_10.RequestSenseSize =
+    sizeof(DAC960_SCSI_RequestSense_T);
+  CommandMailbox->SCSI_10.CDBLength = 10;
+  CommandMailbox->SCSI_10.SCSI_CDB[0] =
+    (Command->CommandType == DAC960_ReadCommand ? 0x28 : 0x2A);
+  CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
+  CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
+  CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
+  CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
+  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+  if (Command->SegmentCount == 1)
+    {
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentDataPointer =
+	Virtual_to_Bus(Command->RequestBuffer);
+      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			     .ScatterGatherSegments[0]
+			     .SegmentByteCount =
+	CommandMailbox->SCSI_10.DataTransferSize;
+    }
+  else
+    {
+      DAC960_V2_ScatterGatherSegment_T
+	*ScatterGatherList = Command->V2.ScatterGatherList;
+      BufferHeader_T *BufferHeader = Command->BufferHeader;
+      char *LastDataEndPointer = NULL;
+      int SegmentNumber = 0;
+      if (Command->SegmentCount > 2)
+	{
+	  CommandMailbox->SCSI_10.CommandControlBits
+			 .AdditionalScatterGatherListMemory = true;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			 .ExtendedScatterGather.ScatterGatherList0Length =
+	    Command->SegmentCount;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+			 .ExtendedScatterGather.ScatterGatherList0Address =
+	    Virtual_to_Bus(ScatterGatherList);
+	}
+      else
+	ScatterGatherList =
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments;
+      while (BufferHeader != NULL)
+	{
+	  if (BufferHeader->b_data == LastDataEndPointer)
+	    {
+	      ScatterGatherList[SegmentNumber-1].SegmentByteCount +=
+		BufferHeader->b_size;
+	      LastDataEndPointer += BufferHeader->b_size;
+	    }
+	  else
+	    {
+	      ScatterGatherList[SegmentNumber].SegmentDataPointer =
+		Virtual_to_Bus(BufferHeader->b_data);
+	      ScatterGatherList[SegmentNumber].SegmentByteCount =
+		BufferHeader->b_size;
+	      LastDataEndPointer = BufferHeader->b_data + BufferHeader->b_size;
+	      if (SegmentNumber++ > Controller->DriverScatterGatherLimit)
 		panic("DAC960: Scatter/Gather Segment Overflow\n");
 	    }
 	  BufferHeader = BufferHeader->b_reqnext;
@@ -1462,6 +2681,48 @@
 	panic("DAC960: SegmentNumber != SegmentCount\n");
     }
   DAC960_QueueCommand(Command);
+}
+
+
+/*
+  DAC960_ProcessRequest attempts to remove one I/O Request from Controller's
+  I/O Request Queue and queues it to the Controller.  WaitForCommand is true if
+  this function should wait for a Command to become available if necessary.
+  This function returns true if an I/O Request was queued and false otherwise.
+*/
+
+static boolean DAC960_ProcessRequest(DAC960_Controller_T *Controller,
+				     boolean WaitForCommand)
+{
+  IO_Request_T **RequestQueuePointer =
+    &blk_dev[DAC960_MAJOR + Controller->ControllerNumber].current_request;
+  IO_Request_T *Request;
+  DAC960_Command_T *Command;
+  while (true)
+    {
+      Request = *RequestQueuePointer;
+      if (Request == NULL || Request->rq_status == RQ_INACTIVE) return false;
+      Command = DAC960_AllocateCommand(Controller);
+      if (Command != NULL) break;
+      if (!WaitForCommand) return false;
+      DAC960_WaitForCommand(Controller);
+    }
+  if (Request->cmd == READ)
+    Command->CommandType = DAC960_ReadCommand;
+  else Command->CommandType = DAC960_WriteCommand;
+  Command->Semaphore = Request->sem;
+  Command->LogicalDriveNumber = DAC960_LogicalDriveNumber(Request->rq_dev);
+  Command->BlockNumber =
+    Request->sector
+    + Controller->GenericDiskInfo.part[MINOR(Request->rq_dev)].start_sect;
+  Command->BlockCount = Request->nr_sectors;
+  Command->SegmentCount = Request->nr_segments;
+  Command->BufferHeader = Request->bh;
+  Command->RequestBuffer = Request->buffer;
+  Request->rq_status = RQ_INACTIVE;
+  *RequestQueuePointer = Request->next;
+  DAC960_QueueReadWriteCommand(Command);
+  wake_up(&wait_for_request);
   return true;
 }
 
@@ -1663,14 +2924,26 @@
 
 
 /*
-  DAC960_ReadWriteError prints an appropriate error message for Command when
-  an error occurs on a Read or Write operation.
+  DAC960_ProcessCompletedBuffer performs completion processing for an
+  individual Buffer.
+*/
+
+static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
+						 boolean SuccessfulIO)
+{
+  BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
+}
+
+
+/*
+  DAC960_V1_ReadWriteError prints an appropriate error message for Command
+  when an error occurs on a Read or Write operation.
 */
 
-static void DAC960_ReadWriteError(DAC960_Command_T *Command)
+static void DAC960_V1_ReadWriteError(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
-  char *CommandName = "UNKNOWN";
+  unsigned char *CommandName = "UNKNOWN";
   switch (Command->CommandType)
     {
     case DAC960_ReadCommand:
@@ -1686,26 +2959,26 @@
     case DAC960_QueuedCommand:
       break;
     }
-  switch (Command->CommandStatus)
+  switch (Command->V1.CommandStatus)
     {
-    case DAC960_IrrecoverableDataError:
+    case DAC960_V1_IrrecoverableDataError:
       DAC960_Error("Irrecoverable Data Error on %s:\n",
 		   Controller, CommandName);
       break;
-    case DAC960_LogicalDriveNonexistentOrOffline:
+    case DAC960_V1_LogicalDriveNonexistentOrOffline:
       DAC960_Error("Logical Drive Nonexistent or Offline on %s:\n",
 		   Controller, CommandName);
       break;
-    case DAC960_AccessBeyondEndOfLogicalDrive:
+    case DAC960_V1_AccessBeyondEndOfLogicalDrive:
       DAC960_Error("Attempt to Access Beyond End of Logical Drive "
 		   "on %s:\n", Controller, CommandName);
       break;
-    case DAC960_BadDataEncountered:
+    case DAC960_V1_BadDataEncountered:
       DAC960_Error("Bad Data Encountered on %s:\n", Controller, CommandName);
       break;
     default:
       DAC960_Error("Unexpected Error Status %04X on %s:\n",
-		   Controller, Command->CommandStatus, CommandName);
+		   Controller, Command->V1.CommandStatus, CommandName);
       break;
     }
   DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
@@ -1723,33 +2996,22 @@
 
 
 /*
-  DAC960_ProcessCompletedBuffer performs completion processing for an
-  individual Buffer.
-*/
-
-static inline void DAC960_ProcessCompletedBuffer(BufferHeader_T *BufferHeader,
-						 boolean SuccessfulIO)
-{
-  BufferHeader->b_end_io(BufferHeader, SuccessfulIO);
-}
-
-
-/*
-  DAC960_ProcessCompletedCommand performs completion processing for Command.
+  DAC960_V1_ProcessCompletedCommand performs completion processing for Command
+  for DAC960 V1 Firmware Controllers.
 */
 
-static void DAC960_ProcessCompletedCommand(DAC960_Command_T *Command)
+static void DAC960_V1_ProcessCompletedCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
   DAC960_CommandType_T CommandType = Command->CommandType;
-  DAC960_CommandOpcode_T CommandOpcode =
-    Command->CommandMailbox.Common.CommandOpcode;
-  DAC960_CommandStatus_T CommandStatus = Command->CommandStatus;
+  DAC960_V1_CommandOpcode_T CommandOpcode =
+    Command->V1.CommandMailbox.Common.CommandOpcode;
+  DAC960_V1_CommandStatus_T CommandStatus = Command->V1.CommandStatus;
   BufferHeader_T *BufferHeader = Command->BufferHeader;
   if (CommandType == DAC960_ReadCommand ||
       CommandType == DAC960_WriteCommand)
     {
-      if (CommandStatus == DAC960_NormalCompletion)
+      if (CommandStatus == DAC960_V1_NormalCompletion)
 	{
 	  /*
 	    Perform completion processing for all buffers in this I/O Request.
@@ -1771,21 +3033,22 @@
 	    }
 	  add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
 	}
-      else if ((CommandStatus == DAC960_IrrecoverableDataError ||
-		CommandStatus == DAC960_BadDataEncountered) &&
+      else if ((CommandStatus == DAC960_V1_IrrecoverableDataError ||
+		CommandStatus == DAC960_V1_BadDataEncountered) &&
 	       BufferHeader != NULL &&
 	       BufferHeader->b_reqnext != NULL)
 	{
-	  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
+	  DAC960_V1_CommandMailbox_T *CommandMailbox =
+	    &Command->V1.CommandMailbox;
 	  if (CommandType == DAC960_ReadCommand)
 	    {
 	      Command->CommandType = DAC960_ReadRetryCommand;
-	      CommandMailbox->Type5.CommandOpcode = DAC960_Read;
+	      CommandMailbox->Type5.CommandOpcode = DAC960_V1_Read;
 	    }
 	  else
 	    {
 	      Command->CommandType = DAC960_WriteRetryCommand;
-	      CommandMailbox->Type5.CommandOpcode = DAC960_Write;
+	      CommandMailbox->Type5.CommandOpcode = DAC960_V1_Write;
 	    }
 	  Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
 	  CommandMailbox->Type5.LD.TransferLength = Command->BlockCount;
@@ -1796,8 +3059,8 @@
 	}
       else
 	{
-	  if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
-	    DAC960_ReadWriteError(Command);
+	  if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+	    DAC960_V1_ReadWriteError(Command);
 	  /*
 	    Perform completion processing for all buffers in this I/O Request.
 	  */
@@ -1826,17 +3089,18 @@
       /*
 	Perform completion processing for this single buffer.
       */
-      if (CommandStatus == DAC960_NormalCompletion)
+      if (CommandStatus == DAC960_V1_NormalCompletion)
 	DAC960_ProcessCompletedBuffer(BufferHeader, true);
       else
 	{
-	  if (CommandStatus != DAC960_LogicalDriveNonexistentOrOffline)
-	    DAC960_ReadWriteError(Command);
+	  if (CommandStatus != DAC960_V1_LogicalDriveNonexistentOrOffline)
+	    DAC960_V1_ReadWriteError(Command);
 	  DAC960_ProcessCompletedBuffer(BufferHeader, false);
 	}
       if (NextBufferHeader != NULL)
 	{
-	  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
+	  DAC960_V1_CommandMailbox_T *CommandMailbox =
+	    &Command->V1.CommandMailbox;
 	  Command->BlockNumber +=
 	    BufferHeader->b_size >> DAC960_BlockSizeBits;
 	  Command->BlockCount =
@@ -1851,30 +3115,43 @@
 	}
     }
   else if (CommandType == DAC960_MonitoringCommand ||
-	   CommandOpcode == DAC960_Enquiry ||
-	   CommandOpcode == DAC960_GetRebuildProgress)
+	   CommandOpcode == DAC960_V1_Enquiry ||
+	   CommandOpcode == DAC960_V1_GetRebuildProgress)
     {
       if (CommandType != DAC960_MonitoringCommand)
 	{
-	  if (CommandOpcode == DAC960_Enquiry)
-	    memcpy(&Controller->Enquiry[Controller->EnquiryIndex ^ 1],
-		   Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
-		   sizeof(DAC960_Enquiry_T));
-	  else if (CommandOpcode == DAC960_GetRebuildProgress)
-	    memcpy(&Controller->RebuildProgress,
-		   Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress),
-		   sizeof(DAC960_RebuildProgress_T));
-	}
-      if (CommandOpcode == DAC960_Enquiry)
-	{
-	  DAC960_Enquiry_T *OldEnquiry =
-	    &Controller->Enquiry[Controller->EnquiryIndex];
-	  DAC960_Enquiry_T *NewEnquiry =
-	    &Controller->Enquiry[Controller->EnquiryIndex ^= 1];
+	  if (CommandOpcode == DAC960_V1_Enquiry)
+	    memcpy(&Controller->V1.NewEnquiry,
+		   Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
+		   sizeof(DAC960_V1_Enquiry_T));
+	  else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
+	    memcpy(&Controller->V1.RebuildProgress,
+		   Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress),
+		   sizeof(DAC960_V1_RebuildProgress_T));
+	}
+      if (CommandOpcode == DAC960_V1_Enquiry &&
+	  Controller->ControllerInitialized)
+	{
+	  DAC960_V1_Enquiry_T *OldEnquiry = &Controller->V1.Enquiry;
+	  DAC960_V1_Enquiry_T *NewEnquiry = &Controller->V1.NewEnquiry;
 	  unsigned int OldCriticalLogicalDriveCount =
 	    OldEnquiry->CriticalLogicalDriveCount;
 	  unsigned int NewCriticalLogicalDriveCount =
 	    NewEnquiry->CriticalLogicalDriveCount;
+	  if (NewEnquiry->NumberOfLogicalDrives > Controller->LogicalDriveCount)
+	    {
+	      int LogicalDriveNumber = Controller->LogicalDriveCount;
+	      while (LogicalDriveNumber < NewEnquiry->NumberOfLogicalDrives)
+		{
+		  DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+				  "Now Exists\n", Controller,
+				  LogicalDriveNumber,
+				  Controller->ControllerNumber,
+				  LogicalDriveNumber);
+		  LogicalDriveNumber++;
+		}
+	      Controller->LogicalDriveCount = LogicalDriveNumber;
+	    }
 	  if (NewEnquiry->StatusFlags.DeferredWriteError !=
 	      OldEnquiry->StatusFlags.DeferredWriteError)
 	    DAC960_Critical("Deferred Write Error Flag is now %s\n", Controller,
@@ -1894,72 +3171,86 @@
 	      (jiffies - Controller->SecondaryMonitoringTime
 	       >= DAC960_SecondaryMonitoringInterval))
 	    {
-	      Controller->NeedLogicalDriveInformation = true;
-	      Controller->NewEventLogSequenceNumber =
+	      Controller->V1.NeedLogicalDriveInformation = true;
+	      Controller->V1.NewEventLogSequenceNumber =
 		NewEnquiry->EventLogSequenceNumber;
-	      Controller->NeedErrorTableInformation = true;
-	      Controller->NeedDeviceStateInformation = true;
-	      Controller->DeviceStateChannel = 0;
-	      Controller->DeviceStateTargetID = -1;
+	      Controller->V1.NeedErrorTableInformation = true;
+	      Controller->V1.NeedDeviceStateInformation = true;
+	      Controller->V1.DeviceStateChannel = 0;
+	      Controller->V1.DeviceStateTargetID = -1;
 	      Controller->SecondaryMonitoringTime = jiffies;
 	    }
-	  if (NewEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
-	      NewEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress ||
-	      OldEnquiry->RebuildFlag == DAC960_StandbyRebuildInProgress ||
-	      OldEnquiry->RebuildFlag == DAC960_BackgroundRebuildInProgress)
-	    Controller->NeedRebuildProgress = true;
-	  if (OldEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
+	  if (NewEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
+	      NewEnquiry->RebuildFlag
+	      == DAC960_V1_BackgroundRebuildInProgress ||
+	      OldEnquiry->RebuildFlag == DAC960_V1_StandbyRebuildInProgress ||
+	      OldEnquiry->RebuildFlag == DAC960_V1_BackgroundRebuildInProgress)
+	    {
+	      Controller->V1.NeedRebuildProgress = true;
+	      Controller->V1.RebuildProgressFirst =
+		(NewEnquiry->CriticalLogicalDriveCount <
+		 OldEnquiry->CriticalLogicalDriveCount);
+	    }
+	  if (OldEnquiry->RebuildFlag == DAC960_V1_BackgroundCheckInProgress)
 	    switch (NewEnquiry->RebuildFlag)
 	      {
-	      case DAC960_NoStandbyRebuildOrCheckInProgress:
+	      case DAC960_V1_NoStandbyRebuildOrCheckInProgress:
 		DAC960_Progress("Consistency Check Completed Successfully\n",
 				Controller);
 		break;
-	      case DAC960_StandbyRebuildInProgress:
-	      case DAC960_BackgroundRebuildInProgress:
+	      case DAC960_V1_StandbyRebuildInProgress:
+	      case DAC960_V1_BackgroundRebuildInProgress:
 		break;
-	      case DAC960_BackgroundCheckInProgress:
-		Controller->NeedConsistencyCheckProgress = true;
+	      case DAC960_V1_BackgroundCheckInProgress:
+		Controller->V1.NeedConsistencyCheckProgress = true;
 		break;
-	      case DAC960_StandbyRebuildCompletedWithError:
+	      case DAC960_V1_StandbyRebuildCompletedWithError:
 		DAC960_Progress("Consistency Check Completed with Error\n",
 				Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckFailed_DriveFailed:
+	      case DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed:
 		DAC960_Progress("Consistency Check Failed - "
-				"Physical Drive Failed\n", Controller);
+				"Physical Device Failed\n", Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
+	      case DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed:
 		DAC960_Progress("Consistency Check Failed - "
 				"Logical Drive Failed\n", Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckFailed_OtherCauses:
+	      case DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses:
 		DAC960_Progress("Consistency Check Failed - Other Causes\n",
 				Controller);
 		break;
-	      case DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated:
+	      case DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated:
 		DAC960_Progress("Consistency Check Successfully Terminated\n",
 				Controller);
 		break;
 	      }
-	  else if (NewEnquiry->RebuildFlag == DAC960_BackgroundCheckInProgress)
-	    Controller->NeedConsistencyCheckProgress = true;
+	  else if (NewEnquiry->RebuildFlag
+		   == DAC960_V1_BackgroundCheckInProgress)
+	    Controller->V1.NeedConsistencyCheckProgress = true;
+	  Controller->MonitoringAlertMode =
+	    (NewEnquiry->CriticalLogicalDriveCount > 0 ||
+	     NewEnquiry->OfflineLogicalDriveCount > 0 ||
+	     NewEnquiry->DeadDriveCount > 0);
 	  if (CommandType != DAC960_MonitoringCommand &&
-	      Controller->RebuildFlagPending)
+	      Controller->V1.RebuildFlagPending)
 	    {
-	      DAC960_Enquiry_T *Enquiry = (DAC960_Enquiry_T *)
-		Bus_to_Virtual(Command->CommandMailbox.Type3.BusAddress);
-	      Enquiry->RebuildFlag = Controller->PendingRebuildFlag;
-	      Controller->RebuildFlagPending = false;
+	      DAC960_V1_Enquiry_T *Enquiry = (DAC960_V1_Enquiry_T *)
+		Bus_to_Virtual(Command->V1.CommandMailbox.Type3.BusAddress);
+	      Enquiry->RebuildFlag = Controller->V1.PendingRebuildFlag;
+	      Controller->V1.RebuildFlagPending = false;
 	    }
 	  else if (CommandType == DAC960_MonitoringCommand &&
-		   NewEnquiry->RebuildFlag > DAC960_BackgroundCheckInProgress)
+		   NewEnquiry->RebuildFlag >
+		   DAC960_V1_BackgroundCheckInProgress)
 	    {
-	      Controller->PendingRebuildFlag = NewEnquiry->RebuildFlag;
-	      Controller->RebuildFlagPending = true;
+	      Controller->V1.PendingRebuildFlag = NewEnquiry->RebuildFlag;
+	      Controller->V1.RebuildFlagPending = true;
 	    }
+	  memcpy(&Controller->V1.Enquiry, &Controller->V1.NewEnquiry,
+		 sizeof(DAC960_V1_Enquiry_T));
 	}
-      else if (CommandOpcode == DAC960_PerformEventLogOperation)
+      else if (CommandOpcode == DAC960_V1_PerformEventLogOperation)
 	{
 	  static char
 	    *DAC960_EventMessages[] =
@@ -1976,37 +3267,39 @@
 		 "killed because of selection timeout",
 		 "killed due to SCSI phase sequence error",
 		 "killed due to unknown status" };
-	  DAC960_EventLogEntry_T *EventLogEntry = &Controller->EventLogEntry;
+	  DAC960_V1_EventLogEntry_T *EventLogEntry =
+	    &Controller->V1.EventLogEntry;
 	  if (EventLogEntry->SequenceNumber ==
-	      Controller->OldEventLogSequenceNumber)
+	      Controller->V1.OldEventLogSequenceNumber)
 	    {
 	      unsigned char SenseKey = EventLogEntry->SenseKey;
 	      unsigned char AdditionalSenseCode =
 		EventLogEntry->AdditionalSenseCode;
 	      unsigned char AdditionalSenseCodeQualifier =
 		EventLogEntry->AdditionalSenseCodeQualifier;
-	      if (SenseKey == 9 &&
+	      if (SenseKey == DAC960_SenseKey_VendorSpecific &&
 		  AdditionalSenseCode == 0x80 &&
 		  AdditionalSenseCodeQualifier <
 		  sizeof(DAC960_EventMessages) / sizeof(char *))
-		DAC960_Critical("Physical Drive %d:%d %s\n", Controller,
+		DAC960_Critical("Physical Device %d:%d %s\n", Controller,
 				EventLogEntry->Channel,
 				EventLogEntry->TargetID,
 				DAC960_EventMessages[
 				  AdditionalSenseCodeQualifier]);
-	      else if (SenseKey == 6 && AdditionalSenseCode == 0x29)
+	      else if (SenseKey == DAC960_SenseKey_UnitAttention &&
+		       AdditionalSenseCode == 0x29)
 		{
 		  if (Controller->MonitoringTimerCount > 0)
-		    Controller->DeviceResetCount[EventLogEntry->Channel]
-						[EventLogEntry->TargetID]++;
+		    Controller->V1.DeviceResetCount[EventLogEntry->Channel]
+						   [EventLogEntry->TargetID]++;
 		}
-	      else if (!(SenseKey == 0 ||
-			 (SenseKey == 2 &&
+	      else if (!(SenseKey == DAC960_SenseKey_NoSense ||
+			 (SenseKey == DAC960_SenseKey_NotReady &&
 			  AdditionalSenseCode == 0x04 &&
 			  (AdditionalSenseCodeQualifier == 0x01 ||
 			   AdditionalSenseCodeQualifier == 0x02))))
 		{
-		  DAC960_Critical("Physical Drive %d:%d Error Log: "
+		  DAC960_Critical("Physical Device %d:%d Error Log: "
 				  "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
 				  Controller,
 				  EventLogEntry->Channel,
@@ -2014,7 +3307,7 @@
 				  SenseKey,
 				  AdditionalSenseCode,
 				  AdditionalSenseCodeQualifier);
-		  DAC960_Critical("Physical Drive %d:%d Error Log: "
+		  DAC960_Critical("Physical Device %d:%d Error Log: "
 				  "Information = %02X%02X%02X%02X "
 				  "%02X%02X%02X%02X\n",
 				  Controller,
@@ -2030,21 +3323,19 @@
 				  EventLogEntry->CommandSpecificInformation[3]);
 		}
 	    }
-	  Controller->OldEventLogSequenceNumber++;
+	  Controller->V1.OldEventLogSequenceNumber++;
 	}
-      else if (CommandOpcode == DAC960_GetErrorTable)
+      else if (CommandOpcode == DAC960_V1_GetErrorTable)
 	{
-	  DAC960_ErrorTable_T *OldErrorTable =
-	    &Controller->ErrorTable[Controller->ErrorTableIndex];
-	  DAC960_ErrorTable_T *NewErrorTable =
-	    &Controller->ErrorTable[Controller->ErrorTableIndex ^= 1];
+	  DAC960_V1_ErrorTable_T *OldErrorTable = &Controller->V1.ErrorTable;
+	  DAC960_V1_ErrorTable_T *NewErrorTable = &Controller->V1.NewErrorTable;
 	  int Channel, TargetID;
 	  for (Channel = 0; Channel < Controller->Channels; Channel++)
-	    for (TargetID = 0; TargetID < DAC960_MaxTargets; TargetID++)
+	    for (TargetID = 0; TargetID < Controller->Targets; TargetID++)
 	      {
-		DAC960_ErrorTableEntry_T *NewErrorEntry =
+		DAC960_V1_ErrorTableEntry_T *NewErrorEntry =
 		  &NewErrorTable->ErrorTableEntries[Channel][TargetID];
-		DAC960_ErrorTableEntry_T *OldErrorEntry =
+		DAC960_V1_ErrorTableEntry_T *OldErrorEntry =
 		  &OldErrorTable->ErrorTableEntries[Channel][TargetID];
 		if ((NewErrorEntry->ParityErrorCount !=
 		     OldErrorEntry->ParityErrorCount) ||
@@ -2054,7 +3345,7 @@
 		     OldErrorEntry->HardErrorCount) ||
 		    (NewErrorEntry->MiscErrorCount !=
 		     OldErrorEntry->MiscErrorCount))
-		  DAC960_Critical("Physical Drive %d:%d Errors: "
+		  DAC960_Critical("Physical Device %d:%d Errors: "
 				  "Parity = %d, Soft = %d, "
 				  "Hard = %d, Misc = %d\n",
 				  Controller, Channel, TargetID,
@@ -2063,51 +3354,49 @@
 				  NewErrorEntry->HardErrorCount,
 				  NewErrorEntry->MiscErrorCount);
 	      }
+	  memcpy(&Controller->V1.ErrorTable, &Controller->V1.NewErrorTable,
+		 sizeof(DAC960_V1_ErrorTable_T));
 	}
-      else if (CommandOpcode == DAC960_GetDeviceState)
+      else if (CommandOpcode == DAC960_V1_GetDeviceState)
 	{
-	  DAC960_DeviceState_T *OldDeviceState =
-	    &Controller->DeviceState[Controller->DeviceStateIndex]
-				    [Controller->DeviceStateChannel]
-				    [Controller->DeviceStateTargetID];
-	  DAC960_DeviceState_T *NewDeviceState =
-	    &Controller->DeviceState[Controller->DeviceStateIndex ^ 1]
-				    [Controller->DeviceStateChannel]
-				    [Controller->DeviceStateTargetID];
+	  DAC960_V1_DeviceState_T *OldDeviceState =
+	    &Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
+				       [Controller->V1.DeviceStateTargetID];
+	  DAC960_V1_DeviceState_T *NewDeviceState =
+	    &Controller->V1.NewDeviceState;
 	  if (NewDeviceState->DeviceState != OldDeviceState->DeviceState)
-	    DAC960_Critical("Physical Drive %d:%d is now %s\n", Controller,
-			    Controller->DeviceStateChannel,
-			    Controller->DeviceStateTargetID,
-			    (NewDeviceState->DeviceState == DAC960_Device_Dead
+	    DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
+			    Controller->V1.DeviceStateChannel,
+			    Controller->V1.DeviceStateTargetID,
+			    (NewDeviceState->DeviceState
+			     == DAC960_V1_Device_Dead
 			     ? "DEAD"
 			     : NewDeviceState->DeviceState
-			       == DAC960_Device_WriteOnly
+			       == DAC960_V1_Device_WriteOnly
 			       ? "WRITE-ONLY"
 			       : NewDeviceState->DeviceState
-				 == DAC960_Device_Online
+				 == DAC960_V1_Device_Online
 				 ? "ONLINE" : "STANDBY"));
-	  if (OldDeviceState->DeviceState == DAC960_Device_Dead &&
-	      NewDeviceState->DeviceState != DAC960_Device_Dead)
+	  if (OldDeviceState->DeviceState == DAC960_V1_Device_Dead &&
+	      NewDeviceState->DeviceState != DAC960_V1_Device_Dead)
 	    {
-	      Controller->NeedDeviceInquiryInformation = true;
-	      Controller->NeedDeviceSerialNumberInformation = true;
+	      Controller->V1.NeedDeviceInquiryInformation = true;
+	      Controller->V1.NeedDeviceSerialNumberInformation = true;
 	    }
+	  memcpy(OldDeviceState, NewDeviceState,
+		 sizeof(DAC960_V1_DeviceState_T));
 	}
-      else if (CommandOpcode == DAC960_GetLogicalDriveInformation)
+      else if (CommandOpcode == DAC960_V1_GetLogicalDriveInformation)
 	{
 	  int LogicalDriveNumber;
 	  for (LogicalDriveNumber = 0;
 	       LogicalDriveNumber < Controller->LogicalDriveCount;
 	       LogicalDriveNumber++)
 	    {
-	      DAC960_LogicalDriveInformation_T *OldLogicalDriveInformation =
-		&Controller->LogicalDriveInformation
-			     [Controller->LogicalDriveInformationIndex]
-			     [LogicalDriveNumber];
-	      DAC960_LogicalDriveInformation_T *NewLogicalDriveInformation =
-		&Controller->LogicalDriveInformation
-			     [Controller->LogicalDriveInformationIndex ^ 1]
-			     [LogicalDriveNumber];
+	      DAC960_V1_LogicalDriveInformation_T *OldLogicalDriveInformation =
+		&Controller->V1.LogicalDriveInformation[LogicalDriveNumber];
+	      DAC960_V1_LogicalDriveInformation_T *NewLogicalDriveInformation =
+		&Controller->V1.NewLogicalDriveInformation[LogicalDriveNumber];
 	      if (NewLogicalDriveInformation->LogicalDriveState !=
 		  OldLogicalDriveInformation->LogicalDriveState)
 		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2116,11 +3405,11 @@
 				Controller->ControllerNumber,
 				LogicalDriveNumber,
 				(NewLogicalDriveInformation->LogicalDriveState
-				 == DAC960_LogicalDrive_Online
+				 == DAC960_V1_LogicalDrive_Online
 				 ? "ONLINE"
 				 : NewLogicalDriveInformation->LogicalDriveState
-				 == DAC960_LogicalDrive_Critical
-				 ? "CRITICAL" : "OFFLINE"));
+				   == DAC960_V1_LogicalDrive_Critical
+				   ? "CRITICAL" : "OFFLINE"));
 	      if (NewLogicalDriveInformation->WriteBack !=
 		  OldLogicalDriveInformation->WriteBack)
 		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2131,22 +3420,24 @@
 				(NewLogicalDriveInformation->WriteBack
 				 ? "WRITE BACK" : "WRITE THRU"));
 	    }
-	  Controller->LogicalDriveInformationIndex ^= 1;
+	  memcpy(&Controller->V1.LogicalDriveInformation,
+		 &Controller->V1.NewLogicalDriveInformation,
+		 sizeof(DAC960_V1_LogicalDriveInformationArray_T));
 	}
-      else if (CommandOpcode == DAC960_GetRebuildProgress)
+      else if (CommandOpcode == DAC960_V1_GetRebuildProgress)
 	{
 	  unsigned int LogicalDriveNumber =
-	    Controller->RebuildProgress.LogicalDriveNumber;
+	    Controller->V1.RebuildProgress.LogicalDriveNumber;
 	  unsigned int LogicalDriveSize =
-	    Controller->RebuildProgress.LogicalDriveSize;
+	    Controller->V1.RebuildProgress.LogicalDriveSize;
 	  unsigned int BlocksCompleted =
-	    LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
-	  if (CommandStatus == DAC960_NoRebuildOrCheckInProgress &&
-	      Controller->LastRebuildStatus == DAC960_NormalCompletion)
-	    CommandStatus = DAC960_RebuildSuccessful;
+	    LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+	  if (CommandStatus == DAC960_V1_NoRebuildOrCheckInProgress &&
+	      Controller->V1.LastRebuildStatus == DAC960_V1_NormalCompletion)
+	    CommandStatus = DAC960_V1_RebuildSuccessful;
 	  switch (CommandStatus)
 	    {
-	    case DAC960_NormalCompletion:
+	    case DAC960_V1_NormalCompletion:
 	      Controller->EphemeralProgressMessage = true;
 	      DAC960_Progress("Rebuild in Progress: "
 			      "Logical Drive %d (/dev/rd/c%dd%d) "
@@ -2158,244 +3449,1061 @@
 			      / (LogicalDriveSize >> 7));
 	      Controller->EphemeralProgressMessage = false;
 	      break;
-	    case DAC960_RebuildFailed_LogicalDriveFailure:
+	    case DAC960_V1_RebuildFailed_LogicalDriveFailure:
 	      DAC960_Progress("Rebuild Failed due to "
 			      "Logical Drive Failure\n", Controller);
 	      break;
-	    case DAC960_RebuildFailed_BadBlocksOnOther:
+	    case DAC960_V1_RebuildFailed_BadBlocksOnOther:
 	      DAC960_Progress("Rebuild Failed due to "
 			      "Bad Blocks on Other Drives\n", Controller);
 	      break;
-	    case DAC960_RebuildFailed_NewDriveFailed:
+	    case DAC960_V1_RebuildFailed_NewDriveFailed:
 	      DAC960_Progress("Rebuild Failed due to "
 			      "Failure of Drive Being Rebuilt\n", Controller);
 	      break;
-	    case DAC960_NoRebuildOrCheckInProgress:
+	    case DAC960_V1_NoRebuildOrCheckInProgress:
 	      break;
-	    case DAC960_RebuildSuccessful:
+	    case DAC960_V1_RebuildSuccessful:
 	      DAC960_Progress("Rebuild Completed Successfully\n", Controller);
 	      break;
-	    case DAC960_RebuildSuccessfullyTerminated:
+	    case DAC960_V1_RebuildSuccessfullyTerminated:
 	      DAC960_Progress("Rebuild Successfully Terminated\n", Controller);
 	      break;
 	    }
-	  Controller->LastRebuildStatus = CommandStatus;
+	  Controller->V1.LastRebuildStatus = CommandStatus;
 	  if (CommandType != DAC960_MonitoringCommand &&
-	      Controller->RebuildStatusPending)
+	      Controller->V1.RebuildStatusPending)
+	    {
+	      Command->V1.CommandStatus = Controller->V1.PendingRebuildStatus;
+	      Controller->V1.RebuildStatusPending = false;
+	    }
+	  else if (CommandType == DAC960_MonitoringCommand &&
+		   CommandStatus != DAC960_V1_NormalCompletion &&
+		   CommandStatus != DAC960_V1_NoRebuildOrCheckInProgress)
+	    {
+	      Controller->V1.PendingRebuildStatus = CommandStatus;
+	      Controller->V1.RebuildStatusPending = true;
+	    }
+	}
+      else if (CommandOpcode == DAC960_V1_RebuildStat)
+	{
+	  unsigned int LogicalDriveNumber =
+	    Controller->V1.RebuildProgress.LogicalDriveNumber;
+	  unsigned int LogicalDriveSize =
+	    Controller->V1.RebuildProgress.LogicalDriveSize;
+	  unsigned int BlocksCompleted =
+	    LogicalDriveSize - Controller->V1.RebuildProgress.RemainingBlocks;
+	  if (CommandStatus == DAC960_V1_NormalCompletion)
+	    {
+	      Controller->EphemeralProgressMessage = true;
+	      DAC960_Progress("Consistency Check in Progress: "
+			      "Logical Drive %d (/dev/rd/c%dd%d) "
+			      "%d%% completed\n",
+			      Controller, LogicalDriveNumber,
+			      Controller->ControllerNumber,
+			      LogicalDriveNumber,
+			      (100 * (BlocksCompleted >> 7))
+			      / (LogicalDriveSize >> 7));
+	      Controller->EphemeralProgressMessage = false;
+	    }
+	}
+    }
+  if (CommandType == DAC960_MonitoringCommand)
+    {
+      if (Controller->V1.NewEventLogSequenceNumber
+	  - Controller->V1.OldEventLogSequenceNumber > 0)
+	{
+	  Command->V1.CommandMailbox.Type3E.CommandOpcode =
+	    DAC960_V1_PerformEventLogOperation;
+	  Command->V1.CommandMailbox.Type3E.OperationType =
+	    DAC960_V1_GetEventLogEntry;
+	  Command->V1.CommandMailbox.Type3E.OperationQualifier = 1;
+	  Command->V1.CommandMailbox.Type3E.SequenceNumber =
+	    Controller->V1.OldEventLogSequenceNumber;
+	  Command->V1.CommandMailbox.Type3E.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.EventLogEntry);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedErrorTableInformation)
+	{
+	  Controller->V1.NeedErrorTableInformation = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetErrorTable;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.NewErrorTable);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedRebuildProgress &&
+	  Controller->V1.RebuildProgressFirst)
+	{
+	  Controller->V1.NeedRebuildProgress = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetRebuildProgress;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.RebuildProgress);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedDeviceStateInformation)
+	{
+	  if (Controller->V1.NeedDeviceInquiryInformation)
+	    {
+	      DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
+	      DAC960_SCSI_Inquiry_T *InquiryStandardData =
+		&Controller->V1.InquiryStandardData
+				[Controller->V1.DeviceStateChannel]
+				[Controller->V1.DeviceStateTargetID];
+	      InquiryStandardData->PeripheralDeviceType = 0x1F;
+	      Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+	      Command->V1.CommandMailbox.Type3.BusAddress =
+		Virtual_to_Bus(DCDB);
+	      DCDB->Channel = Controller->V1.DeviceStateChannel;
+	      DCDB->TargetID = Controller->V1.DeviceStateTargetID;
+	      DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
+	      DCDB->EarlyStatus = false;
+	      DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
+	      DCDB->NoAutomaticRequestSense = false;
+	      DCDB->DisconnectPermitted = true;
+	      DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
+	      DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
+	      DCDB->CDBLength = 6;
+	      DCDB->TransferLengthHigh4 = 0;
+	      DCDB->SenseLength = sizeof(DCDB->SenseData);
+	      DCDB->CDB[0] = 0x12; /* INQUIRY */
+	      DCDB->CDB[1] = 0; /* EVPD = 0 */
+	      DCDB->CDB[2] = 0; /* Page Code */
+	      DCDB->CDB[3] = 0; /* Reserved */
+	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
+	      DCDB->CDB[5] = 0; /* Control */
+	      DAC960_QueueCommand(Command);
+	      Controller->V1.NeedDeviceInquiryInformation = false;
+	      return;
+	    }
+	  if (Controller->V1.NeedDeviceSerialNumberInformation)
+	    {
+	      DAC960_V1_DCDB_T *DCDB = &Controller->V1.MonitoringDCDB;
+	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+		&Controller->V1.InquiryUnitSerialNumber
+				[Controller->V1.DeviceStateChannel]
+				[Controller->V1.DeviceStateTargetID];
+	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+	      Command->V1.CommandMailbox.Type3.CommandOpcode = DAC960_V1_DCDB;
+	      Command->V1.CommandMailbox.Type3.BusAddress =
+		Virtual_to_Bus(DCDB);
+	      DCDB->Channel = Controller->V1.DeviceStateChannel;
+	      DCDB->TargetID = Controller->V1.DeviceStateTargetID;
+	      DCDB->Direction = DAC960_V1_DCDB_DataTransferDeviceToSystem;
+	      DCDB->EarlyStatus = false;
+	      DCDB->Timeout = DAC960_V1_DCDB_Timeout_10_seconds;
+	      DCDB->NoAutomaticRequestSense = false;
+	      DCDB->DisconnectPermitted = true;
+	      DCDB->TransferLength =
+		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
+	      DCDB->CDBLength = 6;
+	      DCDB->TransferLengthHigh4 = 0;
+	      DCDB->SenseLength = sizeof(DCDB->SenseData);
+	      DCDB->CDB[0] = 0x12; /* INQUIRY */
+	      DCDB->CDB[1] = 1; /* EVPD = 1 */
+	      DCDB->CDB[2] = 0x80; /* Page Code */
+	      DCDB->CDB[3] = 0; /* Reserved */
+	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      DCDB->CDB[5] = 0; /* Control */
+	      DAC960_QueueCommand(Command);
+	      Controller->V1.NeedDeviceSerialNumberInformation = false;
+	      return;
+	    }
+	  if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
+	    {
+	      Controller->V1.DeviceStateChannel++;
+	      Controller->V1.DeviceStateTargetID = 0;
+	    }
+	  while (Controller->V1.DeviceStateChannel < Controller->Channels)
+	    {
+	      DAC960_V1_DeviceState_T *OldDeviceState =
+		&Controller->V1.DeviceState[Controller->V1.DeviceStateChannel]
+					   [Controller->V1.DeviceStateTargetID];
+	      if (OldDeviceState->Present &&
+		  OldDeviceState->DeviceType == DAC960_V1_DiskType)
+		{
+		  Command->V1.CommandMailbox.Type3D.CommandOpcode =
+		    DAC960_V1_GetDeviceState;
+		  Command->V1.CommandMailbox.Type3D.Channel =
+		    Controller->V1.DeviceStateChannel;
+		  Command->V1.CommandMailbox.Type3D.TargetID =
+		    Controller->V1.DeviceStateTargetID;
+		  Command->V1.CommandMailbox.Type3D.BusAddress =
+		    Virtual_to_Bus(&Controller->V1.NewDeviceState);
+		  DAC960_QueueCommand(Command);
+		  return;
+		}
+	      if (++Controller->V1.DeviceStateTargetID == Controller->Targets)
+		{
+		  Controller->V1.DeviceStateChannel++;
+		  Controller->V1.DeviceStateTargetID = 0;
+		}
+	    }
+	  Controller->V1.NeedDeviceStateInformation = false;
+	}
+      if (Controller->V1.NeedLogicalDriveInformation)
+	{
+	  Controller->V1.NeedLogicalDriveInformation = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetLogicalDriveInformation;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.NewLogicalDriveInformation);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedRebuildProgress)
+	{
+	  Controller->V1.NeedRebuildProgress = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_GetRebuildProgress;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.RebuildProgress);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      if (Controller->V1.NeedConsistencyCheckProgress)
+	{
+	  Controller->V1.NeedConsistencyCheckProgress = false;
+	  Command->V1.CommandMailbox.Type3.CommandOpcode =
+	    DAC960_V1_RebuildStat;
+	  Command->V1.CommandMailbox.Type3.BusAddress =
+	    Virtual_to_Bus(&Controller->V1.RebuildProgress);
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      Controller->MonitoringTimerCount++;
+      Controller->MonitoringTimer.expires =
+	jiffies + DAC960_MonitoringTimerInterval;
+      add_timer(&Controller->MonitoringTimer);
+    }
+  if (CommandType == DAC960_ImmediateCommand)
+    {
+      up(Command->Semaphore);
+      Command->Semaphore = NULL;
+      return;
+    }
+  if (CommandType == DAC960_QueuedCommand)
+    {
+      DAC960_V1_KernelCommand_T *KernelCommand = Command->V1.KernelCommand;
+      KernelCommand->CommandStatus = Command->V1.CommandStatus;
+      Command->V1.KernelCommand = NULL;
+      if (CommandOpcode == DAC960_V1_DCDB)
+	Controller->V1.DirectCommandActive[KernelCommand->DCDB->Channel]
+					  [KernelCommand->DCDB->TargetID] =
+	  false;
+      DAC960_DeallocateCommand(Command);
+      KernelCommand->CompletionFunction(KernelCommand);
+      return;
+    }
+  /*
+    Queue a Status Monitoring Command to the Controller using the just
+    completed Command if one was deferred previously due to lack of a
+    free Command when the Monitoring Timer Function was called.
+  */
+  if (Controller->MonitoringCommandDeferred)
+    {
+      Controller->MonitoringCommandDeferred = false;
+      DAC960_V1_QueueMonitoringCommand(Command);
+      return;
+    }
+  /*
+    Deallocate the Command.
+  */
+  DAC960_DeallocateCommand(Command);
+  /*
+    Wake up any processes waiting on a free Command.
+  */
+  wake_up(&Controller->CommandWaitQueue);
+}
+
+
+/*
+  DAC960_V2_ReadWriteError prints an appropriate error message for Command
+  when an error occurs on a Read or Write operation.
+*/
+
+static void DAC960_V2_ReadWriteError(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  unsigned char *SenseErrors[] = { "NO SENSE", "RECOVERED ERROR",
+				   "NOT READY", "MEDIUM ERROR",
+				   "HARDWARE ERROR", "ILLEGAL REQUEST",
+				   "UNIT ATTENTION", "DATA PROTECT",
+				   "BLANK CHECK", "VENDOR-SPECIFIC",
+				   "COPY ABORTED", "ABORTED COMMAND",
+				   "EQUAL", "VOLUME OVERFLOW",
+				   "MISCOMPARE", "RESERVED" };
+  unsigned char *CommandName = "UNKNOWN";
+  switch (Command->CommandType)
+    {
+    case DAC960_ReadCommand:
+    case DAC960_ReadRetryCommand:
+      CommandName = "READ";
+      break;
+    case DAC960_WriteCommand:
+    case DAC960_WriteRetryCommand:
+      CommandName = "WRITE";
+      break;
+    case DAC960_MonitoringCommand:
+    case DAC960_ImmediateCommand:
+    case DAC960_QueuedCommand:
+      break;
+    }
+  DAC960_Error("Error Condition %s on %s:\n", Controller,
+	       SenseErrors[Command->V2.RequestSense.SenseKey], CommandName);
+  DAC960_Error("  /dev/rd/c%dd%d:   absolute blocks %d..%d\n",
+	       Controller, Controller->ControllerNumber,
+	       Command->LogicalDriveNumber, Command->BlockNumber,
+	       Command->BlockNumber + Command->BlockCount - 1);
+  if (DAC960_PartitionNumber(Command->BufferHeader->b_rdev) > 0)
+    DAC960_Error("  /dev/rd/c%dd%dp%d: relative blocks %d..%d\n",
+		 Controller, Controller->ControllerNumber,
+		 Command->LogicalDriveNumber,
+		 DAC960_PartitionNumber(Command->BufferHeader->b_rdev),
+		 Command->BufferHeader->b_rsector,
+		 Command->BufferHeader->b_rsector + Command->BlockCount - 1);
+}
+
+
+/*
+  DAC960_V2_ReportEvent prints an appropriate message when a Controller Event
+  occurs.
+*/
+
+static void DAC960_V2_ReportEvent(DAC960_Controller_T *Controller,
+				  DAC960_V2_Event_T *Event)
+{
+  DAC960_SCSI_RequestSense_T *RequestSense =
+    (DAC960_SCSI_RequestSense_T *) &Event->RequestSenseData;
+  unsigned char MessageBuffer[DAC960_LineBufferSize];
+  static struct { int EventCode; unsigned char *EventMessage; } EventList[] =
+    { /* Physical Device Events (0x0000 - 0x007F) */
+      { 0x0001, "P Online" },
+      { 0x0002, "P Standby" },
+      { 0x0005, "P Automatic Rebuild Started" },
+      { 0x0006, "P Manual Rebuild Started" },
+      { 0x0007, "P Rebuild Completed" },
+      { 0x0008, "P Rebuild Cancelled" },
+      { 0x0009, "P Rebuild Failed for Unknown Reasons" },
+      { 0x000A, "P Rebuild Failed due to New Physical Device" },
+      { 0x000B, "P Rebuild Failed due to Logical Drive Failure" },
+      { 0x000C, "S Offline" },
+      { 0x000D, "P Found" },
+      { 0x000E, "P Gone" },
+      { 0x000F, "P Unconfigured" },
+      { 0x0010, "P Expand Capacity Started" },
+      { 0x0011, "P Expand Capacity Completed" },
+      { 0x0012, "P Expand Capacity Failed" },
+      { 0x0016, "P Parity Error" },
+      { 0x0017, "P Soft Error" },
+      { 0x0018, "P Miscellaneous Error" },
+      { 0x0019, "P Reset" },
+      { 0x001A, "P Active Spare Found" },
+      { 0x001B, "P Warm Spare Found" },
+      { 0x001C, "S Sense Data Received" },
+      { 0x001D, "P Initialization Started" },
+      { 0x001E, "P Initialization Completed" },
+      { 0x001F, "P Initialization Failed" },
+      { 0x0020, "P Initialization Cancelled" },
+      { 0x0021, "P Failed because Write Recovery Failed" },
+      { 0x0022, "P Failed because SCSI Bus Reset Failed" },
+      { 0x0023, "P Failed because of Double Check Condition" },
+      { 0x0024, "P Failed because Device Cannot Be Accessed" },
+      { 0x0025, "P Failed because of Gross Error on SCSI Processor" },
+      { 0x0026, "P Failed because of Bad Tag from Device" },
+      { 0x0027, "P Failed because of Command Timeout" },
+      { 0x0028, "P Failed because of System Reset" },
+      { 0x0029, "P Failed because of Busy Status or Parity Error" },
+      { 0x002A, "P Failed because Host Set Device to Failed State" },
+      { 0x002B, "P Failed because of Selection Timeout" },
+      { 0x002C, "P Failed because of SCSI Bus Phase Error" },
+      { 0x002D, "P Failed because Device Returned Unknown Status" },
+      { 0x002E, "P Failed because Device Not Ready" },
+      { 0x002F, "P Failed because Device Not Found at Startup" },
+      { 0x0030, "P Failed because COD Write Operation Failed" },
+      { 0x0031, "P Failed because BDT Write Operation Failed" },
+      { 0x0039, "P Missing at Startup" },
+      { 0x003A, "P Start Rebuild Failed due to Physical Drive Too Small" },
+      /* Logical Device Events (0x0080 - 0x00FF) */
+      { 0x0080, "M Consistency Check Started" },
+      { 0x0081, "M Consistency Check Completed" },
+      { 0x0082, "M Consistency Check Cancelled" },
+      { 0x0083, "M Consistency Check Completed With Errors" },
+      { 0x0084, "M Consistency Check Failed due to Logical Drive Failure" },
+      { 0x0085, "M Consistency Check Failed due to Physical Device Failure" },
+      { 0x0086, "L Offline" },
+      { 0x0087, "L Critical" },
+      { 0x0088, "L Online" },
+      { 0x0089, "M Automatic Rebuild Started" },
+      { 0x008A, "M Manual Rebuild Started" },
+      { 0x008B, "M Rebuild Completed" },
+      { 0x008C, "M Rebuild Cancelled" },
+      { 0x008D, "M Rebuild Failed for Unknown Reasons" },
+      { 0x008E, "M Rebuild Failed due to New Physical Device" },
+      { 0x008F, "M Rebuild Failed due to Logical Drive Failure" },
+      { 0x0090, "L Initialization Started" },
+      { 0x0091, "L Initialization Completed" },
+      { 0x0092, "L Initialization Cancelled" },
+      { 0x0093, "L Initialization Failed" },
+      { 0x0094, "L Found" },
+      { 0x0095, "L Gone" },
+      { 0x0096, "L Expand Capacity Started" },
+      { 0x0097, "L Expand Capacity Completed" },
+      { 0x0098, "L Expand Capacity Failed" },
+      { 0x0099, "L Bad Block Found" },
+      { 0x009A, "L Size Changed" },
+      { 0x009B, "L Type Changed" },
+      { 0x009C, "L Bad Data Block Found" },
+      { 0x009E, "L Read of Data Block in BDT" },
+      { 0x009F, "L Write Back Data for Disk Block Lost" },
+      /* Fault Management Events (0x0100 - 0x017F) */
+      { 0x0140, "E Fan %d Failed" },
+      { 0x0141, "E Fan %d OK" },
+      { 0x0142, "E Fan %d Not Present" },
+      { 0x0143, "E Power Supply %d Failed" },
+      { 0x0144, "E Power Supply %d OK" },
+      { 0x0145, "E Power Supply %d Not Present" },
+      { 0x0146, "E Temperature Sensor %d Failed" },
+      { 0x0147, "E Temperature Sensor %d Critical" },
+      { 0x0148, "E Temperature Sensor %d OK" },
+      { 0x0149, "E Temperature Sensor %d Not Present" },
+      { 0x014A, "E Unit %d Access Critical" },
+      { 0x014B, "E Unit %d Access OK" },
+      { 0x014C, "E Unit %d Access Offline" },
+      /* Controller Events (0x0180 - 0x01FF) */
+      { 0x0181, "C Cache Write Back Error" },
+      { 0x0188, "C Battery Backup Unit Found" },
+      { 0x0189, "C Battery Backup Unit Charge Level Low" },
+      { 0x018A, "C Battery Backup Unit Charge Level OK" },
+      { 0x0193, "C Installation Aborted" },
+      { 0x0195, "C Mirror Race Recovery In Progress" },
+      { 0x0196, "C Mirror Race on Critical Drive" },
+      { 0x019E, "C Memory Soft ECC Error" },
+      { 0x019F, "C Memory Hard ECC Error" },
+      { 0x01A2, "C Battery Backup Unit Failed" },
+      { 0, "" } };
+  int EventListIndex = 0, EventCode;
+  unsigned char EventType, *EventMessage;
+  while (true)
+    {
+      EventCode = EventList[EventListIndex].EventCode;
+      if (EventCode == Event->EventCode || EventCode == 0) break;
+      EventListIndex++;
+    }
+  EventType = EventList[EventListIndex].EventMessage[0];
+  EventMessage = &EventList[EventListIndex].EventMessage[2];
+  if (EventCode == 0)
+    {
+      DAC960_Critical("Unknown Controller Event Code %04X\n",
+		      Controller, Event->EventCode);
+      return;
+    }
+  switch (EventType)
+    {
+    case 'P':
+      DAC960_Critical("Physical Device %d:%d %s\n", Controller,
+		      Event->Channel, Event->TargetID, EventMessage);
+      break;
+    case 'L':
+      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
+		      Event->LogicalUnit, Controller->ControllerNumber,
+		      Event->LogicalUnit, EventMessage);
+      break;
+    case 'M':
+      DAC960_Progress("Logical Drive %d (/dev/rd/c%dd%d) %s\n", Controller,
+		      Event->LogicalUnit, Controller->ControllerNumber,
+		      Event->LogicalUnit, EventMessage);
+      break;
+    case 'S':
+      if (RequestSense->SenseKey == DAC960_SenseKey_NoSense ||
+	  (RequestSense->SenseKey == DAC960_SenseKey_NotReady &&
+	   RequestSense->AdditionalSenseCode == 0x04 &&
+	   (RequestSense->AdditionalSenseCodeQualifier == 0x01 ||
+	    RequestSense->AdditionalSenseCodeQualifier == 0x02)))
+	break;
+      DAC960_Critical("Physical Device %d:%d %s\n", Controller,
+		      Event->Channel, Event->TargetID, EventMessage);
+      DAC960_Critical("Physical Device %d:%d Request Sense: "
+		      "Sense Key = %d, ASC = %02X, ASCQ = %02X\n",
+		      Controller,
+		      Event->Channel,
+		      Event->TargetID,
+		      RequestSense->SenseKey,
+		      RequestSense->AdditionalSenseCode,
+		      RequestSense->AdditionalSenseCodeQualifier);
+      DAC960_Critical("Physical Device %d:%d Request Sense: "
+		      "Information = %02X%02X%02X%02X "
+		      "%02X%02X%02X%02X\n",
+		      Controller,
+		      Event->Channel,
+		      Event->TargetID,
+		      RequestSense->Information[0],
+		      RequestSense->Information[1],
+		      RequestSense->Information[2],
+		      RequestSense->Information[3],
+		      RequestSense->CommandSpecificInformation[0],
+		      RequestSense->CommandSpecificInformation[1],
+		      RequestSense->CommandSpecificInformation[2],
+		      RequestSense->CommandSpecificInformation[3]);
+      break;
+    case 'E':
+      sprintf(MessageBuffer, EventMessage, Event->LogicalUnit);
+      DAC960_Critical("Enclosure %d %s\n", Controller,
+		      Event->TargetID, MessageBuffer);
+      break;
+    case 'C':
+      DAC960_Critical("Controller %s\n", Controller, EventMessage);
+      break;
+    default:
+      DAC960_Critical("Unknown Controller Event Code %04X\n",
+		      Controller, Event->EventCode);
+      break;
+    }
+}
+
+
+/*
+  DAC960_V2_ReportProgress prints an appropriate progress message for
+  Logical Device Long Operations.
+*/
+
+static void DAC960_V2_ReportProgress(DAC960_Controller_T *Controller,
+				     unsigned char *MessageString,
+				     unsigned int LogicalDeviceNumber,
+				     unsigned long BlocksCompleted,
+				     unsigned long LogicalDeviceSize)
+{
+  Controller->EphemeralProgressMessage = true;
+  DAC960_Progress("%s in Progress: Logical Drive %d (/dev/rd/c%dd%d) "
+		  "%d%% completed\n", Controller,
+		  MessageString,
+		  LogicalDeviceNumber,
+		  Controller->ControllerNumber,
+		  LogicalDeviceNumber,
+		  (100 * (BlocksCompleted >> 7)) / (LogicalDeviceSize >> 7));
+  Controller->EphemeralProgressMessage = false;
+}
+
+
+/*
+  DAC960_V2_ProcessCompletedCommand performs completion processing for Command
+  for DAC960 V2 Firmware Controllers.
+*/
+
+static void DAC960_V2_ProcessCompletedCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_CommandType_T CommandType = Command->CommandType;
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_IOCTL_Opcode_T CommandOpcode = CommandMailbox->Common.IOCTL_Opcode;
+  DAC960_V2_CommandStatus_T CommandStatus = Command->V2.CommandStatus;
+  BufferHeader_T *BufferHeader = Command->BufferHeader;
+  if (CommandType == DAC960_ReadCommand ||
+      CommandType == DAC960_WriteCommand)
+    {
+      if (CommandStatus == DAC960_V2_NormalCompletion)
+	{
+	  /*
+	    Perform completion processing for all buffers in this I/O Request.
+	  */
+	  while (BufferHeader != NULL)
 	    {
-	      Command->CommandStatus = Controller->PendingRebuildStatus;
-	      Controller->RebuildStatusPending = false;
+	      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+	      BufferHeader->b_reqnext = NULL;
+	      DAC960_ProcessCompletedBuffer(BufferHeader, true);
+	      BufferHeader = NextBufferHeader;
 	    }
-	  else if (CommandType == DAC960_MonitoringCommand &&
-		   CommandStatus != DAC960_NormalCompletion &&
-		   CommandStatus != DAC960_NoRebuildOrCheckInProgress)
+	  /*
+	    Wake up requestor for swap file paging requests.
+	  */
+	  if (Command->Semaphore != NULL)
 	    {
-	      Controller->PendingRebuildStatus = CommandStatus;
-	      Controller->RebuildStatusPending = true;
+	      up(Command->Semaphore);
+	      Command->Semaphore = NULL;
 	    }
+	  add_blkdev_randomness(DAC960_MAJOR + Controller->ControllerNumber);
 	}
-      else if (CommandOpcode == DAC960_RebuildStat)
+      else if (Command->V2.RequestSense.SenseKey
+	       == DAC960_SenseKey_MediumError &&
+	       BufferHeader != NULL &&
+	       BufferHeader->b_reqnext != NULL)
 	{
-	  unsigned int LogicalDriveNumber =
-	    Controller->RebuildProgress.LogicalDriveNumber;
-	  unsigned int LogicalDriveSize =
-	    Controller->RebuildProgress.LogicalDriveSize;
-	  unsigned int BlocksCompleted =
-	    LogicalDriveSize - Controller->RebuildProgress.RemainingBlocks;
-	  if (CommandStatus == DAC960_NormalCompletion)
+	  if (CommandType == DAC960_ReadCommand)
+	    Command->CommandType = DAC960_ReadRetryCommand;
+	  else Command->CommandType = DAC960_WriteRetryCommand;
+	  Command->BlockCount = BufferHeader->b_size >> DAC960_BlockSizeBits;
+	  CommandMailbox->SCSI_10.CommandControlBits
+				 .AdditionalScatterGatherListMemory = false;
+	  CommandMailbox->SCSI_10.DataTransferSize =
+	    Command->BlockCount << DAC960_BlockSizeBits;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0].SegmentDataPointer =
+	    Virtual_to_Bus(BufferHeader->b_data);
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0].SegmentByteCount =
+	    CommandMailbox->SCSI_10.DataTransferSize;
+	  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+	  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
+	  DAC960_QueueCommand(Command);
+	  return;
+	}
+      else
+	{
+	  if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+	    DAC960_V2_ReadWriteError(Command);
+	  /*
+	    Perform completion processing for all buffers in this I/O Request.
+	  */
+	  while (BufferHeader != NULL)
 	    {
-	      Controller->EphemeralProgressMessage = true;
-	      DAC960_Progress("Consistency Check in Progress: "
-			      "Logical Drive %d (/dev/rd/c%dd%d) "
-			      "%d%% completed\n",
-			      Controller, LogicalDriveNumber,
-			      Controller->ControllerNumber,
-			      LogicalDriveNumber,
-			      (100 * (BlocksCompleted >> 7))
-			      / (LogicalDriveSize >> 7));
-	      Controller->EphemeralProgressMessage = false;
+	      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+	      BufferHeader->b_reqnext = NULL;
+	      DAC960_ProcessCompletedBuffer(BufferHeader, false);
+	      BufferHeader = NextBufferHeader;
+	    }
+	  /*
+	    Wake up requestor for swap file paging requests.
+	  */
+	  if (Command->Semaphore != NULL)
+	    {
+	      up(Command->Semaphore);
+	      Command->Semaphore = NULL;
 	    }
 	}
     }
-  if (CommandType == DAC960_MonitoringCommand)
+  else if (CommandType == DAC960_ReadRetryCommand ||
+	   CommandType == DAC960_WriteRetryCommand)
     {
-      if (Controller->NewEventLogSequenceNumber
-	  - Controller->OldEventLogSequenceNumber > 0)
+      BufferHeader_T *NextBufferHeader = BufferHeader->b_reqnext;
+      BufferHeader->b_reqnext = NULL;
+      /*
+	Perform completion processing for this single buffer.
+      */
+      if (CommandStatus == DAC960_V2_NormalCompletion)
+	DAC960_ProcessCompletedBuffer(BufferHeader, true);
+      else
 	{
-	  Command->CommandMailbox.Type3E.CommandOpcode =
-	    DAC960_PerformEventLogOperation;
-	  Command->CommandMailbox.Type3E.OperationType =
-	    DAC960_GetEventLogEntry;
-	  Command->CommandMailbox.Type3E.OperationQualifier = 1;
-	  Command->CommandMailbox.Type3E.SequenceNumber =
-	    Controller->OldEventLogSequenceNumber;
-	  Command->CommandMailbox.Type3E.BusAddress =
-	    Virtual_to_Bus(&Controller->EventLogEntry);
-	  DAC960_QueueCommand(Command);
-	  return;
+	  if (Command->V2.RequestSense.SenseKey != DAC960_SenseKey_NotReady)
+	    DAC960_V2_ReadWriteError(Command);
+	  DAC960_ProcessCompletedBuffer(BufferHeader, false);
 	}
-      if (Controller->NeedErrorTableInformation)
+      if (NextBufferHeader != NULL)
 	{
-	  Controller->NeedErrorTableInformation = false;
-	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_GetErrorTable;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(
-	      &Controller->ErrorTable[Controller->ErrorTableIndex ^ 1]);
-	  DAC960_QueueCommand(Command);
-	  return;
-	}
-      if (Controller->NeedRebuildProgress && 
-	  Controller->Enquiry[Controller->EnquiryIndex]
-		      .CriticalLogicalDriveCount <
-	  Controller->Enquiry[Controller->EnquiryIndex ^ 1]
-		      .CriticalLogicalDriveCount)
-	{
-	  Controller->NeedRebuildProgress = false;
-	  Command->CommandMailbox.Type3.CommandOpcode =
-	    DAC960_GetRebuildProgress;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(&Controller->RebuildProgress);
+	  Command->BlockNumber +=
+	    BufferHeader->b_size >> DAC960_BlockSizeBits;
+	  Command->BlockCount =
+	    NextBufferHeader->b_size >> DAC960_BlockSizeBits;
+	  Command->BufferHeader = NextBufferHeader;
+	  CommandMailbox->SCSI_10.DataTransferSize =
+	    Command->BlockCount << DAC960_BlockSizeBits;
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0]
+				 .SegmentDataPointer =
+	    Virtual_to_Bus(NextBufferHeader->b_data);
+	  CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				 .ScatterGatherSegments[0]
+				 .SegmentByteCount =
+	    CommandMailbox->SCSI_10.DataTransferSize;
+	  CommandMailbox->SCSI_10.SCSI_CDB[2] = Command->BlockNumber >> 24;
+	  CommandMailbox->SCSI_10.SCSI_CDB[3] = Command->BlockNumber >> 16;
+	  CommandMailbox->SCSI_10.SCSI_CDB[4] = Command->BlockNumber >> 8;
+	  CommandMailbox->SCSI_10.SCSI_CDB[5] = Command->BlockNumber;
+	  CommandMailbox->SCSI_10.SCSI_CDB[7] = Command->BlockCount >> 8;
+	  CommandMailbox->SCSI_10.SCSI_CDB[8] = Command->BlockCount;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
-      if (Controller->NeedDeviceStateInformation)
+    }
+  else if (CommandType == DAC960_MonitoringCommand)
+    {
+      if (CommandOpcode == DAC960_V2_GetControllerInfo)
 	{
-	  if (Controller->NeedDeviceInquiryInformation)
+	  DAC960_V2_ControllerInfo_T *NewControllerInfo =
+	    &Controller->V2.NewControllerInformation;
+	  DAC960_V2_ControllerInfo_T *ControllerInfo =
+	    &Controller->V2.ControllerInformation;
+	  Controller->LogicalDriveCount =
+	    NewControllerInfo->LogicalDevicesPresent;
+	  Controller->V2.NeedLogicalDeviceInformation = true;
+	  Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber = 0;
+	  Controller->V2.NeedPhysicalDeviceInformation = true;
+	  Controller->V2.PhysicalDeviceIndex = 0;
+	  Controller->V2.NewPhysicalDeviceInformation.Channel = 0;
+	  Controller->V2.NewPhysicalDeviceInformation.TargetID = 0;
+	  Controller->V2.NewPhysicalDeviceInformation.LogicalUnit = 0;
+	  Controller->MonitoringAlertMode =
+	    (NewControllerInfo->LogicalDevicesCritical > 0 ||
+	     NewControllerInfo->LogicalDevicesOffline > 0 ||
+	     NewControllerInfo->PhysicalDisksCritical > 0 ||
+	     NewControllerInfo->PhysicalDisksOffline > 0);
+	  memcpy(ControllerInfo, NewControllerInfo,
+		 sizeof(DAC960_V2_ControllerInfo_T));
+	}
+      else if (CommandOpcode == DAC960_V2_GetEvent)
+	{
+	  if (CommandStatus == DAC960_V2_NormalCompletion)
+	    DAC960_V2_ReportEvent(Controller, &Controller->V2.Event);
+	  Controller->V2.NextEventSequenceNumber++;
+	}
+      else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid &&
+	       CommandStatus == DAC960_V2_NormalCompletion)
+	{
+	  DAC960_V2_PhysicalDeviceInfo_T *NewPhysicalDeviceInfo =
+	    &Controller->V2.NewPhysicalDeviceInformation;
+	  unsigned int PhysicalDeviceIndex = Controller->V2.PhysicalDeviceIndex;
+	  DAC960_V2_PhysicalDeviceInfo_T *PhysicalDeviceInfo =
+	    Controller->V2.PhysicalDeviceInformation[PhysicalDeviceIndex];
+	  DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber;
+	  if (PhysicalDeviceInfo == NULL ||
+	      (NewPhysicalDeviceInfo->Channel !=
+	       PhysicalDeviceInfo->Channel) ||
+	      (NewPhysicalDeviceInfo->TargetID !=
+	       PhysicalDeviceInfo->TargetID) ||
+	      (NewPhysicalDeviceInfo->LogicalUnit !=
+	       PhysicalDeviceInfo->LogicalUnit))
 	    {
-	      DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
-	      DAC960_SCSI_Inquiry_T *InquiryStandardData =
-		&Controller->InquiryStandardData
-			       [Controller->DeviceStateChannel]
-			       [Controller->DeviceStateTargetID];
-	      InquiryStandardData->PeripheralDeviceType = 0x1F;
-	      Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
-	      Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
-	      DCDB->Channel = Controller->DeviceStateChannel;
-	      DCDB->TargetID = Controller->DeviceStateTargetID;
-	      DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
-	      DCDB->EarlyStatus = false;
-	      DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
-	      DCDB->NoAutomaticRequestSense = false;
-	      DCDB->DisconnectPermitted = true;
-	      DCDB->TransferLength = sizeof(DAC960_SCSI_Inquiry_T);
-	      DCDB->BusAddress = Virtual_to_Bus(InquiryStandardData);
-	      DCDB->CDBLength = 6;
-	      DCDB->TransferLengthHigh4 = 0;
-	      DCDB->SenseLength = sizeof(DCDB->SenseData);
-	      DCDB->CDB[0] = 0x12; /* INQUIRY */
-	      DCDB->CDB[1] = 0; /* EVPD = 0 */
-	      DCDB->CDB[2] = 0; /* Page Code */
-	      DCDB->CDB[3] = 0; /* Reserved */
-	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_T);
-	      DCDB->CDB[5] = 0; /* Control */
-	      DAC960_QueueCommand(Command);
-	      Controller->NeedDeviceInquiryInformation = false;
-	      return;
+	      unsigned int DeviceIndex;
+	      PhysicalDeviceInfo = (DAC960_V2_PhysicalDeviceInfo_T *)
+		kmalloc(sizeof(DAC960_V2_PhysicalDeviceInfo_T), GFP_ATOMIC);
+	      InquiryUnitSerialNumber =
+		(DAC960_SCSI_Inquiry_UnitSerialNumber_T *)
+		  kmalloc(sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T),
+			  GFP_ATOMIC);
+	      if (InquiryUnitSerialNumber == NULL)
+		{
+		  kfree(PhysicalDeviceInfo);
+		  PhysicalDeviceInfo = NULL;
+		}
+	      DAC960_Critical("Physical Device %d:%d Now Exists%s\n",
+			      Controller,
+			      NewPhysicalDeviceInfo->Channel,
+			      NewPhysicalDeviceInfo->TargetID,
+			      (PhysicalDeviceInfo != NULL
+			       ? "" : " - Allocation Failed"));
+	      if (PhysicalDeviceInfo != NULL)
+		{
+		  for (DeviceIndex = PhysicalDeviceIndex;
+		       DeviceIndex < DAC960_V2_MaxPhysicalDevices - 1;
+		       DeviceIndex++)
+		    {
+		      Controller->V2.PhysicalDeviceInformation[DeviceIndex+1] =
+			Controller->V2.PhysicalDeviceInformation[DeviceIndex];
+		      Controller->V2.InquiryUnitSerialNumber[DeviceIndex+1] =
+			Controller->V2.InquiryUnitSerialNumber[DeviceIndex];
+		      Controller->V2.PhysicalDeviceInformation
+				     [PhysicalDeviceIndex] =
+			PhysicalDeviceInfo;
+		      Controller->V2.InquiryUnitSerialNumber
+				     [PhysicalDeviceIndex] =
+			InquiryUnitSerialNumber;
+		    }
+		  memset(PhysicalDeviceInfo, 0,
+			 sizeof(DAC960_V2_PhysicalDeviceInfo_T));
+		  PhysicalDeviceInfo->PhysicalDeviceState =
+		    DAC960_V2_Device_InvalidState;
+		  memset(InquiryUnitSerialNumber, 0,
+			 sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T));
+		  InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+		  Controller->V2.NeedDeviceSerialNumberInformation = true;
+		}
 	    }
-	  if (Controller->NeedDeviceSerialNumberInformation)
+	  if (PhysicalDeviceInfo != NULL)
 	    {
-	      DAC960_DCDB_T *DCDB = &Controller->MonitoringDCDB;
-	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
-		&Controller->InquiryUnitSerialNumber
-			       [Controller->DeviceStateChannel]
-			       [Controller->DeviceStateTargetID];
-	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
-	      Command->CommandMailbox.Type3.CommandOpcode = DAC960_DCDB;
-	      Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
-	      DCDB->Channel = Controller->DeviceStateChannel;
-	      DCDB->TargetID = Controller->DeviceStateTargetID;
-	      DCDB->Direction = DAC960_DCDB_DataTransferDeviceToSystem;
-	      DCDB->EarlyStatus = false;
-	      DCDB->Timeout = DAC960_DCDB_Timeout_10_seconds;
-	      DCDB->NoAutomaticRequestSense = false;
-	      DCDB->DisconnectPermitted = true;
-	      DCDB->TransferLength =
-		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
-	      DCDB->BusAddress = Virtual_to_Bus(InquiryUnitSerialNumber);
-	      DCDB->CDBLength = 6;
-	      DCDB->TransferLengthHigh4 = 0;
-	      DCDB->SenseLength = sizeof(DCDB->SenseData);
-	      DCDB->CDB[0] = 0x12; /* INQUIRY */
-	      DCDB->CDB[1] = 1; /* EVPD = 1 */
-	      DCDB->CDB[2] = 0x80; /* Page Code */
-	      DCDB->CDB[3] = 0; /* Reserved */
-	      DCDB->CDB[4] = sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
-	      DCDB->CDB[5] = 0; /* Control */
-	      DAC960_QueueCommand(Command);
-	      Controller->NeedDeviceSerialNumberInformation = false;
-	      return;
+	      if (NewPhysicalDeviceInfo->PhysicalDeviceState !=
+		  PhysicalDeviceInfo->PhysicalDeviceState)
+		DAC960_Critical("Physical Device %d:%d is now %s\n", Controller,
+				NewPhysicalDeviceInfo->Channel,
+				NewPhysicalDeviceInfo->TargetID,
+				(NewPhysicalDeviceInfo->PhysicalDeviceState
+				 == DAC960_V2_Device_Unconfigured
+				 ? "UNCONFIGURED"
+				 : NewPhysicalDeviceInfo->PhysicalDeviceState
+				   == DAC960_V2_Device_Online
+				   ? "ONLINE"
+				   : NewPhysicalDeviceInfo->PhysicalDeviceState
+				     == DAC960_V2_Device_WriteOnly
+				     ? "WRITE-ONLY"
+				     : NewPhysicalDeviceInfo
+				       ->PhysicalDeviceState
+				       == DAC960_V2_Device_Dead
+				       ? "DEAD" : "STANDBY"));
+	      if ((NewPhysicalDeviceInfo->ParityErrors !=
+		   PhysicalDeviceInfo->ParityErrors) ||
+		  (NewPhysicalDeviceInfo->SoftErrors !=
+		   PhysicalDeviceInfo->SoftErrors) ||
+		  (NewPhysicalDeviceInfo->HardErrors !=
+		   PhysicalDeviceInfo->HardErrors) ||
+		  (NewPhysicalDeviceInfo->MiscellaneousErrors !=
+		   PhysicalDeviceInfo->MiscellaneousErrors) ||
+		  (NewPhysicalDeviceInfo->CommandTimeouts !=
+		   PhysicalDeviceInfo->CommandTimeouts) ||
+		  (NewPhysicalDeviceInfo->Retries !=
+		   PhysicalDeviceInfo->Retries) ||
+		  (NewPhysicalDeviceInfo->Aborts !=
+		   PhysicalDeviceInfo->Aborts) ||
+		  (NewPhysicalDeviceInfo->PredictedFailuresDetected !=
+		   PhysicalDeviceInfo->PredictedFailuresDetected))
+		{
+		  DAC960_Critical("Physical Device %d:%d Errors: "
+				  "Parity = %d, Soft = %d, "
+				  "Hard = %d, Misc = %d\n",
+				  Controller,
+				  NewPhysicalDeviceInfo->Channel,
+				  NewPhysicalDeviceInfo->TargetID,
+				  NewPhysicalDeviceInfo->ParityErrors,
+				  NewPhysicalDeviceInfo->SoftErrors,
+				  NewPhysicalDeviceInfo->HardErrors,
+				  NewPhysicalDeviceInfo->MiscellaneousErrors);
+		  DAC960_Critical("Physical Device %d:%d Errors: "
+				  "Timeouts = %d, Retries = %d, "
+				  "Aborts = %d, Predicted = %d\n",
+				  Controller,
+				  NewPhysicalDeviceInfo->Channel,
+				  NewPhysicalDeviceInfo->TargetID,
+				  NewPhysicalDeviceInfo->CommandTimeouts,
+				  NewPhysicalDeviceInfo->Retries,
+				  NewPhysicalDeviceInfo->Aborts,
+				  NewPhysicalDeviceInfo
+				  ->PredictedFailuresDetected);
+		}
+	      if (PhysicalDeviceInfo->PhysicalDeviceState
+		  == DAC960_V2_Device_Dead &&
+		  NewPhysicalDeviceInfo->PhysicalDeviceState
+		  != DAC960_V2_Device_Dead)
+		Controller->V2.NeedDeviceSerialNumberInformation = true;
+	      memcpy(PhysicalDeviceInfo, NewPhysicalDeviceInfo,
+		     sizeof(DAC960_V2_PhysicalDeviceInfo_T));
 	    }
-	  if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
+	  NewPhysicalDeviceInfo->LogicalUnit++;
+	  Controller->V2.PhysicalDeviceIndex++;
+	}
+      else if (CommandOpcode == DAC960_V2_GetPhysicalDeviceInfoValid)
+	Controller->V2.NeedPhysicalDeviceInformation = false;
+      else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid &&
+	       CommandStatus == DAC960_V2_NormalCompletion)
+	{
+	  DAC960_V2_LogicalDeviceInfo_T *NewLogicalDeviceInfo =
+	    &Controller->V2.NewLogicalDeviceInformation;
+	  unsigned short LogicalDeviceNumber =
+	    NewLogicalDeviceInfo->LogicalDeviceNumber;
+	  DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	    Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber];
+	  if (LogicalDeviceInfo == NULL)
 	    {
-	      Controller->DeviceStateChannel++;
-	      Controller->DeviceStateTargetID = 0;
+	      DAC960_V2_PhysicalDevice_T PhysicalDevice;
+	      PhysicalDevice.Controller = 0;
+	      PhysicalDevice.Channel = NewLogicalDeviceInfo->Channel;
+	      PhysicalDevice.TargetID = NewLogicalDeviceInfo->TargetID;
+	      PhysicalDevice.LogicalUnit = NewLogicalDeviceInfo->LogicalUnit;
+	      Controller->V2.LogicalDriveToVirtualDevice[LogicalDeviceNumber] =
+		PhysicalDevice;
+	      LogicalDeviceInfo = (DAC960_V2_LogicalDeviceInfo_T *)
+		kmalloc(sizeof(DAC960_V2_LogicalDeviceInfo_T), GFP_ATOMIC);
+	      Controller->V2.LogicalDeviceInformation[LogicalDeviceNumber] =
+		LogicalDeviceInfo;
+	      DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+			      "Now Exists%s\n", Controller,
+			      LogicalDeviceNumber,
+			      Controller->ControllerNumber,
+			      LogicalDeviceNumber,
+			      (LogicalDeviceInfo != NULL
+			       ? "" : " - Allocation Failed"));
+	      if (LogicalDeviceInfo != NULL)
+		memset(LogicalDeviceInfo, 0,
+		       sizeof(DAC960_V2_LogicalDeviceInfo_T));
 	    }
-	  while (Controller->DeviceStateChannel < Controller->Channels)
+	  if (LogicalDeviceInfo != NULL)
 	    {
-	      DAC960_DeviceState_T *OldDeviceState =
-		&Controller->DeviceState[Controller->DeviceStateIndex]
-					[Controller->DeviceStateChannel]
-					[Controller->DeviceStateTargetID];
-	      if (OldDeviceState->Present &&
-		  OldDeviceState->DeviceType == DAC960_DiskType)
-		{
-		  Command->CommandMailbox.Type3D.CommandOpcode =
-		    DAC960_GetDeviceState;
-		  Command->CommandMailbox.Type3D.Channel =
-		    Controller->DeviceStateChannel;
-		  Command->CommandMailbox.Type3D.TargetID =
-		    Controller->DeviceStateTargetID;
-		  Command->CommandMailbox.Type3D.BusAddress =
-		    Virtual_to_Bus(&Controller->DeviceState
-				      [Controller->DeviceStateIndex ^ 1]
-				      [Controller->DeviceStateChannel]
-				      [Controller->DeviceStateTargetID]);
-		  DAC960_QueueCommand(Command);
-		  return;
-		}
-	      if (++Controller->DeviceStateTargetID == DAC960_MaxTargets)
-		{
-		  Controller->DeviceStateChannel++;
-		  Controller->DeviceStateTargetID = 0;
-		}
+	      unsigned long LogicalDeviceSize =
+		NewLogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB;
+	      if (NewLogicalDeviceInfo->LogicalDeviceState !=
+		  LogicalDeviceInfo->LogicalDeviceState)
+		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) "
+				"is now %s\n", Controller,
+				LogicalDeviceNumber,
+				Controller->ControllerNumber,
+				LogicalDeviceNumber,
+				(NewLogicalDeviceInfo->LogicalDeviceState
+				 == DAC960_V2_LogicalDevice_Online
+				 ? "ONLINE"
+				 : NewLogicalDeviceInfo->LogicalDeviceState
+				   == DAC960_V2_LogicalDevice_Critical
+				   ? "CRITICAL" : "OFFLINE"));
+	      if ((NewLogicalDeviceInfo->SoftErrors !=
+		   LogicalDeviceInfo->SoftErrors) ||
+		  (NewLogicalDeviceInfo->CommandsFailed !=
+		   LogicalDeviceInfo->CommandsFailed) ||
+		  (NewLogicalDeviceInfo->DeferredWriteErrors !=
+		   LogicalDeviceInfo->DeferredWriteErrors))
+		DAC960_Critical("Logical Drive %d (/dev/rd/c%dd%d) Errors: "
+				"Soft = %d, Failed = %d, Deferred Write = %d\n",
+				Controller, LogicalDeviceNumber,
+				Controller->ControllerNumber,
+				LogicalDeviceNumber,
+				NewLogicalDeviceInfo->SoftErrors,
+				NewLogicalDeviceInfo->CommandsFailed,
+				NewLogicalDeviceInfo->DeferredWriteErrors);
+	      if (NewLogicalDeviceInfo->ConsistencyCheckInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Consistency Check",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->ConsistencyCheckBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->RebuildInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Rebuild",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->RebuildBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->BackgroundInitializationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "BackgroundInitialization",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->BackgroundInitializationBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->ForegroundInitializationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Foreground Initialization",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->ForegroundInitializationBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->DataMigrationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Data Migration",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->DataMigrationBlockNumber,
+					 LogicalDeviceSize);
+	      else if (NewLogicalDeviceInfo->PatrolOperationInProgress)
+		DAC960_V2_ReportProgress(Controller,
+					 "Patrol Operation",
+					 LogicalDeviceNumber,
+					 NewLogicalDeviceInfo
+					 ->PatrolOperationBlockNumber,
+					 LogicalDeviceSize);
+	      memcpy(LogicalDeviceInfo, NewLogicalDeviceInfo,
+		     sizeof(DAC960_V2_LogicalDeviceInfo_T));
 	    }
-	  Controller->NeedDeviceStateInformation = false;
-	  Controller->DeviceStateIndex ^= 1;
+	  NewLogicalDeviceInfo->LogicalDeviceNumber++;
 	}
-      if (Controller->NeedLogicalDriveInformation)
-	{
-	  Controller->NeedLogicalDriveInformation = false;
-	  Command->CommandMailbox.Type3.CommandOpcode =
-	    DAC960_GetLogicalDriveInformation;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(
-	      &Controller->LogicalDriveInformation
-			   [Controller->LogicalDriveInformationIndex ^ 1]);
+      else if (CommandOpcode == DAC960_V2_GetLogicalDeviceInfoValid)
+	Controller->V2.NeedLogicalDeviceInformation = false;
+      if (Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+	  - Controller->V2.NextEventSequenceNumber > 0)
+	{
+	  CommandMailbox->GetEvent.CommandOpcode = DAC960_V2_IOCTL;
+	  CommandMailbox->GetEvent.DataTransferSize = sizeof(DAC960_V2_Event_T);
+	  CommandMailbox->GetEvent.EventSequenceNumberHigh16 =
+	    Controller->V2.NextEventSequenceNumber >> 16;
+	  CommandMailbox->GetEvent.ControllerNumber = 0;
+	  CommandMailbox->GetEvent.IOCTL_Opcode =
+	    DAC960_V2_GetEvent;
+	  CommandMailbox->GetEvent.EventSequenceNumberLow16 =
+	    Controller->V2.NextEventSequenceNumber & 0xFFFF;
+	  CommandMailbox->GetEvent.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentDataPointer =
+	    Virtual_to_Bus(&Controller->V2.Event);
+	  CommandMailbox->GetEvent.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentByteCount =
+	    CommandMailbox->GetEvent.DataTransferSize;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
-      if (Controller->NeedRebuildProgress)
+      if (Controller->V2.NeedPhysicalDeviceInformation)
 	{
-	  Controller->NeedRebuildProgress = false;
-	  Command->CommandMailbox.Type3.CommandOpcode =
-	    DAC960_GetRebuildProgress;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(&Controller->RebuildProgress);
+	  if (Controller->V2.NeedDeviceSerialNumberInformation)
+	    {
+	      DAC960_SCSI_Inquiry_UnitSerialNumber_T *InquiryUnitSerialNumber =
+		Controller->V2.InquiryUnitSerialNumber
+			       [Controller->V2.PhysicalDeviceIndex - 1];
+	      InquiryUnitSerialNumber->PeripheralDeviceType = 0x1F;
+	      CommandMailbox->SCSI_10.CommandOpcode =
+		DAC960_V2_SCSI_10_Passthru;
+	      CommandMailbox->SCSI_10.DataTransferSize =
+		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      CommandMailbox->SCSI_10.PhysicalDevice.LogicalUnit =
+		Controller->V2.NewPhysicalDeviceInformation.LogicalUnit - 1;
+	      CommandMailbox->SCSI_10.PhysicalDevice.TargetID =
+		Controller->V2.NewPhysicalDeviceInformation.TargetID;
+	      CommandMailbox->SCSI_10.PhysicalDevice.Channel =
+		Controller->V2.NewPhysicalDeviceInformation.Channel;
+	      CommandMailbox->SCSI_10.CDBLength = 6;
+	      CommandMailbox->SCSI_10.SCSI_CDB[0] = 0x12; /* INQUIRY */
+	      CommandMailbox->SCSI_10.SCSI_CDB[1] = 1; /* EVPD = 1 */
+	      CommandMailbox->SCSI_10.SCSI_CDB[2] = 0x80; /* Page Code */
+	      CommandMailbox->SCSI_10.SCSI_CDB[3] = 0; /* Reserved */
+	      CommandMailbox->SCSI_10.SCSI_CDB[4] =
+		sizeof(DAC960_SCSI_Inquiry_UnitSerialNumber_T);
+	      CommandMailbox->SCSI_10.SCSI_CDB[5] = 0; /* Control */
+	      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				     .ScatterGatherSegments[0]
+				     .SegmentDataPointer =
+		Virtual_to_Bus(InquiryUnitSerialNumber);
+	      CommandMailbox->SCSI_10.DataTransferMemoryAddress
+				     .ScatterGatherSegments[0]
+				     .SegmentByteCount =
+		CommandMailbox->SCSI_10.DataTransferSize;
+	      DAC960_QueueCommand(Command);
+	      Controller->V2.NeedDeviceSerialNumberInformation = false;
+	      return;
+	    }
+	  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+	  CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+	    sizeof(DAC960_V2_PhysicalDeviceInfo_T);
+	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.LogicalUnit =
+	    Controller->V2.NewPhysicalDeviceInformation.LogicalUnit;
+	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID =
+	    Controller->V2.NewPhysicalDeviceInformation.TargetID;
+	  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel =
+	    Controller->V2.NewPhysicalDeviceInformation.Channel;
+	  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+	    DAC960_V2_GetPhysicalDeviceInfoValid;
+	  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+					    .ScatterGatherSegments[0]
+					    .SegmentDataPointer =
+	    Virtual_to_Bus(&Controller->V2.NewPhysicalDeviceInformation);
+	  CommandMailbox->PhysicalDeviceInfo.DataTransferMemoryAddress
+					    .ScatterGatherSegments[0]
+					    .SegmentByteCount =
+	    CommandMailbox->PhysicalDeviceInfo.DataTransferSize;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
-      if (Controller->NeedConsistencyCheckProgress)
+      if (Controller->V2.NeedLogicalDeviceInformation)
 	{
-	  Controller->NeedConsistencyCheckProgress = false;
-	  Command->CommandMailbox.Type3.CommandOpcode = DAC960_RebuildStat;
-	  Command->CommandMailbox.Type3.BusAddress =
-	    Virtual_to_Bus(&Controller->RebuildProgress);
+	  CommandMailbox->LogicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+	  CommandMailbox->LogicalDeviceInfo.DataTransferSize =
+	    sizeof(DAC960_V2_LogicalDeviceInfo_T);
+	  CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+	    Controller->V2.NewLogicalDeviceInformation.LogicalDeviceNumber;
+	  CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+	    DAC960_V2_GetLogicalDeviceInfoValid;
+	  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+					   .ScatterGatherSegments[0]
+					   .SegmentDataPointer =
+	    Virtual_to_Bus(&Controller->V2.NewLogicalDeviceInformation);
+	  CommandMailbox->LogicalDeviceInfo.DataTransferMemoryAddress
+					   .ScatterGatherSegments[0]
+					   .SegmentByteCount =
+	    CommandMailbox->LogicalDeviceInfo.DataTransferSize;
 	  DAC960_QueueCommand(Command);
 	  return;
 	}
       Controller->MonitoringTimerCount++;
       Controller->MonitoringTimer.expires =
-	jiffies + DAC960_MonitoringTimerInterval;
+	jiffies + DAC960_HealthStatusMonitoringInterval;
       add_timer(&Controller->MonitoringTimer);
     }
   if (CommandType == DAC960_ImmediateCommand)
@@ -2406,12 +4514,11 @@
     }
   if (CommandType == DAC960_QueuedCommand)
     {
-      DAC960_KernelCommand_T *KernelCommand = Command->KernelCommand;
-      KernelCommand->CommandStatus = Command->CommandStatus;
-      Command->KernelCommand = NULL;
-      if (CommandOpcode == DAC960_DCDB)
-	Controller->DirectCommandActive[KernelCommand->DCDB->Channel]
-				       [KernelCommand->DCDB->TargetID] = false;
+      DAC960_V2_KernelCommand_T *KernelCommand = Command->V2.KernelCommand;
+      KernelCommand->CommandStatus = CommandStatus;
+      KernelCommand->RequestSenseLength = Command->V2.RequestSenseLength;
+      KernelCommand->DataTransferLength = Command->V2.DataTransferResidue;
+      Command->V2.KernelCommand = NULL;
       DAC960_DeallocateCommand(Command);
       KernelCommand->CompletionFunction(KernelCommand);
       return;
@@ -2424,7 +4531,7 @@
   if (Controller->MonitoringCommandDeferred)
     {
       Controller->MonitoringCommandDeferred = false;
-      DAC960_QueueMonitoringCommand(Command);
+      DAC960_V2_QueueMonitoringCommand(Command);
       return;
     }
   /*
@@ -2439,16 +4546,163 @@
 
 
 /*
-  DAC960_InterruptHandler handles hardware interrupts from DAC960 Controllers.
+  DAC960_BA_InterruptHandler handles hardware interrupts from DAC960 BA Series
+  Controllers.
+*/
+
+static void DAC960_BA_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  DAC960_BA_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V2.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+    {
+      DAC960_V2_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      Command->V2.RequestSenseLength =
+	NextStatusMailbox->Fields.RequestSenseLength;
+      Command->V2.DataTransferResidue =
+	NextStatusMailbox->Fields.DataTransferResidue;
+      NextStatusMailbox->Words[0] = 0;
+      if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+	NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+      DAC960_V2_ProcessCompletedCommand(Command);
+    }
+  Controller->V2.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_LP_InterruptHandler handles hardware interrupts from DAC960 LP Series
+  Controllers.
+*/
+
+static void DAC960_LP_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  DAC960_LP_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V2.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.CommandIdentifier > 0)
+    {
+      DAC960_V2_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V2.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      Command->V2.RequestSenseLength =
+	NextStatusMailbox->Fields.RequestSenseLength;
+      Command->V2.DataTransferResidue =
+	NextStatusMailbox->Fields.DataTransferResidue;
+      NextStatusMailbox->Words[0] = 0;
+      if (++NextStatusMailbox > Controller->V2.LastStatusMailbox)
+	NextStatusMailbox = Controller->V2.FirstStatusMailbox;
+      DAC960_V2_ProcessCompletedCommand(Command);
+    }
+  Controller->V2.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_LA_InterruptHandler handles hardware interrupts from DAC960 LA Series
+  Controllers.
+*/
+
+static void DAC960_LA_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  DAC960_V1_StatusMailbox_T *NextStatusMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  DAC960_LA_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V1.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.Valid)
+    {
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      NextStatusMailbox->Word = 0;
+      if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
+	NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+      DAC960_V1_ProcessCompletedCommand(Command);
+    }
+  Controller->V1.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_PG_InterruptHandler handles hardware interrupts from DAC960 PG Series
+  Controllers.
 */
 
-static void DAC960_InterruptHandler(int IRQ_Channel,
-				    void *DeviceIdentifier,
-				    Registers_T *InterruptRegisters)
+static void DAC960_PG_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
   void *ControllerBaseAddress = Controller->BaseAddress;
-  DAC960_StatusMailbox_T *NextStatusMailbox;
+  DAC960_V1_StatusMailbox_T *NextStatusMailbox;
   ProcessorFlags_T ProcessorFlags;
   /*
     Acquire exclusive access to Controller.
@@ -2457,53 +4711,61 @@
   /*
     Process Hardware Interrupts for Controller.
   */
-  switch (Controller->ControllerType)
+  DAC960_PG_AcknowledgeInterrupt(ControllerBaseAddress);
+  NextStatusMailbox = Controller->V1.NextStatusMailbox;
+  while (NextStatusMailbox->Fields.Valid)
+    {
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+	NextStatusMailbox->Fields.CommandIdentifier;
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V1.CommandStatus = NextStatusMailbox->Fields.CommandStatus;
+      NextStatusMailbox->Word = 0;
+      if (++NextStatusMailbox > Controller->V1.LastStatusMailbox)
+	NextStatusMailbox = Controller->V1.FirstStatusMailbox;
+      DAC960_V1_ProcessCompletedCommand(Command);
+    }
+  Controller->V1.NextStatusMailbox = NextStatusMailbox;
+  /*
+    Attempt to remove additional I/O Requests from the Controller's
+    I/O Request Queue and queue them to the Controller.
+  */
+  while (DAC960_ProcessRequest(Controller, false)) ;
+  /*
+    Release exclusive access to Controller.
+  */
+  DAC960_ReleaseControllerLockIH(Controller, &ProcessorFlags);
+}
+
+
+/*
+  DAC960_PD_InterruptHandler handles hardware interrupts from DAC960 PD Series
+  Controllers.
+*/
+
+static void DAC960_PD_InterruptHandler(int IRQ_Channel,
+				       void *DeviceIdentifier,
+				       Registers_T *InterruptRegisters)
+{
+  DAC960_Controller_T *Controller = (DAC960_Controller_T *) DeviceIdentifier;
+  void *ControllerBaseAddress = Controller->BaseAddress;
+  ProcessorFlags_T ProcessorFlags;
+  /*
+    Acquire exclusive access to Controller.
+  */
+  DAC960_AcquireControllerLockIH(Controller, &ProcessorFlags);
+  /*
+    Process Hardware Interrupts for Controller.
+  */
+  while (DAC960_PD_StatusAvailableP(ControllerBaseAddress))
     {
-    case DAC960_V5_Controller:
-      DAC960_V5_AcknowledgeInterrupt(ControllerBaseAddress);
-      NextStatusMailbox = Controller->NextStatusMailbox;
-      while (NextStatusMailbox->Fields.Valid)
-	{
-	  DAC960_CommandIdentifier_T CommandIdentifier =
-	    NextStatusMailbox->Fields.CommandIdentifier;
-	  DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
-	  Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
-	  NextStatusMailbox->Word = 0;
-	  if (++NextStatusMailbox > Controller->LastStatusMailbox)
-	    NextStatusMailbox = Controller->FirstStatusMailbox;
-	  DAC960_ProcessCompletedCommand(Command);
-	}
-      Controller->NextStatusMailbox = NextStatusMailbox;
-      break;
-    case DAC960_V4_Controller:
-      DAC960_V4_AcknowledgeInterrupt(ControllerBaseAddress);
-      NextStatusMailbox = Controller->NextStatusMailbox;
-      while (NextStatusMailbox->Fields.Valid)
-	{
-	  DAC960_CommandIdentifier_T CommandIdentifier =
-	    NextStatusMailbox->Fields.CommandIdentifier;
-	  DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
-	  Command->CommandStatus = NextStatusMailbox->Fields.CommandStatus;
-	  NextStatusMailbox->Word = 0;
-	  if (++NextStatusMailbox > Controller->LastStatusMailbox)
-	    NextStatusMailbox = Controller->FirstStatusMailbox;
-	  DAC960_ProcessCompletedCommand(Command);
-	}
-      Controller->NextStatusMailbox = NextStatusMailbox;
-      break;
-    case DAC960_V3_Controller:
-      while (DAC960_V3_StatusAvailableP(ControllerBaseAddress))
-	{
-	  DAC960_CommandIdentifier_T CommandIdentifier =
-	    DAC960_V3_ReadStatusCommandIdentifier(ControllerBaseAddress);
-	  DAC960_Command_T *Command = &Controller->Commands[CommandIdentifier];
-	  Command->CommandStatus =
-	    DAC960_V3_ReadStatusRegister(ControllerBaseAddress);
-	  DAC960_V3_AcknowledgeInterrupt(ControllerBaseAddress);
-	  DAC960_V3_AcknowledgeStatus(ControllerBaseAddress);
-	  DAC960_ProcessCompletedCommand(Command);
-	}
-      break;
+      DAC960_V1_CommandIdentifier_T CommandIdentifier =
+	DAC960_PD_ReadStatusCommandIdentifier(ControllerBaseAddress);
+      DAC960_Command_T *Command = Controller->Commands[CommandIdentifier-1];
+      Command->V1.CommandStatus =
+	DAC960_PD_ReadStatusRegister(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeInterrupt(ControllerBaseAddress);
+      DAC960_PD_AcknowledgeStatus(ControllerBaseAddress);
+      DAC960_V1_ProcessCompletedCommand(Command);
     }
   /*
     Attempt to remove additional I/O Requests from the Controller's
@@ -2518,18 +4780,50 @@
 
 
 /*
-  DAC960_QueueMonitoringCommand queues a Monitoring Command to Controller.
+  DAC960_V1_QueueMonitoringCommand queues a Monitoring Command to DAC960 V1
+  Firmware Controllers.
+*/
+
+static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *Command)
+{
+  DAC960_Controller_T *Controller = Command->Controller;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  DAC960_V1_ClearCommand(Command);
+  Command->CommandType = DAC960_MonitoringCommand;
+  CommandMailbox->Type3.CommandOpcode = DAC960_V1_Enquiry;
+  CommandMailbox->Type3.BusAddress = Virtual_to_Bus(&Controller->V1.NewEnquiry);
+  DAC960_QueueCommand(Command);
+}
+
+
+/*
+  DAC960_V2_QueueMonitoringCommand queues a Monitoring Command to DAC960 V2
+  Firmware Controllers.
 */
 
-static void DAC960_QueueMonitoringCommand(DAC960_Command_T *Command)
+static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *Command)
 {
   DAC960_Controller_T *Controller = Command->Controller;
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  DAC960_ClearCommand(Command);
+  DAC960_V2_CommandMailbox_T *CommandMailbox = &Command->V2.CommandMailbox;
+  DAC960_V2_ClearCommand(Command);
   Command->CommandType = DAC960_MonitoringCommand;
-  CommandMailbox->Type3.CommandOpcode = DAC960_Enquiry;
-  CommandMailbox->Type3.BusAddress =
-    Virtual_to_Bus(&Controller->Enquiry[Controller->EnquiryIndex ^ 1]);
+  CommandMailbox->ControllerInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.DataTransferControllerToHost = true;
+  CommandMailbox->ControllerInfo.CommandControlBits
+				.NoAutoRequestSense = true;
+  CommandMailbox->ControllerInfo.DataTransferSize =
+    sizeof(DAC960_V2_ControllerInfo_T);
+  CommandMailbox->ControllerInfo.ControllerNumber = 0;
+  CommandMailbox->ControllerInfo.IOCTL_Opcode = DAC960_V2_GetControllerInfo;
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentDataPointer =
+    Virtual_to_Bus(&Controller->V2.NewControllerInformation);
+  CommandMailbox->ControllerInfo.DataTransferMemoryAddress
+				.ScatterGatherSegments[0]
+				.SegmentByteCount =
+    CommandMailbox->ControllerInfo.DataTransferSize;
   DAC960_QueueCommand(Command);
 }
 
@@ -2544,21 +4838,69 @@
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) TimerData;
   DAC960_Command_T *Command;
   ProcessorFlags_T ProcessorFlags;
-  /*
-    Acquire exclusive access to Controller.
-  */
-  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
-  /*
-    Queue a Status Monitoring Command to Controller.
-  */
-  Command = DAC960_AllocateCommand(Controller);
-  if (Command != NULL)
-    DAC960_QueueMonitoringCommand(Command);
-  else Controller->MonitoringCommandDeferred = true;
-  /*
-    Release exclusive access to Controller.
-  */
-  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      /*
+	Acquire exclusive access to Controller.
+      */
+      DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+      /*
+	Queue a Status Monitoring Command to Controller.
+      */
+      Command = DAC960_AllocateCommand(Controller);
+      if (Command != NULL)
+	DAC960_V1_QueueMonitoringCommand(Command);
+      else Controller->MonitoringCommandDeferred = true;
+      /*
+	Release exclusive access to Controller.
+      */
+      DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+    }
+  else
+    {
+      DAC960_V2_ControllerInfo_T *ControllerInfo =
+	&Controller->V2.ControllerInformation;
+      unsigned int StatusChangeCounter =
+	Controller->V2.HealthStatusBuffer->StatusChangeCounter;
+      if (StatusChangeCounter == Controller->V2.StatusChangeCounter &&
+	  Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+	  == Controller->V2.NextEventSequenceNumber &&
+	  (ControllerInfo->BackgroundInitializationsActive +
+	   ControllerInfo->LogicalDeviceInitializationsActive +
+	   ControllerInfo->PhysicalDeviceInitializationsActive +
+	   ControllerInfo->ConsistencyChecksActive +
+	   ControllerInfo->RebuildsActive +
+	   ControllerInfo->OnlineExpansionsActive == 0 ||
+	   jiffies - Controller->PrimaryMonitoringTime
+	   < DAC960_MonitoringTimerInterval))
+	{
+	  Controller->MonitoringTimer.expires =
+	    jiffies + DAC960_HealthStatusMonitoringInterval;
+	  add_timer(&Controller->MonitoringTimer);
+	  return;
+	}
+      Controller->V2.StatusChangeCounter = StatusChangeCounter;
+      Controller->PrimaryMonitoringTime = jiffies;
+      /*
+	Acquire exclusive access to Controller.
+      */
+      DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+      /*
+	Queue a Status Monitoring Command to Controller.
+      */
+      Command = DAC960_AllocateCommand(Controller);
+      if (Command != NULL)
+	DAC960_V2_QueueMonitoringCommand(Command);
+      else Controller->MonitoringCommandDeferred = true;
+      /*
+	Release exclusive access to Controller.
+      */
+      DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+      /*
+	Wake up any processes waiting on a Health Status Buffer change.
+      */
+      wake_up(&Controller->HealthStatusWaitQueue);
+    }
 }
 
 
@@ -2577,19 +4919,28 @@
   if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
     return -ENXIO;
   Controller = DAC960_Controllers[ControllerNumber];
-  if (Controller == NULL ||
-      LogicalDriveNumber > Controller->LogicalDriveCount - 1)
-    return -ENXIO;
-  if (Controller->LogicalDriveInformation
-		  [Controller->LogicalDriveInformationIndex]
-		  [LogicalDriveNumber].LogicalDriveState
-      == DAC960_LogicalDrive_Offline)
-    return -ENXIO;
-  if (Controller->LogicalDriveInitialState[LogicalDriveNumber]
-      == DAC960_LogicalDrive_Offline)
+  if (Controller == NULL) return -ENXIO;
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    {
+      if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
+	return -ENXIO;
+      if (Controller->V1.LogicalDriveInformation
+			 [LogicalDriveNumber].LogicalDriveState
+	  == DAC960_V1_LogicalDrive_Offline)
+	return -ENXIO;
+    }
+  else
+    {
+      DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+      if (LogicalDeviceInfo == NULL ||
+	  LogicalDeviceInfo->LogicalDeviceState
+	  == DAC960_V2_LogicalDevice_Offline)
+	return -ENXIO;
+    }
+  if (!Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber])
     {
-      Controller->LogicalDriveInitialState[LogicalDriveNumber] =
-	DAC960_LogicalDrive_Online;
+      Controller->LogicalDriveInitiallyAccessible[LogicalDriveNumber] = true;
       DAC960_InitializeGenericDiskInfo(&Controller->GenericDiskInfo);
       resetup_one_dev(&Controller->GenericDiskInfo, LogicalDriveNumber);
     }
@@ -2650,25 +5001,51 @@
   if (ControllerNumber < 0 || ControllerNumber > DAC960_ControllerCount - 1)
     return -ENXIO;
   Controller = DAC960_Controllers[ControllerNumber];
-  if (Controller == NULL ||
-      LogicalDriveNumber > Controller->LogicalDriveCount - 1)
-    return -ENXIO;
+  if (Controller == NULL) return -ENXIO;
   switch (Request)
     {
     case HDIO_GETGEO:
       /* Get BIOS Disk Geometry. */
       UserGeometry = (DiskGeometry_T *) Argument;
       if (UserGeometry == NULL) return -EINVAL;
-      Geometry.heads = Controller->GeometryTranslationHeads;
-      Geometry.sectors = Controller->GeometryTranslationSectors;
-      Geometry.cylinders =
-	Controller->LogicalDriveInformation
-		    [Controller->LogicalDriveInformationIndex]
-		    [LogicalDriveNumber].LogicalDriveSize
-	/ (Controller->GeometryTranslationHeads *
-	   Controller->GeometryTranslationSectors);
-      Geometry.start = Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)]
-						  .start_sect;
+      if (Controller->FirmwareType == DAC960_V1_Controller)
+	{
+	  if (LogicalDriveNumber > Controller->LogicalDriveCount - 1)
+	    return -ENXIO;
+	  Geometry.heads = Controller->V1.GeometryTranslationHeads;
+	  Geometry.sectors = Controller->V1.GeometryTranslationSectors;
+	  Geometry.cylinders =
+	    Controller->V1.LogicalDriveInformation[LogicalDriveNumber]
+						  .LogicalDriveSize
+	    / (Geometry.heads * Geometry.sectors);
+	}
+      else
+	{
+	  DAC960_V2_LogicalDeviceInfo_T *LogicalDeviceInfo =
+	    Controller->V2.LogicalDeviceInformation[LogicalDriveNumber];
+	  if (LogicalDeviceInfo == NULL)
+	    return -EINVAL;
+	  switch(LogicalDeviceInfo->DriveGeometry)
+	    {
+	    case DAC960_V2_Geometry_128_32:
+	      Geometry.heads = 128;
+	      Geometry.sectors = 32;
+	      break;
+	    case DAC960_V2_Geometry_255_63:
+	      Geometry.heads = 255;
+	      Geometry.sectors = 63;
+	      break;
+	    default:
+	      DAC960_Error("Illegal Logical Device Geometry %d\n",
+			   Controller, LogicalDeviceInfo->DriveGeometry);
+	      return -EINVAL;
+	    }
+	  Geometry.cylinders =
+	    LogicalDeviceInfo->ConfigurableDeviceSizeIn512ByteBlocksOrMB
+	    / (Geometry.heads * Geometry.sectors);
+	}
+      Geometry.start =
+	Controller->GenericDiskInfo.part[MINOR(Inode->i_rdev)].start_sect;
       return copy_to_user(UserGeometry, &Geometry, sizeof(DiskGeometry_T));
     case BLKGETSIZE:
       /* Get Device Size. */
@@ -2764,59 +5141,63 @@
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
 	memset(&ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
 	ControllerInfo.ControllerNumber = ControllerNumber;
+	ControllerInfo.FirmwareType = Controller->FirmwareType;
+	ControllerInfo.Channels = Controller->Channels;
+	ControllerInfo.Targets = Controller->Targets;
 	ControllerInfo.PCI_Bus = Controller->Bus;
 	ControllerInfo.PCI_Device = Controller->Device;
 	ControllerInfo.PCI_Function = Controller->Function;
 	ControllerInfo.IRQ_Channel = Controller->IRQ_Channel;
-	ControllerInfo.Channels = Controller->Channels;
 	ControllerInfo.PCI_Address = Controller->PCI_Address;
 	strcpy(ControllerInfo.ModelName, Controller->ModelName);
 	strcpy(ControllerInfo.FirmwareVersion, Controller->FirmwareVersion);
 	return copy_to_user(UserSpaceControllerInfo, &ControllerInfo,
 			    sizeof(DAC960_ControllerInfo_T));
       }
-    case DAC960_IOCTL_EXECUTE_COMMAND:
+    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
       {
-	DAC960_UserCommand_T *UserSpaceUserCommand =
-	  (DAC960_UserCommand_T *) Argument;
-	DAC960_UserCommand_T UserCommand;
+	DAC960_V1_UserCommand_T *UserSpaceUserCommand =
+	  (DAC960_V1_UserCommand_T *) Argument;
+	DAC960_V1_UserCommand_T UserCommand;
 	DAC960_Controller_T *Controller;
 	DAC960_Command_T *Command = NULL;
-	DAC960_CommandOpcode_T CommandOpcode;
-	DAC960_CommandStatus_T CommandStatus;
-	DAC960_DCDB_T DCDB;
+	DAC960_V1_CommandOpcode_T CommandOpcode;
+	DAC960_V1_CommandStatus_T CommandStatus;
+	DAC960_V1_DCDB_T DCDB;
 	ProcessorFlags_T ProcessorFlags;
 	int ControllerNumber, DataTransferLength;
 	unsigned char *DataTransferBuffer = NULL;
 	if (UserSpaceUserCommand == NULL) return -EINVAL;
 	ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
-				   sizeof(DAC960_UserCommand_T));
-	if (ErrorCode != 0) goto Failure;
+				   sizeof(DAC960_V1_UserCommand_T));
+	if (ErrorCode != 0) goto Failure1;
 	ControllerNumber = UserCommand.ControllerNumber;
 	if (ControllerNumber < 0 ||
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
 	CommandOpcode = UserCommand.CommandMailbox.Common.CommandOpcode;
 	DataTransferLength = UserCommand.DataTransferLength;
 	if (CommandOpcode & 0x80) return -EINVAL;
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    ErrorCode =
-	      copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_DCDB_T));
-	    if (ErrorCode != 0) goto Failure;
+	      copy_from_user(&DCDB, UserCommand.DCDB, sizeof(DAC960_V1_DCDB_T));
+	    if (ErrorCode != 0) goto Failure1;
 	    if (!((DataTransferLength == 0 &&
-		   DCDB.Direction == DAC960_DCDB_NoDataTransfer) ||
+		   DCDB.Direction
+		   == DAC960_V1_DCDB_NoDataTransfer) ||
 		  (DataTransferLength > 0 &&
-		   DCDB.Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
+		   DCDB.Direction
+		   == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
 		  (DataTransferLength < 0 &&
-		   DCDB.Direction == DAC960_DCDB_DataTransferSystemToDevice)))
+		   DCDB.Direction
+		   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
 	      return -EINVAL;
 	    if (((DCDB.TransferLengthHigh4 << 16) | DCDB.TransferLength)
 		!= abs(DataTransferLength))
@@ -2835,23 +5216,24 @@
 	    ErrorCode = copy_from_user(DataTransferBuffer,
 				       UserCommand.DataTransferBuffer,
 				       -DataTransferLength);
-	    if (ErrorCode != 0) goto Failure;
+	    if (ErrorCode != 0) goto Failure1;
 	  }
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
-	    while (Controller->DirectCommandActive[DCDB.Channel]
-						  [DCDB.TargetID] ||
+	    while (Controller->V1.DirectCommandActive[DCDB.Channel]
+						     [DCDB.TargetID] ||
 		   (Command = DAC960_AllocateCommand(Controller)) == NULL)
 	      DAC960_WaitForCommand(Controller);
-	    Controller->DirectCommandActive[DCDB.Channel]
-					   [DCDB.TargetID] = true;
+	    Controller->V1.DirectCommandActive[DCDB.Channel]
+					      [DCDB.TargetID] = true;
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-	    DAC960_ClearCommand(Command);
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_ImmediateCommand;
-	    memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
-	    Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(&DCDB);
+	    memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
+	    Command->V1.CommandMailbox.Type3.BusAddress =
+	      Virtual_to_Bus(&DCDB);
 	    DCDB.BusAddress = Virtual_to_Bus(DataTransferBuffer);
 	  }
 	else
@@ -2860,38 +5242,211 @@
 	    while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
 	      DAC960_WaitForCommand(Controller);
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-	    DAC960_ClearCommand(Command);
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_ImmediateCommand;
-	    memcpy(&Command->CommandMailbox, &UserCommand.CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
+	    memcpy(&Command->V1.CommandMailbox, &UserCommand.CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
 	    if (DataTransferBuffer != NULL)
-	      Command->CommandMailbox.Type3.BusAddress =
+	      Command->V1.CommandMailbox.Type3.BusAddress =
 		Virtual_to_Bus(DataTransferBuffer);
 	  }
 	DAC960_ExecuteCommand(Command);
-	CommandStatus = Command->CommandStatus;
+	CommandStatus = Command->V1.CommandStatus;
 	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
 	DAC960_DeallocateCommand(Command);
 	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
-	if (CommandStatus == DAC960_NormalCompletion &&
-	    DataTransferLength > 0)
+	if (DataTransferLength > 0)
 	  {
 	    ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
 				     DataTransferBuffer, DataTransferLength);
-	    if (ErrorCode != 0) goto Failure;
+	    if (ErrorCode != 0) goto Failure1;
 	  }
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
-	    Controller->DirectCommandActive[DCDB.Channel]
-					   [DCDB.TargetID] = false;
+	    Controller->V1.DirectCommandActive[DCDB.Channel]
+					      [DCDB.TargetID] = false;
 	    ErrorCode =
-	      copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_DCDB_T));
-	    if (ErrorCode != 0) goto Failure;
+	      copy_to_user(UserCommand.DCDB, &DCDB, sizeof(DAC960_V1_DCDB_T));
+	    if (ErrorCode != 0) goto Failure1;
+	  }
+	ErrorCode = CommandStatus;
+      Failure1:
+	if (DataTransferBuffer != NULL)
+	  kfree(DataTransferBuffer);
+	return ErrorCode;
+      }
+    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
+      {
+	DAC960_V2_UserCommand_T *UserSpaceUserCommand =
+	  (DAC960_V2_UserCommand_T *) Argument;
+	DAC960_V2_UserCommand_T UserCommand;
+	DAC960_Controller_T *Controller;
+	DAC960_Command_T *Command = NULL;
+	DAC960_V2_CommandMailbox_T *CommandMailbox;
+	DAC960_V2_CommandStatus_T CommandStatus;
+	ProcessorFlags_T ProcessorFlags;
+	int ControllerNumber, DataTransferLength;
+	int DataTransferResidue, RequestSenseLength;
+	unsigned char *DataTransferBuffer = NULL;
+	unsigned char *RequestSenseBuffer = NULL;
+	if (UserSpaceUserCommand == NULL) return -EINVAL;
+	ErrorCode = copy_from_user(&UserCommand, UserSpaceUserCommand,
+				   sizeof(DAC960_V2_UserCommand_T));
+	if (ErrorCode != 0) goto Failure2;
+	ControllerNumber = UserCommand.ControllerNumber;
+	if (ControllerNumber < 0 ||
+	    ControllerNumber > DAC960_ControllerCount - 1)
+	  return -ENXIO;
+	Controller = DAC960_Controllers[ControllerNumber];
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+	DataTransferLength = UserCommand.DataTransferLength;
+	if (DataTransferLength > 0)
+	  {
+	    DataTransferBuffer = kmalloc(DataTransferLength, GFP_KERNEL);
+	    if (DataTransferBuffer == NULL) return -ENOMEM;
+	    memset(DataTransferBuffer, 0, DataTransferLength);
+	  }
+	else if (DataTransferLength < 0)
+	  {
+	    DataTransferBuffer = kmalloc(-DataTransferLength, GFP_KERNEL);
+	    if (DataTransferBuffer == NULL) return -ENOMEM;
+	    ErrorCode = copy_from_user(DataTransferBuffer,
+				       UserCommand.DataTransferBuffer,
+				       -DataTransferLength);
+	    if (ErrorCode != 0) goto Failure2;
+	  }
+	RequestSenseLength = UserCommand.RequestSenseLength;
+	if (RequestSenseLength > 0)
+	  {
+	    RequestSenseBuffer = kmalloc(RequestSenseLength, GFP_KERNEL);
+	    if (RequestSenseBuffer == NULL)
+	      {
+		ErrorCode = -ENOMEM;
+		goto Failure2;
+	      }
+	    memset(RequestSenseBuffer, 0, RequestSenseLength);
+	  }
+	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+	while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+	  DAC960_WaitForCommand(Controller);
+	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	DAC960_V2_ClearCommand(Command);
+	Command->CommandType = DAC960_ImmediateCommand;
+	CommandMailbox = &Command->V2.CommandMailbox;
+	memcpy(CommandMailbox, &UserCommand.CommandMailbox,
+	       sizeof(DAC960_V2_CommandMailbox_T));
+	CommandMailbox->Common.CommandControlBits
+			      .AdditionalScatterGatherListMemory = false;
+	CommandMailbox->Common.CommandControlBits
+			      .NoAutoRequestSense = true;
+	CommandMailbox->Common.DataTransferSize = 0;
+	CommandMailbox->Common.DataTransferPageNumber = 0;
+	memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
+	       sizeof(DAC960_V2_DataTransferMemoryAddress_T));
+	if (DataTransferLength != 0)
+	  {
+	    if (DataTransferLength > 0)
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = true;
+		CommandMailbox->Common.DataTransferSize = DataTransferLength;
+	      }
+	    else
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = false;
+		CommandMailbox->Common.DataTransferSize = -DataTransferLength;
+	      }
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentDataPointer =
+	      Virtual_to_Bus(DataTransferBuffer);
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentByteCount =
+	      CommandMailbox->Common.DataTransferSize;
+	  }
+	if (RequestSenseLength > 0)
+	  {
+	    CommandMailbox->Common.CommandControlBits
+				  .NoAutoRequestSense = false;
+	    CommandMailbox->Common.RequestSenseSize = RequestSenseLength;
+	    CommandMailbox->Common.RequestSenseBusAddress =
+	      Virtual_to_Bus(RequestSenseBuffer);
+	  }
+	DAC960_ExecuteCommand(Command);
+	CommandStatus = Command->V2.CommandStatus;
+	RequestSenseLength = Command->V2.RequestSenseLength;
+	DataTransferResidue = Command->V2.DataTransferResidue;
+	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+	DAC960_DeallocateCommand(Command);
+	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	if (RequestSenseLength > UserCommand.RequestSenseLength)
+	  RequestSenseLength = UserCommand.RequestSenseLength;
+	ErrorCode = copy_to_user(&UserSpaceUserCommand->DataTransferLength,
+				 &DataTransferResidue,
+				 sizeof(DataTransferResidue));
+	if (ErrorCode != 0) goto Failure2;
+	ErrorCode = copy_to_user(&UserSpaceUserCommand->RequestSenseLength,
+				 &RequestSenseLength,
+				 sizeof(RequestSenseLength));
+	if (ErrorCode != 0) goto Failure2;
+	if (DataTransferLength > 0)
+	  {
+	    ErrorCode = copy_to_user(UserCommand.DataTransferBuffer,
+				     DataTransferBuffer, DataTransferLength);
+	    if (ErrorCode != 0) goto Failure2;
+	  }
+	if (RequestSenseLength > 0)
+	  {
+	    ErrorCode = copy_to_user(UserCommand.RequestSenseBuffer,
+				     RequestSenseBuffer, RequestSenseLength);
+	    if (ErrorCode != 0) goto Failure2;
 	  }
 	ErrorCode = CommandStatus;
-      Failure:
+      Failure2:
 	if (DataTransferBuffer != NULL)
 	  kfree(DataTransferBuffer);
+	if (RequestSenseBuffer != NULL)
+	  kfree(RequestSenseBuffer);
+	return ErrorCode;
+      }
+    case DAC960_IOCTL_V2_GET_HEALTH_STATUS:
+      {
+	DAC960_V2_GetHealthStatus_T *UserSpaceGetHealthStatus =
+	  (DAC960_V2_GetHealthStatus_T *) Argument;
+	DAC960_V2_GetHealthStatus_T GetHealthStatus;
+	DAC960_V2_HealthStatusBuffer_T HealthStatusBuffer;
+	DAC960_Controller_T *Controller;
+	int ControllerNumber;
+	if (UserSpaceGetHealthStatus == NULL) return -EINVAL;
+	ErrorCode = copy_from_user(&GetHealthStatus, UserSpaceGetHealthStatus,
+				   sizeof(DAC960_V2_GetHealthStatus_T));
+	if (ErrorCode != 0) return ErrorCode;
+	ControllerNumber = GetHealthStatus.ControllerNumber;
+	if (ControllerNumber < 0 ||
+	    ControllerNumber > DAC960_ControllerCount - 1)
+	  return -ENXIO;
+	Controller = DAC960_Controllers[ControllerNumber];
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+	ErrorCode = copy_from_user(&HealthStatusBuffer,
+				   GetHealthStatus.HealthStatusBuffer,
+				   sizeof(DAC960_V2_HealthStatusBuffer_T));
+	if (ErrorCode != 0) return ErrorCode;
+	while (Controller->V2.HealthStatusBuffer->StatusChangeCounter
+	       == HealthStatusBuffer.StatusChangeCounter &&
+	       Controller->V2.HealthStatusBuffer->NextEventSequenceNumber
+	       == HealthStatusBuffer.NextEventSequenceNumber)
+	  {
+	    interruptible_sleep_on_timeout(&Controller->HealthStatusWaitQueue,
+					   DAC960_MonitoringTimerInterval);
+	    if (signal_pending(current)) return -EINTR;
+	  }
+	ErrorCode = copy_to_user(GetHealthStatus.HealthStatusBuffer,
+				 Controller->V2.HealthStatusBuffer,
+				 sizeof(DAC960_V2_HealthStatusBuffer_T));
 	return ErrorCode;
       }
     }
@@ -2921,28 +5476,29 @@
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
 	memset(ControllerInfo, 0, sizeof(DAC960_ControllerInfo_T));
 	ControllerInfo->ControllerNumber = ControllerNumber;
+	ControllerInfo->FirmwareType = Controller->FirmwareType;
+	ControllerInfo->Channels = Controller->Channels;
+	ControllerInfo->Targets = Controller->Targets;
 	ControllerInfo->PCI_Bus = Controller->Bus;
 	ControllerInfo->PCI_Device = Controller->Device;
 	ControllerInfo->PCI_Function = Controller->Function;
 	ControllerInfo->IRQ_Channel = Controller->IRQ_Channel;
-	ControllerInfo->Channels = Controller->Channels;
 	ControllerInfo->PCI_Address = Controller->PCI_Address;
 	strcpy(ControllerInfo->ModelName, Controller->ModelName);
 	strcpy(ControllerInfo->FirmwareVersion, Controller->FirmwareVersion);
 	return 0;
       }
-    case DAC960_IOCTL_EXECUTE_COMMAND:
+    case DAC960_IOCTL_V1_EXECUTE_COMMAND:
       {
-	DAC960_KernelCommand_T *KernelCommand =
-	  (DAC960_KernelCommand_T *) Argument;
+	DAC960_V1_KernelCommand_T *KernelCommand =
+	  (DAC960_V1_KernelCommand_T *) Argument;
 	DAC960_Controller_T *Controller;
 	DAC960_Command_T *Command = NULL;
-	DAC960_CommandOpcode_T CommandOpcode;
-	DAC960_DCDB_T *DCDB = NULL;
+	DAC960_V1_CommandOpcode_T CommandOpcode;
+	DAC960_V1_DCDB_T *DCDB = NULL;
 	ProcessorFlags_T ProcessorFlags;
 	int ControllerNumber, DataTransferLength;
 	unsigned char *DataTransferBuffer = NULL;
@@ -2952,21 +5508,23 @@
 	    ControllerNumber > DAC960_ControllerCount - 1)
 	  return -ENXIO;
 	Controller = DAC960_Controllers[ControllerNumber];
-	if (Controller == NULL)
-	  return -ENXIO;
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V1_Controller) return -EINVAL;
 	CommandOpcode = KernelCommand->CommandMailbox.Common.CommandOpcode;
 	DataTransferLength = KernelCommand->DataTransferLength;
 	DataTransferBuffer = KernelCommand->DataTransferBuffer;
 	if (CommandOpcode & 0x80) return -EINVAL;
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    DCDB = KernelCommand->DCDB;
 	    if (!((DataTransferLength == 0 &&
-		   DCDB->Direction == DAC960_DCDB_NoDataTransfer) ||
+		   DCDB->Direction == DAC960_V1_DCDB_NoDataTransfer) ||
 		  (DataTransferLength > 0 &&
-		   DCDB->Direction == DAC960_DCDB_DataTransferDeviceToSystem) ||
+		   DCDB->Direction
+		   == DAC960_V1_DCDB_DataTransferDeviceToSystem) ||
 		  (DataTransferLength < 0 &&
-		   DCDB->Direction == DAC960_DCDB_DataTransferSystemToDevice)))
+		   DCDB->Direction
+		   == DAC960_V1_DCDB_DataTransferSystemToDevice)))
 	      return -EINVAL;
 	    if (((DCDB->TransferLengthHigh4 << 16) | DCDB->TransferLength)
 		!= abs(DataTransferLength))
@@ -2976,25 +5534,26 @@
 	  return -EINVAL;
 	if (DataTransferLength > 0)
 	  memset(DataTransferBuffer, 0, DataTransferLength);
-	if (CommandOpcode == DAC960_DCDB)
+	if (CommandOpcode == DAC960_V1_DCDB)
 	  {
 	    DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
-	    if (!Controller->DirectCommandActive[DCDB->Channel]
-						[DCDB->TargetID])
+	    if (!Controller->V1.DirectCommandActive[DCDB->Channel]
+						   [DCDB->TargetID])
 	      Command = DAC960_AllocateCommand(Controller);
 	    if (Command == NULL)
 	      {
 		DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
 		return -EBUSY;
 	      }
-	    else Controller->DirectCommandActive[DCDB->Channel]
-						[DCDB->TargetID] = true;
-	    DAC960_ClearCommand(Command);
+	    else Controller->V1.DirectCommandActive[DCDB->Channel]
+						   [DCDB->TargetID] = true;
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_QueuedCommand;
-	    memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
-	    Command->CommandMailbox.Type3.BusAddress = Virtual_to_Bus(DCDB);
-	    Command->KernelCommand = KernelCommand;
+	    memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
+	    Command->V1.CommandMailbox.Type3.BusAddress =
+	      Virtual_to_Bus(DCDB);
+	    Command->V1.KernelCommand = KernelCommand;
 	    DCDB->BusAddress = Virtual_to_Bus(DataTransferBuffer);
 	    DAC960_QueueCommand(Command);
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
@@ -3008,42 +5567,153 @@
 		DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
 		return -EBUSY;
 	      }
-	    DAC960_ClearCommand(Command);
+	    DAC960_V1_ClearCommand(Command);
 	    Command->CommandType = DAC960_QueuedCommand;
-	    memcpy(&Command->CommandMailbox, &KernelCommand->CommandMailbox,
-		   sizeof(DAC960_CommandMailbox_T));
+	    memcpy(&Command->V1.CommandMailbox, &KernelCommand->CommandMailbox,
+		   sizeof(DAC960_V1_CommandMailbox_T));
 	    if (DataTransferBuffer != NULL)
-	      Command->CommandMailbox.Type3.BusAddress =
+	      Command->V1.CommandMailbox.Type3.BusAddress =
 		Virtual_to_Bus(DataTransferBuffer);
-	    Command->KernelCommand = KernelCommand;
+	    Command->V1.KernelCommand = KernelCommand;
 	    DAC960_QueueCommand(Command);
 	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
 	  }
 	return 0;
       }
+    case DAC960_IOCTL_V2_EXECUTE_COMMAND:
+      {
+	DAC960_V2_KernelCommand_T *KernelCommand =
+	  (DAC960_V2_KernelCommand_T *) Argument;
+	DAC960_Controller_T *Controller;
+	DAC960_Command_T *Command = NULL;
+	DAC960_V2_CommandMailbox_T *CommandMailbox;
+	ProcessorFlags_T ProcessorFlags;
+	int ControllerNumber, DataTransferLength, RequestSenseLength;
+	unsigned char *DataTransferBuffer = NULL;
+	unsigned char *RequestSenseBuffer = NULL;
+	if (KernelCommand == NULL) return -EINVAL;
+	ControllerNumber = KernelCommand->ControllerNumber;
+	if (ControllerNumber < 0 ||
+	    ControllerNumber > DAC960_ControllerCount - 1)
+	  return -ENXIO;
+	Controller = DAC960_Controllers[ControllerNumber];
+	if (Controller == NULL) return -ENXIO;
+	if (Controller->FirmwareType != DAC960_V2_Controller) return -EINVAL;
+	DataTransferLength = KernelCommand->DataTransferLength;
+	RequestSenseLength = KernelCommand->RequestSenseLength;
+	DataTransferBuffer = KernelCommand->DataTransferBuffer;
+	RequestSenseBuffer = KernelCommand->RequestSenseBuffer;
+	if (DataTransferLength != 0 && DataTransferBuffer == NULL)
+	  return -EINVAL;
+	if (RequestSenseLength < 0)
+	  return -EINVAL;
+	if (RequestSenseLength > 0 && RequestSenseBuffer == NULL)
+	  return -EINVAL;
+	if (DataTransferLength > 0)
+	  memset(DataTransferBuffer, 0, DataTransferLength);
+	if (RequestSenseLength > 0)
+	  memset(RequestSenseBuffer, 0, RequestSenseLength);
+	DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+	Command = DAC960_AllocateCommand(Controller);
+	if (Command == NULL)
+	  {
+	    DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	    return -EBUSY;
+	  }
+	DAC960_V2_ClearCommand(Command);
+	Command->CommandType = DAC960_QueuedCommand;
+	CommandMailbox = &Command->V2.CommandMailbox;
+	memcpy(CommandMailbox, &KernelCommand->CommandMailbox,
+	       sizeof(DAC960_V2_CommandMailbox_T));
+	CommandMailbox->Common.CommandControlBits
+			      .AdditionalScatterGatherListMemory = false;
+	CommandMailbox->Common.CommandControlBits
+			      .NoAutoRequestSense = true;
+	CommandMailbox->Common.DataTransferSize = 0;
+	CommandMailbox->Common.DataTransferPageNumber = 0;
+	memset(&CommandMailbox->Common.DataTransferMemoryAddress, 0,
+	       sizeof(DAC960_V2_DataTransferMemoryAddress_T));
+	if (DataTransferLength != 0)
+	  {
+	    if (DataTransferLength > 0)
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = true;
+		CommandMailbox->Common.DataTransferSize = DataTransferLength;
+	      }
+	    else
+	      {
+		CommandMailbox->Common.CommandControlBits
+				      .DataTransferControllerToHost = false;
+		CommandMailbox->Common.DataTransferSize = -DataTransferLength;
+	      }
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentDataPointer =
+	      Virtual_to_Bus(DataTransferBuffer);
+	    CommandMailbox->Common.DataTransferMemoryAddress
+				  .ScatterGatherSegments[0]
+				  .SegmentByteCount =
+	      CommandMailbox->Common.DataTransferSize;
+	  }
+	if (RequestSenseLength > 0)
+	  {
+	    CommandMailbox->Common.CommandControlBits
+				  .NoAutoRequestSense = false;
+	    CommandMailbox->Common.RequestSenseBusAddress =
+	      Virtual_to_Bus(RequestSenseBuffer);
+	  }
+	Command->V2.KernelCommand = KernelCommand;
+	DAC960_QueueCommand(Command);
+	DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+	return 0;
+      }
     }
   return -EINVAL;
 }
 
 
 /*
-  DAC960_GenericDiskInit is the Generic Disk Information Initialization
-  Function for the DAC960 Driver.
-*/
-
-static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *GenericDiskInfo)
-{
-  DAC960_Controller_T *Controller =
-    (DAC960_Controller_T *) GenericDiskInfo->real_devices;
-  DAC960_LogicalDriveInformation_T *LogicalDriveInformation =
-    Controller->LogicalDriveInformation
-		[Controller->LogicalDriveInformationIndex];
-  int LogicalDriveNumber;
-  for (LogicalDriveNumber = 0;
-       LogicalDriveNumber < Controller->LogicalDriveCount;
-       LogicalDriveNumber++)
-    GenericDiskInfo->part[DAC960_MinorNumber(LogicalDriveNumber, 0)].nr_sects =
-      LogicalDriveInformation[LogicalDriveNumber].LogicalDriveSize;
+  DAC960_CheckStatusBuffer verifies that there is room to hold ByteCount
+  additional bytes in the Combined Status Buffer and grows the buffer if
+  necessary.  It returns true if there is enough room and false otherwise.
+*/
+
+static boolean DAC960_CheckStatusBuffer(DAC960_Controller_T *Controller,
+					unsigned int ByteCount)
+{
+  unsigned char *NewStatusBuffer;
+  if (Controller->InitialStatusLength + 1 +
+      Controller->CurrentStatusLength + ByteCount + 1 <=
+      Controller->CombinedStatusBufferLength)
+    return true;
+  if (Controller->CombinedStatusBufferLength == 0)
+    {
+      unsigned int NewStatusBufferLength = DAC960_InitialStatusBufferSize;
+      while (NewStatusBufferLength < ByteCount)
+	NewStatusBufferLength *= 2;
+      Controller->CombinedStatusBuffer =
+	(unsigned char *) kmalloc(NewStatusBufferLength, GFP_ATOMIC);
+      if (Controller->CombinedStatusBuffer == NULL) return false;
+      Controller->CombinedStatusBufferLength = NewStatusBufferLength;
+      return true;
+    }
+  NewStatusBuffer = (unsigned char *)
+    kmalloc(2 * Controller->CombinedStatusBufferLength, GFP_ATOMIC);
+  if (NewStatusBuffer == NULL)
+    {
+      DAC960_Warning("Unable to expand Combined Status Buffer - Truncating\n",
+		     Controller);
+      return false;
+    }
+  memcpy(NewStatusBuffer, Controller->CombinedStatusBuffer,
+	 Controller->CombinedStatusBufferLength);
+  kfree(Controller->CombinedStatusBuffer);
+  Controller->CombinedStatusBuffer = NewStatusBuffer;
+  Controller->CombinedStatusBufferLength *= 2;
+  Controller->CurrentStatusBuffer =
+    &NewStatusBuffer[Controller->InitialStatusLength + 1];
+  return true;
 }
 
 
@@ -3052,11 +5722,11 @@
 */
 
 static void DAC960_Message(DAC960_MessageLevel_T MessageLevel,
-			   char *Format,
+			   unsigned char *Format,
 			   DAC960_Controller_T *Controller,
 			   ...)
 {
-  static char Buffer[DAC960_LineBufferSize];
+  static unsigned char Buffer[DAC960_LineBufferSize];
   static boolean BeginningOfLine = true;
   va_list Arguments;
   int Length = 0;
@@ -3071,9 +5741,16 @@
     {
       if (!Controller->ControllerInitialized)
 	{
-	  strcpy(&Controller->InitialStatusBuffer[
-		    Controller->InitialStatusLength], Buffer);
-	  Controller->InitialStatusLength += Length;
+	  if (DAC960_CheckStatusBuffer(Controller, Length))
+	    {
+	      strcpy(&Controller->CombinedStatusBuffer
+				  [Controller->InitialStatusLength],
+		     Buffer);
+	      Controller->InitialStatusLength += Length;
+	      Controller->CurrentStatusBuffer =
+		&Controller->CombinedStatusBuffer
+			     [Controller->InitialStatusLength + 1];
+	    }
 	  if (MessageLevel == DAC960_AnnounceLevel)
 	    {
 	      static int AnnouncementLines = 0;
@@ -3093,7 +5770,7 @@
 	      else printk("%s", Buffer);
 	    }
 	}
-      else
+      else if (DAC960_CheckStatusBuffer(Controller, Length))
 	{
 	  strcpy(&Controller->CurrentStatusBuffer[
 		    Controller->CurrentStatusLength], Buffer);
@@ -3102,8 +5779,8 @@
     }
   else if (MessageLevel == DAC960_ProgressLevel)
     {
-      strcpy(Controller->RebuildProgressBuffer, Buffer);
-      Controller->RebuildProgressLength = Length;
+      strcpy(Controller->ProgressBuffer, Buffer);
+      Controller->ProgressBufferLength = Length;
       if (Controller->EphemeralProgressMessage)
 	{
 	  if (jiffies - Controller->LastProgressReportTime
@@ -3138,15 +5815,15 @@
 
 
 /*
-  DAC960_ParsePhysicalDrive parses spaces followed by a Physical Drive
+  DAC960_ParsePhysicalDevice parses spaces followed by a Physical Device
   Channel:TargetID specification from a User Command string.  It updates
-  Channel and TargetID and returns true on success and returns false otherwise.
+  Channel and TargetID and returns true on success and false on failure.
 */
 
-static boolean DAC960_ParsePhysicalDrive(DAC960_Controller_T *Controller,
-					 char *UserCommandString,
-					 unsigned char *Channel,
-					 unsigned char *TargetID)
+static boolean DAC960_ParsePhysicalDevice(DAC960_Controller_T *Controller,
+					  char *UserCommandString,
+					  unsigned char *Channel,
+					  unsigned char *TargetID)
 {
   char *NewUserCommandString = UserCommandString;
   unsigned long XChannel, XTargetID;
@@ -3162,7 +5839,7 @@
   XTargetID = simple_strtoul(UserCommandString, &NewUserCommandString, 10);
   if (NewUserCommandString == UserCommandString ||
       *NewUserCommandString != '\0' ||
-      XTargetID >= DAC960_MaxTargets)
+      XTargetID >= Controller->Targets)
     return false;
   *Channel = XChannel;
   *TargetID = XTargetID;
@@ -3173,7 +5850,7 @@
 /*
   DAC960_ParseLogicalDrive parses spaces followed by a Logical Drive Number
   specification from a User Command string.  It updates LogicalDriveNumber and
-  returns true on success and returns false otherwise.
+  returns true on success and false on failure.
 */
 
 static boolean DAC960_ParseLogicalDrive(DAC960_Controller_T *Controller,
@@ -3189,7 +5866,7 @@
     simple_strtoul(UserCommandString, &NewUserCommandString, 10);
   if (NewUserCommandString == UserCommandString ||
       *NewUserCommandString != '\0' ||
-      XLogicalDriveNumber >= Controller->LogicalDriveCount)
+      XLogicalDriveNumber > DAC960_MaxLogicalDrives - 1)
     return false;
   *LogicalDriveNumber = XLogicalDriveNumber;
   return true;
@@ -3197,68 +5874,71 @@
 
 
 /*
-  DAC960_SetDeviceState sets the Device State for a Physical Drive.
+  DAC960_V1_SetDeviceState sets the Device State for a Physical Device for
+  DAC960 V1 Firmware Controllers.
 */
 
-static void DAC960_SetDeviceState(DAC960_Controller_T *Controller,
-				  DAC960_Command_T *Command,
-				  unsigned char Channel,
-				  unsigned char TargetID,
-				  DAC960_PhysicalDeviceState_T DeviceState,
-				  const char *DeviceStateString)
+static void DAC960_V1_SetDeviceState(DAC960_Controller_T *Controller,
+				     DAC960_Command_T *Command,
+				     unsigned char Channel,
+				     unsigned char TargetID,
+				     DAC960_V1_PhysicalDeviceState_T
+				       DeviceState,
+				     const unsigned char *DeviceStateString)
 {
-  DAC960_CommandMailbox_T *CommandMailbox = &Command->CommandMailbox;
-  CommandMailbox->Type3D.CommandOpcode = DAC960_StartDevice;
+  DAC960_V1_CommandMailbox_T *CommandMailbox = &Command->V1.CommandMailbox;
+  CommandMailbox->Type3D.CommandOpcode = DAC960_V1_StartDevice;
   CommandMailbox->Type3D.Channel = Channel;
   CommandMailbox->Type3D.TargetID = TargetID;
   CommandMailbox->Type3D.DeviceState = DeviceState;
   CommandMailbox->Type3D.Modifier = 0;
   DAC960_ExecuteCommand(Command);
-  switch (Command->CommandStatus)
+  switch (Command->V1.CommandStatus)
     {
-    case DAC960_NormalCompletion:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Succeeded\n", Controller,
+    case DAC960_V1_NormalCompletion:
+      DAC960_UserCritical("%s of Physical Device %d:%d Succeeded\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_UnableToStartDevice:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_UnableToStartDevice:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Unable to Start Device\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_NoDeviceAtAddress:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_NoDeviceAtAddress:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "No Device at Address\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_InvalidChannelOrTargetOrModifier:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_InvalidChannelOrTargetOrModifier:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Invalid Channel or Target or Modifier\n",
 			  Controller, DeviceStateString, Channel, TargetID);
       break;
-    case DAC960_ChannelBusy:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+    case DAC960_V1_ChannelBusy:
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Channel Busy\n", Controller,
 			  DeviceStateString, Channel, TargetID);
       break;
     default:
-      DAC960_UserCritical("%s of Physical Drive %d:%d Failed - "
+      DAC960_UserCritical("%s of Physical Device %d:%d Failed - "
 			  "Unexpected Status %04X\n", Controller,
 			  DeviceStateString, Channel, TargetID,
-			  Command->CommandStatus);
+			  Command->V1.CommandStatus);
       break;
     }
 }
 
 
 /*
-  DAC960_ExecuteUserCommand executes a User Command.
+  DAC960_V1_ExecuteUserCommand executes a User Command for DAC960 V1 Firmware
+  Controllers.
 */
 
-static boolean DAC960_ExecuteUserCommand(DAC960_Controller_T *Controller,
-					 char *UserCommand)
+static boolean DAC960_V1_ExecuteUserCommand(DAC960_Controller_T *Controller,
+					    unsigned char *UserCommand)
 {
   DAC960_Command_T *Command;
-  DAC960_CommandMailbox_T *CommandMailbox;
+  DAC960_V1_CommandMailbox_T *CommandMailbox;
   ProcessorFlags_T ProcessorFlags;
   unsigned char Channel, TargetID, LogicalDriveNumber;
   DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
@@ -3266,100 +5946,98 @@
     DAC960_WaitForCommand(Controller);
   DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
   Controller->UserStatusLength = 0;
-  DAC960_ClearCommand(Command);
+  DAC960_V1_ClearCommand(Command);
   Command->CommandType = DAC960_ImmediateCommand;
-  CommandMailbox = &Command->CommandMailbox;
+  CommandMailbox = &Command->V1.CommandMailbox;
   if (strcmp(UserCommand, "flush-cache") == 0)
     {
-      CommandMailbox->Type3.CommandOpcode = DAC960_Flush;
+      CommandMailbox->Type3.CommandOpcode = DAC960_V1_Flush;
       DAC960_ExecuteCommand(Command);
       DAC960_UserCritical("Cache Flush Completed\n", Controller);
     }
   else if (strncmp(UserCommand, "kill", 4) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[4],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
+				      &Channel, &TargetID))
     {
-      DAC960_DeviceState_T *DeviceState =
-	&Controller->DeviceState[Controller->DeviceStateIndex]
-				[Channel][TargetID];
+      DAC960_V1_DeviceState_T *DeviceState =
+	&Controller->V1.DeviceState[Channel][TargetID];
       if (DeviceState->Present &&
-	  DeviceState->DeviceType == DAC960_DiskType &&
-	  DeviceState->DeviceState != DAC960_Device_Dead)
-	DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
-			      DAC960_Device_Dead, "Kill");
-      else DAC960_UserCritical("Kill of Physical Drive %d:%d Illegal\n",
+	  DeviceState->DeviceType == DAC960_V1_DiskType &&
+	  DeviceState->DeviceState != DAC960_V1_Device_Dead)
+	DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+				 DAC960_V1_Device_Dead, "Kill");
+      else DAC960_UserCritical("Kill of Physical Device %d:%d Illegal\n",
 			       Controller, Channel, TargetID);
     }
   else if (strncmp(UserCommand, "make-online", 11) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[11],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
+				      &Channel, &TargetID))
     {
-      DAC960_DeviceState_T *DeviceState =
-	&Controller->DeviceState[Controller->DeviceStateIndex]
-				[Channel][TargetID];
+      DAC960_V1_DeviceState_T *DeviceState =
+	&Controller->V1.DeviceState[Channel][TargetID];
       if (DeviceState->Present &&
-	  DeviceState->DeviceType == DAC960_DiskType &&
-	  DeviceState->DeviceState == DAC960_Device_Dead)
-	DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
-			      DAC960_Device_Online, "Make Online");
-      else DAC960_UserCritical("Make Online of Physical Drive %d:%d Illegal\n",
+	  DeviceState->DeviceType == DAC960_V1_DiskType &&
+	  DeviceState->DeviceState == DAC960_V1_Device_Dead)
+	DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+				 DAC960_V1_Device_Online, "Make Online");
+      else DAC960_UserCritical("Make Online of Physical Device %d:%d Illegal\n",
 			       Controller, Channel, TargetID);
 
     }
   else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[12],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
+				      &Channel, &TargetID))
     {
-      DAC960_DeviceState_T *DeviceState =
-	&Controller->DeviceState[Controller->DeviceStateIndex]
-				[Channel][TargetID];
+      DAC960_V1_DeviceState_T *DeviceState =
+	&Controller->V1.DeviceState[Channel][TargetID];
       if (DeviceState->Present &&
-	  DeviceState->DeviceType == DAC960_DiskType &&
-	  DeviceState->DeviceState == DAC960_Device_Dead)
-	DAC960_SetDeviceState(Controller, Command, Channel, TargetID,
-			      DAC960_Device_Standby, "Make Standby");
-      else DAC960_UserCritical("Make Standby of Physical Drive %d:%d Illegal\n",
+	  DeviceState->DeviceType == DAC960_V1_DiskType &&
+	  DeviceState->DeviceState == DAC960_V1_Device_Dead)
+	DAC960_V1_SetDeviceState(Controller, Command, Channel, TargetID,
+				 DAC960_V1_Device_Standby, "Make Standby");
+      else DAC960_UserCritical("Make Standby of Physical "
+			       "Device %d:%d Illegal\n",
 			       Controller, Channel, TargetID);
     }
   else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
-	   DAC960_ParsePhysicalDrive(Controller, &UserCommand[7],
-				     &Channel, &TargetID))
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
+				      &Channel, &TargetID))
     {
-      CommandMailbox->Type3D.CommandOpcode = DAC960_RebuildAsync;
+      CommandMailbox->Type3D.CommandOpcode = DAC960_V1_RebuildAsync;
       CommandMailbox->Type3D.Channel = Channel;
       CommandMailbox->Type3D.TargetID = TargetID;
       DAC960_ExecuteCommand(Command);
-      switch (Command->CommandStatus)
+      switch (Command->V1.CommandStatus)
 	{
-	case DAC960_NormalCompletion:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Initiated\n",
+	case DAC960_V1_NormalCompletion:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Initiated\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_AttemptToRebuildOnlineDrive:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_AttemptToRebuildOnlineDrive:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Attempt to Rebuild Online or "
 			      "Unresponsive Drive\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_NewDiskFailedDuringRebuild:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_NewDiskFailedDuringRebuild:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "New Disk Failed During Rebuild\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_InvalidDeviceAddress:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_InvalidDeviceAddress:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Invalid Device Address\n",
 			      Controller, Channel, TargetID);
 	  break;
-	case DAC960_RebuildOrCheckAlreadyInProgress:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	case DAC960_V1_RebuildOrCheckAlreadyInProgress:
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Rebuild or Consistency Check Already "
 			      "in Progress\n", Controller, Channel, TargetID);
 	  break;
 	default:
-	  DAC960_UserCritical("Rebuild of Physical Drive %d:%d Failed - "
+	  DAC960_UserCritical("Rebuild of Physical Device %d:%d Failed - "
 			      "Unexpected Status %04X\n", Controller,
-			      Channel, TargetID, Command->CommandStatus);
+			      Channel, TargetID, Command->V1.CommandStatus);
 	  break;
 	}
     }
@@ -3367,28 +6045,28 @@
 	   DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
 				    &LogicalDriveNumber))
     {
-      CommandMailbox->Type3C.CommandOpcode = DAC960_CheckConsistencyAsync;
+      CommandMailbox->Type3C.CommandOpcode = DAC960_V1_CheckConsistencyAsync;
       CommandMailbox->Type3C.LogicalDriveNumber = LogicalDriveNumber;
       CommandMailbox->Type3C.AutoRestore = true;
       DAC960_ExecuteCommand(Command);
-      switch (Command->CommandStatus)
+      switch (Command->V1.CommandStatus)
 	{
-	case DAC960_NormalCompletion:
+	case DAC960_V1_NormalCompletion:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Initiated\n",
 			      Controller, LogicalDriveNumber,
 			      Controller->ControllerNumber,
 			      LogicalDriveNumber);
 	  break;
-	case DAC960_DependentDiskIsDead:
+	case DAC960_V1_DependentDiskIsDead:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Failed - "
-			      "Dependent Physical Drive is DEAD\n",
+			      "Dependent Physical Device is DEAD\n",
 			      Controller, LogicalDriveNumber,
 			      Controller->ControllerNumber,
 			      LogicalDriveNumber);
 	  break;
-	case DAC960_InvalidOrNonredundantLogicalDrive:
+	case DAC960_V1_InvalidOrNonredundantLogicalDrive:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Failed - "
 			      "Invalid or Nonredundant Logical Drive\n",
@@ -3396,7 +6074,7 @@
 			      Controller->ControllerNumber,
 			      LogicalDriveNumber);
 	  break;
-	case DAC960_RebuildOrCheckAlreadyInProgress:
+	case DAC960_V1_RebuildOrCheckAlreadyInProgress:
 	  DAC960_UserCritical("Consistency Check of Logical Drive %d "
 			      "(/dev/rd/c%dd%d) Failed - Rebuild or "
 			      "Consistency Check Already in Progress\n",
@@ -3410,7 +6088,7 @@
 			      "Unexpected Status %04X\n",
 			      Controller, LogicalDriveNumber,
 			      Controller->ControllerNumber,
-			      LogicalDriveNumber, Command->CommandStatus);
+			      LogicalDriveNumber, Command->V1.CommandStatus);
 	  break;
 	}
     }
@@ -3418,14 +6096,14 @@
 	   strcmp(UserCommand, "cancel-consistency-check") == 0)
     {
       unsigned char OldRebuildRateConstant;
-      CommandMailbox->Type3R.CommandOpcode = DAC960_RebuildControl;
+      CommandMailbox->Type3R.CommandOpcode = DAC960_V1_RebuildControl;
       CommandMailbox->Type3R.RebuildRateConstant = 0xFF;
       CommandMailbox->Type3R.BusAddress =
 	Virtual_to_Bus(&OldRebuildRateConstant);
       DAC960_ExecuteCommand(Command);
-      switch (Command->CommandStatus)
+      switch (Command->V1.CommandStatus)
 	{
-	case DAC960_NormalCompletion:
+	case DAC960_V1_NormalCompletion:
 	  DAC960_UserCritical("Rebuild or Consistency Check Cancelled\n",
 			      Controller);
 	  break;
@@ -3433,7 +6111,7 @@
 	  DAC960_UserCritical("Cancellation of Rebuild or "
 			      "Consistency Check Failed - "
 			      "Unexpected Status %04X\n",
-			      Controller, Command->CommandStatus);
+			      Controller, Command->V1.CommandStatus);
 	  break;
 	}
     }
@@ -3447,25 +6125,235 @@
 
 
 /*
+  DAC960_V2_TranslatePhysicalDevice translates a Physical Device Channel and
+  TargetID into a Logical Device.  It returns true on success and false
+  on failure.
+*/
+
+static boolean DAC960_V2_TranslatePhysicalDevice(DAC960_Command_T *Command,
+						 unsigned char Channel,
+						 unsigned char TargetID,
+						 unsigned short
+						   *LogicalDeviceNumber)
+{
+  DAC960_V2_CommandMailbox_T SavedCommandMailbox, *CommandMailbox;
+  DAC960_V2_PhysicalToLogicalDevice_T PhysicalToLogicalDevice;
+  CommandMailbox = &Command->V2.CommandMailbox;
+  memcpy(&SavedCommandMailbox, CommandMailbox,
+	 sizeof(DAC960_V2_CommandMailbox_T));
+  CommandMailbox->PhysicalDeviceInfo.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .DataTransferControllerToHost = true;
+  CommandMailbox->PhysicalDeviceInfo.CommandControlBits
+				    .NoAutoRequestSense = true;
+  CommandMailbox->PhysicalDeviceInfo.DataTransferSize =
+    sizeof(DAC960_V2_PhysicalToLogicalDevice_T);
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.TargetID = TargetID;
+  CommandMailbox->PhysicalDeviceInfo.PhysicalDevice.Channel = Channel;
+  CommandMailbox->PhysicalDeviceInfo.IOCTL_Opcode =
+    DAC960_V2_TranslatePhysicalToLogicalDevice;
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentDataPointer =
+    Virtual_to_Bus(&PhysicalToLogicalDevice);
+  CommandMailbox->Common.DataTransferMemoryAddress
+			.ScatterGatherSegments[0]
+			.SegmentByteCount =
+    CommandMailbox->Common.DataTransferSize;
+  DAC960_ExecuteCommand(Command);
+  memcpy(CommandMailbox, &SavedCommandMailbox,
+	 sizeof(DAC960_V2_CommandMailbox_T));
+  *LogicalDeviceNumber = PhysicalToLogicalDevice.LogicalDeviceNumber;
+  return (Command->V2.CommandStatus == DAC960_V2_NormalCompletion);
+}
+
+
+/*
+  DAC960_V2_ExecuteUserCommand executes a User Command for DAC960 V2 Firmware
+  Controllers.
+*/
+
+static boolean DAC960_V2_ExecuteUserCommand(DAC960_Controller_T *Controller,
+					    unsigned char *UserCommand)
+{
+  DAC960_Command_T *Command;
+  DAC960_V2_CommandMailbox_T *CommandMailbox;
+  ProcessorFlags_T ProcessorFlags;
+  unsigned char Channel, TargetID, LogicalDriveNumber;
+  unsigned short LogicalDeviceNumber;
+  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+  while ((Command = DAC960_AllocateCommand(Controller)) == NULL)
+    DAC960_WaitForCommand(Controller);
+  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+  Controller->UserStatusLength = 0;
+  DAC960_V2_ClearCommand(Command);
+  Command->CommandType = DAC960_ImmediateCommand;
+  CommandMailbox = &Command->V2.CommandMailbox;
+  CommandMailbox->Common.CommandOpcode = DAC960_V2_IOCTL;
+  CommandMailbox->Common.CommandControlBits.DataTransferControllerToHost = true;
+  CommandMailbox->Common.CommandControlBits.NoAutoRequestSense = true;
+  if (strcmp(UserCommand, "flush-cache") == 0)
+    {
+      CommandMailbox->DeviceOperation.IOCTL_Opcode = DAC960_V2_PauseDevice;
+      CommandMailbox->DeviceOperation.OperationDevice =
+	DAC960_V2_RAID_Controller;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Cache Flush Completed\n", Controller);
+    }
+  else if (strncmp(UserCommand, "kill", 4) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[4],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->SetDeviceState.IOCTL_Opcode =
+	DAC960_V2_SetDeviceState;
+      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+	DAC960_V2_Device_Dead;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Kill of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Succeeded" : "Failed"));
+    }
+  else if (strncmp(UserCommand, "make-online", 11) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[11],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->SetDeviceState.IOCTL_Opcode =
+	DAC960_V2_SetDeviceState;
+      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+	DAC960_V2_Device_Online;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Make Online of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Succeeded" : "Failed"));
+    }
+  else if (strncmp(UserCommand, "make-standby", 12) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[12],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->SetDeviceState.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->SetDeviceState.IOCTL_Opcode =
+	DAC960_V2_SetDeviceState;
+      CommandMailbox->SetDeviceState.DeviceState.PhysicalDeviceState =
+	DAC960_V2_Device_Standby;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Make Standby of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Succeeded" : "Failed"));
+    }
+  else if (strncmp(UserCommand, "rebuild", 7) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[7],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+	DAC960_V2_RebuildDeviceStart;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Initiated" : "Not Initiated"));
+    }
+  else if (strncmp(UserCommand, "cancel-rebuild", 14) == 0 &&
+	   DAC960_ParsePhysicalDevice(Controller, &UserCommand[14],
+				      &Channel, &TargetID) &&
+	   DAC960_V2_TranslatePhysicalDevice(Command, Channel, TargetID,
+					     &LogicalDeviceNumber))
+    {
+      CommandMailbox->LogicalDeviceInfo.LogicalDevice.LogicalDeviceNumber =
+	LogicalDeviceNumber;
+      CommandMailbox->LogicalDeviceInfo.IOCTL_Opcode =
+	DAC960_V2_RebuildDeviceStop;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Rebuild of Physical Device %d:%d %s\n",
+			  Controller, Channel, TargetID,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Cancelled" : "Not Cancelled"));
+    }
+  else if (strncmp(UserCommand, "check-consistency", 17) == 0 &&
+	   DAC960_ParseLogicalDrive(Controller, &UserCommand[17],
+				    &LogicalDriveNumber))
+    {
+      CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
+	LogicalDriveNumber;
+      CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
+	DAC960_V2_ConsistencyCheckStart;
+      CommandMailbox->ConsistencyCheck.RestoreConsistency = true;
+      CommandMailbox->ConsistencyCheck.InitializedAreaOnly = false;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Consistency Check of Logical Drive %d "
+			  "(/dev/rd/c%dd%d) %s\n",
+			  Controller, LogicalDriveNumber,
+			  Controller->ControllerNumber,
+			  LogicalDriveNumber,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Initiated" : "Not Initiated"));
+    }
+  else if (strncmp(UserCommand, "cancel-consistency-check", 24) == 0 &&
+	   DAC960_ParseLogicalDrive(Controller, &UserCommand[24],
+				    &LogicalDriveNumber))
+    {
+      CommandMailbox->ConsistencyCheck.LogicalDevice.LogicalDeviceNumber =
+	LogicalDriveNumber;
+      CommandMailbox->ConsistencyCheck.IOCTL_Opcode =
+	DAC960_V2_ConsistencyCheckStop;
+      DAC960_ExecuteCommand(Command);
+      DAC960_UserCritical("Consistency Check of Logical Drive %d "
+			  "(/dev/rd/c%dd%d) %s\n",
+			  Controller, LogicalDriveNumber,
+			  Controller->ControllerNumber,
+			  LogicalDriveNumber,
+			  (Command->V2.CommandStatus
+			   == DAC960_V2_NormalCompletion
+			   ? "Cancelled" : "Not Cancelled"));
+    }
+  else DAC960_UserCritical("Illegal User Command: '%s'\n",
+			   Controller, UserCommand);
+  DAC960_AcquireControllerLock(Controller, &ProcessorFlags);
+  DAC960_DeallocateCommand(Command);
+  DAC960_ReleaseControllerLock(Controller, &ProcessorFlags);
+  return true;
+}
+
+
+/*
   DAC960_ProcReadStatus implements reading /proc/rd/status.
 */
 
 static int DAC960_ProcReadStatus(char *Page, char **Start, off_t Offset,
 				 int Count, int *EOF, void *Data)
 {
-  char *StatusMessage = "OK\n";
+  unsigned char *StatusMessage = "OK\n";
   int ControllerNumber, BytesAvailable;
   for (ControllerNumber = 0;
        ControllerNumber < DAC960_ControllerCount;
        ControllerNumber++)
     {
       DAC960_Controller_T *Controller = DAC960_Controllers[ControllerNumber];
-      DAC960_Enquiry_T *Enquiry;
       if (Controller == NULL) continue;
-      Enquiry = &Controller->Enquiry[Controller->EnquiryIndex];
-      if (Enquiry->CriticalLogicalDriveCount > 0 ||
-	  Enquiry->OfflineLogicalDriveCount > 0 ||
-	  Enquiry->DeadDriveCount > 0)
+      if (Controller->MonitoringAlertMode)
 	{
 	  StatusMessage = "ALERT\n";
 	  break;
@@ -3500,7 +6388,7 @@
     }
   if (Count <= 0) return 0;
   *Start = Page;
-  memcpy(Page, &Controller->InitialStatusBuffer[Offset], Count);
+  memcpy(Page, &Controller->CombinedStatusBuffer[Offset], Count);
   return Count;
 }
 
@@ -3513,6 +6401,9 @@
 					int Count, int *EOF, void *Data)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
+  unsigned char *StatusMessage =
+    "No Rebuild or Consistency Check in Progress\n";
+  int ProgressMessageLength = strlen(StatusMessage);
   int BytesAvailable;
   if (jiffies != Controller->LastCurrentStatusTime)
     {
@@ -3520,22 +6411,20 @@
       DAC960_AnnounceDriver(Controller);
       DAC960_ReportControllerConfiguration(Controller);
       DAC960_ReportDeviceConfiguration(Controller);
-      Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
-      Controller->CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
-      if (Controller->RebuildProgressLength > 0)
-	{
-	  strcpy(&Controller->CurrentStatusBuffer
-			      [Controller->CurrentStatusLength],
-		 Controller->RebuildProgressBuffer);
-	  Controller->CurrentStatusLength += Controller->RebuildProgressLength;
-	}
-      else
-	{
-	  char *StatusMessage = "No Rebuild or Consistency Check in Progress\n";
-	  strcpy(&Controller->CurrentStatusBuffer
-			      [Controller->CurrentStatusLength],
-		 StatusMessage);
-	  Controller->CurrentStatusLength += strlen(StatusMessage);
+      if (Controller->ProgressBufferLength > 0)
+	ProgressMessageLength = Controller->ProgressBufferLength;
+      if (DAC960_CheckStatusBuffer(Controller, 2 + ProgressMessageLength))
+	{
+	  unsigned char *CurrentStatusBuffer = Controller->CurrentStatusBuffer;
+	  CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
+	  CurrentStatusBuffer[Controller->CurrentStatusLength++] = ' ';
+	  if (Controller->ProgressBufferLength > 0)
+	    strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
+		   Controller->ProgressBuffer);
+	  else
+	    strcpy(&CurrentStatusBuffer[Controller->CurrentStatusLength],
+		   StatusMessage);
+	  Controller->CurrentStatusLength += ProgressMessageLength;
 	}
       Controller->LastCurrentStatusTime = jiffies;
     }
@@ -3581,7 +6470,7 @@
 				       unsigned long Count, void *Data)
 {
   DAC960_Controller_T *Controller = (DAC960_Controller_T *) Data;
-  char CommandBuffer[80];
+  unsigned char CommandBuffer[80];
   int Length;
   if (Count > sizeof(CommandBuffer)-1) return -EINVAL;
   copy_from_user(CommandBuffer, Buffer, Count);
@@ -3589,8 +6478,12 @@
   Length = strlen(CommandBuffer);
   if (CommandBuffer[Length-1] == '\n')
     CommandBuffer[--Length] = '\0';
-  return (DAC960_ExecuteUserCommand(Controller, CommandBuffer)
-	  ? Count : -EBUSY);
+  if (Controller->FirmwareType == DAC960_V1_Controller)
+    return (DAC960_V1_ExecuteUserCommand(Controller, CommandBuffer)
+	    ? Count : -EBUSY);
+  else
+    return (DAC960_V2_ExecuteUserCommand(Controller, CommandBuffer)
+	    ? Count : -EBUSY);
 }
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/DAC960.h linux.17p18/drivers/block/DAC960.h
--- linux.vanilla/drivers/block/DAC960.h	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/DAC960.h	Tue Aug  1 19:11:11 2000
@@ -1,8 +1,8 @@
 /*
 
-  Linux Driver for Mylex DAC960 and DAC1100 PCI RAID Controllers
+  Linux Driver for Mylex DAC960/AcceleRAID/eXtremeRAID PCI RAID Controllers
 
-  Copyright 1998-1999 by Leonard N. Zubkoff <lnz@dandelion.com>
+  Copyright 1998-2000 by Leonard N. Zubkoff <lnz@dandelion.com>
 
   This program is free software; you may redistribute and/or modify it under
   the terms of the GNU General Public License Version 2 as published by the
@@ -27,27 +27,41 @@
 
 
 /*
-  Define the maximum number of Controller Channels supported by this driver.
+  Define the maximum number of Controller Channels supported by DAC960
+  V1 and V2 Firmware Controllers.
 */
 
-#define DAC960_MaxChannels			3
+#define DAC960_V1_MaxChannels			3
+#define DAC960_V2_MaxChannels			4
 
 
 /*
-  Define the maximum number of Targets per Channel supported by this driver.
+  Define the maximum number of Targets per Channel supported by DAC960
+  V1 and V2 Firmware Controllers.
 */
 
-#define DAC960_MaxTargets			16
+#define DAC960_V1_MaxTargets			16
+#define DAC960_V2_MaxTargets			128
 
 
 /*
-  Define the maximum number of Logical Drives supported by any DAC960 model.
+  Define the maximum number of Logical Drives supported by DAC960
+  V1 and V2 Firmware Controllers.
 */
 
 #define DAC960_MaxLogicalDrives			32
 
 
 /*
+  Define the maximum number of Physical Devices supported by DAC960
+  V1 and V2 Firmware Controllers.
+*/
+
+#define DAC960_V1_MaxPhysicalDevices		45
+#define DAC960_V2_MaxPhysicalDevices		272
+
+
+/*
   Define a Boolean data type.
 */
 
@@ -72,149 +86,264 @@
   Define a 32 bit Bus Address data type.
 */
 
-typedef unsigned int DAC960_BusAddress_T;
+typedef unsigned int DAC960_BusAddress32_T;
+
+
+/*
+  Define a 64 bit Bus Address data type.
+*/
+
+typedef unsigned long long DAC960_BusAddress64_T;
 
 
 /*
   Define a 32 bit Byte Count data type.
 */
 
-typedef unsigned int DAC960_ByteCount_T;
+typedef unsigned int DAC960_ByteCount32_T;
+
+
+/*
+  Define a 64 bit Byte Count data type.
+*/
+
+typedef unsigned long long DAC960_ByteCount64_T;
+
+
+/*
+  Define the SCSI INQUIRY Standard Data structure.
+*/
+
+typedef struct DAC960_SCSI_Inquiry
+{
+  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
+  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
+  unsigned char DeviceTypeModifier:7;			/* Byte 1 Bits 0-6 */
+  boolean RMB:1;					/* Byte 1 Bit 7 */
+  unsigned char ANSI_ApprovedVersion:3;			/* Byte 2 Bits 0-2 */
+  unsigned char ECMA_Version:3;				/* Byte 2 Bits 3-5 */
+  unsigned char ISO_Version:2;				/* Byte 2 Bits 6-7 */
+  unsigned char ResponseDataFormat:4;			/* Byte 3 Bits 0-3 */
+  unsigned char :2;					/* Byte 3 Bits 4-5 */
+  boolean TrmIOP:1;					/* Byte 3 Bit 6 */
+  boolean AENC:1;					/* Byte 3 Bit 7 */
+  unsigned char AdditionalLength;			/* Byte 4 */
+  unsigned char :8;					/* Byte 5 */
+  unsigned char :8;					/* Byte 6 */
+  boolean SftRe:1;					/* Byte 7 Bit 0 */
+  boolean CmdQue:1;					/* Byte 7 Bit 1 */
+  boolean :1;						/* Byte 7 Bit 2 */
+  boolean Linked:1;					/* Byte 7 Bit 3 */
+  boolean Sync:1;					/* Byte 7 Bit 4 */
+  boolean WBus16:1;					/* Byte 7 Bit 5 */
+  boolean WBus32:1;					/* Byte 7 Bit 6 */
+  boolean RelAdr:1;					/* Byte 7 Bit 7 */
+  unsigned char VendorIdentification[8];		/* Bytes 8-15 */
+  unsigned char ProductIdentification[16];		/* Bytes 16-31 */
+  unsigned char ProductRevisionLevel[4];		/* Bytes 32-35 */
+}
+DAC960_SCSI_Inquiry_T;
+
+
+/*
+  Define the SCSI INQUIRY Unit Serial Number structure.
+*/
+
+typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber
+{
+  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
+  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
+  unsigned char PageCode;				/* Byte 1 */
+  unsigned char :8;					/* Byte 2 */
+  unsigned char PageLength;				/* Byte 3 */
+  unsigned char ProductSerialNumber[28];		/* Bytes 4-31 */
+}
+DAC960_SCSI_Inquiry_UnitSerialNumber_T;
+
+
+/*
+  Define the SCSI REQUEST SENSE Sense Key type.
+*/
+
+typedef enum
+{
+  DAC960_SenseKey_NoSense =			0x0,
+  DAC960_SenseKey_RecoveredError =		0x1,
+  DAC960_SenseKey_NotReady =			0x2,
+  DAC960_SenseKey_MediumError =			0x3,
+  DAC960_SenseKey_HardwareError =		0x4,
+  DAC960_SenseKey_IllegalRequest =		0x5,
+  DAC960_SenseKey_UnitAttention =		0x6,
+  DAC960_SenseKey_DataProtect =			0x7,
+  DAC960_SenseKey_BlankCheck =			0x8,
+  DAC960_SenseKey_VendorSpecific =		0x9,
+  DAC960_SenseKey_CopyAborted =			0xA,
+  DAC960_SenseKey_AbortedCommand =		0xB,
+  DAC960_SenseKey_Equal =			0xC,
+  DAC960_SenseKey_VolumeOverflow =		0xD,
+  DAC960_SenseKey_Miscompare =			0xE,
+  DAC960_SenseKey_Reserved =			0xF
+}
+__attribute__ ((packed))
+DAC960_SCSI_RequestSenseKey_T;
+
+
+/*
+  Define the SCSI REQUEST SENSE structure.
+*/
+
+typedef struct DAC960_SCSI_RequestSense
+{
+  unsigned char ErrorCode:7;				/* Byte 0 Bits 0-6 */
+  boolean Valid:1;					/* Byte 0 Bit 7 */
+  unsigned char SegmentNumber;				/* Byte 1 */
+  DAC960_SCSI_RequestSenseKey_T SenseKey:4;		/* Byte 2 Bits 0-3 */
+  unsigned char :1;					/* Byte 2 Bit 4 */
+  boolean ILI:1;					/* Byte 2 Bit 5 */
+  boolean EOM:1;					/* Byte 2 Bit 6 */
+  boolean Filemark:1;					/* Byte 2 Bit 7 */
+  unsigned char Information[4];				/* Bytes 3-6 */
+  unsigned char AdditionalSenseLength;			/* Byte 7 */
+  unsigned char CommandSpecificInformation[4];		/* Bytes 8-11 */
+  unsigned char AdditionalSenseCode;			/* Byte 12 */
+  unsigned char AdditionalSenseCodeQualifier;		/* Byte 13 */
+}
+DAC960_SCSI_RequestSense_T;
 
 
 /*
-  Define the DAC960 Command Opcodes.
+  Define the DAC960 V1 Firmware Command Opcodes.
 */
 
 typedef enum
 {
   /* I/O Commands */
-  DAC960_ReadExtended =				0x33,
-  DAC960_WriteExtended =			0x34,
-  DAC960_ReadAheadExtended =			0x35,
-  DAC960_ReadExtendedWithScatterGather =	0xB3,
-  DAC960_WriteExtendedWithScatterGather =	0xB4,
-  DAC960_Read =					0x36,
-  DAC960_ReadWithOldScatterGather =		0xB6,
-  DAC960_Write =				0x37,
-  DAC960_WriteWithOldScatterGather =		0xB7,
-  DAC960_DCDB =					0x04,
-  DAC960_DCDBWithScatterGather =		0x84,
-  DAC960_Flush =				0x0A,
+  DAC960_V1_ReadExtended =			0x33,
+  DAC960_V1_WriteExtended =			0x34,
+  DAC960_V1_ReadAheadExtended =			0x35,
+  DAC960_V1_ReadExtendedWithScatterGather =	0xB3,
+  DAC960_V1_WriteExtendedWithScatterGather =	0xB4,
+  DAC960_V1_Read =				0x36,
+  DAC960_V1_ReadWithOldScatterGather =		0xB6,
+  DAC960_V1_Write =				0x37,
+  DAC960_V1_WriteWithOldScatterGather =		0xB7,
+  DAC960_V1_DCDB =				0x04,
+  DAC960_V1_DCDBWithScatterGather =		0x84,
+  DAC960_V1_Flush =				0x0A,
   /* Controller Status Related Commands */
-  DAC960_Enquiry =				0x53,
-  DAC960_Enquiry2 =				0x1C,
-  DAC960_GetLogicalDriveElement =		0x55,
-  DAC960_GetLogicalDriveInformation =		0x19,
-  DAC960_IOPortRead =				0x39,
-  DAC960_IOPortWrite =				0x3A,
-  DAC960_GetSDStats =				0x3E,
-  DAC960_GetPDStats =				0x3F,
-  DAC960_PerformEventLogOperation =		0x72,
+  DAC960_V1_Enquiry =				0x53,
+  DAC960_V1_Enquiry2 =				0x1C,
+  DAC960_V1_GetLogicalDriveElement =		0x55,
+  DAC960_V1_GetLogicalDriveInformation =	0x19,
+  DAC960_V1_IOPortRead =			0x39,
+  DAC960_V1_IOPortWrite =			0x3A,
+  DAC960_V1_GetSDStats =			0x3E,
+  DAC960_V1_GetPDStats =			0x3F,
+  DAC960_V1_PerformEventLogOperation =		0x72,
   /* Device Related Commands */
-  DAC960_StartDevice =				0x10,
-  DAC960_GetDeviceState =			0x50,
-  DAC960_StopChannel =				0x13,
-  DAC960_StartChannel =				0x12,
-  DAC960_ResetChannel =				0x1A,
+  DAC960_V1_StartDevice =			0x10,
+  DAC960_V1_GetDeviceState =			0x50,
+  DAC960_V1_StopChannel =			0x13,
+  DAC960_V1_StartChannel =			0x12,
+  DAC960_V1_ResetChannel =			0x1A,
   /* Commands Associated with Data Consistency and Errors */
-  DAC960_Rebuild =				0x09,
-  DAC960_RebuildAsync =				0x16,
-  DAC960_CheckConsistency =			0x0F,
-  DAC960_CheckConsistencyAsync =		0x1E,
-  DAC960_RebuildStat =				0x0C,
-  DAC960_GetRebuildProgress =			0x27,
-  DAC960_RebuildControl =			0x1F,
-  DAC960_ReadBadBlockTable =			0x0B,
-  DAC960_ReadBadDataTable =			0x25,
-  DAC960_ClearBadDataTable =			0x26,
-  DAC960_GetErrorTable =			0x17,
-  DAC960_AddCapacityAsync =			0x2A,
+  DAC960_V1_Rebuild =				0x09,
+  DAC960_V1_RebuildAsync =			0x16,
+  DAC960_V1_CheckConsistency =			0x0F,
+  DAC960_V1_CheckConsistencyAsync =		0x1E,
+  DAC960_V1_RebuildStat =			0x0C,
+  DAC960_V1_GetRebuildProgress =		0x27,
+  DAC960_V1_RebuildControl =			0x1F,
+  DAC960_V1_ReadBadBlockTable =			0x0B,
+  DAC960_V1_ReadBadDataTable =			0x25,
+  DAC960_V1_ClearBadDataTable =			0x26,
+  DAC960_V1_GetErrorTable =			0x17,
+  DAC960_V1_AddCapacityAsync =			0x2A,
   /* Configuration Related Commands */
-  DAC960_ReadConfig2 =				0x3D,
-  DAC960_WriteConfig2 =				0x3C,
-  DAC960_ReadConfigurationOnDisk =		0x4A,
-  DAC960_WriteConfigurationOnDisk =		0x4B,
-  DAC960_ReadConfiguration =			0x4E,
-  DAC960_ReadBackupConfiguration =		0x4D,
-  DAC960_WriteConfiguration =			0x4F,
-  DAC960_AddConfiguration =			0x4C,
-  DAC960_ReadConfigurationLabel =		0x48,
-  DAC960_WriteConfigurationLabel =		0x49,
+  DAC960_V1_ReadConfig2 =			0x3D,
+  DAC960_V1_WriteConfig2 =			0x3C,
+  DAC960_V1_ReadConfigurationOnDisk =		0x4A,
+  DAC960_V1_WriteConfigurationOnDisk =		0x4B,
+  DAC960_V1_ReadConfiguration =			0x4E,
+  DAC960_V1_ReadBackupConfiguration =		0x4D,
+  DAC960_V1_WriteConfiguration =		0x4F,
+  DAC960_V1_AddConfiguration =			0x4C,
+  DAC960_V1_ReadConfigurationLabel =		0x48,
+  DAC960_V1_WriteConfigurationLabel =		0x49,
   /* Firmware Upgrade Related Commands */
-  DAC960_LoadImage =				0x20,
-  DAC960_StoreImage =				0x21,
-  DAC960_ProgramImage =				0x22,
+  DAC960_V1_LoadImage =				0x20,
+  DAC960_V1_StoreImage =			0x21,
+  DAC960_V1_ProgramImage =			0x22,
   /* Diagnostic Commands */
-  DAC960_SetDiagnosticMode =			0x31,
-  DAC960_RunDiagnostic =			0x32,
+  DAC960_V1_SetDiagnosticMode =			0x31,
+  DAC960_V1_RunDiagnostic =			0x32,
   /* Subsystem Service Commands */
-  DAC960_GetSubsystemData =			0x70,
-  DAC960_SetSubsystemParameters =		0x71
+  DAC960_V1_GetSubsystemData =			0x70,
+  DAC960_V1_SetSubsystemParameters =		0x71
 }
 __attribute__ ((packed))
-DAC960_CommandOpcode_T;
+DAC960_V1_CommandOpcode_T;
 
 
 /*
-  Define the DAC960 Command Identifier type.
+  Define the DAC960 V1 Firmware Command Identifier type.
 */
 
-typedef unsigned char DAC960_CommandIdentifier_T;
+typedef unsigned char DAC960_V1_CommandIdentifier_T;
 
 
 /*
-  Define the DAC960 Command Status Codes.
+  Define the DAC960 V1 Firmware Command Status Codes.
 */
 
-#define DAC960_NormalCompletion			0x0000	/* Common */
-#define DAC960_CheckConditionReceived		0x0002	/* Common */
-#define DAC960_NoDeviceAtAddress		0x0102	/* Common */
-#define DAC960_InvalidDeviceAddress		0x0105	/* Common */
-#define DAC960_InvalidParameter			0x0105	/* Common */
-#define DAC960_IrrecoverableDataError		0x0001	/* I/O */
-#define DAC960_LogicalDriveNonexistentOrOffline	0x0002	/* I/O */
-#define DAC960_AccessBeyondEndOfLogicalDrive	0x0105	/* I/O */
-#define DAC960_BadDataEncountered		0x010C	/* I/O */
-#define DAC960_DeviceBusy			0x0008	/* DCDB */
-#define DAC960_DeviceNonresponsive		0x000E	/* DCDB */
-#define DAC960_CommandTerminatedAbnormally	0x000F	/* DCDB */
-#define DAC960_UnableToStartDevice		0x0002	/* Device */
-#define DAC960_InvalidChannelOrTargetOrModifier	0x0105	/* Device */
-#define DAC960_ChannelBusy			0x0106	/* Device */
-#define DAC960_ChannelNotStopped		0x0002	/* Device */
-#define DAC960_AttemptToRebuildOnlineDrive	0x0002	/* Consistency */
-#define DAC960_RebuildBadBlocksEncountered	0x0003	/* Consistency */
-#define DAC960_NewDiskFailedDuringRebuild	0x0004	/* Consistency */
-#define DAC960_RebuildOrCheckAlreadyInProgress	0x0106	/* Consistency */
-#define DAC960_DependentDiskIsDead		0x0002	/* Consistency */
-#define DAC960_InconsistentBlocksFound		0x0003	/* Consistency */
-#define DAC960_InvalidOrNonredundantLogicalDrive 0x0105	/* Consistency */
-#define DAC960_NoRebuildOrCheckInProgress	0x0105	/* Consistency */
-#define DAC960_RebuildInProgress_DataValid	0x0000	/* Consistency */
-#define DAC960_RebuildFailed_LogicalDriveFailure 0x0002	/* Consistency */
-#define DAC960_RebuildFailed_BadBlocksOnOther	0x0003	/* Consistency */
-#define DAC960_RebuildFailed_NewDriveFailed	0x0004	/* Consistency */
-#define DAC960_RebuildSuccessful		0x0100	/* Consistency */
-#define DAC960_RebuildSuccessfullyTerminated	0x0107	/* Consistency */
-#define DAC960_AddCapacityInProgress		0x0004	/* Consistency */
-#define DAC960_AddCapacityFailedOrSuspended	0x00F4	/* Consistency */
-#define DAC960_Config2ChecksumError		0x0002	/* Configuration */
-#define DAC960_ConfigurationSuspended		0x0106	/* Configuration */
-#define DAC960_FailedToConfigureNVRAM		0x0105	/* Configuration */
-#define DAC960_ConfigurationNotSavedStateChange	0x0106	/* Configuration */
-#define DAC960_SubsystemNotInstalled		0x0001	/* Subsystem */
-#define DAC960_SubsystemFailed			0x0002	/* Subsystem */
-#define DAC960_SubsystemBusy			0x0106	/* Subsystem */
+#define DAC960_V1_NormalCompletion		0x0000	/* Common */
+#define DAC960_V1_CheckConditionReceived	0x0002	/* Common */
+#define DAC960_V1_NoDeviceAtAddress		0x0102	/* Common */
+#define DAC960_V1_InvalidDeviceAddress		0x0105	/* Common */
+#define DAC960_V1_InvalidParameter		0x0105	/* Common */
+#define DAC960_V1_IrrecoverableDataError	0x0001	/* I/O */
+#define DAC960_V1_LogicalDriveNonexistentOrOffline 0x0002 /* I/O */
+#define DAC960_V1_AccessBeyondEndOfLogicalDrive	0x0105	/* I/O */
+#define DAC960_V1_BadDataEncountered		0x010C	/* I/O */
+#define DAC960_V1_DeviceBusy			0x0008	/* DCDB */
+#define DAC960_V1_DeviceNonresponsive		0x000E	/* DCDB */
+#define DAC960_V1_CommandTerminatedAbnormally	0x000F	/* DCDB */
+#define DAC960_V1_UnableToStartDevice		0x0002	/* Device */
+#define DAC960_V1_InvalidChannelOrTargetOrModifier 0x0105 /* Device */
+#define DAC960_V1_ChannelBusy			0x0106	/* Device */
+#define DAC960_V1_ChannelNotStopped		0x0002	/* Device */
+#define DAC960_V1_AttemptToRebuildOnlineDrive	0x0002	/* Consistency */
+#define DAC960_V1_RebuildBadBlocksEncountered	0x0003	/* Consistency */
+#define DAC960_V1_NewDiskFailedDuringRebuild	0x0004	/* Consistency */
+#define DAC960_V1_RebuildOrCheckAlreadyInProgress 0x0106 /* Consistency */
+#define DAC960_V1_DependentDiskIsDead		0x0002	/* Consistency */
+#define DAC960_V1_InconsistentBlocksFound	0x0003	/* Consistency */
+#define DAC960_V1_InvalidOrNonredundantLogicalDrive 0x0105 /* Consistency */
+#define DAC960_V1_NoRebuildOrCheckInProgress	0x0105	/* Consistency */
+#define DAC960_V1_RebuildInProgress_DataValid	0x0000	/* Consistency */
+#define DAC960_V1_RebuildFailed_LogicalDriveFailure 0x0002 /* Consistency */
+#define DAC960_V1_RebuildFailed_BadBlocksOnOther 0x0003	/* Consistency */
+#define DAC960_V1_RebuildFailed_NewDriveFailed	0x0004	/* Consistency */
+#define DAC960_V1_RebuildSuccessful		0x0100	/* Consistency */
+#define DAC960_V1_RebuildSuccessfullyTerminated	0x0107	/* Consistency */
+#define DAC960_V1_AddCapacityInProgress		0x0004	/* Consistency */
+#define DAC960_V1_AddCapacityFailedOrSuspended	0x00F4	/* Consistency */
+#define DAC960_V1_Config2ChecksumError		0x0002	/* Configuration */
+#define DAC960_V1_ConfigurationSuspended	0x0106	/* Configuration */
+#define DAC960_V1_FailedToConfigureNVRAM	0x0105	/* Configuration */
+#define DAC960_V1_ConfigurationNotSavedStateChange 0x0106 /* Configuration */
+#define DAC960_V1_SubsystemNotInstalled		0x0001	/* Subsystem */
+#define DAC960_V1_SubsystemFailed		0x0002	/* Subsystem */
+#define DAC960_V1_SubsystemBusy			0x0106	/* Subsystem */
 
-typedef unsigned short DAC960_CommandStatus_T;
+typedef unsigned short DAC960_V1_CommandStatus_T;
 
 
 /*
-  Define the Enquiry reply structure.
+  Define the DAC960 V1 Firmware Enquiry Command reply structure.
 */
 
-typedef struct DAC960_Enquiry
+typedef struct DAC960_V1_Enquiry
 {
   unsigned char NumberOfLogicalDrives;			/* Byte 0 */
   unsigned int :24;					/* Bytes 1-3 */
@@ -229,15 +358,15 @@
   unsigned char MinorFirmwareVersion;			/* Byte 136 */
   unsigned char MajorFirmwareVersion;			/* Byte 137 */
   enum {
-    DAC960_NoStandbyRebuildOrCheckInProgress =			0x00,
-    DAC960_StandbyRebuildInProgress =				0x01,
-    DAC960_BackgroundRebuildInProgress =			0x02,
-    DAC960_BackgroundCheckInProgress =				0x03,
-    DAC960_StandbyRebuildCompletedWithError =			0xFF,
-    DAC960_BackgroundRebuildOrCheckFailed_DriveFailed =		0xF0,
-    DAC960_BackgroundRebuildOrCheckFailed_LogicalDriveFailed =	0xF1,
-    DAC960_BackgroundRebuildOrCheckFailed_OtherCauses =		0xF2,
-    DAC960_BackgroundRebuildOrCheckSuccessfullyTerminated =	0xF3
+    DAC960_V1_NoStandbyRebuildOrCheckInProgress =		    0x00,
+    DAC960_V1_StandbyRebuildInProgress =			    0x01,
+    DAC960_V1_BackgroundRebuildInProgress =			    0x02,
+    DAC960_V1_BackgroundCheckInProgress =			    0x03,
+    DAC960_V1_StandbyRebuildCompletedWithError =		    0xFF,
+    DAC960_V1_BackgroundRebuildOrCheckFailed_DriveFailed =	    0xF0,
+    DAC960_V1_BackgroundRebuildOrCheckFailed_LogicalDriveFailed =   0xF1,
+    DAC960_V1_BackgroundRebuildOrCheckFailed_OtherCauses =	    0xF2,
+    DAC960_V1_BackgroundRebuildOrCheckSuccessfullyTerminated =	    0xF3
   } __attribute__ ((packed)) RebuildFlag;		/* Byte 138 */
   unsigned char MaxCommands;				/* Byte 139 */
   unsigned char OfflineLogicalDriveCount;		/* Byte 140 */
@@ -261,40 +390,40 @@
   unsigned char Reserved[62];				/* Bytes 195-255 */
 }
 __attribute__ ((packed))
-DAC960_Enquiry_T;
+DAC960_V1_Enquiry_T;
 
 
 /*
-  Define the Enquiry2 reply structure.
+  Define the DAC960 V1 Firmware Enquiry2 Command reply structure.
 */
 
-typedef struct DAC960_Enquiry2
+typedef struct DAC960_V1_Enquiry2
 {
   struct {
     enum {
-      DAC960_P_PD_PU =				0x01,
-      DAC960_PL =				0x02,
-      DAC960_PG =				0x10,
-      DAC960_PJ =				0x11,
-      DAC960_PR =				0x12,
-      DAC960_PT =				0x13,
-      DAC960_PTL0 =				0x14,
-      DAC960_PRL =				0x15,
-      DAC960_PTL1 =				0x16,
-      DAC1164_P =				0x20
+      DAC960_V1_P_PD_PU =			0x01,
+      DAC960_V1_PL =				0x02,
+      DAC960_V1_PG =				0x10,
+      DAC960_V1_PJ =				0x11,
+      DAC960_V1_PR =				0x12,
+      DAC960_V1_PT =				0x13,
+      DAC960_V1_PTL0 =				0x14,
+      DAC960_V1_PRL =				0x15,
+      DAC960_V1_PTL1 =				0x16,
+      DAC960_V1_1164P =				0x20
     } __attribute__ ((packed)) SubModel;		/* Byte 0 */
     unsigned char ActualChannels;			/* Byte 1 */
     enum {
-      DAC960_FiveChannelBoard =			0x01,
-      DAC960_ThreeChannelBoard =		0x02,
-      DAC960_TwoChannelBoard =			0x03,
-      DAC960_ThreeChannelASIC_DAC =		0x04
+      DAC960_V1_FiveChannelBoard =		0x01,
+      DAC960_V1_ThreeChannelBoard =		0x02,
+      DAC960_V1_TwoChannelBoard =		0x03,
+      DAC960_V1_ThreeChannelASIC_DAC =		0x04
     } __attribute__ ((packed)) Model;			/* Byte 2 */
     enum {
-      DAC960_EISA_Controller =			0x01,
-      DAC960_MicroChannel_Controller =		0x02,
-      DAC960_PCI_Controller =			0x03,
-      DAC960_SCSItoSCSI_Controller =		0x08
+      DAC960_V1_EISA_Controller =		0x01,
+      DAC960_V1_MicroChannel_Controller =	0x02,
+      DAC960_V1_PCI_Controller =		0x03,
+      DAC960_V1_SCSItoSCSI_Controller =		0x08
     } __attribute__ ((packed)) ProductFamily;		/* Byte 3 */
   } HardwareID;						/* Bytes 0-3 */
   /* MajorVersion.MinorVersion-FirmwareType-TurnID */
@@ -321,14 +450,14 @@
   unsigned int NonVolatileMemorySize;			/* Bytes 36-39 */
   struct {
     enum {
-      DAC960_DRAM =				0x00,
-      DAC960_EDO =				0x01,
-      DAC960_SDRAM =				0x02
+      DAC960_V1_DRAM =				0x0,
+      DAC960_V1_EDO =				0x1,
+      DAC960_V1_SDRAM =				0x2
     } __attribute__ ((packed)) RamType:3;		/* Byte 40 Bits 0-2 */
     enum {
-      DAC960_None =				0x00,
-      DAC960_Parity =				0x01,
-      DAC960_ECC =				0x02
+      DAC960_V1_None =				0x0,
+      DAC960_V1_Parity =			0x1,
+      DAC960_V1_ECC =				0x2
     } __attribute__ ((packed)) ErrorCorrection:3;	/* Byte 40 Bits 3-5 */
     boolean FastPageMode:1;				/* Byte 40 Bit 6 */
     boolean LowPowerMemory:1;				/* Byte 40 Bit 7 */
@@ -367,14 +496,14 @@
   unsigned short CacheLineSize;				/* Bytes 104-105 */
   struct {
     enum {
-      DAC960_Narrow_8bit =			0x00,
-      DAC960_Wide_16bit =			0x01,
-      DAC960_Wide_32bit =			0x02
+      DAC960_V1_Narrow_8bit =			0x0,
+      DAC960_V1_Wide_16bit =			0x1,
+      DAC960_V1_Wide_32bit =			0x2
     } __attribute__ ((packed)) BusWidth:2;		/* Byte 106 Bits 0-1 */
     enum {
-      DAC960_Fast =				0x00,
-      DAC960_Ultra =				0x01,
-      DAC960_Ultra2 =				0x02
+      DAC960_V1_Fast =				0x0,
+      DAC960_V1_Ultra =				0x1,
+      DAC960_V1_Ultra2 =			0x2
     } __attribute__ ((packed)) BusSpeed:2;		/* Byte 106 Bits 2-3 */
     boolean Differential:1;				/* Byte 106 Bit 4 */
     unsigned char :3;					/* Byte 106 Bits 5-7 */
@@ -383,12 +512,12 @@
   unsigned int :32;					/* Bytes 108-111 */
   unsigned short FirmwareBuildNumber;			/* Bytes 112-113 */
   enum {
-    DAC960_AEMI =				0x01,
-    DAC960_OEM1 =				0x02,
-    DAC960_OEM2 =				0x04,
-    DAC960_OEM3 =				0x08,
-    DAC960_Conner =				0x10,
-    DAC960_SAFTE =				0x20
+    DAC960_V1_AEMI =				0x01,
+    DAC960_V1_OEM1 =				0x02,
+    DAC960_V1_OEM2 =				0x04,
+    DAC960_V1_OEM3 =				0x08,
+    DAC960_V1_Conner =				0x10,
+    DAC960_V1_SAFTE =				0x20
   } __attribute__ ((packed)) FaultManagementType;	/* Byte 114 */
   unsigned char :8;					/* Byte 115 */
   struct {
@@ -399,55 +528,64 @@
   unsigned int :32;					/* Bytes 120-123 */
   unsigned int :32;					/* Bytes 124-127 */
 }
-DAC960_Enquiry2_T;
+DAC960_V1_Enquiry2_T;
 
 
 /*
-  Define the Logical Drive State type.
+  Define the DAC960 V1 Firmware Logical Drive State type.
 */
 
 typedef enum
 {
-    DAC960_LogicalDrive_Online =		0x03,
-    DAC960_LogicalDrive_Critical =		0x04,
-    DAC960_LogicalDrive_Offline =		0xFF
+  DAC960_V1_LogicalDrive_Online =		0x03,
+  DAC960_V1_LogicalDrive_Critical =		0x04,
+  DAC960_V1_LogicalDrive_Offline =		0xFF
 }
 __attribute__ ((packed))
-DAC960_LogicalDriveState_T;
+DAC960_V1_LogicalDriveState_T;
 
 
 /*
-  Define the Get Logical Drive Information reply structure.
+  Define the DAC960 V1 Firmware Logical Drive Information structure.
 */
 
-typedef struct DAC960_LogicalDriveInformation
+typedef struct DAC960_V1_LogicalDriveInformation
 {
   unsigned int LogicalDriveSize;			/* Bytes 0-3 */
-  DAC960_LogicalDriveState_T LogicalDriveState;		/* Byte 4 */
+  DAC960_V1_LogicalDriveState_T LogicalDriveState;	/* Byte 4 */
   unsigned char RAIDLevel:7;				/* Byte 5 Bits 0-6 */
   boolean WriteBack:1;					/* Byte 5 Bit 7 */
-  unsigned int :16;					/* Bytes 6-7 */
+  unsigned short :16;					/* Bytes 6-7 */
 }
-DAC960_LogicalDriveInformation_T;
+DAC960_V1_LogicalDriveInformation_T;
+
+
+/*
+  Define the DAC960 V1 Firmware Get Logical Drive Information Command
+  reply structure.
+*/
+
+typedef DAC960_V1_LogicalDriveInformation_T
+	DAC960_V1_LogicalDriveInformationArray_T[DAC960_MaxLogicalDrives];
 
 
 /*
-  Define the Perform Event Log Operation Types.
+  Define the DAC960 V1 Firmware Perform Event Log Operation Types.
 */
 
 typedef enum
 {
-  DAC960_GetEventLogEntry =			0x00
+  DAC960_V1_GetEventLogEntry =			0x00
 }
 __attribute__ ((packed))
-DAC960_PerformEventLogOpType_T;
+DAC960_V1_PerformEventLogOpType_T;
 
 
 /*
-  Define the Get Event Log Entry reply structure.
+  Define the DAC960 V1 Firmware Get Event Log Entry Command reply structure.
 */
 
-typedef struct DAC960_EventLogEntry
+typedef struct DAC960_V1_EventLogEntry
 {
   unsigned char MessageType;				/* Byte 0 */
   unsigned char MessageLength;				/* Byte 1 */
@@ -459,7 +597,7 @@
   unsigned char ErrorCode:7;				/* Byte 6 Bits 0-6 */
   boolean Valid:1;					/* Byte 6 Bit 7 */
   unsigned char SegmentNumber;				/* Byte 7 */
-  unsigned char SenseKey:4;				/* Byte 8 Bits 0-3 */
+  DAC960_SCSI_RequestSenseKey_T SenseKey:4;		/* Byte 8 Bits 0-3 */
   unsigned char :1;					/* Byte 8 Bit 4 */
   boolean ILI:1;					/* Byte 8 Bit 5 */
   boolean EOM:1;					/* Byte 8 Bit 6 */
@@ -471,37 +609,37 @@
   unsigned char AdditionalSenseCodeQualifier;		/* Byte 19 */
   unsigned char Dummy[12];				/* Bytes 20-31 */
 }
-DAC960_EventLogEntry_T;
+DAC960_V1_EventLogEntry_T;
 
 
 /*
-  Define the Physical Device State type.
+  Define the DAC960 V1 Firmware Physical Device State type.
 */
 
 typedef enum
 {
-    DAC960_Device_Dead =			0x00,
-    DAC960_Device_WriteOnly =			0x02,
-    DAC960_Device_Online =			0x03,
-    DAC960_Device_Standby =			0x10
+    DAC960_V1_Device_Dead =			0x00,
+    DAC960_V1_Device_WriteOnly =		0x02,
+    DAC960_V1_Device_Online =			0x03,
+    DAC960_V1_Device_Standby =			0x10
 }
 __attribute__ ((packed))
-DAC960_PhysicalDeviceState_T;
+DAC960_V1_PhysicalDeviceState_T;
 
 
 /*
-  Define the Get Device State reply structure.
+  Define the DAC960 V1 Firmware Get Device State Command reply structure.
 */
 
-typedef struct DAC960_DeviceState
+typedef struct DAC960_V1_DeviceState
 {
   boolean Present:1;					/* Byte 0 Bit 0 */
   unsigned char :7;					/* Byte 0 Bits 1-7 */
   enum {
-    DAC960_OtherType =				0x00,
-    DAC960_DiskType =				0x01,
-    DAC960_SequentialType =			0x02,
-    DAC960_CDROM_or_WORM_Type =			0x03
+    DAC960_V1_OtherType =			0x0,
+    DAC960_V1_DiskType =			0x1,
+    DAC960_V1_SequentialType =			0x2,
+    DAC960_V1_CDROM_or_WORM_Type =		0x3
     } __attribute__ ((packed)) DeviceType:2;		/* Byte 1 Bits 0-1 */
   boolean :1;						/* Byte 1 Bit 2 */
   boolean Fast20:1;					/* Byte 1 Bit 3 */
@@ -509,60 +647,60 @@
   boolean Fast:1;					/* Byte 1 Bit 5 */
   boolean Wide:1;					/* Byte 1 Bit 6 */
   boolean TaggedQueuingSupported:1;			/* Byte 1 Bit 7 */
-  DAC960_PhysicalDeviceState_T DeviceState;		/* Byte 2 */
+  DAC960_V1_PhysicalDeviceState_T DeviceState;		/* Byte 2 */
   unsigned char :8;					/* Byte 3 */
   unsigned char SynchronousMultiplier;			/* Byte 4 */
   unsigned char SynchronousOffset:5;			/* Byte 5 Bits 0-4 */
   unsigned char :3;					/* Byte 5 Bits 5-7 */
   unsigned int DiskSize __attribute__ ((packed));	/* Bytes 6-9 */
 }
-DAC960_DeviceState_T;
+DAC960_V1_DeviceState_T;
 
 
 /*
-  Define the Get Rebuild Progress reply structure.
+  Define the DAC960 V1 Firmware Get Rebuild Progress Command reply structure.
 */
 
-typedef struct DAC960_RebuildProgress
+typedef struct DAC960_V1_RebuildProgress
 {
   unsigned int LogicalDriveNumber;			/* Bytes 0-3 */
   unsigned int LogicalDriveSize;			/* Bytes 4-7 */
   unsigned int RemainingBlocks;				/* Bytes 8-11 */
 }
-DAC960_RebuildProgress_T;
+DAC960_V1_RebuildProgress_T;
 
 
 /*
-  Define the Error Table Entry and Get Error Table reply structure.
+  Define the DAC960 V1 Firmware Error Table Entry structure.
 */
 
-typedef struct DAC960_ErrorTableEntry
+typedef struct DAC960_V1_ErrorTableEntry
 {
   unsigned char ParityErrorCount;			/* Byte 0 */
   unsigned char SoftErrorCount;				/* Byte 1 */
   unsigned char HardErrorCount;				/* Byte 2 */
   unsigned char MiscErrorCount;				/* Byte 3 */
 }
-DAC960_ErrorTableEntry_T;
+DAC960_V1_ErrorTableEntry_T;
 
 
 /*
-  Define the Get Error Table reply structure.
+  Define the DAC960 V1 Firmware Get Error Table Command reply structure.
 */
 
-typedef struct DAC960_ErrorTable
+typedef struct DAC960_V1_ErrorTable
 {
-  DAC960_ErrorTableEntry_T
-    ErrorTableEntries[DAC960_MaxChannels][DAC960_MaxTargets];
+  DAC960_V1_ErrorTableEntry_T
+    ErrorTableEntries[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
 }
-DAC960_ErrorTable_T;
+DAC960_V1_ErrorTable_T;
 
 
 /*
-  Define the Config2 reply structure.
+  Define the DAC960 V1 Firmware Read Config2 Command reply structure.
 */
 
-typedef struct DAC960_Config2
+typedef struct DAC960_V1_Config2
 {
   unsigned char :1;					/* Byte 0 Bit 0 */
   boolean ActiveNegationEnabled:1;			/* Byte 0 Bit 1 */
@@ -576,12 +714,12 @@
   boolean AEMI_OFM:1;					/* Byte 1 Bit 6 */
   unsigned char :1;					/* Byte 1 Bit 7 */
   enum {
-    DAC960_OEMID_Mylex =			0x00,
-    DAC960_OEMID_IBM =				0x08,
-    DAC960_OEMID_HP =				0x0A,
-    DAC960_OEMID_DEC =				0x0C,
-    DAC960_OEMID_Siemens =			0x10,
-    DAC960_OEMID_Intel =			0x12
+    DAC960_V1_OEMID_Mylex =			0x00,
+    DAC960_V1_OEMID_IBM =			0x08,
+    DAC960_V1_OEMID_HP =			0x0A,
+    DAC960_V1_OEMID_DEC =			0x0C,
+    DAC960_V1_OEMID_Siemens =			0x10,
+    DAC960_V1_OEMID_Intel =			0x12
   } __attribute__ ((packed)) OEMID;			/* Byte 2 */
   unsigned char OEMModelNumber;				/* Byte 3 */
   unsigned char PhysicalSector;				/* Byte 4 */
@@ -600,21 +738,21 @@
   unsigned char BlocksPerStripe;			/* Byte 11 */
   struct {
     enum {
-      DAC960_Async =				0x00,
-      DAC960_Sync_8MHz =			0x01,
-      DAC960_Sync_5MHz =			0x02,
-      DAC960_Sync_10or20MHz =			0x03	/* Bits 0-1 */
+      DAC960_V1_Async =				0x0,
+      DAC960_V1_Sync_8MHz =			0x1,
+      DAC960_V1_Sync_5MHz =			0x2,
+      DAC960_V1_Sync_10or20MHz =		0x3	/* Byte 11 Bits 0-1 */
     } __attribute__ ((packed)) Speed:2;
-    boolean Force8Bit:1;				/* Bit 2 */
-    boolean DisableFast20:1;				/* Bit 3 */
-    unsigned char :3;					/* Bits 4-6 */
-    boolean EnableTaggedQueuing:1;			/* Bit 7 */
+    boolean Force8Bit:1;				/* Byte 11 Bit 2 */
+    boolean DisableFast20:1;				/* Byte 11 Bit 3 */
+    unsigned char :3;					/* Byte 11 Bits 4-6 */
+    boolean EnableTaggedQueuing:1;			/* Byte 11 Bit 7 */
   } __attribute__ ((packed)) ChannelParameters[6];	/* Bytes 12-17 */
   unsigned char SCSIInitiatorID;			/* Byte 18 */
   unsigned char :8;					/* Byte 19 */
   enum {
-    DAC960_StartupMode_ControllerSpinUp =	0x00,
-    DAC960_StartupMode_PowerOnSpinUp =		0x01
+    DAC960_V1_StartupMode_ControllerSpinUp =	0x00,
+    DAC960_V1_StartupMode_PowerOnSpinUp =	0x01
   } __attribute__ ((packed)) StartupMode;		/* Byte 20 */
   unsigned char SimultaneousDeviceSpinUpCount;		/* Byte 21 */
   unsigned char SecondsDelayBetweenSpinUps;		/* Byte 22 */
@@ -623,44 +761,44 @@
   boolean CDROMBootEnabled:1;				/* Byte 52 Bit 1 */
   unsigned char :3;					/* Byte 52 Bits 2-4 */
   enum {
-    DAC960_Geometry_128_32 =			0x00,
-    DAC960_Geometry_255_63 =			0x01,
-    DAC960_Geometry_Reserved1 =			0x02,
-    DAC960_Geometry_Reserved2 =			0x03
+    DAC960_V1_Geometry_128_32 =			0x0,
+    DAC960_V1_Geometry_255_63 =			0x1,
+    DAC960_V1_Geometry_Reserved1 =		0x2,
+    DAC960_V1_Geometry_Reserved2 =		0x3
   } __attribute__ ((packed)) DriveGeometry:2;		/* Byte 52 Bits 5-6 */
   unsigned char :1;					/* Byte 52 Bit 7 */
   unsigned char Reserved2[9];				/* Bytes 53-61 */
   unsigned short Checksum;				/* Bytes 62-63 */
 }
-DAC960_Config2_T;
+DAC960_V1_Config2_T;
 
 
 /*
-  Define the DCDB request structure.
+  Define the DAC960 V1 Firmware DCDB request structure.
 */
 
-typedef struct DAC960_DCDB
+typedef struct DAC960_V1_DCDB
 {
   unsigned char TargetID:4;				 /* Byte 0 Bits 0-3 */
   unsigned char Channel:4;				 /* Byte 0 Bits 4-7 */
   enum {
-    DAC960_DCDB_NoDataTransfer = 0,
-    DAC960_DCDB_DataTransferDeviceToSystem = 1,
-    DAC960_DCDB_DataTransferSystemToDevice = 2,
-    DAC960_DCDB_IllegalDataTransfer = 3
+    DAC960_V1_DCDB_NoDataTransfer =		0,
+    DAC960_V1_DCDB_DataTransferDeviceToSystem = 1,
+    DAC960_V1_DCDB_DataTransferSystemToDevice = 2,
+    DAC960_V1_DCDB_IllegalDataTransfer =	3
   } __attribute__ ((packed)) Direction:2;		 /* Byte 1 Bits 0-1 */
   boolean EarlyStatus:1;				 /* Byte 1 Bit 2 */
   unsigned char :1;					 /* Byte 1 Bit 3 */
   enum {
-    DAC960_DCDB_Timeout_24_hours = 0,
-    DAC960_DCDB_Timeout_10_seconds = 1,
-    DAC960_DCDB_Timeout_60_seconds = 2,
-    DAC960_DCDB_Timeout_10_minutes = 3
+    DAC960_V1_DCDB_Timeout_24_hours =		0,
+    DAC960_V1_DCDB_Timeout_10_seconds =		1,
+    DAC960_V1_DCDB_Timeout_60_seconds =		2,
+    DAC960_V1_DCDB_Timeout_10_minutes =		3
   } __attribute__ ((packed)) Timeout:2;			 /* Byte 1 Bits 4-5 */
   boolean NoAutomaticRequestSense:1;			 /* Byte 1 Bit 6 */
   boolean DisconnectPermitted:1;			 /* Byte 1 Bit 7 */
   unsigned short TransferLength;			 /* Bytes 2-3 */
-  DAC960_BusAddress_T BusAddress;			 /* Bytes 4-7 */
+  DAC960_BusAddress32_T BusAddress;			 /* Bytes 4-7 */
   unsigned char CDBLength:4;				 /* Byte 8 Bits 0-3 */
   unsigned char TransferLengthHigh4:4;			 /* Byte 8 Bits 4-7 */
   unsigned char SenseLength;				 /* Byte 9 */
@@ -669,387 +807,1288 @@
   unsigned char Status;					 /* Byte 86 */
   unsigned char :8;					 /* Byte 87 */
 }
-DAC960_DCDB_T;
-
-
-/*
-  Define the SCSI INQUIRY Standard Data reply structure.
-*/
-
-typedef struct DAC960_SCSI_Inquiry
-{
-  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
-  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
-  unsigned char DeviceTypeModifier:7;			/* Byte 1 Bits 0-6 */
-  boolean RMB:1;					/* Byte 1 Bit 7 */
-  unsigned char ANSI_ApprovedVersion:3;			/* Byte 2 Bits 0-2 */
-  unsigned char ECMA_Version:3;				/* Byte 2 Bits 3-5 */
-  unsigned char ISO_Version:2;				/* Byte 2 Bits 6-7 */
-  unsigned char ResponseDataFormat:4;			/* Byte 3 Bits 0-3 */
-  unsigned char :2;					/* Byte 3 Bits 4-5 */
-  boolean TrmIOP:1;					/* Byte 3 Bit 6 */
-  boolean AENC:1;					/* Byte 3 Bit 7 */
-  unsigned char AdditionalLength;			/* Byte 4 */
-  unsigned char :8;					/* Byte 5 */
-  unsigned char :8;					/* Byte 6 */
-  boolean SftRe:1;					/* Byte 7 Bit 0 */
-  boolean CmdQue:1;					/* Byte 7 Bit 1 */
-  boolean :1;						/* Byte 7 Bit 2 */
-  boolean Linked:1;					/* Byte 7 Bit 3 */
-  boolean Sync:1;					/* Byte 7 Bit 4 */
-  boolean WBus16:1;					/* Byte 7 Bit 5 */
-  boolean WBus32:1;					/* Byte 7 Bit 6 */
-  boolean RelAdr:1;					/* Byte 7 Bit 7 */
-  unsigned char VendorIdentification[8];		/* Bytes 8-15 */
-  unsigned char ProductIdentification[16];		/* Bytes 16-31 */
-  unsigned char ProductRevisionLevel[4];		/* Bytes 32-35 */
-}
-DAC960_SCSI_Inquiry_T;
-
-
-/*
-  Define the SCSI INQUIRY Unit Serial Number reply structure.
-*/
-
-typedef struct DAC960_SCSI_Inquiry_UnitSerialNumber
-{
-  unsigned char PeripheralDeviceType:5;			/* Byte 0 Bits 0-4 */
-  unsigned char PeripheralQualifier:3;			/* Byte 0 Bits 5-7 */
-  unsigned char PageCode;				/* Byte 1 */
-  unsigned char :8;					/* Byte 2 */
-  unsigned char PageLength;				/* Byte 3 */
-  unsigned char ProductSerialNumber[28];		/* Bytes 4 - 31 */
-}
-DAC960_SCSI_Inquiry_UnitSerialNumber_T;
+DAC960_V1_DCDB_T;
 
 
 /*
-  Define the Scatter/Gather List Type 1 32 Bit Address 32 Bit Byte Count
-  structure.
+  Define the DAC960 V1 Firmware Scatter/Gather List Type 1 32 Bit Address
+  32 Bit Byte Count structure.
 */
 
-typedef struct DAC960_ScatterGatherSegment
+typedef struct DAC960_V1_ScatterGatherSegment
 {
-  DAC960_BusAddress_T SegmentDataPointer;		/* Bytes 0-3 */
-  DAC960_ByteCount_T SegmentByteCount;			/* Bytes 4-7 */
+  DAC960_BusAddress32_T SegmentDataPointer;		/* Bytes 0-3 */
+  DAC960_ByteCount32_T SegmentByteCount;		/* Bytes 4-7 */
 }
-DAC960_ScatterGatherSegment_T;
+DAC960_V1_ScatterGatherSegment_T;
 
 
 /*
-  Define the 13 Byte DAC960 Command Mailbox structure.  Bytes 13-15 are
-  not used.  The Command Mailbox structure is padded to 16 bytes for
+  Define the 13 Byte DAC960 V1 Firmware Command Mailbox structure.  Bytes 13-15
+  are not used.  The Command Mailbox structure is padded to 16 bytes for
   efficient access.
 */
 
-typedef union DAC960_CommandMailbox
+typedef union DAC960_V1_CommandMailbox
 {
   unsigned int Words[4];				/* Words 0-3 */
   unsigned char Bytes[16];				/* Bytes 0-15 */
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy[14];				/* Bytes 2-15 */
   } __attribute__ ((packed)) Common;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy1[6];				/* Bytes 2-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy2[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy1[5];				/* Bytes 2-6 */
     unsigned char LogicalDriveNumber:6;			/* Byte 7 Bits 0-6 */
     boolean AutoRestore:1;				/* Byte 7 Bit 7 */
     unsigned char Dummy2[8];				/* Bytes 8-15 */
   } __attribute__ ((packed)) Type3C;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Channel;				/* Byte 2 */
     unsigned char TargetID;				/* Byte 3 */
-    DAC960_PhysicalDeviceState_T DeviceState:5;		/* Byte 4 Bits 0-4 */
+    DAC960_V1_PhysicalDeviceState_T DeviceState:5;	/* Byte 4 Bits 0-4 */
     unsigned char Modifier:3;				/* Byte 4 Bits 5-7 */
     unsigned char Dummy1[3];				/* Bytes 5-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy2[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3D;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
-    DAC960_PerformEventLogOpType_T OperationType;	/* Byte 2 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_PerformEventLogOpType_T OperationType;	/* Byte 2 */
     unsigned char OperationQualifier;			/* Byte 3 */
     unsigned short SequenceNumber;			/* Bytes 4-5 */
     unsigned char Dummy1[2];				/* Bytes 6-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy2[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3E;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char Dummy1[2];				/* Bytes 2-3 */
     unsigned char RebuildRateConstant;			/* Byte 4 */
     unsigned char Dummy2[3];				/* Bytes 5-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char Dummy3[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) Type3R;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned short TransferLength;			/* Bytes 2-3 */
     unsigned int LogicalBlockAddress;			/* Bytes 4-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char LogicalDriveNumber;			/* Byte 12 */
     unsigned char Dummy[3];				/* Bytes 13-15 */
   } __attribute__ ((packed)) Type4;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     struct {
       unsigned short TransferLength:11;			/* Bytes 2-3 */
       unsigned char LogicalDriveNumber:5;		/* Byte 3 Bits 3-7 */
     } __attribute__ ((packed)) LD;
     unsigned int LogicalBlockAddress;			/* Bytes 4-7 */
-    DAC960_BusAddress_T BusAddress;			/* Bytes 8-11 */
+    DAC960_BusAddress32_T BusAddress;			/* Bytes 8-11 */
     unsigned char ScatterGatherCount:6;			/* Byte 12 Bits 0-5 */
     enum {
-      DAC960_ScatterGather_32BitAddress_32BitByteCount =	0x0,
-      DAC960_ScatterGather_32BitAddress_16BitByteCount =	0x1,
-      DAC960_ScatterGather_32BitByteCount_32BitAddress =	0x2,
-      DAC960_ScatterGather_16BitByteCount_32BitAddress =	0x3
+      DAC960_V1_ScatterGather_32BitAddress_32BitByteCount = 0x0,
+      DAC960_V1_ScatterGather_32BitAddress_16BitByteCount = 0x1,
+      DAC960_V1_ScatterGather_32BitByteCount_32BitAddress = 0x2,
+      DAC960_V1_ScatterGather_16BitByteCount_32BitAddress = 0x3
     } __attribute__ ((packed)) ScatterGatherType:2;	/* Byte 12 Bits 6-7 */
     unsigned char Dummy[3];				/* Bytes 13-15 */
   } __attribute__ ((packed)) Type5;
   struct {
-    DAC960_CommandOpcode_T CommandOpcode;		/* Byte 0 */
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
+    DAC960_V1_CommandOpcode_T CommandOpcode;		/* Byte 0 */
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 1 */
     unsigned char CommandOpcode2;			/* Byte 2 */
     unsigned char :8;					/* Byte 3 */
-    DAC960_BusAddress_T CommandMailboxesBusAddress;	/* Bytes 4-7 */
-    DAC960_BusAddress_T StatusMailboxesBusAddress;	/* Bytes 8-11 */
+    DAC960_BusAddress32_T CommandMailboxesBusAddress;	/* Bytes 4-7 */
+    DAC960_BusAddress32_T StatusMailboxesBusAddress;	/* Bytes 8-11 */
     unsigned char Dummy[4];				/* Bytes 12-15 */
   } __attribute__ ((packed)) TypeX;
 }
-DAC960_CommandMailbox_T;
+DAC960_V1_CommandMailbox_T;
 
 
 /*
-  Define the DAC960 Driver IOCTL requests.
+  Define the DAC960 V2 Firmware Command Opcodes.
 */
 
-#define DAC960_IOCTL_GET_CONTROLLER_COUNT	0xDAC001
-#define DAC960_IOCTL_GET_CONTROLLER_INFO	0xDAC002
-#define DAC960_IOCTL_EXECUTE_COMMAND		0xDAC003
+typedef enum
+{
+  DAC960_V2_MemCopy =				0x01,
+  DAC960_V2_SCSI_10_Passthru =			0x02,
+  DAC960_V2_SCSI_255_Passthru =			0x03,
+  DAC960_V2_SCSI_10 =				0x04,
+  DAC960_V2_SCSI_256 =				0x05,
+  DAC960_V2_IOCTL =				0x20
+}
+__attribute__ ((packed))
+DAC960_V2_CommandOpcode_T;
 
 
 /*
-  Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure.
+  Define the DAC960 V2 Firmware IOCTL Opcodes.
 */
 
-typedef struct DAC960_ControllerInfo
+typedef enum
 {
-  unsigned char ControllerNumber;
-  unsigned char PCI_Bus;
-  unsigned char PCI_Device;
-  unsigned char PCI_Function;
-  unsigned char IRQ_Channel;
-  unsigned char Channels;
-  DAC960_PCI_Address_T PCI_Address;
-  unsigned char ModelName[16];
-  unsigned char FirmwareVersion[16];
+  DAC960_V2_GetControllerInfo =			0x01,
+  DAC960_V2_GetLogicalDeviceInfoValid =		0x03,
+  DAC960_V2_GetPhysicalDeviceInfoValid =	0x05,
+  DAC960_V2_GetHealthStatus =			0x11,
+  DAC960_V2_GetEvent =				0x15,
+  DAC960_V2_SetDeviceState =			0x82,
+  DAC960_V2_RebuildDeviceStart =		0x88,
+  DAC960_V2_RebuildDeviceStop =			0x89,
+  DAC960_V2_ConsistencyCheckStart =		0x8C,
+  DAC960_V2_ConsistencyCheckStop =		0x8D,
+  DAC960_V2_SetMemoryMailbox =			0x8E,
+  DAC960_V2_PauseDevice =			0x92,
+  DAC960_V2_TranslatePhysicalToLogicalDevice =	0xC5
 }
-DAC960_ControllerInfo_T;
+__attribute__ ((packed))
+DAC960_V2_IOCTL_Opcode_T;
 
 
 /*
-  Define the User Mode DAC960_IOCTL_EXECUTE_COMMAND request structure.
+  Define the DAC960 V2 Firmware Command Identifier type.
 */
 
-typedef struct DAC960_UserCommand
-{
-  unsigned char ControllerNumber;
-  DAC960_CommandMailbox_T CommandMailbox;
-  int DataTransferLength;
-  void *DataTransferBuffer;
-  DAC960_DCDB_T *DCDB;
-}
-DAC960_UserCommand_T;
+typedef unsigned short DAC960_V2_CommandIdentifier_T;
 
 
 /*
-  Define the Kernel Mode DAC960_IOCTL_EXECUTE_COMMAND request structure.
+  Define the DAC960 V2 Firmware Command Status Codes.
 */
 
-typedef struct DAC960_KernelCommand
-{
-  unsigned char ControllerNumber;
-  DAC960_CommandMailbox_T CommandMailbox;
-  int DataTransferLength;
-  void *DataTransferBuffer;
-  DAC960_DCDB_T *DCDB;
-  DAC960_CommandStatus_T CommandStatus;
-  void (*CompletionFunction)(struct DAC960_KernelCommand *);
-  void *CompletionData;
-}
-DAC960_KernelCommand_T;
+#define DAC960_V2_NormalCompletion		0x00
+#define DAC960_V2_AbormalCompletion		0x02
+#define DAC960_V2_DeviceNonresponsive		0x0E
+
+typedef unsigned char DAC960_V2_CommandStatus_T;
 
 
 /*
-  Import the Kernel Mode IOCTL interface.
+  Define the DAC960 V2 Firmware Memory Type structure.
 */
 
-extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
+typedef struct DAC960_V2_MemoryType
+{
+  enum {
+    DAC960_V2_MemoryType_Reserved =		0x00,
+    DAC960_V2_MemoryType_DRAM =			0x01,
+    DAC960_V2_MemoryType_EDRAM =		0x02,
+    DAC960_V2_MemoryType_EDO =			0x03,
+    DAC960_V2_MemoryType_SDRAM =		0x04
+  } __attribute__ ((packed)) MemoryType:5;		/* Byte 0 Bits 0-4 */
+  boolean :1;						/* Byte 0 Bit 5 */
+  boolean MemoryParity:1;				/* Byte 0 Bit 6 */
+  boolean MemoryECC:1;					/* Byte 0 Bit 7 */
+}
+DAC960_V2_MemoryType_T;
 
 
 /*
-  Virtual_to_Bus maps from Kernel Virtual Addresses to PCI Bus Addresses.
+  Define the DAC960 V2 Firmware Processor Type structure.
 */
 
-static inline DAC960_BusAddress_T Virtual_to_Bus(void *VirtualAddress)
+typedef enum
 {
-  return (DAC960_BusAddress_T) virt_to_bus(VirtualAddress);
+  DAC960_V2_ProcessorType_i960CA =		0x01,
+  DAC960_V2_ProcessorType_i960RD =		0x02,
+  DAC960_V2_ProcessorType_i960RN =		0x03,
+  DAC960_V2_ProcessorType_i960RP =		0x04,
+  DAC960_V2_ProcessorType_NorthBay =		0x05,
+  DAC960_V2_ProcessorType_StrongArm =		0x06,
+  DAC960_V2_ProcessorType_i960RM =		0x07
 }
+__attribute__ ((packed))
+DAC960_V2_ProcessorType_T;
 
 
 /*
-  Bus_to_Virtual maps from PCI Bus Addresses to Kernel Virtual Addresses.
+  Define the DAC960 V2 Firmware Get Controller Info reply structure.
 */
 
-static inline void *Bus_to_Virtual(DAC960_BusAddress_T BusAddress)
+typedef struct DAC960_V2_ControllerInfo
 {
-  return (void *) bus_to_virt(BusAddress);
+  unsigned char :8;					/* Byte 0 */
+  enum {
+    DAC960_V2_SCSI_Bus =			0x00,
+    DAC960_V2_Fibre_Bus =			0x01,
+    DAC960_V2_PCI_Bus =				0x03
+  } __attribute__ ((packed)) BusInterfaceType;		/* Byte 1 */
+  enum {
+    DAC960_V2_DAC960E =				0x01,
+    DAC960_V2_DAC960M =				0x08,
+    DAC960_V2_DAC960PD =			0x10,
+    DAC960_V2_DAC960PL =			0x11,
+    DAC960_V2_DAC960PU =			0x12,
+    DAC960_V2_DAC960PE =			0x13,
+    DAC960_V2_DAC960PG =			0x14,
+    DAC960_V2_DAC960PJ =			0x15,
+    DAC960_V2_DAC960PTL0 =			0x16,
+    DAC960_V2_DAC960PR =			0x17,
+    DAC960_V2_DAC960PRL =			0x18,
+    DAC960_V2_DAC960PT =			0x19,
+    DAC960_V2_DAC1164P =			0x1A,
+    DAC960_V2_DAC960PTL1 =			0x1B,
+    DAC960_V2_EXR2000P =			0x1C,
+    DAC960_V2_EXR3000P =			0x1D,
+    DAC960_V2_AcceleRAID352 =			0x1E,
+    DAC960_V2_AcceleRAID351 =			0x1F,
+    DAC960_V2_DAC960S =				0x60,
+    DAC960_V2_DAC960SU =			0x61,
+    DAC960_V2_DAC960SX =			0x62,
+    DAC960_V2_DAC960SF =			0x63,
+    DAC960_V2_DAC960SS =			0x64,
+    DAC960_V2_DAC960FL =			0x65,
+    DAC960_V2_DAC960LL =			0x66,
+    DAC960_V2_DAC960FF =			0x67,
+    DAC960_V2_DAC960HP =			0x68,
+    DAC960_V2_RAIDBRICK =			0x69,
+    DAC960_V2_METEOR_FL =			0x6A,
+    DAC960_V2_METEOR_FF =			0x6B
+  } __attribute__ ((packed)) ControllerType;		/* Byte 2 */
+  unsigned char :8;					/* Byte 3 */
+  unsigned short BusInterfaceSpeedMHz;			/* Bytes 4-5 */
+  unsigned char BusWidthBits;				/* Byte 6 */
+  unsigned char Reserved1[9];				/* Bytes 7-15 */
+  unsigned char BusInterfaceName[16];			/* Bytes 16-31 */
+  unsigned char ControllerName[16];			/* Bytes 32-47 */
+  unsigned char Reserved2[16];				/* Bytes 48-63 */
+  /* Firmware Release Information */
+  unsigned char FirmwareMajorVersion;			/* Byte 64 */
+  unsigned char FirmwareMinorVersion;			/* Byte 65 */
+  unsigned char FirmwareTurnNumber;			/* Byte 66 */
+  unsigned char FirmwareBuildNumber;			/* Byte 67 */
+  unsigned char FirmwareReleaseDay;			/* Byte 68 */
+  unsigned char FirmwareReleaseMonth;			/* Byte 69 */
+  unsigned char FirmwareReleaseYearHigh2Digits;		/* Byte 70 */
+  unsigned char FirmwareReleaseYearLow2Digits;		/* Byte 71 */
+  /* Hardware Release Information */
+  unsigned char HardwareRevision;			/* Byte 72 */
+  unsigned int :24;					/* Bytes 73-75 */
+  unsigned char HardwareReleaseDay;			/* Byte 76 */
+  unsigned char HardwareReleaseMonth;			/* Byte 77 */
+  unsigned char HardwareReleaseYearHigh2Digits;		/* Byte 78 */
+  unsigned char HardwareReleaseYearLow2Digits;		/* Byte 79 */
+  /* Hardware Manufacturing Information */
+  unsigned char ManufacturingBatchNumber;		/* Byte 80 */
+  unsigned char :8;					/* Byte 81 */
+  unsigned char ManufacturingPlantNumber;		/* Byte 82 */
+  unsigned char :8;					/* Byte 83 */
+  unsigned char HardwareManufacturingDay;		/* Byte 84 */
+  unsigned char HardwareManufacturingMonth;		/* Byte 85 */
+  unsigned char HardwareManufacturingYearHigh2Digits;	/* Byte 86 */
+  unsigned char HardwareManufacturingYearLow2Digits;	/* Byte 87 */
+  unsigned char MaximumNumberOfPDDperXLDD;		/* Byte 88 */
+  unsigned char MaximumNumberOfILDDperXLDD;		/* Byte 89 */
+  unsigned short NonvolatileMemorySizeKB;		/* Bytes 90-91 */
+  unsigned char MaximumNumberOfXLDD;			/* Byte 92 */
+  unsigned int :24;					/* Bytes 93-95 */
+  /* Unique Information per Controller */
+  unsigned char ControllerSerialNumber[16];		/* Bytes 96-111 */
+  unsigned char Reserved3[16];				/* Bytes 112-127 */
+  /* Vendor Information */
+  unsigned int :24;					/* Bytes 128-130 */
+  unsigned char OEM_Information;			/* Byte 131 */
+  unsigned char VendorName[16];				/* Bytes 132-147 */
+  /* Other Physical/Controller/Operation Information */
+  boolean BBU_Present:1;				/* Byte 148 Bit 0 */
+  boolean ActiveActiveClusteringMode:1;			/* Byte 148 Bit 1 */
+  unsigned char :6;					/* Byte 148 Bits 2-7 */
+  unsigned char :8;					/* Byte 149 */
+  unsigned short :16;					/* Bytes 150-151 */
+  /* Physical Device Scan Information */
+  boolean PhysicalScanActive:1;				/* Byte 152 Bit 0 */
+  unsigned char :7;					/* Byte 152 Bits 1-7 */
+  unsigned char PhysicalDeviceChannelNumber;		/* Byte 153 */
+  unsigned char PhysicalDeviceTargetID;			/* Byte 154 */
+  unsigned char PhysicalDeviceLogicalUnit;		/* Byte 155 */
+  /* Maximum Command Data Transfer Sizes */
+  unsigned short MaximumDataTransferSizeInBlocks;	/* Bytes 156-157 */
+  unsigned short MaximumScatterGatherEntries;		/* Bytes 158-159 */
+  /* Logical/Physical Device Counts */
+  unsigned short LogicalDevicesPresent;			/* Bytes 160-161 */
+  unsigned short LogicalDevicesCritical;		/* Bytes 162-163 */
+  unsigned short LogicalDevicesOffline;			/* Bytes 164-165 */
+  unsigned short PhysicalDevicesPresent;		/* Bytes 166-167 */
+  unsigned short PhysicalDisksPresent;			/* Bytes 168-169 */
+  unsigned short PhysicalDisksCritical;			/* Bytes 170-171 */
+  unsigned short PhysicalDisksOffline;			/* Bytes 172-173 */
+  unsigned short MaximumParallelCommands;		/* Bytes 174-175 */
+  /* Channel and Target ID Information */
+  unsigned char NumberOfPhysicalChannelsPresent;	/* Byte 176 */
+  unsigned char NumberOfVirtualChannelsPresent;		/* Byte 177 */
+  unsigned char NumberOfPhysicalChannelsPossible;	/* Byte 178 */
+  unsigned char NumberOfVirtualChannelsPossible;	/* Byte 179 */
+  unsigned char MaximumTargetsPerChannel[16];		/* Bytes 180-195 */
+  unsigned char Reserved4[12];				/* Bytes 196-207 */
+  /* Memory/Cache Information */
+  unsigned short MemorySizeMB;				/* Bytes 208-209 */
+  unsigned short CacheSizeMB;				/* Bytes 210-211 */
+  unsigned int ValidCacheSizeInBytes;			/* Bytes 212-215 */
+  unsigned int DirtyCacheSizeInBytes;			/* Bytes 216-219 */
+  unsigned short MemorySpeedMHz;			/* Bytes 220-221 */
+  unsigned char MemoryDataWidthBits;			/* Byte 222 */
+  DAC960_V2_MemoryType_T MemoryType;			/* Byte 223 */
+  unsigned char CacheMemoryTypeName[16];		/* Bytes 224-239 */
+  /* Execution Memory Information */
+  unsigned short ExecutionMemorySizeMB;			/* Bytes 240-241 */
+  unsigned short ExecutionL2CacheSizeMB;		/* Bytes 242-243 */
+  unsigned char Reserved5[8];				/* Bytes 244-251 */
+  unsigned short ExecutionMemorySpeedMHz;		/* Bytes 252-253 */
+  unsigned char ExecutionMemoryDataWidthBits;		/* Byte 254 */
+  DAC960_V2_MemoryType_T ExecutionMemoryType;		/* Byte 255 */
+  unsigned char ExecutionMemoryTypeName[16];		/* Bytes 256-271 */
+  /* First CPU Type Information */
+  unsigned short FirstProcessorSpeedMHz;		/* Bytes 272-273 */
+  DAC960_V2_ProcessorType_T FirstProcessorType;		/* Byte 274 */
+  unsigned char FirstProcessorCount;			/* Byte 275 */
+  unsigned char Reserved6[12];				/* Bytes 276-287 */
+  unsigned char FirstProcessorName[16];			/* Bytes 288-303 */
+  /* Second CPU Type Information */
+  unsigned short SecondProcessorSpeedMHz;		/* Bytes 304-305 */
+  DAC960_V2_ProcessorType_T SecondProcessorType;	/* Byte 306 */
+  unsigned char SecondProcessorCount;			/* Byte 307 */
+  unsigned char Reserved7[12];				/* Bytes 308-319 */
+  unsigned char SecondProcessorName[16];		/* Bytes 320-335 */
+  /* Debugging/Profiling/Command Time Tracing Information */
+  unsigned short CurrentProfilingDataPageNumber;	/* Bytes 336-337 */
+  unsigned short ProgramsAwaitingProfilingData;		/* Bytes 338-339 */
+  unsigned short CurrentCommandTimeTraceDataPageNumber;	/* Bytes 340-341 */
+  unsigned short ProgramsAwaitingCommandTimeTraceData;	/* Bytes 342-343 */
+  unsigned char Reserved8[8];				/* Bytes 344-351 */
+  /* Error Counters on Physical Devices */
+  unsigned short PhysicalDeviceBusResets;		/* Bytes 352-353 */
+  unsigned short PhysicalDeviceParityErrors;		/* Bytes 355-355 */
+  unsigned short PhysicalDeviceSoftErrors;		/* Bytes 356-357 */
+  unsigned short PhysicalDeviceCommandsFailed;		/* Bytes 358-359 */
+  unsigned short PhysicalDeviceMiscellaneousErrors;	/* Bytes 360-361 */
+  unsigned short PhysicalDeviceCommandTimeouts;		/* Bytes 362-363 */
+  unsigned short PhysicalDeviceSelectionTimeouts;	/* Bytes 364-365 */
+  unsigned short PhysicalDeviceRetriesDone;		/* Bytes 366-367 */
+  unsigned short PhysicalDeviceAbortsDone;		/* Bytes 368-369 */
+  unsigned short PhysicalDeviceHostCommandAbortsDone;	/* Bytes 370-371 */
+  unsigned short PhysicalDevicePredictedFailuresDetected; /* Bytes 372-373 */
+  unsigned short PhysicalDeviceHostCommandsFailed;	/* Bytes 374-375 */
+  unsigned char Reserved9[8];				/* Bytes 376-383 */
+  /* Error Counters on Logical Devices */
+  unsigned short LogicalDeviceSoftErrors;		/* Bytes 384-385 */
+  unsigned short LogicalDeviceCommandsFailed;		/* Bytes 386-387 */
+  unsigned short LogicalDeviceHostCommandAbortsDone;	/* Bytes 388-389 */
+  unsigned short :16;					/* Bytes 390-391 */
+  unsigned short ControllerMemoryErrors;		/* Bytes 392-393 */
+  unsigned short ControllerHostCommandAbortsDone;	/* Bytes 394-395 */
+  unsigned int :32;					/* Bytes 396-399 */
+  /* Long Duration Activity Information */
+  unsigned short BackgroundInitializationsActive;	/* Bytes 400-401 */
+  unsigned short LogicalDeviceInitializationsActive;	/* Bytes 402-403 */
+  unsigned short PhysicalDeviceInitializationsActive;	/* Bytes 404-405 */
+  unsigned short ConsistencyChecksActive;		/* Bytes 406-407 */
+  unsigned short RebuildsActive;			/* Bytes 408-409 */
+  unsigned short OnlineExpansionsActive;		/* Bytes 410-411 */
+  unsigned short PatrolActivitiesActive;		/* Bytes 412-413 */
+  unsigned char LongOperationStatus;			/* Byte 414 */
+  unsigned char :8;					/* Byte 415 */
+  /* Flash ROM Information */
+  unsigned char FlashType;				/* Byte 416 */
+  unsigned char :8;					/* Byte 417 */
+  unsigned short FlashSizeMB;				/* Bytes 418-419 */
+  unsigned int FlashLimit;				/* Bytes 420-423 */
+  unsigned int FlashCount;				/* Bytes 424-427 */
+  unsigned int :32;					/* Bytes 428-431 */
+  unsigned char FlashTypeName[16];			/* Bytes 432-447 */
+  /* Firmware Run Time Information */
+  unsigned char RebuildRate;				/* Byte 448 */
+  unsigned char BackgroundInitializationRate;		/* Byte 449 */
+  unsigned char ForegroundInitializationRate;		/* Byte 450 */
+  unsigned char ConsistencyCheckRate;			/* Byte 451 */
+  unsigned int :32;					/* Bytes 452-455 */
+  unsigned int MaximumDP;				/* Bytes 456-459 */
+  unsigned int FreeDP;					/* Bytes 460-463 */
+  unsigned int MaximumIOP;				/* Bytes 464-467 */
+  unsigned int FreeIOP;					/* Bytes 468-471 */
+  unsigned short MaximumCombLengthInBlocks;		/* Bytes 472-473 */
+  unsigned short NumberOfConfigurationGroups;		/* Bytes 474-475 */
+  boolean InstallationAbortStatus:1;			/* Byte 476 Bit 0 */
+  boolean MaintenanceModeStatus:1;			/* Byte 476 Bit 1 */
+  unsigned int :6;					/* Byte 476 Bits 2-7 */
+  unsigned int :24;					/* Bytes 477-479 */
+  unsigned char Reserved10[32];				/* Bytes 480-511 */
+  unsigned char Reserved11[512];			/* Bytes 512-1023 */
 }
+DAC960_V2_ControllerInfo_T;
 
 
 /*
-  DAC960_DriverVersion protects the private portion of this file.
+  Define the DAC960 V2 Firmware Logical Device State type.
 */
 
-#ifdef DAC960_DriverVersion
+typedef enum
+{
+  DAC960_V2_LogicalDevice_Online =		0x01,
+  DAC960_V2_LogicalDevice_Offline =		0x08,
+  DAC960_V2_LogicalDevice_Critical =		0x09
+}
+__attribute__ ((packed))
+DAC960_V2_LogicalDeviceState_T;
 
 
 /*
-  Define the maximum Driver Queue Depth and Controller Queue Depth supported
-  by any DAC960 model.
+  Define the DAC960 V2 Firmware Get Logical Device Info reply structure.
 */
 
-#define DAC960_MaxDriverQueueDepth		127
-#define DAC960_MaxControllerQueueDepth		128
+typedef struct DAC960_V2_LogicalDeviceInfo
+{
+  unsigned char :8;					/* Byte 0 */
+  unsigned char Channel;				/* Byte 1 */
+  unsigned char TargetID;				/* Byte 2 */
+  unsigned char LogicalUnit;				/* Byte 3 */
+  DAC960_V2_LogicalDeviceState_T LogicalDeviceState;	/* Byte 4 */
+  unsigned char RAIDLevel;				/* Byte 5 */
+  unsigned char StripeSize;				/* Byte 6 */
+  unsigned char CacheLineSize;				/* Byte 7 */
+  struct {
+    enum {
+      DAC960_V2_ReadCacheDisabled =		0x0,
+      DAC960_V2_ReadCacheEnabled =		0x1,
+      DAC960_V2_ReadAheadEnabled =		0x2,
+      DAC960_V2_IntelligentReadAheadEnabled =	0x3
+    } __attribute__ ((packed)) ReadCache:3;		/* Byte 8 Bits 0-2 */
+    enum {
+      DAC960_V2_WriteCacheDisabled =		0x0,
+      DAC960_V2_LogicalDeviceReadOnly =		0x1,
+      DAC960_V2_WriteCacheEnabled =		0x2,
+      DAC960_V2_IntelligentWriteCacheEnabled =	0x3
+    } __attribute__ ((packed)) WriteCache:3;		/* Byte 8 Bits 3-5 */
+    boolean :1;						/* Byte 8 Bit 6 */
+    boolean LogicalDeviceInitialized:1;			/* Byte 8 Bit 7 */
+  } LogicalDeviceControl;				/* Byte 8 */
+  /* Logical Device Operations Status */
+  boolean ConsistencyCheckInProgress:1;			/* Byte 9 Bit 0 */
+  boolean RebuildInProgress:1;				/* Byte 9 Bit 1 */
+  boolean BackgroundInitializationInProgress:1;		/* Byte 9 Bit 2 */
+  boolean ForegroundInitializationInProgress:1;		/* Byte 9 Bit 3 */
+  boolean DataMigrationInProgress:1;			/* Byte 9 Bit 4 */
+  boolean PatrolOperationInProgress:1;			/* Byte 9 Bit 5 */
+  unsigned char :2;					/* Byte 9 Bits 6-7 */
+  unsigned char RAID5WriteUpdate;			/* Byte 10 */
+  unsigned char RAID5Algorithm;				/* Byte 11 */
+  unsigned short LogicalDeviceNumber;			/* Bytes 12-13 */
+  /* BIOS Info */
+  boolean BIOSDisabled:1;				/* Byte 14 Bit 0 */
+  boolean CDROMBootEnabled:1;				/* Byte 14 Bit 1 */
+  boolean DriveCoercionEnabled:1;			/* Byte 14 Bit 2 */
+  boolean WriteSameDisabled:1;				/* Byte 14 Bit 3 */
+  boolean HBA_ModeEnabled:1;				/* Byte 14 Bit 4 */
+  enum {
+    DAC960_V2_Geometry_128_32 =			0x0,
+    DAC960_V2_Geometry_255_63 =			0x1,
+    DAC960_V2_Geometry_Reserved1 =		0x2,
+    DAC960_V2_Geometry_Reserved2 =		0x3
+  } __attribute__ ((packed)) DriveGeometry:2;		/* Byte 14 Bits 5-6 */
+  unsigned char :1;					/* Byte 14 Bit 7 */
+  unsigned char :8;					/* Byte 15 */
+  /* Error Counters */
+  unsigned short SoftErrors;				/* Bytes 16-17 */
+  unsigned short CommandsFailed;			/* Bytes 18-19 */
+  unsigned short HostCommandAbortsDone;			/* Bytes 20-21 */
+  unsigned short DeferredWriteErrors;			/* Bytes 22-23 */
+  unsigned int :32;					/* Bytes 24-27 */
+  unsigned int :32;					/* Bytes 28-31 */
+  /* Device Size Information */
+  unsigned short :16;					/* Bytes 32-33 */
+  unsigned short DeviceBlockSizeInBytes;		/* Bytes 34-35 */
+  unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;	/* Bytes 36-39 */
+  unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 40-43 */
+  unsigned int :32;					/* Bytes 44-47 */
+  unsigned char LogicalDeviceName[32];			/* Bytes 48-79 */
+  unsigned char SCSI_InquiryData[36];			/* Bytes 80-115 */
+  unsigned char Reserved1[12];				/* Bytes 116-127 */
+  DAC960_ByteCount64_T LastReadBlockNumber;		/* Bytes 128-135 */
+  DAC960_ByteCount64_T LastWrittenBlockNumber;		/* Bytes 136-143 */
+  DAC960_ByteCount64_T ConsistencyCheckBlockNumber;	/* Bytes 144-151 */
+  DAC960_ByteCount64_T RebuildBlockNumber;		/* Bytes 152-159 */
+  DAC960_ByteCount64_T BackgroundInitializationBlockNumber; /* Bytes 160-167 */
+  DAC960_ByteCount64_T ForegroundInitializationBlockNumber; /* Bytes 168-175 */
+  DAC960_ByteCount64_T DataMigrationBlockNumber;	/* Bytes 176-183 */
+  DAC960_ByteCount64_T PatrolOperationBlockNumber;	/* Bytes 184-191 */
+  unsigned char Reserved2[64];				/* Bytes 192-255 */
+}
+DAC960_V2_LogicalDeviceInfo_T;
 
 
 /*
-  Define the maximum number of Scatter/Gather Segments supported by any
-  DAC960 model.
+  Define the DAC960 V2 Firmware Physical Device State type.
 */
 
-#define DAC960_MaxScatterGatherSegments		33
+typedef enum
+{
+    DAC960_V2_Device_Unconfigured =		0x00,
+    DAC960_V2_Device_Online =			0x01,
+    DAC960_V2_Device_WriteOnly =		0x03,
+    DAC960_V2_Device_Dead =			0x08,
+    DAC960_V2_Device_Standby =			0x21,
+    DAC960_V2_Device_InvalidState =		0xFF
+}
+__attribute__ ((packed))
+DAC960_V2_PhysicalDeviceState_T;
 
 
 /*
-  Define the number of Command Mailboxes and Status Mailboxes used by the
-  Memory Mailbox Interface.
+  Define the DAC960 V2 Firmware Get Physical Device Info reply structure.
 */
 
-#define DAC960_CommandMailboxCount		256
-#define DAC960_StatusMailboxCount		1024
+typedef struct DAC960_V2_PhysicalDeviceInfo
+{
+  unsigned char :8;					/* Byte 0 */
+  unsigned char Channel;				/* Byte 1 */
+  unsigned char TargetID;				/* Byte 2 */
+  unsigned char LogicalUnit;				/* Byte 3 */
+  /* Configuration Status Bits */
+  boolean PhysicalDeviceFaultTolerant:1;		/* Byte 4 Bit 0 */
+  boolean :1;						/* Byte 4 Bit 1 */
+  boolean PhysicalDeviceLocalToController:1;		/* Byte 4 Bit 2 */
+  unsigned char :5;					/* Byte 4 Bits 3-7 */
+  /* Multiple Host/Controller Status Bits */
+  boolean RemoteHostSystemDead:1;			/* Byte 5 Bit 0 */
+  boolean RemoteControllerDead:1;			/* Byte 5 Bit 1 */
+  unsigned char :6;					/* Byte 5 Bits 2-7 */
+  DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState;	/* Byte 6 */
+  unsigned char NegotiatedDataWidthBits;		/* Byte 7 */
+  unsigned short NegotiatedSynchronousMegaTransfers;	/* Bytes 8-9 */
+  /* Multiported Physical Device Information */
+  unsigned char NumberOfPortConnections;		/* Byte 10 */
+  unsigned char DriveAccessibilityBitmap;		/* Byte 11 */
+  unsigned int :32;					/* Bytes 12-15 */
+  unsigned char NetworkAddress[16];			/* Bytes 16-31 */
+  unsigned short MaximumTags;				/* Bytes 32-33 */
+  /* Physical Device Operations Status */
+  boolean ConsistencyCheckInProgress:1;			/* Byte 34 Bit 0 */
+  boolean RebuildInProgress:1;				/* Byte 34 Bit 1 */
+  boolean MakingDataConsistentInProgress:1;		/* Byte 34 Bit 2 */
+  boolean PhysicalDeviceInitializationInProgress:1;	/* Byte 34 Bit 3 */
+  boolean DataMigrationInProgress:1;			/* Byte 34 Bit 4 */
+  boolean PatrolOperationInProgress:1;			/* Byte 34 Bit 5 */
+  unsigned char :2;					/* Byte 34 Bits 6-7 */
+  unsigned char LongOperationStatus;			/* Byte 35 */
+  unsigned char ParityErrors;				/* Byte 36 */
+  unsigned char SoftErrors;				/* Byte 37 */
+  unsigned char HardErrors;				/* Byte 38 */
+  unsigned char MiscellaneousErrors;			/* Byte 39 */
+  unsigned char CommandTimeouts;			/* Byte 40 */
+  unsigned char Retries;				/* Byte 41 */
+  unsigned char Aborts;					/* Byte 42 */
+  unsigned char PredictedFailuresDetected;		/* Byte 43 */
+  unsigned int :32;					/* Bytes 44-47 */
+  unsigned short :16;					/* Bytes 48-49 */
+  unsigned short DeviceBlockSizeInBytes;		/* Bytes 50-51 */
+  unsigned int OriginalDeviceSizeIn512ByteBlocksOrMB;	/* Bytes 52-55 */
+  unsigned int ConfigurableDeviceSizeIn512ByteBlocksOrMB; /* Bytes 56-59 */
+  unsigned int :32;					/* Bytes 60-63 */
+  unsigned char PhysicalDeviceName[16];			/* Bytes 64-79 */
+  unsigned char Reserved1[16];				/* Bytes 80-95 */
+  unsigned char Reserved2[32];				/* Bytes 96-127 */
+  unsigned char SCSI_InquiryData[36];			/* Bytes 128-163 */
+  unsigned char Reserved3[12];				/* Bytes 164-175 */
+  unsigned char Reserved4[16];				/* Bytes 176-191 */
+  DAC960_ByteCount64_T LastReadBlockNumber;		/* Bytes 192-199 */
+  DAC960_ByteCount64_T LastWrittenBlockNumber;		/* Bytes 200-207 */
+  DAC960_ByteCount64_T ConsistencyCheckBlockNumber;	/* Bytes 208-215 */
+  DAC960_ByteCount64_T RebuildBlockNumber;		/* Bytes 216-223 */
+  DAC960_ByteCount64_T MakingDataConsistentBlockNumber;	/* Bytes 224-231 */
+  DAC960_ByteCount64_T DeviceInitializationBlockNumber; /* Bytes 232-239 */
+  DAC960_ByteCount64_T DataMigrationBlockNumber;	/* Bytes 240-247 */
+  DAC960_ByteCount64_T PatrolOperationBlockNumber;	/* Bytes 248-255 */
+  unsigned char Reserved5[256];				/* Bytes 256-511 */
+}
+DAC960_V2_PhysicalDeviceInfo_T;
+
+
+/*
+  Define the DAC960 V2 Firmware Health Status Buffer structure.
+*/
+
+typedef struct DAC960_V2_HealthStatusBuffer
+{
+  unsigned int MicrosecondsFromControllerStartTime;	/* Bytes 0-3 */
+  unsigned int MillisecondsFromControllerStartTime;	/* Bytes 4-7 */
+  unsigned int SecondsFrom1January1970;			/* Bytes 8-11 */
+  unsigned int :32;					/* Bytes 12-15 */
+  unsigned int StatusChangeCounter;			/* Bytes 16-19 */
+  unsigned int :32;					/* Bytes 20-23 */
+  unsigned int DebugOutputMessageBufferIndex;		/* Bytes 24-27 */
+  unsigned int CodedMessageBufferIndex;			/* Bytes 28-31 */
+  unsigned int CurrentTimeTracePageNumber;		/* Bytes 32-35 */
+  unsigned int CurrentProfilerPageNumber;		/* Bytes 36-39 */
+  unsigned int NextEventSequenceNumber;			/* Bytes 40-43 */
+  unsigned int :32;					/* Bytes 44-47 */
+  unsigned char Reserved1[16];				/* Bytes 48-63 */
+  unsigned char Reserved2[64];				/* Bytes 64-127 */
+}
+DAC960_V2_HealthStatusBuffer_T;
 
 
 /*
-  Define the DAC960 Controller Monitoring Timer Interval.
+  Define the DAC960 V2 Firmware Get Event reply structure.
 */
 
-#define DAC960_MonitoringTimerInterval		(10 * HZ)
+typedef struct DAC960_V2_Event
+{
+  unsigned int EventSequenceNumber;			/* Bytes 0-3 */
+  unsigned int EventTime;				/* Bytes 4-7 */
+  unsigned int EventCode;				/* Bytes 8-11 */
+  unsigned char :8;					/* Byte 12 */
+  unsigned char Channel;				/* Byte 13 */
+  unsigned char TargetID;				/* Byte 14 */
+  unsigned char LogicalUnit;				/* Byte 15 */
+  unsigned int :32;					/* Bytes 16-19 */
+  unsigned int EventSpecificParameter;			/* Bytes 20-23 */
+  unsigned char RequestSenseData[40];			/* Bytes 24-63 */
+}
+DAC960_V2_Event_T;
 
 
 /*
-  Define the DAC960 Controller Secondary Monitoring Interval.
+  Define the DAC960 V2 Firmware Command Control Bits structure.
 */
 
-#define DAC960_SecondaryMonitoringInterval	(60 * HZ)
+typedef struct DAC960_V2_CommandControlBits
+{
+  boolean ForceUnitAccess:1;				/* Byte 0 Bit 0 */
+  boolean DisablePageOut:1;				/* Byte 0 Bit 1 */
+  boolean :1;						/* Byte 0 Bit 2 */
+  boolean AdditionalScatterGatherListMemory:1;		/* Byte 0 Bit 3 */
+  boolean DataTransferControllerToHost:1;		/* Byte 0 Bit 4 */
+  boolean :1;						/* Byte 0 Bit 5 */
+  boolean NoAutoRequestSense:1;				/* Byte 0 Bit 6 */
+  boolean DisconnectProhibited:1;			/* Byte 0 Bit 7 */
+}
+DAC960_V2_CommandControlBits_T;
 
 
 /*
-  Define the DAC960 Controller Progress Reporting Interval.
+  Define the DAC960 V2 Firmware Command Timeout structure.
 */
 
-#define DAC960_ProgressReportingInterval	(60 * HZ)
+typedef struct DAC960_V2_CommandTimeout
+{
+  unsigned char TimeoutValue:6;				/* Byte 0 Bits 0-5 */
+  enum {
+    DAC960_V2_TimeoutScale_Seconds =		0,
+    DAC960_V2_TimeoutScale_Minutes =		1,
+    DAC960_V2_TimeoutScale_Hours =		2,
+    DAC960_V2_TimeoutScale_Reserved =		3
+  } __attribute__ ((packed)) TimeoutScale:2;		/* Byte 0 Bits 6-7 */
+}
+DAC960_V2_CommandTimeout_T;
 
 
 /*
-  Define the maximum number of Partitions allowed for each Logical Drive.
+  Define the DAC960 V2 Firmware Physical Device structure.
 */
 
-#define DAC960_MaxPartitions			8
-#define DAC960_MaxPartitionsBits		3
+typedef struct DAC960_V2_PhysicalDevice
+{
+  unsigned char LogicalUnit;				/* Byte 0 */
+  unsigned char TargetID;				/* Byte 1 */
+  unsigned char Channel:3;				/* Byte 2 Bits 0-2 */
+  unsigned char Controller:5;				/* Byte 2 Bits 3-7 */
+}
+__attribute__ ((packed))
+DAC960_V2_PhysicalDevice_T;
 
 
 /*
-  Define macros to extract the Controller Number, Logical Drive Number, and
-  Partition Number from a Kernel Device, and to construct a Major Number, Minor
-  Number, and Kernel Device from the Controller Number, Logical Drive Number,
-  and Partition Number.  There is one Major Number assigned to each Controller.
-  The associated Minor Number is divided into the Logical Drive Number and
-  Partition Number.
+  Define the DAC960 V2 Firmware Logical Device structure.
 */
 
-#define DAC960_ControllerNumber(Device) \
-  (MAJOR(Device) - DAC960_MAJOR)
+typedef struct DAC960_V2_LogicalDevice
+{
+  unsigned short LogicalDeviceNumber;			/* Bytes 0-1 */
+  unsigned char :3;					/* Byte 2 Bits 0-2 */
+  unsigned char Controller:5;				/* Byte 2 Bits 3-7 */
+}
+__attribute__ ((packed))
+DAC960_V2_LogicalDevice_T;
 
-#define DAC960_LogicalDriveNumber(Device) \
-  (MINOR(Device) >> DAC960_MaxPartitionsBits)
 
-#define DAC960_PartitionNumber(Device) \
-  (MINOR(Device) & (DAC960_MaxPartitions - 1))
+/*
+  Define the DAC960 V2 Firmware Operation Device type.
+*/
 
-#define DAC960_MajorNumber(ControllerNumber) \
-  (DAC960_MAJOR + (ControllerNumber))
+typedef enum
+{
+  DAC960_V2_Physical_Device =			0x00,
+  DAC960_V2_RAID_Device =			0x01,
+  DAC960_V2_Physical_Channel =			0x02,
+  DAC960_V2_RAID_Channel =			0x03,
+  DAC960_V2_Physical_Controller =		0x04,
+  DAC960_V2_RAID_Controller =			0x05,
+  DAC960_V2_Configuration_Group =		0x10
+}
+__attribute__ ((packed))
+DAC960_V2_OperationDevice_T;
 
-#define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
-   (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
 
-#define DAC960_MinorCount			(DAC960_MaxLogicalDrives \
-						 * DAC960_MaxPartitions)
+/*
+  Define the DAC960 V2 Firmware Translate Physical To Logical Device structure.
+*/
+
+typedef struct DAC960_V2_PhysicalToLogicalDevice
+{
+  unsigned short LogicalDeviceNumber;			/* Bytes 0-1 */
+  unsigned short :16;					/* Bytes 2-3 */
+  unsigned char PreviousBootController;			/* Byte 4 */
+  unsigned char PreviousBootChannel;			/* Byte 5 */
+  unsigned char PreviousBootTargetID;			/* Byte 6 */
+  unsigned char PreviousBootLogicalUnit;		/* Byte 7 */
+}
+DAC960_V2_PhysicalToLogicalDevice_T;
 
-#define DAC960_KernelDevice(ControllerNumber,				       \
-			    LogicalDriveNumber,				       \
-			    PartitionNumber)				       \
-   MKDEV(DAC960_MajorNumber(ControllerNumber),				       \
-	 DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
 
 
 /*
-  Define the DAC960 Controller fixed Block Size and Block Size Bits.
+  Define the DAC960 V2 Firmware Scatter/Gather List Entry structure.
 */
 
-#define DAC960_BlockSize			512
+typedef struct DAC960_V2_ScatterGatherSegment
+{
+  DAC960_BusAddress64_T SegmentDataPointer;		/* Bytes 0-7 */
+  DAC960_ByteCount64_T SegmentByteCount;		/* Bytes 8-15 */
+}
+DAC960_V2_ScatterGatherSegment_T;
+
+
+/*
+  Define the DAC960 V2 Firmware Data Transfer Memory Address structure.
+*/
+
+typedef union DAC960_V2_DataTransferMemoryAddress
+{
+  DAC960_V2_ScatterGatherSegment_T ScatterGatherSegments[2]; /* Bytes 0-31 */
+  struct {
+    unsigned short ScatterGatherList0Length;		/* Bytes 0-1 */
+    unsigned short ScatterGatherList1Length;		/* Bytes 2-3 */
+    unsigned short ScatterGatherList2Length;		/* Bytes 4-5 */
+    unsigned short :16;					/* Bytes 6-7 */
+    DAC960_BusAddress64_T ScatterGatherList0Address;	/* Bytes 8-15 */
+    DAC960_BusAddress64_T ScatterGatherList1Address;	/* Bytes 16-23 */
+    DAC960_BusAddress64_T ScatterGatherList2Address;	/* Bytes 24-31 */
+  } ExtendedScatterGather;
+}
+DAC960_V2_DataTransferMemoryAddress_T;
+
+
+/*
+  Define the 64 Byte DAC960 V2 Firmware Command Mailbox structure.
+*/
+
+typedef union DAC960_V2_CommandMailbox
+{
+  unsigned int Words[16];				/* Words 0-15 */
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned int :24;					/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } Common;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char CDBLength;				/* Byte 21 */
+    unsigned char SCSI_CDB[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } SCSI_10;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char CDBLength;				/* Byte 21 */
+    unsigned short :16;					/* Bytes 22-23 */
+    DAC960_BusAddress64_T SCSI_CDB_BusAddress;		/* Bytes 24-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } SCSI_255;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned short :16;					/* Bytes 16-17 */
+    unsigned char ControllerNumber;			/* Byte 18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } ControllerInfo;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } LogicalDeviceInfo;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char Reserved[10];				/* Bytes 22-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } PhysicalDeviceInfo;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned short EventSequenceNumberHigh16;		/* Bytes 16-17 */
+    unsigned char ControllerNumber;			/* Byte 18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned short EventSequenceNumberLow16;		/* Bytes 22-23 */
+    unsigned char Reserved[8];				/* Bytes 24-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } GetEvent;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    union {
+      DAC960_V2_LogicalDeviceState_T LogicalDeviceState;
+      DAC960_V2_PhysicalDeviceState_T PhysicalDeviceState;
+    } DeviceState;					/* Byte 22 */
+    unsigned char Reserved[9];				/* Bytes 23-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } SetDeviceState;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_LogicalDevice_T LogicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    boolean RestoreConsistency:1;			/* Byte 22 Bit 0 */
+    boolean InitializedAreaOnly:1;			/* Byte 22 Bit 1 */
+    unsigned char :6;					/* Byte 22 Bits 2-7 */
+    unsigned char Reserved[9];				/* Bytes 23-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } ConsistencyCheck;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    unsigned char FirstCommandMailboxSizeKB;		/* Byte 4 */
+    unsigned char FirstStatusMailboxSizeKB;		/* Byte 5 */
+    unsigned char SecondCommandMailboxSizeKB;		/* Byte 6 */
+    unsigned char SecondStatusMailboxSizeKB;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    unsigned int :24;					/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    unsigned char HealthStatusBufferSizeKB;		/* Byte 22 */
+    unsigned char :8;					/* Byte 23 */
+    DAC960_BusAddress64_T HealthStatusBufferBusAddress; /* Bytes 24-31 */
+    DAC960_BusAddress64_T FirstCommandMailboxBusAddress; /* Bytes 32-39 */
+    DAC960_BusAddress64_T FirstStatusMailboxBusAddress; /* Bytes 40-47 */
+    DAC960_BusAddress64_T SecondCommandMailboxBusAddress; /* Bytes 48-55 */
+    DAC960_BusAddress64_T SecondStatusMailboxBusAddress; /* Bytes 56-63 */
+  } SetMemoryMailbox;
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandOpcode_T CommandOpcode;		/* Byte 2 */
+    DAC960_V2_CommandControlBits_T CommandControlBits;	/* Byte 3 */
+    DAC960_ByteCount32_T DataTransferSize:24;		/* Bytes 4-6 */
+    unsigned char DataTransferPageNumber;		/* Byte 7 */
+    DAC960_BusAddress64_T RequestSenseBusAddress;	/* Bytes 8-15 */
+    DAC960_V2_PhysicalDevice_T PhysicalDevice;		/* Bytes 16-18 */
+    DAC960_V2_CommandTimeout_T CommandTimeout;		/* Byte 19 */
+    unsigned char RequestSenseSize;			/* Byte 20 */
+    unsigned char IOCTL_Opcode;				/* Byte 21 */
+    DAC960_V2_OperationDevice_T OperationDevice;	/* Byte 22 */
+    unsigned char Reserved[9];				/* Bytes 23-31 */
+    DAC960_V2_DataTransferMemoryAddress_T
+      DataTransferMemoryAddress;			/* Bytes 32-63 */
+  } DeviceOperation;
+}
+__attribute__ ((packed))
+DAC960_V2_CommandMailbox_T;
+
+
+/*
+  Define the DAC960 Driver IOCTL requests.
+*/
+
+#define DAC960_IOCTL_GET_CONTROLLER_COUNT	0xDAC001
+#define DAC960_IOCTL_GET_CONTROLLER_INFO	0xDAC002
+#define DAC960_IOCTL_V1_EXECUTE_COMMAND		0xDAC003
+#define DAC960_IOCTL_V2_EXECUTE_COMMAND		0xDAC004
+#define DAC960_IOCTL_V2_GET_HEALTH_STATUS	0xDAC005
+
+
+/*
+  Define the DAC960_IOCTL_GET_CONTROLLER_INFO reply structure.
+*/
+
+typedef struct DAC960_ControllerInfo
+{
+  unsigned char ControllerNumber;
+  unsigned char FirmwareType;
+  unsigned char Channels;
+  unsigned char Targets;
+  unsigned char PCI_Bus;
+  unsigned char PCI_Device;
+  unsigned char PCI_Function;
+  unsigned char IRQ_Channel;
+  DAC960_PCI_Address_T PCI_Address;
+  unsigned char ModelName[20];
+  unsigned char FirmwareVersion[12];
+}
+DAC960_ControllerInfo_T;
+
+
+/*
+  Define the User Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V1_UserCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V1_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  void *DataTransferBuffer;
+  DAC960_V1_DCDB_T *DCDB;
+}
+DAC960_V1_UserCommand_T;
+
+
+/*
+  Define the Kernel Mode DAC960_IOCTL_V1_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V1_KernelCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V1_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  void *DataTransferBuffer;
+  DAC960_V1_DCDB_T *DCDB;
+  DAC960_V1_CommandStatus_T CommandStatus;
+  void (*CompletionFunction)(struct DAC960_V1_KernelCommand *);
+  void *CompletionData;
+}
+DAC960_V1_KernelCommand_T;
+
+
+/*
+  Define the User Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V2_UserCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V2_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  int RequestSenseLength;
+  void *DataTransferBuffer;
+  void *RequestSenseBuffer;
+}
+DAC960_V2_UserCommand_T;
+
+
+/*
+  Define the Kernel Mode DAC960_IOCTL_V2_EXECUTE_COMMAND request structure.
+*/
+
+typedef struct DAC960_V2_KernelCommand
+{
+  unsigned char ControllerNumber;
+  DAC960_V2_CommandMailbox_T CommandMailbox;
+  int DataTransferLength;
+  int RequestSenseLength;
+  void *DataTransferBuffer;
+  void *RequestSenseBuffer;
+  DAC960_V2_CommandStatus_T CommandStatus;
+  void (*CompletionFunction)(struct DAC960_V2_KernelCommand *);
+  void *CompletionData;
+}
+DAC960_V2_KernelCommand_T;
+
+
+/*
+  Define the User Mode DAC960_IOCTL_V2_GET_HEALTH_STATUS request structure.
+*/
+
+typedef struct DAC960_V2_GetHealthStatus
+{
+  unsigned char ControllerNumber;
+  DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+}
+DAC960_V2_GetHealthStatus_T;
+
+
+/*
+  Import the Kernel Mode IOCTL interface.
+*/
+
+extern int DAC960_KernelIOCTL(unsigned int Request, void *Argument);
+
+
+/*
+  Virtual_to_Bus maps from Kernel Virtual Addresses to PCI Bus Addresses.
+*/
+
+static inline DAC960_BusAddress32_T Virtual_to_Bus(void *VirtualAddress)
+{
+  return (DAC960_BusAddress32_T) virt_to_bus(VirtualAddress);
+}
+
+
+/*
+  Bus_to_Virtual maps from PCI Bus Addresses to Kernel Virtual Addresses.
+*/
+
+static inline void *Bus_to_Virtual(DAC960_BusAddress32_T BusAddress)
+{
+  return (void *) bus_to_virt(BusAddress);
+}
+
+
+/*
+  DAC960_DriverVersion protects the private portion of this file.
+*/
+
+#ifdef DAC960_DriverVersion
+
+
+/*
+  Define the maximum Driver Queue Depth and Controller Queue Depth supported
+  by DAC960 V1 and V2 Firmware Controllers.
+*/
+
+#define DAC960_MaxDriverQueueDepth		511
+#define DAC960_MaxControllerQueueDepth		512
+
+
+/*
+  Define the maximum number of Scatter/Gather Segments supported for any
+  DAC960 V1 and V2 Firmware controller.
+*/
+
+#define DAC960_V1_ScatterGatherLimit		33
+#define DAC960_V2_ScatterGatherLimit		128
+
+
+/*
+  Define the number of Command Mailboxes and Status Mailboxes used by the
+  DAC960 V1 and V2 Firmware Memory Mailbox Interface.
+*/
+
+#define DAC960_V1_CommandMailboxCount		256
+#define DAC960_V1_StatusMailboxCount		1024
+#define DAC960_V2_CommandMailboxCount		512
+#define DAC960_V2_StatusMailboxCount		512
+
+
+/*
+  Define the DAC960 Controller Monitoring Timer Interval.
+*/
+
+#define DAC960_MonitoringTimerInterval		(10 * HZ)
+
+
+/*
+  Define the DAC960 Controller Secondary Monitoring Interval.
+*/
+
+#define DAC960_SecondaryMonitoringInterval	(60 * HZ)
+
+
+/*
+  Define the DAC960 Controller Health Status Monitoring Interval.
+*/
+
+#define DAC960_HealthStatusMonitoringInterval	(1 * HZ)
+
+
+/*
+  Define the DAC960 Controller Progress Reporting Interval.
+*/
+
+#define DAC960_ProgressReportingInterval	(60 * HZ)
+
+
+/*
+  Define the maximum number of Partitions allowed for each Logical Drive.
+*/
+
+#define DAC960_MaxPartitions			8
+#define DAC960_MaxPartitionsBits		3
+
+
+/*
+  Define macros to extract the Controller Number, Logical Drive Number, and
+  Partition Number from a Kernel Device, and to construct a Major Number, Minor
+  Number, and Kernel Device from the Controller Number, Logical Drive Number,
+  and Partition Number.  There is one Major Number assigned to each Controller.
+  The associated Minor Number is divided into the Logical Drive Number and
+  Partition Number.
+*/
+
+#define DAC960_ControllerNumber(Device) \
+  (MAJOR(Device) - DAC960_MAJOR)
+
+#define DAC960_LogicalDriveNumber(Device) \
+  (MINOR(Device) >> DAC960_MaxPartitionsBits)
+
+#define DAC960_PartitionNumber(Device) \
+  (MINOR(Device) & (DAC960_MaxPartitions - 1))
+
+#define DAC960_MajorNumber(ControllerNumber) \
+  (DAC960_MAJOR + (ControllerNumber))
+
+#define DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber) \
+   (((LogicalDriveNumber) << DAC960_MaxPartitionsBits) | (PartitionNumber))
+
+#define DAC960_MinorCount			(DAC960_MaxLogicalDrives \
+						 * DAC960_MaxPartitions)
+
+#define DAC960_KernelDevice(ControllerNumber,				       \
+			    LogicalDriveNumber,				       \
+			    PartitionNumber)				       \
+   MKDEV(DAC960_MajorNumber(ControllerNumber),				       \
+	 DAC960_MinorNumber(LogicalDriveNumber, PartitionNumber))
+
+
+/*
+  Define the DAC960 Controller fixed Block Size and Block Size Bits.
+*/
+
+#define DAC960_BlockSize			512
 #define DAC960_BlockSizeBits			9
 
 
 /*
-  Define the Controller Line Buffer, Status Buffer, Rebuild Progress,
-  and User Message Sizes.
+  Define the number of Command structures that should be allocated as a
+  group to optimize kernel memory allocation.
+*/
+
+#define DAC960_V1_CommandAllocationGroupSize	11
+#define DAC960_V2_CommandAllocationGroupSize	29
+
+
+/*
+  Define the Controller Line Buffer, Progress Buffer, User Message, and
+  Initial Status Buffer sizes.
 */
 
 #define DAC960_LineBufferSize			100
-#define DAC960_StatusBufferSize			16384
-#define DAC960_RebuildProgressSize		200
+#define DAC960_ProgressBufferSize		200
 #define DAC960_UserMessageSize			200
+#define DAC960_InitialStatusBufferSize		(8192-32)
+
+
+/*
+  Define the DAC960 Controller Firmware Types.
+*/
+
+typedef enum
+{
+  DAC960_V1_Controller =			1,
+  DAC960_V2_Controller =			2
+}
+DAC960_FirmwareType_T;
 
 
 /*
-  Define the types of DAC960 Controllers that are supported.
+  Define the DAC960 Controller Hardware Types.
 */
 
 typedef enum
 {
-  DAC960_V5_Controller =			1,	/* DAC1164P */
-  DAC960_V4_Controller =			2,	/* DAC960PTL/PJ/PG */
-  DAC960_V3_Controller =			3	/* DAC960PU/PD/PL */
+  DAC960_BA_Controller =			1,	/* eXtremeRAID 2000 */
+  DAC960_LP_Controller =			2,	/* AcceleRAID 352 */
+  DAC960_LA_Controller =			3,	/* DAC1164P */
+  DAC960_PG_Controller =			4,	/* DAC960PTL/PJ/PG */
+  DAC960_PD_Controller =			5	/* DAC960PU/PD/PL */
 }
-DAC960_ControllerType_T;
+DAC960_HardwareType_T;
 
 
 /*
@@ -1131,285 +2170,999 @@
 
 
 /*
-  Define the DAC960 Controller Status Mailbox structure.
+  Define the DAC960 V1 Firmware Controller Status Mailbox structure.
+*/
+
+typedef union DAC960_V1_StatusMailbox
+{
+  unsigned int Word;					/* Word 0 */
+  struct {
+    DAC960_V1_CommandIdentifier_T CommandIdentifier;	/* Byte 0 */
+    unsigned char :7;					/* Byte 1 Bits 0-6 */
+    boolean Valid:1;					/* Byte 1 Bit 7 */
+    DAC960_V1_CommandStatus_T CommandStatus;		/* Bytes 2-3 */
+  } Fields;
+}
+DAC960_V1_StatusMailbox_T;
+
+
+/*
+  Define the DAC960 V2 Firmware Controller Status Mailbox structure.
+*/
+
+typedef union DAC960_V2_StatusMailbox
+{
+  unsigned int Words[2];				/* Words 0-1 */
+  struct {
+    DAC960_V2_CommandIdentifier_T CommandIdentifier;	/* Bytes 0-1 */
+    DAC960_V2_CommandStatus_T CommandStatus;		/* Byte 2 */
+    unsigned char RequestSenseLength;			/* Byte 3 */
+    int DataTransferResidue;				/* Bytes 4-7 */
+  } Fields;
+}
+DAC960_V2_StatusMailbox_T;
+
+
+/*
+  Define the DAC960 Driver Command Types.
+*/
+
+typedef enum
+{
+  DAC960_ReadCommand =				1,
+  DAC960_WriteCommand =				2,
+  DAC960_ReadRetryCommand =			3,
+  DAC960_WriteRetryCommand =			4,
+  DAC960_MonitoringCommand =			5,
+  DAC960_ImmediateCommand =			6,
+  DAC960_QueuedCommand =			7
+}
+DAC960_CommandType_T;
+
+
+/*
+  Define the DAC960 Driver Command structure.
+*/
+
+typedef struct DAC960_Command
+{
+  int CommandIdentifier;
+  DAC960_CommandType_T CommandType;
+  struct DAC960_Controller *Controller;
+  struct DAC960_Command *Next;
+  Semaphore_T *Semaphore;
+  unsigned int LogicalDriveNumber;
+  unsigned int BlockNumber;
+  unsigned int BlockCount;
+  unsigned int SegmentCount;
+  BufferHeader_T *BufferHeader;
+  void *RequestBuffer;
+  union {
+    struct {
+      DAC960_V1_CommandMailbox_T CommandMailbox;
+      DAC960_V1_KernelCommand_T *KernelCommand;
+      DAC960_V1_CommandStatus_T CommandStatus;
+      DAC960_V1_ScatterGatherSegment_T
+	ScatterGatherList[DAC960_V1_ScatterGatherLimit]
+	__attribute__ ((aligned (sizeof(DAC960_V1_ScatterGatherSegment_T))));
+      unsigned int EndMarker[0];
+    } V1;
+    struct {
+      DAC960_V2_CommandMailbox_T CommandMailbox;
+      DAC960_V2_KernelCommand_T *KernelCommand;
+      DAC960_V2_CommandStatus_T CommandStatus;
+      unsigned char RequestSenseLength;
+      int DataTransferResidue;
+      DAC960_V2_ScatterGatherSegment_T
+	ScatterGatherList[DAC960_V2_ScatterGatherLimit]
+	__attribute__ ((aligned (sizeof(DAC960_V2_ScatterGatherSegment_T))));
+      DAC960_SCSI_RequestSense_T RequestSense
+	__attribute__ ((aligned (sizeof(int))));
+      unsigned int EndMarker[0];
+    } V2;
+  } FW;
+}
+DAC960_Command_T;
+
+
+/*
+  Define the DAC960 Driver Controller structure.
+*/
+
+typedef struct DAC960_Controller
+{
+  void *BaseAddress;
+  void *MemoryMappedAddress;
+  DAC960_FirmwareType_T FirmwareType;
+  DAC960_HardwareType_T HardwareType;
+  DAC960_IO_Address_T IO_Address;
+  DAC960_PCI_Address_T PCI_Address;
+  unsigned char ControllerNumber;
+  unsigned char ControllerName[4];
+  unsigned char ModelName[20];
+  unsigned char FullModelName[28];
+  unsigned char FirmwareVersion[12];
+  unsigned char Bus;
+  unsigned char Device;
+  unsigned char Function;
+  unsigned char IRQ_Channel;
+  unsigned char Channels;
+  unsigned char Targets;
+  unsigned char MemorySize;
+  unsigned char LogicalDriveCount;
+  unsigned short CommandAllocationGroupSize;
+  unsigned short ControllerQueueDepth;
+  unsigned short DriverQueueDepth;
+  unsigned short MaxBlocksPerCommand;
+  unsigned short ControllerScatterGatherLimit;
+  unsigned short DriverScatterGatherLimit;
+  unsigned int ControllerUsageCount;
+  unsigned int CombinedStatusBufferLength;
+  unsigned int InitialStatusLength;
+  unsigned int CurrentStatusLength;
+  unsigned int ProgressBufferLength;
+  unsigned int UserStatusLength;
+  unsigned long MemoryMailboxPagesAddress;
+  unsigned long MemoryMailboxPagesOrder;
+  unsigned long MonitoringTimerCount;
+  unsigned long PrimaryMonitoringTime;
+  unsigned long SecondaryMonitoringTime;
+  unsigned long LastProgressReportTime;
+  unsigned long LastCurrentStatusTime;
+  boolean ControllerDetectionSuccessful;
+  boolean ControllerInitialized;
+  boolean MonitoringCommandDeferred;
+  boolean EphemeralProgressMessage;
+  boolean DriveSpinUpMessageDisplayed;
+  boolean MonitoringAlertMode;
+  Timer_T MonitoringTimer;
+  GenericDiskInfo_T GenericDiskInfo;
+  DAC960_Command_T *FreeCommands;
+  unsigned char *CombinedStatusBuffer;
+  unsigned char *CurrentStatusBuffer;
+  PROC_DirectoryEntry_T ControllerProcEntry;
+  PROC_DirectoryEntry_T InitialStatusProcEntry;
+  PROC_DirectoryEntry_T CurrentStatusProcEntry;
+  PROC_DirectoryEntry_T UserCommandProcEntry;
+  WaitQueue_T *CommandWaitQueue;
+  WaitQueue_T *HealthStatusWaitQueue;
+  DAC960_Command_T InitialCommand;
+  DAC960_Command_T *Commands[DAC960_MaxDriverQueueDepth];
+  unsigned int LogicalDriveUsageCount[DAC960_MaxLogicalDrives];
+  boolean LogicalDriveInitiallyAccessible[DAC960_MaxLogicalDrives];
+  void (*QueueCommand)(DAC960_Command_T *Command);
+  boolean (*ReadControllerConfiguration)(struct DAC960_Controller *);
+  boolean (*ReadDeviceConfiguration)(struct DAC960_Controller *);
+  boolean (*ReportDeviceConfiguration)(struct DAC960_Controller *);
+  void (*QueueReadWriteCommand)(DAC960_Command_T *Command);
+  union {
+    struct {
+      unsigned char GeometryTranslationHeads;
+      unsigned char GeometryTranslationSectors;
+      unsigned char PendingRebuildFlag;
+      unsigned short StripeSize;
+      unsigned short SegmentSize;
+      unsigned short NewEventLogSequenceNumber;
+      unsigned short OldEventLogSequenceNumber;
+      unsigned short DeviceStateChannel;
+      unsigned short DeviceStateTargetID;
+      boolean DualModeMemoryMailboxInterface;
+      boolean SAFTE_EnclosureManagementEnabled;
+      boolean NeedLogicalDriveInformation;
+      boolean NeedErrorTableInformation;
+      boolean NeedDeviceStateInformation;
+      boolean NeedDeviceInquiryInformation;
+      boolean NeedDeviceSerialNumberInformation;
+      boolean NeedRebuildProgress;
+      boolean NeedConsistencyCheckProgress;
+      boolean RebuildProgressFirst;
+      boolean RebuildFlagPending;
+      boolean RebuildStatusPending;
+      DAC960_V1_CommandMailbox_T *FirstCommandMailbox;
+      DAC960_V1_CommandMailbox_T *LastCommandMailbox;
+      DAC960_V1_CommandMailbox_T *NextCommandMailbox;
+      DAC960_V1_CommandMailbox_T *PreviousCommandMailbox1;
+      DAC960_V1_CommandMailbox_T *PreviousCommandMailbox2;
+      DAC960_V1_StatusMailbox_T *FirstStatusMailbox;
+      DAC960_V1_StatusMailbox_T *LastStatusMailbox;
+      DAC960_V1_StatusMailbox_T *NextStatusMailbox;
+      DAC960_V1_DCDB_T MonitoringDCDB;
+      DAC960_V1_Enquiry_T Enquiry;
+      DAC960_V1_Enquiry_T NewEnquiry;
+      DAC960_V1_ErrorTable_T ErrorTable;
+      DAC960_V1_ErrorTable_T NewErrorTable;
+      DAC960_V1_EventLogEntry_T EventLogEntry;
+      DAC960_V1_RebuildProgress_T RebuildProgress;
+      DAC960_V1_CommandStatus_T LastRebuildStatus;
+      DAC960_V1_CommandStatus_T PendingRebuildStatus;
+      DAC960_V1_LogicalDriveInformationArray_T LogicalDriveInformation;
+      DAC960_V1_LogicalDriveInformationArray_T NewLogicalDriveInformation;
+      DAC960_V1_DeviceState_T
+	DeviceState[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      DAC960_V1_DeviceState_T NewDeviceState;
+      DAC960_SCSI_Inquiry_T
+	InquiryStandardData[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T
+	InquiryUnitSerialNumber[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      int DeviceResetCount[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+      boolean DirectCommandActive[DAC960_V1_MaxChannels][DAC960_V1_MaxTargets];
+    } V1;
+    struct {
+      unsigned int StatusChangeCounter;
+      unsigned int NextEventSequenceNumber;
+      unsigned int PhysicalDeviceIndex;
+      boolean NeedLogicalDeviceInformation;
+      boolean NeedPhysicalDeviceInformation;
+      boolean NeedDeviceSerialNumberInformation;
+      DAC960_V2_CommandMailbox_T *FirstCommandMailbox;
+      DAC960_V2_CommandMailbox_T *LastCommandMailbox;
+      DAC960_V2_CommandMailbox_T *NextCommandMailbox;
+      DAC960_V2_CommandMailbox_T *PreviousCommandMailbox1;
+      DAC960_V2_CommandMailbox_T *PreviousCommandMailbox2;
+      DAC960_V2_StatusMailbox_T *FirstStatusMailbox;
+      DAC960_V2_StatusMailbox_T *LastStatusMailbox;
+      DAC960_V2_StatusMailbox_T *NextStatusMailbox;
+      DAC960_V2_HealthStatusBuffer_T *HealthStatusBuffer;
+      DAC960_V2_ControllerInfo_T ControllerInformation;
+      DAC960_V2_ControllerInfo_T NewControllerInformation;
+      DAC960_V2_LogicalDeviceInfo_T
+	*LogicalDeviceInformation[DAC960_MaxLogicalDrives];
+      DAC960_V2_LogicalDeviceInfo_T NewLogicalDeviceInformation;
+      DAC960_V2_PhysicalDeviceInfo_T
+	*PhysicalDeviceInformation[DAC960_V2_MaxPhysicalDevices];
+      DAC960_V2_PhysicalDeviceInfo_T NewPhysicalDeviceInformation;
+      DAC960_SCSI_Inquiry_UnitSerialNumber_T
+	*InquiryUnitSerialNumber[DAC960_V2_MaxPhysicalDevices];
+      DAC960_V2_PhysicalDevice_T
+	LogicalDriveToVirtualDevice[DAC960_MaxLogicalDrives];
+      DAC960_V2_Event_T Event;
+    } V2;
+  } FW;
+  DiskPartition_T DiskPartitions[DAC960_MinorCount];
+  int PartitionSizes[DAC960_MinorCount];
+  int BlockSizes[DAC960_MinorCount];
+  int MaxSectorsPerRequest[DAC960_MinorCount];
+  int MaxSegmentsPerRequest[DAC960_MinorCount];
+  unsigned char ProgressBuffer[DAC960_ProgressBufferSize];
+  unsigned char UserStatusBuffer[DAC960_UserMessageSize];
+}
+DAC960_Controller_T;
+
+
+/*
+  Simplify access to Firmware Version Dependent Data Structure Components
+  and Functions.
+*/
+
+#define V1				FW.V1
+#define V2				FW.V2
+#define DAC960_QueueCommand(Command) \
+  (Controller->QueueCommand)(Command)
+#define DAC960_ReadControllerConfiguration(Controller) \
+  (Controller->ReadControllerConfiguration)(Controller)
+#define DAC960_ReadDeviceConfiguration(Controller) \
+  (Controller->ReadDeviceConfiguration)(Controller)
+#define DAC960_ReportDeviceConfiguration(Controller) \
+  (Controller->ReportDeviceConfiguration)(Controller)
+#define DAC960_QueueReadWriteCommand(Command) \
+  (Controller->QueueReadWriteCommand)(Command)
+
+
+/*
+  DAC960_AcquireControllerLock acquires exclusive access to Controller.
+*/
+
+static inline
+void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
+				  ProcessorFlags_T *ProcessorFlags)
+{
+  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  DAC960_ReleaseControllerLock releases exclusive access to Controller.
+*/
+
+static inline
+void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
+				  ProcessorFlags_T *ProcessorFlags)
+{
+  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
+  but is only called from the request function with the io_request_lock held.
+*/
+
+static inline
+void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+}
+
+
+/*
+  DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
+  but is only called from the request function with the io_request_lock held.
+*/
+
+static inline
+void DAC960_ReleaseControllerLockRF(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+}
+
+
+/*
+  DAC960_AcquireControllerLockIH acquires exclusive access to Controller,
+  but is only called from the interrupt handler.
+*/
+
+static inline
+void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  DAC960_ReleaseControllerLockIH releases exclusive access to Controller,
+  but is only called from the interrupt handler.
+*/
+
+static inline
+void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
+				    ProcessorFlags_T *ProcessorFlags)
+{
+  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+}
+
+
+/*
+  Define the DAC960 BA Series Controller Interface Register Offsets.
+*/
+
+#define DAC960_BA_RegisterWindowSize		0x80
+
+typedef enum
+{
+  DAC960_BA_InboundDoorBellRegisterOffset =	0x60,
+  DAC960_BA_OutboundDoorBellRegisterOffset =	0x61,
+  DAC960_BA_InterruptStatusRegisterOffset =	0x30,
+  DAC960_BA_InterruptMaskRegisterOffset =	0x34,
+  DAC960_BA_CommandMailboxBusAddressOffset =	0x50,
+  DAC960_BA_CommandStatusOffset =		0x58,
+  DAC960_BA_ErrorStatusRegisterOffset =		0x63
+}
+DAC960_BA_RegisterOffsets_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Inbound Door Bell Register.
+*/
+
+typedef union DAC960_BA_InboundDoorBellRegister
+{
+  unsigned char All;
+  struct {
+    boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
+    boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
+    boolean GenerateInterrupt:1;			/* Bit 2 */
+    boolean ControllerReset:1;				/* Bit 3 */
+    boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
+    unsigned char :3;					/* Bits 5-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxEmpty:1;			/* Bit 0 */
+    boolean InitializationNotInProgress:1;		/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
+}
+DAC960_BA_InboundDoorBellRegister_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Outbound Door Bell Register.
+*/
+
+typedef union DAC960_BA_OutboundDoorBellRegister
+{
+  unsigned char All;
+  struct {
+    boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
+    boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
+    boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
+}
+DAC960_BA_OutboundDoorBellRegister_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Interrupt Mask Register.
+*/
+
+typedef union DAC960_BA_InterruptMaskRegister
+{
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean DisableInterrupts:1;			/* Bit 2 */
+    boolean DisableInterruptsI2O:1;			/* Bit 3 */
+    unsigned int :4;					/* Bits 4-7 */
+  } Bits;
+}
+DAC960_BA_InterruptMaskRegister_T;
+
+
+/*
+  Define the structure of the DAC960 BA Series Error Status Register.
+*/
+
+typedef union DAC960_BA_ErrorStatusRegister
+{
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean ErrorStatusPending:1;			/* Bit 2 */
+    unsigned int :5;					/* Bits 3-7 */
+  } Bits;
+}
+DAC960_BA_ErrorStatusRegister_T;
+
+
+/*
+  Define inline functions to provide an abstraction for reading and writing the
+  DAC960 BA Series Controller Interface Registers.
+*/
+
+static inline
+void DAC960_BA_HardwareMailboxNewCommand(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_GenerateInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.GenerateInterrupt = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_ControllerReset(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.ControllerReset = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+}
+
+static inline
+boolean DAC960_BA_HardwareMailboxFullP(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+  return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
+}
+
+static inline
+boolean DAC960_BA_InitializationInProgressP(void *ControllerBaseAddress)
+{
+  DAC960_BA_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_InboundDoorBellRegisterOffset);
+  return !InboundDoorBellRegister.Read.InitializationNotInProgress;
+}
+
+static inline
+void DAC960_BA_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+}
+
+static inline
+void DAC960_BA_AcknowledgeInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+}
+
+static inline
+boolean DAC960_BA_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
+}
+
+static inline
+boolean DAC960_BA_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_BA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
+}
+
+static inline
+void DAC960_BA_EnableInterrupts(void *ControllerBaseAddress)
+{
+  DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = false;
+  InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
+}
+
+static inline
+void DAC960_BA_DisableInterrupts(void *ControllerBaseAddress)
+{
+  DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = true;
+  InterruptMaskRegister.Bits.DisableInterruptsI2O = true;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
+}
+
+static inline
+boolean DAC960_BA_InterruptsEnabledP(void *ControllerBaseAddress)
+{
+  DAC960_BA_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_InterruptMaskRegisterOffset);
+  return !InterruptMaskRegister.Bits.DisableInterrupts;
+}
+
+static inline
+void DAC960_BA_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V2_CommandMailbox_T
+				     *CommandMailbox)
+{
+  memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
+	 sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
+  wmb();
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  mb();
+}
+
+static inline
+void DAC960_BA_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V2_CommandMailbox_T *CommandMailbox)
+{
+  writel(Virtual_to_Bus(CommandMailbox),
+	 ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset);
+}
+
+static inline DAC960_V2_CommandIdentifier_T
+DAC960_BA_ReadCommandIdentifier(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset);
+}
+
+static inline DAC960_V2_CommandStatus_T
+DAC960_BA_ReadCommandStatus(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_BA_CommandStatusOffset + 2);
+}
+
+static inline boolean
+DAC960_BA_ReadErrorStatus(void *ControllerBaseAddress,
+			  unsigned char *ErrorStatus,
+			  unsigned char *Parameter0,
+			  unsigned char *Parameter1)
+{
+  DAC960_BA_ErrorStatusRegister_T ErrorStatusRegister;
+  ErrorStatusRegister.All =
+    readb(ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
+  if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
+  ErrorStatusRegister.Bits.ErrorStatusPending = false;
+  *ErrorStatus = ErrorStatusRegister.All;
+  *Parameter0 =
+    readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 0);
+  *Parameter1 =
+    readb(ControllerBaseAddress + DAC960_BA_CommandMailboxBusAddressOffset + 1);
+  writeb(0xFF, ControllerBaseAddress + DAC960_BA_ErrorStatusRegisterOffset);
+  return true;
+}
+
+
+/*
+  Define the DAC960 LP Series Controller Interface Register Offsets.
+*/
+
+#define DAC960_LP_RegisterWindowSize		0x80
+
+typedef enum
+{
+  DAC960_LP_InboundDoorBellRegisterOffset =	0x20,
+  DAC960_LP_OutboundDoorBellRegisterOffset =	0x2C,
+  DAC960_LP_InterruptStatusRegisterOffset =	0x30,
+  DAC960_LP_InterruptMaskRegisterOffset =	0x34,
+  DAC960_LP_CommandMailboxBusAddressOffset =	0x10,
+  DAC960_LP_CommandStatusOffset =		0x18,
+  DAC960_LP_ErrorStatusRegisterOffset =		0x2E
+}
+DAC960_LP_RegisterOffsets_T;
+
+
+/*
+  Define the structure of the DAC960 LP Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_StatusMailbox
+typedef union DAC960_LP_InboundDoorBellRegister
 {
-  unsigned int Word;					/* Bytes 0-3 */
+  unsigned char All;
   struct {
-    DAC960_CommandIdentifier_T CommandIdentifier;	/* Byte 0 */
-    unsigned char :7;					/* Byte 1 Bits 0-6 */
-    boolean Valid:1;					/* Byte 1 Bit 7 */
-    DAC960_CommandStatus_T CommandStatus;		/* Bytes 2-3 */
-  } Fields;
+    boolean HardwareMailboxNewCommand:1;		/* Bit 0 */
+    boolean AcknowledgeHardwareMailboxStatus:1;		/* Bit 1 */
+    boolean GenerateInterrupt:1;			/* Bit 2 */
+    boolean ControllerReset:1;				/* Bit 3 */
+    boolean MemoryMailboxNewCommand:1;			/* Bit 4 */
+    unsigned char :3;					/* Bits 5-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxFull:1;			/* Bit 0 */
+    boolean InitializationInProgress:1;			/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
 }
-DAC960_StatusMailbox_T;
+DAC960_LP_InboundDoorBellRegister_T;
 
 
 /*
-  Define the DAC960 Driver Command Types.
+  Define the structure of the DAC960 LP Series Outbound Door Bell Register.
 */
 
-typedef enum
+typedef union DAC960_LP_OutboundDoorBellRegister
 {
-  DAC960_ReadCommand =				1,
-  DAC960_WriteCommand =				2,
-  DAC960_ReadRetryCommand =			3,
-  DAC960_WriteRetryCommand =			4,
-  DAC960_MonitoringCommand =			5,
-  DAC960_ImmediateCommand =			6,
-  DAC960_QueuedCommand =			7
+  unsigned char All;
+  struct {
+    boolean AcknowledgeHardwareMailboxInterrupt:1;	/* Bit 0 */
+    boolean AcknowledgeMemoryMailboxInterrupt:1;	/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Write;
+  struct {
+    boolean HardwareMailboxStatusAvailable:1;		/* Bit 0 */
+    boolean MemoryMailboxStatusAvailable:1;		/* Bit 1 */
+    unsigned char :6;					/* Bits 2-7 */
+  } Read;
 }
-DAC960_CommandType_T;
+DAC960_LP_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the DAC960 Driver Command structure.
+  Define the structure of the DAC960 LP Series Interrupt Mask Register.
 */
 
-typedef struct DAC960_Command
+typedef union DAC960_LP_InterruptMaskRegister
 {
-  DAC960_CommandType_T CommandType;
-  DAC960_CommandMailbox_T CommandMailbox;
-  DAC960_CommandStatus_T CommandStatus;
-  struct DAC960_Controller *Controller;
-  struct DAC960_Command *Next;
-  Semaphore_T *Semaphore;
-  unsigned int LogicalDriveNumber;
-  unsigned int BlockNumber;
-  unsigned int BlockCount;
-  unsigned int SegmentCount;
-  BufferHeader_T *BufferHeader;
-  DAC960_KernelCommand_T *KernelCommand;
-  DAC960_ScatterGatherSegment_T
-    ScatterGatherList[DAC960_MaxScatterGatherSegments];
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean DisableInterrupts:1;			/* Bit 2 */
+    unsigned int :5;					/* Bits 3-7 */
+  } Bits;
 }
-DAC960_Command_T;
+DAC960_LP_InterruptMaskRegister_T;
 
 
 /*
-  Define the DAC960 Driver Controller structure.
+  Define the structure of the DAC960 LP Series Error Status Register.
 */
 
-typedef struct DAC960_Controller
+typedef union DAC960_LP_ErrorStatusRegister
 {
-  void *BaseAddress;
-  void *MemoryMappedAddress;
-  DAC960_ControllerType_T ControllerType;
-  DAC960_IO_Address_T IO_Address;
-  DAC960_PCI_Address_T PCI_Address;
-  unsigned char ControllerNumber;
-  unsigned char ControllerName[4];
-  unsigned char ModelName[12];
-  unsigned char FullModelName[18];
-  unsigned char FirmwareVersion[14];
-  unsigned char Bus;
-  unsigned char Device;
-  unsigned char Function;
-  unsigned char IRQ_Channel;
-  unsigned char Channels;
-  unsigned char MemorySize;
-  unsigned char LogicalDriveCount;
-  unsigned char GeometryTranslationHeads;
-  unsigned char GeometryTranslationSectors;
-  unsigned char PendingRebuildFlag;
-  unsigned short ControllerQueueDepth;
-  unsigned short DriverQueueDepth;
-  unsigned short MaxBlocksPerCommand;
-  unsigned short MaxScatterGatherSegments;
-  unsigned short StripeSize;
-  unsigned short SegmentSize;
-  unsigned short NewEventLogSequenceNumber;
-  unsigned short OldEventLogSequenceNumber;
-  unsigned short InitialStatusLength;
-  unsigned short CurrentStatusLength;
-  unsigned short UserStatusLength;
-  unsigned short RebuildProgressLength;
-  unsigned int ControllerUsageCount;
-  unsigned int EnquiryIndex;
-  unsigned int LogicalDriveInformationIndex;
-  unsigned int ErrorTableIndex;
-  unsigned int DeviceStateIndex;
-  unsigned int DeviceStateChannel;
-  unsigned int DeviceStateTargetID;
-  unsigned long MonitoringTimerCount;
-  unsigned long SecondaryMonitoringTime;
-  unsigned long LastProgressReportTime;
-  unsigned long LastCurrentStatusTime;
-  boolean DualModeMemoryMailboxInterface;
-  boolean SAFTE_EnclosureManagementEnabled;
-  boolean ControllerInitialized;
-  boolean MonitoringCommandDeferred;
-  boolean NeedLogicalDriveInformation;
-  boolean NeedErrorTableInformation;
-  boolean NeedDeviceStateInformation;
-  boolean NeedDeviceInquiryInformation;
-  boolean NeedDeviceSerialNumberInformation;
-  boolean NeedRebuildProgress;
-  boolean NeedConsistencyCheckProgress;
-  boolean EphemeralProgressMessage;
-  boolean RebuildFlagPending;
-  boolean RebuildStatusPending;
-  boolean DriveSpinUpMessageDisplayed;
-  Timer_T MonitoringTimer;
-  GenericDiskInfo_T GenericDiskInfo;
-  DAC960_Command_T *FreeCommands;
-  DAC960_CommandMailbox_T *FirstCommandMailbox;
-  DAC960_CommandMailbox_T *LastCommandMailbox;
-  DAC960_CommandMailbox_T *NextCommandMailbox;
-  DAC960_CommandMailbox_T *PreviousCommandMailbox1;
-  DAC960_CommandMailbox_T *PreviousCommandMailbox2;
-  DAC960_StatusMailbox_T *FirstStatusMailbox;
-  DAC960_StatusMailbox_T *LastStatusMailbox;
-  DAC960_StatusMailbox_T *NextStatusMailbox;
-  PROC_DirectoryEntry_T ControllerProcEntry;
-  PROC_DirectoryEntry_T InitialStatusProcEntry;
-  PROC_DirectoryEntry_T CurrentStatusProcEntry;
-  PROC_DirectoryEntry_T UserCommandProcEntry;
-  WaitQueue_T *CommandWaitQueue;
-  DAC960_DCDB_T MonitoringDCDB;
-  DAC960_Enquiry_T Enquiry[2];
-  DAC960_ErrorTable_T ErrorTable[2];
-  DAC960_EventLogEntry_T EventLogEntry;
-  DAC960_RebuildProgress_T RebuildProgress;
-  DAC960_CommandStatus_T LastRebuildStatus;
-  DAC960_CommandStatus_T PendingRebuildStatus;
-  DAC960_LogicalDriveInformation_T
-    LogicalDriveInformation[2][DAC960_MaxLogicalDrives];
-  DAC960_LogicalDriveState_T LogicalDriveInitialState[DAC960_MaxLogicalDrives];
-  DAC960_DeviceState_T DeviceState[2][DAC960_MaxChannels][DAC960_MaxTargets];
-  DAC960_Command_T Commands[DAC960_MaxDriverQueueDepth];
-  DAC960_SCSI_Inquiry_T
-    InquiryStandardData[DAC960_MaxChannels][DAC960_MaxTargets];
-  DAC960_SCSI_Inquiry_UnitSerialNumber_T
-    InquiryUnitSerialNumber[DAC960_MaxChannels][DAC960_MaxTargets];
-  DiskPartition_T DiskPartitions[DAC960_MinorCount];
-  int LogicalDriveUsageCount[DAC960_MaxLogicalDrives];
-  int PartitionSizes[DAC960_MinorCount];
-  int BlockSizes[DAC960_MinorCount];
-  int MaxSectorsPerRequest[DAC960_MinorCount];
-  int MaxSegmentsPerRequest[DAC960_MinorCount];
-  int DeviceResetCount[DAC960_MaxChannels][DAC960_MaxTargets];
-  boolean DirectCommandActive[DAC960_MaxChannels][DAC960_MaxTargets];
-  char InitialStatusBuffer[DAC960_StatusBufferSize];
-  char CurrentStatusBuffer[DAC960_StatusBufferSize];
-  char UserStatusBuffer[DAC960_UserMessageSize];
-  char RebuildProgressBuffer[DAC960_RebuildProgressSize];
+  unsigned char All;
+  struct {
+    unsigned int :2;					/* Bits 0-1 */
+    boolean ErrorStatusPending:1;			/* Bit 2 */
+    unsigned int :5;					/* Bits 3-7 */
+  } Bits;
 }
-DAC960_Controller_T;
+DAC960_LP_ErrorStatusRegister_T;
 
 
 /*
-  DAC960_AcquireControllerLock acquires exclusive access to Controller.
+  Define inline functions to provide an abstraction for reading and writing the
+  DAC960 LP Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_AcquireControllerLock(DAC960_Controller_T *Controller,
-				  ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_HardwareMailboxNewCommand(void *ControllerBaseAddress)
 {
-  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
 }
 
+static inline
+void DAC960_LP_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+}
 
-/*
-  DAC960_ReleaseControllerLock releases exclusive access to Controller.
-*/
+static inline
+void DAC960_LP_GenerateInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.GenerateInterrupt = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+}
 
 static inline
-void DAC960_ReleaseControllerLock(DAC960_Controller_T *Controller,
-				  ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_ControllerReset(void *ControllerBaseAddress)
 {
-  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.ControllerReset = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
 }
 
+static inline
+void DAC960_LP_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All = 0;
+  InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
+  writeb(InboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+}
 
-/*
-  DAC960_AcquireControllerLockRF acquires exclusive access to Controller,
-  but is only called from the request function with the io_request_lock held.
-*/
+static inline
+boolean DAC960_LP_HardwareMailboxFullP(void *ControllerBaseAddress)
+{
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+  return InboundDoorBellRegister.Read.HardwareMailboxFull;
+}
 
 static inline
-void DAC960_AcquireControllerLockRF(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+boolean DAC960_LP_InitializationInProgressP(void *ControllerBaseAddress)
 {
+  DAC960_LP_InboundDoorBellRegister_T InboundDoorBellRegister;
+  InboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_InboundDoorBellRegisterOffset);
+  return InboundDoorBellRegister.Read.InitializationInProgress;
 }
 
+static inline
+void DAC960_LP_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+}
 
-/*
-  DAC960_ReleaseControllerLockRF releases exclusive access to Controller,
-  but is only called from the request function with the io_request_lock held.
-*/
+static inline
+void DAC960_LP_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+}
 
 static inline
-void DAC960_ReleaseControllerLockRF(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All = 0;
+  OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
+  OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
+  writeb(OutboundDoorBellRegister.All,
+	 ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
 }
 
+static inline
+boolean DAC960_LP_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
+}
 
-/*
-  DAC960_AcquireControllerLockIH acquires exclusive access to Controller,
-  but is only called from the interrupt handler.
-*/
+static inline
+boolean DAC960_LP_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+{
+  DAC960_LP_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  OutboundDoorBellRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_OutboundDoorBellRegisterOffset);
+  return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
+}
 
 static inline
-void DAC960_AcquireControllerLockIH(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_EnableInterrupts(void *ControllerBaseAddress)
 {
-  spin_lock_irqsave(&io_request_lock, *ProcessorFlags);
+  DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = false;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
 }
 
+static inline
+void DAC960_LP_DisableInterrupts(void *ControllerBaseAddress)
+{
+  DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All = 0xFF;
+  InterruptMaskRegister.Bits.DisableInterrupts = true;
+  writeb(InterruptMaskRegister.All,
+	 ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
+}
 
-/*
-  DAC960_ReleaseControllerLockIH releases exclusive access to Controller,
-  but is only called from the interrupt handler.
-*/
+static inline
+boolean DAC960_LP_InterruptsEnabledP(void *ControllerBaseAddress)
+{
+  DAC960_LP_InterruptMaskRegister_T InterruptMaskRegister;
+  InterruptMaskRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_InterruptMaskRegisterOffset);
+  return !InterruptMaskRegister.Bits.DisableInterrupts;
+}
 
 static inline
-void DAC960_ReleaseControllerLockIH(DAC960_Controller_T *Controller,
-				    ProcessorFlags_T *ProcessorFlags)
+void DAC960_LP_WriteCommandMailbox(DAC960_V2_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V2_CommandMailbox_T
+				     *CommandMailbox)
 {
-  spin_unlock_irqrestore(&io_request_lock, *ProcessorFlags);
+  memcpy(&MemoryCommandMailbox->Words[1], &CommandMailbox->Words[1],
+	 sizeof(DAC960_V2_CommandMailbox_T) - sizeof(unsigned int));
+  wmb();
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  mb();
+}
+
+static inline
+void DAC960_LP_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V2_CommandMailbox_T *CommandMailbox)
+{
+  writel(Virtual_to_Bus(CommandMailbox),
+	 ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset);
+}
+
+static inline DAC960_V2_CommandIdentifier_T
+DAC960_LP_ReadCommandIdentifier(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset);
+}
+
+static inline DAC960_V2_CommandStatus_T
+DAC960_LP_ReadCommandStatus(void *ControllerBaseAddress)
+{
+  return readw(ControllerBaseAddress + DAC960_LP_CommandStatusOffset + 2);
+}
+
+static inline boolean
+DAC960_LP_ReadErrorStatus(void *ControllerBaseAddress,
+			  unsigned char *ErrorStatus,
+			  unsigned char *Parameter0,
+			  unsigned char *Parameter1)
+{
+  DAC960_LP_ErrorStatusRegister_T ErrorStatusRegister;
+  ErrorStatusRegister.All =
+    readb(ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
+  if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
+  ErrorStatusRegister.Bits.ErrorStatusPending = false;
+  *ErrorStatus = ErrorStatusRegister.All;
+  *Parameter0 =
+    readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 0);
+  *Parameter1 =
+    readb(ControllerBaseAddress + DAC960_LP_CommandMailboxBusAddressOffset + 1);
+  writeb(0xFF, ControllerBaseAddress + DAC960_LP_ErrorStatusRegisterOffset);
+  return true;
 }
 
 
 /*
-  Define the DAC960 V5 Controller Interface Register Offsets.
+  Define the DAC960 LA Series Controller Interface Register Offsets.
 */
 
-#define DAC960_V5_RegisterWindowSize		0x80
+#define DAC960_LA_RegisterWindowSize		0x80
 
 typedef enum
 {
-  DAC960_V5_InboundDoorBellRegisterOffset =	0x60,
-  DAC960_V5_OutboundDoorBellRegisterOffset =	0x61,
-  DAC960_V5_InterruptMaskRegisterOffset =	0x34,
-  DAC960_V5_CommandOpcodeRegisterOffset =	0x50,
-  DAC960_V5_CommandIdentifierRegisterOffset =	0x51,
-  DAC960_V5_MailboxRegister2Offset =		0x52,
-  DAC960_V5_MailboxRegister3Offset =		0x53,
-  DAC960_V5_MailboxRegister4Offset =		0x54,
-  DAC960_V5_MailboxRegister5Offset =		0x55,
-  DAC960_V5_MailboxRegister6Offset =		0x56,
-  DAC960_V5_MailboxRegister7Offset =		0x57,
-  DAC960_V5_MailboxRegister8Offset =		0x58,
-  DAC960_V5_MailboxRegister9Offset =		0x59,
-  DAC960_V5_MailboxRegister10Offset =		0x5A,
-  DAC960_V5_MailboxRegister11Offset =		0x5B,
-  DAC960_V5_MailboxRegister12Offset =		0x5C,
-  DAC960_V5_StatusCommandIdentifierRegOffset =	0x5D,
-  DAC960_V5_StatusRegisterOffset =		0x5E,
-  DAC960_V5_ErrorStatusRegisterOffset =		0x63
+  DAC960_LA_InboundDoorBellRegisterOffset =	0x60,
+  DAC960_LA_OutboundDoorBellRegisterOffset =	0x61,
+  DAC960_LA_InterruptMaskRegisterOffset =	0x34,
+  DAC960_LA_CommandOpcodeRegisterOffset =	0x50,
+  DAC960_LA_CommandIdentifierRegisterOffset =	0x51,
+  DAC960_LA_MailboxRegister2Offset =		0x52,
+  DAC960_LA_MailboxRegister3Offset =		0x53,
+  DAC960_LA_MailboxRegister4Offset =		0x54,
+  DAC960_LA_MailboxRegister5Offset =		0x55,
+  DAC960_LA_MailboxRegister6Offset =		0x56,
+  DAC960_LA_MailboxRegister7Offset =		0x57,
+  DAC960_LA_MailboxRegister8Offset =		0x58,
+  DAC960_LA_MailboxRegister9Offset =		0x59,
+  DAC960_LA_MailboxRegister10Offset =		0x5A,
+  DAC960_LA_MailboxRegister11Offset =		0x5B,
+  DAC960_LA_MailboxRegister12Offset =		0x5C,
+  DAC960_LA_StatusCommandIdentifierRegOffset =	0x5D,
+  DAC960_LA_StatusRegisterOffset =		0x5E,
+  DAC960_LA_ErrorStatusRegisterOffset =		0x63
 }
-DAC960_V5_RegisterOffsets_T;
+DAC960_LA_RegisterOffsets_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Inbound Door Bell Register.
+  Define the structure of the DAC960 LA Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_V5_InboundDoorBellRegister
+typedef union DAC960_LA_InboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -1426,14 +3179,14 @@
     unsigned char :6;					/* Bits 2-7 */
   } Read;
 }
-DAC960_V5_InboundDoorBellRegister_T;
+DAC960_LA_InboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Outbound Door Bell Register.
+  Define the structure of the DAC960 LA Series Outbound Door Bell Register.
 */
 
-typedef union DAC960_V5_OutboundDoorBellRegister
+typedef union DAC960_LA_OutboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -1447,14 +3200,14 @@
     unsigned char :6;					/* Bits 2-7 */
   } Read;
 }
-DAC960_V5_OutboundDoorBellRegister_T;
+DAC960_LA_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Interrupt Mask Register.
+  Define the structure of the DAC960 LA Series Interrupt Mask Register.
 */
 
-typedef union DAC960_V5_InterruptMaskRegister
+typedef union DAC960_LA_InterruptMaskRegister
 {
   unsigned char All;
   struct {
@@ -1463,14 +3216,14 @@
     unsigned char :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V5_InterruptMaskRegister_T;
+DAC960_LA_InterruptMaskRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V5 Error Status Register.
+  Define the structure of the DAC960 LA Series Error Status Register.
 */
 
-typedef union DAC960_V5_ErrorStatusRegister
+typedef union DAC960_LA_ErrorStatusRegister
 {
   unsigned char All;
   struct {
@@ -1479,288 +3232,294 @@
     unsigned int :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V5_ErrorStatusRegister_T;
+DAC960_LA_ErrorStatusRegister_T;
 
 
 /*
   Define inline functions to provide an abstraction for reading and writing the
-  DAC960 V5 Controller Interface Registers.
+  DAC960 LA Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_V5_HardwareMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_LA_HardwareMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_GenerateInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_GenerateInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.GenerateInterrupt = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_ControllerReset(void *ControllerBaseAddress)
+void DAC960_LA_ControllerReset(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.ControllerReset = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_LA_MemoryMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V5_HardwareMailboxFullP(void *ControllerBaseAddress)
+boolean DAC960_LA_HardwareMailboxFullP(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
   return !InboundDoorBellRegister.Read.HardwareMailboxEmpty;
 }
 
 static inline
-boolean DAC960_V5_InitializationInProgressP(void *ControllerBaseAddress)
+boolean DAC960_LA_InitializationInProgressP(void *ControllerBaseAddress)
 {
-  DAC960_V5_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_LA_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_InboundDoorBellRegisterOffset);
   return !InboundDoorBellRegister.Read.InitializationNotInProgress;
 }
 
 static inline
-void DAC960_V5_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V5_AcknowledgeInterrupt(void *ControllerBaseAddress)
+void DAC960_LA_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V5_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_LA_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
 }
 
 static inline
-boolean DAC960_V5_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_LA_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V5_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_LA_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_OutboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
 }
 
 static inline
-void DAC960_V5_EnableInterrupts(void *ControllerBaseAddress)
+void DAC960_LA_EnableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0xFF;
   InterruptMaskRegister.Bits.DisableInterrupts = false;
   writeb(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
 }
 
 static inline
-void DAC960_V5_DisableInterrupts(void *ControllerBaseAddress)
+void DAC960_LA_DisableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0xFF;
   InterruptMaskRegister.Bits.DisableInterrupts = true;
   writeb(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
 }
 
 static inline
-boolean DAC960_V5_InterruptsEnabledP(void *ControllerBaseAddress)
+boolean DAC960_LA_InterruptsEnabledP(void *ControllerBaseAddress)
 {
-  DAC960_V5_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_LA_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_InterruptMaskRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_InterruptMaskRegisterOffset);
   return !InterruptMaskRegister.Bits.DisableInterrupts;
 }
 
 static inline
-void DAC960_V5_WriteCommandMailbox(DAC960_CommandMailbox_T *NextCommandMailbox,
-				   DAC960_CommandMailbox_T *CommandMailbox)
-{
-  NextCommandMailbox->Words[1] = CommandMailbox->Words[1];
-  NextCommandMailbox->Words[2] = CommandMailbox->Words[2];
-  NextCommandMailbox->Words[3] = CommandMailbox->Words[3];
+void DAC960_LA_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V1_CommandMailbox_T
+				     *CommandMailbox)
+{
+  MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
+  MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
+  MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
   wmb();
-  NextCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
   mb();
 }
 
 static inline
-void DAC960_V5_WriteHardwareMailbox(void *ControllerBaseAddress,
-				    DAC960_CommandMailbox_T *CommandMailbox)
+void DAC960_LA_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V1_CommandMailbox_T *CommandMailbox)
 {
   writel(CommandMailbox->Words[0],
-	 ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
+	 ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
   writel(CommandMailbox->Words[1],
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
   writel(CommandMailbox->Words[2],
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
   writeb(CommandMailbox->Bytes[12],
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister12Offset);
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister12Offset);
 }
 
-static inline DAC960_CommandIdentifier_T
-DAC960_V5_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandIdentifier_T
+DAC960_LA_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
 {
   return readb(ControllerBaseAddress
-	       + DAC960_V5_StatusCommandIdentifierRegOffset);
+	       + DAC960_LA_StatusCommandIdentifierRegOffset);
 }
 
-static inline DAC960_CommandStatus_T
-DAC960_V5_ReadStatusRegister(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandStatus_T
+DAC960_LA_ReadStatusRegister(void *ControllerBaseAddress)
 {
-  return readw(ControllerBaseAddress + DAC960_V5_StatusRegisterOffset);
+  return readw(ControllerBaseAddress + DAC960_LA_StatusRegisterOffset);
 }
 
 static inline boolean
-DAC960_V5_ReadErrorStatus(void *ControllerBaseAddress,
+DAC960_LA_ReadErrorStatus(void *ControllerBaseAddress,
 			  unsigned char *ErrorStatus,
 			  unsigned char *Parameter0,
 			  unsigned char *Parameter1)
 {
-  DAC960_V5_ErrorStatusRegister_T ErrorStatusRegister;
+  DAC960_LA_ErrorStatusRegister_T ErrorStatusRegister;
   ErrorStatusRegister.All =
-    readb(ControllerBaseAddress + DAC960_V5_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
   ErrorStatusRegister.Bits.ErrorStatusPending = false;
   *ErrorStatus = ErrorStatusRegister.All;
   *Parameter0 =
-    readb(ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
   *Parameter1 =
-    readb(ControllerBaseAddress + DAC960_V5_CommandIdentifierRegisterOffset);
-  writeb(0xFF, ControllerBaseAddress + DAC960_V5_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_LA_CommandIdentifierRegisterOffset);
+  writeb(0xFF, ControllerBaseAddress + DAC960_LA_ErrorStatusRegisterOffset);
   return true;
 }
 
 static inline
-void DAC960_V5_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
+void DAC960_LA_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   writel(0x743C485E,
-	 ControllerBaseAddress + DAC960_V5_CommandOpcodeRegisterOffset);
-  writel((unsigned long) Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
-  writew(Controller->NextCommandMailbox - Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
-  writew(Controller->NextStatusMailbox - Controller->FirstStatusMailbox,
-	 ControllerBaseAddress + DAC960_V5_MailboxRegister10Offset);
+	 ControllerBaseAddress + DAC960_LA_CommandOpcodeRegisterOffset);
+  writel((unsigned long) Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
+  writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
+  writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
+	 ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
+#endif
 }
 
 static inline
-void DAC960_V5_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
+void DAC960_LA_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
 					void **MemoryMailboxAddress,
 					short *NextCommandMailboxIndex,
 					short *NextStatusMailboxIndex)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   if (readl(ControllerBaseAddress
-	    + DAC960_V5_CommandOpcodeRegisterOffset) != 0x743C485E)
+	    + DAC960_LA_CommandOpcodeRegisterOffset) != 0x743C485E)
     return;
   *MemoryMailboxAddress =
-    (void *) readl(ControllerBaseAddress + DAC960_V5_MailboxRegister4Offset);
+    (void *) readl(ControllerBaseAddress + DAC960_LA_MailboxRegister4Offset);
   *NextCommandMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V5_MailboxRegister8Offset);
+    readw(ControllerBaseAddress + DAC960_LA_MailboxRegister8Offset);
   *NextStatusMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V5_MailboxRegister10Offset);
+    readw(ControllerBaseAddress + DAC960_LA_MailboxRegister10Offset);
+#endif
 }
 
 
 /*
-  Define the DAC960 V4 Controller Interface Register Offsets.
+  Define the DAC960 PG Series Controller Interface Register Offsets.
 */
 
-#define DAC960_V4_RegisterWindowSize		0x2000
+#define DAC960_PG_RegisterWindowSize		0x2000
 
 typedef enum
 {
-  DAC960_V4_InboundDoorBellRegisterOffset =	0x0020,
-  DAC960_V4_OutboundDoorBellRegisterOffset =	0x002C,
-  DAC960_V4_InterruptMaskRegisterOffset =	0x0034,
-  DAC960_V4_CommandOpcodeRegisterOffset =	0x1000,
-  DAC960_V4_CommandIdentifierRegisterOffset =	0x1001,
-  DAC960_V4_MailboxRegister2Offset =		0x1002,
-  DAC960_V4_MailboxRegister3Offset =		0x1003,
-  DAC960_V4_MailboxRegister4Offset =		0x1004,
-  DAC960_V4_MailboxRegister5Offset =		0x1005,
-  DAC960_V4_MailboxRegister6Offset =		0x1006,
-  DAC960_V4_MailboxRegister7Offset =		0x1007,
-  DAC960_V4_MailboxRegister8Offset =		0x1008,
-  DAC960_V4_MailboxRegister9Offset =		0x1009,
-  DAC960_V4_MailboxRegister10Offset =		0x100A,
-  DAC960_V4_MailboxRegister11Offset =		0x100B,
-  DAC960_V4_MailboxRegister12Offset =		0x100C,
-  DAC960_V4_StatusCommandIdentifierRegOffset =	0x1018,
-  DAC960_V4_StatusRegisterOffset =		0x101A,
-  DAC960_V4_ErrorStatusRegisterOffset =		0x103F
+  DAC960_PG_InboundDoorBellRegisterOffset =	0x0020,
+  DAC960_PG_OutboundDoorBellRegisterOffset =	0x002C,
+  DAC960_PG_InterruptMaskRegisterOffset =	0x0034,
+  DAC960_PG_CommandOpcodeRegisterOffset =	0x1000,
+  DAC960_PG_CommandIdentifierRegisterOffset =	0x1001,
+  DAC960_PG_MailboxRegister2Offset =		0x1002,
+  DAC960_PG_MailboxRegister3Offset =		0x1003,
+  DAC960_PG_MailboxRegister4Offset =		0x1004,
+  DAC960_PG_MailboxRegister5Offset =		0x1005,
+  DAC960_PG_MailboxRegister6Offset =		0x1006,
+  DAC960_PG_MailboxRegister7Offset =		0x1007,
+  DAC960_PG_MailboxRegister8Offset =		0x1008,
+  DAC960_PG_MailboxRegister9Offset =		0x1009,
+  DAC960_PG_MailboxRegister10Offset =		0x100A,
+  DAC960_PG_MailboxRegister11Offset =		0x100B,
+  DAC960_PG_MailboxRegister12Offset =		0x100C,
+  DAC960_PG_StatusCommandIdentifierRegOffset =	0x1018,
+  DAC960_PG_StatusRegisterOffset =		0x101A,
+  DAC960_PG_ErrorStatusRegisterOffset =		0x103F
 }
-DAC960_V4_RegisterOffsets_T;
+DAC960_PG_RegisterOffsets_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Inbound Door Bell Register.
+  Define the structure of the DAC960 PG Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_V4_InboundDoorBellRegister
+typedef union DAC960_PG_InboundDoorBellRegister
 {
   unsigned int All;
   struct {
@@ -1777,14 +3536,14 @@
     unsigned int :30;					/* Bits 2-31 */
   } Read;
 }
-DAC960_V4_InboundDoorBellRegister_T;
+DAC960_PG_InboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Outbound Door Bell Register.
+  Define the structure of the DAC960 PG Series Outbound Door Bell Register.
 */
 
-typedef union DAC960_V4_OutboundDoorBellRegister
+typedef union DAC960_PG_OutboundDoorBellRegister
 {
   unsigned int All;
   struct {
@@ -1798,14 +3557,14 @@
     unsigned int :30;					/* Bits 2-31 */
   } Read;
 }
-DAC960_V4_OutboundDoorBellRegister_T;
+DAC960_PG_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Interrupt Mask Register.
+  Define the structure of the DAC960 PG Series Interrupt Mask Register.
 */
 
-typedef union DAC960_V4_InterruptMaskRegister
+typedef union DAC960_PG_InterruptMaskRegister
 {
   unsigned int All;
   struct {
@@ -1815,14 +3574,14 @@
     unsigned int Reserved0:24;				/* Bits 8-31 */
   } Bits;
 }
-DAC960_V4_InterruptMaskRegister_T;
+DAC960_PG_InterruptMaskRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V4 Error Status Register.
+  Define the structure of the DAC960 PG Series Error Status Register.
 */
 
-typedef union DAC960_V4_ErrorStatusRegister
+typedef union DAC960_PG_ErrorStatusRegister
 {
   unsigned char All;
   struct {
@@ -1831,292 +3590,298 @@
     unsigned int :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V4_ErrorStatusRegister_T;
+DAC960_PG_ErrorStatusRegister_T;
 
 
 /*
   Define inline functions to provide an abstraction for reading and writing the
-  DAC960 V4 Controller Interface Registers.
+  DAC960 PG Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_V4_HardwareMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_PG_HardwareMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.HardwareMailboxNewCommand = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeHardwareMailboxStatus(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.AcknowledgeHardwareMailboxStatus = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_GenerateInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_GenerateInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.GenerateInterrupt = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_ControllerReset(void *ControllerBaseAddress)
+void DAC960_PG_ControllerReset(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.ControllerReset = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_MemoryMailboxNewCommand(void *ControllerBaseAddress)
+void DAC960_PG_MemoryMailboxNewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.MemoryMailboxNewCommand = true;
   writel(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V4_HardwareMailboxFullP(void *ControllerBaseAddress)
+boolean DAC960_PG_HardwareMailboxFullP(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.HardwareMailboxFull;
 }
 
 static inline
-boolean DAC960_V4_InitializationInProgressP(void *ControllerBaseAddress)
+boolean DAC960_PG_InitializationInProgressP(void *ControllerBaseAddress)
 {
-  DAC960_V4_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PG_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_InboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.InitializationInProgress;
 }
 
 static inline
-void DAC960_V4_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeHardwareMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   writel(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeMemoryMailboxInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writel(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V4_AcknowledgeInterrupt(void *ControllerBaseAddress)
+void DAC960_PG_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeHardwareMailboxInterrupt = true;
   OutboundDoorBellRegister.Write.AcknowledgeMemoryMailboxInterrupt = true;
   writel(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V4_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_PG_HardwareMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.HardwareMailboxStatusAvailable;
 }
 
 static inline
-boolean DAC960_V4_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_PG_MemoryMailboxStatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V4_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PG_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_OutboundDoorBellRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.MemoryMailboxStatusAvailable;
 }
 
 static inline
-void DAC960_V4_EnableInterrupts(void *ControllerBaseAddress)
+void DAC960_PG_EnableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
   InterruptMaskRegister.Bits.DisableInterrupts = false;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
   writel(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
 }
 
 static inline
-void DAC960_V4_DisableInterrupts(void *ControllerBaseAddress)
+void DAC960_PG_DisableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All = 0;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask1 = 0x3;
   InterruptMaskRegister.Bits.DisableInterrupts = true;
   InterruptMaskRegister.Bits.MessageUnitInterruptMask2 = 0x1F;
   writel(InterruptMaskRegister.All,
-	 ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
 }
 
 static inline
-boolean DAC960_V4_InterruptsEnabledP(void *ControllerBaseAddress)
+boolean DAC960_PG_InterruptsEnabledP(void *ControllerBaseAddress)
 {
-  DAC960_V4_InterruptMaskRegister_T InterruptMaskRegister;
+  DAC960_PG_InterruptMaskRegister_T InterruptMaskRegister;
   InterruptMaskRegister.All =
-    readl(ControllerBaseAddress + DAC960_V4_InterruptMaskRegisterOffset);
+    readl(ControllerBaseAddress + DAC960_PG_InterruptMaskRegisterOffset);
   return !InterruptMaskRegister.Bits.DisableInterrupts;
 }
 
 static inline
-void DAC960_V4_WriteCommandMailbox(DAC960_CommandMailbox_T *NextCommandMailbox,
-				   DAC960_CommandMailbox_T *CommandMailbox)
-{
-  NextCommandMailbox->Words[1] = CommandMailbox->Words[1];
-  NextCommandMailbox->Words[2] = CommandMailbox->Words[2];
-  NextCommandMailbox->Words[3] = CommandMailbox->Words[3];
+void DAC960_PG_WriteCommandMailbox(DAC960_V1_CommandMailbox_T
+				     *MemoryCommandMailbox,
+				   DAC960_V1_CommandMailbox_T
+				     *CommandMailbox)
+{
+  MemoryCommandMailbox->Words[1] = CommandMailbox->Words[1];
+  MemoryCommandMailbox->Words[2] = CommandMailbox->Words[2];
+  MemoryCommandMailbox->Words[3] = CommandMailbox->Words[3];
   wmb();
-  NextCommandMailbox->Words[0] = CommandMailbox->Words[0];
+  MemoryCommandMailbox->Words[0] = CommandMailbox->Words[0];
   mb();
 }
 
 static inline
-void DAC960_V4_WriteHardwareMailbox(void *ControllerBaseAddress,
-				    DAC960_CommandMailbox_T *CommandMailbox)
+void DAC960_PG_WriteHardwareMailbox(void *ControllerBaseAddress,
+				    DAC960_V1_CommandMailbox_T *CommandMailbox)
 {
   writel(CommandMailbox->Words[0],
-	 ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
+	 ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
   writel(CommandMailbox->Words[1],
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
   writel(CommandMailbox->Words[2],
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
   writeb(CommandMailbox->Bytes[12],
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister12Offset);
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister12Offset);
 }
 
-static inline DAC960_CommandIdentifier_T
-DAC960_V4_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandIdentifier_T
+DAC960_PG_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
 {
   return readb(ControllerBaseAddress
-	       + DAC960_V4_StatusCommandIdentifierRegOffset);
+	       + DAC960_PG_StatusCommandIdentifierRegOffset);
 }
 
-static inline DAC960_CommandStatus_T
-DAC960_V4_ReadStatusRegister(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandStatus_T
+DAC960_PG_ReadStatusRegister(void *ControllerBaseAddress)
 {
-  return readw(ControllerBaseAddress + DAC960_V4_StatusRegisterOffset);
+  return readw(ControllerBaseAddress + DAC960_PG_StatusRegisterOffset);
 }
 
 static inline boolean
-DAC960_V4_ReadErrorStatus(void *ControllerBaseAddress,
+DAC960_PG_ReadErrorStatus(void *ControllerBaseAddress,
 			  unsigned char *ErrorStatus,
 			  unsigned char *Parameter0,
 			  unsigned char *Parameter1)
 {
-  DAC960_V4_ErrorStatusRegister_T ErrorStatusRegister;
+  DAC960_PG_ErrorStatusRegister_T ErrorStatusRegister;
   ErrorStatusRegister.All =
-    readb(ControllerBaseAddress + DAC960_V4_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
   ErrorStatusRegister.Bits.ErrorStatusPending = false;
   *ErrorStatus = ErrorStatusRegister.All;
   *Parameter0 =
-    readb(ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
   *Parameter1 =
-    readb(ControllerBaseAddress + DAC960_V4_CommandIdentifierRegisterOffset);
-  writeb(0, ControllerBaseAddress + DAC960_V4_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PG_CommandIdentifierRegisterOffset);
+  writeb(0, ControllerBaseAddress + DAC960_PG_ErrorStatusRegisterOffset);
   return true;
 }
 
 static inline
-void DAC960_V4_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
+void DAC960_PG_SaveMemoryMailboxInfo(DAC960_Controller_T *Controller)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   writel(0x743C485E,
-	 ControllerBaseAddress + DAC960_V4_CommandOpcodeRegisterOffset);
-  writel((unsigned long) Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
-  writew(Controller->NextCommandMailbox - Controller->FirstCommandMailbox,
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
-  writew(Controller->NextStatusMailbox - Controller->FirstStatusMailbox,
-	 ControllerBaseAddress + DAC960_V4_MailboxRegister10Offset);
+	 ControllerBaseAddress + DAC960_PG_CommandOpcodeRegisterOffset);
+  writel((unsigned long) Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
+  writew(Controller->V1.NextCommandMailbox - Controller->V1.FirstCommandMailbox,
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
+  writew(Controller->V1.NextStatusMailbox - Controller->V1.FirstStatusMailbox,
+	 ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
+#endif
 }
 
 static inline
-void DAC960_V4_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
+void DAC960_PG_RestoreMemoryMailboxInfo(DAC960_Controller_T *Controller,
 					void **MemoryMailboxAddress,
 					short *NextCommandMailboxIndex,
 					short *NextStatusMailboxIndex)
 {
+#ifdef __i386__
   void *ControllerBaseAddress = Controller->BaseAddress;
   if (readl(ControllerBaseAddress
-	    + DAC960_V4_CommandOpcodeRegisterOffset) != 0x743C485E)
+	    + DAC960_PG_CommandOpcodeRegisterOffset) != 0x743C485E)
     return;
   *MemoryMailboxAddress =
-    (void *) readl(ControllerBaseAddress + DAC960_V4_MailboxRegister4Offset);
+    (void *) readl(ControllerBaseAddress + DAC960_PG_MailboxRegister4Offset);
   *NextCommandMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V4_MailboxRegister8Offset);
+    readw(ControllerBaseAddress + DAC960_PG_MailboxRegister8Offset);
   *NextStatusMailboxIndex =
-    readw(ControllerBaseAddress + DAC960_V4_MailboxRegister10Offset);
+    readw(ControllerBaseAddress + DAC960_PG_MailboxRegister10Offset);
+#endif
 }
 
 
 /*
-  Define the DAC960 V3 Controller Interface Register Offsets.
+  Define the DAC960 PD Series Controller Interface Register Offsets.
 */
 
-#define DAC960_V3_RegisterWindowSize		0x80
+#define DAC960_PD_RegisterWindowSize		0x80
 
 typedef enum
 {
-  DAC960_V3_CommandOpcodeRegisterOffset =	0x00,
-  DAC960_V3_CommandIdentifierRegisterOffset =	0x01,
-  DAC960_V3_MailboxRegister2Offset =		0x02,
-  DAC960_V3_MailboxRegister3Offset =		0x03,
-  DAC960_V3_MailboxRegister4Offset =		0x04,
-  DAC960_V3_MailboxRegister5Offset =		0x05,
-  DAC960_V3_MailboxRegister6Offset =		0x06,
-  DAC960_V3_MailboxRegister7Offset =		0x07,
-  DAC960_V3_MailboxRegister8Offset =		0x08,
-  DAC960_V3_MailboxRegister9Offset =		0x09,
-  DAC960_V3_MailboxRegister10Offset =		0x0A,
-  DAC960_V3_MailboxRegister11Offset =		0x0B,
-  DAC960_V3_MailboxRegister12Offset =		0x0C,
-  DAC960_V3_StatusCommandIdentifierRegOffset =	0x0D,
-  DAC960_V3_StatusRegisterOffset =		0x0E,
-  DAC960_V3_ErrorStatusRegisterOffset =		0x3F,
-  DAC960_V3_InboundDoorBellRegisterOffset =	0x40,
-  DAC960_V3_OutboundDoorBellRegisterOffset =	0x41,
-  DAC960_V3_InterruptEnableRegisterOffset =	0x43
+  DAC960_PD_CommandOpcodeRegisterOffset =	0x00,
+  DAC960_PD_CommandIdentifierRegisterOffset =	0x01,
+  DAC960_PD_MailboxRegister2Offset =		0x02,
+  DAC960_PD_MailboxRegister3Offset =		0x03,
+  DAC960_PD_MailboxRegister4Offset =		0x04,
+  DAC960_PD_MailboxRegister5Offset =		0x05,
+  DAC960_PD_MailboxRegister6Offset =		0x06,
+  DAC960_PD_MailboxRegister7Offset =		0x07,
+  DAC960_PD_MailboxRegister8Offset =		0x08,
+  DAC960_PD_MailboxRegister9Offset =		0x09,
+  DAC960_PD_MailboxRegister10Offset =		0x0A,
+  DAC960_PD_MailboxRegister11Offset =		0x0B,
+  DAC960_PD_MailboxRegister12Offset =		0x0C,
+  DAC960_PD_StatusCommandIdentifierRegOffset =	0x0D,
+  DAC960_PD_StatusRegisterOffset =		0x0E,
+  DAC960_PD_ErrorStatusRegisterOffset =		0x3F,
+  DAC960_PD_InboundDoorBellRegisterOffset =	0x40,
+  DAC960_PD_OutboundDoorBellRegisterOffset =	0x41,
+  DAC960_PD_InterruptEnableRegisterOffset =	0x43
 }
-DAC960_V3_RegisterOffsets_T;
+DAC960_PD_RegisterOffsets_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Inbound Door Bell Register.
+  Define the structure of the DAC960 PD Series Inbound Door Bell Register.
 */
 
-typedef union DAC960_V3_InboundDoorBellRegister
+typedef union DAC960_PD_InboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -2132,14 +3897,14 @@
     unsigned char :6;					/* Bits 2-7 */
   } Read;
 }
-DAC960_V3_InboundDoorBellRegister_T;
+DAC960_PD_InboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Outbound Door Bell Register.
+  Define the structure of the DAC960 PD Series Outbound Door Bell Register.
 */
 
-typedef union DAC960_V3_OutboundDoorBellRegister
+typedef union DAC960_PD_OutboundDoorBellRegister
 {
   unsigned char All;
   struct {
@@ -2151,14 +3916,14 @@
     unsigned char :7;					/* Bits 1-7 */
   } Read;
 }
-DAC960_V3_OutboundDoorBellRegister_T;
+DAC960_PD_OutboundDoorBellRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Interrupt Enable Register.
+  Define the structure of the DAC960 PD Series Interrupt Enable Register.
 */
 
-typedef union DAC960_V3_InterruptEnableRegister
+typedef union DAC960_PD_InterruptEnableRegister
 {
   unsigned char All;
   struct {
@@ -2166,14 +3931,14 @@
     unsigned char :7;					/* Bits 1-7 */
   } Bits;
 }
-DAC960_V3_InterruptEnableRegister_T;
+DAC960_PD_InterruptEnableRegister_T;
 
 
 /*
-  Define the structure of the DAC960 V3 Error Status Register.
+  Define the structure of the DAC960 PD Series Error Status Register.
 */
 
-typedef union DAC960_V3_ErrorStatusRegister
+typedef union DAC960_PD_ErrorStatusRegister
 {
   unsigned char All;
   struct {
@@ -2182,187 +3947,176 @@
     unsigned int :5;					/* Bits 3-7 */
   } Bits;
 }
-DAC960_V3_ErrorStatusRegister_T;
+DAC960_PD_ErrorStatusRegister_T;
 
 
 /*
   Define inline functions to provide an abstraction for reading and writing the
-  DAC960 V3 Controller Interface Registers.
+  DAC960 PD Series Controller Interface Registers.
 */
 
 static inline
-void DAC960_V3_NewCommand(void *ControllerBaseAddress)
+void DAC960_PD_NewCommand(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.NewCommand = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V3_AcknowledgeStatus(void *ControllerBaseAddress)
+void DAC960_PD_AcknowledgeStatus(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.AcknowledgeStatus = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V3_GenerateInterrupt(void *ControllerBaseAddress)
+void DAC960_PD_GenerateInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.GenerateInterrupt = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-void DAC960_V3_ControllerReset(void *ControllerBaseAddress)
+void DAC960_PD_ControllerReset(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All = 0;
   InboundDoorBellRegister.Write.ControllerReset = true;
   writeb(InboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V3_MailboxFullP(void *ControllerBaseAddress)
+boolean DAC960_PD_MailboxFullP(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.MailboxFull;
 }
 
 static inline
-boolean DAC960_V3_InitializationInProgressP(void *ControllerBaseAddress)
+boolean DAC960_PD_InitializationInProgressP(void *ControllerBaseAddress)
 {
-  DAC960_V3_InboundDoorBellRegister_T InboundDoorBellRegister;
+  DAC960_PD_InboundDoorBellRegister_T InboundDoorBellRegister;
   InboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_InboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_InboundDoorBellRegisterOffset);
   return InboundDoorBellRegister.Read.InitializationInProgress;
 }
 
 static inline
-void DAC960_V3_AcknowledgeInterrupt(void *ControllerBaseAddress)
+void DAC960_PD_AcknowledgeInterrupt(void *ControllerBaseAddress)
 {
-  DAC960_V3_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All = 0;
   OutboundDoorBellRegister.Write.AcknowledgeInterrupt = true;
   writeb(OutboundDoorBellRegister.All,
-	 ControllerBaseAddress + DAC960_V3_OutboundDoorBellRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
 }
 
 static inline
-boolean DAC960_V3_StatusAvailableP(void *ControllerBaseAddress)
+boolean DAC960_PD_StatusAvailableP(void *ControllerBaseAddress)
 {
-  DAC960_V3_OutboundDoorBellRegister_T OutboundDoorBellRegister;
+  DAC960_PD_OutboundDoorBellRegister_T OutboundDoorBellRegister;
   OutboundDoorBellRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_OutboundDoorBellRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_OutboundDoorBellRegisterOffset);
   return OutboundDoorBellRegister.Read.StatusAvailable;
 }
 
 static inline
-void DAC960_V3_EnableInterrupts(void *ControllerBaseAddress)
+void DAC960_PD_EnableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
+  DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
   InterruptEnableRegister.All = 0;
   InterruptEnableRegister.Bits.EnableInterrupts = true;
   writeb(InterruptEnableRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
 }
 
 static inline
-void DAC960_V3_DisableInterrupts(void *ControllerBaseAddress)
+void DAC960_PD_DisableInterrupts(void *ControllerBaseAddress)
 {
-  DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
+  DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
   InterruptEnableRegister.All = 0;
   InterruptEnableRegister.Bits.EnableInterrupts = false;
   writeb(InterruptEnableRegister.All,
-	 ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
 }
 
 static inline
-boolean DAC960_V3_InterruptsEnabledP(void *ControllerBaseAddress)
+boolean DAC960_PD_InterruptsEnabledP(void *ControllerBaseAddress)
 {
-  DAC960_V3_InterruptEnableRegister_T InterruptEnableRegister;
+  DAC960_PD_InterruptEnableRegister_T InterruptEnableRegister;
   InterruptEnableRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_InterruptEnableRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_InterruptEnableRegisterOffset);
   return InterruptEnableRegister.Bits.EnableInterrupts;
 }
 
 static inline
-void DAC960_V3_WriteCommandMailbox(void *ControllerBaseAddress,
-				   DAC960_CommandMailbox_T *CommandMailbox)
+void DAC960_PD_WriteCommandMailbox(void *ControllerBaseAddress,
+				   DAC960_V1_CommandMailbox_T *CommandMailbox)
 {
   writel(CommandMailbox->Words[0],
-	 ControllerBaseAddress + DAC960_V3_CommandOpcodeRegisterOffset);
+	 ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
   writel(CommandMailbox->Words[1],
-	 ControllerBaseAddress + DAC960_V3_MailboxRegister4Offset);
+	 ControllerBaseAddress + DAC960_PD_MailboxRegister4Offset);
   writel(CommandMailbox->Words[2],
-	 ControllerBaseAddress + DAC960_V3_MailboxRegister8Offset);
+	 ControllerBaseAddress + DAC960_PD_MailboxRegister8Offset);
   writeb(CommandMailbox->Bytes[12],
-	 ControllerBaseAddress + DAC960_V3_MailboxRegister12Offset);
+	 ControllerBaseAddress + DAC960_PD_MailboxRegister12Offset);
 }
 
-static inline DAC960_CommandIdentifier_T
-DAC960_V3_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandIdentifier_T
+DAC960_PD_ReadStatusCommandIdentifier(void *ControllerBaseAddress)
 {
   return readb(ControllerBaseAddress
-	       + DAC960_V3_StatusCommandIdentifierRegOffset);
+	       + DAC960_PD_StatusCommandIdentifierRegOffset);
 }
 
-static inline DAC960_CommandStatus_T
-DAC960_V3_ReadStatusRegister(void *ControllerBaseAddress)
+static inline DAC960_V1_CommandStatus_T
+DAC960_PD_ReadStatusRegister(void *ControllerBaseAddress)
 {
-  return readw(ControllerBaseAddress + DAC960_V3_StatusRegisterOffset);
+  return readw(ControllerBaseAddress + DAC960_PD_StatusRegisterOffset);
 }
 
 static inline boolean
-DAC960_V3_ReadErrorStatus(void *ControllerBaseAddress,
+DAC960_PD_ReadErrorStatus(void *ControllerBaseAddress,
 			  unsigned char *ErrorStatus,
 			  unsigned char *Parameter0,
 			  unsigned char *Parameter1)
 {
-  DAC960_V3_ErrorStatusRegister_T ErrorStatusRegister;
+  DAC960_PD_ErrorStatusRegister_T ErrorStatusRegister;
   ErrorStatusRegister.All =
-    readb(ControllerBaseAddress + DAC960_V3_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
   if (!ErrorStatusRegister.Bits.ErrorStatusPending) return false;
   ErrorStatusRegister.Bits.ErrorStatusPending = false;
   *ErrorStatus = ErrorStatusRegister.All;
   *Parameter0 =
-    readb(ControllerBaseAddress + DAC960_V3_CommandOpcodeRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_CommandOpcodeRegisterOffset);
   *Parameter1 =
-    readb(ControllerBaseAddress + DAC960_V3_CommandIdentifierRegisterOffset);
-  writeb(0, ControllerBaseAddress + DAC960_V3_ErrorStatusRegisterOffset);
+    readb(ControllerBaseAddress + DAC960_PD_CommandIdentifierRegisterOffset);
+  writeb(0, ControllerBaseAddress + DAC960_PD_ErrorStatusRegisterOffset);
   return true;
 }
 
 
 /*
-  Define compatibility macros between Linux 2.0 and Linux 2.1.
-*/
-
-#if LINUX_VERSION_CODE < 0x20100
-
-#define MODULE_PARM(Variable, Type)
-#define ioremap_nocache(Offset, Size)	vremap(Offset, Size)
-#define iounmap(Address)		vfree(Address)
-
-#endif
-
-
-/*
   Define prototypes for the forward referenced DAC960 Driver Internal Functions.
 */
 
 static void DAC960_FinalizeController(DAC960_Controller_T *);
 static int DAC960_Finalize(NotifierBlock_T *, unsigned long, void *);
+static void DAC960_V1_QueueReadWriteCommand(DAC960_Command_T *);
+static void DAC960_V2_QueueReadWriteCommand(DAC960_Command_T *);
 static void DAC960_RequestFunction0(void);
 static void DAC960_RequestFunction1(void);
 static void DAC960_RequestFunction2(void);
@@ -2371,15 +4125,20 @@
 static void DAC960_RequestFunction5(void);
 static void DAC960_RequestFunction6(void);
 static void DAC960_RequestFunction7(void);
-static void DAC960_InterruptHandler(int, void *, Registers_T *);
-static void DAC960_QueueMonitoringCommand(DAC960_Command_T *);
+static void DAC960_BA_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_LP_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_LA_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_PG_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_PD_InterruptHandler(int, void *, Registers_T *);
+static void DAC960_V1_QueueMonitoringCommand(DAC960_Command_T *);
+static void DAC960_V2_QueueMonitoringCommand(DAC960_Command_T *);
 static void DAC960_MonitoringTimerFunction(unsigned long);
 static int DAC960_Open(Inode_T *, File_T *);
 static int DAC960_Release(Inode_T *, File_T *);
 static int DAC960_IOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
 static int DAC960_UserIOCTL(Inode_T *, File_T *, unsigned int, unsigned long);
 static void DAC960_InitializeGenericDiskInfo(GenericDiskInfo_T *);
-static void DAC960_Message(DAC960_MessageLevel_T, char *,
+static void DAC960_Message(DAC960_MessageLevel_T, unsigned char *,
 			   DAC960_Controller_T *, ...);
 static void DAC960_CreateProcEntries(void);
 static void DAC960_DestroyProcEntries(void);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/cmd646.c linux.17p18/drivers/block/cmd646.c
--- linux.vanilla/drivers/block/cmd646.c	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/cmd646.c	Tue Aug  1 07:59:25 2000
@@ -247,5 +247,9 @@
 	(void) pci_write_config_byte(dev, 0x58, 0x3f);
 	(void) pci_write_config_byte(dev, 0x5b, 0x3f);
 
+#ifdef CONFIG_PPC
+	(void) pci_write_config_byte(dev, 0x73, 0xf0);
+#endif /* CONFIG_PPC */
+
 	hwif->dmaproc = &cmd646_dmaproc;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/cpqarray.c linux.17p18/drivers/block/cpqarray.c
--- linux.vanilla/drivers/block/cpqarray.c	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/cpqarray.c	Tue Aug  1 07:59:25 2000
@@ -41,8 +41,8 @@
 
 #define SMART2_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
 
-#define DRIVER_NAME "Compaq SMART2 Driver (v 1.0.6)"
-#define DRIVER_VERSION SMART2_DRIVER_VERSION(1,0,6)
+#define DRIVER_NAME "Compaq SMART2 Driver (v 1.0.9)"
+#define DRIVER_VERSION SMART2_DRIVER_VERSION(1,0,9)
 #define MAJOR_NR COMPAQ_SMART2_MAJOR
 #include <linux/blk.h>
 #include <linux/blkdev.h>
@@ -70,7 +70,7 @@
  *  product = Marketing Name for the board
  *  access = Address of the struct of function pointers 
  */
-struct board_type products[] = {
+static struct board_type products[] = {
 	{ 0x0040110E, "IDA",			&smart1_access },
 	{ 0x0140110E, "IDA-2",			&smart1_access },
 	{ 0x1040110E, "IAES",			&smart1_access },
@@ -82,6 +82,7 @@
 	{ 0x40330E11, "Smart Array 3100ES",	&smart2_access },
 	{ 0x40340E11, "Smart Array 221",	&smart2_access },
 	{ 0x40400E11, "Integrated Array",	&smart4_access },
+	{ 0x40480E11, "Compaq Raid LC2",        &smart4_access },
 	{ 0x40500E11, "Smart Array 4200",	&smart4_access },
 	{ 0x40510E11, "Smart Array 4250ES",	&smart4_access },
 	{ 0x40580E11, "Smart Array 431",	&smart4_access },
@@ -93,7 +94,7 @@
 static int * ida_hardsizes;
 static struct gendisk ida_gendisk[MAX_CTLR];
 
-struct proc_dir_entry *proc_array = NULL;
+static struct proc_dir_entry *proc_array = NULL;
 
 /* Debug... */
 #define DBG(s)	do { s } while(0)
@@ -847,8 +848,10 @@
 
 /*
  * Get a request and submit it to the controller.
- * This routine needs to grab all the requests it possibly can from the
- * req Q and submit them.  Interrupts are off (and need to be off) when you
+ * This routine needs to grab one requests and submits it.  We would like 
+ * to grab all possible requests, but there is a danger of holding the 
+ * io_request lock to long.  
+ * Interrupts are off (and need to be off) when you
  * are in here (either via the dummy do_ida_request functions or by being
  * called from the interrupt handler
  */
@@ -1005,28 +1008,24 @@
  */
 static inline void complete_command(cmdlist_t *cmd, int timeout)
 {
-	char buf[80];
 	int ok=1;
 
 	if (cmd->req.hdr.rcode & RCODE_NONFATAL &&
 	   (hba[cmd->ctlr]->misc_tflags & MISC_NONFATAL_WARN) == 0) {
-		sprintf(buf, "Non Fatal error on ida/c%dd%d\n",
+		printk(KERN_WARNING "Non Fatal error on ida/c%dd%d\n",
 				cmd->ctlr, cmd->hdr.unit);
-		console_print(buf);
 		hba[cmd->ctlr]->misc_tflags |= MISC_NONFATAL_WARN;
 	}
 	if (cmd->req.hdr.rcode & RCODE_FATAL) {
-		sprintf(buf, "Fatal error on ida/c%dd%d\n",
+		printk(KERN_WARNING "Fatal error on ida/c%dd%d\n",
 				cmd->ctlr, cmd->hdr.unit);
-		console_print(buf);
 		ok = 0;
 	}
 	if (cmd->req.hdr.rcode & RCODE_INVREQ) {
-				sprintf(buf, "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
+				printk(KERN_WARNING "Invalid request on ida/c%dd%d = (cmd=%x sect=%d cnt=%d sg=%d ret=%x)\n",
 				cmd->ctlr, cmd->hdr.unit, cmd->req.hdr.cmd,
 				cmd->req.hdr.blk, cmd->req.hdr.blk_cnt,
 				cmd->req.hdr.sg_cnt, cmd->req.hdr.rcode);
-		console_print(buf);
 		ok = 0;	
 	}
 	if (timeout) ok = 0;
@@ -1586,7 +1585,8 @@
 		id_ctlr_t *id_ctlr_buf; 
 	int ret_code;
 
-	if(	hba[ctlr]->board_id != 0x40400E11)
+	if(	(hba[ctlr]->board_id != 0x40400E11)
+		&& (hba[ctlr]->board_id != 0x40480E11) )
 	/* Not a Integrated Raid, so there is nothing for us to do */
 		return;
 	printk(KERN_DEBUG "cpqarray: Starting firmware's background"
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/genhd.c linux.17p18/drivers/block/genhd.c
--- linux.vanilla/drivers/block/genhd.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/drivers/block/genhd.c	Tue Aug  1 07:59:25 2000
@@ -1089,6 +1089,14 @@
     /* ... more stuff */
 };
 
+static inline void mac_fix_string(char *stg, int len)
+{
+	int i;
+
+	for (i = len - 1; i >= 0 && stg[i] == ' '; i--)
+		stg[i] = 0;
+}
+
 static int mac_partition(struct gendisk *hd, kdev_t dev, unsigned long fsec)
 {
 	struct buffer_head *bh;
@@ -1157,18 +1165,31 @@
 		 */
 		if (_machine == _MACH_Pmac) {
 			int goodness = 0;
+
+			mac_fix_string(part->processor, 16);
+			mac_fix_string(part->name, 32);
+			mac_fix_string(part->type, 32);					
 		    
 			if ((be32_to_cpu(part->status) & MAC_STATUS_BOOTABLE)
 			    && strcasecmp(part->processor, "powerpc") == 0)
 				goodness++;
 
-			if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0) {
+			if (strcasecmp(part->type, "Apple_UNIX_SVR2") == 0
+			    || strcasecmp(part->type, "Linux_PPC") == 0) {
+				int i, l;
+
 				goodness++;
-				if ((strcmp(part->name, "/") == 0) ||
-				    (strstr(part->name, "root") != 0)) {
+				l = strlen(part->name);
+				if (strcmp(part->name, "/") == 0)
 					goodness++;
+				for (i = 0; i <= l - 4; ++i) {
+					if (strnicmp(part->name + i, "root",
+						     4) == 0) {
+						goodness += 2;
+						break;
+					}
 				}
-				if (strncmp(part->name, "swap", 4) == 0)
+				if (strnicmp(part->name, "swap", 4) == 0)
 					goodness--;
 			}
 
@@ -1193,7 +1214,7 @@
 #endif /* CONFIG_MAC_PARTITION */
 
 #ifdef CONFIG_ATARI_PARTITION
-#include <asm/atari_rootsec.h>
+#include <linux/atari_rootsec.h>
 
 /* ++guenther: this should be settable by the user ("make config")?.
  */
@@ -1237,7 +1258,7 @@
 	      part_fmt = 1;
 #endif
 	      printk(" XGM<");
-	      partsect = extensect = pi->st;
+	      partsect = extensect = be32_to_cpu(pi->st);
 	      while (1)
 		{
 		  xbh = bread (dev, partsect / 2, get_ptable_blocksize(dev));
@@ -1258,8 +1279,8 @@
 		    break;
 		  }
 
-		  add_partition(hd, minor, partsect + xrs->part[0].st,
-				xrs->part[0].siz, 0);
+		  add_partition(hd, minor, partsect + be32_to_cpu(xrs->part[0].st),
+				be32_to_cpu(xrs->part[0].siz), 0);
 
 		  if (!(xrs->part[1].flg & 1)) {
 		    /* end of linked partition list */
@@ -1272,7 +1293,7 @@
 		    break;
 		  }
 
-		  partsect = xrs->part[1].st + extensect;
+		  partsect = be32_to_cpu(xrs->part[1].st) + extensect;
 		  brelse (xbh);
 		  minor++;
 		  if (minor >= m_lim) {
@@ -1285,7 +1306,8 @@
 	  else
 	    {
 	      /* we don't care about other id's */
-	      add_partition (hd, minor, pi->st, pi->siz, 0);
+	      printk(" %c%c%c(%d)", pi->id[0], pi->id[1], pi->id[2], be32_to_cpu(pi->siz)/2048);
+	      add_partition (hd, minor, be32_to_cpu(pi->st), be32_to_cpu(pi->siz), 0);
 	    }
 	}
     }
@@ -1520,10 +1542,6 @@
 	if(amiga_partition(hd, dev, first_sector))
 		return;
 #endif
-#ifdef CONFIG_ATARI_PARTITION
-	if(atari_partition(hd, dev, first_sector))
-		return;
-#endif
 #ifdef CONFIG_MAC_PARTITION
 	if (mac_partition(hd, dev, first_sector))
 		return;
@@ -1534,6 +1552,10 @@
 #endif
 #ifdef CONFIG_ULTRIX_PARTITION
 	if(ultrix_partition(hd, dev, first_sector))
+		return;
+#endif
+#ifdef CONFIG_ATARI_PARTITION
+	if(atari_partition(hd, dev, first_sector))
 		return;
 #endif
 #ifdef CONFIG_ARCH_S390
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide-cd.c linux.17p18/drivers/block/ide-cd.c
--- linux.vanilla/drivers/block/ide-cd.c	Sun Jun 11 21:44:11 2000
+++ linux.17p18/drivers/block/ide-cd.c	Wed Aug 16 21:45:46 2000
@@ -1,8 +1,9 @@
 /*
- * linux/drivers/block/ide-cd.c
+ * linux/drivers/ide/ide-cd.c
+ *
  * Copyright (C) 1994, 1995, 1996  scott snyder  <snyder@fnald0.fnal.gov>
  * Copyright (C) 1996-1998  Erik Andersen <andersee@debian.org>
- * Copyright (C) 1998-2000 Jens Axboe <axboe@suse.de>
+ * Copyright (C) 1998-2000  Jens Axboe <axboe@suse.de>
  *
  * May be copied or modified under the terms of the GNU General Public
  * License.  See linux/COPYING for more information.
@@ -271,15 +272,18 @@
  *			- Fixed a problem with WPI CDS-32X drive - it
  *			  failed the capabilities 
  *
- * 4.57 never happened
- *
- * 4.58 May 1, 2000	- Fixed possible oops in ide_cdrom_get_last_session()
+ * 4.57  Apr 7, 2000	- Fixed sense reporting.
+ *			- Fixed possible oops in ide_cdrom_get_last_session()
  *			- Fix locking mania and make ide_cdrom_reset relock
  *			- Stop spewing errors to log when magicdev polls with
  *			  TEST_UNIT_READY on some drives.
- *			- Cleanup ACER50 stuff.
- *			- Integrate the ide_cdrom_packet from 2.3 to
- *			  support DVD CSS ioctls.
+ *			- Various fixes from Tobias Ringstrom:
+ *			  tray if it was locked prior to the reset.
+ *			  - cdrom_read_capacity returns one frame too little.
+ *			  - Fix real capacity reporting.
+ *
+ * 4.58  May 1, 2000	- Clean up ACER50 stuff.
+ *			- Fix small problem with ide_cdrom_capacity
  *
  *************************************************************************/
  
@@ -309,7 +313,6 @@
  * Generic packet command support and error handling routines.
  */
 
-
 /* Mark that we've seen a media change, and invalidate our internal
    buffers. */
 static void cdrom_saw_media_change (ide_drive_t *drive)
@@ -323,8 +326,9 @@
 
 
 static
-void cdrom_analyze_sense_data (ide_drive_t *drive, struct packet_command *pc,
-				struct request_sense *sense)
+void cdrom_analyze_sense_data(ide_drive_t *drive,
+			      struct packet_command *failed_command,
+			      struct request_sense *sense)
 {
 	if (sense->sense_key == NOT_READY ||
 	    sense->sense_key == UNIT_ATTENTION) {
@@ -338,13 +342,12 @@
 		   READ_SUBCHANNEL.  Workman (and probably other programs)
 		   uses this command to poll the drive, and we don't want
 		   to fill the syslog with useless errors. */
-		if (pc && (pc->c[0] == GPCMD_READ_SUBCHANNEL))
+		if (failed_command &&
+		    (failed_command->c[0] == GPCMD_READ_SUBCHANNEL ||
+		     failed_command->c[0] == GPCMD_TEST_UNIT_READY))
 			return;
 	}
 
-	if (pc && (pc->c[0] == GPCMD_TEST_UNIT_READY))
-		return;
-
 	if (sense->error_code == 0x70 && sense->sense_key  == 0x02
 	 && ((sense->asc      == 0x3a && sense->ascq       == 0x00) ||
 	     (sense->asc      == 0x04 && sense->ascq       == 0x01)))
@@ -364,9 +367,9 @@
 		char buf[80];
 
 		printk ("ATAPI device %s:\n", drive->name);
-		if (sense->error_code == 0x70)
+		if (sense->error_code==0x70)
 			printk("  Error: ");
-		else if (sense->error_code == 0x71)
+		else if (sense->error_code==0x71)
 			printk("  Deferred Error: ");
 		else if (sense->error_code == 0x7f)
 			printk("  Vendor-specific Error: ");
@@ -378,17 +381,17 @@
 		else
 			s = "bad sense key!";
 
-		printk ("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
+		printk("%s -- (Sense key=0x%02x)\n", s, sense->sense_key);
 
 		if (sense->asc == 0x40) {
-			sprintf (buf, "Diagnostic failure on component 0x%02x",
+			sprintf(buf, "Diagnostic failure on component 0x%02x",
 				 sense->ascq);
 			s = buf;
 		} else {
-			int lo=0, mid, hi=ARY_LEN (sense_data_texts);
+			int lo = 0, mid, hi = ARY_LEN(sense_data_texts);
 			unsigned long key = (sense->sense_key << 16);
 			key |= (sense->asc << 8);
-			if ( ! (sense->ascq >= 0x80 && sense->ascq <= 0xdd) )
+			if (!(sense->ascq >= 0x80 && sense->ascq <= 0xdd))
 				key |= sense->ascq;
 			s = NULL;
 
@@ -413,30 +416,32 @@
 				s = "(reserved error code)";
 		}
 
-		printk ("  %s -- (asc=0x%02x, ascq=0x%02x)\n",
+		printk("  %s -- (asc=0x%02x, ascq=0x%02x)\n",
 			s, sense->asc, sense->ascq);
 
-		if (pc != NULL) {
+		if (failed_command != NULL) {
 
 			int lo=0, mid, hi= ARY_LEN (packet_command_texts);
 			s = NULL;
 
 			while (hi > lo) {
 				mid = (lo + hi) / 2;
-				if (packet_command_texts[mid].packet_command == pc->c[0]) {
+				if (packet_command_texts[mid].packet_command ==
+				    failed_command->c[0]) {
 					s = packet_command_texts[mid].text;
 					break;
 				}
-				else if (packet_command_texts[mid].packet_command > pc->c[0])
+				if (packet_command_texts[mid].packet_command >
+				    failed_command->c[0])
 					hi = mid;
 				else
 					lo = mid+1;
 			}
 
 			printk ("  The failed \"%s\" packet command was: \n  \"", s);
-			for (i = 0; i < sizeof(pc->c); i++)
-				printk("%02x ", pc->c[i]);
-			printk("\"\n");
+			for (i=0; i<sizeof (failed_command->c); i++)
+				printk ("%02x ", failed_command->c[i]);
+			printk ("\"\n");
 		}
 
 		/* The SKSV bit specifies validity of the sense_key_specific
@@ -452,7 +457,7 @@
 
 		if (sense->sense_key == ILLEGAL_REQUEST &&
 		    (sense->sks[0] & 0x80) != 0) {
-			printk ("  Error in %s byte %d",
+			printk("  Error in %s byte %d",
 				(sense->sks[0] & 0x40) != 0 ?
 				"command packet" : "command data",
 				(sense->sks[1] << 8) + sense->sks[2]);
@@ -460,7 +465,7 @@
 			if ((sense->sks[0] & 0x40) != 0)
 				printk (" bit %d", sense->sks[0] & 0x07);
 
-			printk("\n");
+			printk ("\n");
 		}
 	}
 
@@ -475,15 +480,16 @@
 		return;
 
 	printk("%s: error code: 0x%02x  sense_key: 0x%02x  asc: 0x%02x  ascq: 0x%02x\n",
-		drive->name, sense->error_code, sense->sense_key,
+		drive->name,
+		sense->error_code, sense->sense_key,
 		sense->asc, sense->ascq);
 #endif /* not VERBOSE_IDE_CD_ERRORS */
 }
 
-static void cdrom_queue_request_sense(ide_drive_t *drive,
+static void cdrom_queue_request_sense(ide_drive_t *drive, 
 				      struct semaphore *sem,
 				      struct request_sense *sense,
-				      struct packet_command *failed_cmd)
+				      struct packet_command *failed_command)
 {
 	struct cdrom_info *info = drive->driver_data;
 	struct request *rq;
@@ -496,7 +502,7 @@
 	pc->c[0] = GPCMD_REQUEST_SENSE;
 	pc->c[4] = pc->buflen = 18;
 	pc->buffer = (char *) sense;
-	pc->sense = (struct request_sense *) failed_cmd;
+	pc->sense = (struct request_sense *) failed_command;
 
 	/* stuff the sense request in front of our current request */
 	rq = &info->request_sense_request;
@@ -507,15 +513,16 @@
 	(void) ide_do_drive_cmd(drive, rq, ide_preempt);
 }
 
+
 static void cdrom_end_request (int uptodate, ide_drive_t *drive)
 {
 	struct request *rq = HWGROUP(drive)->rq;
 
 	if (rq->cmd == REQUEST_SENSE_COMMAND && uptodate) {
 		struct packet_command *pc = (struct packet_command *)rq->buffer;
-		cdrom_analyze_sense_data (drive,
+		cdrom_analyze_sense_data(drive,
 			(struct packet_command *) pc->sense,
-			(struct request_sense *) pc->buffer - pc->c[4]);
+			(struct request_sense *) (pc->buffer - pc->c[4]));
 	}
 	if (rq->cmd == READ && !rq->current_nr_sectors)
 		uptodate = 1;
@@ -654,6 +661,9 @@
 	struct packet_command *pc = (struct packet_command *) rq->buffer;
 	unsigned long wait = 0;
 
+	/* blank and format can take an extremly long time to
+	 * complete, if the IMMED bit was not set.
+	 */
 	if (pc->c[0] == GPCMD_BLANK || pc->c[0] == GPCMD_FORMAT_UNIT)
 		wait = 60*60*HZ;
 
@@ -1066,15 +1076,15 @@
 		(65534 / CD_FRAMESIZE) : 65535);
 
 	/* Set up the command */
-	memset(&pc.c, 0, sizeof(pc.c));
+	memset (&pc.c, 0, sizeof (pc.c));
 	pc.c[0] = GPCMD_READ_10;
 	pc.c[7] = (nframes >> 8);
 	pc.c[8] = (nframes & 0xff);
 	put_unaligned(cpu_to_be32(frame), (unsigned int *) &pc.c[2]);
 
 	/* Send the command to the drive and return. */
-	return cdrom_transfer_packet_command(drive, pc.c, sizeof (pc.c),
-					      &cdrom_read_intr);
+	return cdrom_transfer_packet_command(drive, pc.c, sizeof(pc.c),
+					     &cdrom_read_intr);
 }
 
 
@@ -1190,20 +1200,20 @@
 			  struct request_sense *sense);
 
 /* Interrupt routine for packet command completion. */
-static ide_startstop_t cdrom_pc_intr(ide_drive_t *drive)
+static ide_startstop_t cdrom_pc_intr (ide_drive_t *drive)
 {
 	int ireason, len, stat, thislen;
 	struct request *rq = HWGROUP(drive)->rq;
-	struct packet_command *pc = (struct packet_command *) rq->buffer;
+	struct packet_command *pc = (struct packet_command *)rq->buffer;
 	ide_startstop_t startstop;
 
 	/* Check for errors. */
-	if (cdrom_decode_status(&startstop, drive, 0, &stat))
+	if (cdrom_decode_status (&startstop, drive, 0, &stat))
 		return startstop;
 
 	/* Read the interrupt reason and the transfer length. */
-	ireason = IN_BYTE(IDE_NSECTOR_REG);
-	len = IN_BYTE(IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG);
+	ireason = IN_BYTE (IDE_NSECTOR_REG);
+	len = IN_BYTE (IDE_LCYL_REG) + 256 * IN_BYTE (IDE_HCYL_REG);
 
 	/* If DRQ is clear, the command has completed.
 	   Complain if we still have data left to transfer. */
@@ -1242,14 +1252,14 @@
 	/* The drive wants to be written to. */
 	if ((ireason & 3) == 0) {
 		/* Transfer the data. */
-		atapi_output_bytes(drive, pc->buffer, thislen);
+		atapi_output_bytes (drive, pc->buffer, thislen);
 
 		/* If we haven't moved enough data to satisfy the drive,
 		   add some padding. */
 		while (len > thislen) {
 			int dum = 0;
-			atapi_output_bytes(drive, &dum, sizeof (dum));
-			len -= sizeof(dum);
+			atapi_output_bytes (drive, &dum, sizeof (dum));
+			len -= sizeof (dum);
 		}
 
 		/* Keep count of how much data we've moved. */
@@ -1261,28 +1271,28 @@
 	else if ((ireason & 3) == 2) {
 
 		/* Transfer the data. */
-		atapi_input_bytes(drive, pc->buffer, thislen);
+		atapi_input_bytes (drive, pc->buffer, thislen);
 
 		/* If we haven't moved enough data to satisfy the drive,
 		   add some padding. */
 		while (len > thislen) {
 			int dum = 0;
-			atapi_input_bytes(drive, &dum, sizeof (dum));
-			len -= sizeof(dum);
+			atapi_input_bytes (drive, &dum, sizeof (dum));
+			len -= sizeof (dum);
 		}
 
 		/* Keep count of how much data we've moved. */
 		pc->buffer += thislen;
 		pc->buflen -= thislen;
 	} else {
-		printk("%s: cdrom_pc_intr: The drive "
+		printk ("%s: cdrom_pc_intr: The drive "
 			"appears confused (ireason = 0x%2x)\n",
 			drive->name, ireason);
 		pc->stat = 1;
 	}
 
 	/* Now we wait for another interrupt. */
-	ide_set_handler(drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
+	ide_set_handler (drive, &cdrom_pc_intr, WAIT_CMD, cdrom_timer_expiry);
 	return ide_started;
 }
 
@@ -1326,9 +1336,9 @@
 static
 int cdrom_queue_packet_command(ide_drive_t *drive, struct packet_command *pc)
 {
-	int retries = 10;
 	struct request_sense sense;
 	struct request req;
+	int retries = 10;
 
 	if (pc->sense == NULL)
 		pc->sense = &sense;
@@ -1483,9 +1493,10 @@
 	struct cdrom_device_info *cdi = &info->devinfo;
 
 	memset(&pc, 0, sizeof(pc));
-	pc.c[0] = GPCMD_TEST_UNIT_READY;
 	pc.sense = sense;
 
+	pc.c[0] = GPCMD_TEST_UNIT_READY;
+
 #if ! STANDARD_ATAPI
         /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to 
            switch CDs instead of supporting the LOAD_UNLOAD opcode   */
@@ -1509,13 +1520,13 @@
 		sense = &my_sense;
 
 	/* If the drive cannot lock the door, just pretend. */
-	if (CDROM_CONFIG_FLAGS (drive)->no_doorlock)
+	if (CDROM_CONFIG_FLAGS(drive)->no_doorlock) {
 		stat = 0;
-	else {
+	} else {
 		memset(&pc, 0, sizeof(pc));
-		pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
-		pc.c[4] = (lockflag != 0);
 		pc.sense = sense;
+		pc.c[0] = GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL;
+		pc.c[4] = lockflag ? 1 : 0;
 		stat = cdrom_queue_packet_command (drive, &pc);
 	}
 
@@ -1544,7 +1555,7 @@
 /* Eject the disk if EJECTFLAG is 0.
    If EJECTFLAG is 1, try to reload the disk. */
 static int cdrom_eject(ide_drive_t *drive, int ejectflag,
-			struct request_sense *sense)
+		       struct request_sense *sense)
 {
 	struct packet_command pc;
 
@@ -1556,14 +1567,15 @@
 		return 0;
 
 	memset(&pc, 0, sizeof (pc));
+	pc.sense = sense;
+
 	pc.c[0] = GPCMD_START_STOP_UNIT;
 	pc.c[4] = 0x02 + (ejectflag != 0);
-	pc.sense = sense;
 	return cdrom_queue_packet_command (drive, &pc);
 }
 
 static int cdrom_read_capacity(ide_drive_t *drive, unsigned *capacity,
-				struct request_sense *sense)
+			       struct request_sense *sense)
 {
 	struct {
 		__u32 lba;
@@ -1573,16 +1585,16 @@
 	int stat;
 	struct packet_command pc;
 
-	memset(&pc, 0, sizeof (pc));
+	memset(&pc, 0, sizeof(pc));
+	pc.sense = sense;
 
 	pc.c[0] = GPCMD_READ_CDVD_CAPACITY;
 	pc.buffer = (char *)&capbuf;
 	pc.buflen = sizeof(capbuf);
-	pc.sense = sense;
 
 	stat = cdrom_queue_packet_command(drive, &pc);
 	if (stat == 0)
-		*capacity = be32_to_cpu(capbuf.lba) + 1;
+		*capacity = 1 + be32_to_cpu(capbuf.lba);
 
 	return stat;
 }
@@ -1614,10 +1626,10 @@
 /* Try to read the entire TOC for the disk into our internal buffer. */
 static int cdrom_read_toc(ide_drive_t *drive, struct request_sense *sense)
 {
-	int stat, ntracks, i;
+	int minor, stat, ntracks, i;
+	kdev_t dev;
 	struct cdrom_info *info = drive->driver_data;
 	struct atapi_toc *toc = info->toc;
-	int minor = drive->select.b.unit << PARTN_BITS;
 	struct {
 		struct atapi_toc_header hdr;
 		struct atapi_toc_entry  ent;
@@ -1625,7 +1637,7 @@
 
 	if (toc == NULL) {
 		/* Try to allocate space. */
-		toc = (struct atapi_toc *) kmalloc(sizeof(struct atapi_toc),
+		toc = (struct atapi_toc *) kmalloc (sizeof (struct atapi_toc),
 						    GFP_KERNEL);
 		info->toc = toc;
 		if (toc == NULL) {
@@ -1642,7 +1654,7 @@
 	if (CDROM_STATE_FLAGS (drive)->toc_valid) return 0;
 
 	/* First read just the header, so we know how long the TOC is. */
-	stat = cdrom_read_tocentry (drive, 0, 1, 0, (char *)&toc->hdr,
+	stat = cdrom_read_tocentry(drive, 0, 1, 0, (char *) &toc->hdr,
 				    sizeof(struct atapi_toc_header), sense);
 	if (stat) return stat;
 
@@ -1654,14 +1666,17 @@
 #endif  /* not STANDARD_ATAPI */
 
 	ntracks = toc->hdr.last_track - toc->hdr.first_track + 1;
-	if (ntracks <= 0) return -EIO;
-	if (ntracks > MAX_TRACKS) ntracks = MAX_TRACKS;
+	if (ntracks <= 0)
+		return -EIO;
+	if (ntracks > MAX_TRACKS)
+		ntracks = MAX_TRACKS;
 
 	/* Now read the whole schmeer. */
-	stat = cdrom_read_tocentry (drive, toc->hdr.first_track, 1, 0, (char *)&toc->hdr,
-				    sizeof (struct atapi_toc_header) +
-				    (ntracks + 1) *
-				    sizeof (struct atapi_toc_entry), sense);
+	stat = cdrom_read_tocentry(drive, toc->hdr.first_track, 1, 0,
+				  (char *)&toc->hdr,
+				   sizeof(struct atapi_toc_header) +
+				   (ntracks + 1) *
+				   sizeof(struct atapi_toc_entry), sense);
 
 	if (stat && toc->hdr.first_track > 1) {
 		/* Cds with CDI tracks only don't have any TOC entries,
@@ -1674,12 +1689,12 @@
 		   the readable TOC is empty (CDI tracks are not included)
 		   and only holds the Leadout entry. Heiko Eißfeldt */
 		ntracks = 0;
-		stat = cdrom_read_tocentry (drive, CDROM_LEADOUT, 1,
-					    0, (char *)&toc->hdr,
-					    sizeof (struct atapi_toc_header) +
-					   (ntracks+1) *
-					    sizeof (struct atapi_toc_entry),
-					    sense);
+		stat = cdrom_read_tocentry(drive, CDROM_LEADOUT, 1, 0,
+					   (char *)&toc->hdr,
+					   sizeof(struct atapi_toc_header) +
+					   (ntracks + 1) *
+					   sizeof(struct atapi_toc_entry),
+					   sense);
 		if (stat) {
 			return stat;
 		}
@@ -1724,7 +1739,7 @@
 	if (toc->hdr.first_track != CDROM_LEADOUT) {
 		/* Read the multisession information. */
 		stat = cdrom_read_tocentry(drive, 0, 1, 1, (char *)&ms_tmp,
-					   sizeof (ms_tmp), sense);
+					   sizeof(ms_tmp), sense);
 		if (stat) return stat;
 	} else {
 		ms_tmp.ent.addr.msf.minute = 0;
@@ -1745,40 +1760,20 @@
 	toc->xa_flag = (ms_tmp.hdr.first_track != ms_tmp.hdr.last_track);
 
 	/* Now try to get the total cdrom capacity. */
-#if 0
-	stat = cdrom_get_last_written(MKDEV(HWIF(drive)->major, minor),
-				     (long *)&toc->capacity);
+	minor = (drive->select.b.unit) << PARTN_BITS;
+	dev = MKDEV(HWIF(drive)->major, minor);
+	stat = cdrom_get_last_written(dev, (long *)&toc->capacity);
 	if (stat)
-#endif
-	stat = cdrom_read_capacity(drive, &toc->capacity, sense);
-	if (stat) toc->capacity = 0x1fffff;
+		stat = cdrom_read_capacity(drive, &toc->capacity, sense);
+	if (stat)
+		toc->capacity = 0x1fffff;
 
-	/* for general /dev/cdrom like mounting, one big disc */
+	HWIF(drive)->gd->sizes[drive->select.b.unit << PARTN_BITS] = (toc->capacity * SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
 	drive->part[0].nr_sects = toc->capacity * SECTORS_PER_FRAME;
-	HWIF(drive)->gd->sizes[minor] = (toc->capacity * SECTORS_PER_FRAME) >>
-					(BLOCK_SIZE_BITS - 9);
 
 	/* Remember that we've read this stuff. */
 	CDROM_STATE_FLAGS (drive)->toc_valid = 1;
 
-	/* should be "if multisession", but it does no harm. */
-	if (ntracks == 1)
-		return 0;
-
-	/* setup each minor to respond to a session */
-	minor++;
-	i = toc->hdr.first_track;
-	while ((i <= ntracks) && ((minor & CD_PART_MASK) < CD_PART_MAX)) {
-		drive->part[minor & PARTN_MASK].start_sect = 0;
- 		drive->part[minor & PARTN_MASK].nr_sects =
-			(toc->ent[i].addr.lba *
-			SECTORS_PER_FRAME) << (BLOCK_SIZE_BITS - 9);
-		HWIF(drive)->gd->sizes[minor] = (toc->ent[i].addr.lba *
-			SECTORS_PER_FRAME) >> (BLOCK_SIZE_BITS - 9);
-		i++;
-		minor++;
-	}
-
 	return 0;
 }
 
@@ -1821,9 +1816,8 @@
 	pc.c[2] = (speed >> 8) & 0xff;	
 	/* Read Drive speed in kbytes/second LSB */
 	pc.c[3] = speed & 0xff;
-	if (CDROM_CONFIG_FLAGS(drive)->cd_r ||
-            CDROM_CONFIG_FLAGS(drive)->cd_rw ||
-	    CDROM_CONFIG_FLAGS(drive)->dvd_r) {
+	if ( CDROM_CONFIG_FLAGS(drive)->cd_r ||
+                   CDROM_CONFIG_FLAGS(drive)->cd_rw ) {
 		/* Write Drive speed in kbytes/second MSB */
 		pc.c[4] = (speed >> 8) & 0xff;
 		/* Write Drive speed in kbytes/second LSB */
@@ -1874,14 +1868,18 @@
 	pc.buffer = cgc->buffer;
 	pc.buflen = cgc->buflen;
 	cgc->stat = cdrom_queue_packet_command(drive, &pc);
+
+	/*
+	 * FIXME: copy sense, don't just assign pointer!!
+	 */
 	cgc->sense = pc.sense;
 
 	return cgc->stat;
 }
 
 static
-int ide_cdrom_dev_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
-			unsigned long arg)
+int ide_cdrom_dev_ioctl (struct cdrom_device_info *cdi,
+			 unsigned int cmd, unsigned long arg)
 {
 	struct cdrom_generic_command cgc;
 	char buffer[16];
@@ -1977,18 +1975,19 @@
 }
 
 static
-int ide_cdrom_reset(struct cdrom_device_info *cdi)
+int ide_cdrom_reset (struct cdrom_device_info *cdi)
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	struct request_sense sense;
 	struct request req;
 	int ret;
 
-	ide_init_drive_cmd(&req);
+	ide_init_drive_cmd (&req);
 	req.cmd = RESET_DRIVE_COMMAND;
 	ret = ide_do_drive_cmd(drive, &req, ide_wait);
 
-	/* A reset will unlock the door. If it was previously locked,
+	/*
+	 * A reset will unlock the door. If it was previously locked,
 	 * lock it again.
 	 */
 	if (CDROM_STATE_FLAGS(drive)->door_locked)
@@ -1999,7 +1998,7 @@
 
 
 static
-int ide_cdrom_tray_move(struct cdrom_device_info *cdi, int position)
+int ide_cdrom_tray_move (struct cdrom_device_info *cdi, int position)
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	struct request_sense sense;
@@ -2019,19 +2018,17 @@
 	return cdrom_lockdoor(drive, lock, NULL);
 }
 
-
-
 static
-int ide_cdrom_select_speed(struct cdrom_device_info *cdi, int speed)
+int ide_cdrom_select_speed (struct cdrom_device_info *cdi, int speed)
 {
 	ide_drive_t *drive = (ide_drive_t*) cdi->handle;
 	struct request_sense sense;
 	int stat;
 
-	if ((stat = cdrom_select_speed(drive, speed, &sense)) < 0)
+	if ((stat = cdrom_select_speed (drive, speed, &sense)) < 0)
 		return stat;
 
-        cdi->speed = CDROM_STATE_FLAGS(drive)->current_speed;
+        cdi->speed = CDROM_STATE_FLAGS (drive)->current_speed;
         return 0;
 }
 
@@ -2072,10 +2069,11 @@
 	struct request_sense sense;
 	int ret;
 
-	toc = info->toc;
-	if (!CDROM_STATE_FLAGS(drive)->toc_valid || toc == NULL)
+	if (!CDROM_STATE_FLAGS(drive)->toc_valid || info->toc == NULL)
 		if ((ret = cdrom_read_toc(drive, &sense)))
 			return ret;
+
+	toc = info->toc;
 	ms_info->addr.lba = toc->last_session_lba;
 	ms_info->xa_flag = toc->xa_flag;
 
@@ -2121,6 +2119,7 @@
 		CDROM_STATE_FLAGS (drive)->media_changed = 0;
 		return retval;
 	}
+
 	return -EINVAL;
 }
 
@@ -2175,9 +2174,9 @@
 {
 	struct cdrom_info *info = drive->driver_data;
 	struct cdrom_device_info *devinfo = &info->devinfo;
-	int minor = (drive->select.b.unit)<<PARTN_BITS;
+	int minor = (drive->select.b.unit) << PARTN_BITS;
 
-	devinfo->dev = MKDEV (HWIF(drive)->major, minor | CD_PART_MASK);
+	devinfo->dev = MKDEV (HWIF(drive)->major, minor);
 	devinfo->ops = &ide_cdrom_dops;
 	devinfo->mask = 0;
 	*(int *)&devinfo->speed = CDROM_STATE_FLAGS (drive)->current_speed;
@@ -2202,8 +2201,8 @@
 		devinfo->mask |= CDC_PLAY_AUDIO;
 	if (!CDROM_CONFIG_FLAGS (drive)->close_tray)
 		devinfo->mask |= CDC_CLOSE_TRAY;
-		
-	return register_cdrom (devinfo);
+
+	return register_cdrom(devinfo);
 }
 
 static
@@ -2392,7 +2391,9 @@
 	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"))
+		if (!strcmp(drive->id->model, "SAMSUNG SCR-2030"))
+			CDROM_CONFIG_FLAGS (drive)->limit_nframes = 1;
+		else 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;
@@ -2519,9 +2520,17 @@
 static
 int ide_cdrom_check_media_change (ide_drive_t *drive)
 {
-	return cdrom_fops.check_media_change
-		(MKDEV (HWIF (drive)->major,
-			(drive->select.b.unit)<<PARTN_BITS));
+	return cdrom_fops.check_media_change(MKDEV (HWIF (drive)->major,
+			(drive->select.b.unit) << PARTN_BITS));
+}
+
+static
+unsigned long ide_cdrom_capacity (ide_drive_t *drive)
+{
+	unsigned capacity;
+
+	return cdrom_read_capacity(drive, &capacity, NULL)
+		? 0 : capacity * SECTORS_PER_FRAME;
 }
 
 static
@@ -2560,12 +2569,12 @@
 	ide_cdrom_release,		/* release */
 	ide_cdrom_check_media_change,	/* media_change */
 	NULL,				/* pre_reset */
-	NULL,				/* capacity */
+	ide_cdrom_capacity,		/* capacity */
 	NULL,				/* special */
 	NULL				/* proc */
 };
 
-int ide_cdrom_init (void);
+int ide_cdrom_init(void);
 static ide_module_t ide_cdrom_module = {
 	IDE_DRIVER_MODULE,
 	ide_cdrom_init,
@@ -2597,9 +2606,10 @@
 {
 	return ide_cdrom_init();
 }
+
 #endif /* MODULE */
  
-int ide_cdrom_init (void)
+int ide_cdrom_init(void)
 {
 	ide_drive_t *drive;
 	struct cdrom_info *info;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide-cd.h linux.17p18/drivers/block/ide-cd.h
--- linux.vanilla/drivers/block/ide-cd.h	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/ide-cd.h	Tue Aug  1 18:23:15 2000
@@ -1,11 +1,11 @@
-#ifndef _IDE_CD_H
-#define _IDE_CD_H
 /*
- *  linux/drivers/block/ide_cd.h
+ *  linux/drivers/ide/ide_cd.h
  *
- *  Copyright (C) 1996, 1997, 1998  Erik Andersen
- *  Copyright (C) 1998, 1999, 2000  Jens Axboe
+ *  Copyright (C) 1996-98  Erik Andersen
+ *  Copyright (C) 1998-2000 Jens Axboe
  */
+#ifndef _IDE_CD_H
+#define _IDE_CD_H
 
 #include <linux/cdrom.h>
 #include <asm/byteorder.h>
@@ -43,6 +43,8 @@
 #define SECTOR_BUFFER_SIZE	(CD_FRAMESIZE * 32)
 #define SECTORS_BUFFER		(SECTOR_BUFFER_SIZE / SECTOR_SIZE)
 
+#define BLOCKS_PER_FRAME	(CD_FRAMESIZE / BLOCK_SIZE)
+
 #define MIN(a,b) ((a) < (b) ? (a) : (b))
 
 /* special command codes for strategy routine. */
@@ -101,6 +103,7 @@
 	char *buffer;
 	int buflen;
 	int stat;
+	int quiet;
 	struct request_sense *sense;
 	unsigned char c[12];
 };
@@ -397,7 +400,6 @@
 	unsigned short buffer_size;
 	/* Current speed (in kB/s). */
 	unsigned short curspeed;
-
 	char pad[4];
 };
 
@@ -624,9 +626,7 @@
 	  "Logical unit not ready - in progress [sic] of becoming ready" },
 	{ 0x020402, "Logical unit not ready - initializing command required" },
 	{ 0x020403, "Logical unit not ready - manual intervention required" },
-	{ 0x020404, "Logical unit not ready - format in progress" },
-	{ 0x020407, "Logical unit not ready - operation in progress" },
-	{ 0x020408, "Logical unit not ready - long write in progress" },
+	{ 0x020404, "In process of becoming ready - writing" },
 	{ 0x020600, "No reference position found (media may be upside down)" },
 	{ 0x023000, "Incompatible medium installed" },
 	{ 0x023a00, "Medium not present" },
@@ -676,6 +676,7 @@
 	{ 0x04b600, "Media load mechanism failed" },
 	{ 0x051a00, "Parameter list length error" },
 	{ 0x052000, "Invalid command operation code" },
+	{ 0x052c00, "Command sequence error" },
 	{ 0x052100, "Logical block address out of range" },
 	{ 0x052102, "Invalid address for write" },
 	{ 0x052400, "Invalid field in command packet" },
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide-floppy.c linux.17p18/drivers/block/ide-floppy.c
--- linux.vanilla/drivers/block/ide-floppy.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/ide-floppy.c	Tue Aug  1 07:59:25 2000
@@ -1400,6 +1400,13 @@
 
 	*((unsigned short *) &gcw) = id->config;
 
+#ifdef CONFIG_PPC
+	/* kludge for Apple PowerBook internal zip */
+	if ((gcw.device_type == 5) && !strstr(id->model, "CD-ROM")
+	    && strstr(id->model, "ZIP"))
+		gcw.device_type = 0;			
+#endif
+
 #if IDEFLOPPY_DEBUG_INFO
 	printk (KERN_INFO "Dumping ATAPI Identify Device floppy parameters\n");
 	switch (gcw.protocol) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide-pmac.c linux.17p18/drivers/block/ide-pmac.c
--- linux.vanilla/drivers/block/ide-pmac.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/ide-pmac.c	Tue Aug  1 07:59:25 2000
@@ -5,6 +5,8 @@
  *
  *  Copyright (C) 1998 Paul Mackerras.
  *
+ *  Bits from Benjamin Herrenschmidt
+ *
  *  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
@@ -35,26 +37,101 @@
 #include "ide.h"
 #include "ide_modes.h"
 
-ide_ioreg_t pmac_ide_regbase[MAX_HWIFS];
-int pmac_ide_irq[MAX_HWIFS];
-int pmac_ide_count;
-struct device_node *pmac_ide_node[MAX_HWIFS];
+#undef IDE_PMAC_DEBUG
+
+#define IDE_SYSCLK_NS		30
+#define IDE_SYSCLK_ULTRA_PS	0x1d4c /* (15 * 1000 / 2)*/
+
+struct pmac_ide_hwif {
+	ide_ioreg_t			regbase;
+	int				irq;
+	int				kind;
+	int				aapl_bus_id;
+	struct device_node*		node;
+	u32				timings[2];
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+	volatile struct dbdma_regs*	dma_regs;
+	struct dbdma_cmd*		dma_table;
+#endif
+	
+} pmac_ide[MAX_HWIFS];
+
+static int pmac_ide_count;
+
+enum {
+	controller_ohare,	/* OHare based */
+	controller_heathrow,	/* Heathrow/Paddington */
+	controller_kl_ata3,	/* KeyLargo ATA-3 */
+	controller_kl_ata4	/* KeyLargo ATA-4 */
+};
+
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+
+typedef struct {
+	int	accessTime;
+	int	cycleTime;
+} pmac_ide_timing;
+
+/* Multiword DMA timings */
+static pmac_ide_timing mdma_timings[] =
+{
+    { 215,    480 },	/* Mode 0 */
+    {  80,    150 },	/*      1 */
+    {  70,    120 }	/*      2 */
+};
+
+/* Ultra DMA timings (for use when I know how to calculate them */
+static pmac_ide_timing udma_timings[] =
+{
+    {   0,    114 },	/* Mode 0 */
+    {   0,     75 },	/*      1 */
+    {   0,     55 },	/*      2 */
+    {   100,   45 },	/*      3 */
+    {   100,   25 }	/*      4 */
+};
+
+/* allow up to 256 DBDMA commands per xfer */
+#define MAX_DCMDS	256
+/* Wait 1.5s for disk to answer on IDE bus after
+ * enable operation.
+ * NOTE: There is at least one case I know of a disk that needs about 10sec
+ *       before anwering on the bus. I beleive we could add a kernel command
+ *       line arg to override this delay for such cases.
+ */
+#define IDE_WAKEUP_DELAY_MS	1500
 #define MAX_DCMDS	256	/* allow up to 256 DBDMA commands per xfer */
 
-static void pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif);
+static void pmac_ide_setup_dma(struct device_node *np, int ix);
 static int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive);
-static int pmac_ide_build_dmatable(ide_drive_t *drive, int wr);
+static int pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr);
+static void pmac_ide_tuneproc(ide_drive_t *drive, byte pio);
+static void pmac_ide_selectproc(ide_drive_t *drive);
+
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
 #ifdef CONFIG_PMAC_PBOOK
-static int idepmac_notify(struct pmu_sleep_notifier *self, int when);
+static int idepmac_notify_sleep(struct pmu_sleep_notifier *self, int when);
 struct pmu_sleep_notifier idepmac_sleep_notifier = {
-	idepmac_notify, SLEEP_LEVEL_BLOCK,
+	idepmac_notify_sleep, SLEEP_LEVEL_BLOCK,
 };
 #endif /* CONFIG_PMAC_PBOOK */
 
+static int
+pmac_ide_find(ide_drive_t *drive)
+{
+	ide_hwif_t *hwif = HWIF(drive);
+	ide_ioreg_t base;
+	int i;
+	
+	for (i=0; i<pmac_ide_count; i++) {
+		base = pmac_ide[i].regbase;
+		if (base && base == hwif->io_ports[0])
+			return i;
+	}
+	return -1;
+}
+
 /*
  * N.B. this can't be an initfunc, because the media-bay task can
  * call ide_[un]register at any time.
@@ -69,7 +146,7 @@
 		return;
 
 	for (ix = 0; ix < MAX_HWIFS; ++ix)
-		if (base == pmac_ide_regbase[ix])
+		if (base == pmac_ide[ix].regbase)
 			break;
 
 	if (ix >= MAX_HWIFS) {
@@ -83,35 +160,130 @@
 		return;
 	}
 
-	/* we check only for -EINVAL meaning that we have found a matching
-	   bay but with the wrong device type */ 
-
-	i = check_media_bay_by_base(base, MB_CD);
-	if (i == -EINVAL)
-		return;
-		
 	for (i = 0; i < 8; ++i)
 		*p++ = base + i * 0x10;
 	*p = base + 0x160;
 	if (irq != NULL)
-		*irq = pmac_ide_irq[ix];
+		*irq = pmac_ide[ix].irq;
+
+	ide_hwifs[ix].tuneproc = pmac_ide_tuneproc;
+	ide_hwifs[ix].selectproc = pmac_ide_selectproc;
+	if (pmac_ide[ix].dma_regs && pmac_ide[ix].dma_table) {
+		ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
+#ifdef CONFIG_PMAC_IDEDMA_AUTO
+		ide_hwifs[ix].autodma = 1;
+#endif
+	}
 }
 
-void pmac_ide_tuneproc(ide_drive_t *drive, byte pio)
+#if 0
+/* This one could be later extended to handle CMD IDE and be used by some kind
+ * of /proc interface. I want to be able to get the devicetree path of a block
+ * device for yaboot configuration
+ */
+struct device_node*
+pmac_ide_get_devnode(ide_drive_t *drive)
 {
-	ide_pio_data_t d;
+	int i = pmac_ide_find(drive);
+	if (i < 0)
+		return NULL;
+	return pmac_ide[i].node;
+}
+#endif
 
-	if (_machine != _MACH_Pmac)
+/* Setup timings for the selected drive (master/slave). I still need to verify if this
+ * is enough, I beleive selectproc will be called whenever an IDE command is started,
+ * but... */
+static void
+pmac_ide_selectproc(ide_drive_t *drive)
+{
+	int i = pmac_ide_find(drive);
+	if (i < 0)
+		return;
+			
+	if (drive->select.all & 0x10)
+		out_le32((unsigned *)(IDE_DATA_REG + 0x200 + _IO_BASE), pmac_ide[i].timings[1]);
+	else
+		out_le32((unsigned *)(IDE_DATA_REG + 0x200 + _IO_BASE), pmac_ide[i].timings[0]);
+}
+
+/* Number of IDE_SYSCLK_NS ticks, argument is in nanoseconds */
+#define SYSCLK_TICKS(t)		(((t) + IDE_SYSCLK_NS - 1) / IDE_SYSCLK_NS)
+#define SYSCLK_TICKS_UDMA(t)	(((t) + IDE_SYSCLK_ULTRA_PS - 1) / IDE_SYSCLK_ULTRA_PS)
+
+/* Calculate PIO timings */
+static void
+pmac_ide_tuneproc(ide_drive_t *drive, byte pio)
+{
+	ide_pio_data_t d;
+	int i;
+	u32 *timings;
+	int accessTicks, recTicks;
+	
+	i = pmac_ide_find(drive);
+	if (i < 0)
 		return;
+		
 	pio = ide_get_best_pio_mode(drive, pio, 4, &d);
-	switch (pio) {
-	case 4:
-		out_le32((unsigned *)(IDE_DATA_REG + 0x200 + _IO_BASE), 0x211025);
-		break;
-	default:
-		out_le32((unsigned *)(IDE_DATA_REG + 0x200 + _IO_BASE), 0x2f8526);
-		break;
+	if (drive->select.all & 0x10)
+		timings = &pmac_ide[i].timings[1];
+	else
+		timings = &pmac_ide[i].timings[0];
+
+	if (pmac_ide[i].kind == controller_kl_ata4) {
+		/* The "ata-4" IDE controller of Core99 machines */
+		accessTicks = SYSCLK_TICKS_UDMA(ide_pio_timings[pio].active_time * 1000);
+		recTicks = SYSCLK_TICKS_UDMA(d.cycle_time * 1000) - accessTicks;
+
+		*timings = ((*timings) & 0x1FFFFFC00) | accessTicks | (recTicks << 5);
+	} else {
+		/* The old "ata-3" IDE controller */
+		accessTicks = SYSCLK_TICKS(ide_pio_timings[pio].active_time);
+		if (accessTicks < 4)
+			accessTicks = 4;
+		recTicks = SYSCLK_TICKS(d.cycle_time) - accessTicks - 4;
+		if (recTicks < 1)
+			recTicks = 1;
+	
+		*timings = ((*timings) & 0xFFFFFF800) | accessTicks | (recTicks << 5);
+	}
+	
+#ifdef IDE_PMAC_DEBUG
+	printk("ide_pmac: Set PIO timing for mode %d, reg: 0x%08x\n",
+		pio,  *timings);
+#endif	
+		
+	if (drive->select.all == IN_BYTE(IDE_SELECT_REG))
+		pmac_ide_selectproc(drive);
+}
+
+ide_ioreg_t
+pmac_ide_get_base(int index)
+{
+	return pmac_ide[index].regbase;
+}
+
+static int ide_majors[] = { 3, 22, 33, 34, 56, 57 };
+
+__initfunc(kdev_t pmac_find_ide_boot(char *bootdevice, int n))
+{
+	int i;
+	
+	/*
+	 * Look through the list of IDE interfaces for this one.
+	 */
+	for (i = 0; i < pmac_ide_count; ++i) {
+		char *name;
+		if (!pmac_ide[i].node || !pmac_ide[i].node->full_name)
+			continue;
+		name = pmac_ide[i].node->full_name;
+		if (memcmp(name, bootdevice, n) == 0 && name[n] == 0) {
+			/* XXX should cope with the 2nd drive as well... */
+			return MKDEV(ide_majors[i], 0);
+		}
 	}
+
+	return 0;
 }
 
 __initfunc(void
@@ -122,7 +294,7 @@
 	struct device_node *atas;
 	struct device_node *p, **pp, *removables, **rp;
 	unsigned long base;
-	int irq;
+	int irq, big_delay;
 	ide_hwif_t *hwif;
 
 	if (_machine != _MACH_Pmac)
@@ -150,9 +322,11 @@
 	}
 	*rp = NULL;
 	*pp = removables;
+	big_delay = 0;
 
 	for (i = 0, np = atas; i < MAX_HWIFS && np != NULL; np = np->next) {
 		struct device_node *tp;
+		int *bidp;
 
 		/*
 		 * If this node is not under a mac-io or dbdma node,
@@ -193,32 +367,79 @@
 		} else {
 			irq = np->intrs[0].line;
 		}
-		pmac_ide_regbase[i] = base;
-		pmac_ide_irq[i] = irq;
-		pmac_ide_node[i] = np;
+		pmac_ide[i].regbase = base;
+		pmac_ide[i].irq = irq;
+		pmac_ide[i].node = np;
+		if (device_is_compatible(np, "keylargo-ata")) {
+			if (strcmp(np->name, "ata-4") == 0)
+				pmac_ide[i].kind = controller_kl_ata4;
+			else
+				pmac_ide[i].kind = controller_kl_ata3;
+		} else if (device_is_compatible(np, "heathrow-ata"))
+			pmac_ide[i].kind = controller_heathrow;
+		else
+			pmac_ide[i].kind = controller_ohare;
+
+		bidp = (int *)get_property(np, "AAPL,bus-id", NULL);
+		pmac_ide[i].aapl_bus_id =  bidp ? *bidp : 0;
 
 		if (np->parent && np->parent->name
 		    && strcasecmp(np->parent->name, "media-bay") == 0) {
 			media_bay_set_ide_infos(np->parent,base,irq,i);
-		} else
-			feature_set(np, FEATURE_IDE_enable);
-
+		} else if (pmac_ide[i].kind == controller_ohare) {
+			/* The code below is having trouble on some ohare machines
+			 * (timing related ?). Until I can put my hand on one of these
+			 * units, I keep the old way
+			 */
+			 feature_set(np, FEATURE_IDE0_enable);
+			 feature_set(np, FEATURE_IOBUS_enable);
+		} else {
+			/* This is necessary to enable IDE when net-booting */
+			printk("pmac_ide: enabling IDE bus ID %d\n", pmac_ide[i].aapl_bus_id);
+			switch(pmac_ide[i].aapl_bus_id) {
+			    case 0:
+				feature_set(np, FEATURE_IDE0_reset);
+				feature_set(np, FEATURE_IOBUS_enable);
+				mdelay(10);
+ 				feature_set(np, FEATURE_IDE0_enable);
+				mdelay(10);
+				feature_clear(np, FEATURE_IDE0_reset);
+				break;
+			    case 1:
+				feature_set(np, FEATURE_IDE1_reset);
+				feature_set(np, FEATURE_IOBUS_enable);
+				mdelay(10);
+ 				feature_set(np, FEATURE_IDE1_enable);
+				mdelay(10);
+				feature_clear(np, FEATURE_IDE1_reset);
+				break;
+			    case 2:
+			    	/* This one exists only for KL, I don't know
+				   about any enable bit */
+				feature_set(np, FEATURE_IDE2_reset);
+				mdelay(10);
+				feature_clear(np, FEATURE_IDE2_reset);
+				break;
+			}
+			big_delay = 1;
+		}
 		hwif = &ide_hwifs[i];
 		pmac_ide_init_hwif_ports(hwif->io_ports, base, &hwif->irq);
-		hwif->chipset = ide_generic;
-		hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
-		hwif->tuneproc = pmac_ide_tuneproc;
+		hwif->chipset = ide_pmac;
+		hwif->noprobe = (check_media_bay_by_base(base, MB_CD) == -EINVAL);
 
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 		if (np->n_addrs >= 2) {
 			/* has a DBDMA controller channel */
-			pmac_ide_setup_dma(np, hwif);
+			pmac_ide_setup_dma(np, i);
 		}
 #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */
 
 		++i;
 	}
 	pmac_ide_count = i;
+	if (big_delay)
+		mdelay(IDE_WAKEUP_DELAY_MS);
 
 #ifdef CONFIG_PMAC_PBOOK
 	pmu_register_sleep_notifier(&idepmac_sleep_notifier);
@@ -228,26 +449,27 @@
 #ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
 
 __initfunc(static void
-pmac_ide_setup_dma(struct device_node *np, ide_hwif_t *hwif))
+pmac_ide_setup_dma(struct device_node *np, int ix))
 {
-	hwif->dma_base = (unsigned long) ioremap(np->addrs[1].address, 0x200);
+	pmac_ide[ix].dma_regs =
+		(volatile struct dbdma_regs*)ioremap(np->addrs[1].address, 0x200);
 
 	/*
 	 * Allocate space for the DBDMA commands.
 	 * The +2 is +1 for the stop command and +1 to allow for
 	 * aligning the start address to a multiple of 16 bytes.
 	 */
-	hwif->dmatable = (unsigned long *)
-	       kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);
-	if (hwif->dmatable == 0) {
+	pmac_ide[ix].dma_table = (struct dbdma_cmd*)
+		kmalloc((MAX_DCMDS + 2) * sizeof(struct dbdma_cmd), GFP_KERNEL);
+	if (pmac_ide[ix].dma_table == 0) {
 		printk(KERN_ERR "%s: unable to allocate DMA command list\n",
-		       hwif->name);
+		       ide_hwifs[ix].name);
 		return;
 	}
 
-	hwif->dmaproc = &pmac_ide_dmaproc;
+	ide_hwifs[ix].dmaproc = &pmac_ide_dmaproc;
 #ifdef CONFIG_PMAC_IDEDMA_AUTO
-	hwif->autodma = 1;
+	ide_hwifs[ix].autodma = 1;
 #endif
 }
 
@@ -256,19 +478,20 @@
  * for a transfer and sets the DBDMA channel to point to it.
  */
 static int
-pmac_ide_build_dmatable(ide_drive_t *drive, int wr)
+pmac_ide_build_dmatable(ide_drive_t *drive, int ix, int wr)
 {
-	ide_hwif_t *hwif = HWIF(drive);
 	struct dbdma_cmd *table, *tstart;
 	int count = 0;
 	struct request *rq = HWGROUP(drive)->rq;
 	struct buffer_head *bh = rq->bh;
 	unsigned int size, addr;
-	volatile struct dbdma_regs *dma
-		= (volatile struct dbdma_regs *) hwif->dma_base;
+	volatile struct dbdma_regs *dma = pmac_ide[ix].dma_regs;
 
-	table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(hwif->dmatable);
+	table = tstart = (struct dbdma_cmd *) DBDMA_ALIGN(pmac_ide[ix].dma_table);
 	out_le32(&dma->control, (RUN|PAUSE|FLUSH|WAKE|DEAD) << 16);
+	/* Should this be dma->control like in macserial.c ? */
+	while (in_le32(&dma->status) & RUN)
+		udelay(1);
 
 	do {
 		/*
@@ -331,30 +554,274 @@
 	return 1;
 }
 
+
+/* This is fun.  -DaveM */
+#define IDE_SETXFER		0x03
+#define IDE_SETFEATURE		0xef
+#define IDE_DMA2_ENABLE		0x22
+#define IDE_DMA1_ENABLE		0x21
+#define IDE_DMA0_ENABLE		0x20
+#define IDE_UDMA4_ENABLE	0x44
+#define IDE_UDMA3_ENABLE	0x43
+#define IDE_UDMA2_ENABLE	0x42
+#define IDE_UDMA1_ENABLE	0x41
+#define IDE_UDMA0_ENABLE	0x40
+
+static __inline__ unsigned char
+dma_bits_to_command(unsigned char bits)
+{
+	if(bits & 0x04)
+		return IDE_DMA2_ENABLE;
+	if(bits & 0x02)
+		return IDE_DMA1_ENABLE;
+	return IDE_DMA0_ENABLE;
+}
+
+static __inline__ unsigned char
+udma_bits_to_command(unsigned char bits)
+{
+	if(bits & 0x10)
+		return IDE_UDMA4_ENABLE;
+	if(bits & 0x08)
+		return IDE_UDMA3_ENABLE;
+	if(bits & 0x04)
+		return IDE_UDMA2_ENABLE;
+	if(bits & 0x02)
+		return IDE_UDMA1_ENABLE;
+	if(bits & 0x01)
+		return IDE_UDMA0_ENABLE;
+	return 0;
+}
+
+static __inline__ int
+wait_for_ready(ide_drive_t *drive)
+{
+	/* Timeout bumped for some powerbooks */
+	int timeout = 2000;
+	byte stat;
+
+	while(--timeout) {
+		stat = GET_STAT();
+		if(!(stat & BUSY_STAT)) {
+			if (drive->ready_stat == 0)
+				break;
+			else if((stat & drive->ready_stat) || (stat & ERR_STAT))
+				break;
+		}
+		mdelay(1);
+	}
+	if((stat & ERR_STAT) || timeout <= 0) {
+		if (stat & ERR_STAT) {
+			printk("ide_pmace: wait_for_ready, error status: %x\n", stat);
+		}
+		return 1;
+	}
+	return 0;
+}
+
+static int
+pmac_ide_do_setfeature(ide_drive_t *drive, byte command)
+{
+	unsigned long flags;
+	byte old_select;
+	int result = 1;
+
+	save_flags(flags);
+	cli();
+	old_select = IN_BYTE(IDE_SELECT_REG);
+	OUT_BYTE(drive->select.all, IDE_SELECT_REG);
+	udelay(10);
+	OUT_BYTE(IDE_SETXFER, IDE_FEATURE_REG);
+	OUT_BYTE(command, IDE_NSECTOR_REG);
+	if(wait_for_ready(drive)) {
+		printk("pmac_ide_do_setfeature disk not ready before SET_FEATURE!\n");
+		goto out;
+	}
+	OUT_BYTE(IDE_SETFEATURE, IDE_COMMAND_REG);
+	result = wait_for_ready(drive);
+	if (result)
+		printk("pmac_ide_do_setfeature disk not ready after SET_FEATURE !\n");
+out:
+	OUT_BYTE(old_select, IDE_SELECT_REG);
+	restore_flags(flags);
+	
+	return result;
+}
+
+/* Calculate MultiWord DMA timings */
+static int
+pmac_ide_mdma_enable(ide_drive_t *drive, int idx)
+{
+	byte bits = drive->id->dma_mword & 0x07;
+	byte feature = dma_bits_to_command(bits);
+	u32 *timings;
+	int cycleTime, accessTime;
+	int accessTicks, recTicks;
+	struct hd_driveid *id = drive->id;
+	
+	/* Set feature on drive */
+    	printk("%s: Enabling MultiWord DMA %d\n", drive->name, feature & 0xf);
+	if (pmac_ide_do_setfeature(drive, feature)) {
+	    	printk("%s: Failed !\n", drive->name);
+	    	return 0;
+	}
+	
+	/* which drive is it ? */
+	if (drive->select.all & 0x10)
+		timings = &pmac_ide[idx].timings[1];
+	else
+		timings = &pmac_ide[idx].timings[0];
+
+	/* Calculate accesstime and cycle time */
+	cycleTime = mdma_timings[feature & 0xf].cycleTime;
+	accessTime = mdma_timings[feature & 0xf].accessTime;
+	if ((id->field_valid & 2) && (id->eide_dma_time))
+		cycleTime = id->eide_dma_time;
+	if ((pmac_ide[idx].kind == controller_ohare) && (cycleTime < 150))
+		cycleTime = 150;
+
+	/* For ata-4 controller, we don't know the calculation */
+	if (pmac_ide[idx].kind == controller_kl_ata4) {
+		accessTicks = SYSCLK_TICKS_UDMA(accessTime * 1000);
+		recTicks = SYSCLK_TICKS_UDMA(cycleTime * 1000) - accessTicks;
+		*timings = ((*timings) & 0xffe003ff) |
+			(accessTicks | (recTicks << 5)) << 10;
+	} else {
+		int halfTick = 0;
+		int origAccessTime = accessTime;
+		int origCycleTime = cycleTime;
+		
+		accessTicks = SYSCLK_TICKS(accessTime);
+		if (accessTicks < 1)
+			accessTicks = 1;
+		accessTime = accessTicks * IDE_SYSCLK_NS;
+		recTicks = SYSCLK_TICKS(cycleTime - accessTime) - 1;
+		if (recTicks < 1)
+			recTicks = 1;
+		cycleTime = (recTicks + 1 + accessTicks) * IDE_SYSCLK_NS;
+
+		/* KeyLargo ata-3 don't support the half-tick stuff */
+		if ((pmac_ide[idx].kind != controller_kl_ata3) &&
+			(accessTicks > 1) &&
+			((accessTime - IDE_SYSCLK_NS/2) >= origAccessTime) &&
+			((cycleTime - IDE_SYSCLK_NS) >= origCycleTime)) {
+            			halfTick    = 1;
+				accessTicks--;
+		}
+		*timings = ((*timings) & 0x7FF) |
+			(accessTicks | (recTicks << 5) | (halfTick << 10)) << 11;
+	}
+#ifdef IDE_PMAC_DEBUG
+	printk("ide_pmac: Set MDMA timing for mode %d, reg: 0x%08x\n",
+		feature & 0xf, *timings);
+#endif	
+	return 1;
+}
+
+/* Calculate Ultra DMA timings */
+static int
+pmac_ide_udma_enable(ide_drive_t *drive, int idx)
+{
+	byte bits = drive->id->dma_ultra & 0x1f;
+	byte feature = udma_bits_to_command(bits);
+	int cycleTime, accessTime;
+	int rdyToPauseTicks, cycleTicks;
+	u32 *timings;
+	
+	/* Set feature on drive */
+    	printk("%s: Enabling Ultra DMA %d\n", drive->name, feature & 0xf);
+	if (pmac_ide_do_setfeature(drive, feature)) {
+		printk("%s: Failed !\n", drive->name);
+		return 0;
+	}
+
+	/* which drive is it ? */
+	if (drive->select.all & 0x10)
+		timings = &pmac_ide[idx].timings[1];
+	else
+		timings = &pmac_ide[idx].timings[0];
+	
+
+	cycleTime = udma_timings[feature & 0xf].cycleTime;
+	accessTime = udma_timings[feature & 0xf].accessTime;
+
+	rdyToPauseTicks = SYSCLK_TICKS_UDMA(accessTime * 1000);
+	cycleTicks = SYSCLK_TICKS_UDMA(cycleTime * 1000);
+	
+	*timings = ((*timings) & 0xe00fffff) |
+			((cycleTicks << 1) | (rdyToPauseTicks << 5) | 1) << 20;
+	return 1;
+}
+
+static int
+pmac_ide_dma_onoff(ide_drive_t *drive, int enable)
+{
+	int ata4, udma, idx;
+	struct hd_driveid *id = drive->id;
+
+	drive->using_dma = 0;
+	
+	idx = pmac_ide_find(drive);
+	if (idx < 0)
+		return 0;
+		
+	if (drive->media == ide_floppy)
+		enable = 0;
+	if (((id->capability & 1) == 0) && !check_drive_lists(drive, GOOD_DMA_DRIVE))
+		enable = 0;
+	if (check_drive_lists(drive, BAD_DMA_DRIVE))
+		enable = 0;
+
+	udma = 0;
+	ata4 = (pmac_ide[idx].kind == controller_kl_ata4);
+			
+	if(enable) {
+		if (ata4 && (drive->media == ide_disk) &&
+		    (id->field_valid & 0x0004) && (id->dma_ultra & 0x17)) {
+			/* UltraDMA modes. */
+			drive->using_dma = pmac_ide_udma_enable(drive, idx);
+		}
+		if (!drive->using_dma && (id->dma_mword & 0x0007)) {
+			/* Normal MultiWord DMA modes. */
+			drive->using_dma = pmac_ide_mdma_enable(drive, idx);
+		}
+		/* Without this, strange things will happen on Keylargo-based
+		 * machines
+		 */
+		OUT_BYTE(0, IDE_CONTROL_REG);
+		if (drive->select.all == IN_BYTE(IDE_SELECT_REG))
+			pmac_ide_selectproc(drive);
+	}
+	return 0;
+}
+
 int pmac_ide_dmaproc(ide_dma_action_t func, ide_drive_t *drive)
 {
 	ide_hwif_t *hwif = HWIF(drive);
-	volatile struct dbdma_regs *dma
-		= (volatile struct dbdma_regs *) hwif->dma_base;
-	int dstat;
+	int ix, dstat;
+	volatile struct dbdma_regs *dma;
+
+	/* Can we stuff a pointer to our intf structure in config_data
+	 * or select_data in hwif ?
+	 */
+	ix = pmac_ide_find(drive);
+	if (ix < 0)
+		return 0;		
+	dma = pmac_ide[ix].dma_regs;
 
 	switch (func) {
 	case ide_dma_on:
-		/* ide-floppy DMA doesn't work yet... */
-		drive->using_dma = drive->media != ide_floppy;
-		break;
 	case ide_dma_off:
-		printk(KERN_INFO "%s: DMA disabled\n", drive->name);
 	case ide_dma_off_quietly:
-		drive->using_dma = 0;
+		pmac_ide_dma_onoff(drive, (func == ide_dma_on));
 		break;
 	case ide_dma_check:
-		/* ide-floppy DMA doesn't work yet... */
-		drive->using_dma = hwif->autodma && drive->media != ide_floppy;
+		if (hwif->autodma)
+			pmac_ide_dma_onoff(drive, 1);
 		break;
 	case ide_dma_read:
 	case ide_dma_write:
-		if (!pmac_ide_build_dmatable(drive, func==ide_dma_write))
+		if (!pmac_ide_build_dmatable(drive, ix, func==ide_dma_write))
 			return 1;
 		drive->waiting_for_dma = 1;
 		if (drive->media != ide_disk)
@@ -383,11 +850,9 @@
 #ifdef CONFIG_PMAC_PBOOK
 static void idepmac_sleep_disk(int i, unsigned long base)
 {
+	struct device_node* np = pmac_ide[i].node;
 	int j;
 
-	/* Reset to PIO 0 */
-	out_le32((unsigned *)(base + 0x200 + _IO_BASE), 0x2f8526);
-
 	/* FIXME: We only handle the master IDE */
 	if (ide_hwifs[i].drives[0].media == ide_disk) {
 		/* Spin down the drive */
@@ -406,22 +871,61 @@
 				break;
 		}
 	}
+	feature_set(np, FEATURE_IDE0_reset);
+	feature_clear(np, FEATURE_IDE0_enable);
+	switch(pmac_ide[i].aapl_bus_id) {
+	    case 0:
+		feature_set(np, FEATURE_IDE0_reset);
+		feature_clear(np, FEATURE_IDE0_enable);
+		break;
+	    case 1:
+		feature_set(np, FEATURE_IDE1_reset);
+		feature_clear(np, FEATURE_IDE1_enable);
+		break;
+	    case 2:
+		feature_set(np, FEATURE_IDE2_reset);
+		break;
+	}
+	pmac_ide[i].timings[0] = 0;
+	pmac_ide[i].timings[1] = 0;
 }
 
 static void idepmac_wake_disk(int i, unsigned long base)
 {
+	struct device_node* np = pmac_ide[i].node;
 	int j;
 
 	/* Revive IDE disk and controller */
-	feature_set(pmac_ide_node[i], FEATURE_IDE_enable);
-	mdelay(1);
-	feature_set(pmac_ide_node[i], FEATURE_IDE_DiskPower);
-	mdelay(100);
-	feature_set(pmac_ide_node[i], FEATURE_IDE_Reset);
-	mdelay(1);
-	/* Make sure we are still PIO0 */
-	out_le32((unsigned *)(base + 0x200 + _IO_BASE), 0x2f8526);
-	mdelay(100);
+	switch(pmac_ide[i].aapl_bus_id) {
+	    case 0:
+		feature_set(np, FEATURE_IDE0_reset);
+		feature_set(np, FEATURE_IOBUS_enable);
+		mdelay(10);
+ 		feature_set(np, FEATURE_IDE0_enable);
+		mdelay(10);
+		feature_clear(np, FEATURE_IDE0_reset);
+		break;
+	    case 1:
+		feature_set(np, FEATURE_IDE1_reset);
+		feature_set(np, FEATURE_IOBUS_enable);
+		mdelay(10);
+ 		feature_set(np, FEATURE_IDE1_enable);
+		mdelay(10);
+		feature_clear(np, FEATURE_IDE1_reset);
+		break;
+	    case 2:
+	    	/* This one exists only for KL, I don't know
+		   about any enable bit */
+		feature_set(np, FEATURE_IDE2_reset);
+		mdelay(10);
+		feature_clear(np, FEATURE_IDE2_reset);
+		break;
+	}
+	mdelay(IDE_WAKEUP_DELAY_MS);
+
+	/* Reset timings */
+	pmac_ide_selectproc(&ide_hwifs[i].drives[0]);
+	mdelay(10);
 
 	/* Wait up to 10 seconds (enough for recent drives) */
 	for (j = 0; j < 100; j++) {
@@ -439,14 +943,22 @@
 {
 	int timeout;
 
-	timeout = 5000;
+	/* Reset timings */
+	pmac_ide_selectproc(&ide_hwifs[i].drives[0]);
+	mdelay(10);
+
+	timeout = 10000;
 	while ((inb(base + 0x70) & BUSY_STAT) && timeout) {
 		mdelay(1);
 		--timeout;
 	}
 }
 
-static int idepmac_notify(struct pmu_sleep_notifier *self, int when)
+/* Note: We support only master drives for now. This will have to be
+ * improved if we want to handle sleep on the iMacDV where the CD-ROM
+ * is a slave
+ */
+static int idepmac_notify_sleep(struct pmu_sleep_notifier *self, int when)
 {
 	int i, ret;
 	unsigned long base;
@@ -458,27 +970,34 @@
 		break;
 	case PBOOK_SLEEP_NOW:
 		for (i = 0; i < pmac_ide_count; ++i) {
-			if ((base = pmac_ide_regbase[i]) == 0)
+			if ((base = pmac_ide[i].regbase) == 0)
 				continue;
 			/* Disable irq during sleep */
-			disable_irq(pmac_ide_irq[i]);
+			disable_irq(pmac_ide[i].irq);
 			ret = check_media_bay_by_base(base, MB_CD);
-			if (ret == -ENODEV)
+			if ((ret == -ENODEV) && ide_hwifs[i].drives[0].present)
 				/* not media bay - put the disk to sleep */
 				idepmac_sleep_disk(i, base);
 		}
 		break;
 	case PBOOK_WAKE:
 		for (i = 0; i < pmac_ide_count; ++i) {
-			if ((base = pmac_ide_regbase[i]) == 0)
+			ide_hwif_t *hwif;
+			if ((base = pmac_ide[i].regbase) == 0)
 				continue;
+			hwif = &ide_hwifs[i];
 		        /* We don't handle media bay devices this way */
 			ret = check_media_bay_by_base(base, MB_CD);
-			if (ret == -ENODEV)
+			if ((ret == -ENODEV) && ide_hwifs[i].drives[0].present)
 				idepmac_wake_disk(i, base);
 			else if (ret == 0)
 				idepmac_wake_bay(i, base);
-			enable_irq(pmac_ide_irq[i]);
+			enable_irq(pmac_ide[i].irq);
+
+#ifdef CONFIG_BLK_DEV_IDEDMA_PMAC
+			if (hwif->drives[0].present && hwif->drives[0].using_dma)
+				pmac_ide_dma_onoff(&hwif->drives[0], 1);
+#endif				
 		}
 		break;
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide-probe.c linux.17p18/drivers/block/ide-probe.c
--- linux.vanilla/drivers/block/ide-probe.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/ide-probe.c	Tue Aug  1 07:59:25 2000
@@ -109,8 +109,16 @@
 				}
 				type = ide_cdrom;	/* Early cdrom models used zero */
 			case ide_cdrom:
-				printk ("CDROM");
 				drive->removable = 1;
+#ifdef CONFIG_PPC
+				/* kludge for Apple PowerBook internal zip */
+				if (!strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP")) {
+					printk ("FLOPPY");
+					type = ide_floppy;
+					break;
+				}
+#endif
+				printk ("CDROM");
 				break;
 			case ide_tape:
 				printk ("TAPE");
@@ -819,7 +827,12 @@
 	
 	for (index = 0; index < MAX_HWIFS; ++index)
 		ide_unregister(index);
-	return ideprobe_init();
+	ideprobe_init();
+#ifdef CONFIG_PROC_FS
+	proc_ide_destroy();	/* Avoid multiple entry in /proc */
+	proc_ide_create();
+#endif
+	return 0;
 }
 
 void cleanup_module (void)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide-proc.c linux.17p18/drivers/block/ide-proc.c
--- linux.vanilla/drivers/block/ide-proc.c	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/ide-proc.c	Tue Aug  1 07:59:25 2000
@@ -111,7 +111,7 @@
 	unsigned long	startn = 0, n, flags;
 	const char	*start = NULL, *msg = NULL;
 
-	if (!capable(CAP_SYS_ADMIN))
+	if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 		return -EACCES;
 	/*
 	 * Skip over leading whitespace
@@ -333,6 +333,7 @@
 		case ide_rz1000:	name = "rz1000";	break;
 		case ide_trm290:	name = "trm290";	break;
 		case ide_4drives:	name = "4drives";	break;
+		case ide_pmac:		name = "mac-io";	break;
 		default:		name = "(unknown)";	break;
 	}
 	len = sprintf(page, "%s\n", name);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide.c linux.17p18/drivers/block/ide.c
--- linux.vanilla/drivers/block/ide.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/ide.c	Tue Aug  1 07:59:25 2000
@@ -2254,7 +2254,7 @@
 		{
 			byte args[4], *argbuf = args;
 			int argsize = 4;
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO)) return -EACCES;
 			if (NULL == (void *) arg)
 				return ide_do_drive_cmd(drive, &rq, ide_wait);
 			if (copy_from_user(args, (void *)arg, 4))
@@ -2277,7 +2277,7 @@
 		case HDIO_SCAN_HWIF:
 		{
 			int args[3];
-			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
+			if (!capable(CAP_SYS_ADMIN) || !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)
@@ -3131,6 +3131,8 @@
 EXPORT_SYMBOL(ide_add_proc_entries);
 EXPORT_SYMBOL(ide_remove_proc_entries);
 EXPORT_SYMBOL(proc_ide_read_geometry);
+EXPORT_SYMBOL(proc_ide_create);
+EXPORT_SYMBOL(proc_ide_destroy);
 #endif
 EXPORT_SYMBOL(ide_add_setting);
 EXPORT_SYMBOL(ide_remove_setting);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/ide.h linux.17p18/drivers/block/ide.h
--- linux.vanilla/drivers/block/ide.h	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/ide.h	Wed Aug  9 22:33:40 2000
@@ -306,7 +306,7 @@
 		ide_cmd640,	ide_dtc2278,	ide_ali14xx,
 		ide_qd6580,	ide_umc8672,	ide_ht6560b,
 		ide_pdc4030,	ide_rz1000,	ide_trm290,
-		ide_cmd646,	ide_4drives
+		ide_cmd646,	ide_4drives,	ide_pmac
 	} hwif_chipset_t;
 
 typedef struct ide_pci_devid_s {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/md.c linux.17p18/drivers/block/md.c
--- linux.vanilla/drivers/block/md.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/md.c	Tue Aug  1 07:59:25 2000
@@ -446,8 +446,6 @@
   
   factor = min = 1 << FACTOR_SHIFT(FACTOR((md_dev+minor)));
   
-  md_blocksizes[minor] <<= FACTOR_SHIFT(FACTOR((md_dev+minor)));
-
   for (i=0; i<md_dev[minor].nb_dev; i++)
     if (md_dev[minor].devices[i].size<min)
     {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/raid0.c linux.17p18/drivers/block/raid0.c
--- linux.vanilla/drivers/block/raid0.c	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/raid0.c	Tue Aug  1 07:59:25 2000
@@ -184,7 +184,7 @@
 
   if (hash - data->hash_table > data->nr_zones) 
   { 
-	  printk(KERN_DEBUG "raid0_map: invalid block %ul\n", block);
+	  printk(KERN_DEBUG "raid0_map: invalid block %li\n", block);
 	  return -1;
   }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/rd.c linux.17p18/drivers/block/rd.c
--- linux.vanilla/drivers/block/rd.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/block/rd.c	Tue Aug  1 07:59:25 2000
@@ -587,6 +587,9 @@
 	set_fs(fs);
 }
 
+#ifdef CONFIG_MAC_FLOPPY
+int swim3_fd_eject(int devnum);
+#endif
 
 __initfunc(static void rd_load_disk(int n))
 {
@@ -607,6 +610,12 @@
 	if (rd_prompt) {
 #ifdef CONFIG_BLK_DEV_FD
 		floppy_eject();
+#endif
+#ifdef CONFIG_MAC_FLOPPY
+		if(MAJOR(ROOT_DEV) == FLOPPY_MAJOR)
+			swim3_fd_eject(MINOR(ROOT_DEV));
+		else if(MAJOR(real_root_dev) == FLOPPY_MAJOR)
+			swim3_fd_eject(MINOR(real_root_dev));
 #endif
 		printk(KERN_NOTICE
 		       "VFS: Insert root floppy disk to be loaded into RAM disk and press ENTER\n");
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/smart1,2.h linux.17p18/drivers/block/smart1,2.h
--- linux.vanilla/drivers/block/smart1,2.h	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/smart1,2.h	Tue Aug  1 07:59:25 2000
@@ -62,13 +62,14 @@
 }
 
 /*
- *  For this card fifo is full if reading this port returns 0! 
+ *  For older cards FIFO Full = 0. 
+ *  On this card 0 means there is room, anything else FIFO Full. 
  * 
  */ 
 static unsigned long smart4_fifo_full(ctlr_info_t *h)
 {
 	
-        return (~readl(h->vaddr + S42XX_REQUEST_PORT_OFFSET));
+        return (!readl(h->vaddr + S42XX_REQUEST_PORT_OFFSET));
 }
 
 /* This type of controller returns -1 if the fifo is empty, 
@@ -81,7 +82,7 @@
 		= readl(h->vaddr + S42XX_REPLY_PORT_OFFSET);
 
 	/* Fifo is empty */
-	if( register_value == -1)
+	if( register_value == 0xffffffff)
 		return 0; 	
 
 	/* Need to let it know we got the reply */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/block/swim3.c linux.17p18/drivers/block/swim3.c
--- linux.vanilla/drivers/block/swim3.c	Fri Apr 21 12:45:50 2000
+++ linux.17p18/drivers/block/swim3.c	Tue Aug  1 07:59:25 2000
@@ -808,6 +808,16 @@
 	return err;
 }
 
+int swim3_fd_eject(int devnum)
+{
+	if (devnum >= floppy_count)
+		return -ENODEV;
+	/* Do not check this - this function should ONLY be called early
+	 * in the boot process! */
+	/* if (floppy_states[devnum].ref_count != 1) return -EBUSY; */
+	return fd_eject(&floppy_states[devnum]);
+}
+
 static struct floppy_struct floppy_type =
 	{ 2880,18,2,80,0,0x1B,0x00,0xCF,0x6C,NULL };	/*  7 1.44MB 3.5"   */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/cdrom/cdrom.c linux.17p18/drivers/cdrom/cdrom.c
--- linux.vanilla/drivers/cdrom/cdrom.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/cdrom/cdrom.c	Tue Aug  1 07:59:26 2000
@@ -193,7 +193,7 @@
 
   3.07 Feb 2, 2000 - Jens Axboe <axboe@suse.de>
   -- Do same "read header length" trick in cdrom_get_disc_info() as
-  we do in cdrom_get_track_info() -- some drive don't obbey specs and
+  we do in cdrom_get_track_info() -- some drive don't obey specs and
   fail if they can't supply the full Mt Fuji size table.
   -- Deleted stuff related to setting up write modes. It has a different
   home now.
@@ -213,11 +213,20 @@
   -- Fix Video-CD on SCSI drives that don't support READ_CD command. In
   that case switch block size and issue plain READ_10 again, then switch
   back.
+
+  3.10 Jun 10, 2000 - Jens Axboe <axboe@suse.de>
+  -- Fix volume control on CD's - old SCSI-II drives now use their own
+  code, as doing MODE6 stuff in here is really not my intention.
+  -- Use READ_DISC_INFO for more reliable end-of-disc.
+
+  3.11 Jun 12, 2000 - Jens Axboe <axboe@suse.de>
+  -- Fix bug in getting rpc phase 2 region info.
+  -- Reinstate "correct" CDROMPLAYTRKIND
  
 -------------------------------------------------------------------------*/
 
-#define REVISION "Revision: 3.09"
-#define VERSION "Id: cdrom.c 3.09 2000/05/12"
+#define REVISION "Revision: 3.11"
+#define VERSION "Id: cdrom.c 3.11 2000/06/12"
 
 /* I use an error-log mask to give fine grain control over the type of
    messages dumped to the system logs.  The available masks include: */
@@ -287,7 +296,7 @@
 
 /* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
    a lot of places. This macro makes the code more clear. */
-#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & type)
+#define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
 
 /* used in the audio ioctls */
 #define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
@@ -1096,8 +1105,8 @@
 	case DVD_LU_SEND_RPC_STATE:
 		cdinfo(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
 		setup_report_key(&cgc, 0, 8);
+		memset(&rpc_state, 0, sizeof(rpc_state_t));
 
-		init_cdrom_command(&cgc, &rpc_state, 0);
 		if ((ret = cdo->generic_packet(cdi, &cgc)))
 			return ret;
 
@@ -1108,7 +1117,7 @@
 		ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
 		break;
 
-		/* Set region settings */
+	/* Set region settings */
 	case DVD_HOST_SEND_RPC_STATE:
 		cdinfo(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
 		setup_send_key(&cgc, 0, 6);
@@ -1334,6 +1343,18 @@
 	return cdo->generic_packet(cdi, cgc);
 }
 
+static int cdrom_mode_select_6(struct cdrom_device_info *cdi,
+			       struct cdrom_generic_command *cgc)
+{
+	struct cdrom_device_ops *cdo = cdi->ops;
+
+	memset(cgc->cmd, 0, sizeof(cgc->cmd));
+	cgc->cmd[0] = GPCMD_MODE_SELECT_6;
+	cgc->cmd[1] = 0x10;
+	cgc->cmd[4] = cgc->buflen & 0xff;
+	return cdo->generic_packet(cdi, cgc);
+}
+
 static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
 				 struct cdrom_subchnl *subchnl, int mcn)
 {
@@ -1812,26 +1833,17 @@
  */
 static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
 {
-	struct cdrom_device_ops *cdo = cdi->ops;
 	struct cdrom_generic_command cgc;
 	struct modesel_head mh;
 
 	memset(&mh, 0, sizeof(mh));
+	memset(&cgc, 0, sizeof(cgc));
 	mh.block_desc_length = 0x08;
 	mh.block_length_med = (size >> 8) & 0xff;
 	mh.block_length_lo = size & 0xff;
-
-	memset(&cgc, 0, sizeof(cgc));
-	cgc.cmd[0] = 0x15;
-	cgc.cmd[1] = 1 << 4;
-	cgc.cmd[4] = 12;
 	cgc.buflen = sizeof(mh);
 	cgc.buffer = (char *) &mh;
-	mh.block_desc_length = 0x08;
-	mh.block_length_med = (size >> 8) & 0xff;
-	mh.block_length_lo = size & 0xff;
-
-	return cdo->generic_packet(cdi, &cgc);
+	return cdrom_mode_select_6(cdi, &cgc);
 }
 
 static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
@@ -1956,36 +1968,15 @@
 		}
 	case CDROMPLAYTRKIND: {
 		struct cdrom_ti ti;
-		struct cdrom_tocentry entry;
-		struct cdrom_tochdr tochdr;
 
 		cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
 		IOCTL_IN(arg, struct cdrom_ti, ti);
-		entry.cdte_format = CDROM_MSF;
-
-		/* get toc entry for start and end track */
-		if (cdo->audio_ioctl(cdi, CDROMREADTOCHDR, &tochdr))
-			return -EINVAL;
-		if ((entry.cdte_track = ti.cdti_trk0) > tochdr.cdth_trk1)
-			return -EINVAL;
-		if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
-			return -EINVAL;
 
-		cgc.cmd[3] = entry.cdte_addr.msf.minute;
-		cgc.cmd[4] = entry.cdte_addr.msf.second;
-		cgc.cmd[5] = entry.cdte_addr.msf.frame;
-
-		entry.cdte_track = ti.cdti_trk1 + 1;
-		if (entry.cdte_track > tochdr.cdth_trk1)
-			entry.cdte_track = CDROM_LEADOUT;
-
-		if (cdo->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry))
-			return -EINVAL;
-
-		cgc.cmd[6] = entry.cdte_addr.msf.minute;
-		cgc.cmd[7] = entry.cdte_addr.msf.second;
-		cgc.cmd[8] = entry.cdte_addr.msf.frame;
-		cgc.cmd[0] = GPCMD_PLAY_AUDIO_MSF;
+		cgc.cmd[0] = GPCMD_PLAY_AUDIO_TI;
+		cgc.cmd[4] = ti.cdti_trk0;
+		cgc.cmd[5] = ti.cdti_ind0;
+		cgc.cmd[7] = ti.cdti_trk1;
+		cgc.cmd[8] = ti.cdti_ind1;
 		return cdo->generic_packet(cdi, &cgc);
 		}
 	case CDROMPLAYMSF: {
@@ -2018,28 +2009,32 @@
 	case CDROMVOLREAD: {
 		struct cdrom_volctrl volctrl;
 		char mask[32];
-		unsigned short offset;
+		unsigned short offset = sizeof(struct mode_page_header);
+		struct mode_page_header *header = (struct mode_page_header *) buffer;
+		/*
+		 * pass to sr vol control
+		 */
+		if (cdi->scsi_2)
+			return -ENOTTY;
+
 		cdinfo(CD_DO_IOCTL, "entering CDROMVOLUME\n");
 
 		IOCTL_IN(arg, struct cdrom_volctrl, volctrl);
 
 		cgc.buffer = buffer;
 		cgc.buflen = 24;
-		if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 0)))
-		    return ret;
+		if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 0))) {
+			cdi->scsi_2 = 1;
+			return ret;
+		}
 		
 		/* some drives have longer pages, adjust and reread. */
-		if (buffer[1] > cgc.buflen) {
-			cgc.buflen = buffer[1] + 2;
-			if ((ret = cdrom_mode_sense(cdi, &cgc, 
-					GPMODE_AUDIO_CTL_PAGE, 0))) 
-			    return ret;
+		if (be16_to_cpu(header->mode_data_length) != cgc.buflen + 2) {
+			cgc.buflen = be16_to_cpu(header->mode_data_length) + 2;
+			if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 0))) 
+				return ret;
 		}
 		
-		/* get the offset from the length of the page. length
-		   is measure from byte 2 an on, thus the 14. */
-		offset = buffer[1] - 14;
-
 		/* now we have the current volume settings. if it was only
 		   a CDROMVOLREAD, return these values */
 		if (cmd == CDROMVOLREAD) {
@@ -2053,9 +2048,8 @@
 		
 		/* get the volume mask */
 		cgc.buffer = mask;
-		if ((ret = cdrom_mode_sense(cdi, &cgc, 
-				GPMODE_AUDIO_CTL_PAGE, 1)))
-		    return ret;
+		if ((ret = cdrom_mode_sense(cdi, &cgc, GPMODE_AUDIO_CTL_PAGE, 1)))
+			return ret;
 
 		buffer[offset+9] = volctrl.channel0 & mask[offset+9];
 		buffer[offset+11] = volctrl.channel1 & mask[offset+11];
@@ -2252,6 +2246,9 @@
 	int ret = -1;
 
 	if (!CDROM_CAN(CDC_GENERIC_PACKET))
+		goto use_toc;
+
+	if (!CDROM_CAN(CDC_CD_R | CDC_CD_RW))
 		goto use_toc;
 
 	if ((ret = cdrom_get_disc_info(dev, &di)))
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/Makefile linux.17p18/drivers/char/Makefile
--- linux.vanilla/drivers/char/Makefile	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/char/Makefile	Tue Aug  1 07:59:31 2000
@@ -628,6 +628,16 @@
   L_OBJS += dz.o
 endif
 
+
+ifeq ($(CONFIG_TOSHIBA),y)
+L_OBJS += toshiba.o
+else
+  ifeq ($(CONFIG_TOSHIBA),m)
+  M_OBJS += toshiba.o
+  endif
+endif
+
+
 include $(TOPDIR)/Rules.make
 
 fastdep:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/adbmouse.c linux.17p18/drivers/char/adbmouse.c
--- linux.vanilla/drivers/char/adbmouse.c	Fri Apr 21 12:45:51 2000
+++ linux.17p18/drivers/char/adbmouse.c	Tue Aug  1 07:59:31 2000
@@ -35,6 +35,7 @@
 
 #include <asm/adb_mouse.h>
 #include <asm/uaccess.h>
+#include <asm/hardirq.h>
 #ifdef __powerpc__
 #include <asm/processor.h>
 #endif
@@ -56,7 +57,7 @@
  *	XXX: need to figure out what ADB mouse packets mean ... 
  *	This is the stuff stolen from the Atari driver ...
  */
-static void adb_mouse_interrupt(unsigned char *buf, int nb)
+void adb_mouse_interrupt(unsigned char *buf, int nb)
 {
     int buttons, id;
 
@@ -154,6 +155,7 @@
       return 0;
 
     adb_mouse_interrupt_hook = NULL;
+    synchronize_irq();
     MOD_DEC_USE_COUNT;
     return 0;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/bttv.c linux.17p18/drivers/char/bttv.c
--- linux.vanilla/drivers/char/bttv.c	Fri Apr 21 12:45:51 2000
+++ linux.17p18/drivers/char/bttv.c	Mon Aug 14 20:17:03 2000
@@ -1775,8 +1775,7 @@
                         if (v.channel>tvcards[btv->type].video_inputs)
                                 return -EINVAL;
 			bt848_muxsel(btv, v.channel);
-			if(v.norm!=VIDEO_MODE_PAL&&v.norm!=VIDEO_MODE_NTSC
-			   &&v.norm!=VIDEO_MODE_SECAM)
+			if (v.norm > (sizeof(tvnorms)/sizeof(*tvnorms)))
 				return -EOPNOTSUPP;
 			btv->win.norm = v.norm;
                         make_vbitab(btv);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/console.c linux.17p18/drivers/char/console.c
--- linux.vanilla/drivers/char/console.c	Sun Jun 11 21:44:12 2000
+++ linux.17p18/drivers/char/console.c	Tue Aug  1 07:59:31 2000
@@ -33,7 +33,7 @@
  * APM screenblank bug fixed Takashi Manabe <manabe@roy.dsl.tutics.tut.jp>
  *
  * Merge with the abstract console driver by Geert Uytterhoeven
- * <Geert.Uytterhoeven@cs.kuleuven.ac.be>, Jan 1997.
+ * <geert@linux-m68k.org>, Jan 1997.
  *
  *   Original m68k console driver modifications by
  *
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/cyclades.c linux.17p18/drivers/char/cyclades.c
--- linux.vanilla/drivers/char/cyclades.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/cyclades.c	Tue Aug  1 07:59:31 2000
@@ -1,7 +1,8 @@
 #undef	BLOCKMOVE
 #define	Z_WAKE
+#undef	Z_EXT_CHARS_IN_BUFFER
 static char rcsid[] =
-"$Revision: 2.3.2.6 $$Date: 2000/05/05 13:56:05 $";
+"$Revision: 2.3.2.8 $$Date: 2000/07/06 18:14:16 $";
 
 /*
  *  linux/drivers/char/cyclades.c
@@ -24,6 +25,17 @@
  * This version supports shared IRQ's (only for PCI boards).
  *
  * $Log: cyclades.c,v $
+ * Revision 2.3.2.8   2000/07/06 18:14:16 ivan
+ * Fixed the PCI detection function to work properly on Alpha systems.
+ * Implemented support for TIOCSERGETLSR ioctl.
+ * Implemented full support for non-standard baud rates.
+ *
+ * Revision 2.3.2.7   2000/06/01 18:26:34 ivan
+ * Request PLX I/O region, although driver doesn't use it, to avoid 
+ * problems with other drivers accessing it.
+ * Removed count for on-board buffer characters in cy_chars_in_buffer
+ * (Cyclades-Z only).
+ *
  * Revision 2.3.2.6   2000/05/05 13:56:05 ivan
  * Driver now reports physical instead of virtual memory addresses.
  * Masks were added to some Cyclades-Z read accesses.
@@ -634,6 +646,7 @@
 #include <linux/ptrace.h>
 #include <linux/cyclades.h>
 #include <linux/mm.h>
+#include <linux/ioport.h>
 #include <linux/init.h>
 #include <linux/delay.h>
 
@@ -1365,9 +1378,16 @@
 
                     while (char_count-- > 0){
 			if (!info->xmit_cnt){
-                            cy_writeb((u_long)base_addr+(CySRER<<index),
-				cy_readb(base_addr+(CySRER<<index)) & 
-					~CyTxRdy);
+			    if (cy_readb(base_addr+(CySRER<<index))&CyTxMpty) {
+				cy_writeb((u_long)base_addr+(CySRER<<index), 
+					  cy_readb(base_addr+(CySRER<<index)) &
+					  ~CyTxMpty);
+			    } else {
+				cy_writeb((u_long)base_addr+(CySRER<<index), 
+					  ((cy_readb(base_addr+(CySRER<<index))
+					    & ~CyTxRdy)
+					   | CyTxMpty));
+			    }
 			    goto txdone;
 			}
 			if (info->xmit_buf == 0){
@@ -3133,12 +3153,15 @@
     card = info->card;
     channel = (info->line) - (cy_card[card].first_line);
 
+#ifdef Z_EXT_CHARS_IN_BUFFER
     if (!IS_CYC_Z(cy_card[card])) {
+#endif /* Z_EXT_CHARS_IN_BUFFER */
 #ifdef CY_DEBUG_IO
 	printk("cyc:cy_chars_in_buffer ttyC%d %d\n",
 		info->line, info->xmit_cnt); /* */
 #endif
 	return info->xmit_cnt;
+#ifdef Z_EXT_CHARS_IN_BUFFER
     } else {
 	static volatile struct FIRM_ID *firm_id;
 	static volatile struct ZFW_CTRL *zfw_ctrl;
@@ -3167,6 +3190,7 @@
 #endif
 	return (info->xmit_cnt + char_count);
     }
+#endif /* Z_EXT_CHARS_IN_BUFFER */
 } /* cy_chars_in_buffer */
 
 
@@ -3176,6 +3200,30 @@
  * ------------------------------------------------------------
  */
 
+static void
+cyy_baud_calc(struct cyclades_port *info, uclong baud)
+{
+    int co, co_val, bpr;
+    uclong cy_clock = ((info->chip_rev >= CD1400_REV_J) ? 60000000 : 25000000);
+
+    if (baud == 0) {
+	info->tbpr = info->tco = info->rbpr = info->rco = 0;
+	return;
+    }
+
+    /* determine which prescaler to use */
+    for (co = 4, co_val = 2048; co; co--, co_val >>= 2) {
+	if (cy_clock / co_val / baud > 63)
+	    break;
+    }
+
+    bpr = (cy_clock / co_val * 2 / baud + 1) / 2;
+    if (bpr > 255)
+	bpr = 255;
+
+    info->tbpr = info->rbpr = bpr;
+    info->tco = info->rco = co;
+}
 
 /*
  * This routine finds or computes the various line characteristics.
@@ -3189,7 +3237,7 @@
   int card,chip,channel,index;
   unsigned cflag, iflag;
   unsigned short chip_number;
-  int baud;
+  int baud, baud_rate = 0;
   int   i;
 
 
@@ -3225,12 +3273,14 @@
 	index = cy_card[card].bus_index;
 
 	/* baud rate */
-	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
-	    baud = info->baud;
-	} else {
-	    baud = tty_get_baud_rate(info->tty);
-	}
-	if (baud > CD1400_MAX_SPEED) {
+	baud = tty_get_baud_rate(info->tty);
+	if ((baud == 38400) && 
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+	    if (info->custom_divisor)
+		baud_rate = info->baud / info->custom_divisor;
+	    else
+		baud_rate = info->baud;
+	} else if (baud > CD1400_MAX_SPEED) {
 	    baud = CD1400_MAX_SPEED;
 	}
 	/* find the baud index */
@@ -3243,22 +3293,29 @@
 	    i = 19; /* CD1400_MAX_SPEED */
 	} 
 
-
-	if(info->chip_rev >= CD1400_REV_J) {
-	    /* It is a CD1400 rev. J or later */
-	    info->tbpr = baud_bpr_60[i]; /* Tx BPR */
-	    info->tco = baud_co_60[i]; /* Tx CO */
-	    info->rbpr = baud_bpr_60[i]; /* Rx BPR */
-	    info->rco = baud_co_60[i]; /* Rx CO */
+	if ((baud == 38400) && 
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+	    cyy_baud_calc(info, baud_rate);
 	} else {
-	    info->tbpr = baud_bpr_25[i]; /* Tx BPR */
-	    info->tco = baud_co_25[i]; /* Tx CO */
-	    info->rbpr = baud_bpr_25[i]; /* Rx BPR */
-	    info->rco = baud_co_25[i]; /* Rx CO */
+	    if(info->chip_rev >= CD1400_REV_J) {
+		/* It is a CD1400 rev. J or later */
+		info->tbpr = baud_bpr_60[i]; /* Tx BPR */
+		info->tco = baud_co_60[i]; /* Tx CO */
+		info->rbpr = baud_bpr_60[i]; /* Rx BPR */
+		info->rco = baud_co_60[i]; /* Rx CO */
+	    } else {
+		info->tbpr = baud_bpr_25[i]; /* Tx BPR */
+		info->tco = baud_co_25[i]; /* Tx CO */
+		info->rbpr = baud_bpr_25[i]; /* Rx BPR */
+		info->rco = baud_co_25[i]; /* Rx CO */
+	    }
 	}
 	if (baud_table[i] == 134) {
-	    info->timeout = (info->xmit_fifo_size*HZ*15/269) + 2;
 	    /* get it right for 134.5 baud */
+	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+	} else if ((baud == 38400) && 
+		   ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
 	} else if (baud_table[i]) {
 	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_table[i]) + 2;
 	    /* this needs to be propagated into the card info */
@@ -3447,19 +3504,24 @@
 	buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
 
 	/* baud rate */
-	if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) {
-	    baud = info->baud;
-	} else {
-	    baud = tty_get_baud_rate(info->tty);
-	}
-	if (baud > CYZ_MAX_SPEED) {
+	baud = tty_get_baud_rate(info->tty);
+	if ((baud == 38400) && 
+	    ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+	    if (info->custom_divisor)
+		baud_rate = info->baud / info->custom_divisor;
+	    else
+		baud_rate = info->baud;
+	} else if (baud > CYZ_MAX_SPEED) {
 	    baud = CYZ_MAX_SPEED;
 	}
 	cy_writel(&ch_ctrl->comm_baud , baud);
 
 	if (baud == 134) {
-	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
 	    /* get it right for 134.5 baud */
+	    info->timeout = (info->xmit_fifo_size*HZ*30/269) + 2;
+	} else if ((baud == 38400) && 
+		   ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) {
+	    info->timeout = (info->xmit_fifo_size*HZ*15/baud_rate) + 2;
 	} else if (baud) {
 	    info->timeout = (info->xmit_fifo_size*HZ*15/baud) + 2;
 	    /* this needs to be propagated into the card info */
@@ -3549,8 +3611,6 @@
 	    clear_bit(TTY_IO_ERROR, &info->tty->flags);
 	}
     }
-
-
 } /* set_line_char */
 
 
@@ -3571,7 +3631,7 @@
     tmp.flags = info->flags;
     tmp.close_delay = info->close_delay;
     tmp.baud_base = info->baud;
-    tmp.custom_divisor = 0;     /*!!!*/
+    tmp.custom_divisor = info->custom_divisor;
     tmp.hub6 = 0;               /*!!!*/
     return copy_to_user(retinfo,&tmp,sizeof(*retinfo))?-EFAULT:0;
 } /* get_serial_info */
@@ -3597,6 +3657,7 @@
             info->flags = ((info->flags & ~ASYNC_USR_MASK) |
                            (new_serial.flags & ASYNC_USR_MASK));
             info->baud = new_serial.baud_base;
+	    info->custom_divisor = new_serial.custom_divisor;
             goto check_and_exit;
     }
 
@@ -3607,6 +3668,7 @@
      */
 
     info->baud = new_serial.baud_base;
+    info->custom_divisor = new_serial.custom_divisor;
     info->flags = ((info->flags & ~ASYNC_FLAGS) |
                     (new_serial.flags & ASYNC_FLAGS));
     info->close_delay = new_serial.close_delay * HZ/100;
@@ -3621,6 +3683,43 @@
     }
 } /* set_serial_info */
 
+/*
+ * get_lsr_info - get line status register info
+ *
+ * Purpose: Let user call ioctl() to get info when the UART physically
+ *	    is emptied.  On bus types like RS485, the transmitter must
+ *	    release the bus after transmitting. This must be done when
+ *	    the transmit shift register is empty, not be done when the
+ *	    transmit holding register is empty.  This functionality
+ *	    allows an RS485 driver to be written in user space.
+ */
+static int get_lsr_info(struct cyclades_port *info, unsigned int *value)
+{
+    int card, chip, channel, index;
+    unsigned char status;
+    unsigned int result;
+    unsigned long flags;
+    unsigned char *base_addr;
+
+    card = info->card;
+    channel = (info->line) - (cy_card[card].first_line);
+    if (!IS_CYC_Z(cy_card[card])) {
+	chip = channel>>2;
+	channel &= 0x03;
+	index = cy_card[card].bus_index;
+	base_addr = (unsigned char *)
+		     (cy_card[card].base_addr + (cy_chip_offset[chip]<<index));
+
+	CY_LOCK(info, flags);
+	status = cy_readb(base_addr+(CySRER<<index)) & (CyTxRdy|CyTxMpty);
+	CY_UNLOCK(info, flags);
+	result = (status ? 0 : TIOCSER_TEMT);
+    } else {
+	/* Not supported yet */
+	return -EINVAL;
+    }
+    return cy_put_user(result, (unsigned long *) value);
+}
 
 static int
 get_modem_info(struct cyclades_port * info, unsigned int *value)
@@ -4247,6 +4346,9 @@
         case TIOCSSERIAL:
             ret_val = set_serial_info(info, (struct serial_struct *) arg);
             break;
+	case TIOCSERGETLSR: /* Get line status register */
+	    ret_val = get_lsr_info(info, (unsigned int *) arg);
+	    break;
 	/*
 	 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change 
 	 * - mask passed in arg for lines of interest
@@ -4868,7 +4970,7 @@
   struct pci_dev	*pdev = NULL;
   unsigned char		cyy_rev_id;
   unsigned char         cy_pci_irq = 0;
-  uclong		cy_pci_phys0, cy_pci_phys2;
+  uclong		cy_pci_phys0, cy_pci_phys1, cy_pci_phys2;
   uclong		cy_pci_addr0, cy_pci_addr2;
   unsigned short        i,j,cy_pci_nchan, plx_ver;
   unsigned short        device_id,dev_index = 0;
@@ -4897,6 +4999,7 @@
                 /* read PCI configuration area */
 		cy_pci_irq = pdev->irq;
 		cy_pci_phys0 = pdev->base_address[0];
+		cy_pci_phys1 = pdev->base_address[1]; 
 		cy_pci_phys2 = pdev->base_address[2]; 
 		pci_read_config_byte(pdev, PCI_REVISION_ID, &cyy_rev_id);
 
@@ -4913,6 +5016,7 @@
 		(ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
 #endif
 		cy_pci_phys0  &= PCI_BASE_ADDRESS_MEM_MASK;
+		cy_pci_phys1  &= PCI_BASE_ADDRESS_IO_MASK;
 		cy_pci_phys2  &= PCI_BASE_ADDRESS_MEM_MASK;
 
 		if (cy_pci_phys2 & ~PCI_BASE_ADDRESS_IO_MASK) {
@@ -4921,6 +5025,11 @@
 		    cy_pci_phys2 &= PCI_BASE_ADDRESS_IO_MASK;
 		}
 
+		/* Although we don't use this I/O region, we should 
+		   request it from the kernel anyway, to avoid problems 
+		   with other drivers accessing it. */
+		request_region(cy_pci_phys1, CyPCI_Yctl, "Cyclom-Y");
+
 #if defined(__alpha__)
                 if (device_id  == PCI_DEVICE_ID_CYCLOM_Y_Lo) { /* below 1M? */
 		    printk("Cyclom-Y/PCI (bus=0x0%x, pci_id=0x%x, ",
@@ -4934,10 +5043,9 @@
 		    i--;
 	            continue;
                 }
-#else
+#endif
 		cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Yctl);
 		cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ywin);
-#endif
 
 #ifdef CY_PCI_DEBUG
             printk("Cyclom-Y/PCI: relocate winaddr=0x%lx ctladdr=0x%lx\n",
@@ -5046,6 +5154,7 @@
                 (ulong)cy_pci_phys2, (ulong)cy_pci_phys0);
 #endif
                 cy_pci_phys0 &= PCI_BASE_ADDRESS_MEM_MASK;
+		cy_pci_phys1 &= PCI_BASE_ADDRESS_IO_MASK;
                 cy_pci_phys2 &= PCI_BASE_ADDRESS_MEM_MASK;
 
 		if (cy_pci_phys2 & ~PCI_BASE_ADDRESS_IO_MASK) {
@@ -5053,9 +5162,13 @@
 			   "Ignoring it...\n");
 		    cy_pci_phys2 &= PCI_BASE_ADDRESS_IO_MASK;
 		}
-#if !defined(__alpha__)
-                cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
-#endif
+
+		/* Although we don't use this I/O region, we should 
+		   request it from the kernel anyway, to avoid problems 
+		   with other drivers accessing it. */
+		request_region(cy_pci_phys1, CyPCI_Zctl, "Cyclades-Z");
+
+		cy_pci_addr0 = (ulong)ioremap(cy_pci_phys0, CyPCI_Zctl);
 
 		/* Disable interrupts on the PLX before resetting it */
 		cy_writew(cy_pci_addr0+0x68,
@@ -5071,9 +5184,7 @@
 		mailbox = (uclong)cy_readl(&((struct RUNTIME_9060 *) 
 			   cy_pci_addr0)->mail_box_0);
 		if (mailbox == ZE_V1) {
-#if !defined(__alpha__)
-               	    cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
-#endif
+		    cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Ze_win);
 		    if (ZeIndex == NR_CARDS) {
 			printk("Cyclades-Ze/PCI found at 0x%lx ",
 				(ulong)cy_pci_phys2);
@@ -5090,9 +5201,7 @@
 		    i--;
 		    continue;
 		} else {
-#if !defined(__alpha__)
-                    cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
-#endif
+		    cy_pci_addr2 = (ulong)ioremap(cy_pci_phys2, CyPCI_Zwin);
 		}
 
 #ifdef CY_PCI_DEBUG
@@ -5531,6 +5640,7 @@
                     info->tco = 0;
                     info->rbpr = 0;
                     info->rco = 0;
+		    info->custom_divisor = 0;
                     info->close_delay = 5*HZ/10;
 		    info->closing_wait = CLOSING_WAIT_DELAY;
 		    info->icount.cts = info->icount.dsr = 
@@ -5589,6 +5699,7 @@
                     info->cor3 = 0x08; /* _very_ small rcv threshold */
                     info->cor4 = 0;
                     info->cor5 = 0;
+		    info->custom_divisor = 0;
                     info->close_delay = 5*HZ/10;
 		    info->closing_wait = CLOSING_WAIT_DELAY;
 		    info->icount.cts = info->icount.dsr = 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/dtlk.c linux.17p18/drivers/char/dtlk.c
--- linux.vanilla/drivers/char/dtlk.c	Fri Apr 21 12:45:51 2000
+++ linux.17p18/drivers/char/dtlk.c	Tue Aug  1 07:59:32 2000
@@ -272,14 +272,14 @@
 	}
 	/* there are no exception conditions */
 
-	if (mask == 0 && !dtlk_timer_active) {
+	{
 		/* not ready just yet.  There won't be any interrupts,
 		   so we set a timer instead. */
 		dtlk_timer_active = 1;
 		dtlk_timer.expires = jiffies + HZ / 100;
 		add_timer(&dtlk_timer);
 	}
-	return 0;
+	return mask;
 }
 
 static void dtlk_stop_timer()
@@ -295,11 +295,6 @@
 
 	wake_up_interruptible(&dtlk_process_list);
 
-	if (dtlk_timer_active) {
-		del_timer(&dtlk_timer);
-		dtlk_timer.expires = jiffies + HZ / 100;
-		add_timer(&dtlk_timer);
-	}
 }
 
 static int dtlk_ioctl(struct inode *inode,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/epca.c linux.17p18/drivers/char/epca.c
--- linux.vanilla/drivers/char/epca.c	Fri Apr 21 12:45:51 2000
+++ linux.17p18/drivers/char/epca.c	Tue Aug  1 18:17:47 2000
@@ -3833,7 +3833,7 @@
 
 			case 5:
 				board.port = (unsigned char *)ints[index];
-				if (board.port <= 0)
+				if ((signed long)board.port <= 0)
 				{
 					printk(KERN_ERR "<Error> - epca_setup: Invalid io port 0x%x\n", (unsigned int)board.port);
 					invalid_lilo_config = 1;
@@ -3845,7 +3845,7 @@
 
 			case 6:
 				board.membase = (unsigned char *)ints[index];
-				if (board.membase <= 0)
+				if ((signed long)board.membase <= 0)
 				{
 					printk(KERN_ERR "<Error> - epca_setup: Invalid memory base 0x%x\n",(unsigned int)board.membase);
 					invalid_lilo_config = 1;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/generic_serial.c linux.17p18/drivers/char/generic_serial.c
--- linux.vanilla/drivers/char/generic_serial.c	Fri Apr 21 12:46:02 2000
+++ linux.17p18/drivers/char/generic_serial.c	Tue Aug  1 07:59:32 2000
@@ -12,12 +12,18 @@
  *  Version 0.1 -- December, 1998. Initial version.
  *  Version 0.2 -- March, 1999.    Some more routines. Bugfixes. Etc.
  *  Version 0.5 -- August, 1999.   Some more fixes. Reformat for Linus.
- */
+ *
+ *  BitWizard is actively maintaining this file. We sometimes find
+ *  that someone submitted changes to this file. We really appreciate
+ *  your help, but please submit changes through us. We're doing our
+ *  best to be responsive.  -- REW
+ * */
 
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/mm.h>
 #include <asm/semaphore.h>
+#include <asm/uaccess.h>
 #include <linux/version.h>
 #include <linux/module.h>
 #include <linux/compatmac.h>
@@ -40,8 +46,6 @@
 #define func_enter() gs_dprintk (GS_DEBUG_FLOW, "gs: enter " __FUNCTION__ "\n")
 #define func_exit()  gs_dprintk (GS_DEBUG_FLOW, "gs: exit  " __FUNCTION__ "\n")
 
-
-
 #if NEW_WRITE_LOCKING
 #define DECL      /* Nothing */
 #define LOCKIT    down (& port->port_write_sem);
@@ -52,6 +56,9 @@
 #define RELEASEIT restore_flags (flags)
 #endif
 
+#ifdef MODULE
+MODULE_PARM(gs_debug, "i");
+#endif
 
 #ifdef DEBUG
 static void my_hd (unsigned char *addr, int len)
@@ -77,10 +84,18 @@
 
 void gs_put_char(struct tty_struct * tty, unsigned char ch)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	DECL
 
-	/*  func_enter (); */
+	func_enter (); 
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
+	if (! (port->flags & ASYNC_INITIALIZED)) return;
 
 	/* Take a lock on the serial tranmit buffer! */
 	LOCKIT;
@@ -96,7 +111,7 @@
 	port->xmit_cnt++;  /* Characters in buffer */
 
 	RELEASEIT;
-	/* func_exit ();*/
+	func_exit ();
 }
 
 
@@ -112,11 +127,17 @@
 int gs_write(struct tty_struct * tty, int from_user, 
                     const unsigned char *buf, int count)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	int c, total = 0;
 	int t;
 
-	/* func_enter (); */
+	func_enter ();
+
+	if (!tty) return 0;
+
+	port = tty->driver;
+
+	if (!port) return 0;
 
 	if (! (port->flags & ASYNC_INITIALIZED))
 		return 0;
@@ -167,7 +188,7 @@
 		port->flags |= GS_TX_INTEN;
 		port->rd->enable_tx_interrupts (port);
 	}
-	/* func_exit (); */
+	func_exit ();
 	return total;
 }
 #else
@@ -210,12 +231,9 @@
 	if (!port || !port->xmit_buf || !tmp_buf)
 		return -EIO;
 
-	/* printk ("from_user = %d.\n", from_user); */
 	save_flags(flags);
 	if (from_user) {
-		/* printk ("Going into the semaphore\n"); */
 		down(&tmp_buf_sem);
-		/* printk ("got out of the semaphore\n"); */
 		while (1) {
 			c = count;
 
@@ -309,11 +327,11 @@
 	struct gs_port *port = tty->driver_data;
 	int ret;
 
-	/* func_enter (); */
+	func_enter ();
 	ret = SERIAL_XMIT_SIZE - port->xmit_cnt - 1;
 	if (ret < 0)
 		ret = 0;
-	/* func_exit (); */
+	func_exit ();
 	return ret;
 }
 
@@ -330,7 +348,7 @@
 
 int gs_real_chars_in_buffer(struct tty_struct *tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	func_enter ();
 
 	if (!tty) return 0;
@@ -361,22 +379,17 @@
 
 	if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
 		gs_dprintk (GS_DEBUG_FLUSH, "ERROR: !port, !port->xmit_buf or prot->xmit_cnt < 0.\n");
-	func_exit();
+		func_exit();
 		return -EINVAL;  /* This is an error which we don't know how to handle. */
 	}
-	gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 1\n");
 
 	rcib = gs_real_chars_in_buffer(port->tty);
 
-	gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 2\n");
-
 	if(rcib <= 0) {
 		gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
 		func_exit();
 		return rv;
 	}
-	gs_dprintk (GS_DEBUG_FLUSH, "checkpoint 3\n");
-
 	/* stop trying: now + twice the time it would normally take +  seconds */
 	end_jiffies  = jiffies; 
 	if (timeout !=  MAX_SCHEDULE_TIMEOUT)
@@ -424,17 +437,23 @@
 
 void gs_flush_buffer(struct tty_struct *tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	unsigned long flags;
 
 	func_enter ();
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
 	/* XXX Would the write semaphore do? */
 	save_flags(flags); cli();
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
 	restore_flags(flags);
 
 	wake_up_interruptible(&tty->write_wait);
-	wake_up_interruptible(&tty->poll_wait);
 	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	    tty->ldisc.write_wakeup)
 		(tty->ldisc.write_wakeup)(tty);
@@ -444,9 +463,16 @@
 
 void gs_flush_chars(struct tty_struct * tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 
 	func_enter ();
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
 	if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
 	    !port->xmit_buf) {
 		func_exit ();
@@ -462,9 +488,16 @@
 
 void gs_stop(struct tty_struct * tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 
 	func_enter ();
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
+
 	if (port->xmit_cnt && 
 	    port->xmit_buf && 
 	    (port->flags & GS_TX_INTEN) ) {
@@ -477,7 +510,13 @@
 
 void gs_start(struct tty_struct * tty)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
+
+	if (!tty) return;
+
+	port = tty->driver_data;
+
+	if (!port) return;
 
 	if (port->xmit_cnt && 
 	    port->xmit_buf && 
@@ -492,7 +531,11 @@
 void gs_shutdown_port (struct gs_port *port)
 {
 	long flags;
+
 	func_enter();
+	
+	if (!port) return;
+	
 	if (!(port->flags & ASYNC_INITIALIZED))
 		return;
 
@@ -517,10 +560,13 @@
 
 void gs_hangup(struct tty_struct *tty)
 {
-	struct gs_port   *port = tty->driver_data;
+	struct gs_port   *port;
 
 	func_enter ();
 
+	if (!tty) return;
+
+	port = tty->driver_data;
 	tty = port->tty;
 	if (!tty) return;
 
@@ -541,15 +587,19 @@
 	struct gs_port *port = private_;
 	struct tty_struct *tty;
 
+	func_enter ();
+
+	if (!port) return;
+
 	tty = port->tty;
-	if(!tty) return;
+
+	if (!tty) return;
 
 	if (test_and_clear_bit(RS_EVENT_WRITE_WAKEUP, &port->event)) {
 		if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 		    tty->ldisc.write_wakeup)
 			(tty->ldisc.write_wakeup)(tty);
 		wake_up_interruptible(&tty->write_wait);
-		wake_up_interruptible(&tty->poll_wait);
 	}
 	func_exit ();
 }
@@ -565,8 +615,13 @@
 	struct tty_struct *tty;
 
 	func_enter ();
+
+	if (!port) return 0;
+
 	tty = port->tty;
 
+	if (!tty) return 0;
+
 	gs_dprintk (GS_DEBUG_BTR, "Entering block_till_ready.\n"); 
 	/*
 	 * If the device is in the middle of being closed, then block
@@ -625,8 +680,6 @@
 			do_clocal = 1;
 	}
 
-	gs_dprintk (GS_DEBUG_BTR, "after clocal check.\n"); 
-
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -635,10 +688,10 @@
 	 * exit, either normal or abnormal.
 	 */
 	retval = 0;
+
 	add_wait_queue(&port->open_wait, &wait);
 
 	gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 
-
 	cli();
 	if (!tty_hung_up_p(filp))
 		port->count--;
@@ -690,15 +743,12 @@
 	struct gs_port *port;
 
 	func_enter ();
-	port = (struct gs_port *) tty->driver_data;
 
-	gs_dprintk (GS_DEBUG_CLOSE, "tty=%p, port=%p port->tty=%p\n",
-	            tty, port, port->tty);
+	if (!tty) return;
 
-	if(! port) {
-		func_exit();
-		return;
-	}
+	port = (struct gs_port *) tty->driver_data;
+
+	if (!port) return;
 
 	if (!port->tty) {
 		/* This seems to happen when this is called from vhangup. */
@@ -706,7 +756,6 @@
 		port->tty = tty;
 	}
 
-
 	save_flags(flags); cli();
 
 	if (tty_hung_up_p(filp)) {
@@ -800,14 +849,19 @@
 void gs_set_termios (struct tty_struct * tty, 
                      struct termios * old_termios)
 {
-	struct gs_port *port = tty->driver_data;
+	struct gs_port *port;
 	int baudrate, tmp, rv;
 	struct termios *tiosp;
 
 	func_enter();
 
-	tiosp = tty->termios;
+	if (!tty) return;
+
+	port = tty->driver_data;
 
+	if (!port) return;
+
+	tiosp = tty->termios;
 
 	if (gs_debug & GS_DEBUG_TERMIOS) {
 		gs_dprintk (GS_DEBUG_TERMIOS, "termios structure (%p):\n", tiosp);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/i2c.c linux.17p18/drivers/char/i2c.c
--- linux.vanilla/drivers/char/i2c.c	Fri Apr 21 12:46:03 2000
+++ linux.17p18/drivers/char/i2c.c	Tue Aug  1 07:59:32 2000
@@ -38,8 +38,8 @@
 
 #ifdef CONFIG_VIDEO_BT848
 extern int i2c_tuner_init(void);
-extern int msp3400c_init(void);
 #endif
+extern int msp3400c_init(void);
 #ifdef CONFIG_VIDEO_BUZ
 extern int saa7111_init(void);
 extern int saa7185_init(void);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/ip2main.c linux.17p18/drivers/char/ip2main.c
--- linux.vanilla/drivers/char/ip2main.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/ip2main.c	Tue Aug  1 07:59:32 2000
@@ -2585,7 +2585,7 @@
 	 * base. Also line nunber as such is meaningless but we use it for our
 	 * array index so it is fixed also.
 	 */
-	if ( ns.irq  	    != ip2config.irq
+	if ( ns.irq  	    != ip2config.irq[pCh->port_index]
 	    || (int) ns.port      != ((int) pCh->pMyBord->i2eBase)
 	    || ns.baud_base != pCh->BaudBase
 	    || ns.line      != pCh->port_index ) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/misc.c linux.17p18/drivers/char/misc.c
--- linux.vanilla/drivers/char/misc.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/misc.c	Tue Aug  1 07:59:32 2000
@@ -74,6 +74,7 @@
 extern void wdt_init(void);
 extern void acq_init(void);
 extern void wdt60xx_init(void);
+extern void sbc60xxwdt_init(void);
 extern void dtlk_init(void);
 extern void pcwatchdog_init(void);
 extern int rtc_init(void);
@@ -85,6 +86,7 @@
 extern void hfmodem_init(void);
 extern int pc110pad_init(void);
 extern int pmu_device_init(void);
+extern int tosh_init(void);
 
 static int misc_read_proc(char *buf, char **start, off_t offset,
 			  int len, int *eof, void *private)
@@ -277,6 +279,9 @@
 #endif
 #ifdef CONFIG_SGI
 	streamable_init ();
+#endif
+#ifdef CONFIG_TOSHIBA
+	tosh_init();
 #endif
 	if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) {
 		printk("unable to get major %d for misc devices\n",
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/n_tty.c linux.17p18/drivers/char/n_tty.c
--- linux.vanilla/drivers/char/n_tty.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/n_tty.c	Tue Aug  1 07:59:33 2000
@@ -1142,9 +1142,7 @@
 				nr -= num;
 				if (nr == 0)
 					break;
-				current->state = TASK_RUNNING;
 				get_user(c, b);
-				current->state = TASK_INTERRUPTIBLE;
 				if (opost(c, tty) < 0)
 					break;
 				b++; nr--;
@@ -1152,9 +1150,7 @@
 			if (tty->driver.flush_chars)
 				tty->driver.flush_chars(tty);
 		} else {
-			current->state = TASK_RUNNING;
 			c = tty->driver.write(tty, 1, b, nr);
-			current->state = TASK_INTERRUPTIBLE;
 			if (c < 0) {
 				retval = c;
 				goto break_out;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/pc_keyb.c linux.17p18/drivers/char/pc_keyb.c
--- linux.vanilla/drivers/char/pc_keyb.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/pc_keyb.c	Tue Aug  1 07:59:33 2000
@@ -401,15 +401,14 @@
 	}
     else if(scancode == AUX_RECONNECT){
         queue->head = queue->tail = 0;  /* Flush input queue */
-        /*
-         * need this stuff? seems to work fine w/o it for me
-        aux_write_ack(AUX_SET_SAMPLE);
-        aux_write_ack(100);
-        aux_write_ack(AUX_SET_RES);
-        aux_write_ack(3);
-        aux_write_ack(AUX_SET_SCALE21);
-        */
-        aux_write_ack(AUX_ENABLE_DEV);  /* ping the mouse :) */
+        /* ping the mouse :) */
+	kb_wait();
+	kbd_write_command(KBD_CCMD_WRITE_MOUSE);
+	kb_wait();
+	kbd_write_output(AUX_ENABLE_DEV);
+	/* we expect an ACK in response. */
+	mouse_reply_expected++;
+	kb_wait();
         return;
     }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/func.h linux.17p18/drivers/char/rio/func.h
--- linux.vanilla/drivers/char/rio/func.h	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/func.h	Tue Aug  1 07:59:30 2000
@@ -168,4 +168,6 @@
 extern int rio_ismodem (kdev_t device);
 extern void rio_udelay (int usecs);
 
+extern void rio_start_card_running (struct Host * HostP);
+
 #endif	/* __func_h_def */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/host.h linux.17p18/drivers/char/rio/host.h
--- linux.vanilla/drivers/char/rio/host.h	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/host.h	Tue Aug  1 07:59:30 2000
@@ -56,16 +56,16 @@
     uchar             	    Mode;      /* Control stuff */
     uchar                   Slot;      /* Slot */
     volatile caddr_t        Caddr;     /* KV address of DPRAM */
-    volatile struct DpRam   *CardP;    /* KV address of DPRAM, with overlay */
+    volatile struct DpRam  *CardP;     /* KV address of DPRAM, with overlay */
     paddr_t          	    PaddrP;    /* Phys. address of DPRAM */
     char                    Name[MAX_NAME_LEN];  /* The name of the host */
     uint            	    UniqueNum; /* host unique number */
-    semtype	    HostLock;  /* Lock structure for MPX */
-    /*struct pci_devinfo	    PciDevInfo; *//* PCI Bus/Device/Function stuff */
+    spinlock_t	            HostLock;  /* Lock structure for MPX */
+    /*struct pci_devinfo    PciDevInfo; *//* PCI Bus/Device/Function stuff */
     /*struct lockb	    HostLock;  *//* Lock structure for MPX */
     uint                    WorkToBeDone; /* set to true each interrupt */
     uint                    InIntr;    /* Being serviced? */
-    uint                    IntSrvDone;	/* host's interrupt has been serviced */
+    uint                    IntSrvDone;/* host's interrupt has been serviced */
     int			    (*Copy)( caddr_t, caddr_t, int ); /* copy func */
     struct timer_list timer;
     /*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/linux_compat.h linux.17p18/drivers/char/rio/linux_compat.h
--- linux.vanilla/drivers/char/rio/linux_compat.h	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/linux_compat.h	Wed Aug  9 22:24:45 2000
@@ -47,9 +47,6 @@
 
 #define SEM_SIGIGNORE 0x1234
 
-typedef struct semaphore semtype;
-
-
 #ifdef DEBUG_SEM
 #define swait(a,b)      printk ("waiting:    " __FILE__ " line %d\n", __LINE__)
 #define ssignal(sem)    printk ("signalling: " __FILE__ " line %d\n", __LINE__)
@@ -75,8 +72,6 @@
 
 extern int rio_debug;
 
-#define rio_dprint(f, p) do {if (rio_debug & f) printk p;} while (0)
-
 #define RIO_DEBUG_INIT         0x000001
 #define RIO_DEBUG_BOOT         0x000002
 #define RIO_DEBUG_CMD          0x000004
@@ -95,7 +90,7 @@
 #define RIO_DEBUG_REC          0x008000
 #define RIO_DEBUG_SPINLOCK     0x010000
 #define RIO_DEBUG_DELAY        0x020000
-
+#define RIO_DEBUG_MOD_COUNT    0x040000
 
 /* Copied over from riowinif.h . This is ugly. The winif file declares
 also much other stuff which is incompatible with the headers from
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rio_linux.c linux.17p18/drivers/char/rio/rio_linux.c
--- linux.vanilla/drivers/char/rio/rio_linux.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/rio_linux.c	Wed Aug  9 22:24:45 2000
@@ -109,108 +109,6 @@
 more than 512 ports.... */
 
 
-/* ************************************************************** */
-/* * This section can be removed when 2.0 becomes outdated....  * */
-/* ************************************************************** */
-
-#if LINUX_VERSION_CODE < 0x020100    /* Less than 2.1.0 */
-#define TWO_ZERO
-#else
-#if LINUX_VERSION_CODE < 0x020209   /* less than 2.2.x */
-#warning "Please use a recent 2.2.x kernel. "
-#endif
-#endif
-
-
-#ifdef TWO_ZERO
-
-/* Here is the section that makes the 2.2 compatible driver source 
-   work for 2.0 too! We mostly try to adopt the "new thingies" from 2.2, 
-   and provide for compatibility stuff here if possible. */
-
-#include <linux/bios32.h>
-
-#define Get_user(a,b)                a = get_user(b)
-#define Put_user(a,b)                0,put_user(a,b)
-#define copy_to_user(a,b,c)          memcpy_tofs(a,b,c)
-
-static inline int copy_from_user(void *to,const void *from, int c) 
-{
-  memcpy_fromfs(to, from, c);
-  return 0;
-}
-
-#define pci_present                  pcibios_present
-#define pci_read_config_word         pcibios_read_config_word
-#define pci_read_config_dword        pcibios_read_config_dword
-
-static inline unsigned char get_irq (unsigned char bus, unsigned char fn)
-{
-  unsigned char t; 
-  pcibios_read_config_byte (bus, fn, PCI_INTERRUPT_LINE, &t);
-  return t;
-}
-
-static inline void *ioremap(unsigned long base, long length)
-{
-  if (base < 0x100000) return (void *)base;
-  return vremap (base, length);
-}
-
-#define my_iounmap(x, b)             (((long)x<0x100000)?0:vfree ((void*)x))
-
-#define capable(x)                   suser()
-
-#define queue_task                   queue_task_irq_off
-#define tty_flip_buffer_push(tty)    queue_task(&tty->flip.tqueue, &tq_timer)
-#define signal_pending(current)      (current->signal & ~current->blocked)
-#define schedule_timeout(to)         do {current->timeout = jiffies + (to);schedule ();} while (0)
-#define time_after(t1,t2)            (((long)t1-t2) > 0)
-
-
-#define test_and_set_bit(nr, addr)   set_bit(nr, addr)
-#define test_and_clear_bit(nr, addr) clear_bit(nr, addr)
-
-/* Not yet implemented on 2.0 */
-#define ASYNC_SPD_SHI  -1
-#define ASYNC_SPD_WARP -1
-
-
-/* Ugly hack: the driver_name doesn't exist in 2.0.x . So we define it
-   to the "name" field that does exist. As long as the assignments are
-   done in the right order, there is nothing to worry about. */
-#define driver_name           name 
-
-/* Should be in a header somewhere. They are in tty.h on 2.2 */
-#define TTY_HW_COOK_OUT       14 /* Flag to tell ntty what we can handle */
-#define TTY_HW_COOK_IN        15 /* in hardware - output and input       */
-
-/* The return type of a "close" routine. */
-#define INT                   void
-#define NO_ERROR              /* Nothing */
-
-#else
-
-/* The 2.2.x compatibility section. */
-#include <asm/uaccess.h>
-
-#define Get_user(a,b)         get_user(a,b)
-#define Put_user(a,b)         put_user(a,b)
-#define get_irq(pdev)         pdev->irq
-
-#define INT                   int
-#define NO_ERROR              0              
-
-#define my_iounmap(x,b)       (iounmap((char *)(b)))
-
-#endif
-
-/* ************************************************************** */
-/* *                End of compatibility section..              * */
-/* ************************************************************** */
-
-
-
 /* Why the hell am I defining these here? */
 #define RIO_TYPE_NORMAL 1
 #define RIO_TYPE_CALLOUT 2
@@ -353,6 +251,8 @@
 
 #ifndef TWO_ZERO
 #ifdef MODULE
+MODULE_AUTHOR("Rogier Wolff <R.E.Wolff@bitwizard.nl>, Patrick van de Lageweg <patrick@bitwizard.n>");
+MODULE_DESCRIPTION("RIO driver");
 MODULE_PARM(rio_poll, "i");
 MODULE_PARM(rio_debug, "i");
 MODULE_PARM(rio_irqmask, "i");
@@ -373,55 +273,15 @@
   NULL
 };
 
-
-/* 
-   This driver can spew a whole lot of debugging output at you. If you
-   need maximum performance, you should disable the DEBUG define. To
-   aid in debugging in the field, I'm leaving the compile-time debug
-   features enabled, and disable them "runtime". That allows me to
-   instruct people with problems to enable debugging without requiring
-   them to recompile... 
-*/
-#define DEBUG
-
-#ifdef DEBUG
-#define rio_dprintk(f, str...) if (rio_debug & f) printk (str)
-#else
-#define rio_dprintk(f, str...) /* nothing */
-#endif
-
-
-#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
-#define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
-
-#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
-                                  "(port %d)\n", port->line)
-
-
-
-
 /* 
  *  Firmware loader driver specific routines
  *
  */
 
 static struct file_operations rio_fw_fops = {
-	NULL,	/*	lseek	*/
-	NULL,	/*	read	*/
-	NULL,	/*	write	*/
-	NULL,	/*	readdir	*/
-	NULL,	/*	select	*/
-	rio_fw_ioctl,
-	NULL,	/*	mmap	*/
-	rio_fw_open,
-#ifndef TWO_ZERO
-	NULL,	/*	flush	*/
-#endif
-	rio_fw_release,
-	NULL,	/*	fsync	*/
-	NULL,	/*	fasync	*/
-	NULL,	/*	check_media_change	*/
-	NULL,	/*	revalidate	*/
+        open:           rio_fw_open,
+        release:        rio_fw_release,
+	ioctl:		rio_fw_ioctl,
 };
 
 struct miscdevice rio_fw_device = {
@@ -446,11 +306,11 @@
     KERN_ERR "rio: Warning: null rio port for device %s in %s\n";
  
   if (!port) {
-    printk(badinfo, kdevname(device), routine);
+    printk (badinfo, kdevname(device), routine);
     return 1;
   }
   if (port->magic != RIO_MAGIC) {
-    printk(badmagic, kdevname(device), routine);
+    printk (badmagic, kdevname(device), routine);
     return 1;
   }
 
@@ -468,15 +328,15 @@
   unsigned char *addr = ad;
   
   for (i=0;i<len;i+=16) {
-    printk ("%08x ", (int) addr+i);
+    rio_dprintk (RIO_DEBUG_PARAM, "%08x ", (int) addr+i);
     for (j=0;j<16;j++) {
-      printk ("%02x %s", addr[j+i], (j==7)?" ":"");
+      rio_dprintk (RIO_DEBUG_PARAM, "%02x %s", addr[j+i], (j==7)?" ":"");
     }
     for (j=0;j<16;j++) {
       ch = addr[j+i];
-      printk ("%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
+      rio_dprintk (RIO_DEBUG_PARAM, "%c", (ch < 0x20)?'.':((ch > 0x7f)?'.':ch));
     }
-    printk ("\n");
+    rio_dprintk (RIO_DEBUG_PARAM, "\n");
   }
 }
 #else
@@ -539,26 +399,37 @@
 
 void rio_inc_mod_count (void)
 {
+#ifdef MODULE
   func_enter ();
+  rio_dprintk (RIO_DEBUG_MOD_COUNT, "rio_inc_mod_count\n");
   MOD_INC_USE_COUNT; 
   func_exit ();
+#endif
 }
 
 
 void rio_dec_mod_count (void)
 {
+#ifdef MODULE
   func_enter ();
+  rio_dprintk (RIO_DEBUG_MOD_COUNT, "rio_dec_mod_count\n");
   MOD_DEC_USE_COUNT; 
   func_exit ();
+#endif
 }
 
 
 static int rio_set_real_termios (void *ptr)
 {
-  int rv;
+  int rv, modem;
+  struct tty_struct *tty;
   func_enter();
 
-  rv = RIOParam( (struct Port *) ptr, CONFIG, 0, 1);
+  tty = ((struct Port *)ptr)->gs.tty;
+
+  modem = (MAJOR(tty->device) == RIO_NORMAL_MAJOR0) || (MAJOR(tty->device) == RIO_NORMAL_MAJOR1);
+
+  rv = RIOParam( (struct Port *) ptr, CONFIG, modem, 1);
 
   func_exit ();
 
@@ -568,21 +439,26 @@
 
 void rio_reset_interrupt (struct Host *HostP)
 {
+  func_enter();
+
   switch( HostP->Type ) {
   case RIO_AT:
   case RIO_MCA:
   case RIO_PCI:
     WBYTE(HostP->ResetInt , 0xff);
   }
+
+  func_exit();
 }
 
 
 static void rio_interrupt (int irq, void *ptr, struct pt_regs *regs)
 {
   struct Host *HostP;
+  func_enter ();
 
-  HostP = &p->RIOHosts[(long)ptr];
-  /*   func_enter ();  */
+  HostP = (struct Host*)ptr; /* &p->RIOHosts[(long)ptr]; */
+  
   rio_dprintk (RIO_DEBUG_IFLOW, "rio: enter rio_interrupt (%d/%d)\n", 
                irq, HostP->Ivec); 
 
@@ -627,7 +503,7 @@
     }
   }
 #endif
-
+  rio_dprintk (RIO_DEBUG_IFLOW, "rio: We've have noticed the interrupt\n"); 
   if (HostP->Ivec == irq) {
     /* Tell the card we've noticed the interrupt. */
     rio_reset_interrupt (HostP);
@@ -649,7 +525,7 @@
   clear_bit (RIO_BOARD_INTR_LOCK, &HostP->locks);
   rio_dprintk (RIO_DEBUG_IFLOW, "rio: exit rio_interrupt (%d/%d)\n", 
                irq, HostP->Ivec); 
-  /*  func_exit ();  */
+  func_exit ();
 }
 
 
@@ -657,7 +533,7 @@
 {
   func_enter ();
 
-  rio_interrupt (0, (void *)data, NULL);
+  rio_interrupt (0, &p->RIOHosts[data], NULL);
   p->RIOHosts[data].timer.expires = jiffies + rio_poll;
   add_timer (&p->RIOHosts[data].timer);
 
@@ -756,11 +632,11 @@
 #if 0
   port->gs.flags &= ~ GS_ACTIVE;
   if (!port->gs.tty) {
-    printk ("No tty.\n");
+    rio_dprintk (RIO_DBUG_TTY, "No tty.\n");
     return;
   }
   if (!port->gs.tty->termios) {
-    printk ("No termios.\n");
+    rio_dprintk (RIO_DEBUG_TTY, "No termios.\n");
     return;
   }
   if (port->gs.tty->termios->c_cflag & HUPCL) {
@@ -772,7 +648,6 @@
 }
 
 
-
 /* ********************************************************************** *
  *                Here are the routines that actually                     *
  *               interface with the rest of the system                    *
@@ -807,7 +682,7 @@
 static void rio_hungup (void *ptr)
 {
   func_enter ();
-  /* rio_dec_mod_count (); */
+  rio_dec_mod_count (); 
   func_exit ();
 }
 
@@ -818,9 +693,22 @@
  */
 static void rio_close (void *ptr)
 {
+  struct Port *PortP;
+
   func_enter ();
+
+  PortP = (struct Port *)ptr;
+
   riotclose (ptr);
+
+  if(PortP->gs.count) {
+    printk (KERN_ERR "WARNING port count:%d\n", PortP->gs.count);
+    PortP->gs.count = 0; 
+  }                
+
+
   rio_dec_mod_count ();
+
   func_exit ();
 }
 
@@ -1000,6 +888,8 @@
 
   if (rio_debug & RIO_DEBUG_PROBE)
     my_hd ((char *)&vpdp, 0x20);
+  
+  func_exit();
 
   return &vpdp;
 }
@@ -1099,7 +989,7 @@
   /* However, the RIO driver allows users to configure their first
      RTA as the ports numbered 504-511. We therefore need to allocate 
      the whole range. :-(   -- REW */
-
+  
 #define RI_SZ   sizeof(struct rio_info)
 #define HOST_SZ sizeof(struct Host)
 #define PORT_SZ sizeof(struct Port *)
@@ -1138,11 +1028,14 @@
     port->gs.close_delay = HZ/2;
     port->gs.closing_wait = 30 * HZ;
     port->gs.rd = &rio_real_driver;
+    port->portSem = SPIN_LOCK_UNLOCKED;
   }
 #else
   /* We could postpone initializing them to when they are configured. */
 #endif
 
+
+  
   if (rio_debug & RIO_DEBUG_INIT) {
     my_hd (&rio_real_driver, sizeof (rio_real_driver));
   }
@@ -1165,7 +1058,7 @@
   return -ENOMEM;
 }
 
-
+#ifdef MODULE
 static void rio_release_drivers(void)
 {
   func_enter();
@@ -1175,6 +1068,7 @@
   tty_unregister_driver (&rio_driver);
   func_exit();
 }
+#endif 
 
 #ifdef TWO_ZERO
 #define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -1211,7 +1105,7 @@
   unsigned int t;
 
 #define CNTRL_REG_OFFSET        0x50
-#define CNTRL_REG_GOODVALUE     0x00260000
+#define CNTRL_REG_GOODVALUE     0x18260000
 
   pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, &hwbase);
   hwbase &= PCI_BASE_ADDRESS_MEM_MASK;
@@ -1292,7 +1186,6 @@
       pci_read_config_dword (pdev, 0x2c, &tint);
       tshort = (tint >> 16) & 0xffff;
       rio_dprintk (RIO_DEBUG_PROBE, "Got a specialix card: %x.\n", tint);
-      /* rio_dprintk (RIO_DEBUG_PROBE, "pdev = %d/%d  (%x)\n", pdev, tint); */ 
       if (tshort != 0x0100) {
         rio_dprintk (RIO_DEBUG_PROBE, "But it's not a RIO card (%d)...\n", 
                     tshort);
@@ -1305,49 +1198,52 @@
       hp = &p->RIOHosts[p->RIONumHosts];
       hp->PaddrP =  tint & PCI_BASE_ADDRESS_MEM_MASK;
       hp->Ivec = get_irq (pdev);
-      if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+      if (((1 << hp->Ivec) & rio_irqmask) == 0)
+              hp->Ivec = 0;
       hp->CardP	= (struct DpRam *)
       hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy; 
-      hp->Mode  = RIO_PCI_DEFAULT_MODE;
- 
+      hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+      hp->HostLock = SPIN_LOCK_UNLOCKED;
+      rio_reset_interrupt (hp);
+      rio_start_card_running (hp);
+
       rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
                    (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
                    p->RIOHosts[p->RIONumHosts].Caddr);
       if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
                         p->RIOHosts[p->RIONumHosts].Caddr, 
                         RIO_PCI, 0 ) == RIO_SUCCESS) {
-        WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
-        p->RIOHosts[p->RIONumHosts].UniqueNum  =
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
-          ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
-        rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
-                   p->RIOHosts[p->RIONumHosts].UniqueNum);
-
-#if 1
-        fix_rio_pci (pdev);
-#endif
-        p->RIOLastPCISearch = RIO_SUCCESS;
-        p->RIONumHosts++;
-        found++;
+              rio_dprintk (RIO_DEBUG_INIT, "Done RIOBoardTest\n");
+              WBYTE(p->RIOHosts[p->RIONumHosts].ResetInt, 0xff);
+              p->RIOHosts[p->RIONumHosts].UniqueNum  =
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[0]) &0xFF)<< 0)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1]) &0xFF)<< 8)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2]) &0xFF)<<16)|
+                      ((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3]) &0xFF)<<24);
+              rio_dprintk (RIO_DEBUG_PROBE, "Hmm Tested ok, uniqid = %x.\n",
+                           p->RIOHosts[p->RIONumHosts].UniqueNum);
+              
+              fix_rio_pci (pdev);
+              p->RIOLastPCISearch = RIO_SUCCESS;
+              p->RIONumHosts++;
+              found++;
       } else {
-        my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, 
-                    p->RIOHosts[p->RIONumHosts].Caddr);
+              my_iounmap (p->RIOHosts[p->RIONumHosts].PaddrP, 
+                          p->RIOHosts[p->RIONumHosts].Caddr);
       }
-
+      
 #ifdef TWO_ZERO
     }  /* We have two variants with the opening brace, so to prevent */
 #else
     }  /* Emacs from getting confused we have two closing braces too. */
 #endif
     
-
     /* Then look for the older PCI card.... : */
 #ifndef TWO_ZERO
 
+
   /* These older PCI cards have problems (only byte-mode access is
      supported), which makes them a bit awkward to support. 
      They also have problems sharing interrupts. Be careful. 
@@ -1372,15 +1268,21 @@
       hp = &p->RIOHosts[p->RIONumHosts];
       hp->PaddrP =  tint & PCI_BASE_ADDRESS_MEM_MASK;
       hp->Ivec = get_irq (pdev);
-      if (((1 << hp->Ivec) & rio_irqmask) == 0) hp->Ivec = 0;
+      if (((1 << hp->Ivec) & rio_irqmask) == 0) 
+      	hp->Ivec = 0;
       hp->Ivec |= 0x8000; /* Mark as non-sharable */
       hp->CardP	= (struct DpRam *)
       hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
       hp->Type  = RIO_PCI;
       hp->Copy  = rio_pcicopy;
-      hp->Mode  = RIO_PCI_DEFAULT_MODE;
- 
-      rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
+      hp->Mode  = RIO_PCI_BOOT_FROM_RAM;
+
+      rio_dprintk (RIO_DEBUG_PROBE, "Ivec: %x\n", hp->Ivec);
+      rio_dprintk (RIO_DEBUG_PROBE, "Mode: %x\n", hp->Mode);
+
+      rio_reset_interrupt (hp);
+      rio_start_card_running (hp);
+       rio_dprintk (RIO_DEBUG_PROBE, "Going to test it (%p/%p).\n",
                    (void *)p->RIOHosts[p->RIONumHosts].PaddrP,
                    p->RIOHosts[p->RIONumHosts].Caddr);
       if (RIOBoardTest( p->RIOHosts[p->RIONumHosts].PaddrP,
@@ -1423,11 +1325,15 @@
     hp->CardP = (struct DpRam *)
     hp->Caddr = ioremap(p->RIOHosts[p->RIONumHosts].PaddrP, RIO_WINDOW_LEN);
     hp->Type = RIO_AT;
-    hp->Copy = rio_pcicopy;
+    hp->Copy = rio_pcicopy; /* AT card PCI???? - PVDL
+                             * -- YES! this is now a normal copy. Only the 
+                             * old PCI card uses the special PCI copy. 
+                             * Moreover, the ISA card will work with the 
+                             * special PCI copy anyway. -- REW */
     hp->Mode = 0;
 
     vpdp = get_VPD_PROM (hp);
-
+    rio_dprintk (RIO_DEBUG_PROBE, "Got VPD ROM\n");
     okboard = 0;
     if ((strncmp (vpdp->identifier, RIO_ISA_IDENT, 16) == 0) ||
         (strncmp (vpdp->identifier, RIO_ISA2_IDENT, 16) == 0) ||
@@ -1458,11 +1364,21 @@
     if (hp->Ivec) {
       int mode = SA_SHIRQ;
       if (hp->Ivec & 0x8000) {mode = 0; hp->Ivec &= 0x7fff;}
-      if (request_irq (hp->Ivec, rio_interrupt, mode, "rio", (void *)i)) {
-        printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
-        hp->Ivec = 0;
+      rio_dprintk (RIO_DEBUG_INIT, "Requesting interrupt hp: %p rio_interrupt: %d Mode: %x\n", hp,hp->Ivec, hp->Mode);
+      retval = request_irq (hp->Ivec, rio_interrupt, mode, "rio", hp);
+      rio_dprintk (RIO_DEBUG_INIT, "Return value from request_irq: %d\n", retval);
+      if (retval) {
+              printk(KERN_ERR "rio: Cannot allocate irq %d.\n", hp->Ivec);
+              hp->Ivec = 0;
       }
       rio_dprintk (RIO_DEBUG_INIT, "Got irq %d.\n", hp->Ivec);
+      if (hp->Ivec != 0){
+              rio_dprintk (RIO_DEBUG_INIT, "Enabling interrupts on rio card.\n"); 
+              hp->Mode |= RIO_PCI_INT_ENABLE;
+      } else
+              hp->Mode &= !RIO_PCI_INT_ENABLE;
+      rio_dprintk (RIO_DEBUG_INIT, "New Mode: %x\n", hp->Mode);
+      rio_start_card_running (hp);
     }
     /* Init the timer "always" to make sure that it can safely be 
        deleted when we unload... */
@@ -1479,7 +1395,7 @@
   }
 
   if (found) {
-    printk (KERN_INFO "rio: total of %d boards detected.\n", found);
+    rio_dprintk (RIO_DEBUG_INIT, "rio: total of %d boards detected.\n", found);
 
     if (misc_register(&rio_fw_device) < 0) {
       printk(KERN_ERR "RIO: Unable to register firmware loader driver.\n");
@@ -1504,7 +1420,7 @@
   for (i=0,hp=p->RIOHosts;i<p->RIONumHosts;i++, hp++) {
     RIOHostReset (hp->Type, hp->CardP, hp->Slot);
     if (hp->Ivec) {
-      free_irq (hp->Ivec, (void *)i);
+      free_irq (hp->Ivec, hp);
       rio_dprintk (RIO_DEBUG_INIT, "freed irq %d.\n", hp->Ivec);
     }
     /* It is safe/allowed to del_timer a non-active timer */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rio_linux.h linux.17p18/drivers/char/rio/rio_linux.h
--- linux.vanilla/drivers/char/rio/rio_linux.h	Fri Apr 21 23:15:15 2000
+++ linux.17p18/drivers/char/rio/rio_linux.h	Wed Aug  9 22:24:45 2000
@@ -23,11 +23,14 @@
  *  Version 1.0 -- July, 1999. 
  * 
  */
+#include <linux/config.h>
 
 #define RIO_NBOARDS        4
 #define RIO_PORTSPERBOARD 128
 #define RIO_NPORTS        (RIO_NBOARDS * RIO_PORTSPERBOARD)
 
+#define MODEM_SUPPORT
+
 #ifdef __KERNEL__
 
 #define RIO_MAGIC 0x12345678
@@ -84,31 +87,34 @@
 #endif
 
 
+void rio_dec_mod_count (void);
+void rio_inc_mod_count (void);
+
 /* Allow us to debug "in the field" without requiring clients to
    recompile.... */
 #if 1
 #define rio_spin_lock_irqsave(sem, flags) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinlockirqsave: %p %s:%d\n", \
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlockirqsave: %p %s:%d\n", \
+					sem, __FILE__, __LINE__);\
         spin_lock_irqsave(sem, flags);\
         } while (0)
 
 #define rio_spin_unlock_irqrestore(sem, flags) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinunlockirqrestore: %p %s:%d\n",\
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlockirqrestore: %p %s:%d\n",\
+					sem, __FILE__, __LINE__);\
         spin_unlock_irqrestore(sem, flags);\
         } while (0)
 
 
 #define rio_spin_lock(sem) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinlock: %p %s:%d\n",\
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinlock: %p %s:%d\n",\
+					sem, __FILE__, __LINE__);\
         spin_lock(sem);\
         } while (0)
 
 #define rio_spin_unlock(sem) do { \
-	rio_dprint(RIO_DEBUG_SPINLOCK, ("spinunlock: %p %s:%d\n",\
-					sem, __FILE__, __LINE__));\
+	rio_dprintk (RIO_DEBUG_SPINLOCK, "spinunlock: %p %s:%d\n",\
+					sem, __FILE__, __LINE__);\
         spin_unlock(sem);\
         } while (0)
 #else
@@ -157,5 +163,30 @@
 #else
 #define rio_memcpy_toio(dummy,dest,source,n)   memcpy_toio(dest, source, n)
 #define rio_memcpy_fromio                      memcpy_fromio
+#endif
+
+#define DEBUG
+
+
+/* 
+   This driver can spew a whole lot of debugging output at you. If you
+   need maximum performance, you should disable the DEBUG define. To
+   aid in debugging in the field, I'm leaving the compile-time debug
+   features enabled, and disable them "runtime". That allows me to
+   instruct people with problems to enable debugging without requiring
+   them to recompile... 
+*/
+
+#ifdef DEBUG
+#define rio_dprintk(f, str...) do { if (rio_debug & f) printk (str);} while (0)
+#define func_enter() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ "\n")
+#define func_exit()  rio_dprintk (RIO_DEBUG_FLOW, "rio: exit  " __FUNCTION__ "\n")
+#define func_enter2() rio_dprintk (RIO_DEBUG_FLOW, "rio: enter " __FUNCTION__ \
+                                   "(port %d)\n", port->line)
+#else
+#define rio_dprintk(f, str...) /* nothing */
+#define func_enter()
+#define func_exit()
+#define func_enter2()
 #endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rioboot.c linux.17p18/drivers/char/rio/rioboot.c
--- linux.vanilla/drivers/char/rio/rioboot.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/rioboot.c	Wed Aug  9 22:24:45 2000
@@ -35,7 +35,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -82,7 +81,6 @@
 #include "cmdblk.h"
 #include "route.h"
 
-
 static uchar
 RIOAtVec2Ctrl[] =
 {
@@ -114,26 +112,30 @@
 {
 	int offset;
 
+	func_enter ();
+
 	/* Linux doesn't allow you to disable interrupts during a
 	   "copyin". (Crash when a pagefault occurs). */
 	/* disable(oldspl); */
 	
-	rio_dprint(RIO_DEBUG_BOOT, ("Data at user address 0x%x\n",(int)rbp->DataP));
+	rio_dprintk (RIO_DEBUG_BOOT, "Data at user address 0x%x\n",(int)rbp->DataP);
 
 	/*
 	** Check that we have set asside enough memory for this
 	*/
 	if ( rbp->Count > SIXTY_FOUR_K ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code Too Large!\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code Too Large!\n");
 		p->RIOError.Error = HOST_FILE_TOO_LARGE;
 		/* restore(oldspl); */
+		func_exit ();
 		return ENOMEM;
 	}
 
 	if ( p->RIOBooting ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot Code : BUSY BUSY BUSY!\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot Code : BUSY BUSY BUSY!\n");
 		p->RIOError.Error = BOOT_IN_PROGRESS;
 		/* restore(oldspl); */
+		func_exit ();
 		return EBUSY;
 	}
 
@@ -158,9 +160,10 @@
 
 	if ( copyin((int)rbp->DataP,((caddr_t)(p->RIOBootPackets))+offset,
 				rbp->Count) ==COPYFAIL ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("Bad data copy from user space\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Bad data copy from user space\n");
 		p->RIOError.Error = COPYIN_FAILED;
 		/* restore(oldspl); */
+		func_exit ();
 		return EFAULT;
 	}
 
@@ -172,9 +175,61 @@
 	p->RIOBootCount   = rbp->Count;
 
 	/* restore(oldspl); */
+	func_exit();
 	return 0;
 }
 
+void rio_start_card_running (struct Host * HostP)
+{
+	func_enter ();
+
+	switch ( HostP->Type ) {
+	case RIO_AT:
+		rio_dprintk (RIO_DEBUG_BOOT, "Start ISA card running\n");
+		WBYTE(HostP->Control, 
+		      BOOT_FROM_RAM | EXTERNAL_BUS_ON
+		      | HostP->Mode
+		      | RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
+		break;
+		
+#ifdef FUTURE_RELEASE
+	case RIO_MCA:
+				/*
+				** MCA handles IRQ vectors differently, so we don't write 
+				** them to this register.
+				*/
+		rio_dprintk (RIO_DEBUG_BOOT, "Start MCA card running\n");
+		WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
+		break;
+
+	case RIO_EISA:
+				/*
+				** EISA is totally different and expects OUTBZs to turn it on.
+				*/
+		rio_dprintk (RIO_DEBUG_BOOT, "Start EISA card running\n");
+		OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
+		break;
+#endif
+
+	case RIO_PCI:
+				/*
+				** PCI is much the same as MCA. Everything is once again memory
+				** mapped, so we are writing to memory registers instead of io
+				** ports.
+				*/
+		rio_dprintk (RIO_DEBUG_BOOT, "Start PCI card running\n");
+		WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
+		break;
+	default:
+		rio_dprintk (RIO_DEBUG_BOOT, "Unknown host type %d\n", HostP->Type);
+		break;
+	}
+/* 
+	printk (KERN_INFO "Done with starting the card\n");
+	func_exit ();
+*/
+	return;
+}
 
 /*
 ** Load in the host boot code - load it directly onto all halted hosts
@@ -205,11 +260,15 @@
 
 	HostP = NULL; /* Assure the compiler we've initialized it */
 	for ( host=0; host<p->RIONumHosts; host++ ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("Attempt to boot host %d\n",host));
+		rio_dprintk (RIO_DEBUG_BOOT, "Attempt to boot host %d\n",host);
 		HostP = &p->RIOHosts[host];
+		
+		rio_dprintk (RIO_DEBUG_BOOT,  "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+		    HostP->Type, HostP->Mode, HostP->Ivec);
+
 
 		if ( (HostP->Flags & RUN_STATE) != RC_WAITING ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("%s %d already running\n","Host",host));
+			rio_dprintk (RIO_DEBUG_BOOT, "%s %d already running\n","Host",host);
 			continue;
 		}
 
@@ -226,14 +285,15 @@
 		*/
 		StartP = (caddr_t)&Cad[p->RIOConf.HostLoadBase-rbp->Count];
 
-		rio_dprint(RIO_DEBUG_BOOT,  ("kernel virtual address for host is 0x%x\n", (int)Cad ) );
-		rio_dprint(RIO_DEBUG_BOOT,  ("kernel virtual address for download is 0x%x\n", (int)StartP ) );
-		rio_dprint(RIO_DEBUG_BOOT, ("host loadbase is 0x%x\n",p->RIOConf.HostLoadBase));
-		rio_dprint(RIO_DEBUG_BOOT,  ("size of download is 0x%x\n", rbp->Count ) );
+		rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for host is 0x%x\n", (int)Cad );
+		rio_dprintk (RIO_DEBUG_BOOT, "kernel virtual address for download is 0x%x\n", (int)StartP);
+		rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
+		rio_dprintk (RIO_DEBUG_BOOT, "size of download is 0x%x\n", rbp->Count);
 
 		if ( p->RIOConf.HostLoadBase < rbp->Count ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Bin too large\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "Bin too large\n");
 			p->RIOError.Error = HOST_FILE_TOO_LARGE;
+			func_exit ();
 			return EFBIG;
 		}
 		/*
@@ -247,7 +307,7 @@
 		** This ain't going to be none too clever if the download
 		** code is bigger than this segment.
 		*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Copy in code\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Copy in code\n");
 
 		/*
 		** PCI hostcard can't cope with 32 bit accesses and so need to copy 
@@ -258,15 +318,17 @@
 
 			DownCode = sysbrk(rbp->Count);
 			if ( !DownCode ) {
-				rio_dprint(RIO_DEBUG_BOOT, ("No system memory available\n"));
+				rio_dprintk (RIO_DEBUG_BOOT, "No system memory available\n");
 				p->RIOError.Error = NOT_ENOUGH_CORE_FOR_PCI_COPY;
+				func_exit ();
 				return ENOMEM;
 			}
 			bzero(DownCode, rbp->Count);
 
 			if ( copyin((int)rbp->DataP,DownCode,rbp->Count)==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
+				rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
 				p->RIOError.Error = COPYIN_FAILED;
+				func_exit ();
 				return EFAULT;
 			}
 
@@ -275,12 +337,13 @@
 			sysfree( DownCode, rbp->Count );
 		}
 		else if ( copyin((int)rbp->DataP,StartP,rbp->Count)==COPYFAIL ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Bad copyin of host data\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "Bad copyin of host data\n");
 			p->RIOError.Error = COPYIN_FAILED;
+			func_exit ();
 			return EFAULT;
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Copy completed\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Copy completed\n");
 
 		/*
 		**			S T O P !
@@ -381,8 +444,8 @@
 		WBYTE( DestP[6] , NFIX(0) );
 		WBYTE( DestP[7] , JUMP(8) );
 
-		rio_dprint(RIO_DEBUG_BOOT, ("host loadbase is 0x%x\n",p->RIOConf.HostLoadBase));
-		rio_dprint(RIO_DEBUG_BOOT, ("startup offset is 0x%x\n",offset));
+		rio_dprintk (RIO_DEBUG_BOOT, "host loadbase is 0x%x\n",p->RIOConf.HostLoadBase);
+		rio_dprintk (RIO_DEBUG_BOOT, "startup offset is 0x%x\n",offset);
 
 		/*
 		** Flag what is going on
@@ -396,67 +459,29 @@
 		*/
 		OldParmMap = RWORD(HostP->__ParmMapR);
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Original parmmap is 0x%x\n",OldParmMap));
+		rio_dprintk (RIO_DEBUG_BOOT, "Original parmmap is 0x%x\n",OldParmMap);
 
 		/*
 		** And start it running (I hope).
 		** As there is nothing dodgy or obscure about the
 		** above code, this is guaranteed to work every time.
 		*/
-		rio_dprint(RIO_DEBUG_BOOT,  ("Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
-		    HostP->Type, HostP->Mode, HostP->Ivec ) );
-
-		switch ( HostP->Type ) {
-			case RIO_AT:
-				rio_dprint(RIO_DEBUG_BOOT, ("Start ISA card running\n"));
-				WBYTE(HostP->Control, 
-					BOOT_FROM_RAM | EXTERNAL_BUS_ON
-					| HostP->Mode
-					| RIOAtVec2Ctrl[HostP->Ivec & 0xF] );
-				break;
-
-#ifdef FUTURE_RELEASE
-			case RIO_MCA:
-				/*
-				** MCA handles IRQ vectors differently, so we don't write 
-				** them to this register.
-				*/
-				rio_dprint(RIO_DEBUG_BOOT, ("Start MCA card running\n"));
-				WBYTE(HostP->Control, McaTpBootFromRam | McaTpBusEnable | HostP->Mode);
-				break;
+		rio_dprintk (RIO_DEBUG_BOOT,  "Host Type = 0x%x, Mode = 0x%x, IVec = 0x%x\n",
+		    HostP->Type, HostP->Mode, HostP->Ivec);
 
-			case RIO_EISA:
-				/*
-				** EISA is totally different and expects OUTBZs to turn it on.
-				*/
-				rio_dprint(RIO_DEBUG_BOOT, NULL,DBG_DAEMON,"Start EISA card running\n");
-				OUTBZ( HostP->Slot, EISA_CONTROL_PORT, HostP->Mode | RIOEisaVec2Ctrl[HostP->Ivec] | EISA_TP_RUN | EISA_TP_BUS_ENABLE | EISA_TP_BOOT_FROM_RAM );
-				break;
-#endif
+		rio_start_card_running(HostP);
 
-			case RIO_PCI:
-				/*
-				** PCI is much the same as MCA. Everything is once again memory
-				** mapped, so we are writing to memory registers instead of io
-				** ports.
-				*/
-				rio_dprint(RIO_DEBUG_BOOT, ("Start PCI card running\n"));
-				WBYTE(HostP->Control, PCITpBootFromRam | PCITpBusEnable | HostP->Mode);
-				break;
-			default:
-				rio_dprint(RIO_DEBUG_BOOT, ("Unknown host type %d\n",HostP->Type));
-				break;
-		}
-		rio_dprint(RIO_DEBUG_BOOT, ("Set control port\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Set control port\n");
 
 		/*
 		** Now, wait for upto five seconds for the Tp to setup the parmmap
 		** pointer:
 		*/
 		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime)&&
-				(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR)));
+			(RWORD(HostP->__ParmMapR)==OldParmMap); wait_count++ ) {
+			rio_dprintk (RIO_DEBUG_BOOT, "Checkout %d, 0x%x\n",wait_count,RWORD(HostP->__ParmMapR));
 			delay(HostP, HUNDRED_MS);
+
 		}
 
 		/*
@@ -464,8 +489,8 @@
 		** has crashed & burned in a really spectacular way
 		*/
 		if ( RWORD(HostP->__ParmMapR) == OldParmMap ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("parmmap 0x%x\n", RWORD(HostP->__ParmMapR)));
-			rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "parmmap 0x%x\n", RWORD(HostP->__ParmMapR));
+			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail\n");
 
 #define	HOST_DISABLE \
 		HostP->Flags &= ~RUN_STATE; \
@@ -476,7 +501,7 @@
 			HOST_DISABLE;
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Running 0x%x\n",RWORD(HostP->__ParmMapR)));
+		rio_dprintk (RIO_DEBUG_BOOT, "Running 0x%x\n", RWORD(HostP->__ParmMapR));
 
 		/*
 		** Well, the board thought it was OK, and setup its parmmap
@@ -488,10 +513,10 @@
 		** Grab a 32 bit pointer to the parmmap structure
 		*/
 		ParmMapP = (PARM_MAP *)RIO_PTR(Cad,RWORD(HostP->__ParmMapR));
-		rio_dprint(RIO_DEBUG_BOOT, ("ParmMapP : %x\n", (int)ParmMapP));
+		rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
 		ParmMapP = (PARM_MAP *)((unsigned long)Cad + 
 						(unsigned long)((RWORD((HostP->__ParmMapR))) & 0xFFFF)); 
-		rio_dprint(RIO_DEBUG_BOOT, ("ParmMapP : %x\n", (int)ParmMapP));
+		rio_dprintk (RIO_DEBUG_BOOT, "ParmMapP : %x\n", (int)ParmMapP);
 
 		/*
 		** The links entry should be 0xFFFF; we set it up
@@ -499,8 +524,8 @@
 		** which links to use.
 		*/
 		if ( (RWORD(ParmMapP->links) & 0xFFFF) != 0xFFFF ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail %s\n", HostP->Name));
-			rio_dprint(RIO_DEBUG_BOOT, ("Links = 0x%x\n",RWORD(ParmMapP->links)));
+			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
+			rio_dprintk (RIO_DEBUG_BOOT, "Links = 0x%x\n",RWORD(ParmMapP->links));
 			HOST_DISABLE;
 		}
 
@@ -510,28 +535,28 @@
 		** now wait for the card to set all the parmmap->XXX stuff
 		** this is a wait of upto two seconds....
 		*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Looking for init_done - %d ticks\n",p->RIOConf.StartupTime));
+		rio_dprintk (RIO_DEBUG_BOOT, "Looking for init_done - %d ticks\n",p->RIOConf.StartupTime);
 		HostP->timeout_id = 0;
 		for ( wait_count=0; (wait_count<p->RIOConf.StartupTime) && 
 						!RWORD(ParmMapP->init_done); wait_count++ ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Waiting for init_done\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "Waiting for init_done\n");
 			delay(HostP, HUNDRED_MS);
 		}
-		rio_dprint(RIO_DEBUG_BOOT, ("OK! init_done!\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "OK! init_done!\n");
 
 		if (RWORD(ParmMapP->error) != E_NO_ERROR || 
 							!RWORD(ParmMapP->init_done) ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("RIO Mesg Run Fail %s\n", HostP->Name));
-			rio_dprint(RIO_DEBUG_BOOT, ("Timedout waiting for init_done\n"));
+			rio_dprintk (RIO_DEBUG_BOOT, "RIO Mesg Run Fail %s\n", HostP->Name);
+			rio_dprintk (RIO_DEBUG_BOOT, "Timedout waiting for init_done\n");
 			HOST_DISABLE;
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Got init_done\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Got init_done\n");
 
 		/*
 		** It runs! It runs!
 		*/
-		rio_dprint(RIO_DEBUG_BOOT, ("Host ID %x Running\n",HostP->UniqueNum));
+		rio_dprintk (RIO_DEBUG_BOOT, "Host ID %x Running\n",HostP->UniqueNum);
 
 		/*
 		** set the time period between interrupts.
@@ -555,12 +580,14 @@
 			HostP->UnixRups[RupN].RupP		= &HostP->RupP[RupN];
 			HostP->UnixRups[RupN].Id		  = RupN+1;
 			HostP->UnixRups[RupN].BaseSysPort = NO_PORT;
+			HostP->UnixRups[RupN].RupLock = SPIN_LOCK_UNLOCKED;
 		}
 
 		for ( RupN = 0; RupN<LINKS_PER_UNIT; RupN++ ) {
 			HostP->UnixRups[RupN+MAX_RUP].RupP	= &HostP->LinkStrP[RupN].rup;
 			HostP->UnixRups[RupN+MAX_RUP].Id  = 0;
 			HostP->UnixRups[RupN+MAX_RUP].BaseSysPort = NO_PORT;
+			HostP->UnixRups[RupN+MAX_RUP].RupLock = SPIN_LOCK_UNLOCKED;
 		}
 
 		/*
@@ -597,7 +624,7 @@
 			}
 		}
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Set the card running... \n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "Set the card running... \n");
 		/*
 		** last thing - show the world that everything is in place
 		*/
@@ -613,7 +640,8 @@
 
 	p->RIOSystemUp++;
 	
-	rio_dprint(RIO_DEBUG_BOOT, ("Done everything %x\n", HostP->Ivec));
+	rio_dprintk (RIO_DEBUG_BOOT, "Done everything %x\n", HostP->Ivec);
+	func_exit ();
 	return 0;
 }
 
@@ -646,7 +674,7 @@
 	** If we haven't been told what to boot, we can't boot it.
 	*/
 	if ( p->RIONumBootPkts == 0 ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("No RTA code to download yet\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "No RTA code to download yet\n");
 		return 0;
 	}
 
@@ -667,7 +695,7 @@
 	** try to unhook a command block from the command free list.
 	*/
 	if ( !(CmdBlkP = RIOGetCmdBlk()) ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("No command blocks to boot RTA! come back later.\n"));
+		rio_dprintk (RIO_DEBUG_BOOT, "No command blocks to boot RTA! come back later.\n");
 		return 0;
 	}
 
@@ -690,8 +718,8 @@
 		** We only expect one type of command - a BOOT_REQUEST!
 		*/
 		if ( RBYTE(PktCmdP->Command) != BOOT_REQUEST ) {
-			rio_dprint(RIO_DEBUG_BOOT, ("Unexpected command %d on BOOT RUP %d of host %d\n", 
-						PktCmdP->Command,Rup,HostP-p->RIOHosts));
+			rio_dprintk (RIO_DEBUG_BOOT, "Unexpected command %d on BOOT RUP %d of host %d\n", 
+						PktCmdP->Command,Rup,HostP-p->RIOHosts);
 			ShowPacket( DBG_BOOT, PacketP );
 			RIOFreeCmdBlk( CmdBlkP );
 			return 1;
@@ -728,9 +756,9 @@
 
 		bcopy("BOOT",(void *)&CmdBlkP->Packet.data[BOOT_SEQUENCE_LEN],4);
 
-		rio_dprint(RIO_DEBUG_BOOT, ("Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
+		rio_dprintk (RIO_DEBUG_BOOT, "Boot RTA on Host %d Rup %d - %d (0x%x) packets to 0x%x\n",
 			HostP-p->RIOHosts, Rup, p->RIONumBootPkts, p->RIONumBootPkts, 
-								p->RIOConf.RtaLoadBase));
+								p->RIOConf.RtaLoadBase);
 
 		/*
 		** If this host is in slave mode, send the RTA an invalid boot
@@ -749,11 +777,11 @@
 	*/
 	sequence = RWORD(PktCmdP->Sequence);
 
-	rio_dprint(RIO_DEBUG_BOOT, ("Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup));
+	rio_dprintk (RIO_DEBUG_BOOT, "Boot block %d on Host %d Rup%d\n",sequence,HostP-p->RIOHosts,Rup);
 
 	if ( sequence >= p->RIONumBootPkts ) {
-		rio_dprint(RIO_DEBUG_BOOT, ("Got a request for packet %d, max is %d\n", sequence, 
-					p->RIONumBootPkts));
+		rio_dprintk (RIO_DEBUG_BOOT, "Got a request for packet %d, max is %d\n", sequence, 
+					p->RIONumBootPkts);
 		ShowPacket( DBG_BOOT, PacketP );
 	}
 
@@ -795,26 +823,26 @@
 	   driver will never think that the RTA has booted... -- REW */
 	p->RIOBooting = 0;
 
-	rio_dprint(RIO_DEBUG_BOOT, ("RTA Boot completed - BootInProgress now %d\n", p->RIOBooting));
+	rio_dprintk (RIO_DEBUG_BOOT, "RTA Boot completed - BootInProgress now %d\n", p->RIOBooting);
 
 	/*
 	** Determine type of unit (16/8 port RTA).
 	*/
 	RtaType = GetUnitType(RtaUniq);
         if ( Rup >= (ushort)MAX_RUP ) {
-	    rio_dprint(RIO_DEBUG_BOOT, ("RIO: Host %s has booted an RTA(%d) on link %c\n",
-	     HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A' ));
+	    rio_dprintk (RIO_DEBUG_BOOT, "RIO: Host %s has booted an RTA(%d) on link %c\n",
+	     HostP->Name, 8 * RtaType, RBYTE(PktCmdP->LinkNum)+'A');
 	} else {
-	    rio_dprint(RIO_DEBUG_BOOT, ("RIO: RTA %s has booted an RTA(%d) on link %c\n",
+	    rio_dprintk (RIO_DEBUG_BOOT, "RIO: RTA %s has booted an RTA(%d) on link %c\n",
 	     HostP->Mapping[Rup].Name, 8 * RtaType,
-	     RBYTE(PktCmdP->LinkNum)+'A'));
+	     RBYTE(PktCmdP->LinkNum)+'A');
 	}
 
-	rio_dprint(RIO_DEBUG_BOOT, ("UniqNum is 0x%x\n",RtaUniq));
+	rio_dprintk (RIO_DEBUG_BOOT, "UniqNum is 0x%x\n",RtaUniq);
 
         if ( ( RtaUniq == 0x00000000 ) || ( RtaUniq == 0xffffffff ) )
 	{
-	    rio_dprint(RIO_DEBUG_BOOT, ( "Illegal RTA Uniq Number\n"));
+	    rio_dprintk (RIO_DEBUG_BOOT, "Illegal RTA Uniq Number\n");
 	    return TRUE;
 	}
 
@@ -835,8 +863,8 @@
 		*/
 		if (RIOSuspendBootRta(HostP, HostP->Mapping[Rup].ID, MyLink))
 		{
-		    rio_dprint(RIO_DEBUG_BOOT, ("RTA failed to suspend booting on link %c\n",
-		     'A' + MyLink));
+		    rio_dprintk (RIO_DEBUG_BOOT, "RTA failed to suspend booting on link %c\n",
+		     'A' + MyLink);
 		}
 	    }
 	    else
@@ -848,8 +876,8 @@
 		*/
 		WWORD(HostP->LinkStrP[MyLink].WaitNoBoot, 30);
 	    }
-	    rio_dprint(RIO_DEBUG_BOOT, ("RTA %x not owned - suspend booting down link %c on unit %x\n",
-	      RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum));
+	    rio_dprintk (RIO_DEBUG_BOOT, "RTA %x not owned - suspend booting down link %c on unit %x\n",
+	      RtaUniq, 'A' + MyLink, HostP->Mapping[Rup].RtaUniqueNum);
 	    return TRUE;
 	}
 
@@ -899,16 +927,16 @@
 		   }
 		}
 		if (RtaType == TYPE_RTA16) {
-		   rio_dprint(RIO_DEBUG_BOOT, ("RTA will be given IDs %d+%d\n",
-		    entry+1, entry2+1));
+		   rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given IDs %d+%d\n",
+		    entry+1, entry2+1);
 		} else {
-		   rio_dprint(RIO_DEBUG_BOOT, ("RTA will be given ID %d\n",entry+1));
+		   rio_dprintk (RIO_DEBUG_BOOT, "RTA will be given ID %d\n",entry+1);
 		}
 		return TRUE;
 	    }
 	}
 
-	rio_dprint(RIO_DEBUG_BOOT, ("RTA not configured for this host\n"));
+	rio_dprintk (RIO_DEBUG_BOOT, "RTA not configured for this host\n");
 
 	if ( Rup >= (ushort)MAX_RUP )
 	{
@@ -952,13 +980,13 @@
 		    entry2 = HostP->Mapping[entry].ID2 - 1;
 		    if ( (HostP->Mapping[entry2].Flags & SLOT_TENTATIVE) &&
 			 (HostP->Mapping[entry2].RtaUniqueNum == RtaUniq) )
-			rio_dprint(RIO_DEBUG_BOOT, ("Found previous tentative slots (%d+%d)\n",
-			 entry, entry2));
+			rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slots (%d+%d)\n",
+			 entry, entry2);
 		    else
 			continue;
 		}
 		else
-			rio_dprint(RIO_DEBUG_BOOT, ("Found previous tentative slot (%d)\n",entry));
+			rio_dprintk (RIO_DEBUG_BOOT, "Found previous tentative slot (%d)\n",entry);
 		if (! p->RIONoMessage)
 		    cprintf("RTA connected to %s '%s' (%c) not configured.\n",MyType,MyName,MyLink+'A');
 		return TRUE;
@@ -987,7 +1015,7 @@
 	** + Configure RTA on host A. We now have the same RTA configured
 	**   with different ports on two different hosts.
 	*/
-	rio_dprint(RIO_DEBUG_BOOT, ("Have we seen RTA %x before?\n", RtaUniq ));
+	rio_dprintk (RIO_DEBUG_BOOT, "Have we seen RTA %x before?\n", RtaUniq );
 	found = 0;
 	Flag = 0; /* Convince the compiler this variable is initialized */
 	for ( host = 0; !found && (host < p->RIONumHosts); host++ )
@@ -1003,12 +1031,12 @@
 		    if (RtaType == TYPE_RTA16)
 		    {
 			MapP2 = &p->RIOHosts[host].Mapping[MapP->ID2 - 1];
-			rio_dprint(RIO_DEBUG_BOOT, ("This RTA is units %d+%d from host %s\n",
-			 rta+1, MapP->ID2, p->RIOHosts[host].Name ));
+			rio_dprintk (RIO_DEBUG_BOOT, "This RTA is units %d+%d from host %s\n",
+			 rta+1, MapP->ID2, p->RIOHosts[host].Name);
 		    }
 		    else
-			rio_dprint(RIO_DEBUG_BOOT, ("This RTA is unit %d from host %s\n",
-			 rta+1, p->RIOHosts[host].Name ));
+			rio_dprintk (RIO_DEBUG_BOOT, "This RTA is unit %d from host %s\n",
+			 rta+1, p->RIOHosts[host].Name);
 		    found = 1;
 		    break;
 		}
@@ -1026,12 +1054,12 @@
 	*/
 	if ( !MapP )
 	{
-	    rio_dprint(RIO_DEBUG_BOOT, ("Look for RTA %x in RIOSavedTable\n",RtaUniq));
+	    rio_dprintk (RIO_DEBUG_BOOT, "Look for RTA %x in RIOSavedTable\n",RtaUniq);
 	    for ( rta=0; rta < TOTAL_MAP_ENTRIES; rta++ )
 	    {
-		rio_dprint(RIO_DEBUG_BOOT, ("Check table entry %d (%x)",
+		rio_dprintk (RIO_DEBUG_BOOT, "Check table entry %d (%x)",
 		      rta,
-		      p->RIOSavedTable[rta].RtaUniqueNum ));
+		      p->RIOSavedTable[rta].RtaUniqueNum);
 
 		if ( (p->RIOSavedTable[rta].Flags & SLOT_IN_USE) &&
 		 (p->RIOSavedTable[rta].RtaUniqueNum == RtaUniq) )
@@ -1047,11 +1075,11 @@
                                 break;
                         }
                         MapP2 = &p->RIOSavedTable[entry2];
-                        rio_dprint(RIO_DEBUG_BOOT, ("This RTA is from table entries %d+%d\n",
-                              rta, entry2));
+                        rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entries %d+%d\n",
+                              rta, entry2);
 		    }
 		    else
-			rio_dprint(RIO_DEBUG_BOOT, ("This RTA is from table entry %d\n", rta));
+			rio_dprintk (RIO_DEBUG_BOOT, "This RTA is from table entry %d\n", rta);
 		    break;
 		}
 	    }
@@ -1107,8 +1135,8 @@
 	    {
 		if (Flag & SLOT_IN_USE)
 		{
-		    rio_dprint(RIO_DEBUG_BOOT, (
-    "This RTA configured on another host - move entry to current host (1)\n"));
+		    rio_dprintk (RIO_DEBUG_BOOT, 
+    "This RTA configured on another host - move entry to current host (1)\n");
 		    HostP->Mapping[entry].SysPort = MapP->SysPort;
 		    CCOPY( MapP->Name, HostP->Mapping[entry].Name, MAX_NAME_LEN );
 		    HostP->Mapping[entry].Flags =
@@ -1121,12 +1149,12 @@
 			p->RIOFirstPortsBooted = HostP->Mapping[entry].SysPort;
 		    if ( HostP->Mapping[entry].SysPort > p->RIOLastPortsBooted )
 			p->RIOLastPortsBooted = HostP->Mapping[entry].SysPort;
-		    rio_dprint(RIO_DEBUG_BOOT, ("SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name));
+		    rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",(int)MapP->SysPort,MapP->Name);
 		}
 		else
 		{
-		    rio_dprint(RIO_DEBUG_BOOT, (
-   "This RTA has a tentative entry on another host - delete that entry (1)\n"));
+		    rio_dprintk (RIO_DEBUG_BOOT, 
+   "This RTA has a tentative entry on another host - delete that entry (1)\n");
 		    HostP->Mapping[entry].Flags =
 		     SLOT_TENTATIVE | RTA_BOOTED | RTA_NEWBOOT;
 #if NEED_TO_FIX
@@ -1151,9 +1179,9 @@
 			 p->RIOFirstPortsBooted = HostP->Mapping[entry2].SysPort;
 		       if (HostP->Mapping[entry2].SysPort > p->RIOLastPortsBooted)
 			 p->RIOLastPortsBooted = HostP->Mapping[entry2].SysPort;
-			rio_dprint(RIO_DEBUG_BOOT, ("SysPort %d, Name %s\n",
+			rio_dprintk (RIO_DEBUG_BOOT, "SysPort %d, Name %s\n",
 			       (int)HostP->Mapping[entry2].SysPort,
-			       HostP->Mapping[entry].Name));
+			       HostP->Mapping[entry].Name);
 		    }
 		    else
 			HostP->Mapping[entry2].Flags = SLOT_TENTATIVE |
@@ -1246,7 +1274,7 @@
 {
 	int		link;
 
-	rio_dprint(RIO_DEBUG_BOOT, ("FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq));
+	rio_dprintk (RIO_DEBUG_BOOT, "FillSlot(%d, %d, 0x%x...)\n", entry, entry2, RtaUniq);
 
 	HostP->Mapping[entry].Flags = (RTA_BOOTED | RTA_NEWBOOT | SLOT_TENTATIVE);
 	HostP->Mapping[entry].SysPort = NO_PORT;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/riocmd.c linux.17p18/drivers/char/rio/riocmd.c
--- linux.vanilla/drivers/char/rio/riocmd.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/riocmd.c	Wed Aug  9 22:24:45 2000
@@ -35,7 +35,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -43,8 +42,6 @@
 #include <asm/system.h>
 #include <asm/string.h>
 #include <asm/semaphore.h>
-#include <asm/spinlock.h>
-
 
 #include <linux/termios.h>
 #include <linux/serial.h>
@@ -94,12 +91,12 @@
 {
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA\n");
 
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -114,7 +111,7 @@
 	CmdBlkP->Packet.data[3]   = (IFOAD_MAGIC >> 8) & 0xFF;
 
 	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("FOAD RTA: Failed to queue foad command\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "FOAD RTA: Failed to queue foad command\n");
 		return EIO;
 	}
 	return 0;
@@ -127,12 +124,12 @@
 {
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA\n");
 
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -147,7 +144,7 @@
 	CmdBlkP->Packet.data[3]   = (ZOMBIE_MAGIC >> 8) & 0xFF;
 
 	if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("ZOMBIE RTA: Failed to queue zombie command\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "ZOMBIE RTA: Failed to queue zombie command\n");
 		return EIO;
 	}
 	return 0;
@@ -161,7 +158,7 @@
 {
 	uint Host;
 
-	rio_dprint(RIO_DEBUG_CMD, ("Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func ));
+	rio_dprintk (RIO_DEBUG_CMD, "Command RTA 0x%x func 0x%x\n", RtaUnique, (int)func);
 
 	if ( !RtaUnique )
 		return(0);
@@ -206,7 +203,7 @@
 	uint Host;
 
 	if ( copyin( (int)arg, (caddr_t)&IdRta, sizeof(IdRta) ) == COPYFAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("RIO_IDENTIFY_RTA copy failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "RIO_IDENTIFY_RTA copy failed\n");
 		p->RIOError.Error = COPYIN_FAILED;
 		return EFAULT;
 	}
@@ -234,12 +231,12 @@
 						*/
 						struct CmdBlk *CmdBlkP;
 
-						rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA\n"));
+						rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA\n");
 
 						CmdBlkP = RIOGetCmdBlk();
 
 						if ( !CmdBlkP ) {
-							rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA: GetCmdBlk failed\n"));
+							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: GetCmdBlk failed\n");
 							return ENXIO;
 						}
 		
@@ -252,9 +249,8 @@
 						CmdBlkP->Packet.data[1]   = 0;
 						CmdBlkP->Packet.data[2]   = IdRta.ID;
 		
-						if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) 
-										== RIO_FAIL ) {
-							rio_dprint(RIO_DEBUG_CMD, ("IDENTIFY RTA: Failed to queue command\n"));
+						if ( RIOQueueCmdBlk( HostP, MapP->ID-1, CmdBlkP) == RIO_FAIL ) {
+							rio_dprintk (RIO_DEBUG_CMD, "IDENTIFY RTA: Failed to queue command\n");
 							return EIO;
 						}
 						return 0;
@@ -277,11 +273,10 @@
 	struct Host *HostP;
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("KILL HOST NEIGHBOUR\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "KILL HOST NEIGHBOUR\n");
 
-	if ( copyin( (int)arg, (caddr_t)&KillUnit, 
-					sizeof(KillUnit) ) == COPYFAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("RIO_KILL_NEIGHBOUR copy failed\n"));
+	if ( copyin( (int)arg, (caddr_t)&KillUnit, sizeof(KillUnit) ) == COPYFAIL ) {
+		rio_dprintk (RIO_DEBUG_CMD, "RIO_KILL_NEIGHBOUR copy failed\n");
 		p->RIOError.Error = COPYIN_FAILED;
 		return EFAULT;
 	}
@@ -292,7 +287,7 @@
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("UFOAD: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "UFOAD: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -313,7 +308,7 @@
 		if ( HostP->UniqueNum == KillUnit.UniqueNum ) {
 			if ( RIOQueueCmdBlk( HostP, RTAS_PER_HOST+KillUnit.Link,
 							CmdBlkP) == RIO_FAIL ) {
-				rio_dprint(RIO_DEBUG_CMD, ("UFOAD: Failed queue command\n"));
+				rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
 				return EIO;
 			}
 			return 0;
@@ -323,7 +318,7 @@
 			if ( HostP->Mapping[ID].RtaUniqueNum == KillUnit.UniqueNum ) {
 				CmdBlkP->Packet.dest_unit = ID+1;
 				if ( RIOQueueCmdBlk( HostP, ID, CmdBlkP) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_CMD, ("UFOAD: Failed queue command\n"));
+					rio_dprintk (RIO_DEBUG_CMD, "UFOAD: Failed queue command\n");
 					return EIO;
 				}
 				return 0;
@@ -342,12 +337,12 @@
 {
 	struct CmdBlk *CmdBlkP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link));
+	rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA ID %d, link %c\n", ID, 'A' + Link);
 
 	CmdBlkP = RIOGetCmdBlk();
 
 	if ( !CmdBlkP ) {
-		rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA: GetCmdBlk failed\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: GetCmdBlk failed\n");
 		return ENXIO;
 	}
 
@@ -362,7 +357,7 @@
 	CmdBlkP->Packet.data[3]   = (IWAIT_MAGIC >> 8) & 0xFF;
 
 	if ( RIOQueueCmdBlk( HostP, ID - 1, CmdBlkP) == RIO_FAIL ) {
-		rio_dprint(RIO_DEBUG_CMD, ("SUSPEND BOOT ON RTA: Failed to queue iwait command\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "SUSPEND BOOT ON RTA: Failed to queue iwait command\n");
 		return EIO;
 	}
 	return 0;
@@ -419,6 +414,7 @@
 	ushort subCommand;
 	unsigned long flags;
 
+	func_enter ();
 
 #ifdef CHECK
 	CheckHost( Host );
@@ -438,34 +434,35 @@
 	UnixRupP = &HostP->UnixRups[rup];
 	SysPort = UnixRupP->BaseSysPort + 
 			(RBYTE(PktCmdP->PhbNum) % (ushort)PORTS_PER_RTA);
-	rio_dprint(RIO_DEBUG_CMD, ("Command on rup %d, port %d\n", rup, SysPort));
+	rio_dprintk (RIO_DEBUG_CMD, "Command on rup %d, port %d\n", rup, SysPort);
 
 #ifdef CHECK
 	CheckRup( rup );
 	CheckUnixRupP( UnixRupP );
 #endif
 	if ( UnixRupP->BaseSysPort == NO_PORT ) {
-		rio_dprint(RIO_DEBUG_CMD, ("OBSCURE ERROR!\n"));
-		rio_dprint(RIO_DEBUG_CMD, ("Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n"));
-		rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: Host number %d, name ``%s''\n", 
-					HostP-p->RIOHosts, HostP->Name ));
-		rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: Rup number  0x%x\n", rup));
-
-		if ( Rup >= (ushort)MAX_RUP )
-			rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: This is the RUP for RTA ``%s''\n",
-						HostP->Mapping[Rup].Name ));
-		else
-			rio_dprint(RIO_DEBUG_CMD, ("CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 'A' + Rup - MAX_RUP, HostP->Name ));
-
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Destination 0x%x:0x%x\n",
-					PacketP->dest_unit, PacketP->dest_port ));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Source	  0x%x:0x%x\n",
-					PacketP->src_unit, PacketP->src_port ));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len ));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control));
-		rio_dprint(RIO_DEBUG_CMD, ("PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum ));
-		rio_dprint(RIO_DEBUG_CMD, ("COMMAND information: Host Port Number 0x%x, 
-					Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command ));
+		rio_dprintk (RIO_DEBUG_CMD, "OBSCURE ERROR!\n");
+		rio_dprintk (RIO_DEBUG_CMD, "Diagnostics follow. Please WRITE THESE DOWN and report them to Specialix Technical Support\n");
+		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Host number %d, name ``%s''\n", 
+			     HostP-p->RIOHosts, HostP->Name );
+		rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: Rup number  0x%x\n", rup);
+
+		if ( Rup >= (ushort)MAX_RUP ) {
+			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for RTA ``%s''\n",
+				     HostP->Mapping[Rup].Name);
+		} else
+			rio_dprintk (RIO_DEBUG_CMD, "CONTROL information: This is the RUP for link ``%c'' of host ``%s''\n", 
+				     ('A' + Rup - MAX_RUP), HostP->Name);
+
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Destination 0x%x:0x%x\n",
+			     PacketP->dest_unit, PacketP->dest_port );
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Source	  0x%x:0x%x\n",
+			     PacketP->src_unit, PacketP->src_port );
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Length	  0x%x (%d)\n", PacketP->len,PacketP->len );
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Control	 0x%x (%d)\n", PacketP->control, PacketP->control);
+		rio_dprintk (RIO_DEBUG_CMD, "PACKET information: Check	   0x%x (%d)\n", PacketP->csum, PacketP->csum );
+		rio_dprintk (RIO_DEBUG_CMD, "COMMAND information: Host Port Number 0x%x, 
+					Command Code 0x%x\n", PktCmdP->PhbNum, PktCmdP->Command );
 		return TRUE;
 	}
 
@@ -473,13 +470,10 @@
 	CheckSysPort( SysPort );
 #endif
 	PortP = p->RIOPortp[ SysPort ];
-#if 0
-	ttyP = PortP->TtyP;
-#endif
 	rio_spin_lock_irqsave(&PortP->portSem, flags);
 	switch( RBYTE(PktCmdP->Command) ) {
 		case BREAK_RECEIVED:
-			rio_dprint(RIO_DEBUG_CMD, ("Received a break!\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Received a break!\n");
 			/* If the current line disc. is not multi-threading and
 	   			the current processor is not the default, reset rup_intr
 	   			and return FALSE to ensure that the command packet is
@@ -489,16 +483,16 @@
 			break;
 
 		case COMPLETE:
-			rio_dprint(RIO_DEBUG_CMD, ("Command complete on phb %d host %d\n",
-							RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts));
+		rio_dprintk (RIO_DEBUG_CMD, "Command complete on phb %d host %d\n",
+			     RBYTE(PktCmdP->PhbNum), HostP-p->RIOHosts);
 			subCommand = 1;
 			switch (RBYTE(PktCmdP->SubCommand)) {
 				case MEMDUMP :
-					rio_dprint(RIO_DEBUG_CMD, ("Memory dump cmd (0x%x) from addr 0x%x\n",
-		 				RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr)));
+			rio_dprintk (RIO_DEBUG_CMD, "Memory dump cmd (0x%x) from addr 0x%x\n",
+				     RBYTE(PktCmdP->SubCommand), RWORD(PktCmdP->SubAddr));
 					break;
 				case READ_REGISTER :
-					rio_dprint(RIO_DEBUG_CMD, ("Read register (0x%x)\n", RWORD(PktCmdP->SubAddr)));
+			rio_dprintk (RIO_DEBUG_CMD, "Read register (0x%x)\n", RWORD(PktCmdP->SubAddr));
 					p->CdRegister = (RBYTE(PktCmdP->ModemStatus) & MSVR1_HOST);
 					break;
 				default :
@@ -507,18 +501,16 @@
 			}
 			if (subCommand)
 				break;
-			rio_dprint(RIO_DEBUG_CMD, ("New status is 0x%x was 0x%x\n",
-					 RBYTE(PktCmdP->PortStatus),PortP->PortState));
+			rio_dprintk (RIO_DEBUG_CMD, "New status is 0x%x was 0x%x\n",
+				     RBYTE(PktCmdP->PortStatus),PortP->PortState);
 			if (PortP->PortState != RBYTE(PktCmdP->PortStatus)) {
-				rio_dprint(RIO_DEBUG_CMD, ("Mark status & wakeup\n"));
+				rio_dprintk (RIO_DEBUG_CMD, "Mark status & wakeup\n");
 				PortP->PortState = RBYTE(PktCmdP->PortStatus);
 				/* What should we do here ...
 				wakeup( &PortP->PortState );
 				*/
-			}
-			else {
-				rio_dprint(RIO_DEBUG_CMD, ("No change\n"));
-			}
+		} else 
+			rio_dprintk (RIO_DEBUG_CMD, "No change\n");
 
 			/* FALLTHROUGH */
 		case MODEM_STATUS:
@@ -530,7 +522,7 @@
 			ReportedModemStatus = RBYTE(PktCmdP->ModemStatus);
 			if ((PortP->ModemState & MSVR1_HOST) ==
 					(ReportedModemStatus & MSVR1_HOST)) {
-				rio_dprint(RIO_DEBUG_CMD, ("Modem status unchanged 0x%x\n", PortP->ModemState));
+				rio_dprintk (RIO_DEBUG_CMD, "Modem status unchanged 0x%x\n", PortP->ModemState);
 				/*
 				** Update ModemState just in case tbusy or tstop states have
 				** changed.
@@ -538,8 +530,8 @@
 				PortP->ModemState = ReportedModemStatus;
 			}
 			else {
-				rio_dprint(RIO_DEBUG_CMD, ("Modem status change from 0x%x to 0x%x\n",
-							 PortP->ModemState, ReportedModemStatus));
+				rio_dprintk (RIO_DEBUG_CMD, "Modem status change from 0x%x to 0x%x\n",
+				     PortP->ModemState, ReportedModemStatus);
 				PortP->ModemState = ReportedModemStatus;
 #ifdef MODEM_SUPPORT
 				if ( PortP->Mapped ) {
@@ -554,50 +546,41 @@
 				** If the device is a modem, then check the modem
 				** carrier.
 				*/
-				if(!(ttyP->t_cflag & CLOCAL) && 
-					((PortP->State & (RIO_MOPEN|RIO_WOPEN))))
-				{
+				if (PortP->gs.tty == NULL)
+					break;
+			  
+				if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) &&
+				((PortP->State & (RIO_MOPEN|RIO_WOPEN)))) {
+
+					rio_dprintk (RIO_DEBUG_CMD, "Is there a Carrier?\n");
 			/*
 			** Is there a carrier?
 			*/
-			if ( PortP->ModemState & MSVR1_CD )
-			{
+					if ( PortP->ModemState & MSVR1_CD ) {
 			/*
 			** Has carrier just appeared?
 			*/
-			if (!(ttyP->t_state & CARR_ON))
-			{
-				rio_dprint(RIO_DEBUG_CMD, PortP,DBG_MODEM,"Carrier just came up.\n");
-				ttyP->t_state |=CARR_ON;
+						if (!(PortP->State & RIO_CARR_ON)) {
+							rio_dprintk (RIO_DEBUG_CMD, "Carrier just came up.\n");
+							PortP->State |= RIO_CARR_ON;
 				/*
 				** wakeup anyone in WOPEN
 				*/
-				if ( ttyP->t_state & (ISOPEN|WOPEN) )
-				wakeup((caddr_t)&ttyP->t_canq);
+							if (PortP->State & (PORT_ISOPEN | RIO_WOPEN) )
+								wake_up_interruptible (&PortP->gs.open_wait);
 #ifdef STATS
 				PortP->Stat.ModemOnCnt++;
 #endif
 			}
-			}
-			else
-			{
+					} else {
 			/*
 			** Has carrier just dropped?
 			*/
-			if (ttyP->t_state & CARR_ON)
-			{
-				/*
-				** send SIGHUP to the process group
-				*/
-				if ( ttyP->t_state & (ISOPEN|WOPEN) )
-				{
-				signal(ttyP->t_pgrp,SIGHUP);
-				ttyflush(ttyP,(FREAD|FWRITE));
-				}
-				ttyP->t_state &= ~CARR_ON;
-				wakeup( (caddr_t)&PortP->TxBufferOut );
-				wakeup( (caddr_t)&PortP->TxBufferIn );
-				rio_dprint(RIO_DEBUG_CMD, PortP,DBG_MODEM,"Carrier just went down.\n");
+						if (PortP->State & RIO_CARR_ON) {
+							if (PortP->State & (PORT_ISOPEN|RIO_WOPEN|RIO_MOPEN))
+								tty_hangup (PortP->gs.tty);
+							PortP->State &= ~RIO_CARR_ON;
+							rio_dprintk (RIO_DEBUG_CMD, "Carrirer just went down\n");
 #ifdef STATS
 				PortP->Stat.ModemOffCnt++;
 #endif
@@ -610,11 +593,14 @@
 			break;
 
 		default:
-			rio_dprint(RIO_DEBUG_CMD, ("Unknown command %d on CMD_RUP of host %d\n",
-				RBYTE(PktCmdP->Command),HostP-p->RIOHosts));
+			rio_dprintk (RIO_DEBUG_CMD, "Unknown command %d on CMD_RUP of host %d\n",
+			     RBYTE(PktCmdP->Command),HostP-p->RIOHosts);
 			break;
 	}
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+
+	func_exit ();
+
 	return TRUE;
 }
 /*
@@ -670,11 +656,8 @@
 	CheckRup( Rup );
 	CheckCmdBlkP( CmdBlkP );
 #endif
-
-	rio_dprint(RIO_DEBUG_CMD, ("RIOQueueCmdBlk(Host, Rup %d, 0x%x)\n", Rup, (int)CmdBlkP ));
-
 	if ( Rup >= (ushort)(MAX_RUP+LINKS_PER_UNIT) ) {
-		rio_dprint(RIO_DEBUG_CMD, ("Illegal rup number %d in RIOQueueCmdBlk\n",Rup));
+		rio_dprintk (RIO_DEBUG_CMD, "Illegal rup number %d in RIOQueueCmdBlk\n",Rup);
 		RIOFreeCmdBlk( CmdBlkP );
 		return RIO_FAIL;
 	}
@@ -688,11 +671,12 @@
 	** straight on the RUP....
 	*/
 	if ( (UnixRupP->CmdsWaitingP == NULL) && (UnixRupP->CmdPendingP == NULL) && 
-		(RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) &&
+	     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE ) &&
 		(CmdBlkP->PreFuncP ? (*CmdBlkP->PreFuncP)(CmdBlkP->PreArg,CmdBlkP)
 							:TRUE)) {
-		rio_dprint(RIO_DEBUG_CMD, ("RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
-					CmdBlkP->Packet.data[0]));
+		rio_dprintk (RIO_DEBUG_CMD, "RUP inactive-placing command straight on. Cmd byte is 0x%x\n",
+					     CmdBlkP->Packet.data[0]);
+                                            
 
 		/*
 		** Whammy! blat that pack!
@@ -714,28 +698,27 @@
 
 		return RIO_SUCCESS;
 	}
-
-	rio_dprint(RIO_DEBUG_CMD, ("RUP active - en-queing\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "RUP active - en-queing\n");
 
 	if ( UnixRupP->CmdsWaitingP != NULL)
-		rio_dprint(RIO_DEBUG_CMD, ("Rup active - command waiting\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command waiting\n");
 	if ( UnixRupP->CmdPendingP != NULL )
-		rio_dprint(RIO_DEBUG_CMD, ("Rup active - command pending\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command pending\n");
 	if ( RWORD(UnixRupP->RupP->txcontrol) != TX_RUP_INACTIVE )
-		rio_dprint(RIO_DEBUG_CMD, ("Rup active - command rup not ready\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Rup active - command rup not ready\n");
 
 	Base = &UnixRupP->CmdsWaitingP;
 
-	rio_dprint(RIO_DEBUG_CMD, ("First try to queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base));
+	rio_dprintk (RIO_DEBUG_CMD, "First try to queue cmdblk 0x%x at 0x%x\n", (int)CmdBlkP,(int)Base);
 
 	while ( *Base ) {
-		rio_dprint(RIO_DEBUG_CMD, ("Command cmdblk 0x%x here\n",(int)(*Base)));
+		rio_dprintk (RIO_DEBUG_CMD, "Command cmdblk 0x%x here\n", (int)(*Base));
 		Base = &((*Base)->NextP);
-		rio_dprint(RIO_DEBUG_CMD, ("Now try to queue cmd cmdblk 0x%x at 0x%x\n",
-		       (int)CmdBlkP,(int)Base));
+		rio_dprintk (RIO_DEBUG_CMD, "Now try to queue cmd cmdblk 0x%x at 0x%x\n",
+					     (int)CmdBlkP,(int)Base);
 	}
 
-	rio_dprint(RIO_DEBUG_CMD, ("Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base));
+	rio_dprintk (RIO_DEBUG_CMD, "Will queue cmdblk 0x%x at 0x%x\n",(int)CmdBlkP,(int)Base);
 
 	*Base = CmdBlkP;
 
@@ -778,17 +761,15 @@
 		if ( RWORD(UnixRupP->RupP->rxcontrol) != RX_RUP_INACTIVE ) {
 			int FreeMe;
 
-			/* rio_dprint(RIO_DEBUG_CMD, ("RIORupCmd( %d, %d )\n", HostP-p->RIOHosts, Rup )); */
-
 			PacketP =(PKT *)RIO_PTR(HostP->Caddr,RWORD(UnixRupP->RupP->rxpkt));
 
 			ShowPacket( DBG_CMD, PacketP );
 
 			switch ( RBYTE(PacketP->dest_port) ) {
 				case BOOT_RUP:
-					rio_dprint(RIO_DEBUG_CMD, ("Incoming Boot %s packet '%x'\n", 
+					rio_dprintk (RIO_DEBUG_CMD, "Incoming Boot %s packet '%x'\n", 
 						RBYTE(PacketP->len) & 0x80 ? "Command":"Data", 
-						RBYTE(PacketP->data[0]) )); 
+							     RBYTE(PacketP->data[0])); 
 					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
 					FreeMe= RIOBootRup(p, Rup,HostP,PacketP);
 					rio_spin_lock_irqsave(&UnixRupP->RupLock, flags);
@@ -803,8 +784,8 @@
 					rio_spin_unlock_irqrestore(&UnixRupP->RupLock, flags);
 					FreeMe= RIOCommandRup(p, Rup,HostP,PacketP);
 					if (PacketP->data[5] == MEMDUMP) {
-						rio_dprint(RIO_DEBUG_CMD, ("Memdump from 0x%x complete\n",
-			 				*(ushort *) &(PacketP->data[6])));
+						rio_dprintk (RIO_DEBUG_CMD, "Memdump from 0x%x complete\n",
+								     *(ushort *) &(PacketP->data[6]));
 						HostP->Copy( (caddr_t)&(PacketP->data[8]), 
 								(caddr_t)p->RIOMemDump, 32 );
 					}
@@ -818,19 +799,19 @@
 					break;
 
 				default:
-					rio_dprint(RIO_DEBUG_CMD, ("Unknown RUP %d\n", RBYTE(PacketP->dest_port)));
+					rio_dprintk (RIO_DEBUG_CMD, "Unknown RUP %d\n", RBYTE(PacketP->dest_port));
 					FreeMe = 1;
 					break;
 			}
 
 			if ( FreeMe ) {
-				rio_dprint(RIO_DEBUG_CMD, ("Free processed incoming command packet\n"));
+				rio_dprintk (RIO_DEBUG_CMD, "Free processed incoming command packet\n");
 				put_free_end(HostP,PacketP);
 
 				WWORD(UnixRupP->RupP->rxcontrol , RX_RUP_INACTIVE);
 
 				if ( RWORD(UnixRupP->RupP->handshake)==PHB_HANDSHAKE_SET ) {
-					rio_dprint(RIO_DEBUG_CMD, ("Handshake rup %d\n",Rup));
+					rio_dprintk (RIO_DEBUG_CMD, "Handshake rup %d\n",Rup);
 					WWORD(UnixRupP->RupP->handshake,
 						PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
 				}
@@ -842,7 +823,7 @@
 		** and it has completed, then tidy it up.
 		*/
 		if ( (CmdBlkP = UnixRupP->CmdPendingP) && /* ASSIGN! */
-			(RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) ) {
+		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
 			/*
 			** we are idle.
 			** there is a command in pending.
@@ -851,11 +832,11 @@
 			** what happened).
 			*/
 			if ( CmdBlkP->Packet.dest_port == BOOT_RUP )
-				rio_dprint(RIO_DEBUG_CMD, ("Free Boot %s Command Block '%x'\n", 
+				rio_dprintk (RIO_DEBUG_CMD, "Free Boot %s Command Block '%x'\n", 
 						CmdBlkP->Packet.len & 0x80 ? "Command":"Data", 
-							CmdBlkP->Packet.data[0] ));
+							     CmdBlkP->Packet.data[0]);
 
-			rio_dprint(RIO_DEBUG_CMD, ("Command 0x%x completed\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CMD, "Command 0x%x completed\n",(int)CmdBlkP);
 
 			/*
 			** Clear the Rup lock to prevent mutual exclusion.
@@ -883,27 +864,27 @@
 		*/
 		if ( (CmdBlkP = UnixRupP->CmdsWaitingP) && /* ASSIGN! */
 			(UnixRupP->CmdPendingP == NULL) &&
-				(RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE) ) {
+		     (RWORD(UnixRupP->RupP->txcontrol) == TX_RUP_INACTIVE)) {
 			/*
 			** if the pre-function is non-zero, call it.
 			** If it returns RIO_FAIL then don't
 			** send this command yet!
 			*/
 #ifdef CHECK
-CheckCmdBlkP( CmdBlkP );
+			CheckCmdBlkP (CmdBlkP);
 #endif
 			if ( !(CmdBlkP->PreFuncP ?
 				(*CmdBlkP->PreFuncP)(CmdBlkP->PreArg, CmdBlkP) : TRUE)) {
-				rio_dprint(RIO_DEBUG_CMD, ("Not ready to start command 0x%x\n",(int)CmdBlkP));
+				rio_dprintk (RIO_DEBUG_CMD, "Not ready to start command 0x%x\n",(int)CmdBlkP);
 			}
 			else {
-				rio_dprint(RIO_DEBUG_CMD, ("Start new command 0x%x Cmd byte is 0x%x\n",
-						(int)CmdBlkP, CmdBlkP->Packet.data[0]));
+				rio_dprintk (RIO_DEBUG_CMD, "Start new command 0x%x Cmd byte is 0x%x\n",
+							     (int)CmdBlkP, CmdBlkP->Packet.data[0]);
 				/*
 				** Whammy! blat that pack!
 				*/
 #ifdef CHECK
-CheckPacketP( (PKT *)RIO_PTR(HostP->Caddr,UnixRupP->RupP->txpkt) );
+				CheckPacketP ((PKT *)RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt));
 #endif
 				HostP->Copy( (caddr_t)&CmdBlkP->Packet, 
 					RIO_PTR(HostP->Caddr, UnixRupP->RupP->txpkt), sizeof(PKT));
@@ -1029,7 +1010,7 @@
 		** MAGIC! (Basically, handshake the RX buffer, so that
 		** the RTAs upstream can be re-enabled.)
 		*/
-		rio_dprint(RIO_DEBUG_CMD, ("Util: Set RX handshake bit\n"));
+		rio_dprintk (RIO_DEBUG_CMD, "Util: Set RX handshake bit\n");
 		WWORD(PortP->PhbP->handshake, PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET);
 	}
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -1049,7 +1030,7 @@
 #ifdef CHECK
 	CheckPortP( PortP );
 #endif
-	rio_dprint(RIO_DEBUG_CMD, ("Decrement in use count for port\n"));
+	rio_dprintk (RIO_DEBUG_CMD, "Decrement in use count for port\n");
 
 	if (PortP->InUse) {
 		if ( --PortP->InUse != NOT_INUSE ) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rioctrl.c linux.17p18/drivers/char/rio/rioctrl.c
--- linux.vanilla/drivers/char/rio/rioctrl.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/rioctrl.c	Wed Aug  9 22:24:45 2000
@@ -35,7 +35,6 @@
 
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -138,7 +137,7 @@
 {
   int rv;
 
-  rio_dprint (RIO_DEBUG_CTRL, ("Copying %d bytes from user %p to %p.\n", siz, (void *) arg, dp));
+  rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes from user %p to %p.\n", siz, (void *)arg, dp);
   rv = copy_from_user (dp, (void *)arg, siz);
   if (rv < 0) return COPYFAIL;
   else return rv;
@@ -149,7 +148,7 @@
 {
   int rv;
 
-  rio_dprint (RIO_DEBUG_CTRL, ("Copying %d bytes to user %p from %p.\n", siz, (void *) arg, dp));
+  rio_dprintk (RIO_DEBUG_CTRL, "Copying %d bytes to user %p from %p.\n", siz, (void *)arg, dp);
   rv = copy_to_user ((void *)arg, dp, siz);
   if (rv < 0) return COPYFAIL;
   else return rv;
@@ -202,11 +201,13 @@
 	int		retval = 0;
 	unsigned long flags;
 	
+	func_enter ();
+	
 	/* Confuse teh compiler to think that we've initialized these */
 	Host=0;
 	PortP = NULL;
 
-	rio_dprint(RIO_DEBUG_CTRL, ("control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg));
+	rio_dprintk (RIO_DEBUG_CTRL, "control ioctl cmd: 0x%x arg: 0x%x\n", cmd, (int)arg);
 
 	switch (cmd) {
 		/*
@@ -217,7 +218,7 @@
 		** otherwise just the specified host card will be changed.
 		*/
 		case RIO_SET_TIMER:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_TIMER to %dms\n", (uint)arg));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_TIMER to %dms\n", (uint)arg);
 			{
 				int host, value;
 				host = (uint)arg >> 16;
@@ -295,42 +296,42 @@
 			*/
 
 		case RIO_FOAD_RTA:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_FOAD_RTA\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_FOAD_RTA\n");
 			return RIOCommandRta(p, (uint)arg, RIOFoadRta);
 
 		case RIO_ZOMBIE_RTA:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_ZOMBIE_RTA\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_ZOMBIE_RTA\n");
 			return RIOCommandRta(p, (uint)arg, RIOZombieRta);
 
 		case RIO_IDENTIFY_RTA:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_IDENTIFY_RTA\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_IDENTIFY_RTA\n");
 			return RIOIdentifyRta(p, arg);
 
 		case RIO_KILL_NEIGHBOUR:
-			rio_dprint(RIO_DEBUG_CTRL, ("RIO_KILL_NEIGHBOUR\n"));
+			rio_dprintk (RIO_DEBUG_CTRL, "RIO_KILL_NEIGHBOUR\n");
 			return RIOKillNeighbour(p, arg);
 
 		case SPECIAL_RUP_CMD:
 			{
 				struct CmdBlk *CmdBlkP;
 
-				rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD\n");
 				if (copyin((int)arg, (caddr_t)&SpecialRupCmd, 
 							sizeof(SpecialRupCmd)) == COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD copy failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD copy failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
 				CmdBlkP = RIOGetCmdBlk();
 				if ( !CmdBlkP ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("SPECIAL_RUP_CMD GetCmdBlk failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "SPECIAL_RUP_CMD GetCmdBlk failed\n");
 					return ENXIO;
 				}
 				CmdBlkP->Packet = SpecialRupCmd.Packet;
 				if ( SpecialRupCmd.Host >= p->RIONumHosts )
 					SpecialRupCmd.Host = 0;
-					rio_dprint(RIO_DEBUG_CTRL, ("Queue special rup command for host %d rup %d\n",
-						SpecialRupCmd.Host, SpecialRupCmd.RupNum));
+					rio_dprintk (RIO_DEBUG_CTRL, "Queue special rup command for host %d rup %d\n",
+						SpecialRupCmd.Host, SpecialRupCmd.RupNum);
 					if (RIOQueueCmdBlk(&p->RIOHosts[SpecialRupCmd.Host], 
 							SpecialRupCmd.RupNum, CmdBlkP) == RIO_FAIL) {
 						cprintf("FAILED TO QUEUE SPECIAL RUP COMMAND\n");
@@ -347,7 +348,7 @@
 					return EPERM;
 
 			case RIO_ALL_MODEM:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_ALL_MODEM\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_ALL_MODEM\n");
 				p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
 				return EINVAL;
 
@@ -355,44 +356,44 @@
 				/*
 				** Read the routing table from the device driver to user space
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_TABLE\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE\n");
 
 				if ((retval = RIOApel(p)) != 0)
 		 			return retval;
 
 				if (copyout((caddr_t)p->RIOConnectTable, (int)arg,
 						TOTAL_MAP_ENTRIES*sizeof(struct Map)) == COPYFAIL) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_TABLE copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_TABLE copy failed\n");
 		 			p->RIOError.Error = COPYOUT_FAILED;
 		 			return EFAULT;
 				}
 
 				{
 					int entry;
-					rio_dprint(RIO_DEBUG_CTRL,  ("*****\nMAP ENTRIES\n") );
+					rio_dprintk (RIO_DEBUG_CTRL,  "*****\nMAP ENTRIES\n");
 					for ( entry=0; entry<TOTAL_MAP_ENTRIES; entry++ )
 					{
 					  if ((p->RIOConnectTable[entry].ID == 0) &&
 					      (p->RIOConnectTable[entry].HostUniqueNum == 0) &&
 					      (p->RIOConnectTable[entry].RtaUniqueNum == 0)) continue;
 					      
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link ) );
-						rio_dprint(RIO_DEBUG_CTRL,  ("Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name ) );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.HostUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].HostUniqueNum );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.RtaUniqueNum = 0x%x\n", entry, p->RIOConnectTable[entry].RtaUniqueNum );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID = 0x%x\n", entry, p->RIOConnectTable[entry].ID );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.ID2 = 0x%x\n", entry, p->RIOConnectTable[entry].ID2 );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Flags = 0x%x\n", entry, (int)p->RIOConnectTable[entry].Flags );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.SysPort = 0x%x\n", entry, (int)p->RIOConnectTable[entry].SysPort );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[0].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[0].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[1].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[1].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[2].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[2].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[3].Unit = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Unit );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Top[4].Link = %x\n", entry, p->RIOConnectTable[entry].Topology[3].Link );
+						rio_dprintk (RIO_DEBUG_CTRL, "Map entry %d.Name = %s\n", entry, p->RIOConnectTable[entry].Name );
 					}
-					rio_dprint(RIO_DEBUG_CTRL,  ("*****\nEND MAP ENTRIES\n") );
+					rio_dprintk (RIO_DEBUG_CTRL,  "*****\nEND MAP ENTRIES\n");
 				}
 				p->RIOQuickCheck = NOT_CHANGED;	/* a table has been gotten */
 				return 0;
@@ -401,16 +402,16 @@
 				/*
 				** Write the routing table to the device driver from user space
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE\n");
 
 				if ( !su ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if ( copyin((int)arg, (caddr_t)&p->RIOConnectTable[0], 
 					TOTAL_MAP_ENTRIES*sizeof(struct Map) ) == COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_TABLE copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_TABLE copy failed\n");
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
@@ -448,17 +449,17 @@
 				** Send bindings table, containing unique numbers of RTAs owned
 				** by this system to user space
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS\n");
 
 				if ( !su )
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if (copyout((caddr_t) p->RIOBindTab, (int)arg, 
 						(sizeof(ulong) * MAX_RTA_BINDINGS)) == COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_BINDINGS copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_BINDINGS copy failed\n");
 		 			p->RIOError.Error = COPYOUT_FAILED;
 		 			return EFAULT;
 				}
@@ -469,17 +470,17 @@
 			** Receive a bindings table, containing unique numbers of RTAs owned
 			** by this system
 			*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS\n");
 
 				if ( !su )
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&p->RIOBindTab[0], 
 						(sizeof(ulong) * MAX_RTA_BINDINGS))==COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_PUT_BINDINGS copy failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_PUT_BINDINGS copy failed\n");
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
@@ -492,10 +493,10 @@
 					** Bind this RTA to host, so that it will be booted by 
 					** host in 'boot owned RTAs' mode.
 					*/
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_BIND_RTA\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA\n");
 
 					if ( !su ) {
-		 				rio_dprint(RIO_DEBUG_CTRL, ("RIO_BIND_RTA !Root\n"));
+		 				rio_dprintk (RIO_DEBUG_CTRL, "RIO_BIND_RTA !Root\n");
 		 				p->RIOError.Error = NOT_SUPER_USER;
 		 				return EPERM;
 					}
@@ -507,8 +508,8 @@
 							** Already exists - delete
 							*/
 							p->RIOBindTab[Entry] = 0L;
-							rio_dprint(RIO_DEBUG_CTRL, ("Removing Rta %x from p->RIOBindTab\n",
-		 												(int) arg));
+							rio_dprintk (RIO_DEBUG_CTRL, "Removing Rta %x from p->RIOBindTab\n",
+		 												(int) arg);
 							return 0;
 		 				}
 					}
@@ -517,90 +518,90 @@
 					*/
 					if (EmptySlot != -1) {
 		 				p->RIOBindTab[EmptySlot] = (int) arg;
-		 				rio_dprint(RIO_DEBUG_CTRL, ("Adding Rta %x to p->RIOBindTab\n",
-		  					(int) arg));
+		 				rio_dprintk (RIO_DEBUG_CTRL, "Adding Rta %x to p->RIOBindTab\n",
+		  					(int) arg);
 					}
 					else {
-		 				rio_dprint(RIO_DEBUG_CTRL, ("p->RIOBindTab full! - Rta %x not added\n",
-		  					(int) arg));
+		 				rio_dprintk (RIO_DEBUG_CTRL, "p->RIOBindTab full! - Rta %x not added\n",
+		  					(int) arg);
 		 				return 1;
 					}
 					return 0;
 				}
 
 			case RIO_RESUME :
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME\n");
 				port = (uint) arg;
 				if ((port < 0) || (port > 511)) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Bad port number %d\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Bad port number %d\n", port);
 		 			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 		 			return EINVAL;
 				}
 				PortP = p->RIOPortp[port];
 				if (!PortP->Mapped) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d not mapped\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not mapped\n", port);
 		 			p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
 		 			return EINVAL;
 				}
 				if (!(PortP->State & (RIO_LOPEN | RIO_MOPEN))) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d not open\n", port));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d not open\n", port);
 		 			return EINVAL;
 				}
 
 				rio_spin_lock_irqsave(&PortP->portSem, flags);
 				if (RIOPreemptiveCmd(p, (p->RIOPortp[port]), RESUME) == 
 										RIO_FAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME failed\n");
 					rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 					return EBUSY;
 				}
 				else {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESUME: Port %d resumed\n", port));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESUME: Port %d resumed\n", port);
 					PortP->State |= RIO_BUSY;
 				}
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				return retval;
 
 			case RIO_ASSIGN_RTA:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_ASSIGN_RTA\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA\n");
 				if ( !su ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_ASSIGN_RTA !Root\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_ASSIGN_RTA !Root\n");
 					p->RIOError.Error = NOT_SUPER_USER;
 					return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
 									== COPYFAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("Copy from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 				return RIOAssignRta(p, &MapEnt);
 
 			case RIO_CHANGE_NAME:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_CHANGE_NAME\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME\n");
 				if ( !su ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_CHANGE_NAME !Root\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_CHANGE_NAME !Root\n");
 					p->RIOError.Error = NOT_SUPER_USER;
 					return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
 						== COPYFAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("Copy from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "Copy from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 				return RIOChangeName(p, &MapEnt);
 
 			case RIO_DELETE_RTA:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_DELETE_RTA\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA\n");
 				if ( !su ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_DELETE_RTA !Root\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_DELETE_RTA !Root\n");
 		 			p->RIOError.Error = NOT_SUPER_USER;
 		 			return EPERM;
 				}
 				if (copyin((int)arg, (caddr_t)&MapEnt, sizeof(MapEnt))
 							== COPYFAIL ) {
-		 			rio_dprint(RIO_DEBUG_CTRL, ("Copy from data space failed\n"));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "Copy from data space failed\n");
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
@@ -637,7 +638,7 @@
 				return 0;
 
 			case RIO_GET_LOG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_LOG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_LOG\n");
 #ifdef LOGGING
 				RIOGetLog(arg);
 				return 0;
@@ -652,17 +653,17 @@
 		 			p->RIOError.Error = COPYIN_FAILED;
 		 			return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Get module type for port %d\n", port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get module type for port %d\n", port);
 				if ( port < 0 || port > 511 )
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_MODTYPE: Bad port number %d\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Bad port number %d\n", port);
 		 			p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 		 			return EINVAL;
 				}
 				PortP = (p->RIOPortp[port]);
 				if (!PortP->Mapped)
 				{
-		 			rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_MODTYPE: Port %d not mapped\n", port));
+		 			rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_MODTYPE: Port %d not mapped\n", port);
 		 			p->RIOError.Error = PORT_NOT_MAPPED_INTO_SYSTEM;
 		 			return EINVAL;
 				}
@@ -702,7 +703,7 @@
 			*/
 
 	 		case RIO_BLOCK_OPENS:
-				rio_dprint(RIO_DEBUG_CTRL, ("Opens block until booted\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Opens block until booted\n");
 				for ( Entry=0; Entry < RIO_PORTS; Entry++ ) {
 		 			rio_spin_lock_irqsave(&PortP->portSem, flags);
 		 			p->RIOPortp[Entry]->WaitUntilBooted = 1;
@@ -711,33 +712,33 @@
 				return 0;
 			
 	 		case RIO_SETUP_PORTS:
-				rio_dprint(RIO_DEBUG_CTRL, ("Setup ports\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Setup ports\n");
 				if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) 
 						== COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
-					 rio_dprint(RIO_DEBUG_CTRL, ("EFAULT"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "EFAULT");
 					 return EFAULT;
 				}
 				if ( PortSetup.From > PortSetup.To || 
 								PortSetup.To >= RIO_PORTS ) {
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
-					 rio_dprint(RIO_DEBUG_CTRL, ("ENXIO"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "ENXIO");
 					 return ENXIO;
 				}
 				if ( PortSetup.XpCps > p->RIOConf.MaxXpCps ||
 					 PortSetup.XpCps < p->RIOConf.MinXpCps ) {
 					 p->RIOError.Error = XPRINT_CPS_OUT_OF_RANGE;
-					 rio_dprint(RIO_DEBUG_CTRL, ("EINVAL"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "EINVAL");
 					 return EINVAL;
 				}
 				if ( !p->RIOPortp ) {
 					 cprintf("No p->RIOPortp array!\n");
-					 rio_dprint(RIO_DEBUG_CTRL, ("No p->RIOPortp array!\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "No p->RIOPortp array!\n");
 					 return EIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("entering loop (%d %d)!\n", PortSetup.From, PortSetup.To));
+				rio_dprintk (RIO_DEBUG_CTRL, "entering loop (%d %d)!\n", PortSetup.From, PortSetup.To);
 				for (loop=PortSetup.From; loop<=PortSetup.To; loop++) {
-				rio_dprint(RIO_DEBUG_CTRL, ("in loop (%d)!\n", loop));
+				rio_dprintk (RIO_DEBUG_CTRL, "in loop (%d)!\n", loop);
 #if 0
 					PortP = p->RIOPortp[loop];
 					if ( !PortP->TtyP )
@@ -790,12 +791,12 @@
 					 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 #endif
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("after loop (%d)!\n", loop));
-				rio_dprint(RIO_DEBUG_CTRL,  ("Retval:%x\n", retval ) );
+				rio_dprintk (RIO_DEBUG_CTRL, "after loop (%d)!\n", loop);
+				rio_dprintk (RIO_DEBUG_CTRL, "Retval:%x\n", retval);
 				return retval;
 
 			case RIO_GET_PORT_SETUP :
-				rio_dprint(RIO_DEBUG_CTRL, ("Get port setup\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get port setup\n");
 				if (copyin((int)arg, (caddr_t)&PortSetup, sizeof(PortSetup)) 
 							== COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -831,7 +832,7 @@
 				return retval;
 
 			case RIO_GET_PORT_PARAMS :
-				rio_dprint(RIO_DEBUG_CTRL, ("Get port params\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get port params\n");
 				if (copyin( (int)arg, (caddr_t)&PortParams,
 					sizeof(struct PortParams)) == COPYFAIL) {
 					p->RIOError.Error = COPYIN_FAILED;
@@ -844,7 +845,7 @@
 				PortP = (p->RIOPortp[PortParams.Port]);
 				PortParams.Config = PortP->Config;
 				PortParams.State = PortP->State;
-				rio_dprint(RIO_DEBUG_CTRL, ("Port %d\n", PortParams.Port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortParams.Port);
 
 				if (copyout((caddr_t)&PortParams, (int)arg, 
 						sizeof(struct PortParams)) == COPYFAIL ) {
@@ -854,7 +855,7 @@
 				return retval;
 
 			case RIO_GET_PORT_TTY :
-				rio_dprint(RIO_DEBUG_CTRL, ("Get port tty\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Get port tty\n");
 				if (copyin((int)arg, (caddr_t)&PortTty, sizeof(struct PortTty)) 
 						== COPYFAIL) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -865,7 +866,7 @@
 					 return ENXIO;
 				}
 
-				rio_dprint(RIO_DEBUG_CTRL, ("Port %d\n", PortTty.port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Port %d\n", PortTty.port);
 				PortP = (p->RIOPortp[PortTty.port]);
 #if 0
 				PortTty.Tty.tm.c_iflag = PortP->TtyP->tm.c_iflag;
@@ -886,7 +887,7 @@
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Set port %d tty\n", PortTty.port));
+				rio_dprintk (RIO_DEBUG_CTRL, "Set port %d tty\n", PortTty.port);
 				if (PortTty.port >= (ushort) RIO_PORTS) {
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
@@ -905,7 +906,7 @@
 				return retval;
 
 			case RIO_SET_PORT_PARAMS :
-				rio_dprint(RIO_DEBUG_CTRL, ("Set port params\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Set port params\n");
 				if ( copyin((int)arg, (caddr_t)&PortParams, sizeof(PortParams))
 					== COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -922,7 +923,7 @@
 				return retval;
 
 			case RIO_GET_PORT_STATS :
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GET_PORT_STATS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GET_PORT_STATS\n");
 				if ( copyin((int)arg, (caddr_t)&portStats, 
 						sizeof(struct portStats)) == COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -948,7 +949,7 @@
 
 			case RIO_RESET_PORT_STATS :
 				port = (uint) arg;
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_RESET_PORT_STATS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_RESET_PORT_STATS\n");
 				if ( port >= RIO_PORTS ) {
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
@@ -964,7 +965,7 @@
 				return retval;
 
 			case RIO_GATHER_PORT_STATS :
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_GATHER_PORT_STATS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_GATHER_PORT_STATS\n");
 				if ( copyin( (int)arg, (caddr_t)&portStats, 
 						sizeof(struct portStats)) == COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -984,22 +985,22 @@
 			case RIO_READ_LEVELS:
 				{
 					 int num;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_LEVELS\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_LEVELS\n");
 					 for ( num=0; RIODbInf[num].Flag; num++ ) ;
-					 rio_dprint(RIO_DEBUG_CTRL, ("%d levels to copy\n",num));
+					 rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copy\n",num);
 					 if (copyout((caddr_t)RIODbInf,(int)arg,
 						sizeof(struct DbInf)*(num+1))==COPYFAIL) {
-						rio_dprint(RIO_DEBUG_CTRL, ("ReadLevels Copy failed\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "ReadLevels Copy failed\n");
 						p->RIOError.Error = COPYOUT_FAILED;
 						return EFAULT;
 					 }
-					 rio_dprint(RIO_DEBUG_CTRL, ("%d levels to copied\n",num));
+					 rio_dprintk (RIO_DEBUG_CTRL, "%d levels to copied\n",num);
 					 return retval;
 				}
 #endif
 
 			 case RIO_READ_CONFIG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_CONFIG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_CONFIG\n");
 				if (copyout((caddr_t)&p->RIOConf, (int)arg, 
 							sizeof(struct Conf)) ==COPYFAIL ) {
 					 p->RIOError.Error = COPYOUT_FAILED;
@@ -1008,7 +1009,7 @@
 				return retval;
 
 			case RIO_SET_CONFIG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_CONFIG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_CONFIG\n");
 				if ( !su ) {
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
@@ -1028,11 +1029,11 @@
 				return retval;
 
 			case RIO_START_POLLER:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_START_POLLER\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_START_POLLER\n");
 				return EINVAL;
 
 			case RIO_STOP_POLLER:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_STOP_POLLER\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_STOP_POLLER\n");
 				if ( !su ) {
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
@@ -1042,7 +1043,7 @@
 
 			case RIO_SETDEBUG:
 			case RIO_GETDEBUG:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SETDEBUG/RIO_GETDEBUG\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG/RIO_GETDEBUG\n");
 				if ( copyin( (int)arg, (caddr_t)&DebugCtrl, sizeof(DebugCtrl) )
 							==COPYFAIL ) {
 					 p->RIOError.Error = COPYIN_FAILED;
@@ -1056,18 +1057,18 @@
 						}
 						p->rio_debug = DebugCtrl.Debug;
 						p->RIODebugWait = DebugCtrl.Wait;
-						rio_dprint(RIO_DEBUG_CTRL, ("Set global debug to 0x%x set wait to 0x%x\n",
-							p->rio_debug,p->RIODebugWait));
+						rio_dprintk (RIO_DEBUG_CTRL, "Set global debug to 0x%x set wait to 0x%x\n",
+							p->rio_debug,p->RIODebugWait);
 					}
 				 	else {
-						rio_dprint(RIO_DEBUG_CTRL, ("Get global debug 0x%x wait 0x%x\n",
-										p->rio_debug,p->RIODebugWait));
+						rio_dprintk (RIO_DEBUG_CTRL, "Get global debug 0x%x wait 0x%x\n",
+										p->rio_debug,p->RIODebugWait);
 						DebugCtrl.Debug = p->rio_debug;
 						DebugCtrl.Wait  = p->RIODebugWait;
 						if ( copyout((caddr_t)&DebugCtrl,(int)arg,
 								sizeof(DebugCtrl)) == COPYFAIL ) {
-							rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET/GET DEBUG: bad port number %d\n",
-									DebugCtrl.SysPort));
+							rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
+									DebugCtrl.SysPort);
 						 	p->RIOError.Error = COPYOUT_FAILED;
 						 	return EFAULT;
 						}
@@ -1075,8 +1076,8 @@
 				}
 				else if ( DebugCtrl.SysPort >= RIO_PORTS && 
 							DebugCtrl.SysPort != NO_PORT ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET/GET DEBUG: bad port number %d\n",
-									DebugCtrl.SysPort));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET/GET DEBUG: bad port number %d\n",
+									DebugCtrl.SysPort);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
 				}
@@ -1088,16 +1089,16 @@
 					rio_spin_lock_irqsave(&PortP->portSem, flags);
 					p->RIOPortp[DebugCtrl.SysPort]->Debug = DebugCtrl.Debug;
 					rio_spin_unlock_irqrestore( &PortP->portSem , flags);
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_SETDEBUG 0x%x\n",
-								p->RIOPortp[DebugCtrl.SysPort]->Debug));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_SETDEBUG 0x%x\n",
+								p->RIOPortp[DebugCtrl.SysPort]->Debug);
 				}
 				else {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_GETDEBUG 0x%x\n",
-									 p->RIOPortp[DebugCtrl.SysPort]->Debug));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG 0x%x\n",
+									 p->RIOPortp[DebugCtrl.SysPort]->Debug);
 					DebugCtrl.Debug = p->RIOPortp[DebugCtrl.SysPort]->Debug;
 					if ( copyout((caddr_t)&DebugCtrl,(int)arg,
 								sizeof(DebugCtrl))==COPYFAIL ) {
-						rio_dprint(RIO_DEBUG_CTRL, ("RIO_GETDEBUG: Bad copy to user space\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "RIO_GETDEBUG: Bad copy to user space\n");
 						p->RIOError.Error = COPYOUT_FAILED;
 						return EFAULT;
 					}
@@ -1110,12 +1111,12 @@
 				** We return MAX_VERSION_LEN bytes, being a
 				** textual null terminated string.
 				*/
-				rio_dprint(RIO_DEBUG_CTRL,  ("RIO_VERSID\n") );
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_VERSID\n");
 				if ( copyout(	(caddr_t)RIOVersid(),
 						(int)arg,
 						sizeof(struct rioVersion) ) == COPYFAIL )
 				{
-					 rio_dprint(RIO_DEBUG_CTRL,  ("RIO_VERSID: Bad copy to user space (host=%d)\n",Host) );
+					 rio_dprintk (RIO_DEBUG_CTRL,  "RIO_VERSID: Bad copy to user space (host=%d)\n", Host);
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1149,10 +1150,10 @@
 				** Enquire as to the number of hosts located
 				** at init time.
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_NUM_HOSTS\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS\n");
 				if (copyout((caddr_t)&p->RIONumHosts, (int)arg, 
 							sizeof(p->RIONumHosts) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_NUM_HOSTS: Bad copy to user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_NUM_HOSTS: Bad copy to user space\n");
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1162,9 +1163,9 @@
 				/*
 				** Kill host. This may not be in the final version...
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_FOAD %d\n", (int)arg));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD %d\n", (int)arg);
 				if ( !su ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_FOAD: Not super user\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_FOAD: Not super user\n");
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
 				}
@@ -1212,27 +1213,27 @@
 				return retval;
 
 			case RIO_DOWNLOAD:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD\n");
 				if ( !su ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Not super user\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Not super user\n");
 					 p->RIOError.Error = NOT_SUPER_USER;
 					 return EPERM;
 				}
 				if ( copyin((int)arg, (caddr_t)&DownLoad, 
 							sizeof(DownLoad) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Copy in from user space failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Copy in from user space failed\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL,  ("Copied in download code for product code 0x%x\n",
-				    DownLoad.ProductCode ) );
+				rio_dprintk (RIO_DEBUG_CTRL, "Copied in download code for product code 0x%x\n",
+				    DownLoad.ProductCode);
 
 				/*
 				** It is important that the product code is an unsigned object!
 				*/
 				if ( DownLoad.ProductCode > MAX_PRODUCT ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_DOWNLOAD: Bad product code %d passed\n",
-							DownLoad.ProductCode));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_DOWNLOAD: Bad product code %d passed\n",
+							DownLoad.ProductCode);
 					 p->RIOError.Error = NO_SUCH_PRODUCT;
 					 return ENXIO;
 				}
@@ -1253,63 +1254,63 @@
 
 					if (copyin((int)arg, (caddr_t)&host, 
 							sizeof(host) ) == COPYFAIL ) {
-						rio_dprint(RIO_DEBUG_CTRL, (
-							"RIO_HOST_REQ: Copy in from user space failed\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, 
+							"RIO_HOST_REQ: Copy in from user space failed\n");
 						p->RIOError.Error = COPYIN_FAILED;
 						return EFAULT;
 					}
 					/*
 					** Fetch the parmmap
 					*/
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_PARMS\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS\n");
 					if ( copyout( (caddr_t)p->RIOHosts[host].ParmMapP, 
 								(int)arg, sizeof(PARM_MAP) )==COPYFAIL ) {
 						p->RIOError.Error = COPYOUT_FAILED;
-						rio_dprint(RIO_DEBUG_CTRL, ("RIO_PARMS: Copy out to user space failed\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "RIO_PARMS: Copy out to user space failed\n");
 						return EFAULT;
 					}
 				}
 				return retval;
 
 			case RIO_HOST_REQ:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ\n");
 				if (copyin((int)arg, (caddr_t)&HostReq, 
 							sizeof(HostReq) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Copy in from user space failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Copy in from user space failed\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
 				if ( HostReq.HostNum >= p->RIONumHosts ) {
 					 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Illegal host number %d\n",
-							HostReq.HostNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Illegal host number %d\n",
+							HostReq.HostNum);
 					 return ENXIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for host %d\n", HostReq.HostNum));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostReq.HostNum);
 
 				if (copyout((caddr_t)&p->RIOHosts[HostReq.HostNum], 
 					(int)HostReq.HostP,sizeof(struct Host) ) == COPYFAIL) {
 					p->RIOError.Error = COPYOUT_FAILED;
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_REQ: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_REQ: Bad copy to user space\n");
 					return EFAULT;
 				}
 				return retval;
 
 			 case RIO_HOST_DPRAM:
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for DPRAM\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for DPRAM\n");
 				if ( copyin( (int)arg, (caddr_t)&HostDpRam, 
 								sizeof(HostDpRam) )==COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Copy in from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Copy in from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 				if ( HostDpRam.HostNum >= p->RIONumHosts ) {
 					p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Illegal host number %d\n",
-										HostDpRam.HostNum));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Illegal host number %d\n",
+										HostDpRam.HostNum);
 					return ENXIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for host %d\n", HostDpRam.HostNum));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for host %d\n", HostDpRam.HostNum);
 
 				if (p->RIOHosts[HostDpRam.HostNum].Type == RIO_PCI) {
 					 int off;
@@ -1320,7 +1321,7 @@
 					if ( copyout( (caddr_t)copy, (int)HostDpRam.DpRamP, 
 							sizeof(struct DpRam) ) == COPYFAIL ) {
 						p->RIOError.Error = COPYOUT_FAILED;
-						rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Bad copy to user space\n"));
+						rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
 						return EFAULT;
 					}
 				}
@@ -1328,15 +1329,15 @@
 					(int)HostDpRam.DpRamP, 
 						sizeof(struct DpRam) ) == COPYFAIL ) {
 					 p->RIOError.Error = COPYOUT_FAILED;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_DPRAM: Bad copy to user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_DPRAM: Bad copy to user space\n");
 					 return EFAULT;
 				}
 				return retval;
 
 			 case RIO_SET_BUSY:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_BUSY\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY\n");
 				if ( (int)arg < 0 || (int)arg > 511 ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_SET_BUSY: Bad port number %d\n",(int)arg));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SET_BUSY: Bad port number %d\n",(int)arg);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
@@ -1350,26 +1351,26 @@
 				** The daemon want port information
 				** (probably for debug reasons)
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT\n");
 				if ( copyin((int)arg, (caddr_t)&PortReq, 
 					sizeof(PortReq) )==COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Copy in from user space failed\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Copy in from user space failed\n");
 					p->RIOError.Error = COPYIN_FAILED;
 					return EFAULT;
 				}
 
 				if (PortReq.SysPort >= RIO_PORTS) { /* SysPort is unsigned */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Illegal port number %d\n",
-											PortReq.SysPort));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Illegal port number %d\n",
+											PortReq.SysPort);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for port %d\n", PortReq.SysPort));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for port %d\n", PortReq.SysPort);
 				if (copyout((caddr_t)p->RIOPortp[PortReq.SysPort], 
 							 (int)PortReq.PortP,
 								sizeof(struct Port) ) == COPYFAIL) {
 					 p->RIOError.Error = COPYOUT_FAILED;
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_PORT: Bad copy to user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_PORT: Bad copy to user space\n");
 					 return EFAULT;
 				}
 				return retval;
@@ -1379,40 +1380,40 @@
 				** The daemon want rup information
 				** (probably for debug reasons)
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP\n");
 				if (copyin((int)arg, (caddr_t)&RupReq, 
 						sizeof(RupReq) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Copy in from user space failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Copy in from user space failed\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
 				if (RupReq.HostNum >= p->RIONumHosts) { /* host is unsigned */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Illegal host number %d\n",
-								RupReq.HostNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal host number %d\n",
+								RupReq.HostNum);
 					 p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
 					 return ENXIO;
 				}
 				if ( RupReq.RupNum >= MAX_RUP+LINKS_PER_UNIT ) { /* eek! */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Illegal rup number %d\n",
-							RupReq.RupNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Illegal rup number %d\n",
+							RupReq.RupNum);
 					 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
 				HostP = &p->RIOHosts[RupReq.HostNum];
 
 				if ((HostP->Flags & RUN_STATE) != RC_RUNNING) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Host %d not running\n",
-							RupReq.HostNum));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Host %d not running\n",
+							RupReq.HostNum);
 					 p->RIOError.Error = HOST_NOT_RUNNING;
 					 return EIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for rup %d from host %d\n",
-						RupReq.RupNum,RupReq.HostNum));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for rup %d from host %d\n",
+						RupReq.RupNum,RupReq.HostNum);
 
 				if (copyout((caddr_t)HostP->UnixRups[RupReq.RupNum].RupP,
 					(int)RupReq.RupP,sizeof(struct RUP) ) == COPYFAIL) {
 					p->RIOError.Error = COPYOUT_FAILED;
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_RUP: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_RUP: Bad copy to user space\n");
 					return EFAULT;
 				}
 				return retval;
@@ -1422,39 +1423,39 @@
 				** The daemon want lpb information
 				** (probably for debug reasons)
 				*/
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB\n");
 				if (copyin((int)arg, (caddr_t)&LpbReq, 
 					sizeof(LpbReq) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Bad copy from user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy from user space\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
 				if (LpbReq.Host >= p->RIONumHosts) { /* host is unsigned */
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Illegal host number %d\n",
-							LpbReq.Host));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal host number %d\n",
+							LpbReq.Host);
 					p->RIOError.Error = HOST_NUMBER_OUT_OF_RANGE;
 					return ENXIO;
 				}
 				if ( LpbReq.Link >= LINKS_PER_UNIT ) { /* eek! */
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Illegal link number %d\n",
-							LpbReq.Link));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Illegal link number %d\n",
+							LpbReq.Link);
 					 p->RIOError.Error = LINK_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
 				HostP = &p->RIOHosts[LpbReq.Host];
 
 				if ( (HostP->Flags & RUN_STATE) != RC_RUNNING ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Host %d not running\n",
-						LpbReq.Host));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Host %d not running\n",
+						LpbReq.Host );
 					 p->RIOError.Error = HOST_NOT_RUNNING;
 					 return EIO;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Request for lpb %d from host %d\n",
-					LpbReq.Link, LpbReq.Host));
+				rio_dprintk (RIO_DEBUG_CTRL, "Request for lpb %d from host %d\n",
+					LpbReq.Link, LpbReq.Host);
 
 				if (copyout((caddr_t)&HostP->LinkStrP[LpbReq.Link],
 					(int)LpbReq.LpbP,sizeof(struct LPB) ) == COPYFAIL) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_HOST_LPB: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_HOST_LPB: Bad copy to user space\n");
 					p->RIOError.Error = COPYOUT_FAILED;
 					return EFAULT;
 				}
@@ -1493,7 +1494,7 @@
 					 p->RIOError.Error = NOT_RECEIVING_PROCESS;
 					 return EPERM;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("Clear signal process to zero\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Clear signal process to zero\n");
 				p->RIOSignalProcess = 0;
 				return retval;
 
@@ -1525,10 +1526,10 @@
 			case RIO_MAP_B50_TO_57600:
 			case RIO_MAP_B110_TO_110:
 			case RIO_MAP_B110_TO_115200:
-				rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping\n");
 				port = (uint) arg;
 				if ( port < 0 || port > 511 ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping: Bad port number %d\n", port));
+					 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", port);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
@@ -1552,14 +1553,14 @@
 				return retval;
 
 			case RIO_STREAM_INFO:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_STREAM_INFO\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_STREAM_INFO\n");
 				return EINVAL;
 
 			case RIO_SEND_PACKET:
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_SEND_PACKET\n"));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET\n");
 				if ( copyin( (int)arg, (caddr_t)&SendPack,
 									sizeof(SendPack) )==COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_SEND_PACKET: Bad copy from user space\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_SEND_PACKET: Bad copy from user space\n");
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
@@ -1604,7 +1605,7 @@
 			case RIO_WHAT_MESG:
 				if ( copyout( (caddr_t)&p->RIONoMessage, (int)arg, 
 					sizeof(p->RIONoMessage) )==COPYFAIL ) {
-					rio_dprint(RIO_DEBUG_CTRL, ("RIO_WHAT_MESG: Bad copy to user space\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "RIO_WHAT_MESG: Bad copy to user space\n");
 					p->RIOError.Error = COPYOUT_FAILED;
 					return EFAULT;
 				}
@@ -1616,8 +1617,8 @@
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP host %d rup %d addr %x\n", 
-						SubCmd.Host, SubCmd.Rup, SubCmd.Addr));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP host %d rup %d addr %x\n", 
+						SubCmd.Host, SubCmd.Rup, SubCmd.Addr);
 
 				if (SubCmd.Rup >= MAX_RUP+LINKS_PER_UNIT ) {
 					 p->RIOError.Error = RUP_NUMBER_OUT_OF_RANGE;
@@ -1637,7 +1638,7 @@
 				rio_spin_lock_irqsave(&PortP->portSem, flags);
 
 				if ( RIOPreemptiveCmd(p,  PortP, MEMDUMP ) == RIO_FAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP failed\n");
 					 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 					 return EBUSY;
 				}
@@ -1647,7 +1648,7 @@
 				rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 				if ( copyout( (caddr_t)p->RIOMemDump, (int)arg, 
 							MEMDUMP_SIZE) == COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_MEM_DUMP copy failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_MEM_DUMP copy failed\n");
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1656,14 +1657,14 @@
 			case RIO_TICK:
 				if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
 					 return EINVAL;
-				rio_dprint(RIO_DEBUG_CTRL, ("Set interrupt for host %d\n", (int)arg ));
+				rio_dprintk (RIO_DEBUG_CTRL, "Set interrupt for host %d\n", (int)arg);
 				WBYTE(p->RIOHosts[(int)arg].SetInt , 0xff);
 				return 0;
 
 			case RIO_TOCK:
 				if ((int)arg < 0 || (int)arg >= p->RIONumHosts)
 					 return EINVAL;
-				rio_dprint(RIO_DEBUG_CTRL, ("Clear interrupt for host %d\n", (int)arg ));
+				rio_dprintk (RIO_DEBUG_CTRL, "Clear interrupt for host %d\n", (int)arg);
 				WBYTE((p->RIOHosts[(int)arg].ResetInt) , 0xff);
 				return 0;
 
@@ -1683,12 +1684,12 @@
 					 p->RIOError.Error = COPYIN_FAILED;
 					 return EFAULT;
 				}
-				rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER host %d rup %d port %d reg %x\n", 
-						SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr));
+				rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER host %d rup %d port %d reg %x\n", 
+						SubCmd.Host, SubCmd.Rup, SubCmd.Port, SubCmd.Addr);
 
 				if (SubCmd.Port > 511) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("Baud rate mapping: Bad port number %d\n", 
-								SubCmd.Port));
+					 rio_dprintk (RIO_DEBUG_CTRL, "Baud rate mapping: Bad port number %d\n", 
+								SubCmd.Port);
 					 p->RIOError.Error = PORT_NUMBER_OUT_OF_RANGE;
 					 return EINVAL;
 				}
@@ -1710,7 +1711,7 @@
 				rio_spin_lock_irqsave(&PortP->portSem, flags);
 
 				if (RIOPreemptiveCmd(p, PortP, READ_REGISTER) == RIO_FAIL) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER failed\n");
 					 rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 					 return EBUSY;
 				}
@@ -1720,7 +1721,7 @@
 				rio_spin_unlock_irqrestore( &PortP->portSem , flags);
 				if (copyout((caddr_t)&p->CdRegister, (int)arg, 
 							sizeof(uint)) == COPYFAIL ) {
-					 rio_dprint(RIO_DEBUG_CTRL, ("RIO_READ_REGISTER copy failed\n"));
+					 rio_dprintk (RIO_DEBUG_CTRL, "RIO_READ_REGISTER copy failed\n");
 					 p->RIOError.Error = COPYOUT_FAILED;
 					 return EFAULT;
 				}
@@ -1737,18 +1738,18 @@
 					switch ( (uint)arg & RIO_DEV_MASK ) {
 						case RIO_DEV_DIRECT:
 							arg = (caddr_t)drv_makedev(major(dev), port);
-							rio_dprint(RIO_DEBUG_CTRL, ("Makedev direct 0x%x is 0x%x\n",port, (int)arg ));
+							rio_dprintk (RIO_DEBUG_CTRL, "Makedev direct 0x%x is 0x%x\n",port, (int)arg);
 							return (int)arg;
 					 	case RIO_DEV_MODEM:
 							arg =  (caddr_t)drv_makedev(major(dev), (port|RIO_MODEM_BIT) );
-							rio_dprint(RIO_DEBUG_CTRL, ("Makedev modem 0x%x is 0x%x\n",port, (int)arg ));
+							rio_dprintk (RIO_DEBUG_CTRL, "Makedev modem 0x%x is 0x%x\n",port, (int)arg);
 							return (int)arg;
 						case RIO_DEV_XPRINT:
 							arg = (caddr_t)drv_makedev(major(dev), port);
-							rio_dprint(RIO_DEBUG_CTRL, ("Makedev printer 0x%x is 0x%x\n",port, (int)arg ));
+							rio_dprintk (RIO_DEBUG_CTRL, "Makedev printer 0x%x is 0x%x\n",port, (int)arg);
 							return (int)arg;
 					}
-					rio_dprint(RIO_DEBUG_CTRL, ("MAKE Device is called\n"));
+					rio_dprintk (RIO_DEBUG_CTRL, "MAKE Device is called\n");
 					return EINVAL;
 				}
 				/*
@@ -1765,18 +1766,20 @@
 					mino = RIO_UNMODEM(dv);
 
 					if ( RIO_ISMODEM(dv) ) {
-						rio_dprint(RIO_DEBUG_CTRL, ("Minor for device 0x%x: modem %d\n", dv, mino));
+						rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: modem %d\n", dv, mino);
 						arg = (caddr_t)(mino | RIO_DEV_MODEM);
 					}
 					else {
-						rio_dprint(RIO_DEBUG_CTRL, ("Minor for device 0x%x: direct %d\n", dv, mino));
+						rio_dprintk (RIO_DEBUG_CTRL, "Minor for device 0x%x: direct %d\n", dv, mino);
 						arg = (caddr_t)(mino | RIO_DEV_DIRECT);
 					}
 					return (int)arg;
 				}
 	}
-	rio_dprint(RIO_DEBUG_CTRL, ("INVALID DAEMON IOCTL 0x%x\n",cmd));
+	rio_dprintk (RIO_DEBUG_CTRL, "INVALID DAEMON IOCTL 0x%x\n",cmd);
 	p->RIOError.Error = IOCTL_COMMAND_UNKNOWN;
+
+	func_exit ();
 	return EINVAL;
 }
 
@@ -1800,18 +1803,18 @@
 #endif
 
 	if ( PortP->State & RIO_DELETED ) {
-		rio_dprint(RIO_DEBUG_CTRL, ("Preemptive command to deleted RTA ignored\n"));
+		rio_dprintk (RIO_DEBUG_CTRL, "Preemptive command to deleted RTA ignored\n");
 		return RIO_FAIL;
 	}
 
 	if (((int)((char)PortP->InUse) == -1) || ! (CmdBlkP = RIOGetCmdBlk()) ) {
-		rio_dprint(RIO_DEBUG_CTRL, ("Cannot allocate command block for command %d on port %d\n",
-		       Cmd, PortP->PortNum));
+		rio_dprintk (RIO_DEBUG_CTRL, "Cannot allocate command block for command %d on port %d\n",
+		       Cmd, PortP->PortNum);
 		return RIO_FAIL;
 	}
 
-	rio_dprint(RIO_DEBUG_CTRL, ("Command blk 0x%x - InUse now %d\n", 
-	       (int)CmdBlkP,PortP->InUse));
+	rio_dprintk (RIO_DEBUG_CTRL, "Command blk 0x%x - InUse now %d\n", 
+	       (int)CmdBlkP,PortP->InUse);
 
 	PktCmdP = (struct PktCmd_M *)&CmdBlkP->Packet.data[0];
 
@@ -1837,40 +1840,40 @@
 
 	switch ( Cmd ) {
 		case MEMDUMP:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
-			       (int)CmdBlkP, (int)SubCmd.Addr));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue MEMDUMP command blk 0x%x (addr 0x%x)\n",
+			       (int)CmdBlkP, (int)SubCmd.Addr);
 			PktCmdP->SubCommand		= MEMDUMP;
 			PktCmdP->SubAddr		= SubCmd.Addr;
 			break;
 		case FCLOSE:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue FCLOSE command blk 0x%x\n",(int)CmdBlkP);
 			break;
 		case READ_REGISTER:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue READ_REGISTER (0x%x) command blk 0x%x\n",
-		 		(int)SubCmd.Addr, (int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue READ_REGISTER (0x%x) command blk 0x%x\n",
+		 		(int)SubCmd.Addr, (int)CmdBlkP);
 			PktCmdP->SubCommand		= READ_REGISTER;
 			PktCmdP->SubAddr		= SubCmd.Addr;
 			break;
 		case RESUME:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue RESUME command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue RESUME command blk 0x%x\n",(int)CmdBlkP);
 			break;
 		case RFLUSH:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue RFLUSH command blk 0x%x\n",(int)CmdBlkP);
 			CmdBlkP->PostFuncP = RIORFlushEnable;
 			break;
 		case SUSPEND:
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue SUSPEND command blk 0x%x\n",(int)CmdBlkP);
 			break;
 
 		case MGET :
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue MGET command blk 0x%x\n", (int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue MGET command blk 0x%x\n", (int)CmdBlkP);
 			break;
 
 		case MSET :
 		case MBIC :
 		case MBIS :
 			CmdBlkP->Packet.data[4] = (char) PortP->ModemLines;
-			rio_dprint(RIO_DEBUG_CTRL, ("Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP));
+			rio_dprintk (RIO_DEBUG_CTRL, "Queue MSET/MBIC/MBIS command blk 0x%x\n", (int)CmdBlkP);
 			break;
 
 		case WFLUSH:
@@ -1880,12 +1883,12 @@
 			** RTA.
 			*/
 			if ((int)((char)PortP->WflushFlag) == (int)-1) {
-				rio_dprint(RIO_DEBUG_CTRL, ("Trashed WFLUSH, WflushFlag about to wrap!"));
+				rio_dprintk (RIO_DEBUG_CTRL, "Trashed WFLUSH, WflushFlag about to wrap!");
 				RIOFreeCmdBlk(CmdBlkP);
 				return(RIO_FAIL);
 			} else {
-				rio_dprint(RIO_DEBUG_CTRL, ("Queue WFLUSH command blk 0x%x\n",
-				       (int)CmdBlkP));
+				rio_dprintk (RIO_DEBUG_CTRL, "Queue WFLUSH command blk 0x%x\n",
+				       (int)CmdBlkP);
 				CmdBlkP->PostFuncP = RIOWFlushMark;
 			}
 			break;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/riodrvr.h linux.17p18/drivers/char/rio/riodrvr.h
--- linux.vanilla/drivers/char/rio/riodrvr.h	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/riodrvr.h	Tue Aug  1 07:59:30 2000
@@ -44,7 +44,7 @@
 
 struct rio_info {
 	int			mode;			/* Intr or polled, word/byte */
-	semtype			RIOIntrSem;		/* Interrupt thread sem */
+	spinlock_t		RIOIntrSem;		/* Interrupt thread sem */
 	int			current_chan;		/* current channel */
 	int			RIOFailed;		/* Not initialised ? */
 	int			RIOInstallAttempts;	/* no. of rio-install() calls */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rioinit.c linux.17p18/drivers/char/rio/rioinit.c
--- linux.vanilla/drivers/char/rio/rioinit.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/rioinit.c	Wed Aug  9 22:24:45 2000
@@ -81,7 +81,7 @@
 #include "control.h"
 #include "cirrus.h"
 #include "rioioctl.h"
-
+#include "rio_linux.h"
 
 #undef bcopy
 #define bcopy rio_pcicopy
@@ -109,7 +109,7 @@
 	*/
 	if ( !p->RIOPortp )
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("Allocating and setting up driver data structures\n") );
+		rio_dprintk (RIO_DEBUG_INIT,  "Allocating and setting up driver data structures\n");
 
 		RIOAllocDataStructs(p);		/* allocate host/port structs */
 		RIOSetupDataStructs(p);		/* setup topology structs */
@@ -155,16 +155,16 @@
 
 	if ( info->bus & ISA_BUS )
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("initialising card %d (ISA)\n", p->RIONumHosts) );
+		rio_dprintk (RIO_DEBUG_INIT,  "initialising card %d (ISA)\n", p->RIONumHosts);
 		RIOISAinit(p, p->mode);
 	}
 	else
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("initialising card %d (PCI)\n", p->RIONumHosts) );
+		rio_dprintk (RIO_DEBUG_INIT,  "initialising card %d (PCI)\n", p->RIONumHosts);
 		RIOPCIinit(p, RIO_PCI_DEFAULT_MODE);
 	}
 
-	rio_dprint(RIO_DEBUG_INIT,  ("Total hosts initialised so far : %d\n", p->RIONumHosts) );
+	rio_dprintk (RIO_DEBUG_INIT,  "Total hosts initialised so far : %d\n", p->RIONumHosts);
 
 
 #ifdef FUTURE_RELEASE
@@ -193,13 +193,13 @@
 	p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
 					(int (*)())rio_intr, (char*)p->RIONumHosts);
 
-	rio_dprint(RIO_DEBUG_INIT,  ("Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "Set interrupt handler, intr_tid = 0x%x\n", p->intr_tid );
 
 	if (RIODoAT(p, p->RIOHosts[p->RIONumHosts].PaddrP, mode)) {
 		return;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_INIT, ("RIODoAT failed\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIODoAT failed\n");
 		p->RIOFailed++;
 	}
 #endif
@@ -268,7 +268,7 @@
 	** map it in in one 64K block.
 	*/
 	if (RIOMapin(Base, RIO_AT_MEM_SIZE, &virtAddr) == -1) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Couldn't map the board in!\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't map the board in!\n");
 		return((caddr_t)0);
 	}
 
@@ -285,8 +285,8 @@
 			** Signature mismatch - card not at this address
 			*/
 			RIOMapout(Base, RIO_AT_MEM_SIZE, virtAddr);
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
-						(int)cardp, off));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Couldn't match the signature 0x%x 0x%x!\n",
+						(int)cardp, off);
 			return((caddr_t)0);
 		}
 	}
@@ -356,10 +356,10 @@
 		((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[1])&0xFF)<<8)|
 		((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
 		((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Uniquenum 0x%x\n",p->RIOHosts[p->RIONumHosts].UniqueNum);
 
 	p->RIONumHosts++;
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Tests Passed at 0x%x\n", Base));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Tests Passed at 0x%x\n", Base);
 	return(1);
 }
 #if 0
@@ -378,7 +378,7 @@
 	** is only FAST LINKS
 	*/
 	Mode = (Mode & FAST_LINKS) ? McaTpFastLinks : McaTpSlowLinks;
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOMCAinit(%d)\n",Mode);
+	rio_dprintk (RIO_DEBUG_INIT, "RIOMCAinit(%d)\n",Mode);
 
 
 	/*
@@ -395,7 +395,7 @@
 	*/
 	if (((inb(McaIdHigh)<< 8)|inb(McaIdLow)) == McaRIOId)
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Potential MCA card in slot %d\n",SlotNumber);
+		rio_dprintk (RIO_DEBUG_INIT, "Potential MCA card in slot %d\n", SlotNumber);
 
 		/*
 		** Card appears to be a RIO MCA card!
@@ -417,48 +417,44 @@
 		*/
 		Ivec = inb(McaIrqEnable);
 
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Ivec is %x\n",Ivec);
+		rio_dprintk (RIO_DEBUG_INIT, "Ivec is %x\n", Ivec);
 
 		switch ( Ivec & McaIrqMask )
 		{
 		case McaIrq9:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ9\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ9\n");
 		break;
 		case McaIrq3:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ3\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ3\n");
 		break;
 		case McaIrq4:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ4\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ4\n");
 		break;
 		case McaIrq7:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ7\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ7\n");
 		break;
 		case McaIrq10:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ10\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ10\n");
 		break;
 		case McaIrq11:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ11\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ11\n");
 		break;
 		case McaIrq12:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ12\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ12\n");
 		break;
 		case McaIrq15:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"IRQ15\n");
+		rio_dprintk (RIO_DEBUG_INIT, "IRQ15\n");
 		break;
 		}
 
 		/*
 		** If the card enable bit isn't set, then set it!
 		*/
-		if ((Ivec & McaCardEnable) != McaCardEnable )
-		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"McaCardEnable not set - setting!\n");
-		outb(McaIrqEnable,Ivec|McaCardEnable);
-		}
-		else
-		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"McaCardEnable already set\n");
-		}
+		if ((Ivec & McaCardEnable) != McaCardEnable) {
+			rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable not set - setting!\n");
+			outb(McaIrqEnable,Ivec|McaCardEnable);
+		} else
+			rio_dprintk (RIO_DEBUG_INIT, "McaCardEnable already set\n");
 
 		/*
 		** Convert the IRQ enable mask into something useful
@@ -468,10 +464,10 @@
 		/*
 		** Find the physical address
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"inb(McaMemory) is %x\n",inb(McaMemory));
+		rio_dprintk (RIO_DEBUG_INIT, "inb(McaMemory) is %x\n", inb(McaMemory));
 		Paddr = McaAddress(inb(McaMemory));
 
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"MCA card has Ivec %d Addr %x\n",Ivec,Paddr);
+		rio_dprintk (RIO_DEBUG_INIT, "MCA card has Ivec %d Addr %x\n", Ivec, Paddr);
 
 		if ( Paddr != 0 )
 		{
@@ -482,21 +478,20 @@
 		Handle = RIOMapin( Paddr, RIO_MCA_MEM_SIZE, &Caddr );
 
 		if ( Handle == -1 ) {
-			rio_dprint(RIO_DEBUG_INIT, ("Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE,Paddr);
+			rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n", RIO_MCA_MEM_SIZE, Paddr;
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Board mapped to vaddr 0x%x\n",Caddr);
+		rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
 
 		/*
 		** And check that it is actually there!
 		*/
 		if ( RIOBoardTest( Paddr,Caddr,RIO_MCA,SlotNumber ) == RIO_SUCCESS )
 		{
-			rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Board has passed test\n");
-			rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,
-	"Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
-			SlotNumber,RIO_MCA,Paddr,Caddr,Mode);
+			rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
+			rio_dprintk (RIO_DEBUG_INIT, "Slot %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
+			                            SlotNumber, RIO_MCA, Paddr, Caddr, Mode);
 
 			/*
 			** Board has passed its scrub test. Fill in all the
@@ -524,25 +519,25 @@
 			/*
 			** It failed the test, so ignore it.
 			*/
-			rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"TEST FAILED\n");
+			rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
 			RIOMapout(Paddr, RIO_MCA_MEM_SIZE, Caddr );
 		}
 		}
 		else
 		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d - Paddr zero!\n",SlotNumber);
+		rio_dprintk (RIO_DEBUG_INIT, "Slot %d - Paddr zero!\n", SlotNumber);
 		}
 	}
 	else
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d NOT RIO\n",SlotNumber);
+		rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
 	}
 	}
 	/*
 	** Now we have checked all the slots, turn off the MCA slot selector
 	*/
 	outb(McaSlotSelect,0);
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Slot %d NOT RIO\n",SlotNumber);
+	rio_dprintk (RIO_DEBUG_INIT, "Slot %d NOT RIO\n", SlotNumber);
 	return ret;
 }
 
@@ -565,13 +560,13 @@
 
 	if ( EISADone )
 	{
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOEISAinit() - already done, return.\n");
+		rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit() - already done, return.\n");
 		return(0);
 	}
 
 	EISADone++;
 
-	rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIOEISAinit()\n");
+	rio_dprintk (RIO_DEBUG_INIT, "RIOEISAinit()\n");
 
 
 	/*
@@ -584,23 +579,21 @@
 	Ident = (INBZ(EisaSlot,EISA_PRODUCT_IDENT_HI)<<8) |
 		 INBZ(EisaSlot,EISA_PRODUCT_IDENT_LO);
 
-	/* rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT, "Check EISA slot %d, ID=%x\n",EisaSlot,Ident); */
-
 	if ( Ident == RIO_EISA_IDENT )
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Found Specialix product\n");
+		rio_dprintk (RIO_DEBUG_INIT, "Found Specialix product\n");
 
 		if ( INBZ(EisaSlot,EISA_PRODUCT_NUMBER) != RIO_EISA_PRODUCT_CODE )
 		{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Not Specialix RIO - Product number %x\n",
-						INBZ(EisaSlot,EISA_PRODUCT_NUMBER));
+		rio_dprintk (RIO_DEBUG_INIT, "Not Specialix RIO - Product number %x\n",
+						INBZ(EisaSlot, EISA_PRODUCT_NUMBER));
 		continue;  /* next slot */
 		}
 		/*
 		** Its a Specialix RIO!
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"RIO Revision %d\n",
-					INBZ(EisaSlot,EISA_REVISION_NUMBER));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO Revision %d\n",
+					INBZ(EisaSlot, EISA_REVISION_NUMBER));
 		
 		RIOMachineType |= (1<<RIO_EISA);
 
@@ -627,43 +620,43 @@
 		switch ( Ivec & EISA_INTERRUPT_MASK )
 		{
 		case EISA_IRQ_3:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 3\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 3\n");
 		break;
 		case EISA_IRQ_4:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 4\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 4\n");
 		break;
 		case EISA_IRQ_5:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 5\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 5\n");
 		break;
 		case EISA_IRQ_6:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 6\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 6\n");
 		break;
 		case EISA_IRQ_7:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 7\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 7\n");
 		break;
 		case EISA_IRQ_9:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 9\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 9\n");
 		break;
 		case EISA_IRQ_10:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 10\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 10\n");
 		break;
 		case EISA_IRQ_11:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 11\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 11\n");
 		break;
 		case EISA_IRQ_12:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 12\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 12\n");
 		break;
 		case EISA_IRQ_14:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 14\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 14\n");
 		break;
 		case EISA_IRQ_15:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA IRQ 15\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA IRQ 15\n");
 		break;
 		case EISA_POLLED:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"EISA POLLED\n");
+			rio_dprintk (RIO_DEBUG_INIT, "EISA POLLED\n");
 		break;
 		default:
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
+			rio_dprintk (RIO_DEBUG_INIT, NULL,DBG_INIT|DBG_FAIL,"Shagged interrupt number!\n");
 		Ivec &= EISA_CONTROL_MASK;
 		}
 #endif
@@ -741,7 +734,7 @@
 		*/
 		Ivec = RIOEisaToIvec(Ivec);
 
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
+		rio_dprintk (RIO_DEBUG_INIT, "EISA host in slot %d has Ivec 0x%x\n",
 		 EisaSlot, Ivec);
 
 		/*
@@ -750,11 +743,11 @@
 		Paddr = (INBZ(EisaSlot,EISA_MEMORY_BASE_HI)<<24) |
 				(INBZ(EisaSlot,EISA_MEMORY_BASE_LO)<<16);
 
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"EISA card has Ivec %d Addr %x\n",Ivec,Paddr);
+		rio_dprintk (RIO_DEBUG_INIT, "EISA card has Ivec %d Addr %x\n", Ivec, Paddr);
 
 		if ( Paddr == 0 )
 		{
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT | DBG_FAIL,
+		rio_dprintk (RIO_DEBUG_INIT,
 		 "Board in slot %d configured for address zero!\n", EisaSlot);
 		continue;
 		}
@@ -762,23 +755,23 @@
 		/*
 		** Tell the memory mapper that we want to talk to it
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"About to map EISA card \n");
+		rio_dprintk (RIO_DEBUG_INIT, "About to map EISA card \n");
 
 		if (RIOMapin( Paddr, RIO_EISA_MEM_SIZE, &Caddr) == -1) {
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"Couldn't map %d bytes at %x\n",
+		rio_dprintk (RIO_DEBUG_INIT, "Couldn't map %d bytes at %x\n",
 							RIO_EISA_MEM_SIZE,Paddr);
 		continue;
 		}
 
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"Board mapped to vaddr 0x%x\n",Caddr);
+		rio_dprintk (RIO_DEBUG_INIT, "Board mapped to vaddr 0x%x\n", Caddr);
 
 		/*
 		** And check that it is actually there!
 		*/
 		if ( RIOBoardTest( Paddr,Caddr,RIO_EISA,EisaSlot) == RIO_SUCCESS )
 			{
-		rio_dprint(RIO_DEBUG_INIT, NULL, DBG_INIT,"Board has passed test\n");
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,
+		rio_dprintk (RIO_DEBUG_INIT, "Board has passed test\n");
+		rio_dprintk (RIO_DEBUG_INIT, 
 		"Slot %d. Ivec %d. Type %d. Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n",
 			EisaSlot,Ivec,RIO_EISA,Paddr,Caddr,Mode);
 
@@ -818,7 +811,7 @@
 		/*
 		** It failed the test, so ignore it.
 		*/
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_FAIL,"TEST FAILED\n");
+		rio_dprintk (RIO_DEBUG_INIT, "TEST FAILED\n");
 
 		RIOMapout(Paddr, RIO_EISA_MEM_SIZE, Caddr );
 		}
@@ -917,7 +910,7 @@
 	int		Handle;	/* Handle to Virtual memory allocated for current PCI host */
 
 
-	rio_dprint(RIO_DEBUG_INIT,  ("Search for a RIO PCI card - start at slot %d\n", slot ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "Search for a RIO PCI card - start at slot %d\n", slot);
 
 	/*
 	** Initialise the search status
@@ -926,7 +919,7 @@
 
 	while ( (slot < MAX_PCI_SLOT) & (p->RIOLastPCISearch != RIO_SUCCESS) )
 	{
-		rio_dprint(RIO_DEBUG_INIT,  ("Currently testing slot %d\n", slot ) );
+		rio_dprintk (RIO_DEBUG_INIT,  "Currently testing slot %d\n", slot);
 
 		if (read_config(0,slot,0) == RIO_PCI_JET_CARD) {
 			p->RIOHosts[p->RIONumHosts].Ivec = 0;
@@ -934,7 +927,7 @@
 			Paddr = Paddr - (Paddr & 0x1); /* Mask off the io bit */
 
 			if ( (Paddr == 0) || ((Paddr & 0xffff0000) == 0xffff0000) ) {
-				rio_dprint(RIO_DEBUG_INIT,  ("Goofed up slot\n") );	/* what! */
+				rio_dprintk (RIO_DEBUG_INIT,  "Goofed up slot\n");	/* what! */
 				slot++;
 				continue;
 			}
@@ -942,11 +935,11 @@
 			p->RIOHosts[p->RIONumHosts].PaddrP = Paddr;
 			Ivec = (read_config(0,slot,0x3c) & 0xff);
 
-			rio_dprint(RIO_DEBUG_INIT,  ("PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec ) );
+			rio_dprintk (RIO_DEBUG_INIT,  "PCI Host at 0x%x, Intr %d\n", (int)Paddr, Ivec);
 
 			Handle = RIOMapin( Paddr, RIO_PCI_MEM_SIZE, &Caddr );
 			if (Handle == -1) {
-				rio_dprint(RIO_DEBUG_INIT,  ("Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr ) );
+				rio_dprintk (RIO_DEBUG_INIT,  "Couldn't map %d bytes at 0x%x\n", RIO_PCI_MEM_SIZE, (int)Paddr);
 				slot++;
 				continue;
 			}
@@ -954,9 +947,8 @@
 			p->intr_tid = iointset(p->RIOHosts[p->RIONumHosts].Ivec,
 						(int (*)())rio_intr, (char *)p->RIONumHosts);
 			if (RIOBoardTest( Paddr, Caddr, RIO_PCI, 0 ) == RIO_SUCCESS) {
-				rio_dprint(RIO_DEBUG_INIT, ("Board has passed test\n"));
-				rio_dprint(RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, 
-																Mode));
+				rio_dprintk (RIO_DEBUG_INIT, ("Board has passed test\n");
+				rio_dprintk (RIO_DEBUG_INIT, ("Paddr 0x%x. Caddr 0x%x. Mode 0x%x.\n", Paddr, Caddr, Mode);
 
 				/*
 				** Board has passed its scrub test. Fill in all the
@@ -991,8 +983,8 @@
 					((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[2])&0xFF)<<16)|
 					((RBYTE(p->RIOHosts[p->RIONumHosts].Unique[3])&0xFF)<<24);
 
-				rio_dprint(RIO_DEBUG_INIT,  ("Unique no 0x%x.\n", 
-				    p->RIOHosts[p->RIONumHosts].UniqueNum ) );
+				rio_dprintk (RIO_DEBUG_INIT, "Unique no 0x%x.\n", 
+				    p->RIOHosts[p->RIONumHosts].UniqueNum);
 
 				p->RIOLastPCISearch = RIO_SUCCESS;
 				p->RIONumHosts++;
@@ -1002,8 +994,8 @@
 	}
 
 	if ( slot >= MAX_PCI_SLOT ) {
-		rio_dprint(RIO_DEBUG_INIT,  ("All %d PCI slots have tested for RIO cards !!!\n",
-		    MAX_PCI_SLOT ) );
+		rio_dprintk (RIO_DEBUG_INIT,  "All %d PCI slots have tested for RIO cards !!!\n",
+			     MAX_PCI_SLOT);
 	}
 
 
@@ -1025,7 +1017,7 @@
 	int host;
 	for ( host=0; host<p->RIONumHosts; host++ )
 	{
-		rio_dprint(RIO_DEBUG_INIT, NULL,DBG_INIT,"Stop host %d\n",host);
+		rio_dprintk (RIO_DEBUG_INIT, "Stop host %d\n", host);
 		(void)RIOBoardTest( p->RIOHosts[host].PaddrP, p->RIOHosts[host].Caddr, p->RIOHosts[host].Type,p->RIOHosts[host].Slot );
 	}
 }
@@ -1058,8 +1050,8 @@
 	int  op, bank;
 	int  nbanks;
 
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
-			type,(int)DpRam,slot));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Reset host type=%d, DpRam=0x%x, slot=%d\n",
+			type,(int)DpRam, slot);
 
 	RIOHostReset(type, DpRam, slot);
 
@@ -1071,7 +1063,7 @@
 	** scratch	- 1000h bytes
 	*/
 
-	rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Setup ram/size arrays\n"));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Setup ram/size arrays\n");
 
 	size[0] = DP_SRAM1_SIZE;
 	size[1] = DP_SRAM2_SIZE;
@@ -1087,12 +1079,12 @@
 
 
 	if (nbanks == 3) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
-				(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Memory: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
+				(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2]);
 	} else {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x), 0x%x(0x%x)\n",
 			(int)ram[0], size[0], (int)ram[1], size[1], (int)ram[2], size[2], (int)ram[3], 
-					size[3]));
+					size[3]);
 	}
 
 	/*
@@ -1103,14 +1095,14 @@
 	for (op=0; op<TEST_END; op++) {
 		for (bank=0; bank<nbanks; bank++) {
 			if (RIOScrub(op, (BYTE *)ram[bank], size[bank]) == RIO_FAIL) {
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: RIOScrub band %d, op %d failed\n", 
-							bank, op));
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: RIOScrub band %d, op %d failed\n", 
+							bank, op);
 				return RIO_FAIL;
 			}
 		}
 	}
 
-	rio_dprint(RIO_DEBUG_INIT, ("Test completed\n"));
+	rio_dprintk (RIO_DEBUG_INIT, "Test completed\n");
 	return RIO_SUCCESS;
 }
 
@@ -1158,14 +1150,14 @@
 	if (op) {
 		for (off=0; off<size; off++) {
 			if (RBYTE(ram[off]) != oldbyte) {
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off])));
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 1: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
 				return RIO_FAIL;
 			}
 		}
 		for (off=0; off<size; off+=2) {
 			if (*(ushort *)&ram[off] != oldword) {
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]));
-				rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,oldword,*(ushort *)&ram[off]);
+				rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Pre Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 				return RIO_FAIL;
 			}
 		}
@@ -1180,12 +1172,12 @@
 	*/
 	for (off=0; off<size; off++) {
 		if (op && (RBYTE(ram[off]) != oldbyte)) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off,oldbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Pre Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, oldbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 		WBYTE(ram[off],invbyte);
 		if (RBYTE(ram[off]) != invbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n",off,invbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Byte Inv Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, invbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 	}
@@ -1199,15 +1191,15 @@
 	*/
 	for (off=0; off<size; off+=2) {
 		if (*(ushort *)&ram[off] != invword) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n",off,invword,*(ushort *)&ram[off]));
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: WORD at offset 0x%x should have been=%x, was=%x\n", off, invword, *(ushort *)&ram[off]);
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Word Inv Check: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 
 		*(ushort *)&ram[off] = newword;
 		if ( *(ushort *)&ram[off] != newword ) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n",off,newword,*(ushort *)&ram[off]));
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 	}
@@ -1219,15 +1211,15 @@
 	*/
 	for (off=0; off<size; off++) {
 		if (RBYTE(ram[off]) != newbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n",off,newbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Byte Check: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 	}
 
 	for (off=0; off<size; off+=2) {
 		if ( *(ushort *)&ram[off] != newword ) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n",off,newword,*(ushort *)&ram[off]));
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: WORD at offset 0x%x should have been=%x, was=%x\n", off, newword, *(ushort *)&ram[off]);
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: Post Word Check 2: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 	}
@@ -1244,8 +1236,8 @@
 
 	for ( off=0; off<size; off+=2 ) {
 		if (*(ushort *)&ram[off] != swapword) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n",off,swapword,*((ushort *)&ram[off])));
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n",off,RBYTE(ram[off]),off+1,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: WORD at offset 0x%x should have been=%x, was=%x\n", off, swapword, *((ushort *)&ram[off]));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 1: BYTE at offset 0x%x is %x BYTE at offset 0x%x is %x\n", off, RBYTE(ram[off]), off+1, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 		*((ushort *)&ram[off]) = ~swapword;
@@ -1253,11 +1245,11 @@
 
 	for (off=0; off<size; off+=2) {
 		if (RBYTE(ram[off]) != newbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off,newbyte,RBYTE(ram[off])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off, newbyte, RBYTE(ram[off]));
 			return RIO_FAIL;
 		}
 		if (RBYTE(ram[off+1]) != invbyte) {
-			rio_dprint(RIO_DEBUG_INIT, ("RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n",off+1,invbyte,RBYTE(ram[off+1])));
+			rio_dprintk (RIO_DEBUG_INIT, "RIO-init: SwapWord Check 2: BYTE at offset 0x%x should have been=%x, was=%x\n", off+1, invbyte, RBYTE(ram[off+1]));
 			return RIO_FAIL;
 		}
 		*((ushort *)&ram[off]) = newword;
@@ -1384,14 +1376,14 @@
 
 	p->RIOPortp = (struct Port *)sysbrk(RIO_PORTS * sizeof(struct Port));
 	if (!p->RIOPortp) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: No memory for port structures\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for port structures\n");
 		p->RIOFailed++;
 		return;
 	} 
 	bzero( p->RIOPortp, sizeof(struct Port) * RIO_PORTS );
-	rio_dprint(RIO_DEBUG_INIT,  ("RIO-init: allocated and cleared memory for port structs\n") );
-	rio_dprint(RIO_DEBUG_INIT,  ("First RIO port struct @0x%x, size=0x%x bytes\n",
-	    (int)p->RIOPortp, sizeof(struct Port) ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "RIO-init: allocated and cleared memory for port structs\n");
+	rio_dprintk (RIO_DEBUG_INIT,  "First RIO port struct @0x%x, size=0x%x bytes\n",
+	    (int)p->RIOPortp, sizeof(struct Port));
 
 	for( port=0; port<RIO_PORTS; port++ ) {
 		p->RIOPortp[port].PortNum = port;
@@ -1404,17 +1396,17 @@
 
 	p->RIOHosts = (struct Host *)sysbrk(RIO_HOSTS * sizeof(struct Host));
 	if (!p->RIOHosts) {
-		rio_dprint(RIO_DEBUG_INIT, ("RIO-init: No memory for host structures\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "RIO-init: No memory for host structures\n");
 		p->RIOFailed++;
 		return;
 	}
 	bzero(p->RIOHosts, sizeof(struct Host)*RIO_HOSTS);
-	rio_dprint(RIO_DEBUG_INIT,  ("RIO-init: allocated and cleared memory for host structs\n"));
-	rio_dprint(RIO_DEBUG_INIT,  ("First RIO host struct @0x%x, size=0x%x bytes\n",
-	    (int)p->RIOHosts, sizeof(struct Host) ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "RIO-init: allocated and cleared memory for host structs\n");
+	rio_dprintk (RIO_DEBUG_INIT,  "First RIO host struct @0x%x, size=0x%x bytes\n",
+	    (int)p->RIOHosts, sizeof(struct Host));
 
 	for( host=0; host<RIO_HOSTS; host++ ) {
-		p->RIOHosts[host].HostLock = -1; /* Let the first guy takes it */
+		spin_lock_init (&p->RIOHosts[host].HostLock);
 		p->RIOHosts[host].timeout_id = 0; /* Let the first guy takes it */
 	}
 	/*
@@ -1494,10 +1486,10 @@
 	char *	RIORelID = RELEASE_ID;
 	int		host;
 
-	rio_dprint(RIO_DEBUG_INIT, ("RIO : Release: %s ID: %s\n", RIORelease, RIORelID));
+	rio_dprintk (RIO_DEBUG_INIT, "RIO : Release: %s ID: %s\n", RIORelease, RIORelID);
 
 	if ( p->RIONumHosts==0 ) {
-		rio_dprint(RIO_DEBUG_INIT, ("\nNo Hosts configured\n"));
+		rio_dprintk (RIO_DEBUG_INIT, "\nNo Hosts configured\n");
 		return(0);
 	}
 
@@ -1505,7 +1497,7 @@
 		struct Host *HostP = &p->RIOHosts[host];
 		switch ( HostP->Type ) {
 			case RIO_AT:
-				rio_dprint(RIO_DEBUG_INIT, ("AT BUS : found the card at 0x%x\n", HostP->PaddrP));
+				rio_dprintk (RIO_DEBUG_INIT, "AT BUS : found the card at 0x%x\n", HostP->PaddrP);
 		}
 	}
 	return 0;
@@ -1587,17 +1579,17 @@
 	/*
 	** Reset the Tpu
 	*/
-	rio_dprint(RIO_DEBUG_INIT,  ("RIOHostReset: type 0x%x", Type ) );
+	rio_dprintk (RIO_DEBUG_INIT,  "RIOHostReset: type 0x%x", Type);
 	switch ( Type ) {
 		case RIO_AT:
-			rio_dprint(RIO_DEBUG_INIT, (" (RIO_AT)\n"));
+			rio_dprintk (RIO_DEBUG_INIT, " (RIO_AT)\n");
 			WBYTE(DpRamP->DpControl,  BOOT_FROM_RAM | EXTERNAL_BUS_OFF | 
 					  INTERRUPT_DISABLE | BYTE_OPERATION |
 					  SLOW_LINKS | SLOW_AT_BUS);
 			WBYTE(DpRamP->DpResetTpu, 0xFF);
 			rio_udelay (3);
 
-			rio_dprint(RIO_DEBUG_INIT,  ("RIOHostReset: Don't know if it worked. Try reset again\n") );
+			rio_dprintk (RIO_DEBUG_INIT,  "RIOHostReset: Don't know if it worked. Try reset again\n");
 			WBYTE(DpRamP->DpControl,  BOOT_FROM_RAM | EXTERNAL_BUS_OFF |
 					  INTERRUPT_DISABLE | BYTE_OPERATION |
 					  SLOW_LINKS | SLOW_AT_BUS);
@@ -1630,7 +1622,7 @@
 		break;
 #endif
 	case RIO_PCI:
-		rio_dprint(RIO_DEBUG_INIT,  (" (RIO_PCI)\n") );
+		rio_dprintk (RIO_DEBUG_INIT, " (RIO_PCI)\n");
 		DpRamP->DpControl  = RIO_PCI_BOOT_FROM_RAM;
 		DpRamP->DpResetInt = 0xFF;
 		DpRamP->DpResetTpu = 0xFF;
@@ -1645,7 +1637,7 @@
 #endif
 
 	default:
-		rio_dprint(RIO_DEBUG_INIT,  (" (UNKNOWN)\n") );
+		rio_dprintk (RIO_DEBUG_INIT, " (UNKNOWN)\n");
 		break;
 	}
 	return;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/riointr.c linux.17p18/drivers/char/rio/riointr.c
--- linux.vanilla/drivers/char/rio/riointr.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/riointr.c	Wed Aug  9 22:24:45 2000
@@ -35,7 +35,6 @@
 
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -191,8 +190,8 @@
   tty = PortP->gs.tty;
 
 
-  rio_dprint (RIO_DEBUG_INTR, ("tx port %d: %d chars queued.\n", 
-	      PortP->PortNum, PortP->gs.xmit_cnt));
+  rio_dprintk (RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", 
+	      PortP->PortNum, PortP->gs.xmit_cnt);
 
   if (!PortP->gs.xmit_cnt) return;
   
@@ -216,10 +215,10 @@
     { int t;
     t = (c > 10)?10:c;
     
-    rio_dprint (RIO_DEBUG_INTR, ("tx port %d: copying %d chars: %s - %s\n", 
-				 PortP->PortNum, c, 
-	 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail      , t),
-	 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t)));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: tx port %d: copying %d chars: %s - %s\n", 
+		 PortP->PortNum, c, 
+		 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail      , t),
+		 firstchars (PortP->gs.xmit_buf + PortP->gs.xmit_tail + c-t, t));
     }
     /* If for one reason or another, we can't copy more data, 
        we're done! */
@@ -245,16 +244,15 @@
   rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 
   if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2*PKT_MAX_DATA_LEN)) {
-    rio_dprint (RIO_DEBUG_INTR, ("Waking up.... ldisc:%d (%d/%d)....",
+    rio_dprintk (RIO_DEBUG_INTR, "Waking up.... ldisc:%d (%d/%d)....",
 		 (int)(PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)),
-		 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); 
+		 PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); 
     if ((PortP->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 	PortP->gs.tty->ldisc.write_wakeup)
       (PortP->gs.tty->ldisc.write_wakeup)(PortP->gs.tty);
-    rio_dprint (RIO_DEBUG_INTR, ("(%d/%d)\n",
-		PortP->gs.wakeup_chars, PortP->gs.xmit_cnt)); 
+    rio_dprintk (RIO_DEBUG_INTR, "(%d/%d)\n",
+		PortP->gs.wakeup_chars, PortP->gs.xmit_cnt); 
     wake_up_interruptible(&PortP->gs.tty->write_wait);
-    wake_up_interruptible(&PortP->gs.tty->poll_wait);
   }
 
 }
@@ -275,7 +273,7 @@
 	for ( host=0; host<p->RIONumHosts; host++ ) {
 		struct Host *HostP = &p->RIOHosts[host];
 
-		rio_dprint(RIO_DEBUG_INTR,  ("riointr() doing host %d type %d\n", host, HostP->Type ) );
+		rio_dprintk (RIO_DEBUG_INTR,  "riointr() doing host %d type %d\n", host, HostP->Type);
 
 		switch( HostP->Type ) {
 			case RIO_AT:
@@ -365,7 +363,7 @@
     static int t =0;
     rio_spin_unlock (&HostP->HostLock); 
     if ((t++ % 200) == 0)
-      rio_dprint(RIO_DEBUG_INTR, ("Interrupt but host not running. flags=%x.\n", (int)HostP->Flags));
+      rio_dprintk (RIO_DEBUG_INTR, "Interrupt but host not running. flags=%x.\n", (int)HostP->Flags);
     return;
   }
   rio_spin_unlock (&HostP->HostLock); 
@@ -374,7 +372,7 @@
     WWORD( HostP->ParmMapP->rup_intr , 0 );
     p->RIORupCount++;
     RupIntr++;
-    rio_dprint(RIO_DEBUG_INTR, ("RUP interrupt on host %d\n", HostP-p->RIOHosts ));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: RUP interrupt on host %d\n", HostP-p->RIOHosts);
     RIOPollHostCommands(p, HostP );
   }
 
@@ -385,7 +383,7 @@
     p->RIORxCount++;
     RxIntr++;
 
-    rio_dprint(RIO_DEBUG_INTR, ("RX interrupt on host %d\n", HostP-p->RIOHosts));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: RX interrupt on host %d\n", HostP-p->RIOHosts);
     /*
     ** Loop through every port. If the port is mapped into
     ** the system ( i.e. has /dev/ttyXXXX associated ) then it is
@@ -453,7 +451,7 @@
 				** MAGIC! ( Basically, handshake the RX buffer, so that
 				** the RTAs upstream can be re-enabled. )
 				*/
-	rio_dprint(RIO_DEBUG_INTR, ("Set RX handshake bit\n" ));
+	rio_dprintk (RIO_DEBUG_INTR, "Set RX handshake bit\n");
 	WWORD( PortP->PhbP->handshake, 
 	       PHB_HANDSHAKE_SET|PHB_HANDSHAKE_RESET );
       }
@@ -468,7 +466,7 @@
 
     p->RIOTxCount++;
     TxIntr++;
-    rio_dprint(RIO_DEBUG_INTR, ("TX interrupt on host %d\n", HostP-p->RIOHosts));
+    rio_dprintk (RIO_DEBUG_INTR, "rio: TX interrupt on host %d\n", HostP-p->RIOHosts);
 
     /*
     ** Loop through every port.
@@ -506,7 +504,7 @@
 	continue;
       }
 
-      rio_dprint (RIO_DEBUG_INTR, ("Looking into port %d.\n", port));
+      rio_dprintk (RIO_DEBUG_INTR, "rio: Looking into port %d.\n", port);
       /*
       ** Lock the port before we begin working on it.
       */
@@ -517,7 +515,7 @@
       ** we need do none of this processing.
       */
       if ( !can_add_transmit( &PacketP, PortP ) ) {
-	rio_dprint (RIO_DEBUG_INTR, ("Can't add to port, so skipping.\n"));
+	rio_dprintk (RIO_DEBUG_INTR, "Can't add to port, so skipping.\n");
 	rio_spin_unlock(&PortP->portSem);
 	continue;
       }
@@ -529,7 +527,7 @@
       ttyP = PortP->gs.tty;
       /* If ttyP is NULL, the port is getting closed. Forget about it. */
       if (!ttyP) {
-	rio_dprint (RIO_DEBUG_INTR, ("no tty, so skipping.\n"));
+	rio_dprintk (RIO_DEBUG_INTR, "no tty, so skipping.\n");
 	rio_spin_unlock(&PortP->portSem);
 	continue;
       }
@@ -605,10 +603,10 @@
 	** with WFLUSH
 	*/
 	if ( PortP->WflushFlag ) {
-	  rio_dprint(RIO_DEBUG_INTR, ("Want to WFLUSH mark this port\n"));
+	  rio_dprintk (RIO_DEBUG_INTR, "Want to WFLUSH mark this port\n");
 
 	  if ( PortP->InUse )
-	    rio_dprint(RIO_DEBUG_INTR, ("FAILS - PORT IS IN USE\n"));
+	    rio_dprintk (RIO_DEBUG_INTR, "FAILS - PORT IS IN USE\n");
 	}
 				
 	while ( PortP->WflushFlag &&
@@ -617,7 +615,7 @@
 	  int p;
 	  struct PktCmd *PktCmdP;
 
-	  rio_dprint(RIO_DEBUG_INTR, ("Add WFLUSH marker to data queue\n"));
+	  rio_dprintk (RIO_DEBUG_INTR, "Add WFLUSH marker to data queue\n");
 	  /*
 	  ** make it look just like a WFLUSH command
 	  */
@@ -672,8 +670,8 @@
 	    PortP->MagicFlags &= ~MAGIC_FLUSH;
 	  }
 
-	  rio_dprint(RIO_DEBUG_INTR, ("Wflush count now stands at %d\n", 
-		 PortP->WflushFlag));
+	  rio_dprintk (RIO_DEBUG_INTR, "Wflush count now stands at %d\n", 
+		 PortP->WflushFlag);
 	}
 	if ( PortP->MagicFlags & MORE_OUTPUT_EYGOR ) {
 	  if ( PortP->MagicFlags & MAGIC_FLUSH ) {
@@ -749,12 +747,12 @@
 
   TtyP = PortP->gs.tty;
   if (!TtyP) {
-    rio_dprint (RIO_DEBUG_INTR, ("RIOReceive: tty is null. \n"));
+    rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
     return;
   }
 
   if (PortP->State & RIO_THROTTLE_RX) {
-    rio_dprint (RIO_DEBUG_INTR, ("RIOReceive: Throttled. Can't handle more input.\n"));
+    rio_dprintk (RIO_DEBUG_INTR, "RIOReceive: Throttled. Can't handle more input.\n");
     return;
   }
 
@@ -788,18 +786,18 @@
 	  ** check that it is not a command!
 	  */
 	  if ( PacketP->len & PKT_CMD_BIT ) {
-	    rio_dprint(RIO_DEBUG_INTR, ("RIO: unexpected command packet received on PHB\n"));
+	    rio_dprintk (RIO_DEBUG_INTR, "RIO: unexpected command packet received on PHB\n");
 	    /*	    rio_dprint(RIO_DEBUG_INTR, (" sysport   = %d\n", p->RIOPortp->PortNum)); */
-	    rio_dprint(RIO_DEBUG_INTR, (" dest_unit = %d\n", PacketP->dest_unit));
-	    rio_dprint(RIO_DEBUG_INTR, (" dest_port = %d\n", PacketP->dest_port));
-	    rio_dprint(RIO_DEBUG_INTR, (" src_unit  = %d\n", PacketP->src_unit));
-	    rio_dprint(RIO_DEBUG_INTR, (" src_port  = %d\n", PacketP->src_port));
-	    rio_dprint(RIO_DEBUG_INTR, (" len	   = %d\n", PacketP->len));
-	    rio_dprint(RIO_DEBUG_INTR, (" control   = %d\n", PacketP->control));
-	    rio_dprint(RIO_DEBUG_INTR, (" csum	   = %d\n", PacketP->csum));
-	    rio_dprint(RIO_DEBUG_INTR, ("	 data bytes: "));
+	    rio_dprintk (RIO_DEBUG_INTR, " dest_unit = %d\n", PacketP->dest_unit);
+	    rio_dprintk (RIO_DEBUG_INTR, " dest_port = %d\n", PacketP->dest_port);
+	    rio_dprintk (RIO_DEBUG_INTR, " src_unit  = %d\n", PacketP->src_unit);
+	    rio_dprintk (RIO_DEBUG_INTR, " src_port  = %d\n", PacketP->src_port);
+	    rio_dprintk (RIO_DEBUG_INTR, " len	   = %d\n", PacketP->len);
+	    rio_dprintk (RIO_DEBUG_INTR, " control   = %d\n", PacketP->control);
+	    rio_dprintk (RIO_DEBUG_INTR, " csum	   = %d\n", PacketP->csum);
+	    rio_dprintk (RIO_DEBUG_INTR, "	 data bytes: ");
 	    for ( DataCnt=0; DataCnt<PKT_MAX_DATA_LEN; DataCnt++ )
-	      rio_dprint(RIO_DEBUG_INTR, ("%d\n", PacketP->data[DataCnt]));
+	      rio_dprintk (RIO_DEBUG_INTR, "%d\n", PacketP->data[DataCnt]);
 	    remove_receive( PortP );
 	    put_free_end( PortP->HostP, PacketP );
 	    continue; /* with next packet */
@@ -822,8 +820,8 @@
 			
 	  transCount = min(PacketP->len & PKT_LEN_MASK,
 			   TTY_FLIPBUF_SIZE - TtyP->flip.count);
-	  rio_dprint(RIO_DEBUG_REC,  ("port %d: Copy %d bytes\n", 
-				      PortP->PortNum, transCount ) );
+	  rio_dprintk (RIO_DEBUG_REC,  "port %d: Copy %d bytes\n", 
+				      PortP->PortNum, transCount);
 	  /*
 	  ** To use the following 'kkprintfs' for debugging - change the '#undef'
 	  ** to '#define', (this is the only place ___DEBUG_IT___ occurs in the
@@ -882,7 +880,7 @@
 	}
     }
   if (copied) {
-    rio_dprint ( RIO_DEBUG_REC, ("port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum,  copied));
+    rio_dprintk (RIO_DEBUG_REC, "port %d: pushing tty flip buffer: %d total bytes copied.\n", PortP->PortNum, copied);
     tty_flip_buffer_push (TtyP);
   }
 
@@ -908,25 +906,25 @@
 	SysPort = port;	/* Believe me, it works. */
 
 	if ( SysPort < 0 || SysPort >= RIO_PORTS ) {
-		rio_dprint(RIO_DEBUG_INTR, ("Illegal port %d derived from TTY in riotproc()\n",SysPort));
+		rio_dprintk (RIO_DEBUG_INTR, "Illegal port %d derived from TTY in riotproc()\n",SysPort);
 		return 0;
 	}
 	PortP = p->RIOPortp[SysPort];
 
 	if ((uint)PortP->PhbP < (uint)PortP->Caddr || 
 			(uint)PortP->PhbP >= (uint)PortP->Caddr+SIXTY_FOUR_K ) {
-		rio_dprint(RIO_DEBUG_INTR, ("RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
-							SysPort));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP = 0x%x\n",PortP));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP->PhbP = 0x%x\n",PortP->PhbP));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP->Caddr = 0x%x\n",PortP->PhbP));
-		rio_dprint(RIO_DEBUG_INTR, ("	 PortP->HostPort = 0x%x\n",PortP->HostPort));
+		rio_dprintk (RIO_DEBUG_INTR, "RIO: NULL or BAD PhbP on sys port %d in proc routine\n",
+							SysPort);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP = 0x%x\n",PortP);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->PhbP = 0x%x\n",PortP->PhbP);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->Caddr = 0x%x\n",PortP->PhbP);
+		rio_dprintk (RIO_DEBUG_INTR, "	 PortP->HostPort = 0x%x\n",PortP->HostPort);
 		return 0;
 	}
 
 	switch(cmd) {
 		case T_WFLUSH:
-			rio_dprint(RIO_DEBUG_INTR, "T_WFLUSH\n");
+			rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH\n");
 			/*
 			** Because of the spooky way the RIO works, we don't need
 			** to issue a flush command on any of the SET*F commands,
@@ -943,14 +941,14 @@
 				** form a wflush packet - 1 byte long, no data
 				*/
 				if ( PortP->State & RIO_DELETED ) {
-					rio_dprint(RIO_DEBUG_INTR, ("WFLUSH on deleted RTA\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "WFLUSH on deleted RTA\n");
 				}
 				else {
 					if ( RIOPreemptiveCmd(p, PortP, WFLUSH ) == RIO_FAIL ) {
-						rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command failed\n"));
+						rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command failed\n");
 					}
 					else
-						rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command\n"));
+						rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command\n");
 				}
 				/*
 				** WFLUSH operation - flush the data!
@@ -958,7 +956,7 @@
 				PortP->TxBufferIn = PortP->TxBufferOut = 0;
 			}
 			else {
-				rio_dprint(RIO_DEBUG_INTR, ("T_WFLUSH Command ignored\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "T_WFLUSH Command ignored\n");
 			}
 			/*
 			** sort out the line discipline
@@ -968,16 +966,16 @@
 			break;
 	
 		case T_RESUME:
-			rio_dprint(RIO_DEBUG_INTR, ("T_RESUME\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_RESUME\n");
 			/*
 			** send pre-emptive resume packet
 			*/
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("RESUME on deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "RESUME on deleted RTA\n");
 			}
 			else {
 				if ( RIOPreemptiveCmd(p, PortP, RESUME ) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_INTR, ("T_RESUME Command failed\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "T_RESUME Command failed\n");
 				}
 			}
 			/*
@@ -988,7 +986,7 @@
 			break;
 	
 		case T_TIME:
-			rio_dprint(RIO_DEBUG_INTR, ("T_TIME\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_TIME\n");
 			/*
 			** T_TIME is called when xDLY is set in oflags and
 			** the line discipline timeout has expired. It's
@@ -1010,16 +1008,16 @@
 			break;
 	
 		case T_SUSPEND:
-			rio_dprint(RIO_DEBUG_INTR, ("T_SUSPEND\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND\n");
 			/*
 			** send a suspend pre-emptive packet.
 			*/
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("SUSPEND deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "SUSPEND deleted RTA\n");
 			}
 			else {
 				if ( RIOPreemptiveCmd(p, PortP, SUSPEND ) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_INTR, ("T_SUSPEND Command failed\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "T_SUSPEND Command failed\n");
 				}
 			}
 			/*
@@ -1028,18 +1026,18 @@
 			break;
 	
 		case T_BLOCK:
-			rio_dprint(RIO_DEBUG_INTR, ("T_BLOCK\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_BLOCK\n");
 			break;
 	
 		case T_RFLUSH:
-			rio_dprint(RIO_DEBUG_INTR, ("T_RFLUSH\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH\n");
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("RFLUSH on deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "RFLUSH on deleted RTA\n");
 				PortP->RxDataStart = 0;
 			}
 			else {
 				if ( RIOPreemptiveCmd( p, PortP, RFLUSH ) == RIO_FAIL ) {
-					rio_dprint(RIO_DEBUG_INTR, ("T_RFLUSH Command failed\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "T_RFLUSH Command failed\n");
 					return 0;
 				}
 				PortP->RxDataStart = 0;
@@ -1052,14 +1050,14 @@
 					/*
 					** MAGIC!
 					*/
-					rio_dprint(RIO_DEBUG_INTR, ("Set receive handshake bit\n"));
+					rio_dprintk (RIO_DEBUG_INTR, "Set receive handshake bit\n");
 					PortP->PhbP->handshake |= PHB_HANDSHAKE_RESET;
 				}
 			}
 			break;
 			/* FALLTHROUGH */
 		case T_UNBLOCK:
-			rio_dprint(RIO_DEBUG_INTR, ("T_UNBLOCK\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_UNBLOCK\n");
 			/*
 			** If there is any data to receive set a timeout to service it.
 			*/
@@ -1067,7 +1065,7 @@
 			break;
 	
 		case T_BREAK:
-			rio_dprint(RIO_DEBUG_INTR, ("T_BREAK\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "T_BREAK\n");
 			/*
 			** Send a break command. For Sys V
 			** this is a timed break, so we
@@ -1077,12 +1075,12 @@
 			** Build a BREAK command
 			*/
 			if ( PortP->State & RIO_DELETED ) {
-				rio_dprint(RIO_DEBUG_INTR, ("BREAK on deleted RTA\n"));
+				rio_dprintk (RIO_DEBUG_INTR, "BREAK on deleted RTA\n");
 			}
 			else {
 				if (RIOShortCommand(PortP,SBREAK,2,
 								p->RIOConf.BreakInterval)==RIO_FAIL) {
-			   		rio_dprint(RIO_DEBUG_INTR, ("SBREAK RIOShortCommand failed\n"));
+			   		rio_dprintk (RIO_DEBUG_INTR, "SBREAK RIOShortCommand failed\n");
 				}
 			}
 	
@@ -1092,18 +1090,18 @@
 			break;
 	
 		case T_INPUT:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc T_INPUT called - I don't know what to do!\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc T_INPUT called - I don't know what to do!\n");
 			break;
 		case T_PARM:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc T_PARM called - I don't know what to do!\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc T_PARM called - I don't know what to do!\n");
 			break;
 	
 		case T_SWTCH:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc T_SWTCH called - I don't know what to do!\n"));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc T_SWTCH called - I don't know what to do!\n");
 			break;
 	
 		default:
-			rio_dprint(RIO_DEBUG_INTR, ("Proc UNKNOWN command %d\n",cmd));
+			rio_dprintk (RIO_DEBUG_INTR, "Proc UNKNOWN command %d\n",cmd);
 	}
 	/*
 	** T_OUTPUT returns without passing through this point!
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rioparam.c linux.17p18/drivers/char/rio/rioparam.c
--- linux.vanilla/drivers/char/rio/rioparam.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/rioparam.c	Wed Aug  9 22:24:45 2000
@@ -35,7 +35,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -177,13 +176,18 @@
 	int		retries = 0xff;
 	unsigned long flags;
 
+	func_enter ();
+
 	TtyP = PortP->gs.tty;
 
-	rio_dprint(RIO_DEBUG_PARAM, ("RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
-	    PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP) );
+	rio_dprintk (RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n",
+	    PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
 
 	if (!TtyP) {
-	  rio_dprint (RIO_DEBUG_PARAM, ("Can't call rioparam with null tty.\n"));
+	  rio_dprintk (RIO_DEBUG_PARAM, "Can't call rioparam with null tty.\n");
+
+	  func_exit ();
+
 	  return RIO_FAIL;
 	}
 	rio_spin_lock_irqsave(&PortP->portSem, flags );
@@ -206,7 +210,7 @@
 			PortP->FirstOpen = 0;
 		}
 		else if (PortP->Store || PortP->Lock) {
-			rio_dprint(RIO_DEBUG_PARAM, ("OPEN: Restoring stored/locked params\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "OPEN: Restoring stored/locked params\n");
 			TtyP->tm.c_iflag = PortP->StoredTty.iflag;
 			TtyP->tm.c_oflag = PortP->StoredTty.oflag;
 			TtyP->tm.c_cflag = PortP->StoredTty.cflag;
@@ -227,41 +231,49 @@
 			break;
 		}
 		if ( PortP->InUse != NOT_INUSE ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Port IN_USE for pre-emptive command\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Port IN_USE for pre-emptive command\n");
 		}
 
 		if ( !res ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Port has no space on transmit queue\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Port has no space on transmit queue\n");
 		}
 
 		if ( SleepFlag != OK_TO_SLEEP ) {
 			rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+			func_exit();
+			
 			return RIO_FAIL;
 		}
 
-		rio_dprint(RIO_DEBUG_PARAM, ("wait for can_add_transmit\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit\n");
 		rio_spin_unlock_irqrestore( &PortP->portSem, flags);
 		retval = RIODelay(PortP, HUNDRED_MS);
 		rio_spin_lock_irqsave( &PortP->portSem, flags);
 		if (retval == RIO_FAIL) {
-			rio_dprint(RIO_DEBUG_PARAM, ("wait for can_add_transmit broken by signal\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "wait for can_add_transmit broken by signal\n");
 			rio_spin_unlock_irqrestore( &PortP->portSem, flags);
 			pseterr(EINTR);
+			func_exit();
+
 			return RIO_FAIL;
 		}
 		if ( PortP->State & RIO_DELETED ) {
 			rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+			func_exit ();
+
 			return RIO_SUCCESS;
 		}
 	}
 
 	if (!res) {
 		rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+		func_exit ();
+
 		return RIO_FAIL;
 	}
 
-	rio_dprint(RIO_DEBUG_PARAM, ("can_add_transmit() returns %x\n",res));
-	rio_dprint(RIO_DEBUG_PARAM, ("Packet is 0x%x\n",(int) PacketP));
+	rio_dprintk (RIO_DEBUG_PARAM, "can_add_transmit() returns %x\n",res);
+	rio_dprintk (RIO_DEBUG_PARAM, "Packet is 0x%x\n",(int) PacketP);
 
 	phb_param_ptr = (struct phb_param *)PacketP->data;
 
@@ -271,7 +283,7 @@
 	** COR 1
 	*/
 	if ( TtyP->tm.c_iflag & INPCK ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Parity checking on input enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Parity checking on input enabled\n");
 		Cor1 |= COR1_INPCK;
 	}
 #endif
@@ -279,53 +291,53 @@
 	switch ( TtyP->termios->c_cflag & CSIZE ) {
 		case CS5:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("5 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "5 bit data\n");
 			Cor1 |= COR1_5BITS;
 			break;
 		}
 		case CS6:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("6 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "6 bit data\n");
 			Cor1 |= COR1_6BITS;
 			break;
 		}
 		case CS7:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("7 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "7 bit data\n");
 			Cor1 |= COR1_7BITS;
 			break;
 		}
 		case CS8:
 		{
-			rio_dprint(RIO_DEBUG_PARAM, ("8 bit data\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "8 bit data\n");
 			Cor1 |= COR1_8BITS;
 			break;
 		}
 	}
 
 	if ( TtyP->termios->c_cflag & CSTOPB ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("2 stop bits\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "2 stop bits\n");
 		Cor1 |= COR1_2STOP;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("1 stop bit\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "1 stop bit\n");
 		Cor1 |= COR1_1STOP;
 	}
 
 	if ( TtyP->termios->c_cflag & PARENB ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable parity\n");
 		Cor1 |= COR1_NORMAL;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Disable parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Disable parity\n");
 		Cor1 |= COR1_NOP;
 	}
 	if ( TtyP->termios->c_cflag & PARODD ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Odd parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Odd parity\n");
 		Cor1 |= COR1_ODD;
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Even parity\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Even parity\n");
 		Cor1 |= COR1_EVEN; 
 	}
 
@@ -333,89 +345,89 @@
 	** COR 2
 	*/
 	if ( TtyP->termios->c_iflag & IXON ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable start/stop output control\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop output control\n");
 		Cor2 |= COR2_IXON;
 	}
 	else {
 		if ( PortP->Config & RIO_IXON ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Force enable start/stop output control\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Force enable start/stop output control\n");
 			Cor2 |= COR2_IXON;
 		}
 		else
-			rio_dprint(RIO_DEBUG_PARAM, ("IXON has been disabled.\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "IXON has been disabled.\n");
 	}
 
 	if (TtyP->termios->c_iflag & IXANY) {
 		if ( PortP->Config & RIO_IXANY ) {
-			rio_dprint(RIO_DEBUG_PARAM, ("Enable any key to restart output\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "Enable any key to restart output\n");
 			Cor2 |= COR2_IXANY;
 		}
 		else
-			rio_dprint(RIO_DEBUG_PARAM, ("IXANY has been disabled due to sanity reasons.\n"));
+			rio_dprintk (RIO_DEBUG_PARAM, "IXANY has been disabled due to sanity reasons.\n");
 	}
 
 	if ( TtyP->termios->c_iflag & IXOFF ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable start/stop input control 2\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable start/stop input control 2\n");
 		Cor2 |= COR2_IXOFF;
 	}
 
 	if ( TtyP->termios->c_cflag & HUPCL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Hangup on last close\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Hangup on last close\n");
 		Cor2 |= COR2_HUPCL;
 	}
 
 	if ( C_CRTSCTS (TtyP)) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Rx hardware flow control enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control enabled\n");
 		Cor2 |= COR2_CTSFLOW;
 		Cor2 |= COR2_RTSFLOW;
 	} else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Rx hardware flow control disabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Rx hardware flow control disabled\n");
 		Cor2 &= ~COR2_CTSFLOW;
 		Cor2 &= ~COR2_RTSFLOW;
 	}
 
 
 	if ( TtyP->termios->c_cflag & CLOCAL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Local line\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Local line\n");
 	}
 	else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Possible Modem line\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Possible Modem line\n");
 	}
 
 	/*
 	** COR 4 (there is no COR 3)
 	*/
 	if ( TtyP->termios->c_iflag & IGNBRK ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Ignore break condition\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Ignore break condition\n");
 		Cor4 |= COR4_IGNBRK;
 	}
 	if ( !(TtyP->termios->c_iflag & BRKINT) ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Break generates NULL condition\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Break generates NULL condition\n");
 		Cor4 |= COR4_NBRKINT;
 	} else {
-		rio_dprint(RIO_DEBUG_PARAM, ("Interrupt on	break condition\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Interrupt on	break condition\n");
 	}
 
 	if ( TtyP->termios->c_iflag & INLCR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map newline to carriage return on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage return on input\n");
 		Cor4 |= COR4_INLCR;
 	}
 
 	if ( TtyP->termios->c_iflag & IGNCR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Ignore carriage return on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Ignore carriage return on input\n");
 		Cor4 |= COR4_IGNCR;
 	}
 
 	if ( TtyP->termios->c_iflag & ICRNL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map carriage return to newline on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on input\n");
 		Cor4 |= COR4_ICRNL;
 	}
 	if ( TtyP->termios->c_iflag & IGNPAR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Ignore characters with parity errors\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Ignore characters with parity errors\n");
 		Cor4 |= COR4_IGNPAR;
 	}
 	if ( TtyP->termios->c_iflag & PARMRK ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Mark parity errors\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Mark parity errors\n");
 		Cor4 |= COR4_PARMRK;
 	}
 
@@ -445,24 +457,24 @@
 	** Could set LNE here if you wanted LNext processing. SVR4 will use it.
 	*/
 	if ( TtyP->termios->c_iflag & ISTRIP ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Strip input characters\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Strip input characters\n");
 		if (! (PortP->State & RIO_TRIAD_MODE)) {
 			Cor5 |= COR5_ISTRIP;
 		}
 	}
 
 	if ( TtyP->termios->c_oflag & ONLCR ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map newline to carriage-return, newline on output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map newline to carriage-return, newline on output\n");
 		if ( PortP->CookMode == COOK_MEDIUM )
 			Cor5 |= COR5_ONLCR;
 	}
 	if ( TtyP->termios->c_oflag & OCRNL ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Map carriage return to newline on output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map carriage return to newline on output\n");
 		if ( PortP->CookMode == COOK_MEDIUM )
 			Cor5 |= COR5_OCRNL;
 	}
 	if ( ( TtyP->termios->c_oflag & TABDLY) == TAB3 ) {
-		rio_dprint(RIO_DEBUG_PARAM, ("Tab delay 3 set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Tab delay 3 set\n");
 		if ( PortP->CookMode == COOK_MEDIUM )
 			Cor5 |= COR5_TAB3;
 	}
@@ -482,8 +494,8 @@
 	/*
 	** Baud rate bytes
 	*/
-	rio_dprint(RIO_DEBUG_PARAM, ("Mapping of rx/tx baud %x (%x)\n", 
-				     TtyP->termios->c_cflag, CBAUD));
+	rio_dprintk (RIO_DEBUG_PARAM, "Mapping of rx/tx baud %x (%x)\n", 
+				     TtyP->termios->c_cflag, CBAUD);
 
 	switch (TtyP->termios->c_cflag & CBAUD) {
 #define e(b) case B ## b : RxBaud = TxBaud = RIO_B ## b ;break
@@ -495,77 +507,77 @@
 	/* XXX MIssing conversion table. XXX */
 	/* 	 (TtyP->termios->c_cflag & V_CBAUD); */
 
-	rio_dprint(RIO_DEBUG_PARAM, ("tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud));
+	rio_dprintk (RIO_DEBUG_PARAM, "tx baud 0x%x, rx baud 0x%x\n", TxBaud, RxBaud);
 
 
 	/*
 	** Leftovers
 	*/
 	if ( TtyP->termios->c_cflag & CREAD )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable receiver\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable receiver\n");
 #ifdef RCV1EN
 	if ( TtyP->termios->c_cflag & RCV1EN )
-		rio_dprint(RIO_DEBUG_PARAM, ("RCV1EN (?)\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "RCV1EN (?)\n");
 #endif
 #ifdef XMT1EN
 	if ( TtyP->termios->c_cflag & XMT1EN )
-		rio_dprint(RIO_DEBUG_PARAM, ("XMT1EN (?)\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "XMT1EN (?)\n");
 #endif
 #if 0
 	if ( TtyP->termios->c_cflag & LOBLK )
-		rio_dprint(RIO_DEBUG_PARAM, ("LOBLK - JCL output blocks when not current\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "LOBLK - JCL output blocks when not current\n");
 #endif
 	if ( TtyP->termios->c_lflag & ISIG )
-		rio_dprint(RIO_DEBUG_PARAM, ("Input character signal generating enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Input character signal generating enabled\n");
 	if ( TtyP->termios->c_lflag & ICANON )
-		rio_dprint(RIO_DEBUG_PARAM, ("Canonical input: erase and kill enabled\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Canonical input: erase and kill enabled\n");
 	if ( TtyP->termios->c_lflag & XCASE )
-		rio_dprint(RIO_DEBUG_PARAM, ("Canonical upper/lower presentation\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Canonical upper/lower presentation\n");
 	if ( TtyP->termios->c_lflag & ECHO )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable input echo\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable input echo\n");
 	if ( TtyP->termios->c_lflag & ECHOE )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable echo erase\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable echo erase\n");
 	if ( TtyP->termios->c_lflag & ECHOK )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable echo kill\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable echo kill\n");
 	if ( TtyP->termios->c_lflag & ECHONL )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable echo newline\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable echo newline\n");
 	if ( TtyP->termios->c_lflag & NOFLSH )
-		rio_dprint(RIO_DEBUG_PARAM, ("Disable flush after interrupt or quit\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Disable flush after interrupt or quit\n");
 #ifdef TOSTOP
 	if ( TtyP->termios->c_lflag & TOSTOP )
-		rio_dprint(RIO_DEBUG_PARAM, ("Send SIGTTOU for background output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Send SIGTTOU for background output\n");
 #endif
 #ifdef XCLUDE
 	if ( TtyP->termios->c_lflag & XCLUDE )
-		rio_dprint(RIO_DEBUG_PARAM, ("Exclusive use of this line\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Exclusive use of this line\n");
 #endif
 	if ( TtyP->termios->c_iflag & IUCLC )
-		rio_dprint(RIO_DEBUG_PARAM, ("Map uppercase to lowercase on input\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map uppercase to lowercase on input\n");
 	if ( TtyP->termios->c_oflag & OPOST )
-		rio_dprint(RIO_DEBUG_PARAM, ("Enable output post-processing\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Enable output post-processing\n");
 	if ( TtyP->termios->c_oflag & OLCUC )
-		rio_dprint(RIO_DEBUG_PARAM, ("Map lowercase to uppercase on output\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Map lowercase to uppercase on output\n");
 	if ( TtyP->termios->c_oflag & ONOCR )
-		rio_dprint(RIO_DEBUG_PARAM, ("No carriage return output at column 0\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "No carriage return output at column 0\n");
 	if ( TtyP->termios->c_oflag & ONLRET )
-		rio_dprint(RIO_DEBUG_PARAM, ("Newline performs carriage return function\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Newline performs carriage return function\n");
 	if ( TtyP->termios->c_oflag & OFILL )
-		rio_dprint(RIO_DEBUG_PARAM, ("Use fill characters for delay\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Use fill characters for delay\n");
 	if ( TtyP->termios->c_oflag & OFDEL )
-		rio_dprint(RIO_DEBUG_PARAM, ("Fill character is DEL\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Fill character is DEL\n");
 	if ( TtyP->termios->c_oflag & NLDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Newline delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Newline delay set\n");
 	if ( TtyP->termios->c_oflag & CRDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Carriage return delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Carriage return delay set\n");
 	if ( TtyP->termios->c_oflag & TABDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Tab delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Tab delay set\n");
 #if 0
 	if ( TtyP->termios->c_oflag & BSDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Back-space delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Back-space delay set\n");
 	if ( TtyP->termios->c_oflag & VTDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Vertical tab delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Vertical tab delay set\n");
 	if ( TtyP->termios->c_oflag & FFDLY )
-		rio_dprint(RIO_DEBUG_PARAM, ("Form-feed delay set\n"));
+		rio_dprintk (RIO_DEBUG_PARAM, "Form-feed delay set\n");
 #endif
 	/*
 	** These things are kind of useful in a later life!
@@ -574,6 +586,8 @@
 
 	if ( PortP->State & RIO_DELETED ) {
 		rio_spin_unlock_irqrestore( &PortP->portSem, flags);
+		func_exit ();
+
 		return RIO_FAIL;
 	}
 
@@ -611,10 +625,12 @@
 
 	rio_spin_unlock_irqrestore( &PortP->portSem, flags);
 
-	rio_dprint(RIO_DEBUG_PARAM, ("add_transmit returned.\n"));
+	rio_dprintk (RIO_DEBUG_PARAM, "add_transmit returned.\n");
 	/*
 	** job done.
 	*/
+	func_exit ();
+
 	return RIO_SUCCESS;
 }
 
@@ -645,7 +661,7 @@
 struct Port *PortP; 
 {
   if (RWORD(*PortP->TxAdd) & PKT_IN_USE) {
-    rio_dprint (RIO_DEBUG_PARAM, ("add_transmit: Packet has been stolen!"));
+    rio_dprintk (RIO_DEBUG_PARAM, "add_transmit: Packet has been stolen!");
   }
 	WWORD( *(ushort *)PortP->TxAdd, RWORD(*PortP->TxAdd) | PKT_IN_USE);
 	PortP->TxAdd = (PortP->TxAdd == PortP->TxEnd) ? PortP->TxStart : 
@@ -673,7 +689,7 @@
 	*
 	************************************************/
 
-	rio_dprint(RIO_DEBUG_PFE, ("put_free_end(PktP=%x)\n",(int)PktP));
+	rio_dprintk (RIO_DEBUG_PFE,  "put_free_end(PktP=%x)\n",(int)PktP);
 
 	if ((old_end=RWORD(HostP->ParmMapP->free_list_end)) != TPNULL) {
 		new_end = RIO_OFF(HostP->Caddr,PktP);
@@ -684,12 +700,13 @@
 		WWORD(HostP->ParmMapP->free_list_end, new_end);
 	}
 	else {	/* First packet on the free list this should never happen! */
-		rio_dprint(RIO_DEBUG_PFE, ("put_free_end(): This should never happen\n"));
+		rio_dprintk (RIO_DEBUG_PFE, "put_free_end(): This should never happen\n");
 		WWORD(HostP->ParmMapP->free_list_end , RIO_OFF(HostP->Caddr,PktP));
 		tmp_pointer = (FREE_LIST *)PktP;
 		WWORD(tmp_pointer->prev , TPNULL);
 		WWORD(tmp_pointer->next , TPNULL);
 	}
+	rio_dprintk (RIO_DEBUG_CMD, "Before unlock: %p\n", &HostP->HostLock);
 	rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/rioroute.c linux.17p18/drivers/char/rio/rioroute.c
--- linux.vanilla/drivers/char/rio/rioroute.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/rioroute.c	Wed Aug  9 22:24:45 2000
@@ -34,7 +34,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -179,8 +178,8 @@
 
     if ( Lies )
     {
-      rio_dprint(RIO_DEBUG_ROUTE, ("LIES! DAMN LIES! %d LIES!\n",Lies));
-      rio_dprint(RIO_DEBUG_ROUTE, ("%d:%c %d:%c %d:%c %d:%c\n",
+      rio_dprintk (RIO_DEBUG_ROUTE, "LIES! DAMN LIES! %d LIES!\n",Lies);
+      rio_dprintk (RIO_DEBUG_ROUTE, "%d:%c %d:%c %d:%c %d:%c\n",
           RBYTE(PktCmdP->RouteTopology[0].Unit), 
 	  'A'+RBYTE(PktCmdP->RouteTopology[0].Link),
           RBYTE(PktCmdP->RouteTopology[1].Unit),
@@ -188,7 +187,7 @@
           RBYTE(PktCmdP->RouteTopology[2].Unit),
 	  'A'+RBYTE(PktCmdP->RouteTopology[2].Link),
           RBYTE(PktCmdP->RouteTopology[3].Unit),
-	  'A'+RBYTE(PktCmdP->RouteTopology[3].Link)));
+	  'A'+RBYTE(PktCmdP->RouteTopology[3].Link));
       return TRUE;
     }
 
@@ -220,11 +219,11 @@
 	     NewUnit != ROUTE_NO_ID &&
 	     NewUnit != ROUTE_INTERCONNECT )
 	{
-	    rio_dprint(RIO_DEBUG_ROUTE, ("I have a link from %s %s to unit %d:%d - I don't like it.\n",
+	    rio_dprintk (RIO_DEBUG_ROUTE, "I have a link from %s %s to unit %d:%d - I don't like it.\n",
 		  MyType,
 		  MyName,
 		  NewUnit,
-		  NewLink));
+		  NewLink);
 	}
 	else
 	{
@@ -249,8 +248,8 @@
 	    RIOConCon(p,HostP,ThisUnit,ThisLink,NewUnit,NewLink,CONNECT);
 
 	  if ( NewUnit == ROUTE_NO_ID )
-	    rio_dprint(RIO_DEBUG_ROUTE, ("%s %s (%c) is connected to an unconfigured unit.\n",
-		    MyType,MyName,'A'+ThisLink));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "%s %s (%c) is connected to an unconfigured unit.\n",
+		    MyType,MyName,'A'+ThisLink);
 
 	  if ( NewUnit == ROUTE_INTERCONNECT )
 	  {
@@ -268,14 +267,14 @@
 	    if ( HostP->Topology[OldLink].Unit == ThisUnit &&
 		 HostP->Topology[OldLink].Link == ThisLink )
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A'));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "SETTING HOST (%c) TO DISCONNECTED!\n", OldLink+'A');
 	      HostP->Topology[OldLink].Unit = ROUTE_DISCONNECT;
 	      HostP->Topology[OldLink].Link = NO_LINK;
 	    }
 	    else
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
-		    OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "HOST(%c) WAS NOT CONNECTED TO %s (%c)!\n",
+		    OldLink+'A',HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
 	    }
 	  }
 	  else if ( OldUnit <= MAX_RUP )
@@ -283,29 +282,29 @@
 	    if ( HostP->Mapping[OldUnit-1].Topology[OldLink].Unit == ThisUnit &&
 	         HostP->Mapping[OldUnit-1].Topology[OldLink].Link == ThisLink )
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("SETTING RTA %s (%c) TO DISCONNECTED!\n",
-				   HostP->Mapping[OldUnit-1].Name,OldLink+'A'));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "SETTING RTA %s (%c) TO DISCONNECTED!\n",
+				   HostP->Mapping[OldUnit-1].Name,OldLink+'A');
 	      HostP->Mapping[OldUnit-1].Topology[OldLink].Unit=ROUTE_DISCONNECT;
 	      HostP->Mapping[OldUnit-1].Topology[OldLink].Link=NO_LINK;
 	    }
 	    else
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
+	      rio_dprintk (RIO_DEBUG_ROUTE, "RTA %s (%c) WAS NOT CONNECTED TO %s (%c)\n",
 			    HostP->Mapping[OldUnit-1].Name,OldLink+'A',
-			    HostP->Mapping[ThisUnit-1].Name,ThisLink+'A'));
+			    HostP->Mapping[ThisUnit-1].Name,ThisLink+'A');
 	    }
 	  }
 	  if ( NewUnit == HOST_ID )
 	  {
-	    rio_dprint(RIO_DEBUG_ROUTE, ("MARKING HOST (%c) CONNECTED TO %s (%c)\n",
-				NewLink+'A',MyName,ThisLink+'A'));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "MARKING HOST (%c) CONNECTED TO %s (%c)\n",
+				NewLink+'A',MyName,ThisLink+'A');
 	    HostP->Topology[NewLink].Unit = ThisUnit;
 	    HostP->Topology[NewLink].Link = ThisLink;
 	  }
 	  else if ( NewUnit <= MAX_RUP )
 	  {
-	    rio_dprint(RIO_DEBUG_ROUTE, ("MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
-	      HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A'));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "MARKING RTA %s (%c) CONNECTED TO %s (%c)\n",
+	      HostP->Mapping[NewUnit-1].Name,NewLink+'A',MyName,ThisLink+'A');
 	    HostP->Mapping[NewUnit-1].Topology[NewLink].Unit=ThisUnit;
 	    HostP->Mapping[NewUnit-1].Topology[NewLink].Link=ThisLink;
 	  }
@@ -322,8 +321,8 @@
   */
   if ( RBYTE(PktCmdP->Command) != ROUTE_REQUEST )
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("Unknown command %d received on rup %d host %d ROUTE_RUP\n", 
-	   RBYTE(PktCmdP->Command),Rup,(int)HostP));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Unknown command %d received on rup %d host %d ROUTE_RUP\n", 
+	   RBYTE(PktCmdP->Command),Rup,(int)HostP);
     return TRUE;
   }
       
@@ -337,7 +336,7 @@
   */
   RtaType = GetUnitType(RtaUniq);
 
-  rio_dprint(RIO_DEBUG_ROUTE, ("Received a request for an ID for serial number %x\n", RtaUniq));
+  rio_dprintk (RIO_DEBUG_ROUTE, "Received a request for an ID for serial number %x\n", RtaUniq);
 
   Mod = RBYTE(PktCmdP->ModuleTypes);
   Mod1 = LONYBLE(Mod);
@@ -348,14 +347,14 @@
     ** with 8 port, set 2nd ident in Mod2 to the same as Mod1.
     */
     Mod2 = Mod1;
-    rio_dprint(RIO_DEBUG_ROUTE, ("Backplane type is %s (all ports)\n",
-     p->RIOModuleTypes[Mod1].Name ));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Backplane type is %s (all ports)\n",
+     p->RIOModuleTypes[Mod1].Name);
   }
   else
   {
     Mod2 = HINYBLE(Mod);
-    rio_dprint(RIO_DEBUG_ROUTE, ("Module types are %s (ports 0-3) and %s (ports 4-7)\n",
-     p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name ));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Module types are %s (ports 0-3) and %s (ports 4-7)\n",
+     p->RIOModuleTypes[Mod1].Name, p->RIOModuleTypes[Mod2].Name);
   }
 
   if ( RtaUniq == 0xffffffff )
@@ -368,7 +367,7 @@
   */
   if ( !(CmdBlkP = RIOGetCmdBlk()) )
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("No command blocks to route RTA! come back later.\n"));
+    rio_dprintk (RIO_DEBUG_ROUTE, "No command blocks to route RTA! come back later.\n");
     return 0;
   }
 
@@ -385,8 +384,8 @@
 
   if (! RIOBootOk(p, HostP, RtaUniq))
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("RTA %x tried to get an ID, but does not belong - FOAD it!\n",
-	  RtaUniq));
+    rio_dprintk (RIO_DEBUG_ROUTE, "RTA %x tried to get an ID, but does not belong - FOAD it!\n",
+	  RtaUniq);
     PktReplyP->Command = ROUTE_FOAD;
     HostP->Copy("RT_FOAD", PktReplyP->CommandText, 7);
     RIOQueueCmdBlk(HostP, Rup, CmdBlkP);
@@ -398,13 +397,13 @@
   */
   for ( ThisUnit=0; ThisUnit<MAX_RUP; ThisUnit++ )
   {
-    rio_dprint(RIO_DEBUG_ROUTE, ("Entry %d Flags=%s %s UniqueNum=0x%x\n",
+    rio_dprintk (RIO_DEBUG_ROUTE, "Entry %d Flags=%s %s UniqueNum=0x%x\n",
 			ThisUnit,
 			HostP->Mapping[ThisUnit].Flags & SLOT_IN_USE ?
 					    "Slot-In-Use":"Not In Use",
 			HostP->Mapping[ThisUnit].Flags & SLOT_TENTATIVE ? 
 					    "Slot-Tentative":"Not Tentative",
-			HostP->Mapping[ThisUnit].RtaUniqueNum ));
+			HostP->Mapping[ThisUnit].RtaUniqueNum);
 
     /*
     ** We have an entry for it.
@@ -415,12 +414,12 @@
       if (RtaType == TYPE_RTA16)
       {
 	  ThisUnit2 = HostP->Mapping[ThisUnit].ID2 - 1;
-          rio_dprint(RIO_DEBUG_ROUTE, ("Found unit 0x%x at slots %d+%d\n",
-					    RtaUniq,ThisUnit,ThisUnit2));
+          rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slots %d+%d\n",
+					    RtaUniq,ThisUnit,ThisUnit2);
       }
       else
-          rio_dprint(RIO_DEBUG_ROUTE, ("Found unit 0x%x at slot %d\n",
-					    RtaUniq,ThisUnit));
+          rio_dprintk (RIO_DEBUG_ROUTE, "Found unit 0x%x at slot %d\n",
+					    RtaUniq,ThisUnit);
       /*
       ** If we have no knowledge of booting it, then the host has
       ** been re-booted, and so we must kill the RTA, so that it
@@ -459,14 +458,14 @@
 	    */
 	    RIOFixPhbs(p, HostP, ThisUnit2);
 	    PktReplyP->IDNum2  = ThisUnit2+1;
-	    rio_dprint(RIO_DEBUG_ROUTE, ("RTA '%s' has been allocated IDs %d+%d\n",
-	          HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated IDs %d+%d\n",
+	          HostP->Mapping[ThisUnit].Name, PktReplyP->IDNum, PktReplyP->IDNum2);
       }
       else
       {
 	    PktReplyP->IDNum2 = ROUTE_NO_ID;
-	    rio_dprint(RIO_DEBUG_ROUTE, ("RTA '%s' has been allocated ID %d\n",
-	          HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "RTA '%s' has been allocated ID %d\n",
+	          HostP->Mapping[ThisUnit].Name,PktReplyP->IDNum);
       }
       HostP->Copy("RT_ALLOCAT",PktReplyP->CommandText,10);
 
@@ -490,7 +489,7 @@
 	  PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit].SysPort];
 	  if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
 	  {
-	    rio_dprint(RIO_DEBUG_ROUTE, ("Re-opened this port\n"));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
 	    rio_spin_lock_irqsave(&PortP->portSem, flags);
 	    PortP->MagicFlags |= MAGIC_REBOOT;
 	    rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -503,7 +502,7 @@
 	    PortP = p->RIOPortp[port+HostP->Mapping[ThisUnit2].SysPort];
 	    if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) )
 	    {
-	      rio_dprint(RIO_DEBUG_ROUTE, ("Re-opened this port\n"));
+	      rio_dprintk (RIO_DEBUG_ROUTE, "Re-opened this port\n");
 	      rio_spin_lock_irqsave(&PortP->portSem, flags);
 	      PortP->MagicFlags |= MAGIC_REBOOT;
 	      rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -629,7 +628,7 @@
 	unsigned long flags;
 	int PortN = HostP->Mapping[unit].SysPort;
 
-	rio_dprint(RIO_DEBUG_ROUTE, ("RIOFixPhbs unit %d sysport %d\n", unit, PortN));
+	rio_dprintk (RIO_DEBUG_ROUTE, "RIOFixPhbs unit %d sysport %d\n", unit, PortN);
 
 	if (PortN != -1) {
 		ushort		dest_unit = HostP->Mapping[unit].ID2;
@@ -657,7 +656,7 @@
 			** unset, so go no further.
 			*/
 			if (PortP->TxStart == 0) {
-					rio_dprint(RIO_DEBUG_ROUTE, ("Tx pkts not set up yet\n"));
+					rio_dprintk (RIO_DEBUG_ROUTE, "Tx pkts not set up yet\n");
 					break;
 			}
 
@@ -692,10 +691,10 @@
 				WBYTE(Pkt->dest_unit, dest_unit);
 				WBYTE(Pkt->dest_port, dest_port);
 			}
-			rio_dprint(RIO_DEBUG_ROUTE, ("phb dest: Old %x:%x New %x:%x\n",
+			rio_dprintk (RIO_DEBUG_ROUTE, "phb dest: Old %x:%x New %x:%x\n",
 					RWORD(PortP->PhbP->destination) & 0xff,
 					(RWORD(PortP->PhbP->destination) >> 8) & 0xff,
-					dest_unit, dest_port));
+					dest_unit, dest_port);
 			WWORD(PortP->PhbP->destination, dest_unit + (dest_port << 8));
 			WWORD(PortP->PhbP->link, link);
 
@@ -707,7 +706,7 @@
 		*/
 		if (link > 3) return;
 		if (((unit * 8) + 7) > RWORD(HostP->LinkStrP[link].last_port)) {
-			rio_dprint(RIO_DEBUG_ROUTE, ("last port on host link %d: %d\n", link, (unit * 8) + 7));
+			rio_dprintk (RIO_DEBUG_ROUTE, "last port on host link %d: %d\n", link, (unit * 8) + 7);
 			WWORD(HostP->LinkStrP[link].last_port, (unit * 8) + 7);
 		}
 	}
@@ -733,7 +732,7 @@
 	CheckUnitId( UnitId );
 #endif
 	if ( RIOCheck( HostP, UnitId ) ) {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated\n",UnitId));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Unit %d is NOT isolated\n", UnitId);
 		rio_spin_unlock_irqrestore(&HostP->HostLock, flags);
 		return(0);
 	}
@@ -772,7 +771,7 @@
 	HostP->Mapping[UnitId].Flags |= BEEN_HERE;
 
 	if ( p->RIOPrintDisabled == DO_PRINT )
-		rio_dprint(RIO_DEBUG_ROUTE, ("RIOMesgIsolated %s",HostP->Mapping[UnitId].Name));
+		rio_dprintk (RIO_DEBUG_ROUTE, "RIOMesgIsolated %s", HostP->Mapping[UnitId].Name);
 
 	for ( link=0; link<LINKS_PER_UNIT; link++) {
 		unit = HostP->Mapping[UnitId].Topology[link].Unit;
@@ -796,7 +795,7 @@
 	CheckUnitId( UnitId );
 #endif
 /* 	rio_dprint(RIO_DEBUG_ROUTE, ("Check to see if unit %d has a route to the host\n",UnitId)); */
-	rio_dprint(RIO_DEBUG_ROUTE, ("RIOCheck : UnitID = %d\n",UnitId));
+	rio_dprintk (RIO_DEBUG_ROUTE, "RIOCheck : UnitID = %d\n", UnitId);
 
 	if ( UnitId == HOST_ID ) {
 		/* rio_dprint(RIO_DEBUG_ROUTE, ("Unit %d is NOT isolated - it IS the host!\n", UnitId)); */
@@ -855,16 +854,16 @@
 		case RIO_MCA:
 		case RIO_EISA:
 		case RIO_PCI:
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: Host\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Host\n");
 			return(TYPE_HOST);
 		case RIO_RTA_16:
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: 16 port RTA\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 16 port RTA\n");
 			return(TYPE_RTA16);
 		case RIO_RTA:
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: 8 port RTA\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: 8 port RTA\n");
 			return(TYPE_RTA8);
 		default :
-			rio_dprint(RIO_DEBUG_ROUTE, ("Unit type: Unrecognised\n"));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Unit type: Unrecognised\n");
 			return(99);
 	}
 }
@@ -877,7 +876,7 @@
 		return(0);
 	p->RIOQuickCheck = CHANGED;
 	if ( p->RIOSignalProcess ) {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Send SIG-HUP"));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Send SIG-HUP");
 		/*
 		psignal( RIOSignalProcess, SIGHUP );
 		*/
@@ -952,10 +951,10 @@
     ToName = ToId ? HostP->Mapping[ToId-1].Name : HostP->Name;
     ToType = ToId ? "RTA" : "HOST";
 
-    rio_dprint(RIO_DEBUG_ROUTE, ("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
+    rio_dprintk (RIO_DEBUG_ROUTE, "Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
 			    FromType, FromName, 'A'+FromLink,
 			    ToType,   ToName,   'A'+ToLink,
-			    (Change==CONNECT) ? "established" : "disconnected"));
+			    (Change==CONNECT) ? "established" : "disconnected");
     cprintf("Link between %s '%s' (%c) and %s '%s' (%c) %s.\n",
 			    FromType, FromName, 'A'+FromLink,
 			    ToType,   ToName,   'A'+ToLink,
@@ -1001,7 +1000,7 @@
     int		link;
 
 
-    rio_dprint(RIO_DEBUG_ROUTE, ("RIOFreeDisconnect unit %d\n",unit));
+    rio_dprintk (RIO_DEBUG_ROUTE, "RIOFreeDisconnect unit %d\n", unit);
     /*
     ** If the slot is tentative and does not belong to the
     ** second half of a 16 port RTA then scan to see if
@@ -1024,17 +1023,17 @@
     ** made this slot tentative and not yet received a topology update.
     ** Lets check how long ago we made it tentative.
     */
-    rio_dprint(RIO_DEBUG_ROUTE, ("Just about to check LBOLT on entry %d\n",unit));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Just about to check LBOLT on entry %d\n", unit);
     if (drv_getparm(LBOLT, (ulong_t *) &current_time))
-        rio_dprint(RIO_DEBUG_ROUTE, ("drv_getparm(LBOLT,....) Failed.\n"));
+        rio_dprintk (RIO_DEBUG_ROUTE, "drv_getparm(LBOLT,....) Failed.\n");
 
     elapse_time = current_time - TentTime[unit];
-    rio_dprint(RIO_DEBUG_ROUTE, ("elapse %d = current %d - tent %d (%d usec)\n",
-        elapse_time, current_time, TentTime[unit],drv_hztousec(elapse_time)));
+    rio_dprintk (RIO_DEBUG_ROUTE, "elapse %d = current %d - tent %d (%d usec)\n",
+        elapse_time, current_time, TentTime[unit], drv_hztousec(elapse_time));
     if (drv_hztousec(elapse_time) < WAIT_TO_FINISH)
     {
-        rio_dprint(RIO_DEBUG_ROUTE, ("Skipping slot %d, not timed out yet %d\n"
-            ,unit,drv_hztousec(elapse_time)));
+      rio_dprintk (RIO_DEBUG_ROUTE, "Skipping slot %d, not timed out yet %d\n",
+            unit, drv_hztousec(elapse_time));
         return 1;
     }
 #endif
@@ -1047,7 +1046,7 @@
     {
 	int nOther = (HostP->Mapping[unit].ID2) -1;
 
-	rio_dprint(RIO_DEBUG_ROUTE, ("RioFreedis second slot %d.\n",nOther));
+	rio_dprintk (RIO_DEBUG_ROUTE, "RioFreedis second slot %d.\n", nOther);
 	bzero((caddr_t)&HostP->Mapping[nOther], sizeof(struct Map));
     }
     RIORemoveFromSavedTable(p, &HostP->Mapping[unit]);
@@ -1083,19 +1082,19 @@
     */
     for (unit = 0; unit < MAX_RUP; unit++)
     {
-	rio_dprint(RIO_DEBUG_ROUTE, ("Scanning unit %d\n",unit));
+	rio_dprintk (RIO_DEBUG_ROUTE, "Scanning unit %d\n",unit);
 	/*
 	** If the flags are zero then the slot is empty.
 	*/
 	if (HostP->Mapping[unit].Flags == 0)
 	{
-	    rio_dprint(RIO_DEBUG_ROUTE, ("      This slot is empty.\n"));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "      This slot is empty.\n");
 	    /*
 	    ** If we haven't allocated the first ID then do it now.
 	    */
 	    if (*pID1 == MAX_RUP)
 	    {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Make tentative entry for first unit %d\n", unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for first unit %d\n", unit);
 		*pID1 = unit;
 
 		/*
@@ -1110,7 +1109,7 @@
 		/*
 		** Allocate the second slot and return.
 		*/
-		rio_dprint(RIO_DEBUG_ROUTE, ("Make tentative entry for second unit %d\n", unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Make tentative entry for second unit %d\n", unit);
 		*pID2 = unit;
 		return 0;
 	    }
@@ -1122,18 +1121,18 @@
     ** need to start all over again looking for tentative slots
     ** that we can re-use.
     */
-    rio_dprint(RIO_DEBUG_ROUTE, ("Starting to scan for tentative slots\n"));
+    rio_dprintk (RIO_DEBUG_ROUTE, "Starting to scan for tentative slots\n");
     for (unit = 0; unit < MAX_RUP; unit++)
     {
 	if (((HostP->Mapping[unit].Flags & SLOT_TENTATIVE) ||
 	                       (HostP->Mapping[unit].Flags == 0))  && ! 
 	   (HostP->Mapping[unit].Flags & RTA16_SECOND_SLOT ))
 	{
-	    rio_dprint(RIO_DEBUG_ROUTE, ("    Slot %d looks promising.\n",unit));
+	    rio_dprintk (RIO_DEBUG_ROUTE, "    Slot %d looks promising.\n",unit);
 
 	    if(unit == *pID1)
 	    {
-	    	rio_dprint(RIO_DEBUG_ROUTE, ("    No it isn't, its the 1st half\n"));
+	    	rio_dprintk (RIO_DEBUG_ROUTE, "    No it isn't, its the 1st half\n");
 		continue;
 	    }
 
@@ -1153,7 +1152,7 @@
 	    */
 	    if (*pID1 == MAX_RUP)
 	    {
-		rio_dprint(RIO_DEBUG_ROUTE, ("Grab tentative entry for first unit %d\n", unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative entry for first unit %d\n", unit);
 		*pID1 = unit;
 
 		/*
@@ -1173,8 +1172,8 @@
 		/*
 		** Allocate the second slot and return.
 		*/
-		rio_dprint(RIO_DEBUG_ROUTE, ("Grab tentative/empty  entry for second unit %d\n",
-		      unit));
+		rio_dprintk (RIO_DEBUG_ROUTE, "Grab tentative/empty  entry for second unit %d\n",
+		      unit);
 		*pID2 = unit;
 
 		/*
@@ -1191,7 +1190,7 @@
 
 		if (*pID1 > *pID2)
 		{
-			rio_dprint(RIO_DEBUG_ROUTE, ("Swapping IDS %d %d\n",*pID1,*pID2));
+			rio_dprintk (RIO_DEBUG_ROUTE, "Swapping IDS %d %d\n", *pID1, *pID2);
 			tempID = *pID1;
 			*pID1 = *pID2;
 			*pID2 = tempID;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/riotable.c linux.17p18/drivers/char/rio/riotable.c
--- linux.vanilla/drivers/char/rio/riotable.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/riotable.c	Wed Aug  9 22:24:45 2000
@@ -34,7 +34,6 @@
 #endif
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -121,7 +120,7 @@
 	** (9)	That names aren't duplicated
 	** xx (10) That hosts that actually exist are mentioned in the table. xx
 	*/
-	rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(1)\n")); 
+	rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(1)\n"); 
 	if ( p->RIOSystemUp ) {		/* (1) */
 		p->RIOError.Error = HOST_HAS_ALREADY_BEEN_BOOTED;
 		return EBUSY;
@@ -134,7 +133,7 @@
 	for ( Entry=0; Entry<TOTAL_MAP_ENTRIES; Entry++ ) {
 		MapP = &p->RIOConnectTable[Entry];
 		if ((MapP->Flags & RTA16_SECOND_SLOT) == 0) {
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(2)\n"));
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(2)\n");
 			cptr = MapP->Name;		/* (2) */
 			cptr[MAX_NAME_LEN-1]='\0';
 			if ( cptr[0]=='\0' ) {
@@ -162,19 +161,19 @@
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(3)\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(3)\n");
 		if ( !MapP->RtaUniqueNum && !MapP->HostUniqueNum ) { /* (3) */
 			if ( MapP->ID || MapP->SysPort || MapP->Flags ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("%s pretending to be empty but isn't\n",MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "%s pretending to be empty but isn't\n",MapP->Name);
 				p->RIOError.Error = TABLE_ENTRY_ISNT_PROPERLY_NULL;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
-			rio_dprint(RIO_DEBUG_TABLE, ("!RIO: Daemon: test (3) passes\n"));
+			rio_dprintk (RIO_DEBUG_TABLE, "!RIO: Daemon: test (3) passes\n");
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(4)\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(4)\n");
 		for ( Host=0; Host<p->RIONumHosts; Host++ ) { /* (4) */
 			if ( p->RIOHosts[Host].UniqueNum==MapP->HostUniqueNum ) {
 				HostP = &p->RIOHosts[Host];
@@ -188,8 +187,8 @@
 		}
 
 		if ( Host >= p->RIONumHosts ) {
-			rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has unknown host unique number 0x%x\n",
-									MapP->Name,MapP->HostUniqueNum));
+			rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has unknown host unique number 0x%x\n",
+									MapP->Name, MapP->HostUniqueNum);
 			MapP->HostUniqueNum = 0;
 			/* MapP->RtaUniqueNum	= 0; */
 			/* MapP->ID			= 0; */
@@ -199,18 +198,18 @@
 			continue;
 		}
 
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(5)\n")); 
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(5)\n"); 
 		if ( MapP->RtaUniqueNum ) { /* (5) */
 			if ( !MapP->ID ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO: RTA %s has been allocated an ID of zero!\n",
-							MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an ID of zero!\n",
+							MapP->Name);
 				p->RIOError.Error		 = ZERO_RTA_ID;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
 			if ( MapP->ID > MAX_RUP ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO: RTA %s has been allocated an illegal ID %d\n",
-							MapP->Name, MapP->ID));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO: RTA %s has been allocated an illegal ID %d\n",
+							MapP->Name, MapP->ID);
 				p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
@@ -219,8 +218,8 @@
 				if ( MapP->HostUniqueNum == 
 						p->RIOConnectTable[SubEnt].HostUniqueNum && 
 						MapP->ID == p->RIOConnectTable[SubEnt].ID ) {
-					rio_dprint(RIO_DEBUG_TABLE, ("Dupl. ID number allocated to RTA %s and RTA %s\n",
-							MapP->Name,p->RIOConnectTable[SubEnt].Name));
+					rio_dprintk (RIO_DEBUG_TABLE, "Dupl. ID number allocated to RTA %s and RTA %s\n",
+							MapP->Name, p->RIOConnectTable[SubEnt].Name);
 					p->RIOError.Error = DUPLICATED_RTA_ID;
 					p->RIOError.Entry = Entry;
 					p->RIOError.Other = SubEnt;
@@ -233,29 +232,29 @@
 				if ((MapP->RtaUniqueNum == 
 						p->RIOConnectTable[SubEnt].RtaUniqueNum)
 				 		&& (MapP->ID2 != p->RIOConnectTable[SubEnt].ID)) {
-					rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has duplicate unique number\n",MapP->Name));
-					rio_dprint(RIO_DEBUG_TABLE, ("RTA %s has duplicate unique number\n",
-										p->RIOConnectTable[SubEnt].Name));
+					rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",MapP->Name);
+					rio_dprintk (RIO_DEBUG_TABLE, "RTA %s has duplicate unique number\n",
+										p->RIOConnectTable[SubEnt].Name);
 					p->RIOError.Error = DUPLICATE_UNIQUE_NUMBER;
 					p->RIOError.Entry = Entry;
 					p->RIOError.Other = SubEnt;
 					return ENXIO;
 				}
 			}
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(7a)\n")); 
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7a)\n"); 
 			/* (7a) */
 			if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort % PORTS_PER_RTA)) {
-				rio_dprint(RIO_DEBUG_TABLE, ("TTY Port number %d-RTA %s is not a multiple of %d!\n",
-					(int)MapP->SysPort,MapP->Name,PORTS_PER_RTA));
+				rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d-RTA %s is not a multiple of %d!\n",
+					(int)MapP->SysPort,MapP->Name, PORTS_PER_RTA);
 				p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(7b)\n")); 
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(7b)\n"); 
 			/* (7b) */
 			if ((MapP->SysPort != NO_PORT)&&(MapP->SysPort >= RIO_PORTS)) {
-				rio_dprint(RIO_DEBUG_TABLE, ("TTY Port number %d for RTA %s is too big\n",
-							(int)MapP->SysPort,MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "TTY Port number %d for RTA %s is too big\n",
+							(int)MapP->SysPort, MapP->Name);
 				p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
@@ -264,22 +263,22 @@
 				if ( p->RIOConnectTable[SubEnt].Flags & RTA16_SECOND_SLOT )
 						continue;
 				if ( p->RIOConnectTable[SubEnt].RtaUniqueNum ) {
-					rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(8)\n")); 
+					rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(8)\n"); 
 					/* (8) */
 					if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort == 
 									p->RIOConnectTable[SubEnt].SysPort) ) {
-						rio_dprint(RIO_DEBUG_TABLE, ("RTA %s:same TTY port # as RTA %s (%d)\n",
+						rio_dprintk (RIO_DEBUG_TABLE, "RTA %s:same TTY port # as RTA %s (%d)\n",
 							MapP->Name, p->RIOConnectTable[SubEnt].Name,
-							(int)MapP->SysPort));
+							(int)MapP->SysPort);
 						p->RIOError.Error = TTY_NUMBER_IN_USE;
 						p->RIOError.Entry = Entry;
 						p->RIOError.Other = SubEnt;
 						return ENXIO;
 					}
-					rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(9)\n")); 
+					rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(9)\n"); 
 					if (RIOStrCmp(MapP->Name,
 							p->RIOConnectTable[SubEnt].Name)==0 && !(MapP->Flags & RTA16_SECOND_SLOT)) { /* (9) */
-						rio_dprint(RIO_DEBUG_TABLE, ("RTA name %s used twice\n",MapP->Name));
+						rio_dprintk (RIO_DEBUG_TABLE, "RTA name %s used twice\n", MapP->Name);
 						p->RIOError.Error = NAME_USED_TWICE;
 						p->RIOError.Entry = Entry;
 						p->RIOError.Other = SubEnt;
@@ -289,17 +288,17 @@
 			}
 		}
 		else { /* (6) */
-			rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: entering(6)\n")); 
+			rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: entering(6)\n"); 
 			if ( MapP->ID ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO:HOST %s has been allocated ID that isn't zero!\n",
-					MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO:HOST %s has been allocated ID that isn't zero!\n",
+					MapP->Name);
 				p->RIOError.Error = HOST_ID_NOT_ZERO;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
 			}
 			if ( MapP->SysPort != NO_PORT ) {
-				rio_dprint(RIO_DEBUG_TABLE, ("RIO: HOST %s has been allocated port numbers!\n",
-					MapP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "RIO: HOST %s has been allocated port numbers!\n",
+					MapP->Name);
 				p->RIOError.Error = HOST_SYSPORT_BAD;
 				p->RIOError.Entry = Entry;
 				return ENXIO;
@@ -327,7 +326,7 @@
 	** Copy in the new table entries
 	*/
 	for ( Entry=0; Entry< TOTAL_MAP_ENTRIES; Entry++ ) {
-		rio_dprint(RIO_DEBUG_TABLE, ("RIONewTable: Copy table for Host entry %d\n", Entry));
+		rio_dprintk (RIO_DEBUG_TABLE, "RIONewTable: Copy table for Host entry %d\n", Entry);
 		MapP = &p->RIOConnectTable[Entry];
 
 		/*
@@ -345,7 +344,7 @@
 		** If it is a host, then we only need to fill in the name field.
 		*/
 		if ( MapP->ID==0 ) {
-			rio_dprint(RIO_DEBUG_TABLE, ("Host entry found. Name %s\n",MapP->Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "Host entry found. Name %s\n", MapP->Name);
 			bcopy(MapP->Name,HostP->Name,MAX_NAME_LEN);
 			continue;
 		}
@@ -358,7 +357,7 @@
 		HostMapP = &HostP->Mapping[MapP->ID-1];
 
 		if (MapP->Flags & SLOT_IN_USE) {
-			rio_dprint(RIO_DEBUG_TABLE, ("Rta entry found. Name %s\n",MapP->Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "Rta entry found. Name %s\n", MapP->Name);
 			/*
 			** structure assign, then sort out the bits we shouldn't have done
 			*/
@@ -371,7 +370,7 @@
 			RIOReMapPorts(p, HostP, HostMapP );
 		}
 		else {
-			rio_dprint(RIO_DEBUG_TABLE, ("TENTATIVE Rta entry found. Name %s\n",MapP->Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "TENTATIVE Rta entry found. Name %s\n", MapP->Name);
 		}
 	}
 
@@ -421,11 +420,11 @@
 		*/
 		if (Host1 != Host)
 		{
-			rio_dprint(RIO_DEBUG_TABLE, ("Default name %s already used\n", p->RIOHosts[Host].Name));
+			rio_dprintk (RIO_DEBUG_TABLE, "Default name %s already used\n", p->RIOHosts[Host].Name);
 			bcopy("HOST 1",p->RIOHosts[Host].Name,7);
 			p->RIOHosts[Host].Name[5] += Host1;
 		}
-		rio_dprint(RIO_DEBUG_TABLE, ("Assigning default name %s\n", p->RIOHosts[Host].Name));
+		rio_dprintk (RIO_DEBUG_TABLE, "Assigning default name %s\n", p->RIOHosts[Host].Name);
 	}
 	return 0;
 }
@@ -448,13 +447,13 @@
 
 	disable(oldspl);		/* strange but true! */
  
-	rio_dprint(RIO_DEBUG_TABLE, ("Generating a table to return to config.rio\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Generating a table to return to config.rio\n");
 
 	bzero((caddr_t)&p->RIOConnectTable[0], 
 					sizeof(struct Map) * TOTAL_MAP_ENTRIES );
 
 	for ( Host=0; Host<RIO_HOSTS; Host++ ) {
-		rio_dprint(RIO_DEBUG_TABLE, ("Processing host %d\n", Host));
+		rio_dprintk (RIO_DEBUG_TABLE, "Processing host %d\n", Host);
 		HostP = &p->RIOHosts[Host];
 		MapP = &p->RIOConnectTable[Next++];
 		MapP->HostUniqueNum = HostP->UniqueNum;
@@ -502,8 +501,8 @@
 	int work_done = 0;
 	unsigned long flags;
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Delete entry on host %x, rta %x\n",
-								MapP->HostUniqueNum,MapP->RtaUniqueNum));
+	rio_dprintk (RIO_DEBUG_TABLE, "Delete entry on host %x, rta %x\n",
+								MapP->HostUniqueNum, MapP->RtaUniqueNum);
 
 	for ( host=0; host < p->RIONumHosts; host++ ) {
 		HostP = &p->RIOHosts[host];
@@ -518,15 +517,15 @@
 		for ( entry=0; entry<MAX_RUP; entry++ ) {
 			if ( MapP->RtaUniqueNum == HostP->Mapping[entry].RtaUniqueNum ) {
 				HostMapP = &HostP->Mapping[entry];
-				rio_dprint(RIO_DEBUG_TABLE, ("Found entry offset %d on host %s\n", 
-						entry,HostP->Name));
+				rio_dprintk (RIO_DEBUG_TABLE, "Found entry offset %d on host %s\n", 
+						entry, HostP->Name);
 
 				/*
 				** Check all four links of the unit are disconnected
 				*/
 				for ( link=0; link< LINKS_PER_UNIT; link++ ) {
 					if ( HostMapP->Topology[link].Unit != ROUTE_DISCONNECT ) {
-						rio_dprint(RIO_DEBUG_TABLE, ("Entry is in use and cannot be deleted!\n"));
+						rio_dprintk (RIO_DEBUG_TABLE, "Entry is in use and cannot be deleted!\n");
 						p->RIOError.Error = UNIT_IS_IN_USE;
 						rio_spin_unlock_irqrestore( &HostP->HostLock, flags);
 						return EBUSY;
@@ -541,7 +540,7 @@
 				if ( SysPort != NO_PORT ) {
 					for (port=SysPort; port < SysPort+PORTS_PER_RTA; port++) {
 						PortP = p->RIOPortp[port];
-						rio_dprint(RIO_DEBUG_TABLE, ("Unmap port\n"));
+						rio_dprintk (RIO_DEBUG_TABLE, "Unmap port\n");
 
 						rio_spin_lock_irqsave( &PortP->portSem, flags );
 
@@ -549,7 +548,7 @@
 
 						if ( PortP->State & (RIO_MOPEN|RIO_LOPEN) ) {
 
-							rio_dprint(RIO_DEBUG_TABLE, ("Gob on port\n"));
+							rio_dprintk (RIO_DEBUG_TABLE, "Gob on port\n");
 							PortP->TxBufferIn = PortP->TxBufferOut = 0;
 							/* What should I do 
 							wakeup( &PortP->TxBufferIn );
@@ -586,25 +585,25 @@
 								*/
 								Pkt = (PKT *) RIO_PTR(HostP->Caddr,
 								 	RWORD(*TxPktP));
-								rio_dprint(RIO_DEBUG_TABLE, (
+								rio_dprintk (RIO_DEBUG_TABLE, 
 						"Tx packet (%x) destination: Old %x:%x New %x:%x\n",
 								 *TxPktP, Pkt->dest_unit,
-								 Pkt->dest_port, dest_unit, dest_port));
+								 Pkt->dest_port, dest_unit, dest_port);
 								WWORD(Pkt->dest_unit, dest_unit);
 								WWORD(Pkt->dest_port, dest_port);
 							}
-							rio_dprint(RIO_DEBUG_TABLE, (
+							rio_dprintk (RIO_DEBUG_TABLE, 
 						"Port %d phb destination: Old %x:%x New %x:%x\n",
 							 port, PortP->PhbP->destination & 0xff,
 							 (PortP->PhbP->destination >> 8) & 0xff,
-							 dest_unit, dest_port));
+							 dest_unit, dest_port);
 							WWORD(PortP->PhbP->destination,
 							 dest_unit + (dest_port << 8));
 						}
 						rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 					}
 				}
-				rio_dprint(RIO_DEBUG_TABLE, ("Entry nulled.\n"));
+				rio_dprintk (RIO_DEBUG_TABLE, "Entry nulled.\n");
 				bzero((char *)HostMapP,sizeof(struct Map));
 				work_done++;
 			}
@@ -626,7 +625,7 @@
 	if ( work_done )
 		return 0;
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Couldn't find entry to be deleted\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Couldn't find entry to be deleted\n");
 	p->RIOError.Error = COULDNT_FIND_ENTRY;
 	return ENXIO;
 }
@@ -639,32 +638,32 @@
     int	link;
 
 
-    rio_dprint(RIO_DEBUG_TABLE, ("Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
+    rio_dprintk (RIO_DEBUG_TABLE, "Assign entry on host %x, rta %x, ID %d, Sysport %d\n",
 				MapP->HostUniqueNum,MapP->RtaUniqueNum,
-				MapP->ID, (int)MapP->SysPort ));
+				MapP->ID, (int)MapP->SysPort);
 
     if ((MapP->ID != (ushort)-1) &&
 	((int)MapP->ID < (int)1 || (int)MapP->ID > MAX_RUP ))
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Bad ID in map entry!\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
 	p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
 	return EINVAL;
     }
     if (MapP->RtaUniqueNum == 0)
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Rta Unique number zero!\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Rta Unique number zero!\n");
 	p->RIOError.Error = RTA_UNIQUE_NUMBER_ZERO;
 	return EINVAL;
     }
     if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort % PORTS_PER_RTA) )
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA));
+	rio_dprintk (RIO_DEBUG_TABLE, "Port %d not multiple of %d!\n",(int)MapP->SysPort,PORTS_PER_RTA);
 	p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 	return EINVAL;
     }
     if ( (MapP->SysPort != NO_PORT) && (MapP->SysPort >= RIO_PORTS) )
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Port %d not valid!\n",(int)MapP->SysPort));
+	rio_dprintk (RIO_DEBUG_TABLE, "Port %d not valid!\n",(int)MapP->SysPort);
 	p->RIOError.Error = TTY_NUMBER_OUT_OF_RANGE;
 	return EINVAL;
     }
@@ -678,7 +677,7 @@
     {
     if ( *sptr<' ' || *sptr>'~' )
     {
-	rio_dprint(RIO_DEBUG_TABLE, ("Name entry contains non-printing characters!\n"));
+	rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
 	p->RIOError.Error = BAD_CHARACTER_IN_NAME;
 	return EINVAL;
     }
@@ -703,8 +702,8 @@
 	    {
 		int nNewID;
 
-		rio_dprint(RIO_DEBUG_TABLE, ("Attempting to get a new ID for rta \"%s\"\n",
-		      MapP->Name));
+		rio_dprintk (RIO_DEBUG_TABLE, "Attempting to get a new ID for rta \"%s\"\n",
+		      MapP->Name);
 		/*
 		** The idea here is to allow RTA's to be assigned
 		** before they actually appear on the network.
@@ -722,7 +721,7 @@
 		    return EBUSY;
 		}
 		MapP->ID = (ushort)nNewID + 1;
-		rio_dprint(RIO_DEBUG_TABLE, ("Allocated ID %d for this new RTA.\n",MapP->ID));
+		rio_dprintk (RIO_DEBUG_TABLE, "Allocated ID %d for this new RTA.\n", MapP->ID);
 		HostMapP = &p->RIOHosts[host].Mapping[nNewID];
 		HostMapP->RtaUniqueNum = MapP->RtaUniqueNum;
 		HostMapP->HostUniqueNum = MapP->HostUniqueNum;
@@ -748,9 +747,9 @@
 		    HostMapP->Flags |= RTA16_SECOND_SLOT;
 		    HostMapP->ID2 = MapP->ID2 = p->RIOHosts[host].Mapping[unit].ID;
 		    p->RIOHosts[host].Mapping[unit].ID2 = MapP->ID;
-		    rio_dprint(RIO_DEBUG_TABLE, ("Cross referenced id %d to ID %d.\n",
+		    rio_dprintk (RIO_DEBUG_TABLE, "Cross referenced id %d to ID %d.\n",
 			  MapP->ID,
-			  p->RIOHosts[host].Mapping[unit].ID));
+			  p->RIOHosts[host].Mapping[unit].ID);
 		}
 	    }
 
@@ -758,7 +757,7 @@
 
 	    if ( HostMapP->Flags & SLOT_IN_USE )
 	    {
-		rio_dprint(RIO_DEBUG_TABLE, ("Map table slot for ID %d is already in use.\n",MapP->ID));
+		rio_dprintk (RIO_DEBUG_TABLE, "Map table slot for ID %d is already in use.\n", MapP->ID);
 		p->RIOError.Error = ID_ALREADY_IN_USE;
 		return EBUSY;
 	    }
@@ -792,15 +791,15 @@
 		    p->RIOLastPortsBooted = HostMapP->SysPort;
 	    }
 	    if (MapP->Flags & RTA16_SECOND_SLOT)
-	        rio_dprint(RIO_DEBUG_TABLE, ("Second map of RTA %s added to configuration\n",
-		 p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name));
+	        rio_dprintk (RIO_DEBUG_TABLE, "Second map of RTA %s added to configuration\n",
+		 p->RIOHosts[host].Mapping[MapP->ID2 - 1].Name);
 	    else
-	        rio_dprint(RIO_DEBUG_TABLE, ("RTA %s added to configuration\n",MapP->Name));
+	        rio_dprintk (RIO_DEBUG_TABLE, "RTA %s added to configuration\n", MapP->Name);
 	    return 0;
 	}
     }
     p->RIOError.Error = UNKNOWN_HOST_NUMBER;
-    rio_dprint(RIO_DEBUG_TABLE, ("Unknown host %x\n",MapP->HostUniqueNum));
+    rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
     return ENXIO;
 }
 
@@ -823,7 +822,7 @@
 	CheckHostMapP( HostMapP );
 #endif
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Mapping sysport %d to id %d\n",(int)HostMapP->SysPort, HostMapP->ID));
+	rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d to id %d\n", (int)HostMapP->SysPort, HostMapP->ID);
 
 	/*
 	** We need to tell the UnixRups which sysport the rup corresponds to
@@ -834,26 +833,26 @@
 		return(0);
 
 	RtaType = GetUnitType(HostMapP->RtaUniqueNum);
-	rio_dprint(RIO_DEBUG_TABLE, ("Mapping sysport %d-%d\n",
-				(int)HostMapP->SysPort,(int)HostMapP->SysPort+PORTS_PER_RTA-1));
+	rio_dprintk (RIO_DEBUG_TABLE, "Mapping sysport %d-%d\n",
+				(int)HostMapP->SysPort, (int)HostMapP->SysPort+PORTS_PER_RTA-1);
 
 	/*
 	** now map each of its eight ports
 	*/
 	for ( SubEnt=0; SubEnt<PORTS_PER_RTA; SubEnt++) {
-	  rio_dprint  (RIO_DEBUG_TABLE, ("subent = %d, HostMapP->SysPort = %d\n", 
-		  SubEnt, (int) HostMapP->SysPort));
+	  rio_dprintk (RIO_DEBUG_TABLE, "subent = %d, HostMapP->SysPort = %d\n", 
+		  SubEnt, (int)HostMapP->SysPort);
 		SysPort = HostMapP->SysPort+SubEnt;		/* portnumber within system */
 					/* portnumber on host */
 		
 		HostPort = (HostMapP->ID-1)*PORTS_PER_RTA+SubEnt; 
 
-		rio_dprint (RIO_DEBUG_TABLE, ("c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp));
+		rio_dprintk (RIO_DEBUG_TABLE, "c1 p = %p, p->rioPortp = %p\n", p, p->RIOPortp);
 		PortP = p->RIOPortp[SysPort];
 #if 0
 		PortP->TtyP	= &p->channel[SysPort];
 #endif
-		rio_dprint(RIO_DEBUG_TABLE, ("Map port\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "Map port\n");
 
 		/*
 		** Point at all the real neat data structures
@@ -1009,12 +1008,12 @@
 	struct Map *HostMapP;
 	char *sptr;
 
-	rio_dprint(RIO_DEBUG_TABLE, ("Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
+	rio_dprintk (RIO_DEBUG_TABLE, "Change name entry on host %x, rta %x, ID %d, Sysport %d\n",
 								MapP->HostUniqueNum,MapP->RtaUniqueNum,
-								MapP->ID, (int)MapP->SysPort ));
+								MapP->ID, (int)MapP->SysPort);
 
 	if ( MapP->ID > MAX_RUP ) {
-		rio_dprint(RIO_DEBUG_TABLE, ("Bad ID in map entry!\n"));
+		rio_dprintk (RIO_DEBUG_TABLE, "Bad ID in map entry!\n");
 		p->RIOError.Error = ID_NUMBER_OUT_OF_RANGE;
 		return EINVAL;
 	}
@@ -1024,7 +1023,7 @@
 
 	while ( *sptr ) {
 		if ( *sptr<' ' || *sptr>'~' ) {
-			rio_dprint(RIO_DEBUG_TABLE, ("Name entry contains non-printing characters!\n"));
+			rio_dprintk (RIO_DEBUG_TABLE, "Name entry contains non-printing characters!\n");
 			p->RIOError.Error = BAD_CHARACTER_IN_NAME;
 			return EINVAL;
 		}
@@ -1053,6 +1052,6 @@
 		}
 	}
 	p->RIOError.Error = UNKNOWN_HOST_NUMBER;
-	rio_dprint(RIO_DEBUG_TABLE, ("Unknown host %x\n",MapP->HostUniqueNum));
+	rio_dprintk (RIO_DEBUG_TABLE, "Unknown host %x\n", MapP->HostUniqueNum);
 	return ENXIO;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/riotty.c linux.17p18/drivers/char/rio/riotty.c
--- linux.vanilla/drivers/char/rio/riotty.c	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/riotty.c	Wed Aug  9 22:24:45 2000
@@ -37,7 +37,6 @@
 #define __EXPLICIT_DEF_H__
 
 #define __NO_VERSION__
-#include <linux/config.h>
 #include <linux/module.h>
 #include <linux/malloc.h>
 #include <linux/errno.h>
@@ -90,7 +89,6 @@
 #include "list.h"
 #include "sam.h"
 
-
 #if 0
 static void ttyseth_pv(struct Port *, struct ttystatics *, 
 				struct termios *sg, int);
@@ -155,18 +153,26 @@
 	unsigned long flags;
 	int retval = 0;
 
+	func_enter ();
+
+	/* Make sure driver_data is NULL in case the rio isn't booted jet. Else gs_close
+	   is going to oops.
+	*/
+	tty->driver_data = NULL;
+        
 	SysPort = rio_minor (tty->device);
 	Modem   = rio_ismodem (tty->device);
 
 	if ( p->RIOFailed ) {
-		rio_dprint(RIO_DEBUG_TTY, ("System initialisation failed\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "System initialisation failed\n");
 		pseterr(ENXIO);
-		return 0;
+		func_exit ();
+		return -ENXIO;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("port open SysPort %d (%s) (mapped:%d)\n",
+	rio_dprintk (RIO_DEBUG_TTY, "port open SysPort %d (%s) (mapped:%d)\n",
 	       SysPort,  Modem ? "Modem" : "tty",
-				   p->RIOPortp[SysPort]->Mapped  ) );
+				   p->RIOPortp[SysPort]->Mapped);
 
 	/*
 	** Validate that we have received a legitimate request.
@@ -175,42 +181,54 @@
 	** has been mapped onto a host.
 	*/
 	if (SysPort >= RIO_PORTS) {	/* out of range ? */
-		rio_dprint(RIO_DEBUG_TTY, ("Illegal port number %d\n",SysPort));
+		rio_dprintk (RIO_DEBUG_TTY, "Illegal port number %d\n",SysPort);
 		pseterr(ENXIO);
-		return 0;
+		func_exit();
+		return -ENXIO;
 	}
 
 	/*
 	** Grab pointer to the port stucture
 	*/
 	PortP = p->RIOPortp[SysPort];	/* Get control struc */
-
+	rio_dprintk (RIO_DEBUG_TTY, "PortP: %p\n", PortP);
 	if ( !PortP->Mapped ) {	/* we aren't mapped yet! */
 		/*
 		** The system doesn't know which RTA this port
 		** corresponds to.
 		*/
-		rio_dprint(RIO_DEBUG_TTY, ("port not mapped into system\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "port not mapped into system\n");
+		func_exit ();
 		pseterr(ENXIO);
-		return 0;
+		return -ENXIO;
 	}
 
 	tty->driver_data = PortP;
 
 	PortP->gs.tty = tty;
+	if (!PortP->gs.count)
+		rio_inc_mod_count ();
 	PortP->gs.count++;
-	rio_dprint(RIO_DEBUG_TTY, ("%d bytes in tx buffer\n",
-				   PortP->gs.xmit_cnt));
-	gs_init_port (&PortP->gs);
 
+	rio_dprintk (RIO_DEBUG_TTY, "%d bytes in tx buffer\n",
+				   PortP->gs.xmit_cnt);
+
+	retval = gs_init_port (&PortP->gs);
+	if (retval) {
+		PortP->gs.count--;
+		if (PortP->gs.count)
+			rio_dec_mod_count ();
+		return -ENXIO;
+	}
 	/*
 	** If the host hasn't been booted yet, then 
 	** fail
 	*/
 	if ( (PortP->HostP->Flags & RUN_STATE) != RC_RUNNING ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Host not running\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Host not running\n");
 		pseterr(ENXIO);
-		return 0;
+		func_exit ();
+		return -ENXIO;
 	}
 
 	/*
@@ -221,23 +239,26 @@
 #if 0
 	if (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
 		if (PortP->WaitUntilBooted) {
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot\n");
 			do {
 				if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
-					rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+					rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
+					func_exit ();
 					return -EINTR;
 				}
 				if (repeat_this -- <= 0) {
-					rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+					rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
 					RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 					pseterr(EINTR);
+					func_exit ();
 					return -EIO;
 				}
 			} while(!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED));
-			rio_dprint(RIO_DEBUG_TTY, ("RTA has been booted\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
 		} else {
-			rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
 			pseterr(ENXIO);
+			func_exit ();
 			return 0;
 		}
 	}
@@ -246,10 +267,11 @@
            easier to read and shorter. Now, if it works too that would
 	   be great... -- REW 
 	*/
-	rio_dprint(RIO_DEBUG_TTY, ("Checking if RTA has booted... \n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Checking if RTA has booted... \n");
 	while (!(PortP->HostP->Mapping[PortP->RupNum].Flags & RTA_BOOTED)) {
 	  if (!PortP->WaitUntilBooted) {
-	    rio_dprint(RIO_DEBUG_TTY, ("RTA never booted\n"));
+	    rio_dprintk (RIO_DEBUG_TTY, "RTA never booted\n");
+	    func_exit ();
 	    return -ENXIO;
 	  }
 
@@ -258,15 +280,17 @@
 	     now. --REW 
 	  */
 	  if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
-	    rio_dprint(RIO_DEBUG_TTY, ("RTA_wait_for_boot: EINTR in delay \n"));
+	    rio_dprintk (RIO_DEBUG_TTY, "RTA_wait_for_boot: EINTR in delay \n");
+	    func_exit ();
 	    return -EINTR;
 	  }
 	  if (repeat_this -- <= 0) {
-	    rio_dprint(RIO_DEBUG_TTY, ("Waiting for RTA to boot timeout\n"));
+	    rio_dprintk (RIO_DEBUG_TTY, "Waiting for RTA to boot timeout\n");
+	    func_exit ();
 	    return -EIO;
 	  }
 	}
-	rio_dprint(RIO_DEBUG_TTY, ("RTA has been booted\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "RTA has been booted\n");
 #endif
 #if 0
 	tp =  PortP->TtyP;		/* get tty struct */
@@ -277,8 +301,10 @@
 	}
 #if 0
 	retval = gs_init_port(&PortP->gs);
-	if (retval)
-	  return retval;
+	if (retval){
+		func_exit ();
+		return retval;
+	}
 #endif
 
 	/*
@@ -287,9 +313,9 @@
 	** for it to finish, so that it doesn't close us!
 	*/
 	while ( (PortP->State & RIO_CLOSING) && !p->RIOHalted ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Waiting for RIO_CLOSING to go away\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Waiting for RIO_CLOSING to go away\n");
 		if (repeat_this -- <= 0) {
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for not idle closed broken by signal\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
 			RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 			retval = -EINTR;
 			goto bombout;
@@ -304,9 +330,10 @@
 	}
 
 	if ( !PortP->Mapped ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Port unmapped while closing!\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Port unmapped while closing!\n");
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		retval = -ENXIO;
+		func_exit ();
 		return retval;
 	}
 
@@ -326,8 +353,8 @@
 	}
 
 	if (!(PortP->firstOpen)) {	/* First time ? */
-		rio_dprint(RIO_DEBUG_TTY, ("First open for this port\n"));
-		rio_inc_mod_count ();
+		rio_dprintk (RIO_DEBUG_TTY, "First open for this port\n");
+	
 
 		PortP->firstOpen++;
 		PortP->CookMode = 0; /* XXX RIOCookMode(tp); */
@@ -357,7 +384,7 @@
 		** wait for the port to be not closed.
 		*/
 		while ( !(PortP->PortState & PORT_ISOPEN) && !p->RIOHalted ) {
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for PORT_ISOPEN-currently %x\n",PortP->PortState);
 /*
 ** 15.10.1998 ARG - ESIL 0759
 ** (Part) fix for port being trashed when opened whilst RTA "disconnected"
@@ -374,8 +401,9 @@
 */
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			if (RIODelay(PortP, HUNDRED_MS) == RIO_FAIL) {
-				rio_dprint(RIO_DEBUG_TTY, ("Waiting for open to finish broken by signal\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Waiting for open to finish broken by signal\n");
 				RIOPreemptiveCmd(p, PortP, FCLOSE );
+				func_exit ();
 				return -EINTR;
 			}
 			rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -388,51 +416,67 @@
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return retval;
 		}
-		rio_dprint(RIO_DEBUG_TTY, ("PORT_ISOPEN found\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "PORT_ISOPEN found\n");
 	}
 
 #ifdef MODEM_SUPPORT 
 	if (Modem) {
-		rio_dprint(RIO_DEBUG_TTY, ("Modem - test for carrier\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Modem - test for carrier\n");
 		/*
 		** ACTION
 		** insert test for carrier here. -- ???
 		** I already see that test here. What's the deal? -- REW
 		*/
-		if ((tp->tm.c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
+		if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || (PortP->ModemState & MSVR1_CD))
 		{
-			rio_dprint(RIO_DEBUG_TTY, (PortP,DBG_OPEN,"open(%d) Modem carr on\n",SysPort));
+			rio_dprintk (RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
+			/*
 			tp->tm.c_state |= CARR_ON;
 			wakeup((caddr_t) &tp->tm.c_canq);
+			*/
+			PortP->State |= RIO_CARR_ON;
+			wake_up_interruptible (&PortP->gs.open_wait);
 		}
 		else /* no carrier - wait for DCD */
 		{
-			while (!(tp->tm.c_state&CARR_ON) && 
-			       !(filp->f_flags&O_NONBLOCK) && !p->RIOHalted )
-			{
-				rio_dprint(RIO_DEBUG_TTY, (PortP,DBG_OPEN,"open(%d) sleeping for carr on\n",SysPort));
-				tp->tm.c_state |= WOPEN;
+		  /*
+			while (!(PortP->gs.tty->termios->c_state & CARR_ON) && 
+			       !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
+		  */
+			while (!(PortP->State & RIO_CARR_ON) && 
+			       !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) {
+
+				rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n",SysPort);
+				/*
+				PortP->gs.tty->termios->c_state |= WOPEN;
+				*/
 				PortP->State |= RIO_WOPEN;
-				if ( sleep((caddr_t)&tp->tm.c_canq, TTIPRI|PCATCH))
+#if 0
+				if ( sleep((caddr_t)&tp->tm.c_canqo, TTIPRI|PCATCH))
 				{
 					/*
 					** ACTION: verify that this is a good thing
 					** to do here. -- ???
 					** I think it's OK. -- REW
 					*/
-					rio_dprint(RIO_DEBUG_TTY, ("open(%d) sleeping for carr broken by signal\n",
-					       SysPort));
+					rio_dprintk (RIO_DEBUG_TTY, "open(%d) sleeping for carr broken by signal\n",
+					       SysPort);
 					RIOPreemptiveCmd( p, PortP, FCLOSE );
+					/*
 					tp->tm.c_state &= ~WOPEN;
+					*/
 					PortP->State &= ~RIO_WOPEN;
 					rio_spin_unlock_irqrestore(&PortP->portSem, flags);
+					func_exit ();
 					return -EINTR;
 				}
+#endif
 			}
 			PortP->State &= ~RIO_WOPEN;
 		}
-		if ( RIOHalted )
+		if ( p->RIOHalted )
 			goto bombout;
+		rio_dprintk (RIO_DEBUG_TTY, "Setting RIO_MOPEN\n");
 		PortP->State |= RIO_MOPEN;
 	}
 	else
@@ -450,7 +494,7 @@
 		goto bombout;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("high level open done\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "high level open done\n");
 
 #ifdef STATS
 	PortP->Stat.OpenCnt++;
@@ -462,7 +506,8 @@
 		PortP->opens++;
 
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
-	rio_dprint(RIO_DEBUG_TTY, ("Returning from open\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Returning from open\n");
+	func_exit ();
 	return 0;
 }
 
@@ -488,13 +533,13 @@
 	int Modem;
 	int rv =0;
 	
-	rio_dprint(RIO_DEBUG_TTY, ("port close SysPort %d\n",PortP->PortNum));
+	rio_dprintk (RIO_DEBUG_TTY, "port close SysPort %d\n",PortP->PortNum);
 
 	/* PortP = p->RIOPortp[SysPort]; */
-	rio_dprint(RIO_DEBUG_TTY, ("Port is at address 0x%x\n",(int)PortP));
+	rio_dprintk (RIO_DEBUG_TTY, "Port is at address 0x%x\n",(int)PortP);
 	/* tp = PortP->TtyP;*/			/* Get tty */
 	tty = PortP->gs.tty;
-	rio_dprint(RIO_DEBUG_TTY, ("TTY is at address 0x%x\n",(int)tty));
+	rio_dprintk (RIO_DEBUG_TTY, "TTY is at address 0x%x\n",(int)tty);
 	Modem = rio_ismodem(tty->device);
 #if 0
 	/* What F.CKING cache? Even then, a higly idle multiprocessor,
@@ -512,7 +557,7 @@
 	PortP->State |= RIO_CLOSING;
 
 	if ( (PortP->State & RIO_DELETED) ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Close on deleted RTA\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Close on deleted RTA\n");
 		deleted = 1;
 	}
 	
@@ -522,7 +567,7 @@
 		goto close_end;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("Clear bits\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Clear bits\n");
 	/*
 	** clear the open bits for this device
 	*/
@@ -540,7 +585,7 @@
 		** The port is still open for the other task -
 		** return, pretending that we are still active.
 		*/
-		rio_dprint(RIO_DEBUG_TTY, ("Channel %d still open !\n",PortP->PortNum));
+		rio_dprintk (RIO_DEBUG_TTY, "Channel %d still open !\n",PortP->PortNum);
 		PortP->State &= ~RIO_CLOSING;
 		if (PortP->firstOpen)
 			PortP->firstOpen--;
@@ -548,7 +593,7 @@
 		return -EIO;
 	}
 
-	rio_dprint(RIO_DEBUG_TTY, ("Closing down - everything must go!\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Closing down - everything must go!\n");
 
 	PortP->State &= ~RIO_DYNOROD;
 
@@ -557,7 +602,7 @@
 	** to drain down before closing. Bye-bye....
 	** (We never meant to do this)
 	*/
-	rio_dprint(RIO_DEBUG_TTY, ("Timeout 1 starts\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Timeout 1 starts\n");
 
 #if 0
 	if (!deleted)
@@ -566,14 +611,14 @@
 		cprintf("Need to flush the ttyport\n");
 		if (repeat_this -- <= 0) {
 			rv = -EINTR;
-			rio_dprint(RIO_DEBUG_TTY, ("Waiting for not idle closed broken by signal\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "Waiting for not idle closed broken by signal\n");
 			RIOPreemptiveCmd(p, PortP, FCLOSE ); 
 			goto close_end;
 		}
-		rio_dprint(RIO_DEBUG_TTY, ("Calling timeout to flush in closing\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Calling timeout to flush in closing\n");
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (RIODelay_ni(PortP, HUNDRED_MS*10) == RIO_FAIL) {
-			rio_dprint(RIO_DEBUG_TTY, ("RTA EINTR in delay \n"));
+			rio_dprintk (RIO_DEBUG_TTY, "RTA EINTR in delay \n");
 			rv = -EINTR;
 			rio_spin_lock_irqsave(&PortP->portSem, flags);
 			goto close_end;
@@ -590,7 +635,7 @@
 		** The port has been re-opened for the other task -
 		** return, pretending that we are still active.
 		*/
-		rio_dprint(RIO_DEBUG_TTY, ("Channel %d re-open!\n", PortP->PortNum));
+		rio_dprintk (RIO_DEBUG_TTY, "Channel %d re-open!\n", PortP->PortNum);
 		PortP->State &= ~RIO_CLOSING;
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (PortP->firstOpen)
@@ -617,12 +662,12 @@
 	  while (try && (PortP->PortState & PORT_ISOPEN)) {
 	        try--;
 		if (try == 0) {
-		  rio_dprint(RIO_DEBUG_TTY, ("Run out of tries - force the bugger shut!\n" ));
+		  rio_dprintk (RIO_DEBUG_TTY, "Run out of tries - force the bugger shut!\n" );
 		  RIOPreemptiveCmd(p, PortP,FCLOSE);
 		  break;
 		}
-		rio_dprint(RIO_DEBUG_TTY, ("Close: PortState:ISOPEN is %d\n", 
-					   PortP->PortState & PORT_ISOPEN));
+		rio_dprintk (RIO_DEBUG_TTY, "Close: PortState:ISOPEN is %d\n", 
+					   PortP->PortState & PORT_ISOPEN);
 
 		if ( p->RIOHalted ) {
 			RIOClearUp( PortP );
@@ -631,7 +676,7 @@
 		RIODelay_ni(PortP, HUNDRED_MS);
 	}
 	rio_spin_lock_irqsave(&PortP->portSem, flags);
-	rio_dprint(RIO_DEBUG_TTY, ("Close: try was %d on completion\n", try ));
+	rio_dprintk (RIO_DEBUG_TTY, "Close: try was %d on completion\n", try );
  
 	/* RIOPreemptiveCmd(p, PortP, FCLOSE); */
 
@@ -661,7 +706,7 @@
 	if (PortP->firstOpen)
 		PortP->firstOpen--;
 	rio_spin_unlock_irqrestore(&PortP->portSem, flags);
-	rio_dprint(RIO_DEBUG_TTY, ("Return from close\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "Return from close\n");
 	return rv;
 }
 
@@ -710,7 +755,7 @@
 RIOClearUp(PortP)
 struct Port *PortP;
 {
-	rio_dprint(RIO_DEBUG_TTY, ("RIOHalted set\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "RIOHalted set\n");
 	PortP->Config = 0;	  /* Direct semaphore */
 	PortP->PortState = 0;
 	PortP->firstOpen = 0;
@@ -740,7 +785,7 @@
 	int		retries = 20; /* at 10 per second -> 2 seconds */
 	unsigned long flags;
 
-	rio_dprint(RIO_DEBUG_TTY, ("entering shortcommand.\n"));
+	rio_dprintk (RIO_DEBUG_TTY, "entering shortcommand.\n");
 #ifdef CHECK
 	CheckPortP( PortP );
 	if ( len < 1 || len > 2 )
@@ -748,7 +793,7 @@
 #endif
 
 	if ( PortP->State & RIO_DELETED ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Short command to deleted RTA ignored\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
 		return RIO_FAIL;
 	}
 	rio_spin_lock_irqsave(&PortP->portSem, flags);
@@ -758,8 +803,8 @@
 	** be free again.
 	*/
 	while ( (PortP->InUse != NOT_INUSE) && !p->RIOHalted ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Waiting for not in use (%d)\n", 
-					   retries));
+		rio_dprintk (RIO_DEBUG_TTY, "Waiting for not in use (%d)\n", 
+					   retries);
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (retries-- <= 0) {
 			return RIO_FAIL;
@@ -770,16 +815,16 @@
 		rio_spin_lock_irqsave(&PortP->portSem, flags);
 	}
 	if ( PortP->State & RIO_DELETED ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Short command to deleted RTA ignored\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Short command to deleted RTA ignored\n");
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		return RIO_FAIL;
 	}
 
 	while ( !can_add_transmit(&PacketP,PortP) && !p->RIOHalted ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Waiting to add short command to queue (%d)\n", retries));
+		rio_dprintk (RIO_DEBUG_TTY, "Waiting to add short command to queue (%d)\n", retries);
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 		if (retries-- <= 0) {
-		  rio_dprint(RIO_DEBUG_TTY, ("out of tries. Failing\n"));
+		  rio_dprintk (RIO_DEBUG_TTY, "out of tries. Failing\n");
 			return RIO_FAIL;
 		}
 		if ( RIODelay_ni(PortP, HUNDRED_MS)==RIO_FAIL ) {
@@ -844,11 +889,11 @@
 	int					Modem = rio_ismodem(dev);
 	int					ioctl_processed;
 
-	rio_dprint(RIO_DEBUG_TTY, ("port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
-			SysPort,cmd,arg,Modem?"Modem":"tty"));
+	rio_dprintk (RIO_DEBUG_TTY, "port ioctl SysPort %d command 0x%x argument 0x%x %s\n",
+			SysPort, cmd, arg, Modem?"Modem":"tty") ;
 
 	if ( SysPort >= RIO_PORTS ) {
-		rio_dprint(RIO_DEBUG_TTY, ("Bad port number %d\n",SysPort));
+		rio_dprintk (RIO_DEBUG_TTY, "Bad port number %d\n", SysPort);
 		return -ENXIO;
 	}
 
@@ -905,22 +950,22 @@
 			return 0;
 
 		case TCRIOTSTATE:
-			rio_dprint(RIO_DEBUG_TTY, ("tbusy/tstop monitoring %sabled\n",
-		 		arg ? "en" : "dis"));
+			rio_dprintk (RIO_DEBUG_TTY, "tbusy/tstop monitoring %sabled\n",
+		 		arg ? "en" : "dis");
 			/* MonitorTstate = 0 ;*/
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP, CONFIG, Modem, OK_TO_SLEEP);
 			return 0;
 
 		case TCRIOSTATE: /* current state of Modem input pins */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOSTATE\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE\n");
 			if (RIOPreemptiveCmd(p, PortP, MGET) == RIO_FAIL)
-				rio_dprint(RIO_DEBUG_TTY, ("TCRIOSTATE command failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "TCRIOSTATE command failed\n");
 			PortP->State |= RIO_BUSY;
 			current = PortP->ModemState;
 			if ( copyout((caddr_t)&current, (int)arg,
 							sizeof(current))==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_TTY, ("Copyout failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Copyout failed\n");
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EFAULT);
 			}
@@ -929,15 +974,15 @@
 
 		case TCRIOMBIS:		/* Set modem lines */
 		case TCRIOMBIC:		/* Clear modem lines */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOMBIS/TCRIOMBIC\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIS/TCRIOMBIC\n");
 			if (cmd == TCRIOMBIS) {
 				uint		state;
 				state = (uint)arg;
 				PortP->ModemState |= (ushort)state;
 				PortP->ModemLines = (ulong) arg;
 				if (RIOPreemptiveCmd(p, PortP, MBIS) == RIO_FAIL)
-					rio_dprint(RIO_DEBUG_TTY, (
-					 "TCRIOMBIS command failed\n"));
+					rio_dprintk (RIO_DEBUG_TTY, 
+					 "TCRIOMBIS command failed\n");
 			}
 			else {
 				uint		state;
@@ -946,17 +991,17 @@
 				PortP->ModemState &= ~(ushort)state;
 				PortP->ModemLines = (ulong) arg;
 				if (RIOPreemptiveCmd(p, PortP, MBIC) == RIO_FAIL)
-					rio_dprint(RIO_DEBUG_TTY, ("TCRIOMBIC command failed\n"));
+					rio_dprintk (RIO_DEBUG_TTY, "TCRIOMBIC command failed\n");
 			}
 			PortP->State |= RIO_BUSY;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOXPON: /* set Xprint ON string */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPON\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPON\n");
 			if ( copyin((int)arg, (caddr_t)PortP->Xprint.XpOn,
 						MAX_XP_CTRL_LEN)==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_TTY, ("Copyin failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
 				PortP->Xprint.XpOn[0] = '\0';
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EFAULT);
@@ -968,10 +1013,10 @@
 			return 0;
 
 		case TCRIOXPOFF: /* set Xprint OFF string */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPOFF\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPOFF\n");
 			if ( copyin( (int)arg, (caddr_t)PortP->Xprint.XpOff,
 						MAX_XP_CTRL_LEN)==COPYFAIL ) {
-				rio_dprint(RIO_DEBUG_TTY, ("Copyin failed\n"));
+				rio_dprintk (RIO_DEBUG_TTY, "Copyin failed\n");
 				PortP->Xprint.XpOff[0] = '\0';
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EFAULT);
@@ -983,10 +1028,10 @@
 			return 0;
 
 		case TCRIOXPCPS: /* set Xprint CPS string */
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPCPS\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPCPS\n");
 			if ( (uint)arg > p->RIOConf.MaxXpCps || 
 					(uint)arg < p->RIOConf.MinXpCps ) {
-				rio_dprint(RIO_DEBUG_TTY, ("%d CPS out of range\n",arg));
+				rio_dprintk (RIO_DEBUG_TTY, "%d CPS out of range\n",arg);
 				rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 				pseterr(EINVAL);
 				return 0;
@@ -996,7 +1041,7 @@
 			return 0;
 
 		case TCRIOXPRINT:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOXPRINT\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOXPRINT\n");
 			if ( copyout((caddr_t)&PortP->Xprint, (int)arg,
 					sizeof(struct Xprint))==COPYFAIL ) {
 			        rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -1006,25 +1051,25 @@
 			return 0;
 
 		case TCRIOIXANYON:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXANYON\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYON\n");
 			PortP->Config |= RIO_IXANY;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOIXANYOFF:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXANYOFF\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXANYOFF\n");
 			PortP->Config &= ~RIO_IXANY;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOIXONON:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXONON\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONON\n");
 			PortP->Config |= RIO_IXON;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
 
 		case TCRIOIXONOFF:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOIXONOFF\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOIXONOFF\n");
 			PortP->Config &= ~RIO_IXON;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			return 0;
@@ -1034,28 +1079,28 @@
 ** Added support for CTS and RTS flow control ioctls :
 */
 		case TCRIOCTSFLOWEN:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOCTSFLOWEN\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWEN\n");
 			PortP->Config |= RIO_CTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 			return 0;
 
 		case TCRIOCTSFLOWDIS:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIOCTSFLOWDIS\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIOCTSFLOWDIS\n");
 			PortP->Config &= ~RIO_CTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 			return 0;
 
 		case TCRIORTSFLOWEN:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIORTSFLOWEN\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWEN\n");
 			PortP->Config |= RIO_RTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 			return 0;
 
 		case TCRIORTSFLOWDIS:
-			rio_dprint(RIO_DEBUG_TTY, ("TCRIORTSFLOWDIS\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "TCRIORTSFLOWDIS\n");
 			PortP->Config &= ~RIO_RTSFLOW;
 			rio_spin_unlock_irqrestore(&PortP->portSem, flags);
 			RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
@@ -1079,13 +1124,13 @@
 		case TCSETAW:
 		case TCSETAF:
 			ioctl_processed++;
-			rio_dprint(RIO_DEBUG_TTY, ("NON POSIX ioctl\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "NON POSIX ioctl\n");
 			ttyseth_pv(PortP, tp, (struct termios *)arg, 0);
 			break;
 		case TCSETAP:	/* posix tcsetattr() */
 		case TCSETAWP:	/* posix tcsetattr() */
 		case TCSETAFP:	/* posix tcsetattr() */
-			rio_dprint(RIO_DEBUG_TTY, ("NON POSIX SYSV ioctl\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "NON POSIX SYSV ioctl\n");
 			ttyseth_pv(PortP, tp, (struct termios *)arg, 1);
 			ioctl_processed++;
 			break;
@@ -1120,7 +1165,7 @@
 #endif
 		case TIOCSETD:
 		case TIOCSETN:
-			rio_dprint(RIO_DEBUG_TTY, ("wait for non-BUSY, semaphore set\n"));
+			rio_dprintk (RIO_DEBUG_TTY, "wait for non-BUSY, semaphore set\n");
 			/*
 			** Wait for drain here, at least as far as the double buffer
 			** being empty.
@@ -1187,8 +1232,8 @@
 
 	PortP->CookMode = RIOCookMode(tp);	/* Set new cooking mode */
 
-	rio_dprint(RIO_DEBUG_TTY, ("RIOIoctl changed %d newcook %d oldcook %d\n",
-			changed,PortP->CookMode,oldcook));
+	rio_dprintk (RIO_DEBUG_TTY, "RIOIoctl changed %d newcook %d oldcook %d\n",
+			changed,PortP->CookMode,oldcook);
 
 #ifdef MODEM_SUPPORT
 	/*
@@ -1211,7 +1256,7 @@
 	*/
 	if (changed || oldcook != PortP->CookMode || (ioctl_processed)) {
 		rio_spin_unlock_irqrestore(&PortP->portSem, flags);
-		rio_dprint(RIO_DEBUG_TTY, ("Ioctl changing the PORT settings\n"));
+		rio_dprintk (RIO_DEBUG_TTY, "Ioctl changing the PORT settings\n");
 		RIOParam(PortP,CONFIG,Modem,OK_TO_SLEEP);	
 		rio_spin_lock_irqsave(&PortP->portSem, flags);
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/rio/unixrup.h linux.17p18/drivers/char/rio/unixrup.h
--- linux.vanilla/drivers/char/rio/unixrup.h	Fri Apr 21 12:46:05 2000
+++ linux.17p18/drivers/char/rio/unixrup.h	Tue Aug  1 07:59:31 2000
@@ -49,7 +49,7 @@
     uint             Id;		/* Id number */
     uint             BaseSysPort;	/* SysPort of first tty on this RTA */
     uint             ModTypes;		/* Modules on this RTA */
-  semtype	RupLock;		/* Lock structure for MPX */
+    spinlock_t	     RupLock;		/* Lock structure for MPX */
 /*    struct lockb     RupLock;	*/	/* Lock structure for MPX */
 };
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/sx.c linux.17p18/drivers/char/sx.c
--- linux.vanilla/drivers/char/sx.c	Fri Apr 21 12:46:06 2000
+++ linux.17p18/drivers/char/sx.c	Tue Aug  1 07:59:32 2000
@@ -33,7 +33,12 @@
  *
  * Revision history:
  * $Log: sx.c,v $
- * Revision 1.32  2000/03/07 90:00:00  wolff,pvdl
+ * Revision 1.33  2000/03/09 10:00:00  pvdl,wolff
+ * - Fixed module and port counting
+ * - Fixed signal handling
+ * - Fixed an Ooops
+ * 
+ * Revision 1.32  2000/03/07 09:00:00  wolff,pvdl
  * - Fixed some sx_dprintk typos
  * - added detection for an invalid board/module configuration
  *
@@ -195,8 +200,8 @@
  * */
 
 
-#define RCS_ID "$Id: sx.c,v 1.32 2000/03/07 17:01:02 wolff, pvdl Exp $"
-#define RCS_REV "$Revision: 1.32 $"
+#define RCS_ID "$Id: sx.c,v 1.33 2000/03/08 10:01:02 wolff, pvdl Exp $"
+#define RCS_REV "$Revision: 1.33 $"
 
 
 #include <linux/module.h>
@@ -414,22 +419,9 @@
  */
 
 static struct file_operations sx_fw_fops = {
-	NULL,	/*	lseek	*/
-	NULL,	/*	read	*/
-	NULL,	/*	write	*/
-	NULL,	/*	readdir	*/
-	NULL,	/*	select	*/
-	sx_fw_ioctl,
-	NULL,	/*	mmap	*/
-	sx_fw_open,
-#ifndef TWO_ZERO
-	NULL,	/*	flush	*/
-#endif
-	sx_fw_release,
-	NULL,	/*	fsync	*/
-	NULL,	/*	fasync	*/
-	NULL,	/*	check_media_change	*/
-	NULL,	/*	revalidate	*/
+	open:		sx_fw_open,
+	release:       	sx_fw_release,
+	ioctl:		sx_fw_ioctl
 };
 
 struct miscdevice sx_fw_device = {
@@ -781,6 +773,7 @@
 	if (rts >= 0) t = rts? (t | OP_RTS): (t & ~OP_RTS);
 	sx_write_channel_byte (port, hi_op, t);
 	sx_dprintk (SX_DEBUG_MODEMSIGNALS, "setsignals: %d/%d\n", dtr, rts);
+
 	func_exit ();
 }
 
@@ -896,6 +889,9 @@
 
 	func_enter2();
 
+	if (!port->gs.tty)
+		return 0;
+
 	/* What is this doing here? -- REW
 	   Ha! figured it out. It is to allow you to get DTR active again
 	   if you've dropped it with stty 0. Moved to set_baud, where it
@@ -1032,8 +1028,8 @@
 		if (c > SERIAL_XMIT_SIZE - port->gs.xmit_tail) 
 			c = SERIAL_XMIT_SIZE - port->gs.xmit_tail;
 
-		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%d) \n", 
-		            c, SERIAL_XMIT_SIZE- port->gs.xmit_tail);
+		sx_dprintk (SX_DEBUG_TRANSMIT, " %d(%ld) \n", 
+		            c, (long)SERIAL_XMIT_SIZE- port->gs.xmit_tail);
 
 		/* If for one reason or another, we can't copy more data, we're done! */
 		if (c == 0) break;
@@ -1057,14 +1053,13 @@
 		sx_disable_tx_interrupts (port);
 	}
 
-	if (port->gs.xmit_cnt <= port->gs.wakeup_chars) {
+	if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) {
 		if ((port->gs.tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
 		    port->gs.tty->ldisc.write_wakeup)
 			(port->gs.tty->ldisc.write_wakeup)(port->gs.tty);
 		sx_dprintk (SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
 		            port->gs.wakeup_chars); 
 		wake_up_interruptible(&port->gs.tty->write_wait);
-		wake_up_interruptible(&port->gs.tty->poll_wait);
 	}
 
 	clear_bit (SX_PORT_TRANSMIT_LOCK, &port->locks);
@@ -1084,7 +1079,7 @@
 	struct tty_struct *tty;
 	int copied=0;
 
-	/* func_enter2 (); */
+	func_enter2 ();
 	tty = port->gs.tty;
 	while (1) {
 		rx_op = sx_read_channel_byte (port, hi_rxopos);
@@ -1139,7 +1134,7 @@
 		/*    tty_schedule_flip (tty); */
 	}
 
-	/* func_exit (); */
+	func_exit ();
 }
 
 /* Inlined: it is called only once. Remove the inline if you add another 
@@ -1309,6 +1304,8 @@
 
 	sx_interrupt (0, board, NULL);
 
+	init_timer(&board->timer);
+
 	board->timer.expires = jiffies + sx_poll;
 	add_timer (&board->timer);
 	func_exit ();
@@ -1404,7 +1401,7 @@
 	func_enter();
 
 	port->gs.flags &= ~ GS_ACTIVE;
-	if (port->gs.tty && port->gs.tty->termios->c_cflag & HUPCL) {
+	if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) {
 		sx_setsignals (port, 0, 0);
 		sx_reconfigure_port(port);
 	}
@@ -1421,7 +1418,6 @@
  *               interface with the rest of the system                    *
  * ********************************************************************** */
 
-
 static int sx_fw_open(struct inode *inode, struct file *filp)
 {
 	func_enter ();
@@ -1440,6 +1436,7 @@
 }
 
 
+
 static int sx_open  (struct tty_struct * tty, struct file * filp)
 {
 	struct sx_port *port;
@@ -1467,6 +1464,8 @@
 
 	tty->driver_data = port;
 	port->gs.tty = tty;
+	if (!port->gs.count)
+		MOD_INC_USE_COUNT;
 	port->gs.count++;
 
 	sx_dprintk (SX_DEBUG_OPEN, "starting port\n");
@@ -1478,19 +1477,13 @@
 	sx_dprintk (SX_DEBUG_OPEN, "done gs_init\n");
 	if (retval) {
 		port->gs.count--;
+		if (port->gs.count) MOD_DEC_USE_COUNT;
 		return retval;
 	}
 
 	port->gs.flags |= GS_ACTIVE;
 	sx_setsignals (port, 1,1);
 
-	sx_dprintk (SX_DEBUG_OPEN, "before inc_use_count (count=%d.\n", 
-	            port->gs.count);
-	if (port->gs.count == 1) {
-		MOD_INC_USE_COUNT;
-	}
-	sx_dprintk (SX_DEBUG_OPEN, "after inc_use_count\n");
-
 #if 0
 	if (sx_debug & SX_DEBUG_OPEN)
 		my_hd ((unsigned char *)port, sizeof (*port));
@@ -1502,8 +1495,8 @@
 
 	if (sx_send_command (port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
 		printk (KERN_ERR "sx: Card didn't respond to LOPEN command.\n");
-		MOD_DEC_USE_COUNT;
 		port->gs.count--;
+		if (!port->gs.count) MOD_DEC_USE_COUNT;
 		return -EIO;
 	}
 
@@ -1512,8 +1505,10 @@
 	            retval, port->gs.count);
 
 	if (retval) {
-		MOD_DEC_USE_COUNT;
-		port->gs.count--;
+		/* 
+		 * Don't lower gs.count here because sx_close() will be called later
+		 */ 
+
 		return retval;
 	}
 	/* tty->low_latency = 1; */
@@ -1545,7 +1540,24 @@
    exit minicom.  I expect an "oops".  -- REW */
 static void sx_hungup (void *ptr)
 {
+	struct sx_port *port = ptr; 
 	func_enter ();
+
+	/* Don't force the SX card to close. mgetty doesn't like it !!!!!! -- pvdl */
+	/* For some reson we added this code. Don't know why anymore ;-) -- pvdl */
+	/*
+	sx_setsignals (port, 0, 0);
+	sx_reconfigure_port(port);	
+	sx_send_command (port, HS_CLOSE, 0, 0);
+
+	if (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED) {
+		if (sx_send_command (port, HS_FORCE_CLOSED, -1, HS_IDLE_CLOSED) != 1) {
+			printk (KERN_ERR 
+			        "sx: sent the force_close command, but card didn't react\n");
+		} else
+			sx_dprintk (SX_DEBUG_CLOSE, "sent the force_close command.\n");
+	}
+	*/
 	MOD_DEC_USE_COUNT;
 	func_exit ();
 }
@@ -1558,6 +1570,9 @@
 	int to = 5 * HZ; 
 
 	func_enter ();
+
+	sx_setsignals (port, 0, 0);
+	sx_reconfigure_port(port);	
 	sx_send_command (port, HS_CLOSE, 0, 0);
 
 	while (to-- && (sx_read_channel_byte (port, hi_hstat) != HS_IDLE_CLOSED)) {
@@ -1578,6 +1593,11 @@
 	sx_dprintk (SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 
 	            5 * HZ - to - 1, port->gs.count);
 
+	if(port->gs.count) {
+		sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", port->gs.count);
+		port->gs.count = 0;
+	}
+
 	MOD_DEC_USE_COUNT;
 	func_exit ();
 }
@@ -2326,6 +2346,13 @@
 #ifdef NEW_WRITE_LOCKING
 			port->gs.port_write_sem = MUTEX;
 #endif
+			/*
+			 * Initializing wait queue
+			 */
+			/*
+			init_waitqueue_head(&port->gs.open_wait);
+			init_waitqueue_head(&port->gs.close_wait); 		
+			*/
 			port++;
 		}
 	}
@@ -2367,7 +2394,7 @@
 	return 0;
 }
 
-
+#ifdef MODULE
 static void sx_release_drivers(void)
 {
 	func_enter();
@@ -2375,6 +2402,7 @@
 	tty_unregister_driver(&sx_callout_driver);
 	func_exit();
 }
+#endif
 
 #ifdef TWO_ZERO
 #define PDEV unsigned char pci_bus, unsigned pci_fun
@@ -2455,6 +2483,10 @@
 		while ((pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
 		                                PCI_DEVICE_ID_SPECIALIX_SX_XIO_IO8, 
 			                              pdev))) {
+		  /*
+			if (pci_enable_device(pdev))
+				continue;
+		  */
 #else
 			for (i=0;i< SX_NBOARDS;i++) {
 				if (pcibios_find_device (PCI_VENDOR_ID_SPECIALIX, 
@@ -2490,10 +2522,14 @@
 				                      &tint);
 			else
 				pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2,
-				                      &tint);
-			board->hw_base = tint & PCI_BASE_ADDRESS_MEM_MASK;
+						      &tint);
 			board->base2 = 
 			board->base = (ulong) ioremap(board->hw_base, WINDOW_LEN (board));
+			if (!board->base) {
+				printk(KERN_ERR "ioremap failed\n");
+				/* XXX handle error */
+			}
+
 			/* Most of the stuff on the CF board is offset by
 			   0x18000 ....  */
 			if (IS_CF_BOARD (board)) board->base += 0x18000;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/synclink.c linux.17p18/drivers/char/synclink.c
--- linux.vanilla/drivers/char/synclink.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/synclink.c	Tue Aug  1 07:59:33 2000
@@ -1,7 +1,7 @@
 /*
  * linux/drivers/char/synclink.c
  *
- * ==FILEDATE 20000220==
+ * ==FILEDATE 20000705==
  *
  * Device driver for Microgate SyncLink ISA and PCI
  * high speed multiprotocol serial adapters.
@@ -390,7 +390,7 @@
 	char netname[10];
 	struct net_device *netdev;
 	struct net_device_stats netstats;
-#if LINUX_VERSION_CODE >= VERSION(2,3,43) 
+#if LINUX_VERSION_CODE >= VERSION(2,2,16) 
 	struct net_device netdevice;
 #endif
 #endif
@@ -965,7 +965,7 @@
 #endif
 
 static char *driver_name = "SyncLink serial driver";
-static char *driver_version = "1.18";
+static char *driver_version = "1.19";
 
 static struct tty_driver serial_driver, callout_driver;
 static int serial_refcount;
@@ -5964,12 +5964,12 @@
 {
 	if ( info->bus_type == MGSL_BUS_TYPE_PCI ) {
 		int i;
-		volatile u32 readval;
+		u32 readval;
 
 		/* Set BIT30 of Misc Control Register */
 		/* (Local Control Register 0x50) to force reset of USC. */
 
-		u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
+		volatile u32 *MiscCtrl = (u32 *)(info->lcr_base + 0x50);
 		u32 *LCR0BRDR = (u32 *)(info->lcr_base + 0x28);
 
 		info->misc_ctrl_value |= BIT30;
@@ -6985,8 +6985,8 @@
 	unsigned int i;
 	char *TmpPtr;
 	BOOLEAN rc = TRUE;
-	volatile unsigned short status;
-	volatile unsigned long EndTime;
+	unsigned short status;
+	unsigned long EndTime;
 	unsigned long flags;
 	MGSL_PARAMS tmp_params;
 
@@ -7357,7 +7357,6 @@
 }	/* End Of mgsl_memory_test() */
 
 
-#pragma optimize( "", off )
 /* mgsl_load_pci_memory()
  * 
  * 	Load a large block of data into the PCI shared memory.
@@ -7420,7 +7419,6 @@
 	memcpy( TargetPtr, SourcePtr, count % PCI_LOAD_INTERVAL );
 
 }	/* End Of mgsl_load_pci_memory() */
-#pragma optimize( "", on )
 
 void mgsl_trace_block(struct mgsl_struct *info,const char* data, int count, int xmit)
 {
@@ -7575,7 +7573,7 @@
 
 	sprintf(info->netname,"mgsl%d",info->line);
 
-#if LINUX_VERSION_CODE < VERSION(2,3,43) 
+#if LINUX_VERSION_CODE < VERSION(2,2,16) 
 	info->netdev = &info->pppdev.dev;
 #else
 	info->if_ptr = &info->pppdev;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/toshiba.c linux.17p18/drivers/char/toshiba.c
--- linux.vanilla/drivers/char/toshiba.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/char/toshiba.c	Tue Aug  1 07:59:33 2000
@@ -0,0 +1,561 @@
+/* toshiba.c -- Linux driver for accessing the SMM on Toshiba laptops
+ *
+ * Copyright (c) 1996-2000  Jonathan A. Buzzard (jonathan@buzzard.org.uk)
+ *
+ * Valuable assistance and patches from:
+ *     Tom May <tom@you-bastards.com>
+ *     Rob Napier <rnapier@employees.org>
+ *
+ * Fn status port numbers for machine ID's courtesy of
+ *     0xfc08: Garth Berry <garth@itsbruce.net>
+ *     0xfc11: Spencer Olson <solson@novell.com>
+ *     0xfc13: Claudius Frankewitz <kryp@gmx.de>
+ *     0xfc15: Tom May <tom@you-bastards.com>
+ *     0xfc17: Dave Konrad <konrad@xenia.it>
+ *     0xfc1a: George Betzos <betzos@engr.colostate.edu>
+ *     0xfc1d: Arthur Liu <armie@slap.mine.nu>
+ *
+ * WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
+ *
+ *   This code is covered by the GNU GPL and you are free to make any
+ *   changes you wish to it under the terms of the license. However the
+ *   code has the potential to render your computer and/or someone else's
+ *   unusable. Please proceed with care when modifying the code.
+ *
+ * Note: Unfortunately the laptop hardware can close the System Configuration
+ *       Interface on it's own accord. It is therefore necessary for *all*
+ *       programs using this driver to be aware that *any* SCI call can fail at
+ *       *any* time. It is up to any program to be aware of this eventuality
+ *       and take appropriate steps.
+ *
+ * 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, 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.
+ *
+ * The information used to write this driver has been obtained by reverse
+ * engineering the software supplied by Toshiba for their portable computers in
+ * strict accordance with the European Council Directive 92/250/EEC on the legal
+ * protection of computer programs, and it's implementation into English Law by
+ * the Copyright (Computer Programs) Regulations 1992 (S.I. 1992 No.3233).
+ *
+ */
+
+#define TOSH_VERSION "1.7 22/6/2000"
+#define TOSH_DEBUG 0
+
+#include<linux/module.h>
+#include<linux/version.h>
+#include<linux/kernel.h>
+#include<linux/sched.h>
+#include<linux/types.h>
+#include<linux/fcntl.h>
+#include<linux/miscdevice.h>
+#include<linux/ioport.h>
+#include<asm/io.h>
+#include<asm/uaccess.h>
+#include<asm/init.h>
+#include<linux/stat.h>
+#include<linux/proc_fs.h>
+
+#include<linux/toshiba.h>
+
+#define TOSH_MINOR_DEV 181
+
+static int tosh_id = 0x0000;
+static int tosh_bios = 0x0000;
+static int tosh_date = 0x0000;
+static int tosh_sci = 0x0000;
+static int tosh_fan = 0;
+static int tosh_start = 0;
+static int tosh_extent = 0;
+
+static int tosh_fn = 0;
+
+MODULE_PARM(tosh_fn, "i");
+
+
+static int tosh_get_info(char *, char **, off_t, int, int);
+static int tosh_open(struct inode *ip, struct file *);
+static int tosh_release(struct inode *, struct file *);
+static int tosh_ioctl(struct inode *, struct file *, unsigned int,
+	unsigned long);
+
+
+static struct file_operations tosh_fops = {
+	NULL,		/* lseek */
+	NULL,		/* read */
+	NULL,		/* write */
+	NULL,		/* readdir */  
+	NULL,		/* select */ 
+	tosh_ioctl,	/* ioctl */
+	NULL,		/* mmap */
+	tosh_open,	/* open */
+	NULL,		/* flush */
+	tosh_release, 	/* close */
+	NULL,		/* fsync */
+	NULL		/* fasync */
+};
+
+static struct miscdevice tosh_device = {
+	TOSH_MINOR_DEV,
+	"toshiba",
+	&tosh_fops
+};
+
+static struct proc_dir_entry tosh_proc_entry = {
+	0, 7, "toshiba", S_IFREG|S_IRUGO, 1, 0, 0, 33, NULL, tosh_get_info, NULL
+};
+
+/*
+ * Read the Fn key status
+ */
+static int tosh_fn_status(void)
+{
+        unsigned char scan;
+	unsigned long flags;
+
+	if (tosh_fn!=0) {
+		scan = inb(tosh_fn);
+	} else {
+		save_flags(flags);
+		cli();
+		outb(0x8e, 0xe4);
+		scan = inb(0xe5);
+		restore_flags(flags);
+	}
+
+        return (int) scan;
+}
+
+
+/*
+ * At some point we need to emulate setting the HDD auto off times for
+ * the new laptops. We can do this by calling the ide_ioctl on /dev/hda.
+ * The values we need for the various times are
+ *
+ *    Disabled   0x00
+ *    1 minute   0x0c
+ *    3 minutes  0x24
+ *    5 minutes  0x3c
+ *   10 minutes  0x78
+ *   15 minutes  0xb4
+ *   20 minutes  0xf0
+ *   30 minutes  0xf1
+ *
+ */
+/*static int tosh_emulate_hdd(SMMRegisters *regs)
+{
+	return 0;
+}*/
+
+
+/*
+ * For the Portage 610CT and the Tecra 700CS/700CDT emulate the HCI fan function
+ */
+static int tosh_emulate_fan(SMMRegisters *regs)
+{
+	unsigned long eax,ecx,flags;
+	unsigned char al;
+
+	eax = regs->eax & 0xff00;
+	ecx = regs->ecx & 0xffff;
+
+	/* Portage 610CT */
+
+	if (tosh_id==0xfccb) {
+		if (eax==0xfe00) {
+			/* fan status */
+			save_flags(flags);
+			cli();
+			outb(0xbe, 0xe4);
+			al = inb(0xe5);
+			restore_flags(flags);
+			regs->eax = 0x00;
+			regs->ecx = (unsigned int) (al & 0x01);
+		}
+		if ((eax==0xff00) && (ecx==0x0000)) {
+			/* fan off */
+			save_flags(flags);
+			cli();
+			outb(0xbe, 0xe4);
+			al = inb(0xe5);
+			outb(0xbe, 0xe4);
+			outb (al | 0x01, 0xe5);
+			restore_flags(flags);
+			regs->eax = 0x00;
+			regs->ecx = 0x00;
+		}
+		if ((eax==0xff00) && (ecx==0x0001)) {
+			/* fan on */
+			save_flags(flags);
+			cli();
+			outb(0xbe, 0xe4);
+			al = inb(0xe5);
+			outb(0xbe, 0xe4);
+			outb(al & 0xfe, 0xe5);
+			restore_flags(flags);
+			regs->eax = 0x00;
+			regs->ecx = 0x01;
+		}
+	}
+
+	/* Tecra 700CS/CDT */
+
+	if (tosh_id==0xfccc) {
+		if (eax==0xfe00) {
+			/* fan status */
+			save_flags(flags);
+			cli();
+			outb(0xe0, 0xe4);
+			al = inb(0xe5);
+			restore_flags(flags);
+			regs->eax = 0x00;
+			regs->ecx = al & 0x01;
+		}
+		if ((eax==0xff00) && (ecx==0x0000)) {
+			/* fan off */
+			save_flags(flags);
+			cli();
+			outb(0xe0, 0xe4);
+			al = inb(0xe5);
+			outw(0xe0 | ((al & 0xfe) << 8), 0xe4);
+			restore_flags(flags);
+			regs->eax = 0x00;
+			regs->ecx = 0x00;
+		}
+		if ((eax==0xff00) && (ecx==0x0001)) {
+			/* fan on */
+			save_flags(flags);
+			cli();
+			outb(0xe0, 0xe4);
+			al = inb(0xe5);
+			outw(0xe0 | ((al | 0x01) << 8), 0xe4);
+			restore_flags(flags);
+			regs->eax = 0x00;
+			regs->ecx = 0x01;
+		}
+	}
+
+	return 0;
+}
+
+
+/*
+ * Put the laptop into System Management Mode
+ */
+static int tosh_smm(SMMRegisters *regs)
+{
+	int eax;
+
+	asm ("# load the values into the registers\n\t" \
+		"pushl %%eax\n\t" \
+		"movl 0(%%eax),%%edx\n\t" \
+		"push %%edx\n\t" \
+		"movl 4(%%eax),%%ebx\n\t" \
+		"movl 8(%%eax),%%ecx\n\t" \
+		"movl 12(%%eax),%%edx\n\t" \
+		"movl 16(%%eax),%%esi\n\t" \
+		"movl 20(%%eax),%%edi\n\t" \
+		"popl %%eax\n\t" \
+		"# call the System Management mode\n\t" \
+		"inb $0xb2,%%al\n\t"
+		"# fill out the memory with the values in the registers\n\t" \
+		"xchgl %%eax,(%%esp)\n\t"
+		"movl %%ebx,4(%%eax)\n\t" \
+		"movl %%ecx,8(%%eax)\n\t" \
+		"movl %%edx,12(%%eax)\n\t" \
+		"movl %%esi,16(%%eax)\n\t" \
+		"movl %%edi,20(%%eax)\n\t" \
+		"popl %%edx\n\t" \
+		"movl %%edx,0(%%eax)\n\t" \
+		"# setup the return value to the carry flag\n\t" \
+		"lahf\n\t" \
+		"shrl $8,%%eax\n\t" \
+		"andl $1,%%eax\n" \
+		: "=a" (eax)
+		: "a" (regs)
+		: "%ebx", "%ecx", "%edx", "%esi", "%edi", "memory");
+
+	return eax;
+}
+
+
+static int tosh_open(struct inode *ip, struct file *fp)
+{
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+
+static int tosh_release(struct inode *ip, struct file *fp)
+{
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+
+static int tosh_ioctl(struct inode *ip, struct file *fp, unsigned int cmd,
+	unsigned long arg)
+{
+	SMMRegisters regs;
+	unsigned short ax,bx;
+	int err;
+
+	if (!arg)
+		return -EINVAL;
+
+	if(copy_from_user(&regs, (SMMRegisters *) arg, sizeof(SMMRegisters)))
+		return -EFAULT;
+
+	switch (cmd) {
+		case TOSH_SMM:
+			ax = regs.eax & 0xff00;
+			bx = regs.ebx & 0xffff;
+			/* block HCI calls to read/write memory & PCI devices */
+			if (((ax==0xff00) || (ax==0xfe00)) && (bx>0x0069))
+				return -EINVAL;
+
+			/* do we need to emulate the fan ? */
+			if (tosh_fan==1) {
+				if (((ax==0xf300) || (ax==0xf400)) && (bx==0x0004)) {
+					err = tosh_emulate_fan(&regs);
+					break;
+				}
+			}
+			err = tosh_smm(&regs);
+			break;
+		default:
+			return -EINVAL;
+	}
+
+        if(copy_to_user((SMMRegisters *) arg, &regs, sizeof(SMMRegisters)))
+        	return -EFAULT;
+
+	return (err==0) ? 0:-EINVAL;
+}
+
+
+/*
+ * Print the information for /proc/toshiba
+ */
+int tosh_get_info(char *buffer, char **start, off_t fpos, int length, int dummy)
+{
+	char *temp;
+	int key;
+
+	temp = buffer;
+	key = tosh_fn_status();
+
+	/* Arguments
+	     0) Linux driver version (this will change if format changes)
+	     1) Machine ID
+	     2) SCI version
+	     3) BIOS version (major, minor)
+	     4) BIOS date (in SCI date format)
+	     5) Fn Key status
+	*/
+
+	temp += sprintf(temp, "1.1 0x%04x %d.%d %d.%d 0x%04x 0x%02x\n",
+		tosh_id,
+		(tosh_sci & 0xff00)>>8,
+		tosh_sci & 0xff,
+		(tosh_bios & 0xff00)>>8,
+		tosh_bios & 0xff,
+		tosh_date,
+		key);
+
+	return temp-buffer;
+}
+
+
+/*
+ * Determine which port to use for the Fn key status
+ */
+static void tosh_set_fn_port(void)
+{
+	switch (tosh_id) {
+		case 0xfc11: case 0xfc13: case 0xfc15: case 0xfc1a:
+			tosh_fn = 0x62;
+			break;
+		case 0xfc08: case 0xfc17: case 0xfc1d: case 0xfcd1:
+		case 0xfce0: case 0xfce2:
+			tosh_fn = 0x68;
+			break;
+		default:
+			tosh_fn = 0x00;
+			break;
+	}
+
+	return;
+}
+
+
+/*
+ * Get the machine identification number of the current model
+ */
+static int tosh_get_machine_id(void)
+{
+	int id;
+	SMMRegisters regs;
+	unsigned short bx,cx;
+	unsigned long address;
+
+	id = (0x100*(int) readb(0xffffe))+((int) readb(0xffffa));
+	
+	/* do we have a SCTTable machine identication number on our hands */
+
+	if (id==0xfc2f) {
+
+		/* start by getting a pointer into the BIOS */
+
+		regs.eax = 0xc000;
+		regs.ebx = 0x0000;
+		regs.ecx = 0x0000;
+		tosh_smm(&regs);
+		bx = (unsigned short) (regs.ebx & 0xffff);
+
+		/* At this point in the Toshiba routines under MS Windows
+		   the bx register holds 0xe6f5. However my code is producing
+		   a different value! For the time being I will just fudge the
+		   value. This has been verified on a Satellite Pro 430CDT,
+		   Tecra 750CDT, Tecra 780DVD and Satellite 310CDT. */
+#if TOSH_DEBUG
+		printk("toshiba: debugging ID ebx=0x%04x\n", regs.ebx);
+#endif
+		bx = 0xe6f5;
+
+		/* now twiddle with our pointer a bit */
+
+		address = 0x000f0000+bx;
+		cx = readw(address);
+		address = 0x000f0009+bx+cx;
+		cx = readw(address);
+		address = 0x000f000a+cx;
+		cx = readw(address);
+
+		/* now construct our machine identification number */
+
+		id = ((cx & 0xff)<<8)+((cx & 0xff00)>>8);
+	}
+
+	return id;
+}
+
+
+/*
+ * Probe for the presence of a Toshiba laptop
+ *
+ *   returns and non-zero if unable to detect the presence of a Toshiba
+ *   laptop, otherwise zero and determines the Machine ID, BIOS version and
+ *   date, and SCI version.
+ */
+int tosh_probe(void)
+{
+	int major,minor,day,year,month,flag;
+	SMMRegisters regs;
+
+	/* call the Toshiba SCI support check routine */
+	
+	regs.eax = 0xf0f0;
+	regs.ebx = 0x0000;
+	regs.ecx = 0x0000;
+	flag = tosh_smm(&regs);
+
+	/* if this is not a Toshiba laptop carry flag is set and ah=0x86 */
+
+	if ((flag==1) || ((regs.eax & 0xff00)==0x8600)) {
+		printk("toshiba: not a supported Toshiba laptop\n");
+		return -ENODEV;
+	}
+
+	/* if we get this far then we are running on a Toshiba (probably)! */
+
+	tosh_sci = regs.edx & 0xffff;
+	
+	/* next get the machine ID of the current laptop */
+
+	tosh_id = tosh_get_machine_id();
+
+	/* get the BIOS version */
+
+	major = readb(0xfe009)-'0';
+	minor = ((readb(0xfe00b)-'0')*10)+(readb(0xfe00c)-'0');
+	tosh_bios = (major*0x100)+minor;
+
+	/* get the BIOS date */
+
+	day = ((readb(0xffff5)-'0')*10)+(readb(0xffff6)-'0');
+	month = ((readb(0xffff8)-'0')*10)+(readb(0xffff9)-'0');
+	year = ((readb(0xffffb)-'0')*10)+(readb(0xffffc)-'0');
+	tosh_date = (((year-90) & 0x1f)<<10) | ((month & 0xf)<<6)
+		| ((day & 0x1f)<<1);
+
+
+	/* in theory we should check the ports we are going to use for the
+	   fn key detection (and the fan on the Portage 610/Tecra700), and
+	   then request them to stop other drivers using them. However as
+	   the keyboard driver grabs 0x60-0x6f and the pic driver grabs
+	   0xa0-0xbf we can't. We just have to live dangerously and use the
+	   ports anyway, oh boy! */
+
+
+	/* do we need to emulate the fan? */
+
+	if ((tosh_id==0xfccb) || (tosh_id==0xfccc))
+		tosh_fan = 1;
+
+	return 0;
+}
+
+int __init tosh_init(void)
+{
+	/* are we running on a Toshiba laptop */
+
+	if (tosh_probe()!=0)
+		return -EIO;
+
+	printk(KERN_INFO "Toshiba System Managment Mode driver v"
+		TOSH_VERSION"\n");
+
+	/* set the port to use for Fn status if not specified as a parameter */
+
+	if (tosh_fn==0x00)
+		tosh_set_fn_port();
+
+	/* register the device file */
+
+	misc_register(&tosh_device);
+
+	/* register the proc entry */
+	proc_register(&proc_root, &tosh_proc_entry);
+	return 0;
+}
+
+#ifdef MODULE
+int init_module(void)
+{
+	return tosh_init();
+}
+
+void cleanup_module(void)
+{
+	/* remove the proc entry */
+	proc_unregister(&proc_root, tosh_proc_entry.low_ino);
+
+	/* unregister the device file */
+	misc_deregister(&tosh_device);
+
+	/* release ports */
+	release_region(tosh_start, tosh_extent);
+
+	return;
+}
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/tty_io.c linux.17p18/drivers/char/tty_io.c
--- linux.vanilla/drivers/char/tty_io.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/char/tty_io.c	Tue Aug  1 07:59:33 2000
@@ -135,6 +135,8 @@
 #ifdef CONFIG_HWC_CONSOLE
 extern long hwc_console_init(long);
 #endif
+extern int rio_init(void);
+extern int sx_init(void);
 
 #ifndef MIN
 #define MIN(a,b)	((a) < (b) ? (a) : (b))
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/char/vt.c linux.17p18/drivers/char/vt.c
--- linux.vanilla/drivers/char/vt.c	Fri Apr 21 12:46:07 2000
+++ linux.17p18/drivers/char/vt.c	Tue Aug  1 07:59:33 2000
@@ -590,6 +590,8 @@
 
 	case KDGETKEYCODE:
 	case KDSETKEYCODE:
+		if(!suser())
+			perm=0;
 		return do_kbkeycode_ioctl(cmd, (struct kbkeycode *)arg, perm);
 
 	case KDGKBENT:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/i2o/i2o_block.c linux.17p18/drivers/i2o/i2o_block.c
--- linux.vanilla/drivers/i2o/i2o_block.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/i2o/i2o_block.c	Tue Aug  1 07:59:34 2000
@@ -166,13 +166,14 @@
 
 static int i2ob_install_device(struct i2o_controller *, struct i2o_device *, int);
 static void i2ob_end_request(struct request *);
-static void i2ob_request(struct request  * q);
+static void i2ob_request(void);
 static int do_i2ob_revalidate(kdev_t, int);
 static int i2ob_query_device(struct i2ob_device *, int, int, void*, int);
 static int i2ob_evt(void *);
 
 static int evt_pid = 0;
 static int evt_running = 0;
+static int scan_unit = 0;
 
 static void i2ob_new_device(struct i2o_controller *, struct i2o_device *);
 static void i2ob_del_device(struct i2o_controller *, struct i2o_device *);
@@ -375,14 +376,14 @@
 		
 	}
 
-	 if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
-	 {
-		  spin_lock(&i2ob_evt_lock);
-		  memcpy(&evt_msg, m, msg->size);
-		  spin_unlock(&i2ob_evt_lock);
-		  wake_up_interruptible(&i2ob_evt_wait);
-		  return;
-	 }
+	if(msg->function == I2O_CMD_UTIL_EVT_REGISTER)
+	{
+		spin_lock(&i2ob_evt_lock);
+		memcpy(&evt_msg, m, msg->size);
+		spin_unlock(&i2ob_evt_lock);
+		wake_up_interruptible(&i2ob_evt_wait);
+		return;
+	}
 	if(!dev->i2odev)
 	{
 		/*
@@ -404,18 +405,17 @@
 		return;
 	}
 		 
-		/*
-		 *      Lets see what is cooking. We stuffed the
-		 *      request in the context.
-		 */
+	/*
+	 *      Lets see what is cooking. We stuffed the
+	 *      request in the context.
+	 */
 
-		ireq=&i2ob_queue[m[3]];
-		st=m[4]>>24;
+	ireq=&i2ob_queue[m[3]];
+	st=m[4]>>24;
 	
-		if(st!=0)
-		{
-			char *bsa_errors[] =
-			{
+	if(st!=0)
+	{
+		char *bsa_errors[] = {
 			"Success",
 			"Media Error",
 			"Failure communicating to device",
@@ -430,59 +430,57 @@
 			"Device is write protected",
 			"Device has reset",
 			"Volume has changed, waiting for acknowledgement"
-			};
-			printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]);
+		};
 
-			if(m[4]&0x00FF0000)
-				printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF);
-			printk("\n");
+		printk(KERN_ERR "\n/dev/%s error: %s", dev->i2odev->dev_name, bsa_errors[m[4]&0XFFFF]);
 
-			ireq->req->errors++;	
+		if(m[4]&0x00FF0000)
+			printk(" - DDM attempted %d retries", (m[4]>>16)&0x00FF);
+		printk("\n");
 
-			if (ireq->req->errors < MAX_I2OB_RETRIES)
-			{
-				u32 retry_msg;
+		ireq->req->errors++;	
+		if (ireq->req->errors < MAX_I2OB_RETRIES)
+		{
+			u32 retry_msg;
+			printk(KERN_ERR "i2ob: attempting retry %d for request %p\n",ireq->req->errors+1,ireq->req);
+    				
+			/* 
+			 * Get a message for this retry.
+			 */
+	  		retry_msg = i2ob_get(dev);
 
-  				printk(KERN_ERR "i2ob: attempting retry %d for request %p\n",ireq->req->errors+1,ireq->req);
-     				
-				  /* 
-				 * Get a message for this retry.
+	  		/* 
+			 * If we cannot get a message then
+			 * forget the retry and fail the
+			 * request.   Note that since this is
+			 * being called from the interrupt 
+			 * handler, a request has just been 
+			 * completed and there will most likely 
+			 * be space on the inbound message
+			 * fifo so this won't happen often.
+			 */
+	  		if(retry_msg!=0xFFFFFFFF)
+			{
+				/*
+				 * Decrement the queue depth since
+				 * this request has completed and
+				 * it will be incremented again when
+				 * i2ob_send is called below.
 				 */
-		  		retry_msg = i2ob_get(dev);
-
-		  		/* 
-				 * If we cannot get a message then
-				 * forget the retry and fail the
-				 * request.   Note that since this is
-				 * being called from the interrupt 
-				 * handler, a request has just been 
-				 * completed and there will most likely 
-				 * be space on the inbound message
-				 * fifo so this won't happen often.
+				atomic_dec(&queue_depth);
+				/*
+				 * Send the request again.
 				 */
-		  		if(retry_msg!=0xFFFFFFFF)
-				{
-					  /*
-					   * Decrement the queue depth since
-					   * this request has completed and
-					   * it will be incremented again when
-					   * i2ob_send is called below.
-					   */
-					  atomic_dec(&queue_depth);
-
-					  /*
-					   * Send the request again.
-					   */
-					  i2ob_send(retry_msg, dev,ireq,i2ob[unit].start_sect, (unit&0xF0));
-					/*
-					 * Don't fall through.
-					 */
-					return;
-				}
-			}		
-		}
-		else
-			ireq->req->errors = 0;
+				i2ob_send(retry_msg, dev,ireq,i2ob[unit].start_sect, (unit&0xF0));
+				/*
+				 * Don't fall through.
+				 */
+				return;
+			}
+		}		
+	}
+	else
+		ireq->req->errors = 0;
 		
 	/*
 	 *	Dequeue the request. We use irqsave locks as one day we
@@ -498,7 +496,7 @@
 	 */
 	 
 	atomic_dec(&queue_depth);
-	i2ob_request(NULL);
+	i2ob_request();
 	spin_unlock_irqrestore(&io_request_lock, flags);
 }
 
@@ -675,7 +673,7 @@
 	/* 
 	 * Restart any requests.
 	 */
-	i2ob_request(NULL);
+	i2ob_request();
 
 	/* 
 	 * Free the lock.
@@ -691,7 +689,7 @@
  *	we use it.
  */
 
-static void i2ob_request(struct request * q)
+static void i2ob_request(void)
 {
 	unsigned long flags;
 	struct request *req;
@@ -732,10 +730,9 @@
 			CURRENT = CURRENT->next;
 			req->sem = NULL;	
 			i2ob_end_request(req);	
+			continue;
 		}
 
-		else
-		{
 		/* Get a message */
 		m = i2ob_get(dev);
 
@@ -778,7 +775,6 @@
 		ireq->req = req;
 
 		i2ob_send(m, dev, ireq, i2ob[unit].start_sect, (unit&0xF0));
-		} 
 	}
 }
 
@@ -1190,68 +1186,127 @@
 	return 0;
 }
 
-static void i2ob_probe(void)
+static int i2ob_scan(int bios)
 {
 	int i;
-	int unit = 0;
 	int warned = 0;
+	struct i2o_device *d, *b=NULL;
+	struct i2o_controller *c;
+	struct i2ob_device *dev;
 		
 	for(i=0; i< MAX_I2O_CONTROLLERS; i++)
 	{
-		struct i2o_controller *c=i2o_find_controller(i);
-		struct i2o_device *d;
-	
+		c=i2o_find_controller(i);
+
 		if(c==NULL)
 			continue;
 
-		for(d=c->devices;d!=NULL;d=d->next)
+		/* 
+		 * 	The device list connected to the I2O Controller is doubly linked
+		 *	Here we traverse the end of the list , and start claiming devices
+		 *	from that end. This assures that within an I2O controller atleast
+		 *	the newly created volumes get claimed after the older ones, thus
+		 *	mapping to same major/minor (and hence device file name) after 
+		 *	every reboot.
+		 *	The exception being: 
+		 *	1. If there was a TID reuse.
+		 *	2. There was more than one I2O controller. 
+		 */
+
+		if(!bios)
 		{
-		if(d->lct_data.class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE)
+			for (d=c->devices;d!=NULL;d=d->next)
+				if(d->next == NULL)
+					b = d;
+		}
+		else
+			b = c->devices;
+		
+		while(b != NULL)
+		{
+			d=b;
+			if(bios)
+				b = b->next;
+			else
+				b = b->prev;
+			
+			if(d->lct_data.class_id!=I2O_CLASS_RANDOM_BLOCK_STORAGE)
 				continue;
-
 			if(d->lct_data.user_tid != 0xFFF)
 				continue;
-
-			   if(i2o_claim_device(d, &i2o_block_handler))
-			   {
-				    printk(KERN_WARNING "i2o_block: Controller %d, TID %d\n", c->unit,
-					     d->lct_data.tid);
-				    printk(KERN_WARNING "\tDevice refused claim! Skipping installation\n");
-				    continue;
-			   }
-
-			if(unit<MAX_I2OB<<4)
+			if(bios)
 			{
- 				/*
+				if(d->lct_data.bios_info != 0x80)
+					continue;
+				printk(KERN_INFO "Claiming as Boot device: Controller %d, TID %d\n", c->unit, d->lct_data.tid);
+			}
+			else
+			{
+				if(d->lct_data.bios_info == 0x80)
+					continue;	/* Already claimed on pass 1 */
+			}
+			if(i2o_claim_device(d, &i2o_block_handler))
+			{
+				printk(KERN_WARNING "i2o_block: Controller %d, TID %d\n", c->unit, d->lct_data.tid);
+				printk(KERN_WARNING "\t%sevice refused claim! Skipping installation\n",
+					bios?"Boot d":"D");
+				continue;
+			}
+			if(scan_unit<MAX_I2OB<<4)
+			{
+				/*
 				 * Get the device and fill in the
 				 * Tid and controller.
 				 */
-				struct i2ob_device *dev=&i2ob_dev[unit];
-				dev->i2odev = d; 
+				dev=&i2ob_dev[scan_unit];
+				dev->i2odev = d;
 				dev->controller = c;
-				    dev->unit = c->unit;
+				dev->unit = c->unit;
 				dev->tid = d->lct_data.tid;
- 
-				    if(i2ob_install_device(c,d,unit))
-					     printk(KERN_WARNING "Could not install I2O block device\n");
-				    else
-				    {
-					     unit+=16;
-					     i2ob_dev_count++;
-
-					  /* We want to know when device goes away */
-					 i2o_device_notify_on(d, &i2o_block_handler);
-				    }
+				if(i2ob_install_device(c,d,scan_unit))
+					printk(KERN_WARNING "Could not install I2O block device\n");
+				else
+				{
+					scan_unit+=16;
+					i2ob_dev_count++;
+					/* We want to know when device goes away */
+					i2o_device_notify_on(d, &i2o_block_handler);
+				}
 			}
 			else
 			{
-			if(!warned++)
-				printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", unit>>4);
+				if(!warned++)
+					printk(KERN_WARNING "i2o_block: too many device, registering only %d.\n", scan_unit>>4);
 			}
-			   i2o_release_device(d, &i2o_block_handler);
+			i2o_release_device(d, &i2o_block_handler);
 		}
 		i2o_unlock_controller(c);
 	}
+	return 0;
+}
+
+static void i2ob_probe(void)
+{
+	/* 
+	 *	Some overhead/redundancy involved here, while trying to
+	 *	claim the first boot volume encountered as /dev/i2o/hda
+	 *	everytime. All the i2o_controllers are searched and the
+	 *	first i2o block device marked as bootable is claimed
+	 *	If an I2O block device was booted off , the bios sets
+	 *	its bios_info field to 0x80, this what we search for.
+ 	 *	Assuming that the bootable volume is /dev/i2o/hda
+	 *	everytime will prevent any kernel panic while mounting
+	 *	root partition
+	 */ 
+
+	printk(KERN_INFO "i2o_block: Checking for Boot device...\n");
+	i2ob_scan(1);
+	
+	/*
+	 *	Now the remainder.
+	 */
+	printk(KERN_INFO "i2o_block: Checking for I2O Block devices...\n"); 
+	i2ob_scan(0);
 }
 
 /*
@@ -1283,14 +1338,6 @@
 			   break;
 	 }
 
-	 /*
-	  * Creating a RAID 5 volume takes a little while and the UTIL_CLAIM
-	  * will fail if we don't give the card enough time to do it's magic,
-	  * so we just sleep for a little while and let it do it's thing
-	  */
-	 current->state = TASK_INTERRUPTIBLE;
-	 schedule_timeout(5*HZ);
-
 	 if(i2o_claim_device(d, &i2o_block_handler))
 	 {
 		  printk(KERN_INFO
@@ -1606,7 +1653,7 @@
 	 *	Finally see what is actually plugged in to our controllers
 	 */
 	i2ob_probe();
-	
+
 	return 0;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/i2o/i2o_core.c linux.17p18/drivers/i2o/i2o_core.c
--- linux.vanilla/drivers/i2o/i2o_core.c	Sun Jun 11 21:44:13 2000
+++ linux.17p18/drivers/i2o/i2o_core.c	Tue Aug  1 07:59:34 2000
@@ -260,7 +260,7 @@
 	{
 		if (msg[4] >> 24)
 		{
-			i2o_report_status(KERN_WARNING, "i2o_core: post_wait reply", msg);
+			i2o_report_status(KERN_INFO, "i2o_core: post_wait reply", msg);
 			status = -(msg[4] & 0xFFFF);
 		}
 		else
@@ -352,6 +352,9 @@
 	d->controller=c;
 	d->owner=NULL;
 	d->next=c->devices;
+	d->prev=NULL;
+	if (c->devices != NULL)
+		c->devices->prev=d;
 	c->devices=d;
 	*d->dev_name = 0;
 
@@ -2981,7 +2984,6 @@
 void cleanup_module(void)
 {
 	 int stat;
-
 	 unregister_reboot_notifier(&i2o_reboot_notifier);
 
 	if(i2o_num_controllers)
@@ -3021,7 +3023,6 @@
 extern int i2o_lan_init(void);
 extern int i2o_pci_init(void);
 extern int i2o_proc_init(void);
-extern int i2o_scsi_init(void);
 
 int __init i2o_init(void)
 {
@@ -3063,10 +3064,6 @@
 
 #ifdef CONFIG_I2O_BLOCK
 	i2o_block_init();
-#endif
-
-#ifdef CONFIG_I2O_SCSI
-	i2o_scsi_init();
 #endif
 
 #ifdef CONFIG_I2O_LAN
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/i2o/i2o_scsi.h linux.17p18/drivers/i2o/i2o_scsi.h
--- linux.vanilla/drivers/i2o/i2o_scsi.h	Wed May  3 22:34:53 2000
+++ linux.17p18/drivers/i2o/i2o_scsi.h	Thu Aug 17 18:15:25 2000
@@ -5,7 +5,9 @@
 #include <linux/version.h>
 #endif
 
+#ifndef LinuxVersionCode
 #define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
+#endif
 
 #include <linux/types.h>
 #include <linux/kdev_t.h>
@@ -24,6 +26,7 @@
 extern int i2o_scsi_reset(Scsi_Cmnd *, unsigned int);
 extern int i2o_scsi_bios_param(Disk *, kdev_t, int *);
 extern void i2o_scsi_setup(char *str, int *ints);
+extern int i2o_scsi_release(struct Scsi_Host *host);
 
 #define I2OSCSI {                                          \
 		  next: NULL,				    \
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/isdn/avmb1/b1.c linux.17p18/drivers/isdn/avmb1/b1.c
--- linux.vanilla/drivers/isdn/avmb1/b1.c	Fri Apr 21 12:46:07 2000
+++ linux.17p18/drivers/isdn/avmb1/b1.c	Tue Aug  1 18:17:47 2000
@@ -507,7 +507,7 @@
 	struct sk_buff *skb;
 
 	unsigned ApplId;
-	unsigned MsgLen;
+	signed MsgLen;
 	unsigned DataB3Len;
 	unsigned NCCI;
 	unsigned WindowSize;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/isdn/avmb1/b1dma.c linux.17p18/drivers/isdn/avmb1/b1dma.c
--- linux.vanilla/drivers/isdn/avmb1/b1dma.c	Fri Apr 21 12:46:07 2000
+++ linux.17p18/drivers/isdn/avmb1/b1dma.c	Tue Aug  1 18:17:47 2000
@@ -462,7 +462,8 @@
 	struct capi_ctr *ctrl = cinfo->capi_ctrl;
 	struct sk_buff *skb;
 	void *p = dma->recvbuf+4;
-	__u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
+	__u32 ApplId, DataB3Len, NCCI, WindowSize;
+	__s32 MsgLen;
 	__u8 b1cmd =  _get_byte(&p);
 
 #ifdef CONFIG_B1DMA_DEBUG
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/isdn/avmb1/c4.c linux.17p18/drivers/isdn/avmb1/c4.c
--- linux.vanilla/drivers/isdn/avmb1/c4.c	Fri Apr 21 12:46:07 2000
+++ linux.17p18/drivers/isdn/avmb1/c4.c	Tue Aug  1 18:17:47 2000
@@ -535,7 +535,8 @@
 	avmctrl_info *cinfo;
 	struct sk_buff *skb;
 	void *p = dma->recvbuf;
-	__u32 ApplId, MsgLen, DataB3Len, NCCI, WindowSize;
+	__u32 ApplId, DataB3Len, NCCI, WindowSize;
+	__s32 MsgLen;
 	__u8 b1cmd =  _get_byte(&p);
 	__u32 cidx;
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/isdn/avmb1/t1isa.c linux.17p18/drivers/isdn/avmb1/t1isa.c
--- linux.vanilla/drivers/isdn/avmb1/t1isa.c	Fri Apr 21 12:46:08 2000
+++ linux.17p18/drivers/isdn/avmb1/t1isa.c	Tue Aug  1 18:17:47 2000
@@ -190,7 +190,7 @@
 	struct sk_buff *skb;
 
 	unsigned ApplId;
-	unsigned MsgLen;
+	signed MsgLen;
 	unsigned DataB3Len;
 	unsigned NCCI;
 	unsigned WindowSize;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/isdn/isdn_cards.c linux.17p18/drivers/isdn/isdn_cards.c
--- linux.vanilla/drivers/isdn/isdn_cards.c	Fri Apr 21 12:46:12 2000
+++ linux.17p18/drivers/isdn/isdn_cards.c	Tue Aug  1 07:59:39 2000
@@ -75,6 +75,7 @@
 extern void capi_init(void);
 extern void capidrv_init(void);
 #endif
+extern void act2000_init(void);
 
 void
 isdn_cards_init(void)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/isdn/isdn_ppp.h linux.17p18/drivers/isdn/isdn_ppp.h
--- linux.vanilla/drivers/isdn/isdn_ppp.h	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/isdn/isdn_ppp.h	Tue Aug  1 18:32:35 2000
@@ -76,6 +76,7 @@
  */
 
 #include <linux/ppp_defs.h>     /* for PPP_PROTOCOL */
+#include <linux/isdn_ppp.h>
 extern int isdn_ppp_read(int, struct file *, char *, int);
 extern int isdn_ppp_write(int, struct file *, const char *, int);
 extern int isdn_ppp_open(int, struct file *);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/Makefile linux.17p18/drivers/macintosh/Makefile
--- linux.vanilla/drivers/macintosh/Makefile	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/Makefile	Tue Aug  1 07:59:39 2000
@@ -36,6 +36,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_PPC_RTC),y)
+  L_OBJS += rtc.o
+else
+  ifeq ($(CONFIG_PPC_RTC),m)
+    M_OBJS += rtc.o
+  endif
+endif
+
 ifdef CONFIG_MAC_KEYBOARD
 L_OBJS += mac_keyb.o
 endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/adb.c linux.17p18/drivers/macintosh/adb.c
--- linux.vanilla/drivers/macintosh/adb.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/adb.c	Tue Aug  1 07:59:39 2000
@@ -170,9 +170,9 @@
 	
 	if (adb_controller == NULL)
 		printk(KERN_WARNING "Warning: no ADB interface detected\n");
-	else
-	{
+	else {
 		adb_hardware = adb_controller->kind;
+		
 #ifdef CONFIG_PMAC_PBOOK
 		pmu_register_sleep_notifier(&adb_sleep_notifier);
 #endif /* CONFIG_PMAC_PBOOK */
@@ -194,6 +194,8 @@
 	switch (when) {
 	case PBOOK_SLEEP_REQUEST:
 		adb_got_sleep = 1;
+		if (adb_controller->autopoll)
+			adb_controller->autopoll(0);
 		ret = notifier_call_chain(&adb_client_list, ADB_MSG_POWERDOWN, NULL);
 		if (ret & NOTIFY_STOP_MASK)
 			return PBOOK_SLEEP_REFUSE;
@@ -209,6 +211,7 @@
 		break;
 	case PBOOK_WAKE:
 		adb_reset_bus();
+		adb_got_sleep = 0;
 		break;
 	}
 	return PBOOK_SLEEP_OK;
@@ -218,15 +221,21 @@
 int
 adb_reset_bus(void)
 {
-	int ret, devs;
+	int ret, nret, devs;
 	unsigned long flags;
 	
 	if (adb_controller == NULL)
 		return -ENXIO;
 		
-	ret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL);
-	if (ret & NOTIFY_STOP_MASK)
+	if (adb_controller->autopoll)
+		adb_controller->autopoll(0);
+
+	nret = notifier_call_chain(&adb_client_list, ADB_MSG_PRE_RESET, NULL);
+	if (nret & NOTIFY_STOP_MASK) {
+		if (adb_controller->autopoll)
+			adb_controller->autopoll(devs);
 		return -EBUSY;
+	}
 
 	save_flags(flags);
 	cli();
@@ -238,18 +247,17 @@
 	else
 		ret = 0;
 
-	if (!ret)
-	{
+	if (!ret) {
 		devs = adb_scan_bus();
 		if (adb_controller->autopoll)
 			adb_controller->autopoll(devs);
 	}
 
-	ret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL);
-	if (ret & NOTIFY_STOP_MASK)
+	nret = notifier_call_chain(&adb_client_list, ADB_MSG_POST_RESET, NULL);
+	if (nret & NOTIFY_STOP_MASK)
 		return -EBUSY;
 	
-	return 1;
+	return ret;
 }
 
 void
@@ -327,6 +335,12 @@
 	int i, id;
 	static int dump_adb_input = 0;
 
+	/* We skip keystrokes and mouse moves when the sleep process
+	 * has been started. We stop autopoll, but this is another security
+	 */
+	if (adb_got_sleep)
+		return;
+		
 	id = buf[0] >> 4;
 	if (dump_adb_input) {
 		printk(KERN_INFO "adb packet: ");
@@ -347,12 +361,8 @@
 
 	if (adb_handler[address].handler_id == new_id)
 	    return 1;
-	adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
-    	    ADB_READREG(address,3));
-	if (req.reply_len < 2)
-	    return 0;
 	adb_request(&req, NULL, ADBREQ_SYNC, 3,
-	    ADB_WRITEREG(address, 3), req.reply[1] & 0xF0, new_id);	
+	    ADB_WRITEREG(address, 3), address | 0x20, new_id);
 	adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
 	    ADB_READREG(address, 3));
 	if (req.reply_len < 2)
@@ -423,7 +433,7 @@
 {
 	struct adbdev_state *state;
 
-	if (MINOR(inode->i_rdev) > 0 || (adb_controller == NULL)/*adb_hardware == ADB_NONE*/)
+	if (MINOR(inode->i_rdev) > 0 || (adb_controller == NULL))
 		return -ENXIO;
 	state = kmalloc(sizeof(struct adbdev_state), GFP_KERNEL);
 	if (state == 0)
@@ -554,10 +564,11 @@
 	/* Special case for ADB_BUSRESET request, all others are sent to
 	   the controller */
 	if ((req->data[0] == ADB_PACKET)&&(count > 1)
-		&&(req->data[1] == ADB_BUSRESET))
+		&&(req->data[1] == ADB_BUSRESET)) {
 		ret = adb_reset_bus();
-	else
-	{	
+		atomic_dec(&state->n_pending);
+		goto out;
+	} else {	
 		req->reply_expected = ((req->data[1] & 0xc) == 0xc);
 
 		if (adb_controller && adb_controller->send_request)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/mac_keyb.c linux.17p18/drivers/macintosh/mac_keyb.c
--- linux.vanilla/drivers/macintosh/mac_keyb.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/mac_keyb.c	Tue Aug  1 07:59:39 2000
@@ -24,6 +24,7 @@
  * - Hunter digital (NoHandsMouse)
  * - Kensignton TurboMouse 5 (needs testing)
  * - Mouse Systems A3 mice and trackballs <aidan@kublai.com>
+ * - MacAlly 2-buttons mouse (needs testing) <pochini@denise.shiny.it>
  *
  * To do:
  *
@@ -272,6 +273,7 @@
 #define ADBMOUSE_MICROSPEED	6	/* Microspeed mouse (&trackball ?), MacPoint */
 #define ADBMOUSE_TRACKBALLPRO	7	/* Trackball Pro (special buttons) */
 #define ADBMOUSE_MS_A3		8	/* Mouse systems A3 trackball (handler 3) */
+#define ADBMOUSE_MACALLY2	9	/* MacAlly 2-button mouse */
 
 static int adb_mouse_kinds[16];
 
@@ -490,6 +492,19 @@
     data[3] = byyy bxxx Third button and fourth button.  Y is additional
 	      high bits of y-axis motion.  XY is additional
 	      high bits of x-axis motion.
+
+    MacAlly 2-button mouse protocol.
+
+    For MacAlly 2-button mouse protocol the data array will contain the
+    following values:
+
+		BITS    COMMENTS
+    data[0] = dddd 1100 ADB command: Talk, register 0, for device dddd.
+    data[1] = bxxx xxxx Left button and x-axis motion.
+    data[2] = byyy yyyy Right button and y-axis motion.
+    data[3] = ???? ???? unknown
+    data[4] = ???? ???? unknown
+
   */
 	struct kbd_struct *kbd;
 
@@ -521,6 +536,11 @@
 		data[2] = (data[2] & 0x7f) | ((data[3] & 0x02) << 6);
 		data[3] = ((data[3] & 0x04) << 5);
 		break;
+            case ADBMOUSE_MACALLY2:
+		data[3] = (data[2] & 0x80) ? 0x80 : 0x00;
+		data[2] |= 0x80;  /* Right button is mapped as button 3 */
+		nb=4;
+                break;
 	}
 
 	if (adb_mouse_interrupt_hook)
@@ -581,7 +601,7 @@
 	/* Ignore data from register other than 0 */
 	if ((adb_hardware != ADB_VIAPMU) || (data[0] & 0x3) || (nb < 2))
 		return;
-		
+
 	switch (data[1]&0xf )
 	{
 		/* mute */
@@ -645,7 +665,6 @@
 
 static void real_mackbd_leds(unsigned char leds, int device)
 {
-
     if (led_request.complete) {
 	adb_request(&led_request, leds_done, 0, 3,
 		    ADB_WRITEREG(device, KEYB_LEDREG), 0xff,
@@ -705,21 +724,29 @@
 	led_request.complete = 1;
 
 	mackeyb_probe();
-	
+
 	notifier_chain_register(&adb_client_list, &mackeyb_adb_notifier);
 }
 
 static int
 adb_message_handler(struct notifier_block *this, unsigned long code, void *x)
 {
+	unsigned long flags;
+
 	switch (code) {
 	case ADB_MSG_PRE_RESET:
 	case ADB_MSG_POWERDOWN:
-		/* Add unregister_keyboard when merging with Paul Mackerras */
+	    	/* Stop the repeat timer. Autopoll is already off at this point */
+		save_flags(flags);
+		cli();
+		del_timer(&repeat_timer);
+		restore_flags(flags);
+
+		/* Stop pending led requests */
 		while(!led_request.complete)
 			adb_poll();
 		break;
-			
+
 	case ADB_MSG_POST_RESET:
 		mackeyb_probe();
 		break;
@@ -802,7 +829,7 @@
 		    || (adb_mouse_kinds[id] == ADBMOUSE_MICROSPEED)) {
 			init_microspeed(id);
 		} else if (adb_mouse_kinds[id] == ADBMOUSE_MS_A3) {
-			init_ms_a3(id);	
+			init_ms_a3(id);
 		}  else if (adb_mouse_kinds[id] ==  ADBMOUSE_EXTENDED) {
 			/*
 			 * Register 1 is usually used for device
@@ -825,6 +852,14 @@
 			    (req.reply[1] == 0x4b) && (req.reply[2] == 0x4d) &&
 			    (req.reply[3] == 0x4c) && (req.reply[4] == 0x31))
 				init_turbomouse(id);
+			else if ((req.reply_len == 9) &&
+			    (req.reply[1] == 0x4b) && (req.reply[2] == 0x4f) &&
+			    (req.reply[3] == 0x49) && (req.reply[4] == 0x54)){
+				if (adb_try_handler_change(id, 0x42)) {
+					printk("\nADB MacAlly 2-button mouse at %d, handler set to 0x42", id);
+					adb_mouse_kinds[id] = ADBMOUSE_MACALLY2;
+				}
+			}
 		}
 		printk("\n");
         }
@@ -833,7 +868,7 @@
 static void 
 init_trackpad(int id)
 {
-	struct adb_request req;	
+	struct adb_request req;
 	unsigned char r1_buffer[8];
 
 	printk(" (trackpad)");
@@ -886,9 +921,9 @@
 init_trackball(int id)
 {
 	struct adb_request req;
-	
+
 	printk(" (trackman/mouseman)");
-	
+
 	adb_mouse_kinds[id] = ADBMOUSE_TRACKBALL;
 
 	adb_request(&req, NULL, ADBREQ_SYNC, 3,
@@ -924,7 +959,7 @@
         printk(" (TurboMouse 5)");
 
 	adb_mouse_kinds[id] = ADBMOUSE_TURBOMOUSE5;
-	
+
 	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(id));
 
 	adb_request(&req, NULL, ADBREQ_SYNC, 1, ADB_FLUSH(3));
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/macio-adb.c linux.17p18/drivers/macintosh/macio-adb.c
--- linux.vanilla/drivers/macintosh/macio-adb.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/macio-adb.c	Tue Aug  1 07:59:39 2000
@@ -115,11 +115,6 @@
 	out_8(&adb->intr_enb.r, DFB | TAG);
 
 	adb_controller = &macio_controller;
-//	adb_hardware = ADB_MACIO;
-
-//	adb_send_request = macio_adb_send_request;
-//	adb_autopoll = macio_adb_autopoll;
-//	adb_reset_bus = macio_reset_bus;
 }
 
 static int macio_adb_autopoll(int devs)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/macserial.c linux.17p18/drivers/macintosh/macserial.c
--- linux.vanilla/drivers/macintosh/macserial.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/macserial.c	Wed Aug 16 21:41:39 2000
@@ -129,6 +129,22 @@
 
 #define _INLINE_ inline
 
+#ifdef SERIAL_DEBUG_OPEN
+#define OPNDBG(fmt, arg...)	printk(KERN_INFO fmt , ## arg)
+#else
+#define OPNDBG(fmt, arg...)	do { } while (0)
+#endif
+#ifdef SERIAL_DEBUG_POWER
+#define PWRDBG(fmt, arg...)	printk(KERN_INFO fmt , ## arg)
+#else
+#define PWRDBG(fmt, arg...)	do { } while (0)
+#endif
+#ifdef SERIAL_DEBUG_BAUDS
+#define BAUDBG(fmt, arg...)	printk(KERN_INFO fmt , ## arg)
+#else
+#define BAUDBG(fmt, arg...)	do { } while (0)
+#endif
+
 static void probe_sccs(void);
 static void change_speed(struct mac_serial *info, struct termios *old);
 static void rs_wait_until_sent(struct tty_struct *tty, int timeout);
@@ -318,7 +334,7 @@
 	 * to it. - paulus)
 	 */
 	for (i = 200; i > 0; --i)
-		if (ld_le32(&dma->control) & RUN)
+		if (ld_le32(&dma->status) & RUN)
 			udelay(1);
 }
 
@@ -398,7 +414,7 @@
 			continue;
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE)
 			tty_flip_buffer_push(tty);
-			
+
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			static int flip_buf_ovf;
 			if (++flip_buf_ovf <= 1)
@@ -489,7 +505,7 @@
 			if (info->tx_stopped) {
 #ifdef SERIAL_DEBUG_FLOW
 				printk("CTS up\n");
-#endif			
+#endif
 				info->tx_stopped = 0;
 				if (!info->tx_active)
 					transmit_chars(info);
@@ -497,7 +513,7 @@
 		} else {
 #ifdef SERIAL_DEBUG_FLOW
 			printk("CTS down\n");
-#endif			
+#endif
 			info->tx_stopped = 1;
 		}
 	}
@@ -520,7 +536,7 @@
 	    == virt_to_bus(info->rx_cmds[info->rx_cbuf] + 1))
 		where -= in_le16(&info->rx->res_count);
 	where--;
-	
+
 	stat = read_zsreg(info->zs_channel, R1);
 
 	flag = stat_to_flag(stat);
@@ -566,7 +582,7 @@
 #ifdef SERIAL_DEBUG_INTR
 		printk("rs_interrupt: irq %d, zs_intreg 0x%x\n",
 		       irq, (int)zs_intreg);
-#endif	
+#endif
 
 		if ((zs_intreg & CHAN_IRQMASK) == 0)
 			break;
@@ -643,7 +659,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_stop"))
 		return;
-	
+
 #if 0
 	save_flags(flags); cli();
 	if (info->curregs[5] & TxENAB) {
@@ -659,7 +675,7 @@
 {
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
-	
+
 #ifdef SERIAL_DEBUG_STOP
 	printk("rs_start %ld....\n", 
 	       tty->ldisc.chars_in_buffer(tty));
@@ -667,7 +683,7 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_start"))
 		return;
-	
+
 	save_flags(flags); cli();
 #if 0
 	if (info->xmit_cnt && info->xmit_buf && !(info->curregs[5] & TxENAB)) {
@@ -701,7 +717,7 @@
 {
 	struct mac_serial	*info = (struct mac_serial *) private_;
 	struct tty_struct	*tty;
-	
+
 	tty = info->tty;
 	if (!tty)
 		return;
@@ -719,14 +735,10 @@
 {
 	int delay;
 
-#ifdef SERIAL_DEBUG_OPEN
-	printk("startup() (ttyS%d, irq %d)\n", info->line, info->irq);
-#endif
+	OPNDBG("startup() (ttyS%d, irq %d)\n", info->line, info->irq);
  
 	if (info->flags & ZILOG_INITIALIZED) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk(" -> already inited\n");
-#endif
+		OPNDBG(" -> already inited\n");
  		return 0;
 	}
 
@@ -736,22 +748,17 @@
 			return -ENOMEM;
 	}
 
-#ifdef SERIAL_DEBUG_OPEN
-	printk("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
-#endif
+	OPNDBG("starting up ttyS%d (irq %d)...\n", info->line, info->irq);
 
 	delay = set_scc_power(info, 1);
-	
+
 	setup_scc(info);
 
-#ifdef SERIAL_DEBUG_OPEN
-	printk("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq);
-#endif
+	OPNDBG("enabling IRQ on ttyS%d (irq %d)...\n", info->line, info->irq);
 
 	info->flags |= ZILOG_INITIALIZED;
 	enable_irq(info->irq);
 	if (info->dma_initted) {
-//		enable_irq(info->tx_dma_irq);
 		enable_irq(info->rx_dma_irq);
 	}
 
@@ -874,8 +881,6 @@
 	volatile struct dbdma_cmd *cd;
 	unsigned char *p;
 
-//printk(KERN_DEBUG "SCC: dma_init\n");
-
 	info->rx_nbuf = 8;
 
 	/* various mem set up */
@@ -951,12 +956,10 @@
 static int setup_scc(struct mac_serial * info)
 {
 	unsigned long flags;
-	
-#ifdef SERIAL_DEBUG_OPEN
-	printk("setting up ttys%d SCC...\n", info->line);
-#endif
 
-	save_flags(flags); cli(); /* Disable interrupts */	
+	OPNDBG("setting up ttys%d SCC...\n", info->line);
+
+	save_flags(flags); cli(); /* Disable interrupts */
 
 	/*
 	 * Reset the chip.
@@ -987,7 +990,8 @@
 	/*
 	 * Turn on RTS and DTR.
 	 */
-	zs_rtsdtr(info, 1);
+	if (!info->is_irda)
+		zs_rtsdtr(info, 1);
 
 	/*
 	 * Finally, enable sequencing and interrupts
@@ -1051,16 +1055,11 @@
  */
 static void shutdown(struct mac_serial * info)
 {
-#ifdef SERIAL_DEBUG_OPEN
-	printk("Shutting down serial port %d (irq %d)....\n", info->line,
+	OPNDBG("Shutting down serial port %d (irq %d)....\n", info->line,
 	       info->irq);
-#endif
-	
+
 	if (!(info->flags & ZILOG_INITIALIZED)) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk("(already shutdown)\n");
-#endif
-	
+		OPNDBG("(already shutdown)\n");
 		return;
 	}
 
@@ -1124,86 +1123,63 @@
 	/* The timings looks strange but that's the ones MacOS seems
 	   to use for the internal modem. I think we can use a lot faster
 	   ones, at least whe not using the modem, this should be tested.
-	 */				
+	 */
 	if (state) {
-#ifdef SERIAL_DEBUG_POWER
-		printk(KERN_INFO "ttyS%02d: powering up hardware\n", info->line);
-#endif
+		PWRDBG("ttyS%02d: powering up hardware\n", info->line);
 		if (feature_test(info->dev_node, FEATURE_Serial_enable) == 0) {
-			feature_clear(info->dev_node, FEATURE_Serial_reset);
-			mdelay(5);
 			feature_set(info->dev_node, FEATURE_Serial_enable);
+			mdelay(10);
+			feature_set(info->dev_node, FEATURE_Serial_reset);
+			mdelay(15);
+			feature_clear(info->dev_node, FEATURE_Serial_reset);
+			mdelay(10);
 		}
 		if (info->zs_chan_a == info->zs_channel)
 			feature_set(info->dev_node, FEATURE_Serial_IO_A);
 		else
 			feature_set(info->dev_node, FEATURE_Serial_IO_B);
-		delay = 1;
-		
+		delay = 10;
 		if (info->is_cobalt_modem){
-			feature_set(info->dev_node, FEATURE_Modem_Reset);
+			mdelay(300);
+			feature_set(info->dev_node, FEATURE_Modem_power);
 	   		mdelay(5);
-			feature_clear(info->dev_node, FEATURE_Modem_Reset);
+			feature_clear(info->dev_node, FEATURE_Modem_power);
+	   		mdelay(10);
+			feature_set(info->dev_node, FEATURE_Modem_power);
 			delay = 2500;	/* wait for 2.5s before using */
 		}
 #ifdef CONFIG_PMAC_PBOOK
-		if (info->is_pwbk_ir)
+		if (info->is_irda)
 			pmu_enable_irled(1);
 #endif /* CONFIG_PMAC_PBOOK */
 	} else {
-#ifdef SERIAL_DEBUG_POWER
-		printk(KERN_INFO "ttyS%02d: shutting down hardware\n", info->line);
-#endif
-#ifdef CONFIG_KGDB
-		if (info->kgdb_channel) {
-#ifdef SERIAL_DEBUG_POWER
-			printk(KERN_INFO "        (canceled by KGDB)\n");
-#endif
-			return 0;
-		}
-#endif
-#ifdef CONFIG_XMON
-		if (!info->is_cobalt_modem) {
-#ifdef SERIAL_DEBUG_POWER
-			printk(KERN_INFO "        (canceled by XMON)\n");
-#endif
-			return 0;
-		}
-#endif
+		PWRDBG("ttyS%02d: shutting down hardware\n", info->line);
 		if (info->is_cobalt_modem) {
-#ifdef SERIAL_DEBUG_POWER
-			printk(KERN_INFO "ttyS%02d: shutting down modem\n", info->line);
-#endif
-			feature_set(info->dev_node, FEATURE_Modem_Reset);
-			mdelay(15);
-			feature_clear(info->dev_node, FEATURE_Modem_Reset);
-			mdelay(25);
+			PWRDBG("ttyS%02d: shutting down modem\n", info->line);
+			feature_clear(info->dev_node, FEATURE_Modem_power);
+			mdelay(10);
 		}
 #ifdef CONFIG_PMAC_PBOOK
-		if (info->is_pwbk_ir)
+		if (info->is_irda)
 			pmu_enable_irled(0);
 #endif /* CONFIG_PMAC_PBOOK */
-			
-		if (info->zs_chan_a == info->zs_channel) {
-#ifdef SERIAL_DEBUG_POWER
-			printk(KERN_INFO "ttyS%02d: shutting down SCC channel A\n", info->line);
-#endif
+
+		if (info->zs_chan_a == info->zs_channel && !info->is_irda) {
+			PWRDBG("ttyS%02d: shutting down SCC channel A\n", info->line);
 			feature_clear(info->dev_node, FEATURE_Serial_IO_A);
-		} else {
-#ifdef SERIAL_DEBUG_POWER
-			printk(KERN_INFO "ttyS%02d: shutting down SCC channel B\n", info->line);
-#endif
+		} else if (!info->is_irda) {
+			PWRDBG("ttyS%02d: shutting down SCC channel B\n", info->line);
 			feature_clear(info->dev_node, FEATURE_Serial_IO_B);
 		}
 		/* XXX for now, shut down SCC core only on powerbooks */
 		if (is_powerbook
 		    && !(feature_test(info->dev_node, FEATURE_Serial_IO_A) ||
 			 feature_test(info->dev_node, FEATURE_Serial_IO_B))) {
-#ifdef SERIAL_DEBUG_POWER
-			printk(KERN_INFO "ttyS%02d: shutting down SCC core\n", info->line);
-#endif
+			PWRDBG("ttyS%02d: shutting down SCC core\n", info->line);
 			feature_set(info->dev_node, FEATURE_Serial_reset);
-			mdelay(10);
+			mdelay(15);
+			feature_clear(info->dev_node, FEATURE_Serial_reset);
+			mdelay(25);
 			feature_clear(info->dev_node, FEATURE_Serial_enable);
 			mdelay(5);
 		}
@@ -1211,6 +1187,113 @@
 	return delay;
 }
 
+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);
+	udelay(8);
+	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB);
+	udelay(4);
+	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
+	restore_flags(flags);
+}
+
+/*
+ * Set the irda codec on the imac to the specified baud rate.
+ */
+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)
+		return;
+	code = 0x4d + B115200 - speed;
+
+	/* disable serial interrupts and receive DMA */
+	write_zsreg(info->zs_channel, 1, info->curregs[1] & ~0x9f);
+
+	/* wait for transmitter to drain */
+	t = 10000;
+	while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP) == 0
+	       || (read_zsreg(info->zs_channel, 1) & ALL_SNT) == 0) {
+		if (--t <= 0) {
+			printk(KERN_ERR "transmitter didn't drain\n");
+			return;
+		}
+		udelay(10);
+	}
+	udelay(100);
+
+	/* set to 8 bits, no parity, 19200 baud, RTS on, DTR off */
+	write_zsreg(info->zs_channel, 4, X16CLK | SB1);
+	write_zsreg(info->zs_channel, 11, TCBR | RCBR);
+	t = BPS_TO_BRG(19200, ZS_CLOCK/16);
+	write_zsreg(info->zs_channel, 12, t);
+	write_zsreg(info->zs_channel, 13, t >> 8);
+	write_zsreg(info->zs_channel, 14, BRENABL);
+	write_zsreg(info->zs_channel, 3, Rx8 | RxENABLE);
+	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
+
+	/* 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);
+
+	/* assert DTR, wait 30ms, talk to the chip */
+	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS | DTR);
+	udelay(30000);
+	while (read_zsreg(info->zs_channel, 0) & Rx_CH_AV)
+		read_zsdata(info->zs_channel);
+
+	write_zsdata(info->zs_channel, 1);
+	t = 1000;
+	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0) {
+		if (--t <= 0) {
+			printk(KERN_ERR "irda_setup timed out on 1st byte\n");
+			goto out;
+		}
+		udelay(10);
+	}
+	t = read_zsdata(info->zs_channel);
+	if (t != 4)
+		printk(KERN_ERR "irda_setup 1st byte = %x\n", t);
+
+	write_zsdata(info->zs_channel, code);
+	t = 1000;
+	while ((read_zsreg(info->zs_channel, 0) & Rx_CH_AV) == 0) {
+		if (--t <= 0) {
+			printk(KERN_ERR "irda_setup timed out on 2nd byte\n");
+			goto out;
+		}
+		udelay(10);
+	}
+	t = read_zsdata(info->zs_channel);
+	if (t != code)
+		printk(KERN_ERR "irda_setup 2nd byte = %x (%x)\n", t, code);
+
+	/* Drop DTR again and do some more RTS pulses */
+ out:
+	udelay(100);
+	write_zsreg(info->zs_channel, 5, Tx8 | TxENAB | RTS);
+	irda_rts_pulses(info, 80);
+
+	/* We should be right to go now.  We assume that load_zsregs
+	   will get called soon to load up the correct baud rate etc. */
+	info->curregs[5] = (info->curregs[5] | RTS) & ~DTR;
+	info->pendregs[5] = info->curregs[5];
+}
 
 /*
  * This routine is called to set the UART divisor registers to match
@@ -1218,7 +1301,6 @@
  */
 static void change_speed(struct mac_serial *info, struct termios *old_termios)
 {
-	unsigned short port;
 	unsigned cflag;
 	int	bits;
 	int	brg, baud;
@@ -1226,8 +1308,6 @@
 
 	if (!info->tty || !info->tty->termios)
 		return;
-	if (!(port = info->port))
-		return;
 
 	cflag = info->tty->termios->c_cflag;
 	baud = tty_get_baud_rate(info->tty);
@@ -1250,9 +1330,7 @@
 	info->zs_baud = baud;
 	info->clk_divisor = 16;
 
-#ifdef SERIAL_DEBUG_BAUDS
-	printk("set speed to %d bds, ", baud);
-#endif
+	BAUDBG("set speed to %d bds, ", baud);
 
 	switch (baud) {
 	case ZS_CLOCK/16:	/* 230400 */
@@ -1279,34 +1357,26 @@
 	case CS5:
 		info->curregs[3] |= Rx5;
 		info->curregs[5] |= Tx5;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("5 bits, ");
-#endif
+		BAUDBG("5 bits, ");
 		bits = 7;
 		break;
 	case CS6:
 		info->curregs[3] |= Rx6;
 		info->curregs[5] |= Tx6;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("6 bits, ");
-#endif
+		BAUDBG("6 bits, ");
 		bits = 8;
 		break;
 	case CS7:
 		info->curregs[3] |= Rx7;
 		info->curregs[5] |= Tx7;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("7 bits, ");
-#endif
+		BAUDBG("7 bits, ");
 		bits = 9;
 		break;
 	case CS8:
 	default: /* defaults to 8 bits */
 		info->curregs[3] |= Rx8;
 		info->curregs[5] |= Tx8;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("8 bits, ");
-#endif
+		BAUDBG("8 bits, ");
 		bits = 10;
 		break;
 	}
@@ -1317,21 +1387,15 @@
 	if (cflag & CSTOPB) {
 		info->curregs[4] |= SB2;
 		bits++;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("2 stop, ");
-#endif
+		BAUDBG("2 stop, ");
 	} else {
 		info->curregs[4] |= SB1;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("1 stop, ");
-#endif
+		BAUDBG("1 stop, ");
 	}
 	if (cflag & PARENB) {
 		bits++;
  		info->curregs[4] |= PAR_ENA;
-#ifdef SERIAL_DEBUG_BAUDS
-		printk("parity, ");
-#endif
+		BAUDBG("parity, ");
 	}
 	if (!(cflag & PARODD)) {
 		info->curregs[4] |= PAR_EVEN;
@@ -1361,9 +1425,12 @@
 	info->timeout = ((info->xmit_fifo_size*HZ*bits) / baud);
 	info->timeout += HZ/50+1;	/* Add .02 seconds of slop */
 
-#ifdef SERIAL_DEBUG_BAUDS
-	printk("timeout=%d/%ds, base:%d\n", (int)info->timeout, (int)HZ, (int)info->baud_base);
-#endif
+	BAUDBG("timeout=%d/%ds, base:%d\n", (int)info->timeout, (int)HZ,
+	       (int)info->baud_base);
+
+	/* set the irda codec to the right rate */
+	if (info->is_irda)
+		irda_setup(info);
 
 	/* Load up the new values */
 	load_zsregs(info->zs_channel, info->curregs);
@@ -1431,7 +1498,7 @@
 	} else {
 		while (1) {
 			save_flags(flags);
-			cli();		
+			cli();
 			c = MIN(count,
 				MIN(SERIAL_XMIT_SIZE - info->xmit_cnt - 1,
 				    SERIAL_XMIT_SIZE - info->xmit_head));
@@ -1459,7 +1526,7 @@
 {
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	int	ret;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_write_room"))
 		return 0;
 	ret = SERIAL_XMIT_SIZE - info->xmit_cnt - 1;
@@ -1471,7 +1538,7 @@
 static int rs_chars_in_buffer(struct tty_struct *tty)
 {
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_chars_in_buffer"))
 		return 0;
 	return info->xmit_cnt;
@@ -1481,7 +1548,7 @@
 {
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
-				
+
 	if (serial_paranoia_check(info, tty->device, "rs_flush_buffer"))
 		return;
 	save_flags(flags); cli();
@@ -1507,13 +1574,13 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
-	
+
 	printk("throttle %ld....\n",tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_throttle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		save_flags(flags); cli();
 		info->x_char = STOP_CHAR(tty);
@@ -1543,13 +1610,13 @@
 	struct mac_serial *info = (struct mac_serial *)tty->driver_data;
 	unsigned long flags;
 #ifdef SERIAL_DEBUG_THROTTLE
-	
+
 	printk("unthrottle %s: %d....\n",tty->ldisc.chars_in_buffer(tty));
 #endif
 
 	if (serial_paranoia_check(info, tty->device, "rs_unthrottle"))
 		return;
-	
+
 	if (I_IXOFF(tty)) {
 		save_flags(flags); cli();
 		if (info->x_char)
@@ -1726,8 +1793,6 @@
 
 	if (serial_paranoia_check(info, tty->device, "rs_break"))
 		return;
-	if (!info->port)
-		return;
 
 	save_flags(flags); cli();
 	if (break_state == -1)
@@ -1755,7 +1820,7 @@
 		if (tty->flags & (1 << TTY_IO_ERROR))
 		    return -EIO;
 	}
-	
+
 	switch (cmd) {
 		case TIOCMGET:
 			return get_modem_info(info, (unsigned int *) arg);
@@ -1777,7 +1842,7 @@
 					 info, sizeof(struct mac_serial)))
 				return -EFAULT;
 			return 0;
-			
+
 		default:
 			return -ENOIOCTLCMD;
 		}
@@ -1816,18 +1881,16 @@
 
 	if (!info || serial_paranoia_check(info, tty->device, "rs_close"))
 		return;
-	
+
 	save_flags(flags); cli();
-	
+
 	if (tty_hung_up_p(filp)) {
 		MOD_DEC_USE_COUNT;
 		restore_flags(flags);
 		return;
 	}
-	
-#ifdef SERIAL_DEBUG_OPEN
-	printk("rs_close ttys%d, count = %d\n", info->line, info->count);
-#endif
+
+	OPNDBG("rs_close ttys%d, count = %d\n", info->line, info->count);
 	if ((tty->count == 1) && (info->count != 1)) {
 		/*
 		 * Uh, oh.  tty->count is 1, which means that the tty
@@ -1863,9 +1926,7 @@
 	 * Now we wait for the transmit buffer to clear; and we notify 
 	 * the line discipline to only process XON/XOFF characters.
 	 */
-#ifdef SERIAL_DEBUG_OPEN
-	printk("waiting end of Tx... (timeout:%d)\n", info->closing_wait);
-#endif
+	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);
@@ -1889,9 +1950,7 @@
 		 * Before we drop DTR, make sure the SCC transmitter
 		 * has completely drained.
 		 */
-#ifdef SERIAL_DEBUG_OPEN
-		printk("waiting end of Rx...\n");
-#endif
+		OPNDBG("waiting end of Rx...\n");
 		restore_flags(flags);
 		rs_wait_until_sent(tty, info->timeout);
 		save_flags(flags); cli();
@@ -2031,7 +2090,7 @@
 		info->flags |= ZILOG_CALLOUT_ACTIVE;
 		return 0;
 	}
-	
+
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -2051,7 +2110,7 @@
 		if (tty->termios->c_cflag & CLOCAL)
 			do_clocal = 1;
 	}
-	
+
 	/*
 	 * Block waiting for the carrier detect and the line to become
 	 * free (i.e., not in use by the callout).  While we are in
@@ -2061,10 +2120,8 @@
 	 */
 	retval = 0;
 	add_wait_queue(&info->open_wait, &wait);
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready before block: ttys%d, count = %d\n",
+	OPNDBG("block_til_ready before block: ttys%d, count = %d\n",
 	       info->line, info->count);
-#endif
 	cli();
 	if (!tty_hung_up_p(filp)) 
 		info->count--;
@@ -2073,7 +2130,8 @@
 	while (1) {
 		cli();
 		if (!(info->flags & ZILOG_CALLOUT_ACTIVE) &&
-		    (tty->termios->c_cflag & CBAUD))
+		    (tty->termios->c_cflag & CBAUD) &&
+		    !info->is_irda)
 			zs_rtsdtr(info, 1);
 		sti();
 		current->state = TASK_INTERRUPTIBLE;
@@ -2083,7 +2141,7 @@
 			if (info->flags & ZILOG_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 #else
 			retval = -EAGAIN;
 #endif
@@ -2097,10 +2155,8 @@
 			retval = -ERESTARTSYS;
 			break;
 		}
-#ifdef SERIAL_DEBUG_OPEN
-		printk("block_til_ready blocking: ttys%d, count = %d\n",
+		OPNDBG("block_til_ready blocking: ttys%d, count = %d\n",
 		       info->line, info->count);
-#endif
 		schedule();
 	}
 	current->state = TASK_RUNNING;
@@ -2108,15 +2164,13 @@
 	if (!tty_hung_up_p(filp))
 		info->count++;
 	info->blocked_open--;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("block_til_ready after blocking: ttys%d, count = %d\n",
+	OPNDBG("block_til_ready after blocking: ttys%d, count = %d\n",
 	       info->line, info->count);
-#endif
 	if (retval)
 		return retval;
 	info->flags |= ZILOG_NORMAL_ACTIVE;
 	return 0;
-}	
+}
 
 /*
  * This routine is called whenever a serial port is opened.  It
@@ -2146,10 +2200,8 @@
 #endif
 	if (serial_paranoia_check(info, tty->device, "rs_open"))
 		return -ENODEV;
-#ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	OPNDBG("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
 	       info->count);
-#endif
 
 	info->count++;
 	tty->driver_data = info;
@@ -2190,10 +2242,8 @@
 
 	retval = block_til_ready(tty, filp, info);
 	if (retval) {
-#ifdef SERIAL_DEBUG_OPEN
-		printk("rs_open returning after block_til_ready with %d\n",
+		OPNDBG("rs_open returning after block_til_ready with %d\n",
 			retval);
-#endif
 		return retval;
 	}
 
@@ -2215,9 +2265,7 @@
 	info->session = current->session;
 	info->pgrp = current->pgrp;
 
-#ifdef SERIAL_DEBUG_OPEN
-	printk("rs_open ttys%d successful...\n", info->line);
-#endif
+	OPNDBG("rs_open ttys%d successful...\n", info->line);
 	return 0;
 }
 
@@ -2239,11 +2287,15 @@
 	struct device_node *ch = zss->dev_node;
 	char *conn;
 	int len;
+	struct slot_names_prop {
+		int	count;
+		char	name[1];
+	} *slots;
 
 	zss->irq = ch->intrs[0].line;
 	zss->has_dma = 0;
 #if !defined(CONFIG_KGDB) && defined(SUPPORT_SERIAL_DMA)
-	if (ch->n_addrs == 3 && ch->n_intrs == 3)
+	if (ch->n_addrs >= 3 && ch->n_intrs == 3)
 		zss->has_dma = 1;
 #endif
 	zss->dma_initted = 0;
@@ -2263,7 +2315,11 @@
 	/* XXX tested only with wallstreet PowerBook,
 	   should do no harm anyway */
 	conn = get_property(ch, "AAPL,connector", &len);
-	zss->is_pwbk_ir = conn && (strcmp(conn, "infrared") == 0);
+	zss->is_irda = conn && (strcmp(conn, "infrared") == 0);
+	/* 1999 Powerbook G3 has slot-names property instead */
+	slots = (struct slot_names_prop *)get_property(ch, "slot-names", &len);
+	if (slots && slots->count > 0 && strcmp(slots->name, "IrDA") == 0)
+		zss->is_irda = 1;
 
 	if (zss->has_dma) {
 		zss->dma_priv = NULL;
@@ -2453,7 +2509,7 @@
 		zs_soft[channel].clk_divisor = 16;
 /* -- we are not sure the SCC is powered ON at this point
  		zs_soft[channel].zs_baud = get_zsbaud(&zs_soft[channel]);
-*/		
+*/
 		zs_soft[channel].zs_baud = 38400;
 
 		/* If console serial line, then enable interrupts. */
@@ -2504,20 +2560,17 @@
 			printk(", port = %s", connector);
 		if (info->is_cobalt_modem)
 			printk(" (cobalt modem)");
-		if (info->is_pwbk_ir)
-			printk(" (powerbook IR)");
+		if (info->is_irda)
+			printk(" (IrDA)");
 		printk("\n");
 
+#ifndef CONFIG_XMON
 #ifdef CONFIG_KGDB
-		if (info->kgdb_channel)
-			continue;
-#endif			
-#ifdef CONFIG_XMON
-		if (!info->is_cobalt_modem)
-			continue;
-#endif			
-		/* By default, disable the port */
-		set_scc_power(info, 0);
+		if (!info->kgdb_channel)
+#endif /* CONFIG_KGDB */
+			/* By default, disable the port */
+			set_scc_power(info, 0);
+#endif /* CONFIG_XMON */
  	}
 	tmp_buf = 0;
 
@@ -2613,7 +2666,7 @@
 			while ((read_zsreg(info->zs_channel, 0) & Tx_BUF_EMP)
                                 == 0)
 				eieio();
-			
+
 			write_zsdata(info->zs_channel, 13);
 		}
 	}
@@ -2922,7 +2975,7 @@
 		probe_sccs();
 
 	set_scc_power(&zs_soft[tty_num], 1);
-	
+
 	zs_kgdbchan = zs_soft[tty_num].zs_channel;
 	zs_soft[tty_num].change_needed = 0;
 	zs_soft[tty_num].clk_divisor = 16;
@@ -2944,12 +2997,12 @@
 serial_notify_sleep(struct pmu_sleep_notifier *self, int when)
 {
 	int i;
-	
+
 	switch (when) {
 	case PBOOK_SLEEP_REQUEST:
 	case PBOOK_SLEEP_REJECT:
 		break;
-		
+
 	case PBOOK_SLEEP_NOW:
 		for (i=0; i<zs_channels_found; i++) {
 			struct mac_serial *info = &zs_soft[i];
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/macserial.h linux.17p18/drivers/macintosh/macserial.h
--- linux.vanilla/drivers/macintosh/macserial.h	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/macserial.h	Tue Aug  1 07:59:39 2000
@@ -111,7 +111,7 @@
 	char kgdb_channel;  /* Kgdb is running on this channel */
 	char is_cons;       /* Is this our console. */
 	char is_cobalt_modem;	/* is a gatwick-based cobalt modem */
-	char is_pwbk_ir;	/* is connected to an IR led on powerbooks */
+	char is_irda;		/* is connected to an IrDA codec */
 	unsigned char tx_active; /* character is being xmitted */
 	unsigned char tx_stopped; /* output is suspended */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/mediabay.c linux.17p18/drivers/macintosh/mediabay.c
--- linux.vanilla/drivers/macintosh/mediabay.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/mediabay.c	Tue Aug  1 07:59:39 2000
@@ -3,6 +3,8 @@
  *
  * Copyright (C) 1998 Paul Mackerras.
  *
+ * Various evolutions by Benjamin Herrenschmidt & Henry Worth
+ *
  *  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
@@ -38,6 +40,14 @@
 #endif
 
 #undef MB_USE_INTERRUPTS
+#undef MB_DEBUG
+#define MB_IGNORE_SIGNALS
+
+#ifdef MB_DEBUG
+#define MBDBG(fmt, arg...)	printk(KERN_INFO fmt , ## arg)
+#else
+#define MBDBG(fmt, arg...)	do { } while (0)
+#endif
 
 struct media_bay_hw {
 	unsigned char	b0;
@@ -48,18 +58,20 @@
 
 struct media_bay_info {
 	volatile struct media_bay_hw*	addr;
+	volatile u8*			extint_gpio;
 	int				content_id;
-	int				previous_id;
-	int				ready;
+	int				state;
 	int				last_value;
 	int				value_count;
-	int				reset_timer;
+	int				timer;
 	struct device_node*		dev_node;
+	int				pismo;	/* New PowerBook3,1 */
+	int				gpio_cache;
 #ifdef CONFIG_BLK_DEV_IDE
 	unsigned long			cd_base;
 	int 				cd_index;
 	int				cd_irq;
-	int				cd_timer;
+	int				cd_retry;
 #endif
 };
 
@@ -68,42 +80,102 @@
 static volatile struct media_bay_info media_bays[MAX_BAYS];
 int media_bay_count = 0;
 
-#define MB_CONTENTS(i)	((in_8(&media_bays[i].addr->contents) >> 4) & 7)
+inline int mb_content(volatile struct media_bay_info *bay)
+{
+        if (bay->pismo) {
+                unsigned char new_gpio = in_8(bay->extint_gpio + 0xe) & 2;
+                if (new_gpio) {
+                	bay->gpio_cache = new_gpio;
+                        return MB_NO;
+                } else if (bay->gpio_cache != new_gpio) {
+                        /* make sure content bits are set */
+                        feature_set(bay->dev_node, FEATURE_Mediabay_content);
+                        udelay(5);
+                        bay->gpio_cache = new_gpio;
+                }
+                return (in_le32((unsigned*)bay->addr) >> 4) & 0xf;
+        } else {
+                int cont = (in_8(&bay->addr->contents) >> 4) & 7;
+                return (cont == 7) ? MB_NO : cont;
+        }
+}
 
 #ifdef CONFIG_BLK_DEV_IDE
 /* check the busy bit in the media-bay ide interface
    (assumes the media-bay contains an ide device) */
+//#define MB_IDE_READY(i)	((inb(media_bays[i].cd_base + 0x70) & 0xc0) == 0x40)
 #define MB_IDE_READY(i)	((inb(media_bays[i].cd_base + 0x70) & 0x80) == 0)
 #endif
 
+/* Note: All delays are not in milliseconds and converted to HZ relative
+ * values by the macro below
+ */
+#define MS_TO_HZ(ms)	((ms * HZ) / 1000)
+
 /*
  * Consider the media-bay ID value stable if it is the same for
- * this many consecutive samples (at intervals of 1/HZ seconds).
+ * this number of milliseconds
+ */
+#define MB_STABLE_DELAY	40
+
+/* Wait after powering up the media bay this delay in ms
+ * timeout bumped for some powerbooks
  */
-#define MB_STABLE_COUNT	4
+#define MB_POWER_DELAY	200
 
 /*
  * Hold the media-bay reset signal true for this many ticks
  * after a device is inserted before releasing it.
  */
-#define MB_RESET_COUNT	40
+#define MB_RESET_DELAY	40
+
+/*
+ * Wait this long after the reset signal is released and before doing
+ * further operations. After this delay, the IDE reset signal is released
+ * too for an IDE device
+ */
+#define MB_SETUP_DELAY	100
 
 /*
  * Wait this many ticks after an IDE device (e.g. CD-ROM) is inserted
- * (or until the device is ready) before registering the IDE interface.
+ * (or until the device is ready) before waiting for busy bit to disappear
+ */
+#define MB_IDE_WAIT	1000
+
+/*
+ * Timeout waiting for busy bit of an IDE device to go down
  */
-#define MB_IDE_WAIT	1500
+#define MB_IDE_TIMEOUT	5000
 
 /*
- * Wait at least this many ticks after resetting an IDE device before
- * believing its ready bit.
+ * Max retries of the full power up/down sequence for an IDE device
  */
-#define MB_IDE_MINWAIT	250
+#define MAX_CD_RETRIES	3
+
+/*
+ * States of a media bay
+ */
+enum {
+	mb_empty = 0,		/* Idle */
+	mb_powering_up,		/* power bit set, waiting MB_POWER_DELAY */
+	mb_enabling_bay,	/* enable bits set, waiting MB_RESET_DELAY */
+	mb_resetting,		/* reset bit unset, waiting MB_SETUP_DELAY */
+	mb_ide_resetting,	/* IDE reset bit unser, waiting MB_IDE_WAIT */
+	mb_ide_waiting,		/* Waiting for BUSY bit to go away until MB_IDE_TIMEOUT */
+	mb_up,			/* Media bay full */
+	mb_powering_down	/* Powering down (avoid too fast down/up) */
+};
 
 static void poll_media_bay(int which);
 static void set_media_bay(int which, int id);
+static void set_mb_power(int which, int onoff);
+static void media_bay_step(int i);
 static int media_bay_task(void *);
 
+#ifdef MB_USE_INTERRUPTS
+static void media_bay_intr(int irq, void *devid, struct pt_regs *regs);
+#endif
+
 /*
  * It seems that the bit for the media-bay interrupt in the IRQ_LEVEL
  * register is always set when there is something in the media bay.
@@ -120,56 +192,69 @@
 {
 	struct device_node *np;
 	int		n,i;
-	
-	for (i=0; i<MAX_BAYS; i++)
-	{
+
+	for (i=0; i<MAX_BAYS; i++) {
 		memset((char *)&media_bays[i], 0, sizeof(struct media_bay_info));
 		media_bays[i].content_id	= -1;
 #ifdef CONFIG_BLK_DEV_IDE
 		media_bays[i].cd_index		= -1;
 #endif
 	}
-	
+
 	np = find_devices("media-bay");
 	n = 0;
-	while(np && (n<MAX_BAYS))
-	{
+	while(np && (n<MAX_BAYS)) {
 		if (np->n_addrs == 0)
 			continue;
 		media_bays[n].addr = (volatile struct media_bay_hw *)
 			ioremap(np->addrs[0].address, sizeof(struct media_bay_hw));
 
+		media_bays[n].pismo = device_is_compatible(np, "keylargo-media-bay");
+		if (media_bays[n].pismo) {
+			if (!np->parent || strcmp(np->parent->name, "mac-io")) {
+				printk(KERN_ERR "Pismo media-bay has no mac-io parent !\n");
+				continue;
+			}
+			media_bays[n].extint_gpio = ioremap(np->parent->addrs[0].address
+				+ 0x58, 0x10);
+		}
+
 #ifdef MB_USE_INTERRUPTS
-		if (np->n_intrs == 0)
-		{
+		if (np->n_intrs == 0) {
 			printk(KERN_ERR "media bay %d has no irq\n",n);
 			continue;
 		}
-		
-		if (request_irq(np_intrs[0].line, media_bay_intr, 0, "Media bay", NULL))
-		{
-			printk(KERN_ERR "Couldn't get IRQ %d for media bay %d\n", irq, n);
+
+		if (request_irq(np->intrs[0].line, media_bay_intr, 0, "Media bay", (void *)n)) {
+			printk(KERN_ERR "Couldn't get IRQ %d for media bay %d\n",
+				np->intrs[0].line, n);
 			continue;
 		}
-#endif	
+#endif
 		media_bay_count++;
-	
-		set_media_bay(n, MB_CONTENTS(n));
-		if (media_bays[n].content_id != MB_NO) {
-			feature_clear(media_bays[n].dev_node, FEATURE_Mediabay_reset);
-			udelay(500);
-		}
-		media_bays[n].ready		= 1;
-		media_bays[n].previous_id	= media_bays[n].content_id;
-		media_bays[n].reset_timer	= 0;
+
 		media_bays[n].dev_node		= np;
-#ifdef CONFIG_BLK_DEV_IDE
-		media_bays[n].cd_timer		= 0;
-#endif
+
+		/* Force an immediate detect */
+		set_mb_power(n,0);
+		mdelay(MB_POWER_DELAY);
+		if(!media_bays[n].pismo)
+			out_8(&media_bays[n].addr->contents, 0x70);
+		mdelay(MB_STABLE_DELAY);
+		media_bays[n].content_id = MB_NO;
+		media_bays[n].last_value = mb_content(&media_bays[n]);
+		media_bays[n].value_count = MS_TO_HZ(MB_STABLE_DELAY);
+		media_bays[n].state = mb_empty;
+		do {
+			mdelay(1000/HZ);
+			media_bay_step(n);
+		} while((media_bays[n].state != mb_empty) &&
+			(media_bays[n].state != mb_up));
+
 		n++;
 		np=np->next;
 	}
-	
+
 	if (media_bay_count)
 	{
 		printk(KERN_INFO "Registered %d media-bay(s)\n", media_bay_count);
@@ -178,21 +263,83 @@
 		pmu_register_sleep_notifier(&mb_sleep_notifier);
 #endif /* CONFIG_PMAC_PBOOK */
 
-		kernel_thread(media_bay_task, NULL, 0);
+		kernel_thread(media_bay_task, NULL,
+			      CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
 	}
 }
 
-#if 0
+#ifdef MB_USE_INTERRUPTS
 static void
 media_bay_intr(int irq, void *devid, struct pt_regs *regs)
 {
-	int id = MB_CONTENTS();
-
-	if (id == MB_NO)
-		set_media_bay(id);
 }
 #endif
 
+static void
+set_mb_power(int which, int onoff)
+{
+	volatile struct media_bay_info*	mb = &media_bays[which];
+
+	if (onoff) {
+		feature_set(mb->dev_node, FEATURE_Mediabay_power);
+		udelay(10);
+		feature_set(mb->dev_node, FEATURE_Mediabay_reset);
+		udelay(10);
+		mb->state = mb_powering_up;
+		MBDBG("mediabay%d: powering up\n", which);
+	} else {
+		feature_clear(mb->dev_node, FEATURE_Mediabay_floppy_enable);
+		if (mb->pismo)
+			feature_clear(mb->dev_node, FEATURE_IDE0_enable);
+		else
+			feature_clear(mb->dev_node, FEATURE_IDE1_enable);
+		feature_clear(mb->dev_node, FEATURE_Mediabay_IDE_switch);
+		feature_clear(mb->dev_node, FEATURE_Mediabay_PCI_enable);
+		feature_clear(mb->dev_node, FEATURE_SWIM3_enable);
+		feature_clear(mb->dev_node, FEATURE_Mediabay_power);
+		mb->state = mb_powering_down;
+		MBDBG("mediabay%d: powering down\n", which);
+	}
+	mb->timer = MS_TO_HZ(MB_POWER_DELAY);
+}
+
+static void
+set_media_bay(int which, int id)
+{
+	volatile struct media_bay_info* bay;
+
+	bay = &media_bays[which];
+
+	switch (id) {
+	case MB_CD:
+		if (bay->pismo) {
+			feature_set(bay->dev_node, FEATURE_Mediabay_IDE_switch);
+			udelay(10);
+			feature_set(bay->dev_node, FEATURE_IDE0_enable);
+			udelay(10);
+			feature_set(bay->dev_node, FEATURE_IDE0_reset);
+		} else {
+			feature_set(bay->dev_node, FEATURE_IDE1_enable);
+			udelay(10);
+			feature_set(bay->dev_node, FEATURE_IDE1_reset);
+		}
+		printk(KERN_INFO "media bay %d contains a CD-ROM drive\n", which);
+		break;
+	case MB_FD:
+	case MB_FD1:
+		feature_set(bay->dev_node, FEATURE_Mediabay_floppy_enable);
+		feature_set(bay->dev_node, FEATURE_SWIM3_enable);
+		printk(KERN_INFO "media bay %d contains a floppy disk drive\n", which);
+		break;
+	case MB_NO:
+		break;
+	default:
+		printk(KERN_INFO "media bay %d contains an unknown device (%d)\n",
+		       which, id);
+		break;
+	}
+}
+
 int
 check_media_bay(struct device_node *which_bay, int what)
 {
@@ -202,7 +349,7 @@
 	for (i=0; i<media_bay_count; i++)
 		if (which_bay == media_bays[i].dev_node)
 		{
-			if ((what == media_bays[i].content_id) && media_bays[i].ready)
+			if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
 				return 0;
 			media_bays[i].cd_index = -1;
 			return -EINVAL;
@@ -220,13 +367,13 @@
 	for (i=0; i<media_bay_count; i++)
 		if (base == media_bays[i].cd_base)
 		{
-			if ((what == media_bays[i].content_id) && media_bays[i].ready)
+			if ((what == media_bays[i].content_id) && media_bays[i].state == mb_up)
 				return 0;
 			media_bays[i].cd_index = -1;
 			return -EINVAL;
 		} 
 #endif
-	
+
 	return -ENODEV;
 }
 
@@ -240,17 +387,138 @@
 	for (i=0; i<media_bay_count; i++)
 		if (which_bay == media_bays[i].dev_node)
 		{
+			int timeout = 5000;
+
  			media_bays[i].cd_base	= base;
 			media_bays[i].cd_irq	= irq;
-			media_bays[i].cd_index	= index;
-			printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i);			
-			return 0;
+
+			if ((MB_CD != media_bays[i].content_id) || media_bays[i].state != mb_up)
+				return 0;
+
+			printk(KERN_DEBUG "Registered ide %d for media bay %d\n", index, i);
+			do {
+				if (MB_IDE_READY(i)) {
+					media_bays[i].cd_index	= index;
+					return 0;
+				}
+				mdelay(1);
+			} while(--timeout);
+			printk(KERN_DEBUG "Timeount waiting IDE in bay %d\n", i);
+			return -ENODEV;
 		} 
 #endif
-	
+
 	return -ENODEV;
 }
 
+static void
+media_bay_step(int i)
+{
+	volatile struct media_bay_info* bay = &media_bays[i];
+
+	/* We don't poll when powering down */
+	if (bay->state != mb_powering_down)
+	    poll_media_bay(i);
+
+	/* If timer expired or polling IDE busy, run state machine */
+	if ((bay->state != mb_ide_waiting) && (bay->timer != 0) && ((--bay->timer) != 0))
+	    return;
+
+	switch(bay->state) {
+	case mb_powering_up:
+	    	set_media_bay(i, bay->last_value);
+	    	bay->timer = MS_TO_HZ(MB_RESET_DELAY);
+	    	bay->state = mb_enabling_bay;
+		MBDBG("mediabay%d: enabling (kind:%d)\n", i, bay->content_id);
+		break;
+	case mb_enabling_bay:
+	    	feature_clear(bay->dev_node, FEATURE_Mediabay_reset);
+	    	bay->timer = MS_TO_HZ(MB_SETUP_DELAY);
+	    	bay->state = mb_resetting;
+		MBDBG("mediabay%d: waiting reset (kind:%d)\n", i, bay->content_id);
+	    	break;
+	    
+	case mb_resetting:
+		if (bay->content_id != MB_CD) {
+			MBDBG("mediabay%d: bay is up (kind:%d)\n", i, bay->content_id);
+			bay->state = mb_up;
+			break;
+	    	}
+#ifdef CONFIG_BLK_DEV_IDE
+		MBDBG("mediabay%d: waiting IDE reset (kind:%d)\n", i, bay->content_id);
+		if (bay->pismo)
+	    		feature_clear(bay->dev_node, FEATURE_IDE0_reset);
+		else
+	    		feature_clear(bay->dev_node, FEATURE_IDE1_reset);
+	    	bay->timer = MS_TO_HZ(MB_IDE_WAIT);
+	    	bay->state = mb_ide_resetting;
+#else
+		printk(KERN_DEBUG "media-bay %d is ide (not compiled in kernel)\n", i);
+		set_mb_power(i, 0);
+#endif // #ifdef CONFIG_BLK_DEV_IDE
+	    	break;
+	    
+#ifdef CONFIG_BLK_DEV_IDE
+	case mb_ide_resetting:
+	    	bay->timer = MS_TO_HZ(MB_IDE_TIMEOUT);
+	    	bay->state = mb_ide_waiting;
+		MBDBG("mediabay%d: waiting IDE ready (kind:%d)\n", i, bay->content_id);
+	    	break;
+	    
+	case mb_ide_waiting:
+	    	if (bay->cd_base == 0) {
+			bay->timer = 0;
+			bay->state = mb_up;
+			MBDBG("mediabay%d: up before IDE init\n", i);
+			break;
+	    	} else if (MB_IDE_READY(i)) {
+			bay->timer = 0;
+			bay->state = mb_up;
+			if (bay->cd_index < 0)
+				bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq);
+			if (bay->cd_index == -1) {
+				/* We eventually do a retry */
+				bay->cd_retry++;
+				printk("IDE register error\n");
+				set_mb_power(i, 0);
+			} else {
+				printk(KERN_DEBUG "media-bay %d is ide %d\n", i, bay->cd_index);
+				MBDBG("mediabay %d IDE ready\n", i);
+			}
+			break;
+	    	}
+	    	if (bay->timer == 0) {
+			printk("\nIDE Timeout in bay %d !\n", i);
+			MBDBG("mediabay%d: nIDE Timeout !\n", i);
+			set_mb_power(i, 0);
+	    	}
+		break;
+#endif // #ifdef CONFIG_BLK_DEV_IDE
+
+	case mb_powering_down:
+	    	bay->state = mb_empty;
+#ifdef CONFIG_BLK_DEV_IDE
+    	        if (bay->cd_index >= 0) {
+			printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i,
+			       bay->cd_index);
+			ide_unregister(bay->cd_index);
+			bay->cd_index = -1;
+		}
+	    	if (bay->cd_retry) {
+			if (bay->cd_retry > MAX_CD_RETRIES) {
+				/* Should add an error sound (sort of beep in dmasound) */
+				printk("\nmedia-bay %d, IDE device badly inserted or unrecognised\n", i);
+			} else {
+				/* Force a new power down/up sequence */
+				bay->content_id = MB_NO;
+			}
+	    	}
+#endif	    
+		MBDBG("mediabay%d: end of power down\n", i);
+	    	break;
+	}
+}
+
 /*
  * This procedure runs as a kernel thread to poll the media bay
  * once each tick and register and unregister the IDE interface
@@ -260,128 +528,57 @@
 int
 media_bay_task(void *x)
 {
-	volatile struct media_bay_info* bay;
 	int	i = 0;
-	
+
 	strcpy(current->comm, "media-bay");
-	for (;;)
-	{
-		bay = &media_bays[i];
-		poll_media_bay(i);
-		if (bay->content_id != bay->previous_id) {
-			bay->reset_timer = (bay->content_id != MB_NO) ?
-				MB_RESET_COUNT: 0;
-			bay->ready = 0;
-#ifdef CONFIG_BLK_DEV_IDE
-			bay->cd_timer = 0;
-			if (bay->content_id != MB_CD && bay->cd_index >= 0) {
-				printk(KERN_DEBUG "Unregistering mb %d ide, index:%d\n", i, bay->cd_index);
-				ide_unregister(bay->cd_index);
-				bay->cd_index = -1;
-			}
-#endif
-		} else if (bay->reset_timer) {
-			if (--bay->reset_timer == 0) {
- 				feature_clear(bay->dev_node, FEATURE_Mediabay_reset);
-				bay->ready = 1;
-#ifdef CONFIG_BLK_DEV_IDE
-				bay->cd_timer = 0;
-				if (bay->content_id == MB_CD && bay->cd_base != 0)
-					bay->cd_timer = MB_IDE_WAIT;
+#ifdef MB_IGNORE_SIGNALS
+	sigfillset(&current->blocked);
 #endif
-			}
-#ifdef CONFIG_BLK_DEV_IDE
-		} else if (bay->cd_timer
-			   && (--bay->cd_timer == 0
-			       || (bay->cd_timer < MB_IDE_WAIT - MB_IDE_MINWAIT
-				   && MB_IDE_READY(i)))
-			   && bay->cd_index < 0) {
-			bay->cd_timer = 0;
-			printk(KERN_DEBUG "Registering IDE, base:0x%08lx, irq:%d\n", bay->cd_base, bay->cd_irq);
-			printk("\n");
-			bay->cd_index = ide_register(bay->cd_base, 0, bay->cd_irq);
-			if (bay->cd_index == -1)
-				printk("\nCD-ROM badly inserted. Remove it and try again !\n");
-			else
-				printk(KERN_DEBUG "media-bay %d is ide %d\n", i, bay->cd_index);
-#endif
-		}
 
-		bay->previous_id = bay->content_id;
-		if (++i >= media_bay_count) {
-			i = 0;
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(1);
-			if (signal_pending(current))
-				return 0;
-		}
+	for (;;) {
+	    media_bay_step(i);
+
+	    if (++i >= media_bay_count) {
+		i = 0;
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+		if (signal_pending(current))
+		    return 0;
+	    }
 	}
 }
 
 void
 poll_media_bay(int which)
 {
-	int id = MB_CONTENTS(which);
+	volatile struct media_bay_info* bay = &media_bays[which];
+	int id = mb_content(bay);
 
-	if (id == media_bays[which].last_value) {
-	    if (id != media_bays[which].content_id
-	        && ++media_bays[which].value_count >= MB_STABLE_COUNT) {
+	if (id == bay->last_value) {
+	    if (id != bay->content_id
+	        && ++bay->value_count >= MS_TO_HZ(MB_STABLE_DELAY)) {
 	        /* If the device type changes without going thru "MB_NO", we force
 	           a pass by "MB_NO" to make sure things are properly reset */
-	        if ((id != MB_NO) && (media_bays[which].content_id != MB_NO)) {
-		    set_media_bay(which, MB_NO);
-		    udelay(500);
+	        if ((id != MB_NO) && (bay->content_id != MB_NO)) {
+	            id = MB_NO;
+		    MBDBG("mediabay%d: forcing MB_NO\n", which);
+		}
+		MBDBG("mediabay%d: switching to %d\n", which, id);
+		set_mb_power(which, id != MB_NO);
+		bay->content_id = id;
+		if (id == MB_NO) {
+#ifdef CONFIG_BLK_DEV_IDE
+		    bay->cd_retry = 0;
+#endif
+		    printk(KERN_INFO "media bay %d is empty\n", which);
 		}
- 		set_media_bay(which, id);
  	    }
 	} else {
-		media_bays[which].last_value = id;
-		media_bays[which].value_count = 0;
+		bay->last_value = id;
+		bay->value_count = 0;
 	}
 }
 
-static void
-set_media_bay(int which, int id)
-{
-	volatile struct media_bay_info* bay;
-
-	bay = &media_bays[which];
-	
-	bay->content_id = id;
-	bay->last_value = id;
-	
-	switch (id) {
-	case MB_CD:
-		feature_set(bay->dev_node, FEATURE_Mediabay_enable);
-		feature_set(bay->dev_node, FEATURE_Mediabay_IDE_enable);
-		udelay(500);
-		feature_set(bay->dev_node, FEATURE_CD_power);
-		printk(KERN_INFO "media bay %d contains a CD-ROM drive\n", which);
-		break;
-	case MB_FD:
-		feature_set(bay->dev_node, FEATURE_Mediabay_enable);
-		feature_set(bay->dev_node, FEATURE_Mediabay_floppy_enable);
-		feature_set(bay->dev_node, FEATURE_SWIM3_enable);
-		printk(KERN_INFO "media bay %d contains a floppy disk drive\n", which);
-		break;
-	case MB_NO:
-		feature_clear(bay->dev_node, FEATURE_CD_power);
-		feature_clear(bay->dev_node, FEATURE_Mediabay_enable);
-		feature_clear(bay->dev_node, FEATURE_Mediabay_floppy_enable);
-		feature_clear(bay->dev_node, FEATURE_Mediabay_IDE_enable);
-		feature_clear(bay->dev_node, FEATURE_SWIM3_enable);
-		feature_set(bay->dev_node, FEATURE_Mediabay_reset);
-		printk(KERN_INFO "media bay %d is empty\n", which);
-		break;
-	default:
-		feature_set(bay->dev_node, FEATURE_Mediabay_enable);
-		printk(KERN_INFO "media bay %d contains an unknown device (%d)\n",
-		       which, id);
-		break;
-	}
-	
-	udelay(500);
-}
 
 #ifdef CONFIG_PMAC_PBOOK
 /*
@@ -392,51 +589,44 @@
 {
 	volatile struct media_bay_info* bay;
 	int i;
-	
+
 	switch (when) {
 	case PBOOK_SLEEP_REQUEST:
 	case PBOOK_SLEEP_REJECT:
 		break;
-		
+
 	case PBOOK_SLEEP_NOW:
 		for (i=0; i<media_bay_count; i++) {
 			bay = &media_bays[i];
-			feature_clear(bay->dev_node, FEATURE_Mediabay_enable);
-			feature_clear(bay->dev_node, FEATURE_Mediabay_IDE_enable);
-			feature_clear(bay->dev_node, FEATURE_SWIM3_enable);
-			feature_clear(bay->dev_node, FEATURE_Mediabay_floppy_enable);
-			feature_set(bay->dev_node, FEATURE_Mediabay_reset);
-			feature_clear(bay->dev_node, FEATURE_CD_power);
-			out_8(&media_bays[i].addr->contents, 0x70);
+			set_mb_power(i, 0);
+			mdelay(10);
+			feature_clear(bay->dev_node, FEATURE_IOBUS_enable);
 		}
 		break;
 	case PBOOK_WAKE:
 		for (i=0; i<media_bay_count; i++) {
 			bay = &media_bays[i];
-			feature_set(bay->dev_node, FEATURE_Mediabay_enable);
-			/* I suppose this is enough delay to stabilize MB_CONTENT ... */
-			mdelay(10);
 			/* We re-enable the bay using it's previous content
-			   only if it did not change */
-			if (MB_CONTENTS(i) != bay->content_id)
-				continue;
-			set_media_bay(i, bay->content_id);
-			if (bay->content_id == MB_NO)
+			   only if it did not change. Note those bozo timings,
+			   they seem to help the 3400 get it right.
+			 */
+			feature_set(bay->dev_node, FEATURE_IOBUS_enable);
+			mdelay(MB_STABLE_DELAY);
+			if (!bay->pismo)
+				out_8(&bay->addr->contents, 0x70);
+			mdelay(MB_STABLE_DELAY);
+			if (mb_content(bay) != bay->content_id)
 				continue;
-			mdelay(400);
-			/* Clear the bay reset */
-			feature_clear(bay->dev_node, FEATURE_Mediabay_reset);
-			/* This small delay makes sure the device has time
-			   to assert the BUSY bit (used by IDE sleep) */
-			udelay(100);
-			/* We reset the state machine timers in case we were
-			   in the middle of a wait loop */
-			if (bay->reset_timer)
-				bay->reset_timer = MB_RESET_COUNT;
-#ifdef CONFIG_BLK_DEV_IDE
-			if (bay->cd_timer)
-				bay->cd_timer = MB_IDE_WAIT;
-#endif
+			set_mb_power(i, 1);
+			bay->last_value = bay->content_id;
+			bay->value_count = MS_TO_HZ(MB_STABLE_DELAY);
+			bay->timer = MS_TO_HZ(MB_POWER_DELAY);
+			bay->cd_retry = 0;
+			do {
+				mdelay(1000/HZ);
+				media_bay_step(i);
+			} while((media_bays[i].state != mb_empty) &&
+				(media_bays[i].state != mb_up));
 		}
 		break;
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/rtc.c linux.17p18/drivers/macintosh/rtc.c
--- linux.vanilla/drivers/macintosh/rtc.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/macintosh/rtc.c	Tue Aug  1 07:59:39 2000
@@ -0,0 +1,163 @@
+/*
+ * Linux/PowerPC Real Time Clock Driver
+ *
+ * heavily based on:
+ * Linux/SPARC Real Time Clock Driver
+ * Copyright (C) 1996 Thomas K. Dyas (tdyas@eden.rutgers.edu)
+ *
+ * This is a little driver that lets a user-level program access
+ * the PPC clocks chip. It is no use unless you
+ * use the modified clock utility.
+ *
+ * Get the modified clock utility from:
+ *   ftp://vger.rutgers.edu/pub/linux/Sparc/userland/clock.c
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/miscdevice.h>
+#include <linux/malloc.h>
+#include <linux/fcntl.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/mc146818rtc.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/machdep.h>
+
+#include <asm/time.h>
+
+static int rtc_busy = 0;
+
+/* Retrieve the current date and time from the real time clock. */
+void get_rtc_time(struct rtc_time *t)
+{
+	unsigned long nowtime;
+    
+	nowtime = (ppc_md.get_rtc_time)();
+
+	to_tm(nowtime, t);
+
+	t->tm_year -= 1900;
+	t->tm_mon -= 1;
+	t->tm_wday -= 1;
+}
+
+/* Set the current date and time inthe real time clock. */
+void set_rtc_time(struct rtc_time *t)
+{
+	unsigned long nowtime;
+
+	printk(KERN_INFO "rtc.c:set_rtc_time: %04d-%02d-%02d %02d:%02d:%02d.\n", t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+	nowtime = mktime(t->tm_year+1900, t->tm_mon+1, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
+
+	printk(KERN_INFO "rtc.c:set_rtc_time: set rtc time to %d seconds.\n", nowtime);
+
+	(ppc_md.set_rtc_time)(nowtime);
+}
+
+static long long rtc_lseek(struct file *file, long long offset, int origin)
+{
+	return -ESPIPE;
+}
+
+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
+	unsigned long arg)
+{
+	struct rtc_time rtc_tm;
+
+	switch (cmd)
+	{
+	case RTC_RD_TIME:
+		if (ppc_md.get_rtc_time)
+		{
+			get_rtc_time(&rtc_tm);
+
+			copy_to_user_ret((struct rtc_time*)arg, &rtc_tm, sizeof(struct rtc_time), -EFAULT);
+
+			return 0;
+		}
+		else
+			return -EINVAL;
+
+	case RTC_SET_TIME:
+		if (!capable(CAP_SYS_TIME))
+			return -EPERM;
+
+		if (ppc_md.set_rtc_time)
+		{
+			copy_from_user_ret(&rtc_tm, (struct rtc_time*)arg, sizeof(struct rtc_time), -EFAULT);
+
+			set_rtc_time(&rtc_tm);
+
+			return 0;
+		}
+		else
+			return -EINVAL;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int rtc_open(struct inode *inode, struct file *file)
+{
+	if (rtc_busy)
+		return -EBUSY;
+
+	rtc_busy = 1;
+
+	MOD_INC_USE_COUNT;
+
+	return 0;
+}
+
+static int rtc_release(struct inode *inode, struct file *file)
+{
+	MOD_DEC_USE_COUNT;
+	rtc_busy = 0;
+	return 0;
+}
+
+static struct file_operations rtc_fops = {
+	rtc_lseek,
+	NULL,		/* rtc_read */
+	NULL,		/* rtc_write */
+	NULL,		/* rtc_readdir */
+	NULL,		/* rtc_poll */
+	rtc_ioctl,
+	NULL,		/* rtc_mmap */
+	rtc_open,
+	NULL,		/* flush */
+	rtc_release
+};
+
+static struct miscdevice rtc_dev = { RTC_MINOR, "rtc", &rtc_fops };
+
+EXPORT_NO_SYMBOLS;
+
+#ifdef MODULE
+int init_module(void)
+#else
+__initfunc(int rtc_init(void))
+#endif
+{
+	int error;
+
+	error = misc_register(&rtc_dev);
+	if (error) {
+		printk(KERN_ERR "rtc: unable to get misc minor\n");
+		return error;
+	}
+
+	return 0;
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+	misc_deregister(&rtc_dev);
+}
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/via-cuda.c linux.17p18/drivers/macintosh/via-cuda.c
--- linux.vanilla/drivers/macintosh/via-cuda.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/via-cuda.c	Tue Aug  1 07:59:39 2000
@@ -21,6 +21,7 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/init.h>
+#include <asm/machdep.h>
 
 static volatile unsigned char *via;
 
@@ -496,4 +497,4 @@
 cuda_present(void)
 {
 	return (adb_controller && (adb_controller->kind == ADB_VIACUDA) && via);
-}
\ No newline at end of file
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/macintosh/via-pmu.c linux.17p18/drivers/macintosh/via-pmu.c
--- linux.vanilla/drivers/macintosh/via-pmu.c	Fri Apr 21 12:46:14 2000
+++ linux.17p18/drivers/macintosh/via-pmu.c	Fri Aug  4 15:27:32 2000
@@ -1,4 +1,3 @@
-
 /*
  * Device driver for the via-pmu on Apple Powermacs.
  *
@@ -10,6 +9,12 @@
  * and the RTC (real time clock) chip.
  *
  * Copyright (C) 1998 Paul Mackerras and Fabio Riccardi.
+ * 
+ * todo: - Check this driver for smp safety (new Core99 motherboards).
+ *       - Cleanup synchro between VIA interrupt and GPIO-based PMU
+ *         interrupt.
+ *
+ *
  */
 #include <stdarg.h>
 #include <linux/config.h>
@@ -39,7 +44,7 @@
 /* Misc minor number allocated for /dev/pmu */
 #define PMU_MINOR	154
 
-static volatile unsigned char *via;
+static volatile unsigned char *via = 0;
 
 /* VIA registers - spaced 0x200 bytes apart */
 #define RS		0x200		/* skip between registers */
@@ -91,16 +96,18 @@
 static unsigned char *reply_ptr;
 static int data_index;
 static int data_len;
-static int adb_int_pending;
+static volatile int adb_int_pending;
 static int pmu_adb_flags;
 static int adb_dev_map = 0;
 static struct adb_request bright_req_1, bright_req_2, bright_req_3;
 static struct device_node *vias;
 static int pmu_kind = PMU_UNKNOWN;
 static int pmu_fully_inited = 0;
+static int pmu_has_adb, pmu_has_backlight;
+static unsigned char *gpio_reg = NULL;
+static int gpio_irq = -1;
 
 int asleep;
-struct notifier_block *sleep_notifier_list;
 
 static int init_pmu(void);
 static int pmu_queue_request(struct adb_request *req);
@@ -116,6 +123,7 @@
 static void pmu_handle_data(unsigned char *data, int len,
 			    struct pt_regs *regs);
 static void set_volume(int level);
+static void gpio1_interrupt(int irq, void *arg, struct pt_regs *regs);
 #ifdef CONFIG_PMAC_PBOOK
 static void pmu_pass_intr(unsigned char *data, int len);
 #endif
@@ -186,6 +194,7 @@
 	"PowerBook 2400/3400/3500(G3)",
 	"PowerBook G3 Series",
 	"1999 PowerBook G3",
+	"Core99"
 };
 
 int __openfirmware
@@ -198,9 +207,6 @@
 		return 0;
 	if (vias->next != 0)
 		printk(KERN_WARNING "Warning: only using 1st via-pmu\n");
-	
-	feature_set(vias, FEATURE_VIA_enable);
-
 #if 0
 	{ int i;
 
@@ -213,13 +219,16 @@
 	printk("\n"); }
 #endif
 
-	if (vias->n_addrs != 1 || vias->n_intrs != 1) {
+	if (vias->n_addrs < 1 || vias->n_intrs < 1) {
 		printk(KERN_ERR "via-pmu: %d addresses, %d interrupts!\n",
 		       vias->n_addrs, vias->n_intrs);
 		if (vias->n_addrs < 1 || vias->n_intrs < 1)
 			return 0;
 	}
 
+	pmu_has_adb = 1;
+	pmu_has_backlight = 1;
+
 	if (vias->parent->name && ((strcmp(vias->parent->name, "ohare") == 0)
 	    || device_is_compatible(vias->parent, "ohare")))
 		pmu_kind = PMU_OHARE_BASED;
@@ -227,23 +236,39 @@
 		pmu_kind = PMU_PADDINGTON_BASED;
 	else if (device_is_compatible(vias->parent, "heathrow"))
 		pmu_kind = PMU_HEATHROW_BASED;
-	else
+	else if (device_is_compatible(vias->parent, "Keylargo")) {
+		struct device_node *gpio, *gpiop;
+
+		pmu_kind = PMU_KEYLARGO_BASED;
+		pmu_has_adb = (find_type_devices("adb") != NULL);
+		pmu_has_backlight = 0; /* Not driven by PMU */
+
+		gpiop = find_devices("gpio");
+		if (gpiop && gpiop->n_addrs) {
+			gpio_reg = ioremap(gpiop->addrs->address, 0x10);
+			gpio = find_devices("extint-gpio1");
+			if (gpio && gpio->parent == gpiop && gpio->n_intrs)
+				gpio_irq = gpio->intrs[0].line;
+		}
+	} else
 		pmu_kind = PMU_UNKNOWN;
 
 	via = (volatile unsigned char *) ioremap(vias->addrs->address, 0x2000);
 
 	out_8(&via[IER], IER_CLR | 0x7f);	/* disable all intrs */
+	out_8(&via[IFR], 0x7f);			/* clear IFR */
 
 	pmu_state = idle;
 
-	if (!init_pmu())
+	if (!init_pmu()) {
 		via = NULL;
+		return 0;
+	}
 
 	adb_controller = &pmu_controller;
 
-	if (via)
-		printk(KERN_INFO "PMU driver initialized for %s\n",
-		       pbook_type[pmu_kind]);
+	printk(KERN_INFO "PMU driver initialized for %s\n",
+	       pbook_type[pmu_kind]);
 
 	return via != 0;
 }
@@ -265,13 +290,23 @@
 		return;
 	}
 
+	if (pmu_kind == PMU_KEYLARGO_BASED && gpio_irq != -1) {
+		if (request_irq(gpio_irq, gpio1_interrupt, 0, "GPIO1/ADB", (void *)0))
+			printk(KERN_ERR "pmu: can't get irq %d (GPIO1)\n", gpio_irq);
+	}
+
 	/* Enable interrupts */
 	out_8(&via[IER], IER_SET | SR_INT | CB1_INT);
 
 	pmu_fully_inited = 1;
-	
+
 	/* Enable backlight */
 	pmu_enable_backlight(1);
+
+	/* Make sure PMU settle down before continuing */
+	do {
+		pmu_poll();
+	} while (pmu_state != idle);
 }
 
 static int __openfirmware
@@ -308,6 +343,13 @@
 		udelay(10);
 	}
 
+	/* Tell PMU we are ready. Which PMU support this ? */
+	if (pmu_kind == PMU_KEYLARGO_BASED) {
+		pmu_request(&req, NULL, 2, PMU_SYSTEM_READY, 2);
+		while (!req.complete)
+			pmu_poll();
+	}
+
 	return 1;
 }
 
@@ -323,14 +365,13 @@
 {
     int i, ret;
 
-    if ((vias == NULL) || (!pmu_fully_inited))
-    {
+    if ((vias == NULL) || (!pmu_fully_inited)) {
  	req->complete = 1;
    	return -ENXIO;
-   }
+    }
 
     ret = -EINVAL;
-	
+
     switch (req->data[0]) {
     case PMU_PACKET:
 		for (i = 0; i < req->nbytes - 1; ++i)
@@ -372,6 +413,8 @@
 		}
 		break;
     case ADB_PACKET:
+	    	if (!pmu_has_adb)
+    			return -ENXIO;
 		for (i = req->nbytes - 1; i > 1; --i)
 			req->data[i+2] = req->data[i];
 		req->data[3] = req->nbytes - 2;
@@ -389,7 +432,7 @@
     	req->complete = 1;
     	return ret;
     }
-    	
+    
     if (sync) {
 	while (!req->complete)
 		pmu_poll();
@@ -404,7 +447,7 @@
 {
 	struct adb_request req;
 
-	if ((vias == NULL) || (!pmu_fully_inited))
+	if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
 		return -ENXIO;
 
 	if (devs) {
@@ -426,10 +469,9 @@
 pmu_adb_reset_bus(void)
 {
 	struct adb_request req;
-	long timeout;
 	int save_autopoll = adb_dev_map;
 
-	if ((vias == NULL) || (!pmu_fully_inited))
+	if ((vias == NULL) || (!pmu_fully_inited) || !pmu_has_adb)
 		return -ENXIO;
 
 	/* anyone got a better idea?? */
@@ -439,31 +481,21 @@
 	req.done = NULL;
 	req.data[0] = PMU_ADB_CMD;
 	req.data[1] = 0;
-	req.data[2] = 3; /* ADB_BUSRESET ??? */
+	req.data[2] = ADB_BUSRESET; /* 3 ??? */
 	req.data[3] = 0;
 	req.data[4] = 0;
 	req.reply_len = 0;
 	req.reply_expected = 1;
-	if (pmu_queue_request(&req) != 0)
-	{
+	if (pmu_queue_request(&req) != 0) {
 		printk(KERN_ERR "pmu_adb_reset_bus: pmu_queue_request failed\n");
 		return -EIO;
 	}
 	while (!req.complete)
 		pmu_poll();
-	timeout = 100000;
-	while (!req.complete) {
-		if (--timeout < 0) {
-			printk(KERN_ERR "pmu_adb_reset_bus (reset): no response from PMU\n");
-			return -EIO;
-		}
-		udelay(10);
-		pmu_poll();
-	}
 
 	if (save_autopoll != 0)
 		pmu_adb_autopoll(save_autopoll);
-		
+
 	return 0;
 }
 
@@ -538,6 +570,21 @@
 }
 
 static void __openfirmware
+wait_for_ack(void)
+{
+	int timeout = 3200;
+	while ((in_8(&via[B]) & TACK) == 0) {
+		if (--timeout < 0) {
+			printk(KERN_ERR "PMU not responding (!ack)\n");
+			return;
+		}
+		udelay(10);
+	}
+}
+
+/* New PMU seems to be very sensitive to those timings, so we make sure
+ * PCI is flushed immediately */
+static void __openfirmware
 send_byte(int x)
 {
 	volatile unsigned char *v = via;
@@ -545,6 +592,7 @@
 	out_8(&v[ACR], in_8(&v[ACR]) | SR_OUT | SR_EXT);
 	out_8(&v[SR], x);
 	out_8(&v[B], in_8(&v[B]) & ~TREQ);		/* assert TREQ */
+	(void)in_8(&v[B]);
 }
 
 static void __openfirmware
@@ -554,10 +602,11 @@
 
 	out_8(&v[ACR], (in_8(&v[ACR]) & ~SR_OUT) | SR_EXT);
 	in_8(&v[SR]);		/* resets SR */
-	out_8(&v[B], in_8(&v[B]) & ~0x10);
+	out_8(&v[B], in_8(&v[B]) & ~TREQ);
+	(void)in_8(&v[B]);
 }
 
-static int disable_poll;
+static volatile int disable_poll;
 
 static void __openfirmware
 pmu_start()
@@ -579,6 +628,7 @@
 
 	/* set the shift register to shift out and send a byte */
 	++disable_poll;
+	wait_for_ack();
 	send_byte(req->data[0]);
 	--disable_poll;
 
@@ -594,17 +644,43 @@
 	if (disable_poll)
 		return;
 	ie = _disable_interrupts();
-	if (via[IFR] & (SR_INT | CB1_INT))
+	if ((via[IFR] & (SR_INT | CB1_INT)) ||
+		(gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0))
 		via_pmu_interrupt(0, 0, 0);
 	_enable_interrupts(ie);
 }
 
+/* This function loops until the PMU is idle, to avoid spurrious shutdowns
+ * when prom.c scrollscreen or xmon spends too much time without interupts
+ * while some PMU communication is going on
+ */
+void __openfirmware
+pmu_safe_poll(void)
+{
+	int ie;
+
+	if (!via || disable_poll)
+		return;
+	do {
+		ie = _disable_interrupts();
+		if ((via[IFR] & (SR_INT | CB1_INT)) ||
+			(gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0))
+			via_pmu_interrupt(0, 0, 0);
+		_enable_interrupts(ie);
+	} while (adb_int_pending || pmu_state != idle);
+}
+
 static void __openfirmware
 via_pmu_interrupt(int irq, void *arg, struct pt_regs *regs)
 {
 	int intr;
 	int nloop = 0;
+	unsigned long flags;
 
+	/* Currently, we use brute-force cli() for syncing with GPIO
+	 * interrupt. I'll make this smarter later, along with some
+	 * spinlocks for SMP */
+	save_flags(flags);cli();
 	++disable_poll;
 	while ((intr = in_8(&via[IFR])) != 0) {
 		if (++nloop > 1000) {
@@ -623,9 +699,13 @@
 			out_8(&via[IFR], intr);
 		}
 	}
+	if (gpio_reg && (in_8(gpio_reg + 0x9) & 0x02) == 0)
+		adb_int_pending = 1;
+
 	if (pmu_state == idle) {
 		if (adb_int_pending) {
 			pmu_state = intack;
+			wait_for_ack();
 			send_byte(PMU_INT_ACK);
 			adb_int_pending = 0;
 		} else if (current_req) {
@@ -633,37 +713,43 @@
 		}
 	}
 	--disable_poll;
+	restore_flags(flags);
+}
+
+
+static void __openfirmware
+gpio1_interrupt(int irq, void *arg, struct pt_regs *regs)
+{
+	via_pmu_interrupt(0, 0, 0);
 }
 
 static void __openfirmware
 pmu_sr_intr(struct pt_regs *regs)
 {
 	struct adb_request *req;
-	int bite, timeout;
+	int bite;
 
 	if (via[B] & TREQ) {
 		printk(KERN_ERR "PMU: spurious SR intr (%x)\n", via[B]);
 		out_8(&via[IFR], SR_INT);
 		return;
 	}
-	if (via[B] & TACK)
-		printk(KERN_ERR "PMU: sr_intr but ack still high! (%x)\n",
-		       via[B]);
+	/* This one seems to appear with PMU99. According to OF methods,
+	 * the protocol didn't change...
+	 */
+	if (via[B] & TACK) {
+		while ((in_8(&via[B]) & TACK) != 0)
+			;
+	}
 
 	/* reset TREQ and wait for TACK to go high */
 	out_8(&via[B], in_8(&via[B]) | TREQ);
-	timeout = 3200;
-	while ((in_8(&via[B]) & TACK) == 0) {
-		if (--timeout < 0) {
-			printk(KERN_ERR "PMU not responding (!ack)\n");
-			return;
-		}
-		udelay(10);
-	}
+	wait_for_ack();
 
 	/* if reading grab the byte, and reset the interrupt */
 	if (pmu_state == reading || pmu_state == reading_intr)
 		bite = in_8(&via[SR]);
+
 	out_8(&via[IFR], SR_INT);
 
 	switch (pmu_state) {
@@ -810,9 +896,9 @@
 {
 	struct adb_request req;
 
-	if (vias == NULL)
+	if ((vias == NULL) || !pmu_has_backlight)
 		return;
-		
+
 	/* first call: get current backlight value */
 	if (on && backlight_level < 0) {
 		switch (pmu_kind) {
@@ -831,6 +917,7 @@
 			printk(KERN_DEBUG "pmu: nvram returned bright: %d\n", backlight_level);
 			break;
 		case PMU_PADDINGTON_BASED:
+		case PMU_KEYLARGO_BASED:
 			/* the G3 PB 1999 has a backlight node
 			   and chrp-structured nvram */
 			/* XXX should read macos's "blkt" property in nvram
@@ -861,7 +948,7 @@
 {
 	int bright;
 
-	if (vias == NULL)
+	if ((vias == NULL) || !pmu_has_backlight)
 		return ;
 
 	backlight_level = level;
@@ -890,6 +977,8 @@
 
 	if (vias == NULL)
 		return ;
+	if (pmu_kind == PMU_KEYLARGO_BASED)
+		return ;
 
 	pmu_request(&req, NULL, 2, PMU_POWER_CTRL, PMU_POW_IRLED |
 	    (on ? PMU_POW_ON : PMU_POW_OFF));
@@ -908,12 +997,12 @@
 	struct adb_request req;
 
 	_disable_interrupts();
-	
+
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
 					PMU_INT_TICK );
 	while(!req.complete)
 		pmu_poll();
-	
+
 	pmu_request(&req, NULL, 1, PMU_RESET);
 	while(!req.complete || (pmu_state != idle))
 		pmu_poll();
@@ -927,7 +1016,7 @@
 	struct adb_request req;
 
 	_disable_interrupts();
-	
+
 	pmu_request(&req, NULL, 2, PMU_SET_INTR_MASK, PMU_INT_ADB |
 					PMU_INT_TICK );
 	while(!req.complete)
@@ -944,7 +1033,7 @@
 int
 pmu_present(void)
 {
-	return (adb_controller && (adb_controller->kind == ADB_VIAPMU) && vias);
+	return via != 0;
 }
 
 #ifdef CONFIG_PMAC_PBOOK
@@ -979,7 +1068,7 @@
 
 /* Sleep is broadcast last-to-first */
 static int
-broadcast_sleep(int when, int can_cancel)
+broadcast_sleep(int when, int fallback)
 {
 	int ret = PBOOK_SLEEP_OK;
 	struct list_head *list;
@@ -989,8 +1078,15 @@
 	     list = list->prev) {
 		current = list_entry(list, struct pmu_sleep_notifier, list);
 		ret = current->notifier_call(current, when);
-		if (can_cancel && (ret != PBOOK_SLEEP_OK))
+		if (ret != PBOOK_SLEEP_OK) {
+			printk(KERN_DEBUG "sleep %d rejected by %p (%p)\n",
+			       when, current, current->notifier_call);
+			for (; list != &sleep_notifiers; list = list->next) {
+				current = list_entry(list, struct pmu_sleep_notifier, list);
+				current->notifier_call(current, fallback);
+			}
 			return ret;
+		}
 	}
 	return ret;
 }
@@ -1127,9 +1223,8 @@
 			ioremap(macio->addrs[0].address, 0x40);
 
 	/* Notify device drivers */
-	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, 1);
+	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
 	if (ret != PBOOK_SLEEP_OK) {
-		broadcast_sleep(PBOOK_SLEEP_REJECT, 0);
 		printk("pmu: sleep rejected\n");
 		return -EBUSY;
 	}
@@ -1142,7 +1237,12 @@
 	 * vmalloc's are done before actual sleep of block drivers */
 	fsync_dev(0);
 
-	broadcast_sleep(PBOOK_SLEEP_NOW, 0);
+	/* Sleep can fail now. May not be very robust but useful for debugging */
+	ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE);
+	if (ret != PBOOK_SLEEP_OK) {
+		printk("pmu: sleep failed\n");
+		return -EBUSY;
+	}
 
 	/* Give the disks a little time to actually finish writing */
 	for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
@@ -1210,7 +1310,7 @@
 	/* Restore L2 cache */
 	if (save_l2cr)
  		_set_L2CR(save_l2cr | 0x200000); /* set invalidate bit */
-	
+
 	/* reenable interrupts */
 	sleep_restore_intrs();
 
@@ -1231,9 +1331,8 @@
 	struct adb_request sleep_req;
 
 	/* Notify device drivers */
-	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, 1);
+	ret = broadcast_sleep(PBOOK_SLEEP_REQUEST, PBOOK_SLEEP_REJECT);
 	if (ret != PBOOK_SLEEP_OK) {
-		broadcast_sleep(PBOOK_SLEEP_REJECT, 0);
 		printk("pmu: sleep rejected\n");
 		return -EBUSY;
 	}
@@ -1246,7 +1345,12 @@
 	 * vmalloc's are done before actual sleep of block drivers */
 	fsync_dev(0);
 
-	broadcast_sleep(PBOOK_SLEEP_NOW, 0);
+	/* Sleep can fail now. May not be very robust but useful for debugging */
+	ret = broadcast_sleep(PBOOK_SLEEP_NOW, PBOOK_WAKE);
+	if (ret != PBOOK_SLEEP_OK) {
+		printk("pmu: sleep failed\n");
+		return -EBUSY;
+	}
 
 	/* Give the disks a little time to actually finish writing */
 	for (wait = jiffies + (HZ/4); time_before(jiffies, wait); )
@@ -1473,18 +1577,24 @@
 			error = powerbook_sleep_G3();
 			break;
 		default:
-			error = ENOSYS;
+			error = -ENOSYS;
 		}
 		return error;
 	case PMU_IOC_GET_BACKLIGHT:
+		if (!pmu_has_backlight)
+			return -ENOSYS;
 		return put_user(backlight_level, (__u32 *)arg);
 	case PMU_IOC_SET_BACKLIGHT:
+		if (!pmu_has_backlight)
+			return -ENOSYS;
 		error = get_user(value, (__u32 *)arg);
 		if (!error)
 			pmu_set_brightness(value);
 		return error;
 	case PMU_IOC_GET_MODEL:
 	    	return put_user(pmu_kind, (__u32 *)arg);
+	case PMU_IOC_HAS_ADB:
+		return put_user(pmu_has_adb, (__u32 *)arg);
 	}
 	return -EINVAL;
 }
@@ -1526,7 +1636,6 @@
 
 static inline void polled_send_byte(volatile unsigned char *via, int x)
 {
-	xmon_printf("s%.2x", x);
 	via[ACR] |= SR_OUT | SR_EXT; eieio();
 	via[SR] = x; eieio();
 	polled_handshake(via);
@@ -1540,7 +1649,6 @@
 	x = via[SR]; eieio();
 	polled_handshake(via);
 	x = via[SR]; eieio();
-	xmon_printf("r%.2x", x);
 	return x;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/3c59x.c linux.17p18/drivers/net/3c59x.c
--- linux.vanilla/drivers/net/3c59x.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/3c59x.c	Wed Aug 16 21:42:23 2000
@@ -42,11 +42,23 @@
     - In vortex_error, do_tx_reset and vortex_tx_timeout(Vortex): clear
       tbusy and force a BH rerun to better recover from errors.
 
+    24Jun00 <2.2.16> andrewm
+    - Better handling of shared interrupts
+    - Reset the transmitter in vortex_error() on both maxcollisions and Tx reclaim error
+    - Split the ISR into vortex_interrupt and boomerang_interrupt.  This is
+      to fix once-and-for-all the dubious testing of vortex status bits on
+      boomerang/hurricane/cyclone/tornado NICs.
+    - Fixed crash under OOM during vortex_open() (Mark Hemment)
+    - Fix Rx cessation problem during OOM (help from Mark Hemment)
+
+    01Aug00 <2.2.17-pre14> andrewm
+    - Added 3c556 support (Fred Maciel)
+
     - See http://www.uow.edu.au/~andrewm/linux/#3c59x-2.2 for more details.
 */
 
 static char *version =
-"3c59x.c:v0.99H 27May00 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/vortex.html\n";
+"3c59x.c:v0.99H 01Aug00 Donald Becker and others http://www.scyld.com/network/vortex.html\n";
 
 /* "Knobs" that adjust features and parameters. */
 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
@@ -316,6 +328,8 @@
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
 	{"3c555 Laptop Hurricane",	0x10B7, 0x5055, 0xffff,
 	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE, 128, vortex_probe1},
+	{"3c556 10/100 Mini PCI Adapter",	0x10B7, 0x6055, 0xffff,
+	 PCI_USES_IO|PCI_USES_MASTER, IS_CYCLONE|HAS_CB_FNS, 128, vortex_probe1},
 	{"3c575 Boomerang CardBus",		0x10B7, 0x5057, 0xffff,
 	 PCI_USES_IO|PCI_USES_MASTER, IS_BOOMERANG|HAS_MII, 64, vortex_probe1},
 	{"3CCFE575 Cyclone CardBus",	0x10B7, 0x5157, 0xffff,
@@ -559,6 +573,7 @@
 static int vortex_rx(struct device *dev);
 static int boomerang_rx(struct device *dev);
 static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct device *dev);
 static void update_stats(long ioaddr, struct device *dev);
 static struct net_device_stats *vortex_get_stats(struct device *dev);
@@ -566,6 +581,8 @@
 static int vortex_ioctl(struct device *dev, struct ifreq *rq, int cmd);
 
 
+/* #define dev_alloc_skb dev_alloc_skb_debug */
+
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Option count limit only -- unlimited interfaces are supported. */
 #define MAX_UNITS 8
@@ -620,6 +637,8 @@
 	dev = vortex_probe1(bus, devfn, NULL, io, irq, chip_idx, MAX_UNITS+1);
 	if (dev) {
 		dev_node_t *node = kmalloc(sizeof(dev_node_t), GFP_KERNEL);
+		if (!node)
+			return NULL;
 		strcpy(node->dev_name, dev->name);
 		node->major = node->minor = 0;
 		node->next = NULL;
@@ -859,6 +878,8 @@
 	/* Make certain the descriptor lists are aligned. */
 	{
 		void *mem = kmalloc(sizeof(*vp) + 15, GFP_KERNEL);
+		if (!mem)
+			return NULL;
 		vp =  (void *)(((long)mem + 15) & ~15);
 		vp->priv_addr = mem;
 	}
@@ -903,7 +924,11 @@
 #ifdef CARDBUS
 		outw(0x230 + i, ioaddr + Wn0EepromCmd);
 #else
-		outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
+		if (pci_tbl[chip_idx].device_id == 0x6055) {
+			outw(0x230 + i, ioaddr + Wn0EepromCmd);
+		} else {
+			outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
+		}
 #endif
 		/* Pause for at least 162 us. for the read to take place. */
 		for (timer = 10; timer >= 0; timer--) {
@@ -947,7 +972,11 @@
 		printk("%s: CardBus functions mapped %8.8x->%p (PCMCIA committee"
 			   " brain-damage).\n", dev->name, fn_st_addr, vp->cb_fn_base);
 		EL3WINDOW(2);
-		outw(0x10 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+		if (pci_tbl[chip_idx].device_id == 0x6055) {
+			outw(0x4010 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+		} else {
+			outw(0x10 | inw(ioaddr + Wn2_ResetOptions), ioaddr + Wn2_ResetOptions);
+		}
 	}
 
 	/* Extract our information from the EEPROM data. */
@@ -1029,12 +1058,13 @@
 	request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
 
 	/* The 3c59x-specific entries in the device structure. */
-	dev->open = &vortex_open;
-	dev->hard_start_xmit = &vortex_start_xmit;
-	dev->stop = &vortex_close;
-	dev->get_stats = &vortex_get_stats;
-	dev->do_ioctl = &vortex_ioctl;
-	dev->set_multicast_list = &set_rx_mode;
+	dev->open = vortex_open;
+	dev->hard_start_xmit = vp->full_bus_master_tx ?
+				boomerang_start_xmit : vortex_start_xmit;
+	dev->stop = vortex_close;
+	dev->get_stats = vortex_get_stats;
+	dev->do_ioctl = vortex_ioctl;
+	dev->set_multicast_list = set_rx_mode;
 
 	return dev;
 }
@@ -1046,7 +1076,9 @@
 	long ioaddr = dev->base_addr;
 	struct vortex_private *vp = (struct vortex_private *)dev->priv;
 	unsigned int config;
-	int i;
+	int i, retval;
+
+	MOD_INC_USE_COUNT;
 
 	/* Before initializing select the active media port. */
 	EL3WINDOW(3);
@@ -1068,12 +1100,6 @@
 	} else
 		dev->if_port = vp->default_media;
 
-	init_timer(&vp->timer);
-	vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
-	vp->timer.data = (unsigned long)dev;
-	vp->timer.function = &vortex_timer;		/* timer handler */
-	add_timer(&vp->timer);
-
 	if (vortex_debug > 1)
 		printk(KERN_DEBUG "%s: Initial media type %s.\n",
 			   dev->name, media_tbl[dev->if_port].name);
@@ -1123,8 +1149,11 @@
 	outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 
 	/* Use the now-standard shared IRQ implementation. */
-	if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ, dev->name, dev)) {
-		return -EAGAIN;
+	if ((retval = request_irq(dev->irq, vp->full_bus_master_tx ?
+					&boomerang_interrupt : &vortex_interrupt,
+					SA_SHIRQ, dev->name, dev))) {
+		printk(KERN_ERR "%s: Cannot allocate IRQ #%d\n", dev->name, dev->irq);
+		goto out;
 	}
 
 	if (vortex_debug > 1) {
@@ -1189,12 +1218,20 @@
 			vp->rx_ring[i].addr = virt_to_bus(skb->data);
 #endif
 		}
+		if (i != RX_RING_SIZE) {
+			int j;
+			for (j = 0; j < RX_RING_SIZE; j++) {
+				if (vp->rx_skbuff[j])
+					DEV_FREE_SKB(vp->rx_skbuff[j]);
+			}
+			retval = -ENOMEM;
+			goto out_free_irq;
+		}
 		/* Wrap the ring. */
 		vp->rx_ring[i-1].next = cpu_to_le32(virt_to_bus(&vp->rx_ring[0]));
 		outl(virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
 	}
 	if (vp->full_bus_master_tx) { 		/* Boomerang bus master Tx. */
-		dev->hard_start_xmit = &boomerang_start_xmit;
 		vp->cur_tx = vp->dirty_tx = 0;
 		outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
 		/* Clear the Tx ring. */
@@ -1228,9 +1265,18 @@
 	if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
 		writel(0x8000, vp->cb_fn_base + 4);
 
-	MOD_INC_USE_COUNT;
+	init_timer(&vp->timer);
+	vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
+	vp->timer.data = (unsigned long)dev;
+	vp->timer.function = &vortex_timer;		/* timer handler */
+	add_timer(&vp->timer);
 
 	return 0;
+
+out_free_irq:
+	free_irq(dev->irq, dev);
+out:
+	return retval;
 }
 
 static void vortex_timer(unsigned long data)
@@ -1368,7 +1414,10 @@
 			unsigned long flags;
 			__save_flags(flags);
 			__cli();
-			vortex_interrupt(dev->irq, dev, 0);
+			if (vp->full_bus_master_tx)
+				boomerang_interrupt(dev->irq, dev, 0);
+			else
+				vortex_interrupt(dev->irq, dev, 0);
 			__restore_flags(flags);
 		}
 	}
@@ -1443,8 +1492,8 @@
 		if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
 		if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
 		outb(0, ioaddr + TxStatus);
-		if (tx_status & 0x30)
-			do_tx_reset = 1;
+		if (tx_status & 0x3a)	/* TxReset after 16 collisions, despite what the manual says */
+			do_tx_reset = 1;	/* Also reset on reclaim errors */
 		else					/* Merely re-enable the transmitter. */
 			outw(TxEnable, ioaddr + EL3_CMD);
 	}
@@ -1602,10 +1651,10 @@
 		int i;
 
 		if (vortex_debug > 3)
-			printk(KERN_DEBUG "%s: Trying to send a packet, Tx index %d.\n",
+			printk(KERN_DEBUG "%s: Trying to send a boomerang packet, Tx index %d.\n",
 				   dev->name, vp->cur_tx);
 		if (vp->tx_full) {
-			if (vortex_debug >0)
+			if (vortex_debug > 0)
 				printk(KERN_WARNING "%s: Tx Ring full, refusing to send buffer.\n",
 					   dev->name);
 			return 1;
@@ -1619,7 +1668,7 @@
 		spin_lock_irqsave(&vp->lock, flags);
 		outw(DownStall, ioaddr + EL3_CMD);
 		/* Wait for the stall to complete. */
-		for (i = 4000; i >= 0 ; i--)
+		for (i = 4000; i >= 0; i--)
 			if ( (inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0)
 				break;
 		prev_entry->next = cpu_to_le32(virt_to_bus(&vp->tx_ring[entry]));
@@ -1645,19 +1694,28 @@
 
 /* The interrupt handler does all of the Rx thread work and cleans up
    after the Tx thread. */
+
+/*
+ * This is the ISR for the vortex series chips.
+ * full_bus_master_tx == 0 && full_bus_master_rx == 0
+ */
+
 static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct device *dev = dev_id;
 	struct vortex_private *vp = (struct vortex_private *)dev->priv;
 	long ioaddr;
-	int latency, status;
+	int status;
 	int work_done = max_interrupt_work;
 
-	spin_lock(&vp->lock);
-
 	ioaddr = dev->base_addr;
-	latency = inb(ioaddr + Timer);
+	spin_lock(&vp->lock);
 	status = inw(ioaddr + EL3_STATUS);
+	if ((status & IntLatch) == 0) {
+		if (vortex_debug > 5)
+			printk(KERN_DEBUG "%s: no vortex interrupt pending\n", dev->name);
+		goto no_int;	/* Happens during shared interrupts */
+	}
 
 	if (status & IntReq) {
 		status |= vp->deferred;
@@ -1665,18 +1723,16 @@
 	}
 
 	if (vortex_debug > 4)
-		printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, latency);
+		printk(KERN_DEBUG "%s: vortex_interrupt, status %4.4x, latency %d ticks.\n",
+			   dev->name, status, inb(ioaddr + Timer));
+
 	do {
 		if (vortex_debug > 5)
 				printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
 					   dev->name, status);
+
 		if (status & RxComplete)
 			vortex_rx(dev);
-		if (status & UpComplete) {
-			outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
-			boomerang_rx(dev);
-		}
 
 		if (status & TxAvailable) {
 			if (vortex_debug > 5)
@@ -1687,6 +1743,93 @@
 			mark_bh(NET_BH);
 		}
 
+		if (status & DMADone) {
+			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
+				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+				DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
+				if (inw(ioaddr + TxFree) > 1536) {
+					clear_bit(0, (void*)&dev->tbusy);
+					mark_bh(NET_BH);
+				} else /* Interrupt when FIFO has room for max-sized packet. */
+					outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+			}
+		}
+
+		/* Check for all uncommon interrupts at once. */
+		if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
+			if (status == 0xffff)
+				break;
+			vortex_error(dev, status);
+		}
+
+		if (--work_done < 0) {
+			printk(KERN_WARNING "%s: Too much work in interrupt, status "
+				   "%4.4x.\n", dev->name, status);
+			/* Disable all pending interrupts. */
+			do {
+				vp->deferred |= status;
+				outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+					 ioaddr + EL3_CMD);
+				outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+			} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+			/* The timer will reenable interrupts. */
+			mod_timer(&vp->timer, RUN_AT(1));
+			break;
+		}
+
+		/* Acknowledge the IRQ. */
+		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+	} while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+
+	if (vortex_debug > 4)
+		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
+			   dev->name, status);
+
+no_int:
+	spin_unlock(&vp->lock);
+}
+
+/*
+ * This is the ISR for the boomerang/cyclone/hurricane/tornado series chips.
+ * full_bus_master_tx == 1 && full_bus_master_rx == 1
+ */
+
+static void boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct device *dev = dev_id;
+	struct vortex_private *vp = (struct vortex_private *)dev->priv;
+	long ioaddr;
+	int status;
+	int work_done = max_interrupt_work;
+
+	ioaddr = dev->base_addr;
+	spin_lock(&vp->lock);
+	status = inw(ioaddr + EL3_STATUS);
+	if ((status & IntLatch) == 0) {
+		if (vortex_debug > 5)
+			printk(KERN_DEBUG "%s: no boomerang interrupt pending\n", dev->name);
+		goto no_int;	/* Happens during shared interrupts */
+	}
+
+	if (status & IntReq) {
+		status |= vp->deferred;
+		vp->deferred = 0;
+	}
+
+	if (vortex_debug > 4)
+		printk(KERN_DEBUG "%s: interrupt, status %04x, latency %d, cur_rx %d, dirty_rx %d\n",
+			   dev->name, status, inb(ioaddr + Timer), vp->cur_rx, vp->dirty_rx);
+
+	do {
+		if (vortex_debug > 5)
+				printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
+					   dev->name, status);
+
+		if (status & UpComplete) {
+			outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
+			boomerang_rx(dev);
+		}
+
 		if (status & DownComplete) {
 			unsigned int dirty_tx = vp->dirty_tx;
 
@@ -1705,22 +1848,12 @@
 			vp->dirty_tx = dirty_tx;
 			outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
 			if (vp->tx_full && (vp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
-				vp->tx_full= 0;
+				vp->tx_full = 0;
 				clear_bit(0, (void*)&dev->tbusy);
 				mark_bh(NET_BH);
 			}
 		}
-		if (status & DMADone) {
-			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
-				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
-				DEV_FREE_SKB(vp->tx_skb); /* Release the transfered buffer */
-				if (inw(ioaddr + TxFree) > 1536) {
-					clear_bit(0, (void*)&dev->tbusy);
-					mark_bh(NET_BH);
-				} else /* Interrupt when FIFO has room for max-sized packet. */
-					outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
-			}
-		}
+
 		/* Check for all uncommon interrupts at once. */
 		if (status & (HostError | RxEarly | StatsFull | TxComplete | IntReq)) {
 			if (status == 0xffff)
@@ -1729,25 +1862,18 @@
 		}
 
 		if (--work_done < 0) {
-			if ((status & (0x7fe - (UpComplete | DownComplete))) == 0) {
-				/* Just ack these and return. */
-				outw(AckIntr | UpComplete | DownComplete, ioaddr + EL3_CMD);
-			} else {
-				printk(KERN_WARNING "%s: Too much work in interrupt, status "
-					   "%4.4x.\n", dev->name, status);
-				/* Disable all pending interrupts. */
-				do {
-					vp->deferred |= status;
-					outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
-						 ioaddr + EL3_CMD);
-					outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-				} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
-				/* The timer will reenable interrupts. */
-				del_timer(&vp->timer);
-				vp->timer.expires = RUN_AT(1);
-				add_timer(&vp->timer);
-				break;
-			}
+			printk(KERN_WARNING "%s: Too much work in interrupt, status "
+				   "%4.4x.\n", dev->name, status);
+			/* Disable all pending interrupts. */
+			do {
+				vp->deferred |= status;
+				outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+					 ioaddr + EL3_CMD);
+				outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+			} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+			/* The timer will reenable interrupts. */
+			mod_timer(&vp->timer, RUN_AT(1));
+			break;
 		}
 
 		/* Acknowledge the IRQ. */
@@ -1755,14 +1881,22 @@
 		if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
 			writel(0x8000, vp->cb_fn_base + 4);
 
-	} while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+	} while ((status = inw(ioaddr + EL3_STATUS)) & IntLatch);
+
+	/*
+	 * If we have totally run out to rx skb's due to persistent OOM,
+	 * we can use the Tx interrupt to retry the allocation.  Dirty
+	 * but expedient
+	 */
+	if ((vp->cur_rx - vp->dirty_rx) == RX_RING_SIZE)
+		boomerang_rx(dev);
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
 			   dev->name, status);
 
+no_int:
 	spin_unlock(&vp->lock);
-	return;
 }
 
 static int vortex_rx(struct device *dev)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/Config.in linux.17p18/drivers/net/Config.in
--- linux.vanilla/drivers/net/Config.in	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/Config.in	Tue Aug  1 07:59:44 2000
@@ -46,7 +46,11 @@
   fi
   if [ "$CONFIG_PPC" = "y" ]; then
     tristate 'MACE (Power Mac ethernet) support' CONFIG_MACE
+    if [ "$CONFIG_MACE" != "n" ]; then
+      bool 'Use AAUI port instead of TP by default' CONFIG_MACE_AAUI_PORT
+    fi
     tristate 'BMAC (G3 ethernet) support' CONFIG_BMAC
+    tristate 'GMAC (G4/iBook ethernet) support' CONFIG_GMAC
     tristate 'Symbios 53c885 (Synergy ethernet) support' CONFIG_NCR885E
   fi
   if [ "$CONFIG_ZORRO" = "y" ]; then
@@ -221,8 +225,8 @@
 fi
 
 tristate 'PPP (point-to-point) support' CONFIG_PPP
-if [ ! "$CONFIG_PPP" = "n" ]; then
-  comment 'CCP compressors for PPP are only built as modules.'
+if [ "$CONFIG_PPP" = "y" ]; then
+  comment 'CCP compressors for PPP will also be built in.'
 fi
 
 tristate 'SLIP (serial line) support' CONFIG_SLIP
@@ -319,6 +323,10 @@
 
     if [ "$CONFIG_PCI" != "n" ]; then
       dep_tristate '  SBE wanXL support' CONFIG_WANXL $CONFIG_HDLC
+      dep_tristate '  Cyclades-PC300 support' CONFIG_PC300 $CONFIG_HDLC
+      if [ "$CONFIG_PC300" != "n" ]; then
+        bool '    Cyclades-PC300 X.25 support (please read help)' CONFIG_PC300_X25
+      fi
     fi
   fi
 fi
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/Makefile linux.17p18/drivers/net/Makefile
--- linux.vanilla/drivers/net/Makefile	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/Makefile	Tue Aug  1 07:59:44 2000
@@ -22,6 +22,8 @@
 CONFIG_8390_MODULE  :=
 CONFIG_SLHC_BUILTIN :=
 CONFIG_SLHC_MODULE  :=
+CONFIG_BSDCOMP_BUILTIN :=
+CONFIG_BSDCOMP_MODULE  :=
 CONFIG_PPPDEF_BUILTIN :=
 CONFIG_PPPDEF_MODULE  :=
 CONFIG_7990_BUILTIN :=
@@ -35,12 +37,14 @@
 
 ifeq ($(CONFIG_ISDN),y)
   ifeq ($(CONFIG_ISDN_PPP),y)
+    CONFIG_BSDCOMP_BUILTIN = y
     CONFIG_SLHC_BUILTIN = y
     CONFIG_PPPDEF_BUILTIN = y
   endif
 else
   ifeq ($(CONFIG_ISDN),m)
     ifeq ($(CONFIG_ISDN_PPP),y)
+      CONFIG_BSDCOMP_MODULE = y
       CONFIG_SLHC_MODULE = y
       CONFIG_PPPDEF_MODULE = y
     endif
@@ -311,19 +315,17 @@
   endif
 endif
 
-# bsd_comp.o is *always* a module, for some documented reason
-# (licensing).
 ifeq ($(CONFIG_PPP),y)
 LX_OBJS += ppp.o
-M_OBJS += bsd_comp.o
+CONFIG_BSDCOMP_BUILTIN = y
 CONFIG_SLHC_BUILTIN = y
 CONFIG_PPPDEF_BUILTIN = y
 else
   ifeq ($(CONFIG_PPP),m)
+  CONFIG_BSDCOMP_MODULE = y
   CONFIG_SLHC_MODULE = y
   CONFIG_PPPDEF_MODULE = y
   MX_OBJS += ppp.o
-  M_OBJS += bsd_comp.o
   endif
 endif
 
@@ -1003,6 +1005,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_PC300),y)
+L_OBJS += pc300.o
+else
+  ifeq ($(CONFIG_PC300),m)
+  M_OBJS += pc300.o
+  endif
+endif
+
 # If anything built-in uses syncppp, then build it into the kernel also.
 # If not, but a module uses it, build as a module.
 
@@ -1014,6 +1024,16 @@
   endif
 endif
 
+# If anything built-in uses bsd_comp, then build it into the kernel also.
+# If not, but a module uses it, build as a module.
+ifdef CONFIG_BSDCOMP_BUILTIN
+LX_OBJS += bsd_comp.o
+else
+  ifdef CONFIG_BSDCOMP_MODULE
+  MX_OBJS += bsd_comp.o
+  endif
+endif
+
 # If anything built-in uses slhc, then build it into the kernel also.
 # If not, but a module uses it, build as a module.
 ifdef CONFIG_SLHC_BUILTIN
@@ -1026,10 +1046,8 @@
 
 # if anything built-in uses ppp_deflate, then build it into the kernel also.
 # If not, but a module uses it, build as a module.
-# ... NO!!!  ppp_deflate.o does not work as resident;
-# it works only as a module!
 ifdef CONFIG_PPPDEF_BUILTIN
-MX_OBJS += ppp_deflate.o
+LX_OBJS += ppp_deflate.o
 else
   ifdef CONFIG_PPPDEF_MODULE
   MX_OBJS += ppp_deflate.o
@@ -1242,6 +1260,14 @@
 else
   ifeq ($(CONFIG_BMAC),m)
   M_OBJS += bmac.o
+  endif
+endif
+
+ifeq ($(CONFIG_GMAC),y)
+L_OBJS += gmac.o
+else
+  ifeq ($(CONFIG_GMAC),m)
+  M_OBJS += gmac.o
   endif
 endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/Space.c linux.17p18/drivers/net/Space.c
--- linux.vanilla/drivers/net/Space.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/Space.c	Tue Aug  1 07:59:44 2000
@@ -57,6 +57,7 @@
 extern int eepro100_probe(struct device *);
 extern int el3_probe(struct device *);
 extern int at1500_probe(struct device *);
+extern int bond_init(struct device *);
 extern int pcnet32_probe(struct device *);
 extern int at1700_probe(struct device *);
 extern int fmv18x_probe(struct device *);
@@ -103,6 +104,7 @@
 extern int tlan_probe(struct device *);
 extern int mace_probe(struct device *);
 extern int bmac_probe(struct device *);
+extern int gmac_probe(struct device *);
 extern int ncr885e_probe(struct device *);
 extern int cs89x0_probe(struct device *dev);
 extern int ethertap_probe(struct device *dev);
@@ -121,6 +123,7 @@
 extern int lance_probe(struct device *dev);
 extern int rcpci_probe(struct device *);
 extern int dmfe_probe(struct device *);
+extern int sktr_probe(struct device *dev);
 
 /* Gigabit Ethernet adapters */
 extern int yellowfin_probe(struct device *dev);
@@ -470,6 +473,9 @@
 #ifdef CONFIG_BMAC
 	{bmac_probe, 0},
 #endif
+#ifdef CONFIG_GMAC
+	{gmac_probe, 0},
+#endif
 #ifdef CONFIG_NCR885E
 	{ncr885e_probe, 0},
 #endif
@@ -631,6 +637,12 @@
     static struct device tap0_dev = { "tap0", 0, 0, 0, 0, NETLINK_TAPBASE, 0, 0, 0, 0, NEXT_DEV, ethertap_probe, };
 #   undef NEXT_DEV
 #   define NEXT_DEV	(&tap0_dev)
+#endif
+
+#ifdef CONFIG_BONDING
+static struct device bonding_dev = { "bond0", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, bond_init, };
+#    undef NEXT_DEV
+#    define NEXT_DEV    (&bonding_dev)
 #endif
 
 #ifdef CONFIG_LANMEDIA
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/a2065.c linux.17p18/drivers/net/a2065.c
--- linux.vanilla/drivers/net/a2065.c	Fri Apr 21 12:46:15 2000
+++ linux.17p18/drivers/net/a2065.c	Tue Aug  1 07:59:44 2000
@@ -1,8 +1,7 @@
 /*
  * Amiga Linux/68k A2065 Ethernet Driver
  *
- * (C) Copyright 1995 by Geert Uytterhoeven
- *                      (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ * (C) Copyright 1995 by Geert Uytterhoeven <geert@linux-m68k.org>
  *
  * Fixes and tips by:
  *	- Janos Farkas (CHEXUM@sparta.banki.hu)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/a2065.h linux.17p18/drivers/net/a2065.h
--- linux.vanilla/drivers/net/a2065.h	Fri Apr 21 12:46:15 2000
+++ linux.17p18/drivers/net/a2065.h	Tue Aug  1 07:59:44 2000
@@ -1,8 +1,7 @@
 /*
  * Amiga Linux/68k A2065 Ethernet Driver
  *
- * (C) Copyright 1995 by Geert Uytterhoeven
- *			(Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ * (C) Copyright 1995 by Geert Uytterhoeven <geert@linux-m68k.org>
  *
  * ---------------------------------------------------------------------------
  *
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/ariadne.c linux.17p18/drivers/net/ariadne.c
--- linux.vanilla/drivers/net/ariadne.c	Fri Apr 21 12:46:15 2000
+++ linux.17p18/drivers/net/ariadne.c	Tue Aug  1 07:59:44 2000
@@ -1,8 +1,7 @@
 /*
  *  Amiga Linux/m68k Ariadne Ethernet Driver
  *
- *  © Copyright 1995 by Geert Uytterhoeven
- *		       (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *  © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
  *			Peter De Schrijver
  *		       (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)
  *
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/ariadne.h linux.17p18/drivers/net/ariadne.h
--- linux.vanilla/drivers/net/ariadne.h	Fri Apr 21 12:46:15 2000
+++ linux.17p18/drivers/net/ariadne.h	Tue Aug  1 07:59:44 2000
@@ -1,8 +1,7 @@
 /*
  *  Amiga Linux/m68k Ariadne Ethernet Driver
  *
- *  © Copyright 1995 by Geert Uytterhoeven
- *		       (Geert.Uytterhoeven@cs.kuleuven.ac.be)
+ *  © Copyright 1995 by Geert Uytterhoeven (geert@linux-m68k.org)
  *			Peter De Schrijver
  *		       (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)
  *
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/arlan.c linux.17p18/drivers/net/arlan.c
--- linux.vanilla/drivers/net/arlan.c	Fri Apr 21 12:46:15 2000
+++ linux.17p18/drivers/net/arlan.c	Wed Aug 16 21:42:23 2000
@@ -3,6 +3,11 @@
  *  Copyright (C) 1998 Elmer.Joandi@ut.ee, +37-255-13500        
  *  Gnu Public License applies
  * This module provides support for the Arlan 655 card made by Aironet
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/15/2000
+ * - fix some leaks on failure at arlan_allocate_device
+ * - check kmalloc in arlan_probe and init_module
  */
 
 
@@ -1197,16 +1202,20 @@
 		return 0;
 	}
 
-	memset(dev->priv,0,sizeof(struct arlan_private));
+	if (devs)
+		memset(dev->priv,0,sizeof(struct arlan_private));
 
 	((struct arlan_private *) dev->priv)->conf =
 	    kmalloc(sizeof(struct arlan_shmem), GFP_KERNEL);
 
-	if (dev == NULL || dev->priv == NULL ||
-	    ((struct arlan_private *) dev->priv)->conf == NULL)
+	if (((struct arlan_private *) dev->priv)->conf == NULL)
 	{
-		return 0;
 		printk(KERN_CRIT " No memory at arlan_allocate_device \n");
+		if (!devs)
+			kfree(dev);
+		else
+			kfree(dev->priv);
+		return 0;
 	}
 	/* Fill in the 'dev' fields. */
 	dev->base_addr = 0;
@@ -2032,12 +2041,15 @@
 	printk("Arlan driver %s\n", arlan_version);
 
 	if (arlan_probe_everywhere(dev))
-		return ENODEV;
+		return -ENODEV;
 
 	arlans_found++;
 
-	if (arlans_found == 1)
+	if (arlans_found == 1) {
 		siteName = kmalloc(100, GFP_KERNEL);
+		if (!siteName)
+			return -ENOMEM;
+	}
 	return 0;
 }
 
@@ -2069,10 +2081,13 @@
 	}
 	for (i = 0; i < numDevices && i < MAX_ARLANS; i++)
 	{
-		if (!arlan_allocate_device(i, NULL))
+		if (!arlan_allocate_device(i, NULL)) {
+			kfree(siteName);
 			return -1;
+		}
 		if (arlan_device[i] == NULL)
 		{
+			kfree(siteName);
 			printk(KERN_CRIT "arlan: Not Enough memory \n");
 			return -1;
 		}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/at1700.c linux.17p18/drivers/net/at1700.c
--- linux.vanilla/drivers/net/at1700.c	Fri Apr 21 12:46:15 2000
+++ linux.17p18/drivers/net/at1700.c	Wed Aug  9 22:28:19 2000
@@ -557,7 +557,8 @@
 		/* ToDo: We should try to restart the adaptor... */
 		outw(0xffff, ioaddr + 24);
 		outw(0xffff, ioaddr + TX_STATUS);
-		outw(0xe85a, ioaddr + CONFIG_0);
+		outw(0x5a, ioaddr + CONFIG_0);
+		outw(0xe8, ioaddr + CONFIG_1);
 		outw(0x8182, ioaddr + TX_INTR);
 		outb(0x00, ioaddr + TX_START);
 		outb(0x03, ioaddr + COL16CNTL);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/bmac.c linux.17p18/drivers/net/bmac.c
--- linux.vanilla/drivers/net/bmac.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/bmac.c	Fri Aug  4 15:27:32 2000
@@ -1628,9 +1628,9 @@
     bp = (struct bmac_data *) bmac_devs->priv;
     unregister_netdev(bmac_devs);
 
-    free_irq(bmac_devs->irq, bmac_misc_intr);
-    free_irq(bp->tx_dma_intr, bmac_txdma_intr);
-    free_irq(bp->rx_dma_intr, bmac_rxdma_intr);
+    free_irq(bmac_devs->irq, bmac_devs);
+    free_irq(bp->tx_dma_intr, bmac_devs);
+    free_irq(bp->rx_dma_intr, bmac_devs);
 
 #ifdef CONFIG_PMAC_PBOOK
     pmu_unregister_sleep_notifier(&bmac_sleep_notifier);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/bonding.c linux.17p18/drivers/net/bonding.c
--- linux.vanilla/drivers/net/bonding.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/bonding.c	Wed Aug 16 22:10:48 2000
@@ -4,7 +4,7 @@
  * Copyright 1999, Thomas Davis, tadavis@lbl.gov.  
  * Licensed under the GPL. Based on dummy.c, and eql.c devices.
  *
- * bond.c: a bonding/etherchannel/sun trunking net driver
+ * bonding.c: a bonding/etherchannel/sun trunking net driver
  *
  * This is useful to talk to a Cisco 5500, running Etherchannel, aka:
  *	Linux Channel Bonding
@@ -28,6 +28,10 @@
  *
  * v0.1 - first working version.
  * v0.2 - changed stats to be calculated by summing slaves stats.
+ *
+ * Changes:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
+ * - fix leaks on failure at bond_init
  * 
  */
 
@@ -71,8 +75,12 @@
 	bonding_t *private = (struct bonding *) master->priv;
 	slave_queue_t *queue = (struct slave_queue *) private->queue;
 	slave_t *slave, *next;
+	unsigned long flags;
 
-	for( slave=queue->head; slave != NULL; slave=next) {
+	save_flags(flags);
+	cli();
+
+	for( slave=queue->head; slave != NULL; ) {
 #ifdef BONDING_DEBUG
 		printk("freeing = %s\n", slave->dev->name);
 #endif
@@ -80,8 +88,12 @@
 		slave->dev->slave = NULL;
 		next = slave->next;
 		kfree(slave);
-		queue->num_slaves++;
+		slave=next;
+		queue->num_slaves--;
 	}
+	queue->head = NULL;
+	
+	restore_flags(flags);
 
 	MOD_DEC_USE_COUNT;
 	return 0;
@@ -97,7 +109,7 @@
 	bonding_t *private = (struct bonding *) master->priv;
 	slave_queue_t *queue = (struct slave_queue *) private->queue;
 	slave_t *new_slave;
-	int flags;
+	unsigned long flags;
 	
 	if (master == NULL || slave == NULL) 
 		return -ENODEV;
@@ -121,14 +133,15 @@
 		return -EBUSY;
 	}
 		   
-	slave->slave = master;     /* save the master in slave->slave */
-	slave->flags |= IFF_SLAVE;
-
 	if ((new_slave = kmalloc(sizeof(slave_t), GFP_KERNEL)) == NULL) {
+		restore_flags(flags);
 		return -ENOMEM;
 	}
 	memset(new_slave, 0, sizeof(slave_t));
 
+	slave->slave = master;     /* save the master in slave->slave */
+	slave->flags |= IFF_SLAVE;
+
 	new_slave->dev = slave;
 
 	if (queue->head == NULL) {
@@ -202,14 +215,19 @@
 	bond = (struct bonding *) dev->priv;
 
 	bond->queue = kmalloc(sizeof(struct slave_queue), GFP_KERNEL);
-	if (bond->queue == NULL)
+	if (bond->queue == NULL) {
+		kfree(dev->priv);
 		return -ENOMEM;
+	}
 
 	memset(bond->queue, 0, sizeof(struct slave_queue));
 
 	bond->stats = kmalloc(sizeof(struct enet_statistics), GFP_KERNEL);
-	if (bond->stats == NULL)
+	if (bond->stats == NULL) {
+		kfree(dev->priv);
+		kfree(bond->queue);
 		return -ENOMEM;
+	}
 
 	memset(bond->stats, 0, sizeof(struct enet_statistics));
 
@@ -240,6 +258,11 @@
 	struct slave_queue *queue = bond->queue;
 	int good = 0;
 	
+	if(!queue->num_slaves) {
+		dev_kfree_skb(skb);
+		return 0;
+	}
+
 	while (good == 0) {
 		slave = queue->current_slave->dev;
 		if (slave->flags & (IFF_UP|IFF_RUNNING)) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/bsd_comp.c linux.17p18/drivers/net/bsd_comp.c
--- linux.vanilla/drivers/net/bsd_comp.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/bsd_comp.c	Tue Aug  1 07:59:44 2000
@@ -1,3 +1,11 @@
+/*
+ * Update: The Berkeley copyright was changed, and the change
+ * is retroactive to all "true" BSD software (ie everything
+ * from UCB as opposed to other peoples code that just carried
+ * the same license). The new copyright doesn't clash with the
+ * GPL, so the module-only restriction has been removed..
+ */
+
 /* Because this code is derived from the 4.3BSD compress source:
  *
  * Copyright (c) 1985, 1986 The Regents of the University of California.
@@ -53,12 +61,9 @@
  * From: bsd_comp.c,v 1.3 1994/12/08 01:59:58 paulus Exp
  */
 
-#ifndef MODULE
-#error This file must be compiled as a module.
-#endif
-
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
@@ -1173,12 +1178,7 @@
     bsd_comp_stats		/* decomp_stat */
 };
 
-/*************************************************************
- * Module support routines
- *************************************************************/
-
-int
-init_module(void)
+__initfunc(int bsd_comp_install(void))
 {
 	int answer = ppp_register_compressor (&ppp_bsd_compress);
 	if (answer == 0)
@@ -1186,8 +1186,18 @@
 	return answer;
 }
 
+#ifdef MODULE
+
+int
+init_module(void)
+{
+	return bsd_comp_install();
+}
+
 void
 cleanup_module(void)
 {
 	ppp_unregister_compressor (&ppp_bsd_compress);
 }
+
+#endif /* MODULE */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/c101.c linux.17p18/drivers/net/c101.c
--- linux.vanilla/drivers/net/c101.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/c101.c	Thu Aug 17 17:48:22 2000
@@ -73,21 +73,21 @@
 typedef card_t port_t;
 
 
-#define sca_in(reg, card)	     readb(card->win0base+C101_SCA+reg)
-#define sca_out(value, reg, card)    writeb(value, card->win0base+C101_SCA+reg)
-#define sca_inw(reg, card)	     readw(card->win0base+C101_SCA+reg)
-#define sca_outw(value, reg, card)   writew(value, card->win0base+C101_SCA+reg)
+#define sca_in(reg, card)	   readb((card)->win0base+C101_SCA+(reg))
+#define sca_out(value, reg, card)  writeb(value, (card)->win0base+C101_SCA+(reg))
+#define sca_inw(reg, card)	   readw((card)->win0base+C101_SCA+(reg))
+#define sca_outw(value, reg, card) writew(value, (card)->win0base+C101_SCA+(reg))
 
 #define port_to_card(port)	     (port)
 #define log_node(port)		     (0)
 #define phy_node(port)		     (0)
 #define winsize(card)		     (C101_WINDOW_SIZE)
-#define win0base(card)		     (card->win0base)
-#define winbase(card)      	     (card->win0base+0x2000)
-#define get_port(card, port)	     (port == 0 ? card : NULL)
+#define win0base(card)		     ((card)->win0base)
+#define winbase(card)      	     ((card)->win0base+0x2000)
+#define get_port(card, port)	     ((port) == 0 ? (card) : NULL)
 
 
-static __inline__ u8 get_page(card_t *card)
+static __inline__ u8 sca_get_page(card_t *card)
 {
 	return card->page;
 }
@@ -117,12 +117,14 @@
 static __inline__ void open_port(port_t *port)
 {
 	writeb(1, port->win0base+C101_DTR);
+	sca_out(0, MSCI1_OFFSET + CTL, port); /* RTS uses ch#2 output */
 }
 
 
 static __inline__ void close_port(port_t *port)
 {
 	writeb(0, port->win0base+C101_DTR);
+	sca_out(CTL_NORTS, MSCI1_OFFSET + CTL, port);
 }
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/com20020.c linux.17p18/drivers/net/com20020.c
--- linux.vanilla/drivers/net/com20020.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/com20020.c	Wed Aug 16 21:39:44 2000
@@ -1,6 +1,6 @@
 /*	$Id: com20020.c,v 1.6 1997/11/09 11:04:58 mj Exp $
 
-        Written 1997 by David Woodhouse <dwmw2@cam.ac.uk>
+        Written 1997 by David Woodhouse <dwmw2@infradead.org>
 
 	Derived from the original arcnet.c,
 	Written 1994-1996 by Avery Pennarun,
@@ -995,8 +995,11 @@
 
   if (dev->irq==2) dev->irq=9;
 
-  if (register_netdev(dev) != 0)
+  if (register_netdev(dev) != 0) {
+    kfree(dev->name);
+    kfree(dev);
     return -EIO;
+  }
 
   /* Increase use count of arcnet.o */
   arcnet_use_count(1);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/com90io.c linux.17p18/drivers/net/com90io.c
--- linux.vanilla/drivers/net/com90io.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/com90io.c	Wed Aug 16 21:39:44 2000
@@ -1,6 +1,6 @@
 /*	$Id: com90io.c,v 1.6 1997/11/09 11:04:59 mj Exp $
 
-        Written 1997 by David Woodhouse <dwmw2@cam.ac.uk>
+        Written 1997 by David Woodhouse <dwmw2@infradead.org>
 
 	Derived from the original arcnet.c,
 	Written 1994-1996 by Avery Pennarun,
@@ -871,8 +871,11 @@
 
   if (dev->irq==2) dev->irq=9;
 
-  if (register_netdev(dev) != 0)
+  if (register_netdev(dev) != 0) {
+    kfree(dev->name);
+    kfree(dev);
     return -EIO;
+  }
 
   /* Increase use count of arcnet.o */
   arcnet_use_count(1);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/comx-hw-comx.c linux.17p18/drivers/net/comx-hw-comx.c
--- linux.vanilla/drivers/net/comx-hw-comx.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/comx-hw-comx.c	Wed Aug 16 21:42:30 2000
@@ -9,6 +9,9 @@
  *
  * Copyright (C) 1995-2000 ITConsult-Pro Co. <info@itc.hu>
  *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 0.86
+ *
  * 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
@@ -37,9 +40,11 @@
  * Version 0.85 (00/01/14):
  *		- some additional workarounds :/
  *		- printk cleanups
+ * Version 0.86 (00/08/15):
+ * 		- resource release on failure at COMX_init
  */
 
-#define VERSION "0.85"
+#define VERSION "0.86"
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -1241,7 +1246,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, ch->procdir))
 	    == NULL) {
-	    	return -EIO;
+		goto cleanup_HW_privdata;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &comxhw_read_proc;
@@ -1252,7 +1257,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, ch->procdir))
 	    == NULL) {
-	    	return -EIO;
+		goto cleanup_filename_io;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &comxhw_read_proc;
@@ -1263,8 +1268,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_CHANNEL, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-	    	return -EIO;
+		goto cleanup_filename_irq;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &comxhw_read_proc;
 	new_file->write_proc = &comxhw_write_proc;
@@ -1275,7 +1281,7 @@
 	if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw) {
 		if ((new_file = create_proc_entry(FILENAME_CLOCK, S_IFREG | 0644, 
 		   ch->procdir)) == NULL) {
-		   	return -EIO;
+		   	goto cleanup_filename_channel;
 		}
 		new_file->data = (void *)new_file;
 		new_file->read_proc = &comxhw_read_proc;
@@ -1287,7 +1293,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_MEMADDR, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-	    	return -EIO;
+	    	goto cleanup_filename_clock;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &comxhw_read_proc;
@@ -1298,7 +1304,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_TWIN, S_IFREG | 0444, 
 	    ch->procdir)) == NULL) {
-		return -EIO;
+		goto cleanup_filename_memaddr;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &comxhw_read_proc;
@@ -1308,7 +1314,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_FIRMWARE, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-	    	return -EIO;
+	    	goto cleanup_filename_twin;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &comxhw_read_proc;
@@ -1350,6 +1356,22 @@
 
 	MOD_INC_USE_COUNT;
 	return 0;
+cleanup_filename_twin:
+	remove_proc_entry(FILENAME_TWIN, ch->procdir);
+cleanup_filename_memaddr:
+	remove_proc_entry(FILENAME_MEMADDR, ch->procdir);
+cleanup_filename_clock:
+	if (ch->hardware == &hicomx_hw || ch->hardware == &cmx_hw)
+		remove_proc_entry(FILENAME_CLOCK, ch->procdir);
+cleanup_filename_channel:
+	remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
+cleanup_filename_irq:
+	remove_proc_entry(FILENAME_IRQ, ch->procdir);
+cleanup_filename_io:
+	remove_proc_entry(FILENAME_IO, ch->procdir);
+cleanup_HW_privdata:
+	kfree(ch->HW_privdata);
+	return -EIO;
 }
 
 /* Called on echo valami >boardtype */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/comx-hw-locomx.c linux.17p18/drivers/net/comx-hw-locomx.c
--- linux.vanilla/drivers/net/comx-hw-locomx.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/comx-hw-locomx.c	Wed Aug 16 21:42:30 2000
@@ -7,6 +7,9 @@
  * Based on skeleton code and old LoCOMX driver by Tivadar Szemethy <tiv@itc.hu> 
  * and the hostess_sv11 driver
  *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.14)
+ *
  * Copyright (C) 1999 ITConsult-Pro Co. <info@itc.hu>
  *
  * This program is free software; you can redistribute it and/or
@@ -27,9 +30,11 @@
  * Version 0.13 (99/07/08):
  *		- Fix the transmitter status check
  *		- Handle the net device statistics better
+ * Version 0.14 (00/08/15):
+ * 		- resource release on failure at LOCOMX_init
  */
 
-#define VERSION "0.13"
+#define VERSION "0.14"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -392,7 +397,7 @@
 	/* Register /proc files */
 	if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-		return -EIO;
+		goto cleanup_HW_privdata;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &locomx_read_proc;
@@ -402,7 +407,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, 
 	    ch->procdir)) == NULL)  {
-		return -EIO;
+		goto cleanup_filename_io;
 	}
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &locomx_read_proc;
@@ -442,6 +447,11 @@
 	/* O.K. Count one more user on this module */
 	MOD_INC_USE_COUNT;
 	return 0;
+cleanup_filename_io:
+	remove_proc_entry(FILENAME_IO, ch->procdir);
+cleanup_HW_privdata:
+	kfree(ch->HW_privdata);
+	return -EIO;
 }
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/comx-hw-mixcom.c linux.17p18/drivers/net/comx-hw-mixcom.c
--- linux.vanilla/drivers/net/comx-hw-mixcom.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/comx-hw-mixcom.c	Wed Aug 16 21:42:30 2000
@@ -8,6 +8,9 @@
  *
  * Copyright (C) 1998-1999 ITConsult-Pro Co. <info@itc.hu>
  *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.65)
+ *
  * 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
@@ -29,9 +32,12 @@
  *
  * Version 0.64 (99/12/01):
  *		- some more cosmetical fixes
+ *
+ * Version 0.65 (00/08/15)
+ *		- resource release on failure at MIXCOM_init
  */
 
-#define VERSION "0.64"
+#define VERSION "0.65"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -825,8 +831,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_IO, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-		return -EIO;
+		goto cleanup_HW_privdata;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &mixcom_read_proc;
 	new_file->write_proc = &mixcom_write_proc;
@@ -835,8 +842,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_IRQ, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-	    	return -EIO;
+	    	goto cleanup_filename_io;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &mixcom_read_proc;
 	new_file->write_proc = &mixcom_write_proc;
@@ -857,8 +865,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_CHANNEL, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-	    	return -EIO;
+	    	goto cleanup_filename_irq;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &mixcom_read_proc;
 	new_file->write_proc = &mixcom_write_proc;
@@ -867,8 +876,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_TWIN, S_IFREG | 0444, 
 	    ch->procdir)) == NULL) {
-	    	return -EIO;
+	    	goto cleanup_filename_channel;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &mixcom_read_proc;
 	new_file->write_proc = &mixcom_write_proc;
@@ -892,6 +902,15 @@
 
 	MOD_INC_USE_COUNT;
 	return 0;
+cleanup_filename_channel:
+	remove_proc_entry(FILENAME_CHANNEL, ch->procdir);
+cleanup_filename_irq:
+	remove_proc_entry(FILENAME_IRQ, ch->procdir);
+cleanup_filename_io:
+	remove_proc_entry(FILENAME_IO, ch->procdir);
+cleanup_HW_privdata:
+	kfree(ch->HW_privdata);
+	return -EIO;
 }
 
 static int MIXCOM_exit(struct device *dev)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/comx-proto-fr.c linux.17p18/drivers/net/comx-proto-fr.c
--- linux.vanilla/drivers/net/comx-proto-fr.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/comx-proto-fr.c	Wed Aug 16 21:42:30 2000
@@ -6,6 +6,9 @@
  * Maintainer: Gergely Madarasz <gorgo@itc.hu>
  *
  * Copyright (C) 1998-1999 ITConsult-Pro Co. <info@itc.hu>
+ * 
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.73)
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
@@ -25,9 +28,12 @@
  * Version 0.72 (99/07/09):
  *		- handle slave tbusy with master tbusy (should be fixed)
  *		- fix the keepalive timer addition/deletion
+ * Version 0.73 (00/08/15)
+ * 		- resource release on failure at fr_master_init and
+ *		  fr_slave_init 		  
  */
 
-#define VERSION "0.72"
+#define VERSION "0.73"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -804,8 +810,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_DLCI, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-		return -ENOMEM;
+		goto cleanup_LINE_privdata;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &fr_read_proc;
 	new_file->write_proc = &fr_write_proc;
@@ -815,8 +822,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_KEEPALIVE, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-		return -ENOMEM;
+		goto cleanup_filename_dlci;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &fr_read_proc;
 	new_file->write_proc = &fr_write_proc;
@@ -828,6 +836,11 @@
 
 	MOD_INC_USE_COUNT;
 	return 0;
+cleanup_filename_dlci:
+	 remove_proc_entry(FILENAME_DLCI, ch->procdir);
+cleanup_LINE_privdata:
+	kfree(fr);
+	return -EIO;
 }
 
 static int fr_slave_init(struct device *dev)
@@ -860,7 +873,7 @@
 
 	if ((new_file = create_proc_entry(FILENAME_DLCI, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-		return -ENOMEM;
+		goto cleanup_LINE_privdata;
 	}
 	
 	new_file->data = (void *)new_file;
@@ -872,8 +885,9 @@
 
 	if ((new_file = create_proc_entry(FILENAME_MASTER, S_IFREG | 0644, 
 	    ch->procdir)) == NULL) {
-		return -EIO;
+		goto cleanup_filename_dlci;
 	}
+
 	new_file->data = (void *)new_file;
 	new_file->read_proc = &fr_read_proc;
 	new_file->write_proc = &fr_write_proc;
@@ -882,6 +896,11 @@
 	new_file->nlink = 1;
 	MOD_INC_USE_COUNT;
 	return 0;
+cleanup_filename_dlci:
+         remove_proc_entry(FILENAME_DLCI, ch->procdir);
+cleanup_LINE_privdata:
+	kfree(fr);
+	return -EIO;
 }
 
 static int dlci_open(struct device *dev)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/comx-proto-ppp.c linux.17p18/drivers/net/comx-proto-ppp.c
--- linux.vanilla/drivers/net/comx-proto-ppp.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/comx-proto-ppp.c	Wed Aug 16 21:42:30 2000
@@ -206,6 +206,9 @@
 
 	ch->LINE_privdata = kmalloc(sizeof(struct syncppp_data), GFP_KERNEL);
 
+	if (!ch->LINE_privdata)
+		return -ENOMEM;
+
 	pppdev->dev = dev;
 	sppp_attach(pppdev);
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/comx.c linux.17p18/drivers/net/comx.c
--- linux.vanilla/drivers/net/comx.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/comx.c	Wed Aug 16 21:42:30 2000
@@ -10,6 +10,9 @@
  *
  * Copyright (C) 1995-1999 ITConsult-Pro Co.
  *
+ * Contributors:
+ * Arnaldo Carvalho de Melo <acme@conectiva.com.br> (0.85)
+ *
  * 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
@@ -39,9 +42,12 @@
  * Version 0.84 (99/12/01):
  *		- comx_status should not check for IFF_UP (to report
  *		  line status from dev->open())
+ * Version 0.85 (00/08/15):
+ * 		- resource release on failure in comx_mkdir
+ * 		- fix return value on failure at comx_write_proc
  */
 
-#define VERSION "0.84"
+#define VERSION "0.85"
 
 #include <linux/config.h>
 #include <linux/module.h>
@@ -521,6 +527,7 @@
 	ch->loadavg_size = ch->loadavg[2] / ch->loadavg[0] + 1; 
 	if ((ch->avg_bytes = kmalloc(ch->loadavg_size * 
 		sizeof(unsigned long) * 2, GFP_KERNEL)) == NULL) {
+		kfree(ch);
 		return -ENOMEM;
 	}
 
@@ -649,7 +656,7 @@
 			ch->debug_start = ch->debug_end = 0;
 			restore_flags(flags);
 			free_page((unsigned long)page);
-			return count;
+			return ret ? ret : count;
 		}
 		
 		if (*page != '+' && *page != '-') {
@@ -852,12 +859,18 @@
 	struct proc_dir_entry *new_dir, *debug_file;
 	struct device *dev;
 	struct comx_channel *ch;
+	int ret = -EIO;
 
 	if (dir->i_ino != comx_root_dir.low_ino) return -ENOTDIR;
 
+	if ((dev = kmalloc(sizeof(struct device), GFP_KERNEL)) == NULL) {
+		return -ENOMEM;
+	}
+	memset(dev, 0, sizeof(struct device));
+
 	if ((new_dir = create_proc_entry(dentry->d_name.name, mode | S_IFDIR, 
 		&comx_root_dir)) == NULL) {
-		return -EIO;
+		goto cleanup_dev;
 	}
 
 	new_dir->ops = &proc_dir_inode_operations;  // ez egy normalis /proc konyvtar
@@ -867,22 +880,22 @@
 	/* Ezek kellenek */
 	if (!create_comx_proc_entry(FILENAME_HARDWARE, 0644, 
 	    strlen(HWNAME_NONE) + 1, new_dir)) {
-		return -ENOMEM;
+		goto cleanup_new_dir;
 	}
 	if (!create_comx_proc_entry(FILENAME_PROTOCOL, 0644, 
 	    strlen(PROTONAME_NONE) + 1, new_dir)) {
-		return -ENOMEM;
+		goto cleanup_filename_hardware;
 	}
 	if (!create_comx_proc_entry(FILENAME_STATUS, 0444, 0, new_dir)) {
-		return -ENOMEM;
+		goto cleanup_filename_protocol;
 	}
 	if (!create_comx_proc_entry(FILENAME_LINEUPDELAY, 0644, 2, new_dir)) {
-		return -ENOMEM;
+		goto cleanup_filename_status;
 	}
 
 	if ((debug_file = create_proc_entry(FILENAME_DEBUG, 
 	    S_IFREG | 0644, new_dir)) == NULL) {
-		return -ENOMEM;
+		goto cleanup_filename_lineupdelay;
 	}
 	debug_file->ops = &comx_debug_inode_ops;
 	debug_file->data = (void *)debug_file; 
@@ -890,20 +903,17 @@
 	debug_file->write_proc = &comx_write_proc;
 	debug_file->nlink = 1;
 
-	if ((dev = kmalloc(sizeof(struct device), GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
-	}
-	memset(dev, 0, sizeof(struct device));
 	dev->name = (char *)new_dir->name;
 	dev->init = comx_init_dev;
 
 	if (register_netdevice(dev)) {
-		return -EIO;
+		goto cleanup_filename_debug;
 	}
 	ch=dev->priv;
 	if((ch->if_ptr = (void *)kmalloc(sizeof(struct ppp_device),
 				 GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto cleanup_register;
 	}
 	memset(ch->if_ptr, 0, sizeof(struct ppp_device));
 	ch->debug_file = debug_file; 
@@ -913,13 +923,33 @@
 	ch->debug_start = ch->debug_end = 0;
 	if ((ch->debug_area = kmalloc(ch->debug_size = DEFAULT_DEBUG_SIZE, 
 	    GFP_KERNEL)) == NULL) {
-		return -ENOMEM;
+		ret = -ENOMEM;
+		goto cleanup_if_ptr;
 	}
 
 	ch->lineup_delay = DEFAULT_LINEUP_DELAY;
 
 	MOD_INC_USE_COUNT;
 	return 0;
+cleanup_if_ptr:
+	kfree(ch->if_ptr);
+cleanup_register:
+	unregister_netdevice(dev);
+cleanup_filename_debug:
+	remove_proc_entry(FILENAME_DEBUG, new_dir);
+cleanup_filename_lineupdelay:
+	remove_proc_entry(FILENAME_LINEUPDELAY, new_dir);
+cleanup_filename_status:
+	remove_proc_entry(FILENAME_STATUS, new_dir);
+cleanup_filename_protocol:
+	remove_proc_entry(FILENAME_PROTOCOL, new_dir);
+cleanup_filename_hardware:
+	remove_proc_entry(FILENAME_HARDWARE, new_dir);
+cleanup_new_dir:
+	remove_proc_entry(dentry->d_name.name, &comx_root_dir);
+cleanup_dev:
+	kfree(dev);
+	return ret;
 }
 
 static int comx_rmdir(struct inode *dir, struct dentry *dentry)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/de4x5.c linux.17p18/drivers/net/de4x5.c
--- linux.vanilla/drivers/net/de4x5.c	Fri Apr 21 12:46:16 2000
+++ linux.17p18/drivers/net/de4x5.c	Tue Aug  1 07:59:45 2000
@@ -379,8 +379,7 @@
                           Fix bug in pci_probe() for 64 bit systems reported
 			   by <belliott@accessone.com>.
       0.533   9-Jan-98    Fix more 64 bit bugs reported by <jal@cs.brown.edu>.
-      0.534  24-Jan-98    Fix last (?) endian bug from 
-                           <Geert.Uytterhoeven@cs.kuleuven.ac.be>
+      0.534  24-Jan-98    Fix last (?) endian bug from <geert@linux-m68k.org>
       0.535  21-Feb-98    Fix Ethernet Address PROM reset bug for DC21040.
       0.536  21-Mar-98    Change pci_probe() to use the pci_dev structure.
 			  **Incompatible with 2.0.x from here.**
@@ -653,12 +652,20 @@
 #define ALIGN64     ((u_long)64 - 1)    /* 16 longword align */
 #define ALIGN128    ((u_long)128 - 1)   /* 32 longword align */
 
+#ifndef __powerpc__
 #define ALIGN         ALIGN32           /* Keep the DC21040 happy... */
 #define CACHE_ALIGN   CAL_16LONG
 #define DESC_SKIP_LEN DSL_0             /* Must agree with DESC_ALIGN */
 /*#define DESC_ALIGN    u32 dummy[4];  / * Must agree with DESC_SKIP_LEN */
 #define DESC_ALIGN
 
+#else /* __powerpc__ */
+#define ALIGN         ALIGN32           /* Keep the DC21040 happy... */
+#define CACHE_ALIGN   CAL_8LONG
+#define DESC_SKIP_LEN DSL_4             /* Must agree with DESC_ALIGN */
+#define DESC_ALIGN    u32 dummy[4];  	/* Must agree with DESC_SKIP_LEN */
+#endif /* __powerpc__ */
+
 #ifndef DEC_ONLY                        /* See README.de4x5 for using this */
 static int dec_only = 0;
 #else
@@ -763,6 +770,9 @@
 struct de4x5_private {
     char adapter_name[80];                  /* Adapter name                 */
     u_long interrupt;                       /* Aligned ISR flag             */
+#ifdef __powerpc__
+    u_long dummy[3];			    /* Keep rx_ring 32-byte aligned */
+#endif
     struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring           */
     struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring           */
     struct sk_buff *tx_skb[NUM_TX_DESC];    /* TX skb for freeing when sent */
@@ -3231,6 +3241,7 @@
 
       case ANS:
 	lp->media = ANS;
+	lp->fdx = lp->params.fdx;
 	break;
 
       default: 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/dmfe.c linux.17p18/drivers/net/dmfe.c
--- linux.vanilla/drivers/net/dmfe.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/dmfe.c	Tue Aug  1 07:59:45 2000
@@ -102,7 +102,7 @@
 #define DMFE_AUTO       8
 
 #define DMFE_TIMER_WUT  jiffies+(HZ*2)/2	/* timer wakeup time : 1 second */
-#define DMFE_TX_TIMEOUT HZ*1.5	/* tx packet time-out time 1.5 s" */
+#define DMFE_TX_TIMEOUT ((HZ*3)/2)	/* tx packet time-out time 1.5 s" */
 
 #define DMFE_DBUG(dbug_now, msg, vaule) if (dmfe_debug || dbug_now) printk("DBUG: %s %x\n", msg, vaule)
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/eepro.c linux.17p18/drivers/net/eepro.c
--- linux.vanilla/drivers/net/eepro.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/eepro.c	Tue Aug  1 07:59:45 2000
@@ -23,6 +23,10 @@
 	This is a compatibility hardware problem.
 
 	Versions:
+	0.12b	added reset when the tx interrupt is called and TX isn't done
+		and other minor fixes. this may fix a problem found after
+		initialization that delays tx until a transmit timeout is 
+		reported and the board is reset.
 	0.12a	fixed bug that would make impossible have ee10 boards and
 		other previous supported boards. (aris, 05/19/2000)
 	0.12    added support to 82595FX etherexpress 10 based cards
@@ -97,7 +101,7 @@
 */
 
 static const char *version =
-	"eepro.c: v0.12a 04/26/2000 aris@conectiva.com.br\n";
+	"eepro.c: v0.12b 06/20/2000 aris@conectiva.com.br\n";
 
 #include <linux/module.h>
 
@@ -470,7 +474,7 @@
 #define EEDO 0x08
 
 /* do a full reset */
-#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr)
+#define eepro_reset(ioaddr) outb(RESET_CMD, ioaddr); udelay(40);
 
 /* do a nice reset */
 #define eepro_sel_reset(ioaddr) 	{ \
@@ -523,6 +527,20 @@
 /* ack for tx int */
 #define eepro_ack_tx(ioaddr) outb (TX_INT, ioaddr + STATUS_REG)
 
+/* a complete sel reset */
+#define eepro_complete_selreset(ioaddr) { 	eepro_dis_int(ioaddr);\
+						lp->stats.tx_errors++;\
+						eepro_sel_reset(ioaddr);\
+						lp->tx_end = \
+							(XMT_LOWER_LIMIT << 8);\
+						lp->tx_start = lp->tx_end;\
+						lp->tx_last = 0;\
+						dev->tbusy=0;\
+						dev->trans_start = jiffies;\
+						eepro_en_int(ioaddr);\
+						eepro_en_rx(ioaddr);\
+					}
+
 /* Check for a network adaptor of this type, and return '0' if one exists.
    If dev->base_addr == 0, probe all likely locations.
    If dev->base_addr == 1, always return failure.
@@ -1064,10 +1082,6 @@
 		if (tickssofar < 40)
 			return 1;
 		
-		/* let's disable interrupts so we can avoid confusion on SMP
-		 */
-		eepro_dis_int(ioaddr);
-		
 		/* if (net_debug > 1) */
 		printk(KERN_ERR "%s: transmit timed out, %s?\n", dev->name, 
 			"network cable problem");
@@ -1075,25 +1089,9 @@
 		   one for the the log file  */
 		printk(KERN_DEBUG "%s: transmit timed out, %s?\n", dev->name,
 			"network cable problem");
-		lp->stats.tx_errors++;
-
-		/* Try to restart the adaptor. */
-		/* We are supposed to wait for 2 us after a SEL_RESET */
-		eepro_sel_reset(ioaddr);
-
-		/* Do I also need to flush the transmit buffers here? YES? */
-		lp->tx_start = lp->tx_end = (XMT_LOWER_LIMIT << 8); 
-		lp->tx_last = 0;
-	
-		dev->tbusy=0;
-		dev->trans_start = jiffies;
-
-
-		/* re-enabling all interrupts */
-		eepro_en_int(ioaddr);
-
-		/* enable rx */
-		eepro_en_rx(ioaddr);
+		
+		/* let's do a complete sel reset */
+		eepro_complete_selreset(ioaddr);
 	}
 	spin_lock_irqsave(&lp->lock, flags);
 
@@ -1379,8 +1377,7 @@
 		eepro_en_int(ioaddr);
 	
 	}
-	/* enabling rx */
-	eepro_en_rx(ioaddr);
+	eepro_complete_selreset(ioaddr);
 }
 
 /* The horrible routine to read a word from the serial EEPROM. */
@@ -1492,7 +1489,8 @@
 				last = (XMT_LOWER_LIMIT << 8);
 				end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 			}
-			else end = (XMT_LOWER_LIMIT << 8) + (end - XMT_RAM);
+			else end = (XMT_LOWER_LIMIT << 8) + (end - 
+						(XMT_UPPER_LIMIT << 8));
 		}
 
 		outw(last, ioaddr + HOST_ADDRESS_REG);
@@ -1554,7 +1552,6 @@
 		return;
 	}
 
-	eepro_en_int(ioaddr);
 	dev->tbusy = 1;
 
 	if (net_debug > 5)
@@ -1574,9 +1571,6 @@
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: entering eepro_rx routine.\n", dev->name);
 
-	/* clear all interrupts */
-	eepro_clear_int(ioaddr);
-	
 	/* Set the read pointer to the start of the RCV */
 	outw(rcv_car, ioaddr + HOST_ADDRESS_REG);
 	
@@ -1655,9 +1649,6 @@
 
 	if (net_debug > 5)
 		printk(KERN_DEBUG "%s: exiting eepro_rx routine.\n", dev->name);
-
-	/* enable tx/rx interrupts */
-	eepro_en_int(ioaddr);
 }
 
 static void
@@ -1754,6 +1745,12 @@
 		}
 		boguscount--;
 	}
+	/* if it reached here then it's probable that the adapter won't
+	 * interrupt again for tx. in other words: tx timeout what will take
+	 * a lot of time to happen, so we'll do a complete selreset.
+	 */
+	if (!boguscount)
+		eepro_complete_selreset(ioaddr);
 }
 
 #ifdef MODULE
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/eepro100.c linux.17p18/drivers/net/eepro100.c
--- linux.vanilla/drivers/net/eepro100.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/eepro100.c	Fri Aug  4 15:42:54 2000
@@ -1,3 +1,5 @@
+#define USE_IO
+
 /* drivers/net/eepro100.c: An Intel i82557-559 Ethernet driver for Linux. */
 /*
    NOTICE: this version of the driver is supposed to work with 2.2 kernels.
@@ -53,7 +55,7 @@
 
 /* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
    Lower values use more memory, but are faster. */
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__sparc__)
 /* force copying of all packets to avoid unaligned accesses on Alpha */
 static int rx_copybreak = 1518;
 #else
@@ -611,10 +613,17 @@
 				ioaddr = pciaddr & ~3UL;
 				if (check_region(ioaddr, 32))
 					continue;
-			} else if ((ioaddr = (long)ioremap(pciaddr & ~0xfUL, 0x1000)) == 0) {
-				printk(KERN_INFO "Failed to map PCI address %#lx.\n",
-					   pciaddr);
-				continue;
+			} else {
+#ifdef __sparc__
+				/* ioremap is hosed in 2.2.x on Sparc. */
+				ioaddr = pciaddr & ~0xfUL;
+#else
+				if ((ioaddr = (long)ioremap(pciaddr & ~0xfUL, 0x1000)) == 0) {
+					printk(KERN_INFO "Failed to map PCI address %#lx.\n",
+						   pciaddr);
+					continue;
+				}
+#endif
 			}
 			if (speedo_debug > 2)
 				printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n",
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/ewrk3.c linux.17p18/drivers/net/ewrk3.c
--- linux.vanilla/drivers/net/ewrk3.c	Fri Apr 21 12:46:17 2000
+++ linux.17p18/drivers/net/ewrk3.c	Tue Aug  1 07:59:45 2000
@@ -846,9 +846,9 @@
 						}
 					}
 
+					lp->stats.tx_bytes += skb->len;
 					dev->trans_start = jiffies;
 					dev_kfree_skb(skb);
-
 				} else {	/* return unused page to the free memory queue */
 					outb(page, EWRK3_FMQ);
 				}
@@ -1029,6 +1029,7 @@
 						   ** Update stats
 						 */
 						lp->stats.rx_packets++;
+						lp->stats.rx_bytes += pkt_len;
 						for (i = 1; i < EWRK3_PKT_STAT_SZ - 1; i++) {
 							if (pkt_len < i * EWRK3_PKT_BIN_SZ) {
 								lp->pktStats.bins[i]++;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/gmac.c linux.17p18/drivers/net/gmac.c
--- linux.vanilla/drivers/net/gmac.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/net/gmac.c	Tue Aug  1 07:59:45 2000
@@ -0,0 +1,1166 @@
+/*
+ * Network device driver for the GMAC ethernet controller on
+ * Apple G4 Powermacs.
+ *
+ * Copyright (C) 2000 Paul Mackerras & Ben. Herrenschmidt
+ * 
+ * portions based on sunhme.c by David S. Miller
+ *
+ */
+
+#include <linux/module.h>
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/pci.h>
+#include <asm/prom.h>
+#include <asm/io.h>
+#include <asm/pgtable.h>
+#include <asm/bitops.h>
+
+#include "gmac.h"
+
+#define DEBUG_PHY
+
+/* Driver version 1.1, kernel 2.2.x */
+#define GMAC_VERSION	"v1.1k2"
+
+static unsigned char dummy_buf[RX_BUF_ALLOC_SIZE + RX_OFFSET + GMAC_BUFFER_ALIGN];
+static struct device *gmacs = NULL;
+
+/* Prototypes */
+static int mii_read(struct gmac *gm, int phy, int r);
+static int mii_write(struct gmac *gm, int phy, int r, int v);
+static void mii_poll_start(struct gmac *gm);
+static void mii_poll_stop(struct gmac *gm);
+static void mii_interrupt(struct gmac *gm);
+static int mii_lookup_and_reset(struct gmac *gm);
+static void mii_setup_phy(struct gmac *gm);
+
+static void gmac_set_power(struct gmac *gm, int power_up);
+static int gmac_powerup_and_reset(struct device *dev);
+static void gmac_set_duplex_mode(struct gmac *gm, int full_duplex);
+static void gmac_mac_init(struct gmac *gm, unsigned char *mac_addr);
+static void gmac_init_rings(struct gmac *gm, int from_irq);
+static void gmac_start_dma(struct gmac *gm);
+static void gmac_stop_dma(struct gmac *gm);
+static void gmac_set_multicast(struct device *dev);
+static int gmac_open(struct device *dev);
+static int gmac_close(struct device *dev);
+static void gmac_tx_timeout(struct device *dev);
+static int gmac_xmit_start(struct sk_buff *skb, struct device *dev);
+static void gmac_tx_cleanup(struct device *dev, int force_cleanup);
+static void gmac_receive(struct device *dev);
+static void gmac_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static struct net_device_stats *gmac_stats(struct device *dev);
+int gmac_probe(struct device *dev);
+
+extern int pci_device_loc(struct device_node *dev, unsigned char *bus_ptr,
+		   unsigned char *devfn_ptr);
+
+/* Stuff for talking to the physical-layer chip */
+static int
+mii_read(struct gmac *gm, int phy, int r)
+{
+	int timeout;
+
+	GM_OUT(GM_MIF_FRAME_CTL_DATA,
+		(0x01 << GM_MIF_FRAME_START_SHIFT) |
+		(0x02 << GM_MIF_FRAME_OPCODE_SHIFT) |
+		GM_MIF_FRAME_TURNAROUND_HI |
+		(phy << GM_MIF_FRAME_PHY_ADDR_SHIFT) |
+		(r << GM_MIF_FRAME_REG_ADDR_SHIFT));
+		
+	for (timeout = 1000; timeout > 0; --timeout) {
+		udelay(20);
+		if (GM_IN(GM_MIF_FRAME_CTL_DATA) & GM_MIF_FRAME_TURNAROUND_LO)
+			return GM_IN(GM_MIF_FRAME_CTL_DATA) & GM_MIF_FRAME_DATA_MASK;
+	}
+	return -1;
+}
+
+static int
+mii_write(struct gmac *gm, int phy, int r, int v)
+{
+	int timeout;
+
+	GM_OUT(GM_MIF_FRAME_CTL_DATA,
+		(0x01 << GM_MIF_FRAME_START_SHIFT) |
+		(0x01 << GM_MIF_FRAME_OPCODE_SHIFT) |
+		GM_MIF_FRAME_TURNAROUND_HI |
+		(phy << GM_MIF_FRAME_PHY_ADDR_SHIFT) |
+		(r << GM_MIF_FRAME_REG_ADDR_SHIFT) |
+		(v & GM_MIF_FRAME_DATA_MASK));
+
+	for (timeout = 1000; timeout > 0; --timeout) {
+		udelay(20);
+		if (GM_IN(GM_MIF_FRAME_CTL_DATA) & GM_MIF_FRAME_TURNAROUND_LO)
+			return 0;
+	}
+	return -1;
+}
+
+static void 
+mii_poll_start(struct gmac *gm)
+{
+	unsigned int tmp;
+	
+	/* Start the MIF polling on the external transceiver. */
+	tmp = GM_IN(GM_MIF_CFG);
+	tmp &= ~(GM_MIF_CFGPR_MASK | GM_MIF_CFGPD_MASK);
+	tmp |= ((gm->phy_addr & 0x1f) << GM_MIF_CFGPD_SHIFT);
+	tmp |= (MII_SR << GM_MIF_CFGPR_SHIFT);
+	tmp |= GM_MIF_CFGPE;
+	GM_OUT(GM_MIF_CFG, tmp);
+
+	/* Let the bits set. */
+	udelay(GM_MIF_POLL_DELAY);
+
+	GM_OUT(GM_MIF_IRQ_MASK, 0xffc0);
+}
+
+static void 
+mii_poll_stop(struct gmac *gm)
+{
+	GM_OUT(GM_MIF_IRQ_MASK, 0xffff);
+	GM_BIC(GM_MIF_CFG, GM_MIF_CFGPE);
+	udelay(GM_MIF_POLL_DELAY);
+}
+
+static void
+mii_interrupt(struct gmac *gm)
+{
+	int		phy_status;
+	int		lpar_ability;
+	
+	mii_poll_stop(gm);
+
+	/* May the status change before polling is re-enabled ? */
+	mii_poll_start(gm);
+	
+	/* We read the Auxilliary Status Summary register */
+	phy_status = mii_read(gm, gm->phy_addr, MII_SR);
+	if ((phy_status ^ gm->phy_status) & (MII_SR_ASSC | MII_SR_LKS)) {
+		int		full_duplex;
+		int		link_100;
+#ifdef DEBUG_PHY
+		printk("Link state change, phy_status: 0x%04x\n", phy_status);
+#endif
+		gm->phy_status = phy_status;
+
+		lpar_ability = mii_read(gm, gm->phy_addr, MII_ANLPA);
+		if (lpar_ability & MII_ANLPA_PAUS)
+			GM_BIS(GM_MAC_CTRL_CONFIG, GM_MAC_CTRL_CONF_SND_PAUSE_EN);
+		else
+			GM_BIC(GM_MAC_CTRL_CONFIG, GM_MAC_CTRL_CONF_SND_PAUSE_EN);
+
+		/* Link ? For now we handle only the 5201 PHY */
+		if ((phy_status & MII_SR_LKS) && (phy_status & MII_SR_ASSC)) {
+		    if (gm->phy_type == PHY_B5201) {
+		    	int aux_stat = mii_read(gm, gm->phy_addr, MII_BCM5201_AUXCTLSTATUS);
+#ifdef DEBUG_PHY
+			printk("    Link up ! BCM5201 aux_stat: 0x%04x\n", aux_stat);
+#endif
+		    	full_duplex = ((aux_stat & MII_BCM5201_AUXCTLSTATUS_DUPLEX) != 0);
+		    	link_100 = ((aux_stat & MII_BCM5201_AUXCTLSTATUS_SPEED) != 0);
+		    } else {
+		    	full_duplex = 1;
+		    	link_100 = 1;
+		    }
+#ifdef DEBUG_PHY
+		    printk("    full_duplex: %d, speed: %s\n", full_duplex,
+		    	link_100 ? "100" : "10");
+#endif
+		    if (full_duplex != gm->full_duplex) {
+			gm->full_duplex = full_duplex;
+			gmac_set_duplex_mode(gm, gm->full_duplex);
+			gmac_start_dma(gm);
+		    }
+		} else if (!(phy_status & MII_SR_LKS)) {
+#ifdef DEBUG_PHY
+		    printk("    Link down !\n");
+#endif
+		}
+	}
+}
+
+static int
+mii_lookup_and_reset(struct gmac *gm)
+{
+	int	i, timeout;
+	int	mii_status, mii_control;
+
+	/* Find the PHY */
+	gm->phy_addr = -1;
+	gm->phy_type = PHY_UNKNOWN;
+	
+	for(i=31; i>0; --i) {
+		mii_control = mii_read(gm, i, MII_CR);
+		mii_status = mii_read(gm, i, MII_SR);
+		if (mii_control != -1  && mii_status != -1 &&
+			(mii_control != 0xffff || mii_status != 0xffff))
+			break;
+	}
+	gm->phy_addr = i;
+	if (gm->phy_addr < 0)
+		return 0;
+
+	/* Reset it */
+	mii_write(gm, gm->phy_addr, MII_CR, mii_control | MII_CR_RST);
+	mdelay(10);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mii_control = mii_read(gm, gm->phy_addr, MII_CR);
+		if (mii_control == -1) {
+			printk(KERN_ERR "%s PHY died after reset !\n",
+				gm->dev->name);
+			goto fail;
+		}
+		if ((mii_control & MII_CR_RST) == 0)
+			break;
+		mdelay(10);
+	}
+	if (mii_control & MII_CR_RST) {
+		printk(KERN_ERR "%s PHY reset timeout !\n", gm->dev->name);
+		goto fail;
+	}
+	mii_write(gm, gm->phy_addr, MII_CR, mii_control & ~MII_CR_ISOL);
+
+	/* Read the PHY ID */
+	gm->phy_id = (mii_read(gm, gm->phy_addr, MII_ID0) << 16) |
+		mii_read(gm, gm->phy_addr, MII_ID1);
+#ifdef DEBUG_PHY
+	printk("%s PHY ID: 0x%08x\n", gm->dev->name, gm->phy_id);
+#endif
+	if ((gm->phy_id & MII_BCM5400_MASK) == MII_BCM5400_ID) {
+		gm->phy_type = PHY_B5400;
+		printk(KERN_ERR "%s Warning ! Unsupported BCM5400 PHY !\n",
+			gm->dev->name);
+	} else if ((gm->phy_id & MII_BCM5201_MASK) == MII_BCM5201_ID) {
+		gm->phy_type = PHY_B5201;
+	} else {
+		printk(KERN_ERR "%s: Warning ! Unknown PHY ID 0x%08x !\n",
+			gm->dev->name, gm->phy_id);
+	}
+
+	return 1;
+	
+fail:
+	gm->phy_addr = -1;
+	return 0;
+}
+
+/* Code to setup the PHY duplex mode and speed should be
+ * added here
+ */
+static void
+mii_setup_phy(struct gmac *gm)
+{
+	int data;
+	
+	/* Stop auto-negociation */
+	data = mii_read(gm, gm->phy_addr, MII_CR);
+	mii_write(gm, gm->phy_addr, MII_CR, data & ~MII_CR_ASSE);
+
+	/* Set advertisement to 10/100 and Half/Full duplex
+	 * (full capabilities) */
+	data = mii_read(gm, gm->phy_addr, MII_ANA);
+	data |= MII_ANA_TXAM | MII_ANA_FDAM | MII_ANA_10M;
+	mii_write(gm, gm->phy_addr, MII_ANA, data);
+	
+	/* Restart auto-negociation */
+	data = mii_read(gm, gm->phy_addr, MII_CR);
+	data |= MII_CR_ASSE;
+	mii_write(gm, gm->phy_addr, MII_CR, data);
+	data |= MII_CR_RAN;
+	mii_write(gm, gm->phy_addr, MII_CR, data);
+}
+
+static void
+gmac_set_power(struct gmac *gm, int power_up)
+{
+	if (power_up) {
+		out_le32(gm->sysregs + 0x20/4,
+			in_le32(gm->sysregs + 0x20/4) | 0x02000000);
+		udelay(20);
+		if (gm->pci_devfn != 0xff) {
+			u16 cmd;
+			
+			/* Make sure PCI is correctly configured */
+			pcibios_read_config_word(gm->pci_bus, gm->pci_devfn,
+				PCI_COMMAND, &cmd);
+			cmd |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
+	    		pcibios_write_config_word(gm->pci_bus, gm->pci_devfn,
+	    			PCI_COMMAND, cmd);
+	    		pcibios_write_config_byte(gm->pci_bus, gm->pci_devfn,
+	    			PCI_LATENCY_TIMER, 16);
+	    		pcibios_write_config_byte(gm->pci_bus, gm->pci_devfn,
+	    			PCI_CACHE_LINE_SIZE, 8);
+		}
+	} else {
+		/* FIXME: Add PHY power down */
+		gm->phy_type = 0;
+		out_le32(gm->sysregs + 0x20/4,
+			in_le32(gm->sysregs + 0x20/4) & ~0x02000000);
+		udelay(20);
+	}
+}
+
+static int
+gmac_powerup_and_reset(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	int timeout;
+	
+	/* turn on GB clock */
+	gmac_set_power(gm, 1);
+	/* Perform a software reset */
+	GM_OUT(GM_RESET, GM_RESET_TX | GM_RESET_RX);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mdelay(10);
+		if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) {
+			/* Mask out all chips interrupts */
+			GM_OUT(GM_IRQ_MASK, 0xffffffff);
+			return 0;
+		}
+	}
+	printk(KERN_ERR "%s reset failed!\n", dev->name);
+	gmac_set_power(gm, 0);
+	return -1;
+}
+
+/* Set the MAC duplex mode. Side effect: stops Tx MAC */
+static void
+gmac_set_duplex_mode(struct gmac *gm, int full_duplex)
+{
+	/* Stop Tx MAC */
+	GM_BIC(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_ENABLE);
+	while(GM_IN(GM_MAC_TX_CONFIG) & GM_MAC_TX_CONF_ENABLE)
+		;
+	
+	if (full_duplex) {
+		GM_BIS(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_IGNORE_CARRIER
+			| GM_MAC_TX_CONF_IGNORE_COLL);
+		GM_BIC(GM_MAC_XIF_CONFIG, GM_MAC_XIF_CONF_DISABLE_ECHO);
+	} else {
+		GM_BIC(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_IGNORE_CARRIER
+			| GM_MAC_TX_CONF_IGNORE_COLL);
+		GM_BIS(GM_MAC_XIF_CONFIG, GM_MAC_XIF_CONF_DISABLE_ECHO);
+	}
+}
+
+static void
+gmac_mac_init(struct gmac *gm, unsigned char *mac_addr)
+{
+	int i, fifo_size;
+
+	/* Set random seed to low bits of MAC address */
+	GM_OUT(GM_MAC_RANDOM_SEED, mac_addr[5] | (mac_addr[4] << 8));
+	
+	/* Configure the data path mode to MII/GII */
+	GM_OUT(GM_PCS_DATAPATH_MODE, GM_PCS_DATAPATH_MII);
+	
+	/* Configure XIF to MII mode. Full duplex led is set
+	 * by Apple, so...
+	 */
+	GM_OUT(GM_MAC_XIF_CONFIG, GM_MAC_XIF_CONF_TX_MII_OUT_EN
+		| GM_MAC_XIF_CONF_FULL_DPLX_LED);
+
+	/* Mask out all MAC interrupts */
+	GM_OUT(GM_MAC_TX_MASK, 0xffff);
+	GM_OUT(GM_MAC_RX_MASK, 0xffff);
+	GM_OUT(GM_MAC_CTRLSTAT_MASK, 0xff);
+	
+	/* Setup bits of MAC */
+	GM_OUT(GM_MAC_SND_PAUSE, GM_MAC_SND_PAUSE_DEFAULT);
+	GM_OUT(GM_MAC_CTRL_CONFIG, GM_MAC_CTRL_CONF_RCV_PAUSE_EN);
+	
+	/* Configure GEM DMA */
+	GM_OUT(GM_GCONF, GM_GCONF_BURST_SZ |
+		(31 << GM_GCONF_TXDMA_LIMIT_SHIFT) |
+		(31 << GM_GCONF_RXDMA_LIMIT_SHIFT));
+	GM_OUT(GM_TX_CONF,
+		GM_TX_CONF_FIFO_THR_DEFAULT << GM_TX_CONF_FIFO_THR_SHIFT |
+		NTX_CONF);
+/* 34 byte offset for checksum computation.  This works because ip_input() will clear out
+ * the skb->csum and skb->ip_summed fields and recompute the csum if IP options are
+ * present in the header.  34 == (ethernet header len) + sizeof(struct iphdr)
+ */
+	GM_OUT(GM_RX_CONF,
+		(RX_OFFSET << GM_RX_CONF_FBYTE_OFF_SHIFT) |
+		(0x22 << GM_RX_CONF_CHK_START_SHIFT) |
+		(GM_RX_CONF_DMA_THR_DEFAULT << GM_RX_CONF_DMA_THR_SHIFT) |
+		NRX_CONF);
+
+	/* Configure other bits of MAC */
+	GM_OUT(GM_MAC_INTR_PKT_GAP0, GM_MAC_INTR_PKT_GAP0_DEFAULT);
+	GM_OUT(GM_MAC_INTR_PKT_GAP1, GM_MAC_INTR_PKT_GAP1_DEFAULT);
+	GM_OUT(GM_MAC_INTR_PKT_GAP2, GM_MAC_INTR_PKT_GAP2_DEFAULT);
+	GM_OUT(GM_MAC_MIN_FRAME_SIZE, GM_MAC_MIN_FRAME_SIZE_DEFAULT);
+	GM_OUT(GM_MAC_MAX_FRAME_SIZE, GM_MAC_MAX_FRAME_SIZE_DEFAULT);
+	GM_OUT(GM_MAC_PREAMBLE_LEN, GM_MAC_PREAMBLE_LEN_DEFAULT);
+	GM_OUT(GM_MAC_JAM_SIZE, GM_MAC_JAM_SIZE_DEFAULT);
+	GM_OUT(GM_MAC_ATTEMPT_LIMIT, GM_MAC_ATTEMPT_LIMIT_DEFAULT);
+	GM_OUT(GM_MAC_SLOT_TIME, GM_MAC_SLOT_TIME_DEFAULT);
+	GM_OUT(GM_MAC_CONTROL_TYPE, GM_MAC_CONTROL_TYPE_DEFAULT);
+	
+	/* Setup MAC addresses, clear filters, clear hash table */
+	GM_OUT(GM_MAC_ADDR_NORMAL0, (mac_addr[4] << 8) + mac_addr[5]);
+	GM_OUT(GM_MAC_ADDR_NORMAL1, (mac_addr[2] << 8) + mac_addr[3]);
+	GM_OUT(GM_MAC_ADDR_NORMAL2, (mac_addr[0] << 8) + mac_addr[1]);
+	GM_OUT(GM_MAC_ADDR_ALT0, 0);
+	GM_OUT(GM_MAC_ADDR_ALT1, 0);
+	GM_OUT(GM_MAC_ADDR_ALT2, 0);
+	GM_OUT(GM_MAC_ADDR_CTRL0, 0x0001);
+	GM_OUT(GM_MAC_ADDR_CTRL1, 0xc200);
+	GM_OUT(GM_MAC_ADDR_CTRL2, 0x0180);
+	GM_OUT(GM_MAC_ADDR_FILTER0, 0);
+	GM_OUT(GM_MAC_ADDR_FILTER1, 0);
+	GM_OUT(GM_MAC_ADDR_FILTER2, 0);
+	GM_OUT(GM_MAC_ADDR_FILTER_MASK1_2, 0);
+	GM_OUT(GM_MAC_ADDR_FILTER_MASK0, 0);
+	for (i = 0; i < 27; ++i)
+		GM_OUT(GM_MAC_ADDR_FILTER_HASH0 + i, 0);
+	
+	/* Clear stat counters */
+	GM_OUT(GM_MAC_COLLISION_CTR, 0);
+	GM_OUT(GM_MAC_FIRST_COLLISION_CTR, 0);
+	GM_OUT(GM_MAC_EXCS_COLLISION_CTR, 0);
+	GM_OUT(GM_MAC_LATE_COLLISION_CTR, 0);
+	GM_OUT(GM_MAC_DEFER_TIMER_COUNTER, 0);
+	GM_OUT(GM_MAC_PEAK_ATTEMPTS, 0);
+	GM_OUT(GM_MAC_RX_FRAME_CTR, 0);
+	GM_OUT(GM_MAC_RX_LEN_ERR_CTR, 0);
+	GM_OUT(GM_MAC_RX_ALIGN_ERR_CTR, 0);
+	GM_OUT(GM_MAC_RX_CRC_ERR_CTR, 0);
+	GM_OUT(GM_MAC_RX_CODE_VIOLATION_CTR, 0);
+	
+	/* default to half duplex */
+	GM_OUT(GM_MAC_TX_CONFIG, 0);
+	GM_OUT(GM_MAC_RX_CONFIG, 0);
+	gmac_set_duplex_mode(gm, gm->full_duplex);
+	
+	/* Setup pause thresholds */
+	fifo_size = GM_IN(GM_RX_FIFO_SIZE);
+	GM_OUT(GM_RX_PTH,
+		((fifo_size - ((GM_MAC_MAX_FRAME_SIZE_ALIGN + 8) * 2 / GM_RX_PTH_UNITS))
+			<< GM_RX_PTH_OFF_SHIFT) |
+		((fifo_size - ((GM_MAC_MAX_FRAME_SIZE_ALIGN + 8) * 3 / GM_RX_PTH_UNITS))
+			<< GM_RX_PTH_ON_SHIFT));
+		
+	/* Setup interrupt blanking */
+	if (GM_IN(GM_BIF_CFG) & GM_BIF_CFG_M66EN)
+		GM_OUT(GM_RX_BLANK, (5 << GM_RX_BLANK_INTR_PACKETS_SHIFT)
+			| (8 << GM_RX_BLANK_INTR_TIME_SHIFT));
+	else
+		GM_OUT(GM_RX_BLANK, (5 << GM_RX_BLANK_INTR_PACKETS_SHIFT)
+			| (4 << GM_RX_BLANK_INTR_TIME_SHIFT));	
+}
+
+static void
+gmac_init_rings(struct gmac *gm, int from_irq)
+{
+	int i;
+	struct sk_buff *skb;
+	unsigned char *data;
+	struct gmac_dma_desc *ring;
+	int gfp_flags = GFP_KERNEL;
+
+	if (from_irq || in_interrupt())
+		gfp_flags = GFP_ATOMIC;
+
+	/* init rx ring */
+	ring = (struct gmac_dma_desc *) gm->rxring;
+	memset(ring, 0, NRX * sizeof(struct gmac_dma_desc));
+	for (i = 0; i < NRX; ++i, ++ring) {
+		data = dummy_buf;
+		gm->rx_buff[i] = skb = gmac_alloc_skb(RX_BUF_ALLOC_SIZE, gfp_flags);
+		if (skb != 0) {
+			skb->dev = gm->dev;
+			skb_put(skb, ETH_FRAME_LEN + RX_OFFSET);
+			skb_reserve(skb, RX_OFFSET);
+			data = skb->data - RX_OFFSET;
+		}
+		st_le32(&ring->lo_addr, virt_to_bus(data));
+		st_le32(&ring->size, RX_SZ_OWN | ((RX_BUF_ALLOC_SIZE-RX_OFFSET) << RX_SZ_SHIFT));
+	}
+
+	/* init tx ring */
+	ring = (struct gmac_dma_desc *) gm->txring;
+	memset(ring, 0, NTX * sizeof(struct gmac_dma_desc));
+
+	gm->next_rx = 0;
+	gm->next_tx = 0;
+	gm->tx_gone = 0;
+
+	/* set pointers in chip */
+	mb();
+	GM_OUT(GM_RX_DESC_HI, 0);
+	GM_OUT(GM_RX_DESC_LO, virt_to_bus(gm->rxring));
+	GM_OUT(GM_TX_DESC_HI, 0);
+	GM_OUT(GM_TX_DESC_LO, virt_to_bus(gm->txring));
+}
+
+static void
+gmac_start_dma(struct gmac *gm)
+{
+	/* Enable Tx and Rx */
+	GM_BIS(GM_TX_CONF, GM_TX_CONF_DMA_EN);
+	mdelay(20);
+	GM_BIS(GM_RX_CONF, GM_RX_CONF_DMA_EN);
+	mdelay(20);
+	GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_ENABLE);
+	mdelay(20);
+	GM_BIS(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_ENABLE);
+	mdelay(20);
+	/* Kick the receiver and enable interrupts */
+	GM_OUT(GM_RX_KICK, NRX);
+	GM_BIC(GM_IRQ_MASK, 	GM_IRQ_TX_INT_ME |
+				GM_IRQ_TX_ALL |
+				GM_IRQ_RX_DONE |
+				GM_IRQ_RX_TAG_ERR |
+				GM_IRQ_MAC_RX |
+				GM_IRQ_MIF |
+				GM_IRQ_BUS_ERROR);
+}
+
+static void
+gmac_stop_dma(struct gmac *gm)
+{
+	/* disable interrupts */
+	GM_OUT(GM_IRQ_MASK, 0xffffffff);
+	/* Enable Tx and Rx */
+	GM_BIC(GM_TX_CONF, GM_TX_CONF_DMA_EN);
+	mdelay(20);
+	GM_BIC(GM_RX_CONF, GM_RX_CONF_DMA_EN);
+	mdelay(20);
+	GM_BIC(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_ENABLE);
+	mdelay(20);
+	GM_BIC(GM_MAC_TX_CONFIG, GM_MAC_TX_CONF_ENABLE);
+	mdelay(20);
+}
+
+#define CRC_POLY	0xedb88320
+static void
+gmac_set_multicast(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	struct dev_mc_list *dmi = dev->mc_list;
+	int i,j,k,b;
+	unsigned long crc;
+	int multicast_hash = 0;
+	int multicast_all = 0;
+	int promisc = 0;
+	
+	/* Lock out others. */
+	set_bit(0, (void *) &dev->tbusy);
+
+	if (dev->flags & IFF_PROMISC)
+		promisc = 1;
+	else if ((dev->flags & IFF_ALLMULTI) /* || (dev->mc_count > XXX) */) {
+		multicast_all = 1;
+	} else {
+		u16 hash_table[16];
+
+		for(i = 0; i < 16; i++)
+			hash_table[i] = 0;
+
+	    	for (i = 0; i < dev->mc_count; i++) {
+			crc = ~0;
+			for (j = 0; j < 6; ++j) {
+			    b = dmi->dmi_addr[j];
+			    for (k = 0; k < 8; ++k) {
+				if ((crc ^ b) & 1)
+				    crc = (crc >> 1) ^ CRC_POLY;
+				else
+				    crc >>= 1;
+				b >>= 1;
+			    }
+			}
+			j = crc >> 24;	/* bit number in multicast_filter */
+			hash_table[j >> 4] |= 1 << (15 - (j & 0xf));
+			dmi = dmi->next;
+	    	}
+
+	    	for (i = 0; i < 16; i++)
+	    		GM_OUT(GM_MAC_ADDR_FILTER_HASH0 + (i*4), hash_table[i]);
+		GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_HASH_ENABLE);
+	    	multicast_hash = 1;
+	}
+
+	if (promisc)
+		GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL);
+	else
+		GM_BIC(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL);
+
+	if (multicast_hash)
+		GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_HASH_ENABLE);
+	else
+		GM_BIC(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_HASH_ENABLE);
+
+	if (multicast_all)
+		GM_BIS(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL_MULTI);
+	else
+		GM_BIC(GM_MAC_RX_CONFIG, GM_MAC_RX_CONF_RX_ALL_MULTI);
+	
+	/* Let us get going again. */
+	dev->tbusy = 0;
+}
+
+static int
+gmac_open(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+
+	MOD_INC_USE_COUNT;
+
+	/* Power up and reset chip */
+	if (gmac_powerup_and_reset(dev)) {
+		MOD_DEC_USE_COUNT;
+		return -EIO;
+	}
+
+	/* Get our interrupt */
+	if (request_irq(dev->irq, gmac_interrupt, 0, dev->name, dev)) {
+		printk(KERN_ERR "%s can't get irq %d\n", dev->name, dev->irq);
+		MOD_DEC_USE_COUNT;
+		return -EAGAIN;
+	}
+
+	gm->full_duplex = 0;
+	gm->phy_status = 0;
+	
+	/* Find a PHY */
+	if (!mii_lookup_and_reset(gm))
+		printk(KERN_WARNING "%s WARNING ! Can't find PHY\n", dev->name);
+
+	/* Configure the PHY */
+	mii_setup_phy(gm);
+	
+	/* Initialize the descriptor rings */
+	gmac_init_rings(gm, 0);
+
+	/* Initialize the MAC */
+	gmac_mac_init(gm, dev->dev_addr);
+	
+	/* Initialize the multicast tables & promisc mode if any */
+	gmac_set_multicast(dev);
+	
+	/*
+	 * Check out PHY status and start auto-poll
+	 * 
+	 * Note: do this before enabling interrutps
+	 */
+	mii_interrupt(gm);
+
+	/* Start the chip */
+	gmac_start_dma(gm);
+
+	gm->opened = 1;
+
+	return 0;
+}
+
+static int
+gmac_close(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	int i;
+
+	gm->opened = 0;
+	
+	gmac_stop_dma(gm);
+	
+	mii_poll_stop(gm);
+	
+	free_irq(dev->irq, dev);
+
+	/* Shut down chip */
+	gmac_set_power(gm, 0);
+
+	for (i = 0; i < NRX; ++i) {
+		if (gm->rx_buff[i] != 0) {
+			dev_kfree_skb(gm->rx_buff[i]);
+			gm->rx_buff[i] = 0;
+		}
+	}
+	for (i = 0; i < NTX; ++i) {
+		if (gm->tx_buff[i] != 0) {
+			dev_kfree_skb(gm->tx_buff[i]);
+			gm->tx_buff[i] = 0;
+		}
+	}
+
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+/*
+ * Handle a transmit timeout
+ */
+static void
+gmac_tx_timeout(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	int i, timeout;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	
+	printk (KERN_ERR "%s: transmit timed out, resetting\n", dev->name);
+
+	/*
+	 * Do something useful here
+	 * 
+	 * FIXME: check if a complete re-init of the chip isn't necessary
+	 */
+
+	/* Stop chip */
+	gmac_stop_dma(gm);
+	/* Empty Tx ring of any remaining gremlins */
+	gmac_tx_cleanup(dev, 1);
+	/* Empty Rx ring of any remaining gremlins */
+	for (i = 0; i < NRX; ++i) {
+		if (gm->rx_buff[i] != 0) {
+			dev_kfree_skb(gm->rx_buff[i]);
+			gm->rx_buff[i] = 0;
+		}
+	}
+	/* Perform a software reset */
+	GM_OUT(GM_RESET, GM_RESET_TX | GM_RESET_RX);
+	for (timeout = 100; timeout > 0; --timeout) {
+		mdelay(10);
+		if ((GM_IN(GM_RESET) & (GM_RESET_TX | GM_RESET_RX)) == 0) {
+			/* Mask out all chips interrupts */
+			GM_OUT(GM_IRQ_MASK, 0xffffffff);
+			break;
+		}
+	}
+	if (!timeout)
+		printk(KERN_ERR "%s reset chip failed !\n", dev->name);
+	/* Create fresh rings */
+	gmac_init_rings(gm, 1);
+	/* re-initialize the MAC */
+	gmac_mac_init(gm, dev->dev_addr);	
+	/* re-initialize the multicast tables & promisc mode if any */
+	gmac_set_multicast(dev);
+	/* Restart PHY auto-poll */
+	mii_interrupt(gm);
+	/* Restart chip */
+	gmac_start_dma(gm);
+
+	restore_flags(flags);
+	
+	dev->tbusy = 0;
+}
+
+
+static int
+gmac_xmit_start(struct sk_buff *skb, struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	volatile struct gmac_dma_desc *dp;
+	int i;
+
+	/* Check tbusy bit and handle eventual transmitter timeout */
+	if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
+		int tickssofar = jiffies - dev->trans_start;
+	    
+		if (tickssofar >= 40)
+			gmac_tx_timeout(dev);
+		return 1;
+	}
+
+	i = gm->next_tx;
+	if (gm->tx_buff[i] != 0) {
+		/* buffer is full, can't send this packet at the moment */
+		return 1;
+	}
+	gm->next_tx = (i + 1) & (NTX - 1);
+	gm->tx_buff[i] = skb;
+
+	dp = &gm->txring[i];
+	/* FIXME: Interrupt on all packet for now, change this to every N packet,
+	 * with N to be adjusted
+	 */
+	dp->flags = TX_FL_INTERRUPT;
+	dp->hi_addr = 0;
+	st_le32(&dp->lo_addr, virt_to_bus(skb->data));
+	mb();
+	st_le32(&dp->size, TX_SZ_SOP | TX_SZ_EOP | skb->len);
+	mb();
+
+	dev->trans_start = jiffies;
+	GM_OUT(GM_TX_KICK, gm->next_tx);
+
+	dev->tbusy = (gm->tx_buff[gm->next_tx] != 0);
+
+	return 0;
+}
+
+/*
+ * Handle servicing of the transmit ring by deallocating used
+ * Tx packets and restoring flow control when necessary
+ */
+static void
+gmac_tx_cleanup(struct device *dev, int force_cleanup)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	volatile struct gmac_dma_desc *dp;
+	struct sk_buff *skb;
+	int gone, i;
+
+	i = gm->tx_gone;
+	gone = GM_IN(GM_TX_COMP);
+	
+	while (force_cleanup || i != gone) {
+		skb = gm->tx_buff[i];
+		if (skb == NULL)
+			break;
+		dp = &gm->txring[i];
+		if (force_cleanup)
+			++gm->stats.tx_errors;
+		else {
+			++gm->stats.tx_packets;
+			gm->stats.tx_bytes += skb->len;
+		}
+		gm->tx_buff[i] = NULL;
+		dev_kfree_skb(skb);
+		if (++i >= NTX)
+			i = 0;
+	}
+	gm->tx_gone = i;
+
+	if (!force_cleanup && dev->tbusy &&
+	    (gm->tx_buff[gm->next_tx] == 0))
+		dev->tbusy = 0;
+}
+
+static void
+gmac_receive(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	int i = gm->next_rx;
+	volatile struct gmac_dma_desc *dp;
+	struct sk_buff *skb, *new_skb;
+	int len, flags, drop, last;
+	unsigned char *data;
+	u16 csum;
+
+	last = -1;
+	for (;;) {
+		dp = &gm->rxring[i];
+		if (ld_le32(&dp->size) & RX_SZ_OWN)
+			break;
+		len = (ld_le32(&dp->size) >> 16) & 0x7fff;
+		flags = ld_le32(&dp->flags);
+		skb = gm->rx_buff[i];
+		drop = 0;
+		new_skb = NULL;
+		csum = ld_le32(&dp->size) & RX_SZ_CKSUM_MASK;
+		
+		/* Handle errors */
+		if ((len < ETH_ZLEN)||(flags & RX_FL_CRC_ERROR)||(!skb)) {
+			++gm->stats.rx_errors;
+			if (len < ETH_ZLEN)
+				++gm->stats.rx_length_errors;
+			if (flags & RX_FL_CRC_ERROR)
+				++gm->stats.rx_crc_errors;
+			if (!skb) {
+				++gm->stats.rx_dropped;
+				skb = gmac_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+				if (skb) {
+					gm->rx_buff[i] = skb;
+			    		skb->dev = dev;
+			    		skb_put(skb, ETH_FRAME_LEN + RX_OFFSET);
+			    		skb_reserve(skb, RX_OFFSET);
+				}
+			}
+			drop = 1;
+		} else {
+			/* Large packet, alloc a new skb for the ring */
+			if (len > RX_COPY_THRESHOLD) {
+			    new_skb = gmac_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+			    if(!new_skb) {
+			    	printk(KERN_INFO "%s: Out of SKBs in Rx, packet dropped !\n",
+			    		dev->name);
+			    	drop = 1;
+			    	++gm->stats.rx_dropped;
+			    	goto finish;
+			    }
+
+			    gm->rx_buff[i] = new_skb;
+			    new_skb->dev = dev;
+			    skb_put(new_skb, ETH_FRAME_LEN + RX_OFFSET);
+			    skb_reserve(new_skb, RX_OFFSET);
+			    skb_trim(skb, len);
+			} else {
+			    /* Small packet, copy it to a new small skb */
+			    struct sk_buff *copy_skb = dev_alloc_skb(len + RX_OFFSET);
+
+			    if(!copy_skb) {
+				printk(KERN_INFO "%s: Out of SKBs in Rx, packet dropped !\n",
+					dev->name);
+				drop = 1;
+				++gm->stats.rx_dropped;
+			    	goto finish;
+			    }
+
+			    copy_skb->dev = dev;
+			    skb_reserve(copy_skb, RX_OFFSET);
+			    skb_put(copy_skb, len);
+			    memcpy(copy_skb->data, skb->data, len);
+
+			    new_skb = skb;
+			    skb = copy_skb;
+			}
+		}
+	finish:
+		/* Need to drop packet ? */
+		if (drop) {
+			new_skb = skb;
+			skb = NULL;
+		}
+		
+		/* Put back ring entry */
+		data = new_skb ? (new_skb->data - RX_OFFSET) : dummy_buf;
+		dp->hi_addr = 0;
+		st_le32(&dp->lo_addr, virt_to_bus(data));
+		mb();
+		st_le32(&dp->size, RX_SZ_OWN | ((RX_BUF_ALLOC_SIZE-RX_OFFSET) << RX_SZ_SHIFT));
+		
+		/* Got Rx packet ? */
+		if (skb) {
+			/* Yes, baby, keep that hot ;) */
+			if(!(csum ^ 0xffff))
+				skb->ip_summed = CHECKSUM_UNNECESSARY;
+			else
+				skb->ip_summed = CHECKSUM_NONE;
+			skb->ip_summed = CHECKSUM_NONE;
+			skb->protocol = eth_type_trans(skb, dev);
+			netif_rx(skb);
+			gm->stats.rx_bytes += skb->len;
+			++gm->stats.rx_packets;
+		}
+		
+		last = i;
+		if (++i >= NRX)
+			i = 0;
+	}
+	gm->next_rx = i;
+	if (last >= 0) {
+		mb();
+		GM_OUT(GM_RX_KICK, last & 0xfffffffc);
+	}
+}
+
+static void
+gmac_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct device *dev = (struct device *) dev_id;
+	struct gmac *gm = (struct gmac *) dev->priv;
+	unsigned int status;
+
+	if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+		printk(KERN_ERR "%s: Duplicate entry of the interrupt handler !\n",
+			   dev->name);
+		dev->interrupt = 0;
+		return;
+	}
+
+	status = GM_IN(GM_IRQ_STATUS);
+	if (status & (GM_IRQ_BUS_ERROR | GM_IRQ_MIF))
+		GM_OUT(GM_IRQ_ACK, status & (GM_IRQ_BUS_ERROR | GM_IRQ_MIF));
+	
+	if (status & (GM_IRQ_RX_TAG_ERR | GM_IRQ_BUS_ERROR)) {
+		printk(KERN_ERR "%s: IRQ Error status: 0x%08x\n",
+			dev->name, status);
+	}
+	
+	if (status & GM_IRQ_MIF) {
+		mii_interrupt(gm);
+	}
+
+	if (status & GM_IRQ_RX_DONE)
+		gmac_receive(dev);
+
+	if (status & (GM_IRQ_TX_INT_ME | GM_IRQ_TX_ALL))
+		gmac_tx_cleanup(dev, 0);
+
+	dev->interrupt = 0;
+}
+
+static struct net_device_stats *
+gmac_stats(struct device *dev)
+{
+	struct gmac *gm = (struct gmac *) dev->priv;
+	struct net_device_stats *stats = &gm->stats;
+
+	if (gm && gm->opened) {
+		stats->rx_crc_errors += GM_IN(GM_MAC_RX_CRC_ERR_CTR);
+		GM_OUT(GM_MAC_RX_CRC_ERR_CTR, 0);
+
+		stats->rx_frame_errors += GM_IN(GM_MAC_RX_ALIGN_ERR_CTR);
+		GM_OUT(GM_MAC_RX_ALIGN_ERR_CTR, 0);
+
+		stats->rx_length_errors += GM_IN(GM_MAC_RX_LEN_ERR_CTR);
+		GM_OUT(GM_MAC_RX_LEN_ERR_CTR, 0);
+
+		stats->tx_aborted_errors += GM_IN(GM_MAC_EXCS_COLLISION_CTR);
+
+		stats->collisions +=
+			(GM_IN(GM_MAC_EXCS_COLLISION_CTR) +
+			 GM_IN(GM_MAC_LATE_COLLISION_CTR));
+		GM_OUT(GM_MAC_EXCS_COLLISION_CTR, 0);
+		GM_OUT(GM_MAC_LATE_COLLISION_CTR, 0);
+	}
+	
+	return stats;
+}
+
+int
+gmac_probe(struct device *dev)
+{
+	static int gmacs_found;
+	static struct device_node *next_gmac;
+	struct device_node *gmac;
+	struct gmac *gm;
+	unsigned long rx_descpage, tx_descpage;
+	unsigned char *addr;
+	int i;
+
+	/*
+	 * We could (and maybe should) do this using PCI scanning
+	 * for vendor/device ID 0x106b/0x21.
+	 */
+	if (!gmacs_found) {
+		next_gmac = find_compatible_devices("network", "gmac");
+		gmacs_found = 1;
+	}
+	if ((gmac = next_gmac) == 0)
+		return -ENODEV;
+	next_gmac = gmac->next;
+
+	if (gmac->n_addrs < 1 || gmac->n_intrs < 1) {
+		printk(KERN_ERR "can't use GMAC %s: %d addrs and %d intrs\n",
+		       gmac->full_name, gmac->n_addrs, gmac->n_intrs);
+		return -ENODEV;
+	}
+
+	rx_descpage = get_free_page(GFP_KERNEL);
+	if (rx_descpage == 0) {
+		printk(KERN_ERR "%s can't get a page for rx descriptors\n", dev->name);
+		return -EAGAIN;
+	}
+
+	tx_descpage = get_free_page(GFP_KERNEL);
+	if (tx_descpage == 0) {
+		printk(KERN_ERR "%s can't get a page for tx descriptors\n", dev->name);
+		free_page(rx_descpage);
+		return -EAGAIN;
+	}
+
+	dev = init_etherdev(0, sizeof(struct gmac));
+	memset(dev->priv, 0, sizeof(struct gmac));
+
+	gm = (struct gmac *) dev->priv;
+	dev->base_addr = gmac->addrs[0].address;
+	gm->regs = (volatile unsigned int *)
+		ioremap(gmac->addrs[0].address, 0x10000);
+	gm->sysregs = (volatile unsigned int *) ioremap(0xf8000000, 0x1000);
+	dev->irq = gmac->intrs[0].line;
+	gm->dev = dev;
+
+	if (pci_device_loc(gmac, &gm->pci_bus, &gm->pci_devfn)) {
+		gm->pci_bus = gm->pci_devfn = 0xff;
+		printk(KERN_ERR "Can't locate GMAC PCI entry\n");
+	}
+
+	addr = get_property(gmac, "local-mac-address", NULL);
+	if (addr == NULL) {
+		printk(KERN_ERR "Can't get mac-address for GMAC %s\n",
+		       gmac->full_name);
+		return -EAGAIN;
+	}
+
+	printk(KERN_INFO "%s: GMAC at", dev->name);
+	for (i = 0; i < 6; ++i) {
+		dev->dev_addr[i] = addr[i];
+		printk("%c%.2x", (i? ':': ' '), addr[i]);
+	}
+	printk(", driver " GMAC_VERSION "\n");
+
+	gm->tx_desc_page = tx_descpage;
+	gm->rx_desc_page = rx_descpage;
+	gm->rxring = (volatile struct gmac_dma_desc *) rx_descpage;
+	gm->txring = (volatile struct gmac_dma_desc *) tx_descpage;
+
+	gm->phy_addr = 0;
+	gm->opened = 0;
+	
+	dev->open = gmac_open;
+	dev->stop = gmac_close;
+	dev->hard_start_xmit = gmac_xmit_start;
+	dev->get_stats = gmac_stats;
+	dev->set_multicast_list = &gmac_set_multicast;
+
+	ether_setup(dev);
+
+	gmacs = dev;
+
+	return 0;
+}
+
+#ifdef MODULE
+
+MODULE_AUTHOR("Paul Mackerras/Ben Herrenschmidt");
+MODULE_DESCRIPTION("PowerMac GMAC driver.");
+
+int
+init_module(void)
+{
+	int rc;
+	
+	if (gmacs != NULL)
+		return -EBUSY;
+
+	/* We bump use count during probe since get_free_page can sleep
+	 * which can be a race condition if module is unloaded at this
+	 * point.
+	 */
+	MOD_INC_USE_COUNT;
+
+	rc = gmac_probe(NULL);
+
+	MOD_DEC_USE_COUNT;
+
+	return rc;
+}
+
+void
+cleanup_module(void)
+{
+	struct gmac *gm;
+
+	/* XXX should handle more than one */
+	if (gmacs == NULL)
+		return;
+
+	gm = (struct gmac *) gmacs->priv;
+	unregister_netdev(gmacs);
+	free_page(gm->rx_desc_page);
+	free_page(gm->tx_desc_page);
+	kfree(gmacs);
+	gmacs = NULL;
+}
+
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/gmac.h linux.17p18/drivers/net/gmac.h
--- linux.vanilla/drivers/net/gmac.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/net/gmac.h	Tue Aug  1 07:59:45 2000
@@ -0,0 +1,892 @@
+/*
+ * Definitions for the GMAC ethernet chip, used in the
+ * Apple G4 powermac.
+ */
+
+
+/* 
+ * GMAC register definitions
+ * 
+ * Note: We encode the register size the same way Apple does. I didn't copy
+ *       Apple's source as-is to avoid licence issues however. That's really
+ *       painful to re-define all those registers ...
+ *       The constants themselves were partially found in OF code, in Sun
+ *       GEM driver and in Apple's Darwin GMAC driver
+ */
+
+#define REG_SZ_8			0x00000000
+#define REG_SZ_16			0x40000000
+#define REG_SZ_32			0x80000000
+#define REG_MASK			0x0FFFFFFF
+
+	/*
+	 * Global registers
+	 */
+
+/* -- 0x0004	RW	Global configuration
+ * d: 0x00000042
+ */
+#define GM_GCONF			(0x0004 | REG_SZ_16)
+#define GM_GCONF_BURST_SZ		0x0001		/* 1: 64 bytes/burst, 0: infinite */
+#define GM_GCONF_TXDMA_LIMIT_MASK	0x003e		/* 5-1: No of 64 bytes transfers */
+#define GM_GCONF_TXDMA_LIMIT_SHIFT	1
+#define GM_GCONF_RXDMA_LIMIT_MASK	0x07c0		/* 10-6: No of 64 bytes transfers */
+#define GM_GCONF_RXDMA_LIMIT_SHIFT	6
+
+/* -- 0x000C	R-C	Global Interrupt status. 
+ * d: 0x00000000	bits 0-6 cleared on read (C)
+ */
+#define GM_IRQ_STATUS			(0x000c | REG_SZ_32)
+#define GM_IRQ_TX_INT_ME		0x00000001	/* C Frame with INT_ME bit set in fifo */
+#define GM_IRQ_TX_ALL			0x00000002	/* C TX descriptor ring empty */
+#define GM_IRQ_TX_DONE			0x00000004	/* C moved from host to TX fifo */
+#define GM_IRQ_RX_DONE			0x00000010	/* C moved from RX fifo to host */
+#define GM_IRQ_RX_NO_BUF		0x00000020	/* C No RX buffer available */
+#define GM_IRQ_RX_TAG_ERR		0x00000040	/* C RX tag error */
+#define GM_IRQ_PCS			0x00002000	/* PCS interrupt ? */
+#define GM_IRQ_MAC_TX			0x00004000	/* MAC tx register set */
+#define GM_IRQ_MAC_RX			0x00008000	/* MAC rx register set  */
+#define GM_IRQ_MAC_CTRL			0x00010000	/* MAC control register set  */
+#define GM_IRQ_MIF			0x00020000	/* MIF status register set */
+#define GM_IRQ_BUS_ERROR		0x00040000	/* Bus error status register set */
+#define GM_IRQ_TX_COMP			0xfff80000	/* TX completion mask */
+	
+/* -- 0x0010	RW	Interrupt mask. 
+ * d: 0xFFFFFFFF
+ */
+#define GM_IRQ_MASK			(0x0010 | REG_SZ_32)
+
+/* -- 0x0014	WO	Interrupt ack.
+ * 			Ack. "high" interrupts
+ */
+#define GM_IRQ_ACK			(0x0014 | REG_SZ_32)
+
+/* -- 0x001C	WO	Alias of status register (no auto-clear of "low" interrupts)
+ */
+#define GM_IRQ_ALT_STAT			(0x001C | REG_SZ_32)
+
+/* -- 0x1000	R-C	PCI Error status register
+ */
+#define GM_PCI_ERR_STAT			(0x1000 | REG_SZ_8)
+#define GM_PCI_ERR_BAD_ACK		0x01		/* Bad Ack64 */
+#define GM_PCI_ERR_TIMEOUT		0x02		/* Transaction timeout */
+#define GM_PCI_ERR_OTHER		0x04		/* Any other PCI error */
+	
+/* -- 0x1004	RW	PCI Error mask register
+ * d: 0xFFFFFFFF
+ */
+#define GM_PCI_ERR_MASK			(0x1004 | REG_SZ_8)
+
+/* -- 0x1008	RW	BIF Configuration
+ * d: 0x00000000
+ */
+#define GM_BIF_CFG			(0x1008 | REG_SZ_8)
+#define	GM_BIF_CFG_SLOWCLK		0x01		/* for parity error timing */
+#define	GM_BIF_CFG_HOST_64		0x02		/* 64-bit host */
+#define	GM_BIF_CFG_B64D_DIS		0x04		/* no 64-bit wide data cycle */
+#define	GM_BIF_CFG_M66EN		0x08		/* Read-only: sense if configured for 66MHz */
+	
+/* -- 0x100C	RW	BIF Diagnostic ???
+ */
+#define GM_BIF_DIAG			(0x100C | REG_SZ_32)
+#define GM_BIF_DIAG_BURST_STATE		0x007F0000
+#define GM_BIF_DIAG_STATE_MACH		0xFF000000
+
+/* -- 0x1010	RW	Software reset
+ *			Lower two bits reset TX and RX, both reset whole gmac. They come back
+ *			to 0 when reset is complete.
+ *			bit 2 force RSTOUT# pin when set (PHY reset)
+ */
+#define GM_RESET			(0x1010 | REG_SZ_8)
+#define	GM_RESET_TX			0x01
+#define	GM_RESET_RX			0x02
+#define	GM_RESET_RSTOUT			0x04		/* PHY reset */
+
+
+	/*
+	 * Tx DMA Registers
+	 */
+
+/* -- 0x2000	RW	Tx Kick
+ * d: 0x00000000	Written by the host with the last tx descriptor number +1 to send
+ */
+#define GM_TX_KICK			(0x2000 | REG_SZ_16)
+
+/* -- 0x2004	RW	Tx configuration
+ * d: 0x118010		Controls operation of Tx DMA channel
+ */
+
+#define GM_TX_CONF			(0x2004 | REG_SZ_32)
+#define	GM_TX_CONF_DMA_EN		0x00000001	/* Tx DMA enable */
+#define	GM_TX_CONF_RING_SZ_MASK		0x0000001e	/* Tx desc ring size */
+#define GM_TX_CONF_RING_SZ_SHIFT	1		/* Tx desc ring size shift */
+#define GM_TX_CONF_FIFO_PIO		0x00000020	/* Tx fifo PIO select ??? */
+#define	GM_TX_CONF_FIFO_THR_MASK	0x001ffc00	/* Tx fifo threshold */
+#define GM_TX_CONF_FIFO_THR_SHIFT	10		/* Tx fifo threshold shift */
+#define GM_TX_CONF_FIFO_THR_DEFAULT	0x7ff		/* Tx fifo threshold default */
+#define	GM_TX_CONF_PACED_MODE		0x00100000	/* 1: tx_all irq after last descriptor */
+							/* 0: tx_all irq when tx fifo empty */
+#define	GM_TX_RING_SZ_32		(0 << 1)
+#define	GM_TX_RING_SZ_64		(1 << 1)
+#define	GM_TX_RING_SZ_128		(2 << 1)
+#define	GM_TX_RING_SZ_256		(3 << 1)
+#define	GM_TX_RING_SZ_512		(4 << 1)
+#define	GM_TX_RING_SZ_1024		(5 << 1)
+#define	GM_TX_RING_SZ_2048		(6 << 1)
+#define	GM_TX_RING_SZ_4086		(7 << 1)
+#define	GM_TX_RING_SZ_8192		(8 << 1)
+
+/* -- 0x2008	RW	Tx descriptor ring base low
+ * -- 0x200C	RW	Tx descriptor ring base high
+ *
+ * Base of tx ring, must be 2k aligned
+ */
+#define GM_TX_DESC_LO			(0x2008 | REG_SZ_32)
+#define GM_TX_DESC_HI			(0x200C | REG_SZ_32)
+ 
+/* -- 0x2100	RW	Tx Completion
+ * d: 0x00000000	Written by the gmac with the last tx descriptor number +1 sent
+ */
+#define GM_TX_COMP			(0x2100 | REG_SZ_16)
+
+
+	/*
+	 * Rx DMA registers
+	 */
+
+
+/* -- 0x4000	RW	Rx configuration
+ * d: 0x1000010		Controls operation of Rx DMA channel
+ */
+
+#define GM_RX_CONF			(0x4000 | REG_SZ_32)
+#define	GM_RX_CONF_DMA_EN		0x00000001	/* Rx DMA enable */
+#define	GM_RX_CONF_RING_SZ_MASK		0x0000001e	/* Rx desc ring size */
+#define GM_RX_CONF_RING_SZ_SHIFT	1
+#define	GM_RX_CONF_BATCH_DIS		0x00000020	/* Rx batch disable */
+#define	GM_RX_CONF_FBYTE_OFF_MASK	0x00001c00	/* First byte offset (10-12) */
+#define GM_RX_CONF_FBYTE_OFF_SHIFT	10
+#define	GM_RX_CONF_CHK_START_MASK	0x000FE000	/* Checksum start offset */
+#define GM_RX_CONF_CHK_START_SHIFT	13
+#define	GM_RX_CONF_DMA_THR_MASK		0x07000000	/* Rx DMA threshold */
+#define GM_RX_CONF_DMA_THR_SHIFT	24		/* Rx DMA threshold shift */
+#define GM_RX_CONF_DMA_THR_DEFAULT	1		/* Rx DMA threshold default */
+
+#define	GM_RX_RING_SZ_32		(0 << 1)
+#define	GM_RX_RING_SZ_64		(1 << 1)
+#define	GM_RX_RING_SZ_128		(2 << 1)
+#define	GM_RX_RING_SZ_256		(3 << 1)
+#define	GM_RX_RING_SZ_512		(4 << 1)
+#define	GM_RX_RING_SZ_1024		(5 << 1)
+#define	GM_RX_RING_SZ_2048		(6 << 1)
+#define	GM_RX_RING_SZ_4086		(7 << 1)
+#define	GM_RX_RING_SZ_8192		(8 << 1)
+
+/* -- 0x4004	RW	Rx descriptor ring base low
+ * -- 0x4008	RW	Rx descriptor ring base high
+ *
+ * Base of rx ring
+ */
+#define GM_RX_DESC_LO			(0x4004 | REG_SZ_32)
+#define GM_RX_DESC_HI			(0x4008 | REG_SZ_32)
+
+/* -- 0x4020	RW	Rx pause threshold
+ * d: 0x000000f8	
+ *
+ * Two PAUSE thresholds are used to define when PAUSE flow control frames are
+ * emitted by GEM. The granularity of these thresholds is in 64 byte increments.
+ * XOFF PAUSE frames use the pause_time value pre-programmed in the
+ * Send PAUSE MAC Register.
+ * XON PAUSE frames use a pause_time of 0.
+ */
+#define GM_RX_PTH			(0x4020 | REG_SZ_32)
+			/*
+			 * 0-8: XOFF PAUSE emitted when RX FIFO
+			 * occupancy rises above this value (times 64 bytes)
+			 */
+#define	GM_RX_PTH_OFF_MASK		0x000001ff
+#define GM_RX_PTH_OFF_SHIFT		0
+			/*
+			 * 12-20: XON PAUSE emitted when RX FIFO
+			 * occupancy falls below this value (times 64 bytes)
+			 */
+#define	GM_RX_PTH_ON_MASK		0x001ff000
+#define	GM_RX_PTH_ON_SHIFT		12
+
+#define GM_RX_PTH_UNITS			64
+
+/* -- 0x4100	RW	Rx Kick
+ * d: 0x00000000	The last valid RX descriptor is the one right before the value of the
+ *                      register. Initially set to 0 on reset. RX descriptors must be posted
+ *                      in multiples of 4. The first descriptor should be cache-line aligned
+ *                      for best performance.
+ */
+#define GM_RX_KICK			(0x4100 | REG_SZ_16)
+
+/* -- 0x4104	RW	Rx Completion
+ * d: 0x00000000	All descriptors upto but excluding the register value are ready to be
+ *                      processed by the host.
+ */
+#define GM_RX_COMP			(0x4104 | REG_SZ_16)
+ 
+/* -- 0x4108	RW	Rx Blanking
+ * d: 0x00000000	Written by the gmac with the last tx descriptor number +1 sent
+ *
+ * Defines the values used for receive interrupt blanking.
+ * For INTR_TIME field, every count is 2048 PCI clock time. For 66 Mhz, each
+ * count is about 15 ns.
+ */
+#define GM_RX_BLANK			(0x4108 | REG_SZ_32)
+			/*
+			 * 0-8:no.of pkts to be recvd since the last RX_DONE
+			 * interrupt, before a new interrupt
+			 */
+#define	GM_RX_BLANK_INTR_PACKETS_MASK	0x000001ff
+#define	GM_RX_BLANK_INTR_PACKETS_SHIFT	0
+			/*
+			 * 12-19 : no. of clocks to be counted since the last
+			 * RX_DONE interrupt, before a new interrupt
+			 */
+#define	GM_RX_BLANK_INTR_TIME_MASK	0x000ff000
+#define	GM_RX_BLANK_INTR_TIME_SHIFT	12
+
+#define GM_RX_BLANK_UNITS		2048
+
+/* -- 0x4120	RO	Rx fifo size
+ *
+ * This 11-bit RO register indicates the size, in 64-byte multiples, of the
+ * RX FIFO. Software should use it to properly configure the PAUSE thresholds.
+ * The value read is 0x140, indicating a 20kbyte RX FIFO.
+ * -------------------------------------------------------------------------
+ */
+#define GM_RX_FIFO_SIZE			(0x4120 | REG_SZ_16)
+#define GM_RZ_FIFO_SIZE_UNITS		64
+
+
+	/*
+	 * MAC regisers
+	 */
+
+/* -- 0x6000		MAC Tx reset control
+ */
+#define GM_MAC_TX_RESET			(0x6000 | REG_SZ_8)
+#define GM_MAC_TX_RESET_NOW		0x01
+
+/* -- 0x6004		MAC Rx reset control
+ */
+#define GM_MAC_RX_RESET			(0x6004 | REG_SZ_8)
+#define GM_MAC_RX_RESET_NOW		0x01
+
+/* -- 0x6008		Send Pause command register
+ */
+#define GM_MAC_SND_PAUSE		(0x6008 | REG_SZ_32)
+#define GM_MAC_SND_PAUSE_TIME_MASK	0x0000ffff
+#define GM_MAC_SND_PAUSE_TIME_SHIFT	0
+#define GM_MAC_SND_PAUSE_NOW		0x00010000
+#define GM_MAC_SND_PAUSE_DEFAULT	0x00001bf0
+
+/* -- 0x6010		MAC transmit status
+ */
+#define GM_MAC_TX_STATUS		(0x6010 | REG_SZ_16)
+#define GM_MAC_TX_STAT_SENT		0x0001
+#define GM_MAC_TX_STAT_UNDERRUN		0x0002
+#define GM_MAC_TX_STAT_MAX_PKT_ERR	0x0004
+#define GM_MAC_TX_STAT_NORM_COLL_OVF	0x0008
+#define GM_MAC_TX_STAT_EXCS_COLL_OVF	0x0010
+#define GM_MAC_TX_STAT_LATE_COLL_OVF	0x0020
+#define GM_MAC_TX_STAT_FIRS_COLL_OVF	0x0040
+#define GM_MAC_TX_STAT_DEFER_TIMER_OVF	0x0080
+#define GM_MAC_TX_STAT_PEAK_ATTMP_OVF	0x0100
+
+/* -- 0x6014		MAC receive status
+ */
+#define GM_MAC_RX_STATUS		(0x6014 | REG_SZ_16)
+#define GM_MAC_RX_STAT_RECEIVED		0x0001
+#define GM_MAC_RX_STAT_FIFO_OVF		0x0002
+#define GM_MAC_RX_STAT_FRAME_CTR_OVF	0x0004
+#define GM_MAC_RX_STAT_ALIGN_ERR_OVF	0x0008
+#define GM_MAC_RX_STAT_CRC_ERR_OVF	0x0010
+#define GM_MAC_RX_STAT_LEN_ERR_OVF	0x0020
+#define GM_MAC_RX_STAT_CODE_ERR_OVF	0x0040
+
+/* -- 0x6018		MAC control & status
+ */
+#define GM_MAC_CTRLSTAT			(0x6018 | REG_SZ_32)
+#define GM_MAC_CTRLSTAT_PAUSE_RCVD	0x00000001
+#define GM_MAC_CTRLSTAT_PAUSE_STATE	0x00000002
+#define GM_MAC_CTRLSTAT_PAUSE_NOT	0x00000004
+#define GM_MAC_CTRLSTAT_PAUSE_TIM_MASK	0xffff0000
+#define GM_MAC_CTRLSTAT_PAUSE_TIM_SHIFT	16
+
+/* -- 0x6020		MAC Tx mask
+ * 			Same bits as MAC Tx status
+ */
+#define GM_MAC_TX_MASK			(0x6020 | REG_SZ_16)
+
+/* -- 0x6024		MAC Rx mask
+ * 			Same bits as MAC Rx status
+ */
+#define GM_MAC_RX_MASK			(0x6024 | REG_SZ_16)
+
+/* -- 0x6028		MAC Control/Status mask
+ * 			Same bits as MAC control/status low order byte
+ */
+#define GM_MAC_CTRLSTAT_MASK		(0x6024 | REG_SZ_8)
+
+/* -- 0x6030		MAC Tx configuration
+ */
+#define GM_MAC_TX_CONFIG		(0x6030 | REG_SZ_16)
+#define GM_MAC_TX_CONF_ENABLE		0x0001
+#define GM_MAC_TX_CONF_IGNORE_CARRIER	0x0002
+#define GM_MAC_TX_CONF_IGNORE_COLL	0x0004
+#define GM_MAC_TX_CONF_ENABLE_IPG0	0x0008
+#define GM_MAC_TX_CONF_DONT_GIVEUP	0x0010
+#define GM_MAC_TX_CONF_DONT_GIVEUP_NLMT	0x0020
+#define GM_MAC_TX_CONF_NO_BACKOFF	0x0040
+#define GM_MAC_TX_CONF_SLOWDOWN		0x0080
+#define GM_MAC_TX_CONF_NO_FCS		0x0100
+#define GM_MAC_TX_CONF_CARRIER_EXT	0x0200
+
+/* -- 0x6034		MAC Rx configuration
+ */
+#define GM_MAC_RX_CONFIG		(0x6034 | REG_SZ_16)
+#define GM_MAC_RX_CONF_ENABLE		0x0001
+#define GM_MAC_RX_CONF_STRIP_PAD	0x0002
+#define GM_MAC_RX_CONF_STIP_FCS		0x0004
+#define GM_MAC_RX_CONF_RX_ALL		0x0008
+#define GM_MAC_RX_CONF_RX_ALL_MULTI	0x0010
+#define GM_MAC_RX_CONF_HASH_ENABLE	0x0020
+#define GM_MAC_RX_CONF_ADDR_FLTR_ENABLE	0x0040
+#define GM_MAC_RX_CONF_PASS_ERROR_FRAM	0x0080
+#define GM_MAC_RX_CONF_CARRIER_EXT	0x0100
+
+/* -- 0x6038		MAC control configuration
+ */
+#define GM_MAC_CTRL_CONFIG		(0x6038 | REG_SZ_8)
+#define GM_MAC_CTRL_CONF_SND_PAUSE_EN	0x01
+#define GM_MAC_CTRL_CONF_RCV_PAUSE_EN	0x02
+#define GM_MAC_CTRL_CONF_PASS_CTRL_FRAM	0x04
+
+/* -- 0x603c		MAC XIF configuration */
+#define GM_MAC_XIF_CONFIG		(0x603c | REG_SZ_8)
+#define GM_MAC_XIF_CONF_TX_MII_OUT_EN	0x01
+#define GM_MAC_XIF_CONF_MII_INT_LOOP	0x02
+#define GM_MAC_XIF_CONF_DISABLE_ECHO	0x04
+#define GM_MAC_XIF_CONF_GMII_MODE	0x08
+#define GM_MAC_XIF_CONF_MII_BUFFER_EN	0x10
+#define GM_MAC_XIF_CONF_LINK_LED	0x20
+#define GM_MAC_XIF_CONF_FULL_DPLX_LED	0x40
+
+/* -- 0x6040		MAC inter-packet GAP 0
+ */
+#define GM_MAC_INTR_PKT_GAP0		(0x6040 | REG_SZ_8)
+#define GM_MAC_INTR_PKT_GAP0_DEFAULT	0x00
+
+/* -- 0x6044		MAC inter-packet GAP 1
+ */
+#define GM_MAC_INTR_PKT_GAP1		(0x6044 | REG_SZ_8)
+#define GM_MAC_INTR_PKT_GAP1_DEFAULT	0x08
+
+/* -- 0x6048		MAC inter-packet GAP 2
+ */
+#define GM_MAC_INTR_PKT_GAP2		(0x6048 | REG_SZ_8)
+#define GM_MAC_INTR_PKT_GAP2_DEFAULT	0x04
+
+/* -- 604c		MAC slot time
+ */
+#define GM_MAC_SLOT_TIME		(0x604C | REG_SZ_16)
+#define GM_MAC_SLOT_TIME_DEFAULT	0x0040
+
+/* -- 6050		MAC minimum frame size
+ */
+#define GM_MAC_MIN_FRAME_SIZE		(0x6050 | REG_SZ_16)
+#define GM_MAC_MIN_FRAME_SIZE_DEFAULT	0x0040
+
+/* -- 6054		MAC maximum frame size
+ */
+#define GM_MAC_MAX_FRAME_SIZE		(0x6054 | REG_SZ_16)
+#define GM_MAC_MAX_FRAME_SIZE_DEFAULT	0x05ee
+#define GM_MAC_MAX_FRAME_SIZE_ALIGN	0x5f0
+
+/* -- 6058		MAC preamble length
+ */
+#define GM_MAC_PREAMBLE_LEN		(0x6058 | REG_SZ_16)
+#define GM_MAC_PREAMBLE_LEN_DEFAULT	0x0007
+
+/* -- 605c		MAC jam size
+ */
+#define GM_MAC_JAM_SIZE			(0x605c | REG_SZ_8)
+#define GM_MAC_JAM_SIZE_DEFAULT		0x04
+
+/* -- 6060		MAC attempt limit
+ */
+#define GM_MAC_ATTEMPT_LIMIT		(0x6060 | REG_SZ_8)
+#define GM_MAC_ATTEMPT_LIMIT_DEFAULT	0x10
+
+/* -- 6064		MAC control type
+ */
+#define GM_MAC_CONTROL_TYPE		(0x6064 | REG_SZ_16)
+#define GM_MAC_CONTROL_TYPE_DEFAULT	0x8808
+
+/* -- 6080		MAC address 15..0
+ * -- 6084		MAC address 16..31
+ * -- 6088		MAC address 32..47
+ */
+#define GM_MAC_ADDR_NORMAL0		(0x6080 | REG_SZ_16)
+#define GM_MAC_ADDR_NORMAL1		(0x6084 | REG_SZ_16)
+#define GM_MAC_ADDR_NORMAL2		(0x6088 | REG_SZ_16)
+
+/* -- 608c		MAC alternate address 15..0
+ * -- 6090		MAC alternate address 16..31
+ * -- 6094		MAC alternate address 32..47
+ */
+#define GM_MAC_ADDR_ALT0		(0x608c | REG_SZ_16)
+#define GM_MAC_ADDR_ALT1		(0x6090 | REG_SZ_16)
+#define GM_MAC_ADDR_ALT2		(0x6094 | REG_SZ_16)
+
+/* -- 6098		MAC control address 15..0
+ * -- 609c		MAC control address 16..31
+ * -- 60a0		MAC control address 32..47
+ */
+#define GM_MAC_ADDR_CTRL0		(0x6098 | REG_SZ_16)
+#define GM_MAC_ADDR_CTRL1		(0x609c | REG_SZ_16)
+#define GM_MAC_ADDR_CTRL2		(0x60a0 | REG_SZ_16)
+
+/* -- 60a4		MAC address filter (0_0)
+ * -- 60a8		MAC address filter (0_1)
+ * -- 60ac		MAC address filter (0_2)
+ */
+#define GM_MAC_ADDR_FILTER0		(0x60a4 | REG_SZ_16)
+#define GM_MAC_ADDR_FILTER1		(0x60a8 | REG_SZ_16)
+#define GM_MAC_ADDR_FILTER2		(0x60ac | REG_SZ_16)
+
+/* -- 60b0		MAC address filter mask 1,2
+ */
+#define GM_MAC_ADDR_FILTER_MASK1_2	(0x60b0 | REG_SZ_8)
+
+/* -- 60b4		MAC address filter mask 0
+ */
+#define GM_MAC_ADDR_FILTER_MASK0	(0x60b4 | REG_SZ_16)
+
+/* -- [60c0 .. 60fc]	MAC hash table
+ */
+#define GM_MAC_ADDR_FILTER_HASH0	(0x60c0 | REG_SZ_16)
+
+/* -- 6100		MAC normal collision counter
+ */
+#define GM_MAC_COLLISION_CTR		(0x6100 | REG_SZ_16)
+
+/* -- 6104		MAC 1st successful collision counter
+ */
+#define GM_MAC_FIRST_COLLISION_CTR	(0x6104 | REG_SZ_16)
+
+/* -- 6108		MAC excess collision counter
+ */
+#define GM_MAC_EXCS_COLLISION_CTR	(0x6108 | REG_SZ_16)
+
+/* -- 610c		MAC late collision counter
+ */
+#define GM_MAC_LATE_COLLISION_CTR	(0x610c | REG_SZ_16)
+
+/* -- 6110		MAC defer timer counter
+ */
+#define GM_MAC_DEFER_TIMER_COUNTER	(0x6110 | REG_SZ_16)
+
+/* -- 6114		MAC peak attempts
+ */
+#define GM_MAC_PEAK_ATTEMPTS		(0x6114 | REG_SZ_16)
+
+/* -- 6118		MAC Rx frame counter
+ */
+#define GM_MAC_RX_FRAME_CTR		(0x6118 | REG_SZ_16)
+
+/* -- 611c		MAC Rx length error counter
+ */
+#define GM_MAC_RX_LEN_ERR_CTR		(0x611c | REG_SZ_16)
+
+/* -- 6120		MAC Rx alignment error counter
+ */
+#define GM_MAC_RX_ALIGN_ERR_CTR		(0x6120 | REG_SZ_16)
+
+/* -- 6124		MAC Rx CRC error counter
+ */
+#define GM_MAC_RX_CRC_ERR_CTR		(0x6124 | REG_SZ_16)
+
+/* -- 6128		MAC Rx code violation error counter
+ */
+#define GM_MAC_RX_CODE_VIOLATION_CTR	(0x6128 | REG_SZ_16)
+
+/* -- 6130		MAC random number seed
+ */
+#define GM_MAC_RANDOM_SEED		(0x6130 | REG_SZ_16)
+
+/* -- 6134		MAC state machine
+ */
+#define GM_MAC_STATE_MACHINE		(0x6134 | REG_SZ_8)
+
+
+	/*
+	 * MIF registers
+	 */
+
+
+/* -- 0x6200	RW	MIF bit bang clock
+ */
+#define GM_MIF_BB_CLOCK			(0x6200 | REG_SZ_8)
+
+/* -- 0x6204	RW	MIF bit bang data
+ */
+#define GM_MIF_BB_DATA			(0x6204 | REG_SZ_8)
+
+/* -- 0x6208	RW	MIF bit bang output enable
+ */
+#define GM_MIF_BB_OUT_ENABLE		(0x6208 | REG_SZ_8)
+
+/* -- 0x620c	RW	MIF frame control & data
+ */
+#define GM_MIF_FRAME_CTL_DATA		(0x620c | REG_SZ_32)
+#define GM_MIF_FRAME_START_MASK		0xc0000000
+#define GM_MIF_FRAME_START_SHIFT	30
+#define GM_MIF_FRAME_OPCODE_MASK	0x30000000
+#define GM_MIF_FRAME_OPCODE_SHIFT	28
+#define GM_MIF_FRAME_PHY_ADDR_MASK	0x0f800000
+#define GM_MIF_FRAME_PHY_ADDR_SHIFT	23
+#define GM_MIF_FRAME_REG_ADDR_MASK	0x007c0000
+#define GM_MIF_FRAME_REG_ADDR_SHIFT	18
+#define GM_MIF_FRAME_TURNAROUND_HI	0x00020000
+#define GM_MIF_FRAME_TURNAROUND_LO	0x00010000
+#define GM_MIF_FRAME_DATA_MASK		0x0000ffff
+#define GM_MIF_FRAME_DATA_SHIFT		0
+
+/* -- 0x6210	RW	MIF config reg
+ */
+#define GM_MIF_CFG			(0x6210 | REG_SZ_16)
+#define	GM_MIF_CFGPS			0x00000001	/* PHY Select */
+#define	GM_MIF_CFGPE			0x00000002	/* Poll Enable */
+#define	GM_MIF_CFGBB			0x00000004	/* Bit Bang Enable */
+#define	GM_MIF_CFGPR_MASK		0x000000f8	/* Poll Register address */
+#define	GM_MIF_CFGPR_SHIFT		3
+#define	GM_MIF_CFGM0			0x00000100	/* MDIO_0 Data / MDIO_0 attached */
+#define	GM_MIF_CFGM1			0x00000200	/* MDIO_1 Data / MDIO_1 attached */
+#define	GM_MIF_CFGPD_MASK		0x00007c00	/* Poll Device PHY address */
+#define	GM_MIF_CFGPD_SHIFT		10
+
+#define	GM_MIF_POLL_DELAY		200
+
+#define	GM_INTERNAL_PHYAD		1		/* PHY address for int. transceiver */
+#define	GM_EXTERNAL_PHYAD		0		/* PHY address for ext. transceiver */
+
+/* -- 0x6214	RW	MIF interrupt mask reg
+ *			same as basic/status Register
+ */
+#define GM_MIF_IRQ_MASK			(0x6214 | REG_SZ_16)
+
+/* -- 0x6218	RW	MIF basic/status reg
+ *			The Basic portion of this register indicates the last
+ *			value of the register read indicated in the POLL REG field
+ *			of the Configuration Register.
+ *			The Status portion indicates bit(s) that have changed.
+ *			The MIF Mask register is corresponding to this register in
+ *			terms of the bit(s) that need to be masked for generating
+ *			interrupt on the MIF Interrupt Bit of the Global Status Rgister.
+ */
+#define GM_MIF_STATUS			(0x6218 | REG_SZ_32)
+
+#define	GM_MIF_STATUS_MASK		0x0000ffff	/* 0-15 : Status */
+#define	GM_MIF_BASIC_MASK		0xffff0000	/* 16-31 : Basic register */
+
+	/*
+	 * PCS link registers
+	 */
+
+/* -- 0x9000	RW	PCS mii control reg
+ */
+#define GM_PCS_CONTROL			(0x9000 | REG_SZ_16)
+
+/* -- 0x9004	RW	PCS mii status reg
+ */
+#define GM_PCS_STATUS			(0x9004 | REG_SZ_16)
+
+/* -- 0x9008	RW	PCS mii advertisement
+ */
+#define GM_PCS_ADVERTISEMENT		(0x9008 | REG_SZ_16)
+
+/* -- 0x900c	RW	PCS mii LP ability
+ */
+#define GM_PCS_ABILITY			(0x900c | REG_SZ_16)
+
+/* -- 0x9010	RW	PCS config
+ */
+#define GM_PCS_CONFIG			(0x9010 | REG_SZ_8)
+
+/* -- 0x9014	RW	PCS state machine
+ */
+#define GM_PCS_STATE_MACHINE		(0x9014 | REG_SZ_32)
+
+/* -- 0x9018	RW	PCS interrupt status
+ */
+#define GM_PCS_IRQ_STATUS		(0x9018 | REG_SZ_8)
+
+/* -- 0x9050	RW	PCS datapath mode
+ */
+#define GM_PCS_DATAPATH_MODE		(0x9050 | REG_SZ_8)
+#define GM_PCS_DATAPATH_INTERNAL	0x01	/* Internal serial link */
+#define GM_PCS_DATAPATH_SERDES		0x02	/* 10-bit Serdes interface */
+#define GM_PCS_DATAPATH_MII		0x04	/* Select mii/gmii mode */
+#define GM_PCS_DATAPATH_GMII_OUT	0x08	/* serial mode only, copy data to gmii */
+
+/* -- 0x9054	RW	PCS serdes control
+ */
+#define GM_PCS_SERDES_CTRL		(0x9054 | REG_SZ_8)
+
+/* -- 0x9058	RW	PCS serdes output select
+ */
+#define GM_PCS_SERDES_SELECT		(0x9058 | REG_SZ_8)
+
+/* -- 0x905c	RW	PCS serdes state
+ */
+#define GM_PCS_SERDES_STATE		(0x905c | REG_SZ_8)
+
+
+	/*
+	 * PHY registers
+	 */
+
+/*
+ * Standard PHY registers (from de4x5.h)
+ */
+#define MII_CR       0x00          /* MII Management Control Register */
+#define MII_SR       0x01          /* MII Management Status Register */
+#define MII_ID0      0x02          /* PHY Identifier Register 0 */
+#define MII_ID1      0x03          /* PHY Identifier Register 1 */
+#define MII_ANA      0x04          /* Auto Negotiation Advertisement */
+#define MII_ANLPA    0x05          /* Auto Negotiation Link Partner Ability */
+#define MII_ANE      0x06          /* Auto Negotiation Expansion */
+#define MII_ANP      0x07          /* Auto Negotiation Next Page TX */
+
+/*
+** MII Management Control Register
+*/
+#define MII_CR_RST  0x8000         /* RESET the PHY chip */
+#define MII_CR_LPBK 0x4000         /* Loopback enable */
+#define MII_CR_SPD  0x2000         /* 0: 10Mb/s; 1: 100Mb/s */
+#define MII_CR_10   0x0000         /* Set 10Mb/s */
+#define MII_CR_100  0x2000         /* Set 100Mb/s */
+#define MII_CR_ASSE 0x1000         /* Auto Speed Select Enable */
+#define MII_CR_PD   0x0800         /* Power Down */
+#define MII_CR_ISOL 0x0400         /* Isolate Mode */
+#define MII_CR_RAN  0x0200         /* Restart Auto Negotiation */
+#define MII_CR_FDM  0x0100         /* Full Duplex Mode */
+#define MII_CR_CTE  0x0080         /* Collision Test Enable */
+
+/*
+** MII Management Status Register
+*/
+#define MII_SR_T4C  0x8000         /* 100BASE-T4 capable */
+#define MII_SR_TXFD 0x4000         /* 100BASE-TX Full Duplex capable */
+#define MII_SR_TXHD 0x2000         /* 100BASE-TX Half Duplex capable */
+#define MII_SR_TFD  0x1000         /* 10BASE-T Full Duplex capable */
+#define MII_SR_THD  0x0800         /* 10BASE-T Half Duplex capable */
+#define MII_SR_ASSC 0x0020         /* Auto Speed Selection Complete*/
+#define MII_SR_RFD  0x0010         /* Remote Fault Detected */
+#define MII_SR_ANC  0x0008         /* Auto Negotiation capable */
+#define MII_SR_LKS  0x0004         /* Link Status */
+#define MII_SR_JABD 0x0002         /* Jabber Detect */
+#define MII_SR_XC   0x0001         /* Extended Capabilities */
+
+/*
+** MII Management Auto Negotiation Advertisement Register
+*/
+#define MII_ANA_TAF  0x03e0        /* Technology Ability Field */
+#define MII_ANA_T4AM 0x0200        /* T4 Technology Ability Mask */
+#define MII_ANA_TXAM 0x0180        /* TX Technology Ability Mask */
+#define MII_ANA_FDAM 0x0140        /* Full Duplex Technology Ability Mask */
+#define MII_ANA_HDAM 0x02a0        /* Half Duplex Technology Ability Mask */
+#define MII_ANA_100M 0x0380        /* 100Mb Technology Ability Mask */
+#define MII_ANA_10M  0x0060        /* 10Mb Technology Ability Mask */
+#define MII_ANA_CSMA 0x0001        /* CSMA-CD Capable */
+
+/*
+** MII Management Auto Negotiation Remote End Register
+*/
+#define MII_ANLPA_NP   0x8000      /* Next Page (Enable) */
+#define MII_ANLPA_ACK  0x4000      /* Remote Acknowledge */
+#define MII_ANLPA_RF   0x2000      /* Remote Fault */
+#define MII_ANLPA_TAF  0x03e0      /* Technology Ability Field */
+#define MII_ANLPA_T4AM 0x0200      /* T4 Technology Ability Mask */
+#define MII_ANLPA_TXAM 0x0180      /* TX Technology Ability Mask */
+#define MII_ANLPA_FDAM 0x0140      /* Full Duplex Technology Ability Mask */
+#define MII_ANLPA_HDAM 0x02a0      /* Half Duplex Technology Ability Mask */
+#define MII_ANLPA_100M 0x0380      /* 100Mb Technology Ability Mask */
+#define MII_ANLPA_10M  0x0060      /* 10Mb Technology Ability Mask */
+#define MII_ANLPA_CSMA 0x0001      /* CSMA-CD Capable */
+#define MII_ANLPA_PAUS 0x0400 
+
+/*
+ * Model-specific PHY registers
+ *
+ * Note: Only the BCM5201 is described here for now. I'll add the 5400 once
+ *       I see a machine using it in real world.
+ */
+
+/* Supported PHYs (phy_type field ) */
+#define PHY_B5400	5400
+#define PHY_B5201	5201
+#define PHY_UNKNOWN	0
+
+/* Identification (for multi-PHY) */
+#define MII_BCM5201_OUI                         0x001018
+#define MII_BCM5201_MODEL                       0x21
+#define MII_BCM5201_REV                         0x01
+#define MII_BCM5201_ID                          ((MII_BCM5201_OUI << 10) | (MII_BCM5201_MODEL << 4))
+#define MII_BCM5201_MASK                        0xfffffff0
+#define MII_BCM5400_OUI                         0x000818
+#define MII_BCM5400_MODEL                       0x04
+#define MII_BCM5400_REV                         0x01
+#define MII_BCM5400_ID                          ((MII_BCM5400_OUI << 10) | (MII_BCM5400_MODEL << 4))
+#define MII_BCM5400_MASK                        0xfffffff0
+
+/* BCM5201 AUX STATUS register */
+#define MII_BCM5201_AUXCTLSTATUS		0x18
+#define MII_BCM5201_AUXCTLSTATUS_DUPLEX		0x0001
+#define MII_BCM5201_AUXCTLSTATUS_SPEED		0x0002
+
+/* MII BCM5201 MULTIPHY interrupt register */
+#define MII_BCM5201_INTERRUPT			0x1A
+#define MII_BCM5201_INTERRUPT_INTENABLE		0x4000
+
+#define MII_BCM5201_AUXMODE2			0x1B
+#define MII_BCM5201_AUXMODE2_LOWPOWER		0x0008
+
+#define MII_BCM5201_MULTIPHY                    0x1E
+
+/* MII BCM5201 MULTIPHY register bits */
+#define MII_BCM5201_MULTIPHY_SERIALMODE         0x0002
+#define MII_BCM5201_MULTIPHY_SUPERISOLATE       0x0008
+
+
+
+	/*
+	 * DMA descriptors
+	 */
+
+
+/* 
+ * Descriptor counts and buffer sizes
+ */
+#define NTX			64		/* must be power of 2 */
+#define NTX_CONF		GM_TX_RING_SZ_64
+#define NRX			64		/* must be power of 2 */
+#define NRX_CONF		GM_RX_RING_SZ_64
+#define RX_COPY_THRESHOLD	256
+#define GMAC_BUFFER_ALIGN	32		/* Align on a cache line */
+#define RX_BUF_ALLOC_SIZE	(ETH_FRAME_LEN + GMAC_BUFFER_ALIGN + 2)
+#define RX_OFFSET		2
+
+/*
+ * Definitions of Rx and Tx descriptors
+ */
+
+struct gmac_dma_desc {
+	unsigned int	size;		/* data size and OWN bit */
+	unsigned int	flags;		/* flags */
+	unsigned int	lo_addr;	/* phys addr, low 32 bits */
+	unsigned int	hi_addr;
+};
+
+/*
+ * Rx bits
+ */
+ 
+/* Bits in size */
+#define RX_SZ_OWN		0x80000000	/* 1 = owned by chip */
+#define RX_SZ_MASK		0x7FFF0000
+#define RX_SZ_SHIFT		16
+#define RX_SZ_CKSUM_MASK	0x0000FFFF
+
+/* Bits in flags */
+#define RX_FL_CRC_ERROR		0x40000000
+#define RX_FL_ALT_ADDR		0x20000000	/* Packet rcv. from alt MAC address */
+
+/* 
+ * Tx bits
+ */
+
+/* Bits in size */
+#define TX_SZ_MASK		0x00007FFF
+#define TX_SZ_CRC_MASK		0x00FF8000
+#define TX_SZ_CRC_STUFF		0x1F000000
+#define TX_SZ_CRC_ENABLE	0x20000000
+#define TX_SZ_EOP		0x40000000
+#define TX_SZ_SOP		0x80000000
+/* Bits in flags */
+#define TX_FL_INTERRUPT		0x00000001
+#define TX_FL_NO_CRC		0x00000002
+
+	/*
+	 * Other stuffs
+	 */
+	 
+struct gmac {
+	volatile unsigned int		*regs;	/* hardware registers, virtual addr */
+	volatile unsigned int		*sysregs;
+	struct device			*dev;
+	unsigned long			tx_desc_page;	/* page for DMA descriptors */
+	unsigned long			rx_desc_page;	/* page for DMA descriptors */
+	volatile struct			gmac_dma_desc *rxring;
+	struct sk_buff			*rx_buff[NRX];
+	int				next_rx;
+	volatile struct	gmac_dma_desc	*txring;
+	struct sk_buff			*tx_buff[NTX];
+	int				next_tx;
+	int				tx_gone;
+	int				phy_addr;
+	unsigned int			phy_id;
+	int				phy_type;
+	int				phy_status;	/* Cached PHY status */
+	int				full_duplex;	/* Current set to full duplex */
+	struct net_device_stats		stats;
+	u8				pci_bus;
+	u8				pci_devfn;
+	int				opened;
+};
+
+
+/* Register access macros. We hope the preprocessor will be smart enough
+ * to optimize them into one single access instruction
+ */
+#define GM_OUT(reg, v)		(((reg) & REG_SZ_32) ? out_le32(gm->regs + \
+					(((reg) & REG_MASK)>>2), (v))  \
+				: (((reg) & REG_SZ_16) ? out_le16((volatile u16 *) \
+					(gm->regs + (((reg) & REG_MASK)>>2)), (v))  \
+				: out_8((volatile u8 *)(gm->regs + \
+					(((reg) & REG_MASK)>>2)), (v))))
+#define GM_IN(reg)		(((reg) & REG_SZ_32) ? in_le32(gm->regs + \
+					(((reg) & REG_MASK)>>2))  \
+				: (((reg) & REG_SZ_16) ? in_le16((volatile u16 *) \
+					(gm->regs + (((reg) & REG_MASK)>>2)))  \
+				: in_8((volatile u8 *)(gm->regs + \
+					(((reg) & REG_MASK)>>2)))))
+#define GM_BIS(r, v)		GM_OUT((r), GM_IN(r) | (v))
+#define GM_BIC(r, v)		GM_OUT((r), GM_IN(r) & ~(v))
+
+/* Wrapper to alloc_skb to test various alignements */
+#define GMAC_ALIGNED_RX_SKB_ADDR(addr) \
+        ((((unsigned long)(addr) + GMAC_BUFFER_ALIGN - 1) & \
+        ~(GMAC_BUFFER_ALIGN - 1)) - (unsigned long)(addr))
+        
+static inline struct sk_buff *
+gmac_alloc_skb(unsigned int length, int gfp_flags)
+{
+	struct sk_buff *skb;
+
+	skb = alloc_skb(length + GMAC_BUFFER_ALIGN, gfp_flags);
+	if(skb) {
+		int offset = GMAC_ALIGNED_RX_SKB_ADDR(skb->data);
+
+		if(offset)
+			skb_reserve(skb, offset);
+	}
+	return skb;
+}
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/hamradio/baycom_epp.c linux.17p18/drivers/net/hamradio/baycom_epp.c
--- linux.vanilla/drivers/net/hamradio/baycom_epp.c	Fri Apr 21 12:46:17 2000
+++ linux.17p18/drivers/net/hamradio/baycom_epp.c	Tue Aug  1 07:59:40 2000
@@ -51,12 +51,14 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/processor.h>
+#include <asm/uaccess.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/netdevice.h>
 #include <linux/if_arp.h>
 //#include <net/ax25dev.h>
 #include <linux/kmod.h>
+#include <linux/init.h>
 #include <linux/hdlcdrv.h>
 #include <linux/baycom.h>
 #include <linux/soundmodem.h>
@@ -70,56 +72,6 @@
 
 /* --------------------------------------------------------------------- */
 
-/*
- * currently this module is supposed to support both module styles, i.e.
- * the old one present up to about 2.1.9, and the new one functioning
- * starting with 2.1.21. The reason is I have a kit allowing to compile
- * this module also under 2.0.x which was requested by several people.
- * This will go in 2.2
- */
-#include <linux/version.h>
-
-#if LINUX_VERSION_CODE >= 0x20100
-#include <asm/uaccess.h>
-#else
-#include <asm/segment.h>
-#include <linux/mm.h>
-
-#undef put_user
-#undef get_user
-
-#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
-#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
-
-extern inline int copy_from_user(void *to, const void *from, unsigned long n)
-{
-        int i = verify_area(VERIFY_READ, from, n);
-        if (i)
-                return i;
-        memcpy_fromfs(to, from, n);
-        return 0;
-}
-
-extern inline int copy_to_user(void *to, const void *from, unsigned long n)
-{
-        int i = verify_area(VERIFY_WRITE, to, n);
-        if (i)
-                return i;
-        memcpy_tofs(to, from, n);
-        return 0;
-}
-#endif
-
-#if LINUX_VERSION_CODE >= 0x20123
-#include <linux/init.h>
-#else
-#define __init
-#define __initdata
-#define __initfunc(x) x
-#endif
-
-/* --------------------------------------------------------------------- */
-
 #define BAYCOM_DEBUG
 #define BAYCOM_MAGIC 19730510
 
@@ -455,12 +407,8 @@
 	sprintf(portarg, "%ld", bc->pdev->port->base);
 	printk(KERN_DEBUG "%s: %s -s -p %s -m %s\n", bc_drvname, eppconfig_path, portarg, modearg);
 
-        for (i = 0; i < current->files->max_fds; i++ )
-		if (current->files->fd[i]) 
-			close(i);
-        set_fs(KERNEL_DS);      /* Allow execve args to be in kernel space. */
-        current->uid = current->euid = current->fsuid = 0;
-        if (execve(eppconfig_path, argv, envp) < 0) {
+        i = exec_usermodehelper(eppconfig_path, argv, envp);
+        if (i < 0) {
                 printk(KERN_ERR "%s: failed to exec %s -s -p %s -m %s, errno = %d\n",
                        bc_drvname, eppconfig_path, portarg, modearg, errno);
                 return -errno;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/hd64570.h linux.17p18/drivers/net/hd64570.h
--- linux.vanilla/drivers/net/hd64570.h	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/hd64570.h	Thu Aug 17 17:48:22 2000
@@ -203,7 +203,7 @@
 #define MD2_NRZI      0x20	/* NRZI mode */
 #define MD2_LOOPBACK  0x03      /* Local data Loopback */
 
-#define CTL_RTS	      0x01
+#define CTL_NORTS     0x01
 #define CTL_IDLE      0x10	/* Transmit an idle pattern */
 #define CTL_UDRNC     0x20	/* Idle after CRC or FCS+flag transmition */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/hd6457x.c linux.17p18/drivers/net/hd6457x.c
--- linux.vanilla/drivers/net/hd6457x.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/hd6457x.c	Tue Aug  1 07:59:45 2000
@@ -342,7 +342,7 @@
 	
 #ifdef DEBUG_PKT
 				printk(KERN_DEBUG "%s RX:", port->hdlc.name);
-				for (i=920; i<skb->len; i++)
+				for (i=0; i<skb->len; i++)
 					printk(" %02X", skb->data[i]);
 				printk("\n");
 #endif
@@ -406,7 +406,7 @@
 	u8 stat;
 
 #ifndef ALL_PAGES_ALWAYS_MAPPED
-	u8 page = get_page(card);
+	u8 page = sca_get_page(card);
 #endif
   
 	while((stat = sca_intr_status(card)) != 0) {
@@ -606,7 +606,7 @@
 #ifdef DEBUG_RINGS
 	default:
 #if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
-		page=get_page(card);
+		page=sca_get_page(card);
 		openwin(card, 0);
 #endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/hdlc.c linux.17p18/drivers/net/hdlc.c
--- linux.vanilla/drivers/net/hdlc.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/hdlc.c	Tue Aug  1 18:11:04 2000
@@ -41,7 +41,7 @@
 #ifndef MODULE
 static int version_printed=0;
 #endif
-static const char* version = "HDLC support routines revision: 1.0-pre9";
+static const char* version = "HDLC support routines revision: 1.0";
 
 
 #define CISCO_MULTICAST         0x8f    /* Cisco multicast address */
@@ -69,7 +69,10 @@
 	
 	skb_push(skb, sizeof(hdlc_header));
 	data=(hdlc_header*)skb->data;
-	data->address = CISCO_MULTICAST;
+	if (type == CISCO_KEEPALIVE)
+		data->address = CISCO_MULTICAST;
+	else
+		data->address = CISCO_UNICAST;
 	data->control = 0;
 	data->protocol = htons(type);
 	
@@ -139,9 +142,11 @@
 #endif
 
 	case CISCO_KEEPALIVE:
-		if (skb->len != sizeof(cisco_packet)) {
+		if (skb->len != CISCO_PACKET_LEN && 
+		    skb->len != CISCO_BIG_PACKET_LEN) {
 			printk(KERN_INFO "%s: Invalid length of Cisco "
-			       "control packet\n", hdlc->name);
+			       "control packet (%d bytes)\n", hdlc->name, 
+			       skb->len);
 			goto rx_error;
 		}
 
@@ -180,11 +185,17 @@
 	  
 		case CISCO_KEEPALIVE_REQ:
 			hdlc->lmi.rxseq = ntohl(cisco_data->par1);
-			if (hdlc->lmi.rxseq == hdlc->lmi.txseq) {
+			if (ntohl(cisco_data->par2) == hdlc->lmi.txseq) {
 				hdlc->lmi.last_poll = jiffies;
-				if (!(hdlc->lmi.state & LINK_STATE_RELIABLE))
-					printk(KERN_INFO "%s: Link up\n",
-					       hdlc->name);
+				if (!(hdlc->lmi.state & LINK_STATE_RELIABLE)) {
+					u32 sec, min, hrs, days;
+					sec = ntohl(cisco_data->time)/1000;
+					min = sec / 60; sec -= min * 60;
+					hrs = min / 60; min -= hrs * 60;
+					days = hrs / 24; hrs -= days * 24;
+					printk(KERN_INFO "%s: Link up (peer uptime %ud%uh%um%us)\n",
+					       hdlc->name, days, hrs, min, sec);
+				}
 				hdlc->lmi.state |= LINK_STATE_RELIABLE;
 			}
 
@@ -867,10 +878,6 @@
 	if (hdlc->mode==MODE_NONE)
 		return -ENOSYS;
 
-	result=hdlc->open(hdlc);
-	if (result)
-		return result;
-  
 	memset(&(hdlc->stats), 0, sizeof(struct net_device_stats));
 
 	if (mode_is(hdlc, MODE_FR | MODE_SOFT) ||
@@ -884,10 +891,31 @@
 		dev->do_ioctl = hdlc_ioctl;
 		hdlc->pppdev.sppp.pp_flags&=~PP_CISCO;
 		dev->type=ARPHRD_PPP;
-		sppp_open(dev);
+		result = sppp_open(dev);
+		if (result) {
+			sppp_detach(dev);
+			return result;
+		}
 	}
 
-	return 0;
+	result=hdlc->open(hdlc);
+	if (result) {
+		if (mode_is(hdlc, MODE_FR | MODE_SOFT) ||
+		    mode_is(hdlc, MODE_CISCO | MODE_SOFT))
+			fr_cisco_close(hdlc);
+
+		else if (mode_is(hdlc, MODE_PPP | MODE_SOFT)) {
+			sppp_close(dev);
+			sppp_detach(dev);
+			dev->rebuild_header=NULL;
+			dev->change_mtu=hdlc_change_mtu;
+			dev->mtu=HDLC_MAX_MTU;
+			dev->hard_header_len=16;
+		}
+
+	}
+
+	return result;
 }
 
 
@@ -896,6 +924,8 @@
 {
 	hdlc_device *hdlc=dev_to_hdlc(dev);
 
+	hdlc->close(hdlc);
+
 	if (mode_is(hdlc, MODE_FR | MODE_SOFT) ||
 	    mode_is(hdlc, MODE_CISCO | MODE_SOFT))
 		fr_cisco_close(hdlc);
@@ -909,7 +939,6 @@
 		dev->hard_header_len=16;
 	}
 
-	hdlc->close(hdlc);
 	return 0;
 }
 
@@ -1012,15 +1041,9 @@
 
 		switch(mode & ~MODE_SOFT) {
 		case MODE_CISCO:
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
-			break;
-
 		case MODE_PPP:
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
 			break;
-	
+
 		case MODE_FR_ANSI:
 		case MODE_FR_CCITT:
 		case MODE_FR_ANSI  | MODE_DCE:
@@ -1028,13 +1051,14 @@
 			hdlc_to_dev(hdlc)->addr_len=2;
 			*(u16*)hdlc_to_dev(hdlc)->dev_addr=htons(LMI_DLCI);
 			dlci_to_q922(hdlc_to_dev(hdlc)->broadcast, LMI_DLCI);
-			result = hdlc->set_mode ?
-				hdlc->set_mode(hdlc, MODE_HDLC) : 0;
 			break;
 
 		default:
 			return -EINVAL;
 		}
+
+		result = hdlc->set_mode ?
+			hdlc->set_mode(hdlc, MODE_HDLC) : 0;
 	}
 
 	if (result)
@@ -1043,6 +1067,8 @@
 	hdlc->mode=mode;
 	if (mode_is(hdlc, MODE_PPP))
 		hdlc_to_dev(hdlc)->type=ARPHRD_PPP;
+	if (mode_is(hdlc, MODE_X25))
+		hdlc_to_dev(hdlc)->type=ARPHRD_X25;
 	else if (mode_is(hdlc, MODE_FR))
 		hdlc_to_dev(hdlc)->type=ARPHRD_FRAD;
 	else			/* Conflict - raw HDLC and Cisco */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/hostess_sv11.c linux.17p18/drivers/net/hostess_sv11.c
--- linux.vanilla/drivers/net/hostess_sv11.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/hostess_sv11.c	Wed Aug 16 21:42:30 2000
@@ -308,6 +308,7 @@
 	if(z8530_init(dev)!=0)
 	{
 		printk(KERN_ERR "Z8530 series device not found.\n");
+		restore_flags(flags);
 		goto dmafail2;
 	}
 	z8530_channel_load(&dev->chanB, z8530_dead_port);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/hydra.c linux.17p18/drivers/net/hydra.c
--- linux.vanilla/drivers/net/hydra.c	Fri Apr 21 12:46:17 2000
+++ linux.17p18/drivers/net/hydra.c	Wed Aug 16 21:42:30 2000
@@ -3,7 +3,7 @@
 /* also some code & lots of fixes by Timo Rossi (trossi@cc.jyu.fi)          */
 
 /* The code is mostly based on the linux/68k Ariadne driver                 */
-/* copyrighted by Geert Uytterhoeven (Geert.Uytterhoeven@cs.kuleuven.ac.be) */
+/* copyrighted by Geert Uytterhoeven (geert@linux-m68k.org)                 */
 /* and Peter De Schrijver (Peter.DeSchrijver@linux.cc.kuleuven.ac.be)       */
 
 /* This file is subject to the terms and conditions of the GNU General      */
@@ -14,6 +14,10 @@
 /* NS8390 NIC (network interface controller) clone, 16 or 64K on-board RAM  */
 /* and 10BASE-2 (thin coax) and AUI connectors.                             */
 
+/* Changes:								    */
+/* Arnaldo Carvalho de Melo <acme@conectiva.com.br> - 08/15/2000	    */
+/* - check resource allocation in hydra_probe				    */
+
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -183,6 +187,10 @@
 			init_etherdev(dev, 0);
 	    
 			dev->priv = kmalloc(sizeof(struct hydra_private), GFP_KERNEL);
+
+			if (!dev->priv)
+				return -ENOMEM;
+
 			priv = (struct hydra_private *)dev->priv;
 			memset(priv, 0, sizeof(struct hydra_private));
 	    
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/Makefile linux.17p18/drivers/net/lmc/Makefile
--- linux.vanilla/drivers/net/lmc/Makefile	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/Makefile	Tue Aug  1 07:59:41 2000
@@ -6,13 +6,13 @@
 
 ifeq ($(CONFIG_LANMEDIA),y)
     O_TARGET := lmc.o
-    O_OBJS = lmc_debug.o lmc_media.o lmc_main.o
+    O_OBJS = lmc_debug.o lmc_media.o lmc_main.o lmc_proto.o
 else
   ifeq ($(CONFIG_LANMEDIA),m)
     MOD_LIST_NAME := NET_MODULES
     M_OBJS := lmc.o
     O_TARGET := lmc.o
-    O_OBJS = lmc_debug.o lmc_media.o lmc_main.o
+    O_OBJS = lmc_debug.o lmc_media.o lmc_main.o lmc_proto.o
   endif
 endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc.h linux.17p18/drivers/net/lmc/lmc.h
--- linux.vanilla/drivers/net/lmc/lmc.h	Fri Apr 21 23:18:39 2000
+++ linux.17p18/drivers/net/lmc/lmc.h	Thu Aug 17 18:01:51 2000
@@ -6,7 +6,7 @@
 /*
  * prototypes for everyone
  */
-int lmc_probe(struct device * dev);
+int lmc_probe(struct net_device * dev);
 unsigned lmc_mii_readreg(lmc_softc_t * const sc, unsigned
       			  devaddr, unsigned regno);
 void lmc_mii_writereg(lmc_softc_t * const sc, unsigned devaddr,
@@ -17,6 +17,8 @@
 void lmc_mii_writereg(lmc_softc_t * const, unsigned, unsigned, unsigned);
 void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits);
 void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits);
+
+int lmc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
 
 extern lmc_media_t lmc_ds3_media;
 extern lmc_media_t lmc_ssi_media;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_debug.c linux.17p18/drivers/net/lmc/lmc_debug.c
--- linux.vanilla/drivers/net/lmc/lmc_debug.c	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/lmc_debug.c	Tue Aug  1 07:59:41 2000
@@ -1,6 +1,10 @@
 
 #include <linux/types.h>
 #include <linux/sched.h>
+#include <linux/netdevice.h>
+#include <linux/interrupt.h>
+#include <linux/version.h>
+#include "lmc_ver.h"
 #include "lmc_debug.h"
 
 /*
@@ -45,20 +49,20 @@
 #endif
 }
 
-#ifdef DEBUG
-u_int32_t lmcEventLogIndex = 0;
-u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
-#endif
+inline void lmc_trace(struct net_device *dev, char *msg){
+#ifdef LMC_TRACE
+    unsigned long j = jiffies + 3; /* Wait for 50 ms */
 
-void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
-{
-#ifdef DEBUG
-  lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
-  lmcEventLogBuf[lmcEventLogIndex++] = arg2;
-  lmcEventLogBuf[lmcEventLogIndex++] = arg3;
-  lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
-
-  lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
+    if(in_interrupt()){
+        printk("%s: * %s\n", dev->name, msg);
+//        while(jiffies < j+10)
+//            ;
+    }
+    else {
+        printk("%s: %s\n", dev->name, msg);
+        while(jiffies < j)
+            schedule();
+    }
 #endif
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_debug.h linux.17p18/drivers/net/lmc/lmc_debug.h
--- linux.vanilla/drivers/net/lmc/lmc_debug.h	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/lmc_debug.h	Tue Aug  1 07:59:41 2000
@@ -11,40 +11,7 @@
 #define LMC_CONSOLE_LOG(x,y,z)
 #endif
 
-
-
-/* Debug --- Event log definitions --- */
-/* EVENTLOGSIZE*EVENTLOGARGS needs to be a power of 2 */
-#define LMC_EVENTLOGSIZE 512	/* number of events in eventlog */
-#define LMC_EVENTLOGARGS 4		/* number of args for each event */
-
-/* event indicators */
-#define LMC_EVENT_XMT           1
-#define LMC_EVENT_XMTEND        2
-#define LMC_EVENT_XMTINT        3
-#define LMC_EVENT_RCVINT        4
-#define LMC_EVENT_RCVEND        5
-#define LMC_EVENT_INT           6
-#define LMC_EVENT_XMTINTTMO     7
-#define LMC_EVENT_XMTPRCTMO     8
-#define LMC_EVENT_INTEND        9
-#define LMC_EVENT_RESET1       10
-#define LMC_EVENT_RESET2       11
-#define LMC_EVENT_FORCEDRESET  12
-#define LMC_EVENT_WATCHDOG     13
-#define LMC_EVENT_BADPKTSURGE  14
-
-
-#ifdef DEBUG
-extern u_int32_t lmcEventLogIndex;
-extern u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
-#define LMC_EVENT_LOG(x, y, z) lmcEventLog((x), (y), (z))
-#else
-#define LMC_EVENT_LOG(x,y,z)
-#endif /* end ifdef _DBG_EVENTLOG */
-
-
 void lmcConsoleLog(char *type, unsigned char *ucData, int iLen);
-void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3);
+inline void lmc_trace(struct net_device *dev, char *msg);
 
 #endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_ioctl.h linux.17p18/drivers/net/lmc/lmc_ioctl.h
--- linux.vanilla/drivers/net/lmc/lmc_ioctl.h	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/lmc_ioctl.h	Tue Aug  1 07:59:41 2000
@@ -1,6 +1,6 @@
 #ifndef _LMC_IOCTL_H_
 #define _LMC_IOCTL_H_
-/*	$Id: lmc_ioctl.h,v 1.9 2000/01/21 13:29:47 asj Exp $	*/
+/*	$Id: lmc_ioctl.h,v 1.18 2000/06/06 08:32:12 asj Exp $	*/
 
  /*
   * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
@@ -16,22 +16,20 @@
   * of the GNU Public License version 2, incorporated herein by reference.
   */
 
-#define LMCIOCGINFO         SIOCDEVPRIVATE+3 /* get current state */
-#define LMCIOCSINFO         SIOCDEVPRIVATE+4 /* set state to user values */
-#define LMCIOCSKEEPALIVE    SIOCDEVPRIVATE+5 /* Turn keepalives on/off */
-#ifdef  LMC_DEBUG_FILE
-#define LMCIOCLEARSTATS LMCIOCSINFO + 1 /* Clear debug stats */
-#endif
-#define LMCIOCGETLMCSTATS       LMCIOCSINFO + 3
-#define LMCIOCCLEARLMCSTATS     LMCIOCSINFO + 4
-#define LMCIOCDUMPEVENTLOG      LMCIOCSINFO + 5
-#define LMCIOCGETXINFO          LMCIOCSINFO + 6
-#define LMCIOCSETCIRCUIT        LMCIOCSINFO + 7
-#define LMCIOCUNUSEDATM         LMCIOCSINFO + 8
-#define LMCIOCRESET             LMCIOCSINFO + 9
-#define LMCIOCT1CONTROL         LMCIOCSINFO + 10
+#define LMCIOCGINFO             SIOCDEVPRIVATE+3 /* get current state */
+#define LMCIOCSINFO             SIOCDEVPRIVATE+4 /* set state to user values */
+#define LMCIOCGETLMCSTATS       SIOCDEVPRIVATE+5
+#define LMCIOCCLEARLMCSTATS     SIOCDEVPRIVATE+6
+#define LMCIOCDUMPEVENTLOG      SIOCDEVPRIVATE+7
+#define LMCIOCGETXINFO          SIOCDEVPRIVATE+8
+#define LMCIOCSETCIRCUIT        SIOCDEVPRIVATE+9
+#define LMCIOCUNUSEDATM         SIOCDEVPRIVATE+10
+#define LMCIOCRESET             SIOCDEVPRIVATE+11
+#define LMCIOCMEDIA             SIOCDEVPRIVATE+12
+#define LMCIOCIFTYPE            SIOCDEVPRIVATE+13
+#define LMCIOCXILINX            SIOCDEVPRIVATE+14
 
-#define LMC_CARDTYPE_UNKNOWN    -1
+#define LMC_CARDTYPE_UNKNOWN            -1
 #define LMC_CARDTYPE_HSSI               1       /* probed card is a HSSI card */
 #define LMC_CARDTYPE_DS3                2       /* probed card is a DS3 card */
 #define LMC_CARDTYPE_SSI                3       /* probed card is a SSI card */
@@ -61,6 +59,13 @@
 #define LMC_CTL_CIRCUIT_TYPE_T1 1
 
 /*
+ * IFTYPE defines
+ */
+#define LMC_PPP         1               /* use sppp interface */
+#define LMC_NET         2               /* use direct net interface */
+#define LMC_RAW         3               /* use direct net interface */
+
+/*
  * These are not in the least IOCTL related, but I want them common.
  */
 /*
@@ -68,10 +73,10 @@
  */
 #define LMC_GEP_INIT		0x01 /* 0: */
 #define LMC_GEP_RESET		0x02 /* 1: */
-#define LMC_GEP_LOAD		0x10 /* 4: */
+#define LMC_GEP_MODE		0x10 /* 4: */
 #define LMC_GEP_DP		0x20 /* 5: */
-#define LMC_GEP_SERIAL		0x40 /* 6: serial out */
-#define LMC_GEP_SERIALCLK	0x80 /* 7: serial clock */
+#define LMC_GEP_DATA		0x40 /* 6: serial out */
+#define LMC_GEP_CLK	        0x80 /* 7: serial clock */
 
 /*
  * HSSI GPIO assignments
@@ -80,12 +85,17 @@
 #define LMC_GEP_HSSI_CLOCK	0x08 /* 3: clock source */
 
 /*
- * T1 GPIO assignments
+ * SSI GPIO assignments
  */
 #define LMC_GEP_SSI_GENERATOR	0x04 /* 2: enable prog freq gen serial i/f */
 #define LMC_GEP_SSI_TXCLOCK	0x08 /* 3: provide clock on TXCLOCK output */
 
 /*
+ * T1 GPIO assigments
+ */
+#define LMC_GEP_T1_INT	        0x08 /* 3: Interupt enable */
+
+/*
  * Common MII16 bits
  */
 #define LMC_MII16_LED0         0x0080
@@ -118,6 +128,7 @@
 #define LMC_MII16_DS3_DLOS	0x0040
 #define LMC_MII16_DS3_CRC	0x1000
 #define LMC_MII16_DS3_SCRAM	0x2000
+#define LMC_MII16_DS3_SCRAM_LARS 0x4000
 
 /* Note: 2 pairs of LEDs where swapped by mistake
  * in Xilinx code for DS3 & DS1 adapters */
@@ -176,7 +187,8 @@
 /*
  * And T1, LMC1200
  */
-#define LMC_MII16_T1_UNUSED1    0x0003
+#define LMC_MII16_T1_UNUSED1            0x0001
+#define LMC_MII16_T1_INVERT             0x0002
 #define LMC_MII16_T1_XOE                0x0004
 #define LMC_MII16_T1_RST                0x0008  /* T1 chip reset - RW */
 #define LMC_MII16_T1_Z                  0x0010  /* output impedance T1=1, E1=0 output - RW */
@@ -224,6 +236,15 @@
 #define LMC_T1F_WRITE       0
 #define LMC_T1F_READ        1
 
+enum lmc_st1f_cmd {
+    lmc_st1f_write = 1,
+    lmc_st1f_read = 2,
+    lmc_st1f_inv = 3,
+    lmc_st1f_amisf = 4,
+    lmc_st1f_frac = 5,
+    lmc_st1f_loopt = 6,
+};
+
 typedef struct lmc_st1f_control {
   int command;
   int address;
@@ -231,9 +252,23 @@
   char *data;
 } lmc_t1f_control;
 
+
+
+enum lmc_xilinx_c {
+    lmc_xilinx_reset = 1,
+    lmc_xilinx_load_prom = 2,
+    lmc_xilinx_load = 3
+};
+
+struct lmc_xilinx_control {
+    enum lmc_xilinx_c command;
+    int len;
+    char *data;
+};
+
 /* ------------------ end T1 defs ------------------- */
 
 #define LMC_MII_LedMask                 0x0780
 #define LMC_MII_LedBitPos               7
 
-#endif
\ No newline at end of file
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_main.c linux.17p18/drivers/net/lmc/lmc_main.c
--- linux.vanilla/drivers/net/lmc/lmc_main.c	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/lmc_main.c	Tue Aug  1 07:59:41 2000
@@ -11,7 +11,7 @@
   * With Help By:
   * David Boggs
   * Ron Crane
-  * Allan Cox
+  * Alan Cox
   *
   * This software may be used and distributed according to the terms
   * of the GNU Public License version 2, incorporated herein by reference.
@@ -36,10 +36,11 @@
   *
   */
 
-/* $Id: lmc_main.c,v 1.24 2000/01/21 13:29:48 asj Exp $ */
+/* $Id: lmc_main.c,v 1.44 2000/06/19 16:53:59 asj Exp $ */
 
-#include <linux/version.h>
 #include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
@@ -50,12 +51,10 @@
 #include <linux/malloc.h>
 #include <linux/interrupt.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
+#include <linux/delay.h>
 #include <asm/segment.h>
-#include <asm/smp.h>
-
-#if LINUX_VERSION_CODE < 0x20155
-#include <linux/bios32.h>
-#endif
+#include <linux/init.h>
 
 #include <linux/in.h>
 #include <linux/if_arp.h>
@@ -72,64 +71,75 @@
 
 #if LINUX_VERSION_CODE >= 0x20200
 #include <asm/uaccess.h>
-#include <asm/spinlock.h>
-#endif
-
-#ifdef MODULE
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
-#include <linux/module.h>
-#include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
+//#include <asm/spinlock.h>
+#else				/* 2.0 kernel */
+#define ARPHRD_HDLC 513
 #endif
 
 #define DRIVER_MAJOR_VERSION     1
-#define DRIVER_MINOR_VERSION    33
-#define DRIVER_SUB_VERSION       1
+#define DRIVER_MINOR_VERSION    34
+#define DRIVER_SUB_VERSION       7
 
 #define DRIVER_VERSION  ((DRIVER_MAJOR_VERSION << 8) + DRIVER_MINOR_VERSION)
 
-#include "lmc.h"
 #include "lmc_ver.h"
+#include "lmc.h"
 #include "lmc_var.h"
 #include "lmc_ioctl.h"
 #include "lmc_debug.h"
+#include "lmc_proto.h"
+
 
 static int Lmc_Count = 0;
-static struct device *Lmc_root_dev = NULL;
+static struct net_device *Lmc_root_dev = NULL;
 static u8 cards_found = 0;
 
 static int lmc_first_load = 0;
 
-int lmc_probe_fake(struct device *dev);
-static struct device *lmc_probe1(struct device *dev, int ioaddr, int irq,
-				 int chip_id, int subdevice, int board_idx);
-static int lmc_start_xmit(struct sk_buff *skb, struct device *dev);
-static int lmc_rx(struct device *dev);
-static int lmc_open(struct device *dev);
-static int lmc_close(struct device *dev);
-static struct enet_statistics *lmc_get_stats(struct device *dev);
+int LMC_PKT_BUF_SZ = 1542;
+
+#if LINUX_VERSION_CODE >= 0x20363
+#ifdef MODULE
+static struct pci_device_id lmc_pci_tbl[] __devinitdata = {
+    { 0x1011, 0x009, 0x1376, PCI_ANY_ID, 0, 0, 0},
+    { 0, },
+};
+
+MODULE_DEVICE_TABLE(pci, lmc_pci_tbl);
+#endif
+#endif
+
+
+int lmc_probe_fake(struct net_device *dev);
+static struct net_device *lmc_probe1(struct net_device *dev, unsigned long ioaddr, unsigned int irq,
+				 int chip_id, int subdevice, int board_idx, void *pci_dev);
+static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int lmc_start_xmit(struct sk_buff *skb, struct net_device *dev);
+static int lmc_rx (struct net_device *dev);
+static int lmc_open(struct net_device *dev);
+static int lmc_close(struct net_device *dev);
+static struct enet_statistics *lmc_get_stats(struct net_device *dev);
 static void lmc_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static int lmc_ioctl(struct device *dev, struct ifreq *ifr, int cmd);
-static int lmc_set_config(struct device *dev, struct ifmap *map);
-static void lmc_initcsrs(lmc_softc_t * const, u32, size_t);
+static int lmc_set_config(struct net_device *dev, struct ifmap *map);
+static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, size_t csr_size);
 static void lmc_softreset(lmc_softc_t * const);
-static void lmc_running_reset(struct device *dev);
-static int lmc_ifdown(struct device * const);
+static void lmc_running_reset(struct net_device *dev);
+static int lmc_ifdown(struct net_device * const);
 static void lmc_watchdog(unsigned long data);
-static int lmc_init(struct device * const);
+static int lmc_init(struct net_device * const);
 static void lmc_reset(lmc_softc_t * const sc);
 static void lmc_dec_reset(lmc_softc_t * const sc);
-static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base,size_t csr_size);
+#if LINUX_VERSION_CODE >= 0x20363
+static void lmc_driver_timeout(struct net_device *dev);
+int lmc_setup(void);
+#endif
+
 
 /*
  * linux reserves 16 device specific IOCTLs.  We call them
  * LMCIOC* to control various bits of our world.
  */
-static int lmc_ioctl (struct device *dev, struct ifreq *ifr, int cmd) /*fold00*/
+int lmc_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd) /*fold00*/
 {
     lmc_softc_t *sc;
     lmc_ctl_t ctl;
@@ -143,23 +153,25 @@
 
     sc = dev->priv;
 
+    lmc_trace(dev, "lmc_ioctl in");
+
     /*
      * Most functions mess with the structure
      * Disable interupts while we do the polling
      */
-    spin_lock_irqsave(&sc->lmc_lock, flags);
+    LMC_SPIN_LOCK_IRQSAVE(sc);
 
     switch (cmd) {
         /*
          * Return current driver state.  Since we keep this up
          * To date internally, just copy this out to the user.
          */
-    case LMCIOCGINFO:
+    case LMCIOCGINFO: /*fold01*/
         LMC_COPY_TO_USER(ifr->ifr_data, &sc->ictl, sizeof (lmc_ctl_t));
         ret = 0;
         break;
 
-    case LMCIOCSINFO:
+    case LMCIOCSINFO: /*fold01*/
         sp = &((struct ppp_device *) dev)->sppp;
         if (!suser ()) {
             ret = -EPERM;
@@ -177,6 +189,10 @@
 
         if(ctl.crc_length != sc->ictl.crc_length) {
             sc->lmc_media->set_crc_length(sc, ctl.crc_length);
+	    if (sc->ictl.crc_length == LMC_CTL_CRC_LENGTH_16)
+		sc->TxDescriptControlInit |=  LMC_TDES_ADD_CRC_DISABLE;
+	    else
+		sc->TxDescriptControlInit &= ~LMC_TDES_ADD_CRC_DISABLE;
         }
 
         if (ctl.keepalive_onoff == LMC_CTL_OFF)
@@ -186,7 +202,39 @@
 
         ret = 0;
         break;
-    case LMCIOCGETXINFO:
+
+    case LMCIOCIFTYPE: /*fold01*/
+        {
+            u_int16_t	old_type = sc->if_type;
+            u_int16_t	new_type;
+
+	    if (!suser ()) {
+		ret = -EPERM;
+		break;
+	    }
+
+	    LMC_COPY_FROM_USER(&new_type, ifr->ifr_data, sizeof(u_int16_t));
+
+            
+	    if (new_type == old_type)
+	    {
+		ret = 0 ;
+		break;				/* no change */
+            }
+            
+            lmc_proto_close(sc);
+            lmc_proto_detach(sc);
+
+            sc->if_type = new_type;
+//            lmc_proto_init(sc);
+            lmc_proto_attach(sc);
+            lmc_proto_open(sc);
+
+	    ret = 0 ;
+	    break ;
+	}
+
+    case LMCIOCGETXINFO: /*fold01*/
         sc->lmc_xinfo.Magic0 = 0xBEEFCAFE;
 
         sc->lmc_xinfo.PciCardType = sc->lmc_cardtype;
@@ -196,7 +244,7 @@
         sc->lmc_xinfo.DriverSubVersion = DRIVER_SUB_VERSION;
         sc->lmc_xinfo.XilinxRevisionNumber =
             lmc_mii_readreg (sc, 0, 3) & 0xf;
-        sc->lmc_xinfo.MaxFrameSize = PKT_BUF_SZ;
+        sc->lmc_xinfo.MaxFrameSize = LMC_PKT_BUF_SZ;
         sc->lmc_xinfo.link_status = sc->lmc_media->get_link_status (sc);
         sc->lmc_xinfo.mii_reg16 = lmc_mii_readreg (sc, 0, 16);
 
@@ -208,7 +256,7 @@
 
         break;
 
-    case LMCIOCGETLMCSTATS:
+    case LMCIOCGETLMCSTATS: /*fold01*/
         if (sc->lmc_cardtype == LMC_CARDTYPE_T1){
             lmc_mii_writereg (sc, 0, 17, T1FRAMER_FERR_LSB);
             sc->stats.framingBitErrorCount +=
@@ -239,7 +287,7 @@
         ret = 0;
         break;
 
-    case LMCIOCCLEARLMCSTATS:
+    case LMCIOCCLEARLMCSTATS: /*fold01*/
         if (!suser ()){
             ret = -EPERM;
             break;
@@ -253,7 +301,7 @@
         ret = 0;
         break;
 
-    case LMCIOCSETCIRCUIT:
+    case LMCIOCSETCIRCUIT: /*fold01*/
         if (!suser ()){
             ret = -EPERM;
             break;
@@ -271,7 +319,7 @@
 
         break;
 
-    case LMCIOCRESET:
+    case LMCIOCRESET: /*fold01*/
         if (!suser ()){
             ret = -EPERM;
             break;
@@ -282,31 +330,289 @@
         lmc_running_reset (dev);
         printk (" REG16 after reset +%04x\n", lmc_mii_readreg (sc, 0, 16));
 
-        LMC_EVENT_LOG(LMC_EVENT_FORCEDRESET, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16));
-
         ret = 0;
         break;
+    case LMCIOCMEDIA: /*fold01*/
+        ret = sc->lmc_media->ioctl(sc, ifr->ifr_data);
+        break;
+    case LMCIOCXILINX: /*fold01*/
+        {
+            struct lmc_xilinx_control xc; /*fold02*/
 
-#ifdef DEBUG
-    case LMCIOCDUMPEVENTLOG:
-        LMC_COPY_TO_USER(ifr->ifr_data, &lmcEventLogIndex, sizeof (u32));
-        LMC_COPY_TO_USER(ifr->ifr_data + sizeof (u32), lmcEventLogBuf, sizeof (lmcEventLogBuf));
+            if (!suser ()){
+                ret = -EPERM;
+                break;
+            }
+
+            /*
+             * Stop the xwitter whlie we restart the hardware
+             */
+            LMC_XMITTER_BUSY(dev);
+
+            LMC_COPY_FROM_USER(&xc, ifr->ifr_data, sizeof (struct lmc_xilinx_control));
+            switch(xc.command){
+            case lmc_xilinx_reset: /*fold02*/
+                {
+                    u16 mii;
+                    mii = lmc_mii_readreg (sc, 0, 16);
+
+                    /*
+                     * Make all of them 0 and make input
+                     */
+                    lmc_gpio_mkinput(sc, 0xff);
+
+                    /*
+                     * make the reset output
+                     */
+                    lmc_gpio_mkoutput(sc, LMC_GEP_RESET);
+
+                    /*
+                     * RESET low to force configuration.  This also forces
+                     * the transmitter clock to be internal, but we expect to reset
+                     * that later anyway.
+                     */
+
+                    sc->lmc_gpio &= ~LMC_GEP_RESET;
+                    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+
+
+                    /*
+                     * hold for more than 10 microseconds
+                     */
+                    udelay(50);
+
+                    sc->lmc_gpio |= LMC_GEP_RESET;
+                    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+
+
+                    /*
+                     * stop driving Xilinx-related signals
+                     */
+                    lmc_gpio_mkinput(sc, 0xff);
+
+                    /* Reset the frammer hardware */
+                    sc->lmc_media->set_link_status (sc, 1);
+                    sc->lmc_media->set_status (sc, NULL);
+//                    lmc_softreset(sc);
+
+                    {
+                        int i;
+                        for(i = 0; i < 5; i++){
+                            lmc_led_on(sc, LMC_DS3_LED0);
+                            mdelay(100);
+                            lmc_led_off(sc, LMC_DS3_LED0);
+                            lmc_led_on(sc, LMC_DS3_LED1);
+                            mdelay(100);
+                            lmc_led_off(sc, LMC_DS3_LED1);
+                            lmc_led_on(sc, LMC_DS3_LED3);
+                            mdelay(100);
+                            lmc_led_off(sc, LMC_DS3_LED3);
+                            lmc_led_on(sc, LMC_DS3_LED2);
+                            mdelay(100);
+                            lmc_led_off(sc, LMC_DS3_LED2);
+                        }
+                    }
+                    
+                    
+
+                    ret = 0x0;
+
+                }
+
+                break;
+            case lmc_xilinx_load_prom: /*fold02*/
+                {
+                    u16 mii;
+                    int timeout = 500000;
+                    mii = lmc_mii_readreg (sc, 0, 16);
+
+                    /*
+                     * Make all of them 0 and make input
+                     */
+                    lmc_gpio_mkinput(sc, 0xff);
+
+                    /*
+                     * make the reset output
+                     */
+                    lmc_gpio_mkoutput(sc,  LMC_GEP_DP | LMC_GEP_RESET);
+
+                    /*
+                     * RESET low to force configuration.  This also forces
+                     * the transmitter clock to be internal, but we expect to reset
+                     * that later anyway.
+                     */
+
+                    sc->lmc_gpio &= ~(LMC_GEP_RESET | LMC_GEP_DP);
+                    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+
+
+                    /*
+                     * hold for more than 10 microseconds
+                     */
+                    udelay(50);
+
+                    sc->lmc_gpio |= LMC_GEP_DP | LMC_GEP_RESET;
+                    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+
+                    /*
+                     * busy wait for the chip to reset
+                     */
+                    while( (le32_to_cpu(LMC_CSR_READ(sc, csr_gp)) & LMC_GEP_INIT) == 0 &&
+                           (timeout-- > 0))
+                        ;
+
+                    /*
+                     * stop driving Xilinx-related signals
+                     */
+                    lmc_gpio_mkinput(sc, 0xff);
+                    ret = 0x0;
+                    break;
+
+                }
+
+            case lmc_xilinx_load: /*fold02*/
+                {
+                    char *data;
+                    int pos;
+                    int timeout = 500000;
+
+                    if(xc.data == 0x0){
+                            ret = -EINVAL;
+                            break;
+                    }
+
+                    data = kmalloc(xc.len, GFP_KERNEL);
+                    if(data == 0x0){
+                            printk(KERN_WARNING "%s: Failed to allocate memory for copy\n", dev->name);
+                            ret = -ENOMEM;
+                            break;
+                    }
+                    
+                    LMC_COPY_FROM_USER(data, xc.data, xc.len);
+
+                    printk("%s: Starting load of data Len: %d at 0x%p == 0x%p\n", dev->name, xc.len, xc.data, data);
+
+                    lmc_gpio_mkinput(sc, 0xff);
+
+                    /*
+                     * Clear the Xilinx and start prgramming from the DEC
+                     */
+
+                    /*
+                     * Set ouput as:
+                     * Reset: 0 (active)
+                     * DP:    0 (active)
+                     * Mode:  1
+                     *
+                     */
+                    sc->lmc_gpio = 0x00;
+                    sc->lmc_gpio &= ~LMC_GEP_DP;
+                    sc->lmc_gpio &= ~LMC_GEP_RESET;
+                    sc->lmc_gpio |=  LMC_GEP_MODE;
+                    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+
+                    lmc_gpio_mkoutput(sc, LMC_GEP_MODE | LMC_GEP_DP | LMC_GEP_RESET);
+
+                    /*
+                     * Wait at least 10 us 20 to be safe
+                     */
+                    udelay(50);
+
+                    /*
+                     * Clear reset and activate programing lines
+                     * Reset: Input
+                     * DP:    Input
+                     * Clock: Output
+                     * Data:  Output
+                     * Mode:  Output
+                     */
+                    lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);
+
+                    /*
+                     * Set LOAD, DATA, Clock to 1
+                     */
+                    sc->lmc_gpio = 0x00;
+                    sc->lmc_gpio |= LMC_GEP_MODE;
+                    sc->lmc_gpio |= LMC_GEP_DATA;
+                    sc->lmc_gpio |= LMC_GEP_CLK;
+                    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+                    
+                    lmc_gpio_mkoutput(sc, LMC_GEP_DATA | LMC_GEP_CLK | LMC_GEP_MODE );
+
+                    /*
+                     * busy wait for the chip to reset
+                     */
+                    while( (le32_to_cpu(LMC_CSR_READ(sc, csr_gp)) & LMC_GEP_INIT) == 0 &&
+                           (timeout-- > 0))
+                        ;
+
+                    printk(KERN_DEBUG "%s: Waited %d for the Xilinx to clear it's memory\n", dev->name, 500000-timeout);
+
+                    for(pos = 0; pos < xc.len; pos++){
+                        switch(data[pos]){
+                        case 0:
+                            sc->lmc_gpio &= ~LMC_GEP_DATA; /* Data is 0 */
+                            break;
+                        case 1:
+                            sc->lmc_gpio |= LMC_GEP_DATA; /* Data is 1 */
+                            break;
+                        default:
+                            printk(KERN_WARNING "%s Bad data in xilinx programing data at %d, got %d wanted 0 or 1\n", dev->name, pos, data[pos]);
+                            sc->lmc_gpio |= LMC_GEP_DATA; /* Assume it's 1 */
+                        }
+                        sc->lmc_gpio &= ~LMC_GEP_CLK; /* Clock to zero */
+                        sc->lmc_gpio |= LMC_GEP_MODE;
+                        LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+                        udelay(1);
+                        
+                        sc->lmc_gpio |= LMC_GEP_CLK; /* Put the clack back to one */
+                        sc->lmc_gpio |= LMC_GEP_MODE;
+                        LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
+                        udelay(1);
+                    }
+                    if((le32_to_cpu(LMC_CSR_READ(sc, csr_gp)) & LMC_GEP_INIT) == 0){
+                        printk(KERN_WARNING "%s: Reprograming FAILED. Needs to be reprogramed. (corrupted data)\n", dev->name);
+                    }
+                    else if((le32_to_cpu(LMC_CSR_READ(sc, csr_gp)) & LMC_GEP_DP) == 0){
+                        printk(KERN_WARNING "%s: Reprograming FAILED. Needs to be reprogramed. (done)\n", dev->name);
+                    }
+                    else {
+                        printk(KERN_DEBUG "%s: Done reprograming Xilinx, %d bits, good luck!\n", dev->name, pos);
+                    }
+
+                    lmc_gpio_mkinput(sc, 0xff);
+                    
+                    sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
+                    lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+
+                    sc->lmc_miireg16 &= ~LMC_MII16_FIFO_RESET;
+                    lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+
+                    kfree(data);
+                    
+                    ret = 0;
+                    
+                    break;
+                }
+            default: /*fold02*/
+                ret = -EBADE;
+                break;
+            }
+
+            LMC_XMITTER_FREE(dev);
+            sc->lmc_txfull = 0;
 
-        ret = 0;
-        break;
-#endif /* end ifdef _DBG_EVENTLOG */
-    case LMCIOCT1CONTROL:
-        if (sc->lmc_cardtype != LMC_CARDTYPE_T1){
-            ret = -EOPNOTSUPP;
-            break;
         }
         break;
-    default:
-        /* If we don't know what to do, give syncppp a shot. */
-        ret = sppp_do_ioctl (dev, ifr, cmd);
+    default: /*fold01*/
+        /* If we don't know what to do, give the protocol a shot. */
+        ret = lmc_proto_ioctl (sc, ifr, cmd);
+        break;
     }
 
-    spin_unlock_irqrestore(&sc->lmc_lock, flags);
+    LMC_SPIN_UNLOCK_IRQRESTORE(sc); /*fold01*/
+
+    lmc_trace(dev, "lmc_ioctl out");
 
     return ret;
 }
@@ -315,29 +621,35 @@
 /* the watchdog process that cruises around */
 static void lmc_watchdog (unsigned long data) /*fold00*/
 {
-    struct device *dev = (struct device *) data;
+    struct net_device *dev = (struct net_device *) data;
     lmc_softc_t *sc;
     int link_status;
     u_int32_t ticks;
-    LMC_SPIN_FLAGS
+    LMC_SPIN_FLAGS;
 
     sc = dev->priv;
 
-    spin_lock_irqsave(&sc->lmc_lock, flags);
+    lmc_trace(dev, "lmc_watchdog in");
+
+    LMC_SPIN_LOCK_IRQSAVE(sc);
+
+    if(sc->check != 0xBEAFCAFE){
+        printk("LMC: Corrupt net_device stuct, breaking out\n");
+        return;
+    }
+
 
     /* Make sure the tx jabber and rx watchdog are off,
      * and the transmit and recieve processes are running.
      */
 
-    LMC_CSR_WRITE (sc, csr_15, 0x00000011);
+    LMC_CSR_WRITE (sc, csr_15, cpu_to_le32(0x00000011));
     sc->lmc_cmdmode |= TULIP_CMD_TXRUN | TULIP_CMD_RXRUN;
-    LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
+    LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(sc->lmc_cmdmode));
 
     if (sc->lmc_ok == 0)
         goto kick_timer;
 
-    LMC_EVENT_LOG(LMC_EVENT_WATCHDOG, LMC_CSR_READ (sc, csr_status), lmc_mii_readreg (sc, 0, 16));
-
     /* --- begin time out check -----------------------------------
      * check for a transmit interrupt timeout
      * Has the packet xmt vs xmt serviced threshold been exceeded */
@@ -354,26 +666,12 @@
              sc->tx_TimeoutInd)
     {
 
-        LMC_EVENT_LOG(LMC_EVENT_XMTINTTMO, LMC_CSR_READ (sc, csr_status), 0);
-
         sc->tx_TimeoutDisplay = 1;
         sc->stats.tx_TimeoutCnt++;
 
         /* DEC chip is stuck, hit it with a RESET!!!! */
         lmc_running_reset (dev);
 
-
-        /* look at receive & transmit process state to make sure they are running */
-        LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
-
-        /* look at: DSR - 02  for Reg 16
-         *                  CTS - 08
-         *                  DCD - 10
-         *                  RI  - 20
-         * for Reg 17
-         */
-        LMC_EVENT_LOG(LMC_EVENT_RESET2, lmc_mii_readreg (sc, 0, 16), lmc_mii_readreg (sc, 0, 17));
-
         /* reset the transmit timeout detection flag */
         sc->tx_TimeoutInd = 0;
         sc->lastlmc_taint_tx = sc->lmc_taint_tx;
@@ -396,7 +694,7 @@
      * Mark it as down.
      */
     if ((link_status == 0) && (sc->last_link_status != 0)) {
-        printk(KERN_WARNING "%s: link down\n", dev->name);
+        printk(KERN_WARNING "%s: hardware/physical link down\n", dev->name);
         sc->last_link_status = 0;
         /* lmc_reset (sc); Why reset??? The link can go down ok */
 
@@ -409,7 +707,7 @@
      * Bring it back up again.
      */
      if (link_status != 0 && sc->last_link_status == 0) {
-         printk(KERN_WARNING "%s: link up\n", dev->name);
+         printk(KERN_WARNING "%s: hardware/physical link up\n", dev->name);
          sc->last_link_status = 1;
          /* lmc_reset (sc); Again why reset??? */
 
@@ -424,7 +722,7 @@
           * --bbraun
           */
 
-         sppp_reopen (dev);
+         lmc_proto_reopen(sc);
 
      }
 
@@ -435,7 +733,29 @@
      * Poke the transmitter to make sure it
      * never stops, even if we run out of mem
      */
-    LMC_CSR_WRITE(sc, csr_rxpoll, 0);
+    LMC_CSR_WRITE(sc, csr_rxpoll, cpu_to_le32(0));
+
+    /*
+     * Check for code that failed
+     * and try and fix it as appropriate
+     */
+    if(sc->failed_ring == 1){
+        /*
+         * Failed to setup the recv/xmit rin
+         * Try again
+         */
+        sc->failed_ring = 0;
+        lmc_softreset(sc);
+    }
+    if(sc->failed_recv_alloc == 1){
+        /*
+         * We failed to alloc mem in the
+         * interupt halder, go through the rings
+         * and rebuild them
+         */
+        sc->failed_recv_alloc = 0;
+        lmc_softreset(sc);
+    }
 
 
     /*
@@ -443,8 +763,8 @@
      */
 kick_timer:
 
-    ticks = LMC_CSR_READ (sc, csr_gp_timer);
-    LMC_CSR_WRITE (sc, csr_gp_timer, 0xffffffffUL);
+    ticks = le32_to_cpu(LMC_CSR_READ (sc, csr_gp_timer));
+    LMC_CSR_WRITE (sc, csr_gp_timer, cpu_to_le32(0xffffffffUL));
     sc->ictl.ticks = 0x0000ffff - (ticks & 0x0000ffff);
 
     /*
@@ -453,58 +773,87 @@
     sc->timer.expires = jiffies + (HZ);
     add_timer (&sc->timer);
 
-    spin_unlock_irqrestore(&sc->lmc_lock, flags);
+    LMC_SPIN_UNLOCK_IRQRESTORE(sc);
+
+    lmc_trace(dev, "lmc_watchdog out");
 
 }
 
-static int lmc_init(struct device * const dev) /*fold00*/
+static int lmc_init(struct net_device * const dev) /*fold00*/
 {
+    lmc_trace(dev, "lmc_init in");
+    lmc_trace(dev, "lmc_init out");
+	
     return 0;
 }
 
 /* This initializes each card from lmc_probe() */
-static struct device *lmc_probe1 (struct device *dev, int ioaddr, int irq, /*fold00*/
-                                  int chip_id, int subdevice, int board_idx)
+static struct net_device *lmc_probe1 (struct net_device *dev, unsigned long ioaddr, unsigned int irq, /*FOLD00*/
+                                  int chip_id, int subdevice, int board_idx, void *pci_dev)
 {
     lmc_softc_t *sc = NULL;
     u_int16_t AdapModelNum;
-
+#if LINUX_VERSION_CODE >= 0x20363
+    struct pci_dev *pdev = pci_dev;
+    dma_addr_t dma_handle;
+#endif
     /*
      * Allocate our own device structure
      */
-
+    
+#if LINUX_VERSION_CODE < 0x20210 /* Changed in 2.2.16 */
     dev = kmalloc (sizeof (struct ppp_device)+8, GFP_KERNEL);
+#else
+    dev = kmalloc (sizeof (struct net_device)+8, GFP_KERNEL);
+#endif
     if (dev == NULL){
         printk (KERN_ERR "lmc: kmalloc for device failed\n");
         return NULL;
     }
-    memset (dev, 0, sizeof (struct ppp_device));
+    memset (dev, 0, sizeof (struct net_device));
 
-	/*
-	 *	Switch to common hdlc%d naming. We name by type not by vendor
-	 */
-    dev->name = (char *) (((u32) (dev)) + sizeof (struct ppp_device));
+#ifndef GCOM
+    /*
+     *	Switch to common hdlc%d naming. We name by type not by vendor
+     */
+#if LINUX_VERSION_CODE < 0x20210
+    dev->name = ((char *) (dev)) + sizeof (struct ppp_device);
+#elif LINUX_VERSION_CODE < 0x20363
+    dev->name = ((char *) (dev)) + sizeof (struct net_device);
+#endif
+
+#if LINUX_VERSION_CODE >= 0x20200
     dev_alloc_name(dev, "hdlc%d");
+#else
+    sprintf(dev->name, "hdlc%d", Lmc_Count);
+#endif
+    
+#else
+    /*
+     * GCOM uses LMC vendor name so that clients can know which card
+     * to attach to.
+     */
+    dev->name = ((char *) (dev)) + sizeof (struct ppp_device);
+    dev_alloc_name(dev, "lmc%d");
+#endif
 
+    lmc_trace(dev, "lmc_probe1 in");
+    
     Lmc_Count++;
 
     if(lmc_first_load == 0){
         printk(KERN_INFO "Lan Media Corporation WAN Driver Version %d.%d.%d\n",DRIVER_MAJOR_VERSION, DRIVER_MINOR_VERSION,DRIVER_SUB_VERSION);
-#ifndef MODULE
-        sync_ppp_init();
-#endif
         lmc_first_load = 1;
     }
-
-
-    /* Initialize the sppp layer */
-    sppp_attach ((struct ppp_device *) dev);
-
+    
     /*
      * Allocate space for the private data structure
      */
-
+#if LINUX_VERSION_CODE >= 0x20363
+    sc = pci_alloc_consistent(pdev, sizeof (lmc_softc_t), &dma_handle);
+#else
     sc = kmalloc (sizeof (lmc_softc_t), GFP_KERNEL);
+#endif
     if (sc == NULL) {
         printk (KERN_WARNING "%s: Cannot allocate memory for device state\n",
                 dev->name);
@@ -514,16 +863,37 @@
     dev->priv = sc;
     sc->lmc_device = dev;
     sc->name = dev->name;
-
+    sc->if_type = LMC_PPP;
+    sc->check = 0xBEAFCAFE;
+#if LINUX_VERSION_CODE >= 0x20363
+    sc->pdev = pdev;
+    sc->sc_dma_handle = dma_handle;
+    sc->sc_dma = (lmc_softc_t *) dma_handle;
+#endif
+    
+    dev->base_addr = ioaddr;
+    dev->irq = irq;
+    /*
+     * This will get the protocol layer ready and do any 1 time init's
+     * Must have a valid sc and dev structure
+     */
+    lmc_proto_init(sc);
+    lmc_proto_attach(sc);
     /* Just fill in the entries for the device */
 
     dev->init = lmc_init;
+    dev->type = ARPHRD_HDLC;
     dev->hard_start_xmit = lmc_start_xmit;
     dev->open = lmc_open;
     dev->stop = lmc_close;
     dev->get_stats = lmc_get_stats;
     dev->do_ioctl = lmc_ioctl;
     dev->set_config = lmc_set_config;
+#if LINUX_VERSION_CODE >= 0x20363
+    dev->tx_timeout = lmc_driver_timeout;
+    dev->watchdog_timeo = (HZ); /* 1 second */
+#endif
+
     /*
      * Why were we changing this???
      dev->tx_queue_len = 100;
@@ -531,18 +901,15 @@
 
     /* Init the spin lock so can call it latter */
 
-    spin_lock_init(&sc->lmc_lock);
+    LMC_SPIN_LOCK_INIT(sc);
 
     LMC_SETUP_20_DEV;
-
-    printk ("%s: detected at %#3x, irq %d\n", dev->name, ioaddr, irq);
-
-    dev->base_addr = ioaddr;
-    dev->irq = irq;
+    
+    printk ("%s: detected at %lx, irq %d\n", dev->name, ioaddr, dev->irq);
 
     if (register_netdev (dev) != 0) {
         printk (KERN_ERR "%s: register_netdev failed.\n", dev->name);
-        sppp_detach (dev);
+        lmc_proto_detach(sc);
         kfree (dev->priv);
         kfree (dev);
         return NULL;
@@ -610,14 +977,14 @@
 
     }
     else {
-        printk ("%s: Model number (%d) miscompare for PCI Subsystem ID = 0x%04x\n",
+        /* Print a warning but not a major failure case */
+        printk (KERN_WARNING "%s: Model number (%d) miscompare for PCI Subsystem ID = 0x%04x\n",
                 dev->name, AdapModelNum, subdevice);
-        return (NULL);
     }
     /*
      * reset clock
      */
-    LMC_CSR_WRITE (sc, csr_gp_timer, 0xFFFFFFFFUL);
+    LMC_CSR_WRITE (sc, csr_gp_timer, cpu_to_le32(0xFFFFFFFFUL));
 
     sc->board_idx = board_idx;
 
@@ -631,6 +998,8 @@
     sc->lmc_ok = 0;
     sc->last_link_status = 0;
 
+    lmc_trace(dev, "lmc_probe1 out");
+
     return dev;
 }
 
@@ -638,19 +1007,29 @@
 /* This is the entry point.  This is what is called immediatly. */
 /* This goes out and finds the card */
 
-int lmc_probe_fake(struct device *dev)
+int lmc_probe_fake(struct net_device *dev) /*fold00*/
 {
     lmc_probe(NULL);
     /* Return 1 to unloaded bogus device */
     return 1;
 }
 
-int lmc_probe (struct device *dev) /*fold00*/
+int lmc_probe (struct net_device *dev) /*fold00*/
 {
     int pci_index = 0;
+#if LINUX_VERSION_CODE >= 0x20155
+    unsigned long pci_ioaddr;
+    unsigned int pci_irq_line;
+    struct pci_dev *pdev;
+#if LINUX_VERSION_CODE < 0x20363
+    unsigned short pci_command;
+#endif
+#else
     unsigned char pci_irq_line;
+    u32 pci_ioaddr;
+#endif
     u16 vendor, subvendor, device, subdevice;
-    u32 pci_ioaddr, foundaddr = 0;
+    u32 foundaddr = 0;
     unsigned char pci_bus, pci_device_fn;
     u8 intcf = 0;
 
@@ -674,16 +1053,31 @@
         /* Read the info we need to determine if this is
          * our card or not
          */
-#if LINUX_VERSION_CODE >= 0x20155
-        vendor = pci_find_slot (pci_bus, pci_device_fn)->vendor;
-        device = pci_find_slot (pci_bus, pci_device_fn)->device;
-        pci_irq_line = pci_find_slot (pci_bus, pci_device_fn)->irq;
-        pci_ioaddr = pci_find_slot (pci_bus, pci_device_fn)->base_address[0];
-        pci_read_config_word (pci_find_slot (pci_bus, pci_device_fn),
-                              PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
-        pci_read_config_word (pci_find_slot (pci_bus, pci_device_fn),
-                              PCI_SUBSYSTEM_ID, &subdevice);
-#else
+#if LINUX_VERSION_CODE >= 0x20155 /* 2.2, 2.4 */
+        pdev = pci_find_slot (pci_bus, pci_device_fn);
+        
+        if (!pdev)
+            break;
+
+#if LINUX_VERSION_CODE >= 0x20363
+        if(pci_enable_device(pdev)){
+            break;
+        }
+#endif
+        
+        vendor = pdev->vendor;
+        device = pdev->device;
+        pci_irq_line = pdev->irq;
+#if LINUX_VERSION_CODE < 0x20363 /* 2.2 */
+        pci_ioaddr = pdev->base_address[0];
+        pci_read_config_word (pdev, PCI_SUBSYSTEM_VENDOR_ID, &subvendor);
+        pci_read_config_word (pdev, PCI_SUBSYSTEM_ID, &subdevice);
+#else /* 2.4 */
+        pci_ioaddr = pci_resource_start (pdev, 0);
+        subvendor = pdev->subsystem_vendor;
+        subdevice = pdev->subsystem_device;
+#endif
+#else /* 2.0 */
         pcibios_read_config_word (pci_bus, pci_device_fn,
                                   PCI_VENDOR_ID, &vendor);
         pcibios_read_config_word (pci_bus, pci_device_fn,
@@ -717,7 +1111,7 @@
             (vendor == CORRECT_VENDOR_ID) &&
             (device == CORRECT_DEV_ID) &&
             ((subvendor == PCI_VENDOR_LMC)  || (subdevice == PCI_VENDOR_LMC))){
-            struct device *cur, *prev = NULL;
+            struct net_device *cur, *prev = NULL;
 
             /* Fix the error, exchange the two values */
             if(subdevice == PCI_VENDOR_LMC){
@@ -725,9 +1119,27 @@
                 subvendor = PCI_VENDOR_LMC ;
             }
 
+            /* Set the bus master bit */
+#if LINUX_VERSION_CODE < 0x20363
+#if LINUX_VERSION_CODE > 0x20155
+            pci_read_config_word(pdev, PCI_COMMAND,
+                                 &pci_command);
+            pci_command |= PCI_COMMAND_MASTER;
+            pci_write_config_word(pdev, PCI_COMMAND,
+                                  pci_command);
+#endif
+            /* Make the call to actually setup this card */
+            dev = lmc_probe1 (dev, pci_ioaddr, pci_irq_line,
+                              device, subdevice, cards_found, 0x0);
+
+#else
+            pci_set_master (pdev);
             /* Make the call to actually setup this card */
             dev = lmc_probe1 (dev, pci_ioaddr, pci_irq_line,
-                              device, subdevice, cards_found);
+                              device, subdevice, cards_found, pdev);
+
+#endif
+
             if (dev == NULL) {
                 printk ("lmc_probe: lmc_probe1 failed\n");
                 goto lmc_probe_next_card;
@@ -769,28 +1181,28 @@
 /* After this is called, packets can be sent.
  * Does not initialize the addresses
  */
-static int lmc_open (struct device *dev) /*fold00*/
+static int lmc_open (struct net_device *dev) /*fold00*/
 {
     lmc_softc_t *sc = dev->priv;
-    int err;
 
-    lmc_dec_reset (sc);
-    lmc_reset (sc);
+    lmc_trace(dev, "lmc_open in");
 
-    LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
-    LMC_EVENT_LOG(LMC_EVENT_RESET2,
-                  lmc_mii_readreg (sc, 0, 16),
-                  lmc_mii_readreg (sc, 0, 17));
+    lmc_led_on(sc, LMC_DS3_LED0);
 
+    lmc_dec_reset (sc);
+    lmc_reset (sc);
 
-    if (sc->lmc_ok)
+    if (sc->lmc_ok){
+        lmc_trace(dev, "lmc_open lmc_ok out");
         return (0);
+    }
 
     lmc_softreset (sc);
 
     /* Since we have to use PCI bus, this should work on x86,alpha,ppc */
     if (request_irq (dev->irq, &lmc_interrupt, SA_SHIRQ, dev->name, dev)){
         printk(KERN_WARNING "%s: could not get irq: %d\n", dev->name, dev->irq);
+        lmc_trace(dev, "lmc_open irq failed out");
         return -EAGAIN;
     }
     sc->got_irq = 1;
@@ -818,17 +1230,23 @@
         /* disable 32 bit CRC generated by ASIC */
         sc->TxDescriptControlInit |= LMC_TDES_ADD_CRC_DISABLE;
     }
+    sc->lmc_media->set_crc_length(sc, sc->ictl.crc_length);
     /* Acknoledge the Terminal Active and light LEDs */
 
     /* dev->flags |= IFF_UP; */
 
-    err = sppp_open (dev);
-    if (err){
-        return err;
-    }
+    lmc_proto_open(sc);
+
     dev->do_ioctl = lmc_ioctl;
-    dev->tbusy = 0;
+
+
+    LMC_XMITTER_INIT(dev);
+    
+#if LINUX_VERSION_CODE < 0x20363
     dev->start = 1;
+#endif
+    
+    sc->stats.tx_tbusy0++ ;
 
     MOD_INC_USE_COUNT;
 
@@ -845,12 +1263,13 @@
                          | TULIP_STS_TXSTOPPED
                          | TULIP_STS_TXUNDERFLOW
                          | TULIP_STS_RXSTOPPED
+		         | TULIP_STS_RXNOBUF
                         );
-    LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask);
+    LMC_CSR_WRITE (sc, csr_intr, cpu_to_le32(sc->lmc_intrmask));
 
     sc->lmc_cmdmode |= TULIP_CMD_TXRUN;
     sc->lmc_cmdmode |= TULIP_CMD_RXRUN;
-    LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
+    LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(sc->lmc_cmdmode));
 
     sc->lmc_ok = 1; /* Run watchdog */
 
@@ -870,6 +1289,8 @@
     sc->timer.function = &lmc_watchdog;
     add_timer (&sc->timer);
 
+    lmc_trace(dev, "lmc_open out");
+
     return (0);
 }
 
@@ -877,14 +1298,16 @@
  *  under heavy load
  */
 
-static void lmc_running_reset (struct device *dev) /*fold00*/
+static void lmc_running_reset (struct net_device *dev) /*fold00*/
 {
 
     lmc_softc_t *sc = (lmc_softc_t *) dev->priv;
 
+    lmc_trace(dev, "lmc_runnig_reset in");
+
     /* stop interrupts */
     /* Clear the interrupt mask */
-    LMC_CSR_WRITE (sc, csr_intr, 0x00000000);
+    LMC_CSR_WRITE (sc, csr_intr, cpu_to_le32(0x00000000));
 
     lmc_dec_reset (sc);
     lmc_reset (sc);
@@ -893,15 +1316,20 @@
     sc->lmc_media->set_link_status (sc, 1);
     sc->lmc_media->set_status (sc, NULL);
 
-    dev->flags |= IFF_RUNNING;
-    dev->tbusy = 0;
+    //dev->flags |= IFF_RUNNING;
+    
+    LMC_XMITTER_FREE(dev);
+
     sc->lmc_txfull = 0;
+    sc->stats.tx_tbusy0++ ;
 
     sc->lmc_intrmask = TULIP_DEFAULT_INTR_MASK;
-    LMC_CSR_WRITE (sc, csr_intr, sc->lmc_intrmask);
+    LMC_CSR_WRITE (sc, csr_intr, cpu_to_le32(sc->lmc_intrmask));
 
     sc->lmc_cmdmode |= (TULIP_CMD_TXRUN | TULIP_CMD_RXRUN);
-    LMC_CSR_WRITE (sc, csr_command, sc->lmc_cmdmode);
+    LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(sc->lmc_cmdmode));
+
+    lmc_trace(dev, "lmc_runnin_reset_out");
 }
 
 
@@ -909,47 +1337,68 @@
  * This disables the timer for the watchdog and keepalives,
  * and disables the irq for dev.
  */
-static int lmc_close (struct device *dev) /*fold00*/
+static int lmc_close (struct net_device *dev) /*fold00*/
 {
     /* not calling release_region() as we should */
-    lmc_softc_t *sc;
+    lmc_softc_t *sc = dev->priv;
 
+    lmc_trace(dev, "lmc_close in");
+    
     sc = dev->priv;
     sc->lmc_ok = 0;
     sc->lmc_media->set_link_status (sc, 0);
     del_timer (&sc->timer);
-    sppp_close (dev);
+    lmc_proto_close(sc);
     lmc_ifdown (dev);
 
+#if LINUX_VERSION_CODE < 0x20363
+    dev->start = 0;
+#endif
+
+    
+    /*
+     * Let's make sure all the leds are off
+     * when not configured
+     */
+    lmc_led_off(sc, LMC_DS3_LED0);
+    lmc_led_off(sc, LMC_DS3_LED1);
+    lmc_led_off(sc, LMC_DS3_LED2);
+    lmc_led_off(sc, LMC_DS3_LED3);
+
+    lmc_trace(dev, "lmc_close out");
+    
     return 0;
 }
 
 /* Ends the transfer of packets */
 /* When the interface goes down, this is called */
-static int lmc_ifdown (struct device *dev) /*fold00*/
+static int lmc_ifdown (struct net_device *dev) /*fold00*/
 {
     lmc_softc_t *sc = dev->priv;
     u32 csr6;
     int i;
 
+    lmc_trace(dev, "lmc_ifdown in");
+    
     /* Don't let anything else go on right now */
-    dev->start = 0;
-    dev->tbusy = 1;
+    //    dev->start = 0;
+    LMC_XMITTER_BUSY(dev);
+    sc->stats.tx_tbusy1++ ;
 
     /* stop interrupts */
     /* Clear the interrupt mask */
-    LMC_CSR_WRITE (sc, csr_intr, 0x00000000);
+    LMC_CSR_WRITE (sc, csr_intr, cpu_to_le32(0x00000000));
 
     /* Stop Tx and Rx on the chip */
-    csr6 = LMC_CSR_READ (sc, csr_command);
+    csr6 = le32_to_cpu(LMC_CSR_READ (sc, csr_command));
     csr6 &= ~LMC_DEC_ST;		/* Turn off the Transmission bit */
     csr6 &= ~LMC_DEC_SR;		/* Turn off the Recieve bit */
-    LMC_CSR_WRITE (sc, csr_command, csr6);
+    LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(csr6));
 
     dev->flags &= ~IFF_RUNNING;
 
     sc->stats.rx_missed_errors +=
-        LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
+        le32_to_cpu(LMC_CSR_READ (sc, csr_missed_frames)) & 0xffff;
 
     /* release the interrupt */
     if(sc->got_irq == 1){
@@ -982,7 +1431,10 @@
 
     lmc_led_off (sc, LMC_MII16_LED_ALL);
 
-    dev->tbusy = 0;
+    LMC_XMITTER_FREE(dev);
+    sc->stats.tx_tbusy0++ ;
+
+    lmc_trace(dev, "lmc_ifdown out");
 
     MOD_DEC_USE_COUNT;
     return 0;
@@ -993,31 +1445,34 @@
  */
 static void lmc_interrupt (int irq, void *dev_instance, struct pt_regs *regs) /*fold00*/
 {
-    struct device *dev = (struct device *) dev_instance;
-    lmc_softc_t *sc;
+    struct net_device *dev = (struct net_device *) dev_instance;
+    lmc_softc_t *sc = dev->priv;
     u32 csr;
     int i;
     s32 stat;
     unsigned int badtx;
     u32 firstcsr;
+    int max_work = LMC_RXDESCS;
+    unsigned long flags;
 
-    sc = dev->priv;
+    lmc_trace(dev, "lmc_interrupt in");
 
-    spin_lock(&sc->lmc_lock);
 
-    if (test_and_set_bit (0, (void *) &dev->interrupt)) {
-        goto lmc_int_fail_out;
-    }
+    LMC_SPIN_LOCK_IRQSAVE(sc);
 
     /*
      * Read the csr to find what interupts we have (if any)
      */
-    csr = LMC_CSR_READ (sc, csr_status);
+    csr = le32_to_cpu(LMC_CSR_READ (sc, csr_status));
 
     /*
      * Make sure this is our interrupt
      */
     if ( ! (csr & sc->lmc_intrmask)) {
+        /*
+         * If it's not make sure it's not a media interupt first
+         */
+        sc->lmc_media->got_interupt(sc);
         goto lmc_int_fail_out;
     }
 
@@ -1025,11 +1480,10 @@
 
     /* always go through this loop at least once */
     while (csr & sc->lmc_intrmask) {
-
         /*
          * Clear interupt bits, we handle all case below
          */
-        LMC_CSR_WRITE (sc, csr_status, csr);
+        LMC_CSR_WRITE (sc, csr_status, cpu_to_le32(csr));
 
         /*
          * One of
@@ -1048,14 +1502,15 @@
             lmc_running_reset (dev);
             break;
         }
-
         
-        if (csr & (TULIP_STS_RXINTR | TULIP_STS_RXNOBUF)) {
-	  lmc_rx (dev);
+        if (csr & TULIP_STS_RXINTR){
+            lmc_trace(dev, "rx interupt");
+            lmc_rx (dev);
+            
         }
-        
         if (csr & (TULIP_STS_TXINTR | TULIP_STS_TXNOBUF | TULIP_STS_TXSTOPPED)) {
 
+	    int		n_compl = 0 ;
             /* reset the transmit timeout detection flag -baz */
             sc->stats.tx_NoCompleteCnt = 0;
 
@@ -1063,15 +1518,15 @@
             i = badtx % LMC_TXDESCS;
 
             while ((badtx < sc->lmc_next_tx)) {
-                stat = sc->lmc_txring[i].status;
+                stat = le32_to_cpu(sc->lmc_txring[i].status);
 
-                LMC_EVENT_LOG (LMC_EVENT_XMTINT, stat, 0);
                 /*
                  * If bit 31 is 1 the tulip owns it break out of the loop
                  */
-                if (stat < 0)
+                if (stat & 0x80000000)
                     break;
 
+		n_compl++ ;		/* i.e., have an empty slot in ring */
                 /*
                  * If we have no skbuff or have cleared it
                  * Already continue to the next buffer
@@ -1096,13 +1551,16 @@
                 else {
                     
 #if LINUX_VERSION_CODE >= 0x20200
-                    sc->stats.tx_bytes += sc->lmc_txring[i].length & 0x7ff;
+                    sc->stats.tx_bytes += le32_to_cpu(sc->lmc_txring[i].length) & 0x7ff;
 #endif
                     
                     sc->stats.tx_packets++;
                 }
-                
-                LMC_DEV_KFREE_SKB (sc->lmc_txq[i]);
+
+#if LINUX_VERSION_CODE >= 0x20363 /* 2.4 */
+                pci_unmap_single(sc->pdev, sc->lmc_txring[i].buffer1, sc->lmc_txq[i]->len, PCI_DMA_TODEVICE);
+#endif
+                dev_kfree_skb_irq(sc->lmc_txq[i]);
                 sc->lmc_txq[i] = 0;
 
                 badtx++;
@@ -1115,20 +1573,13 @@
                 badtx += LMC_TXDESCS;
             }
             sc->lmc_txfull = 0;
-            dev->tbusy = 0;
-            mark_bh (NET_BH);  /* Tell Linux to give me more packets */
-
-#ifdef DEBUG
-            sc->stats.dirtyTx = badtx;
-            sc->stats.lmc_next_tx = sc->lmc_next_tx;
-            sc->stats.lmc_txfull = sc->lmc_txfull;
-            sc->stats.tbusy = dev->tbusy;
+            LMC_XMITTER_FREE(dev);
+            sc->stats.tx_tbusy0++ ;
+#if LINUX_VERSION_CODE < 0x20363
+            mark_bh (NET_BH);	/* Tell Linux to give me more packets */
 #endif
             sc->lmc_taint_tx = badtx;
 
-            /*
-             * Why was there a break here???
-             */
         }			/* end handle transmit interrupt */
 
         if (csr & TULIP_STS_SYSERROR) {
@@ -1150,29 +1601,30 @@
             }
             lmc_dec_reset (sc);
             lmc_reset (sc);
-            LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
-            LMC_EVENT_LOG(LMC_EVENT_RESET2,
-                          lmc_mii_readreg (sc, 0, 16),
-                          lmc_mii_readreg (sc, 0, 17));
 
         }
+
+        
+        if(max_work-- <= 0)
+            break;
+        
         /*
          * Get current csr status to make sure
          * we've cleared all interupts
          */
-        csr = LMC_CSR_READ (sc, csr_status);
+        csr = le32_to_cpu(LMC_CSR_READ (sc, csr_status));
     }				/* end interrupt loop */
-    LMC_EVENT_LOG(LMC_EVENT_INT, firstcsr, csr);
-
-    dev->interrupt = 0;
 
 lmc_int_fail_out:
 
-    spin_unlock(&sc->lmc_lock);
+    LMC_SPIN_UNLOCK_IRQRESTORE(sc);
+
+    lmc_trace(dev, "lmc_interrupt out");
+
     return;
 }
 
-static int lmc_start_xmit (struct sk_buff *skb, struct device *dev) /*fold00*/
+static int lmc_start_xmit (struct sk_buff *skb, struct net_device *dev) /*fold00*/
 {
     lmc_softc_t *sc;
     u32 flag;
@@ -1180,13 +1632,11 @@
     int ret = 0;
     LMC_SPIN_FLAGS;
 
-    sc = dev->priv;
+    lmc_trace(dev, "lmc_start_xmit in");
 
-    /* the interface better be up */
-    if ( ! (dev->flags & IFF_UP))
-        return 1;
+    sc = dev->priv;
 
-    spin_lock_irqsave(&sc->lmc_lock, flags);
+    LMC_SPIN_LOCK_IRQSAVE(sc);
 
     /*
      * If the transmitter is busy
@@ -1195,9 +1645,13 @@
      * Poke the chip and try to get it running
      *
      */
-    if (dev->tbusy) {
+#if LINUX_VERSION_CODE < 0x20363
+    if(dev->tbusy != 0){
         u32 csr6;
 
+        printk("%s: Xmitter busy|\n", dev->name);
+
+	sc->stats.tx_tbusy_calls++ ;
         if (jiffies - dev->trans_start < TX_TIMEOUT) {
             ret = 1;
             goto lmc_start_xmit_bug_out;
@@ -1210,24 +1664,15 @@
          * table and starts from scartch
          */
 
-        LMC_EVENT_LOG(LMC_EVENT_XMTPRCTMO,
-                      LMC_CSR_READ (sc, csr_status),
-                      sc->stats.tx_ProcTimeout);
-
         lmc_running_reset (dev);
 
-        LMC_EVENT_LOG(LMC_EVENT_RESET1, LMC_CSR_READ (sc, csr_status), 0);
-        LMC_EVENT_LOG(LMC_EVENT_RESET2,
-                      lmc_mii_readreg (sc, 0, 16),
-                      lmc_mii_readreg (sc, 0, 17));
-
         /* restart the tx processes */
-        csr6 = LMC_CSR_READ (sc, csr_command);
-        LMC_CSR_WRITE (sc, csr_command, csr6 | 0x0002);
-        LMC_CSR_WRITE (sc, csr_command, csr6 | 0x2002);
+        csr6 = le32_to_cpu(LMC_CSR_READ (sc, csr_command));
+        LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(csr6 | 0x0002));
+        LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(csr6 | 0x2002));
 
         /* immediate transmit */
-        LMC_CSR_WRITE (sc, csr_txpoll, 0);
+        LMC_CSR_WRITE (sc, csr_txpoll, cpu_to_le32(0));
 
         sc->stats.tx_errors++;
         sc->stats.tx_ProcTimeout++;	/* -baz */
@@ -1237,57 +1682,66 @@
         ret = 1;
         goto lmc_start_xmit_bug_out;
     }
-    /* normal path */
+#endif
+    /* normal path, tbusy known to be zero */
 
     entry = sc->lmc_next_tx % LMC_TXDESCS;
 
     sc->lmc_txq[entry] = skb;
+#if LINUX_VERSION_CODE >= 0x20363
+    sc->lmc_txring[entry].buffer1 = pci_map_single (sc->pdev, skb->data, skb->len, PCI_DMA_TODEVICE);
+#else
     sc->lmc_txring[entry].buffer1 = virt_to_bus (skb->data);
+#endif
 
     LMC_CONSOLE_LOG("xmit", skb->data, skb->len);
 
+#ifndef GCOM
     /* If the queue is less than half full, don't interrupt */
     if (sc->lmc_next_tx - sc->lmc_taint_tx < LMC_TXDESCS / 2)
     {
         /* Do not interrupt on completion of this packet */
         flag = 0x60000000;
-        dev->tbusy = 0;
+        LMC_XMITTER_FREE(dev);
     }
     else if (sc->lmc_next_tx - sc->lmc_taint_tx == LMC_TXDESCS / 2)
     {
         /* This generates an interrupt on completion of this packet */
         flag = 0xe0000000;
-        dev->tbusy = 0;
+        LMC_XMITTER_FREE(dev);
     }
     else if (sc->lmc_next_tx - sc->lmc_taint_tx < LMC_TXDESCS - 1)
     {
         /* Do not interrupt on completion of this packet */
         flag = 0x60000000;
-        dev->tbusy = 0;
+        LMC_XMITTER_FREE(dev);
     }
     else
     {
         /* This generates an interrupt on completion of this packet */
         flag = 0xe0000000;
         sc->lmc_txfull = 1;
-        dev->tbusy = 1;
+        LMC_XMITTER_BUSY(dev);
     }
+#else
+    flag = LMC_TDES_INTERRUPT_ON_COMPLETION;
 
-    if ((entry == LMC_TXDESCS - 1))
-    {
-        flag |= 0xe2000000;
-        dev->tbusy = 1;
+    if (sc->lmc_next_tx - sc->lmc_taint_tx >= LMC_TXDESCS - 1)
+    {				/* ring full, go busy */
+        sc->lmc_txfull = 1;
+        LMC_XMITTER_BUSY(dev);
+        sc->stats.tx_tbusy1++ ;
+        LMC_EVENT_LOG(LMC_EVENT_TBUSY1, entry, 0);
     }
-    /* don't pad small packets either */
-    sc->lmc_txring[entry].length = (skb->len) | flag | sc->TxDescriptControlInit;
+#endif
 
-    /* Done above through TxDescControlInit */
-    /*
-     sc->lmc_txring[entry].length = (skb->len) | flag | 0x00800000;
-     if(sc->ictl.crc_length == LMC_CTL_CRC_LENGTH_16){
-     sc->lmc_txring[entry].length |= 0x04000000;
-     }
-     */
+
+    if (entry == LMC_TXDESCS - 1)	/* last descriptor in ring */
+	flag |= LMC_TDES_END_OF_RING;	/* flag as such for Tulip */
+
+    /* don't pad small packets either */
+    flag = sc->lmc_txring[entry].length = cpu_to_le32((skb->len) | flag |
+						sc->TxDescriptControlInit);
 
     /* set the transmit timeout flag to be checked in
      * the watchdog timer handler. -baz
@@ -1296,22 +1750,25 @@
     sc->stats.tx_NoCompleteCnt++;
     sc->lmc_next_tx++;
 
-    /* give ownership to the chip */
-    sc->lmc_txring[entry].status = 0x80000000;
+    sc->lmc_txring[entry].status = cpu_to_le32(0x80000000);
 
     /* send now! */
-    LMC_CSR_WRITE (sc, csr_txpoll, 0);
+    LMC_CSR_WRITE (sc, csr_txpoll, cpu_to_le32(0));
 
     dev->trans_start = jiffies;
 
+#if LINUX_VERSION_CODE < 0x20363
 lmc_start_xmit_bug_out:
+#endif
+
+    LMC_SPIN_UNLOCK_IRQRESTORE(sc);
 
-    spin_unlock_irqrestore(&sc->lmc_lock, flags);
+    lmc_trace(dev, "lmc_start_xmit_out");
     return ret;
 }
 
 
-static int lmc_rx (struct device *dev) /*fold00*/
+static int lmc_rx (struct net_device *dev) /*fold00*/
 {
     lmc_softc_t *sc;
     int i;
@@ -1323,45 +1780,44 @@
     struct sk_buff *skb, *nsb;
     u16 len;
 
-    sc = dev->priv;
+    lmc_trace(dev, "lmc_rx in");
 
-    if ( ! (dev->flags & IFF_UP))
-        return 1;
+    sc = dev->priv;
 
-    rxIntLoopCnt = 0;		/* debug -baz */
+    rxIntLoopCnt = 0;
 
     i = sc->lmc_next_rx % LMC_RXDESCS;
     next_rx = sc->lmc_next_rx;
 
-    while (((stat = sc->lmc_rxring[i].status) & LMC_RDES_OWN_BIT) != DESC_OWNED_BY_DC21X4)
+    while (((stat = le32_to_cpu(sc->lmc_rxring[i].status)) & LMC_RDES_OWN_BIT) != DESC_OWNED_BY_DC21X4)
     {
         rxIntLoopCnt++;		/* debug -baz */
-        LMC_EVENT_LOG(LMC_EVENT_RCVINT, stat, 0);
-
+        len = ((stat & LMC_RDES_FRAME_LENGTH) >> RDES_FRAME_LENGTH_BIT_NUMBER);
         if ((stat & 0x0300) != 0x0300) {  /* Check first segment and last segment */
             if ((stat & 0x0000ffff) != 0x7fff) {
                 /* Oversized frame */
                 sc->stats.rx_length_errors++;
+                sc->stats.rx_errors++;
                 goto skip_packet;
             }
         }
 
-        if(stat & 0x00000008){ /* Catch a dribbling bit error */
+        if(stat & 0x00000004){ /* Catch a dribbling bit error */
             sc->stats.rx_errors++;
             sc->stats.rx_frame_errors++;
             goto skip_packet;
         }
 
 
-        if(stat & 0x00000004){ /* Catch a CRC error by the Xilinx */
+        if(stat & 0x00000008){ /* Catch a CRC error by the Xilinx */
             sc->stats.rx_errors++;
             sc->stats.rx_crc_errors++;
             goto skip_packet;
         }
 
 
-        len = ((stat & LMC_RDES_FRAME_LENGTH) >> RDES_FRAME_LENGTH_BIT_NUMBER);
-        if (len > PKT_BUF_SZ){
+        if (len > LMC_PKT_BUF_SZ){
+            sc->stats.rx_errors++;
             sc->stats.rx_length_errors++;
             localLengthErrCnt++;
             goto skip_packet;
@@ -1370,6 +1826,7 @@
         if (len < sc->lmc_crcSize + 2) {
             sc->stats.rx_length_errors++;
             sc->stats.rx_SmallPktCnt++;
+            sc->stats.rx_errors++;
             localLengthErrCnt++;
             goto skip_packet;
         }
@@ -1388,19 +1845,29 @@
          */
         
         if(skb == 0x0){
-            nsb = dev_alloc_skb (PKT_BUF_SZ + 2);
+            nsb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);
             if (nsb) {
                 LMC_SKB_FREE(nsb, 1);
                 sc->lmc_rxq[i] = nsb;
                 nsb->dev = dev;
+#if LINUX_VERSION_CODE >= 0x20363
+                sc->lmc_rxring[i].buffer1 = pci_map_single(sc->pdev, nsb->tail, LMC_PKT_BUF_SZ+2, PCI_DMA_FROMDEVICE);
+#else
                 sc->lmc_rxring[i].buffer1 = virt_to_bus (nsb->tail);
+#endif
             }
+            sc->failed_recv_alloc = 1;
             goto skip_packet;
         }
         
         dev->last_rx = jiffies;
         sc->stats.rx_packets++;
 
+#if LINUX_VERSION_CODE >= 0x20363
+#ifdef LMC_PACKET_LOG
+        pci_dma_sync_single(sc->pdev, sc->lmc_rxring[i].buffer1, len, PCI_DMA_FROMDEVICE);
+#endif
+#endif
         LMC_CONSOLE_LOG("recv", skb->data, len);
 
         /*
@@ -1410,31 +1877,39 @@
          * them into a new buffer??
          */
         
-        if(len > (3*LMC_MTU)/4){
+        if(len > (LMC_MTU - (LMC_MTU>>2))){ /* len > LMC_MTU * 0.75 */
             /*
              * If it's a large packet don't copy it just hand it up
              */
         give_it_anyways:
 
             sc->lmc_rxq[i] = 0x0;
-            sc->lmc_rxring[i].buffer1 = 0x0;
+            sc->lmc_rxring[i].buffer1 = cpu_to_le32(0x0);
 
             skb_put (skb, len);
-            skb->protocol=htons(ETH_P_WAN_PPP);
+            skb->protocol = lmc_proto_type(sc, skb);
+            skb->protocol = htons(ETH_P_WAN_PPP);
             skb->mac.raw = skb->data;
-            skb->nh.raw = skb->data;
+//            skb->nh.raw = skb->data;
             skb->dev = dev;
-            netif_rx(skb);
+#if LINUX_VERSION_CODE >= 0x20363 /* 2.4 */
+            pci_unmap_single(sc->pdev, sc->lmc_rxring[i].buffer1, len, PCI_DMA_FROMDEVICE);
+#endif
+            lmc_proto_netif(sc, skb);
 
             /*
              * This skb will be destroyed by the upper layers, make a new one
              */
-            nsb = dev_alloc_skb (PKT_BUF_SZ + 2);
+            nsb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);
             if (nsb) {
                 LMC_SKB_FREE(nsb, 1);
                 sc->lmc_rxq[i] = nsb;
                 nsb->dev = dev;
+#if LINUX_VERSION_CODE >= 0x20363
+                sc->lmc_rxring[i].buffer1 = pci_map_single(sc->pdev, nsb->tail, LMC_PKT_BUF_SZ+2, PCI_DMA_FROMDEVICE);
+#else
                 sc->lmc_rxring[i].buffer1 = virt_to_bus (nsb->tail);
+#endif
                 /* Transfered to 21140 below */
             }
             else {
@@ -1447,10 +1922,9 @@
                  * again.  (once a second)
                  */
                 sc->stats.rx_BuffAllocErr++;
+                sc->failed_recv_alloc = 1;
                 goto skip_out_of_mem;
-
             }
-
         }
         else {
             nsb = dev_alloc_skb(len);
@@ -1458,15 +1932,19 @@
                 goto give_it_anyways;
             }
             memcpy(skb_put(nsb, len), skb->data, len);
-            nsb->protocol=htons(ETH_P_WAN_PPP);
+            
+            nsb->protocol = lmc_proto_type(sc, skb);
             nsb->mac.raw = nsb->data;
-            nsb->nh.raw = nsb->data;
+            //            nsb->nh.raw = nsb->data;
             nsb->dev = dev;
-            netif_rx(nsb);
+#if LINUX_VERSION_CODE >= 0x20363 /* 2.4 */
+            pci_unmap_single(sc->pdev, sc->lmc_rxring[i].buffer1, len, PCI_DMA_FROMDEVICE);
+#endif
+            lmc_proto_netif(sc, nsb);
         }
 
     skip_packet:
-        sc->lmc_rxring[i].status = DESC_OWNED_BY_DC21X4;
+        sc->lmc_rxring[i].status = cpu_to_le32(DESC_OWNED_BY_DC21X4);
 
         sc->lmc_next_rx++;
         i = sc->lmc_next_rx % LMC_RXDESCS;
@@ -1475,54 +1953,34 @@
             break;
     }
     
-    /* detect condition for LMC1000 where DSU cable attaches and fills
-     * descriptors with bogus packets
-     */
-    if (localLengthErrCnt > LMC_RXDESCS - 3) {
-        sc->stats.rx_BadPktSurgeCnt++;
-        LMC_EVENT_LOG(LMC_EVENT_BADPKTSURGE,
-                      localLengthErrCnt,
-                      sc->stats.rx_BadPktSurgeCnt);
-    }
-
     /* save max count of receive descriptors serviced */
     if (rxIntLoopCnt > sc->stats.rxIntLoopCnt) {
         sc->stats.rxIntLoopCnt = rxIntLoopCnt;	/* debug -baz */
     }
 
-#ifdef DEBUG
-    if (rxIntLoopCnt == 0)
-    {
-        for (i = 0; i < LMC_RXDESCS; i++)
-        {
-            if ((sc->lmc_rxring[i].status & LMC_RDES_OWN_BIT)
-                != DESC_OWNED_BY_DC21X4)
-            {
-                rxIntLoopCnt++;
-            }
-        }
-        LMC_EVENT_LOG(LMC_EVENT_RCVEND, rxIntLoopCnt, 0);
-    }
-#endif
-
 skip_out_of_mem:
 
+    lmc_trace(dev, "lmc_rx out");
+
     return 0;
 }
 
-static struct enet_statistics *lmc_get_stats (struct device *dev) /*fold00*/
+static struct enet_statistics *lmc_get_stats (struct net_device *dev) /*fold00*/
 {
     lmc_softc_t *sc;
     LMC_SPIN_FLAGS;
 
+    lmc_trace(dev, "lmc_get_stats in");
+
     sc = dev->priv;
 
-    spin_lock_irqsave(&sc->lmc_lock, flags);
+    LMC_SPIN_LOCK_IRQSAVE(sc);
+
+    sc->stats.rx_missed_errors += le32_to_cpu(LMC_CSR_READ (sc, csr_missed_frames)) & 0xffff;
 
-    if (dev->start)
-        sc->stats.rx_missed_errors += LMC_CSR_READ (sc, csr_missed_frames) & 0xffff;
+    LMC_SPIN_UNLOCK_IRQRESTORE(sc);
 
-    spin_unlock_irqrestore(&sc->lmc_lock, flags);
+    lmc_trace(dev, "lmc_get_stats out");
 
     return (struct enet_statistics *) &sc->stats;
 }
@@ -1542,7 +2000,8 @@
 
 void cleanup_module (void) /*fold00*/
 {
-    struct device *dev, *next;
+    struct net_device *dev, *next;
+    lmc_softc_t *sc;
 
     /* we have no pointer to our devices, since they are all dynamically
      * allocated.  So, here we loop through all the network devices
@@ -1559,19 +2018,27 @@
 
         /* close the syncppp stuff, and release irq. Close is run on unreg net */
         lmc_close (dev);
-        sppp_detach (dev);
+        
+        sc = dev->priv;
+
+        printk ("%s: detaching from protocol...\n", dev->name);
+        if (sc != NULL)
+            lmc_proto_detach(sc);
 
-        /* Remove the device from the linked list */
         unregister_netdev (dev);
 
         /* Let go of the io region */;
         release_region (dev->base_addr, LMC_REG_RANGE);
 
         /* free our allocated structures. */
+#if LINUX_VERSION_CODE >= 0x20363
+        pci_free_consistent(sc->pdev, sizeof(lmc_softc_t), sc, sc->sc_dma_handle);
+#else
         kfree (dev->priv);
+#endif
         dev->priv = NULL;
 
-        kfree ((struct ppp_device *) dev);
+        kfree (dev);
         dev = NULL;
     }
 
@@ -1587,40 +2054,49 @@
     int command = (0xf6 << 10) | (devaddr << 5) | regno;
     int retval = 0;
 
+    lmc_trace(sc->lmc_device, "lmc_mii_readreg in");
+
     LMC_MII_SYNC (sc);
 
+    lmc_trace(sc->lmc_device, "lmc_mii_readreg: done sync");
+
     for (i = 15; i >= 0; i--)
     {
         int dataval = (command & (1 << i)) ? 0x20000 : 0;
 
-        LMC_CSR_WRITE (sc, csr_9, dataval);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(dataval));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
-        LMC_CSR_WRITE (sc, csr_9, dataval | 0x10000);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(dataval | 0x10000));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
     }
 
+    lmc_trace(sc->lmc_device, "lmc_mii_readreg: done1");
+
     for (i = 19; i > 0; i--)
     {
-        LMC_CSR_WRITE (sc, csr_9, 0x40000);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(0x40000));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
-        retval = (retval << 1) | ((LMC_CSR_READ (sc, csr_9) & 0x80000) ? 1 : 0);
-        LMC_CSR_WRITE (sc, csr_9, 0x40000 | 0x10000);
+        retval = (retval << 1) | (le32_to_cpu((LMC_CSR_READ(sc, csr_9)) & 0x80000) ? 1 : 0);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(0x40000 | 0x10000));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
     }
 
+    lmc_trace(sc->lmc_device, "lmc_mii_readreg out");
+
     return (retval >> 1) & 0xffff;
 }
 
-void lmc_mii_writereg (lmc_softc_t * const sc, unsigned devaddr, /*fold00*/
-                       unsigned regno, unsigned data)
+void lmc_mii_writereg (lmc_softc_t * const sc, unsigned devaddr, unsigned regno, unsigned data) /*fold00*/
 {
     int i = 32;
     int command = (0x5002 << 16) | (devaddr << 23) | (regno << 18) | data;
 
+    lmc_trace(sc->lmc_device, "lmc_mii_writereg in");
+
     LMC_MII_SYNC (sc);
 
     i = 31;
@@ -1633,10 +2109,10 @@
         else
             datav = 0x00000;
 
-        LMC_CSR_WRITE (sc, csr_9, datav);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(datav));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
-        LMC_CSR_WRITE (sc, csr_9, (datav | 0x10000));
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(datav | 0x10000));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
         i--;
@@ -1645,20 +2121,24 @@
     i = 2;
     while (i > 0)
     {
-        LMC_CSR_WRITE (sc, csr_9, 0x40000);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(0x40000));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
-        LMC_CSR_WRITE (sc, csr_9, 0x50000);
+        LMC_CSR_WRITE (sc, csr_9, cpu_to_le32(0x50000));
         lmc_delay ();
         /* __SLOW_DOWN_IO; */
         i--;
     }
+
+    lmc_trace(sc->lmc_device, "lmc_mii_writereg out");
 }
 
 static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
 {
     int i;
 
+    lmc_trace(sc->lmc_device, "lmc_softreset in");
+
     /* Initialize the recieve rings and buffers. */
     sc->lmc_txfull = 0;
     sc->lmc_next_rx = 0;
@@ -1678,8 +2158,15 @@
 
         if (sc->lmc_rxq[i] == NULL)
         {
-            skb = dev_alloc_skb (PKT_BUF_SZ + 2);
-            sc->lmc_rxq[i] = skb;
+            skb = dev_alloc_skb (LMC_PKT_BUF_SZ + 2);
+            if(skb == NULL){
+                printk(KERN_WARNING "%s: Failed to allocate receiver ring, will try again\n", sc->name);
+                sc->failed_ring = 1;
+                break;
+            }
+            else{
+                sc->lmc_rxq[i] = skb;
+            }
         }
         else
         {
@@ -1690,77 +2177,120 @@
         LMC_SKB_FREE(skb, 1);
 
         /* owned by 21140 */
-        sc->lmc_rxring[i].status = 0x80000000;
+        sc->lmc_rxring[i].status = cpu_to_le32(0x80000000);
 
         /* used to be PKT_BUF_SZ now uses skb since we loose some to head room */
-        sc->lmc_rxring[i].length = skb->end - skb->data;
+        sc->lmc_rxring[i].length = cpu_to_le32(skb->end - skb->data);
 
         /* use to be tail which is dumb since you're thinking why write
          * to the end of the packj,et but since there's nothing there tail == data
          */
+#if LINUX_VERSION_CODE >= 0x20363
+        sc->lmc_rxring[i].buffer1 = pci_map_single(sc->pdev, skb->data, sc->lmc_rxring[i].length, PCI_DMA_FROMDEVICE);
+        sc->lmc_rxring[i].buffer2 = (u32) &(sc->sc_dma->lmc_rxring[i + 1]);
+#else
         sc->lmc_rxring[i].buffer1 = virt_to_bus (skb->data);
+        sc->lmc_rxring[i].buffer2 = virt_to_bus (&sc->lmc_rxring[i+1]);
 
-        /* This is fair since the structure is static and we have the next address */
-        sc->lmc_rxring[i].buffer2 = virt_to_bus (&sc->lmc_rxring[i + 1]);
+#endif
 
     }
 
     /*
      * Sets end of ring
      */
-    sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
+    sc->lmc_rxring[i - 1].length |= cpu_to_le32(0x02000000); /* Set end of buffers flag */
+#if LINUX_VERSION_CODE >= 0x20363
+    sc->lmc_rxring[i - 1].buffer2 = (u32) &sc->sc_dma->lmc_rxring[0]; /* Point back to the start */
+    LMC_CSR_WRITE (sc, csr_rxlist, (u32) &sc->sc_dma->lmc_rxring); /* write base address */
+#else
     sc->lmc_rxring[i - 1].buffer2 = virt_to_bus (&sc->lmc_rxring[0]); /* Point back to the start */
     LMC_CSR_WRITE (sc, csr_rxlist, virt_to_bus (sc->lmc_rxring)); /* write base address */
+#endif
 
 
     /* Initialize the transmit rings and buffers */
     for (i = 0; i < LMC_TXDESCS; i++)
     {
+        if (sc->lmc_txq[i] != NULL){		/* have buffer */
+#if LINUX_VERSION_CODE >= 0x20363 /* 2.4 */
+            pci_unmap_single(sc->pdev, sc->lmc_txring[i].buffer1, sc->lmc_txq[i]->len, PCI_DMA_TODEVICE);
+#endif
+            LMC_DEV_KFREE_SKB(sc->lmc_txq[i]);	/* free it */
+            sc->stats.tx_dropped++;      /* We just dropped a packet */
+        }
         sc->lmc_txq[i] = 0;
-        sc->lmc_txring[i].status = 0x00000000;
+        sc->lmc_txring[i].status = cpu_to_le32(0x00000000);
+#if LINUX_VERSION_CODE >= 0x20363
+        sc->lmc_txring[i].buffer2 = (u32) &(sc->sc_dma->lmc_txring[i + 1]);
+#else
         sc->lmc_txring[i].buffer2 = virt_to_bus (&sc->lmc_txring[i + 1]);
+#endif
     }
+    
+#if LINUX_VERSION_CODE >= 0x20363
+    sc->lmc_txring[i - 1].buffer2 = (u32) &sc->sc_dma->lmc_txring[0]; /* Point back to the start */
+    LMC_CSR_WRITE (sc, csr_txlist, (u32) &sc->sc_dma->lmc_txring); /* write base address */
+#else
     sc->lmc_txring[i - 1].buffer2 = virt_to_bus (&sc->lmc_txring[0]);
     LMC_CSR_WRITE (sc, csr_txlist, virt_to_bus (sc->lmc_txring));
+#endif
+    
+    lmc_trace(sc->lmc_device, "lmc_softreset out");
 }
 
-static int lmc_set_config(struct device *dev, struct ifmap *map) /*fold00*/
+static int lmc_set_config(struct net_device *dev, struct ifmap *map) /*fold00*/
 {
+    lmc_trace(dev, "lmc_set_config in");
+    lmc_trace(dev, "lmc_set_config out");
     return -EOPNOTSUPP;
 }
 
-void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits)
+void lmc_gpio_mkinput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
 {
+    lmc_trace(sc->lmc_device, "lmc_gpio_mkinput in");
     sc->lmc_gpio_io &= ~bits;
-    LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
+    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(TULIP_GP_PINSET | (sc->lmc_gpio_io)));
+    lmc_trace(sc->lmc_device, "lmc_gpio_mkinput out");
 }
 
-void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits)
+void lmc_gpio_mkoutput(lmc_softc_t * const sc, u_int32_t bits) /*fold00*/
 {
+    lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput in");
     sc->lmc_gpio_io |= bits;
-    LMC_CSR_WRITE(sc, csr_gp, TULIP_GP_PINSET | (sc->lmc_gpio_io));
+    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(TULIP_GP_PINSET | (sc->lmc_gpio_io)));
+    lmc_trace(sc->lmc_device, "lmc_gpio_mkoutput out");
 }
 
-void lmc_led_on(lmc_softc_t * const sc, u_int32_t led)
+void lmc_led_on(lmc_softc_t * const sc, u_int32_t led) /*fold00*/
 {
-    if((~sc->lmc_miireg16) & led) /* Already on! */
+    lmc_trace(sc->lmc_device, "lmc_led_on in");
+    if((~sc->lmc_miireg16) & led){ /* Already on! */
+        lmc_trace(sc->lmc_device, "lmc_led_on aon out");
         return;
+    }
     
     sc->lmc_miireg16 &= ~led;
     lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+    lmc_trace(sc->lmc_device, "lmc_led_on out");
 }
 
-void lmc_led_off(lmc_softc_t * const sc, u_int32_t led)
+void lmc_led_off(lmc_softc_t * const sc, u_int32_t led) /*fold00*/
 {
-    if(sc->lmc_miireg16 & led) /* Already set don't do anything */
+    lmc_trace(sc->lmc_device, "lmc_led_off in");
+    if(sc->lmc_miireg16 & led){ /* Already set don't do anything */
+        lmc_trace(sc->lmc_device, "lmc_led_off aoff out");
         return;
+    }
     
     sc->lmc_miireg16 |= led;
     lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
+    lmc_trace(sc->lmc_device, "lmc_led_off out");
 }
 
-static void lmc_reset(lmc_softc_t * const sc)
+static void lmc_reset(lmc_softc_t * const sc) /*fold00*/
 {
+    lmc_trace(sc->lmc_device, "lmc_reset in");
     sc->lmc_miireg16 |= LMC_MII16_FIFO_RESET;
     lmc_mii_writereg(sc, 0, 16, sc->lmc_miireg16);
 
@@ -1770,15 +2300,15 @@
     /*
      * make some of the GPIO pins be outputs
      */
-    lmc_gpio_mkoutput(sc, LMC_GEP_DP | LMC_GEP_RESET);
+    lmc_gpio_mkoutput(sc, LMC_GEP_RESET);
 
     /*
-     * drive DP and RESET low to force configuration.  This also forces
+     * RESET low to force state reset.  This also forces
      * the transmitter clock to be internal, but we expect to reset
      * that later anyway.
      */
-    sc->lmc_gpio &= ~(LMC_GEP_DP | LMC_GEP_RESET);
-    LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
+    sc->lmc_gpio &= ~(LMC_GEP_RESET);
+    LMC_CSR_WRITE(sc, csr_gp, cpu_to_le32(sc->lmc_gpio));
 
     /*
      * hold for more than 10 microseconds
@@ -1788,13 +2318,7 @@
     /*
      * stop driving Xilinx-related signals
      */
-    lmc_gpio_mkinput(sc, LMC_GEP_DP | LMC_GEP_RESET);
-
-    /*
-     * busy wait for the chip to reset
-     */
-    while ((LMC_CSR_READ(sc, csr_gp) & LMC_GEP_DP) == 0)
-        ;
+    lmc_gpio_mkinput(sc, LMC_GEP_RESET);
 
     /*
      * Call media specific init routine
@@ -1802,17 +2326,19 @@
     sc->lmc_media->init(sc);
 
     sc->stats.resetCount++;
+    lmc_trace(sc->lmc_device, "lmc_reset out");
 }
 
-static void lmc_dec_reset(lmc_softc_t * const sc)
+static void lmc_dec_reset(lmc_softc_t * const sc) /*fold00*/
 {
     u_int32_t val;
+    lmc_trace(sc->lmc_device, "lmc_dec_reset in");
 
     /*
      * disable all interrupts
      */
     sc->lmc_intrmask = 0;
-    LMC_CSR_WRITE(sc, csr_intr, sc->lmc_intrmask);
+    LMC_CSR_WRITE(sc, csr_intr, cpu_to_le32(sc->lmc_intrmask));
 
     /*
      * Reset the chip with a software reset command.
@@ -1820,9 +2346,16 @@
      * 33MHz that comes to two microseconds but wait a
      * bit longer anyways)
      */
-    LMC_CSR_WRITE(sc, csr_busmode, TULIP_BUSMODE_SWRESET);
+    LMC_CSR_WRITE(sc, csr_busmode, cpu_to_le32(TULIP_BUSMODE_SWRESET));
     udelay(25);
-    sc->lmc_cmdmode = LMC_CSR_READ(sc, csr_command);
+#ifdef __sparc__
+    sc->lmc_busmode = LMC_CSR_READ(sc, cpu_to_le32(csr_busmode));
+    sc->lmc_busmode = 0x00000000;
+    //sc->lmc_busmode = 0x00100000;
+    sc->lmc_busmode &= ~TULIP_BUSMODE_SWRESET;
+    LMC_CSR_WRITE(sc, csr_busmode, cpu_to_le32(sc->lmc_busmode));
+#endif
+    sc->lmc_cmdmode = le32_to_cpu(LMC_CSR_READ(sc, csr_command));
 
     /*
      * We want:
@@ -1848,20 +2381,22 @@
                           | TULIP_CMD_TXTHRSHLDCTL
                         );
 
-    LMC_CSR_WRITE(sc, csr_command, sc->lmc_cmdmode);
+    LMC_CSR_WRITE(sc, csr_command, cpu_to_le32(sc->lmc_cmdmode));
 
     /*
      * disable receiver watchdog and transmit jabber
      */
-    val = LMC_CSR_READ(sc, csr_sia_general);
+    val = le32_to_cpu(LMC_CSR_READ(sc, csr_sia_general));
     val |= (TULIP_WATCHDOG_TXDISABLE | TULIP_WATCHDOG_RXDISABLE);
-    LMC_CSR_WRITE(sc, csr_sia_general, val);
+    LMC_CSR_WRITE(sc, csr_sia_general, cpu_to_le32(val));
 
+    lmc_trace(sc->lmc_device, "lmc_dec_reset out");
 }
 
-static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base,
+static void lmc_initcsrs(lmc_softc_t * const sc, lmc_csrptr_t csr_base, /*fold00*/
                          size_t csr_size)
 {
+    lmc_trace(sc->lmc_device, "lmc_initcsrs in");
     sc->lmc_csrs.csr_busmode	        = csr_base +  0 * csr_size;
     sc->lmc_csrs.csr_txpoll		= csr_base +  1 * csr_size;
     sc->lmc_csrs.csr_rxpoll		= csr_base +  2 * csr_size;
@@ -1878,5 +2413,61 @@
     sc->lmc_csrs.csr_13		        = csr_base + 13 * csr_size;
     sc->lmc_csrs.csr_14		        = csr_base + 14 * csr_size;
     sc->lmc_csrs.csr_15		        = csr_base + 15 * csr_size;
+    lmc_trace(sc->lmc_device, "lmc_initcsrs out");
 }
 
+#if LINUX_VERSION_CODE >= 0x20363
+static void lmc_driver_timeout(struct net_device *dev) { /*fold00*/
+    lmc_softc_t *sc;
+    u32 csr6;
+    LMC_SPIN_FLAGS;
+
+    lmc_trace(dev, "lmc_driver_timeout in");
+
+    sc = dev->priv;
+
+    LMC_SPIN_LOCK_IRQSAVE(sc);
+
+    printk("%s: Xmitter busy|\n", dev->name);
+
+    sc->stats.tx_tbusy_calls++ ;
+    if (jiffies - dev->trans_start < TX_TIMEOUT) {
+        goto bug_out;
+    }
+
+    /*
+     * Chip seems to have locked up
+     * Reset it
+     * This whips out all our decriptor
+     * table and starts from scartch
+     */
+
+    lmc_running_reset (dev);
+
+    /* restart the tx processes */
+    csr6 = le32_to_cpu(LMC_CSR_READ (sc, csr_command));
+    LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(csr6 | 0x0002));
+    LMC_CSR_WRITE (sc, csr_command, cpu_to_le32(csr6 | 0x2002));
+
+    /* immediate transmit */
+    LMC_CSR_WRITE (sc, csr_txpoll, cpu_to_le32(0));
+
+    sc->stats.tx_errors++;
+    sc->stats.tx_ProcTimeout++;	/* -baz */
+
+    dev->trans_start = jiffies;
+
+bug_out:
+
+    LMC_SPIN_UNLOCK_IRQRESTORE(sc);
+
+    lmc_trace(dev, "lmc_driver_timout out");
+
+
+}
+
+int lmc_setup(void) { /*fold00*/
+   return lmc_probe(NULL);
+}
+
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_media.c linux.17p18/drivers/net/lmc/lmc_media.c
--- linux.vanilla/drivers/net/lmc/lmc_media.c	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/lmc_media.c	Tue Aug  1 07:59:41 2000
@@ -1,4 +1,4 @@
-/* $Id: lmc_media.c,v 1.9 2000/01/21 13:29:49 asj Exp $ */
+/* $Id: lmc_media.c,v 1.16 2000/06/06 08:32:14 asj Exp $ */
 
 #include <linux/version.h>
 #include <linux/config.h>
@@ -13,7 +13,7 @@
 #include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <asm/segment.h>
-#include <asm/smp.h>
+//#include <asm/smp.h>
 
 #if LINUX_VERSION_CODE < 0x20155
 #include <linux/bios32.h>
@@ -34,13 +34,14 @@
 
 #if LINUX_VERSION_CODE >= 0x20200
 #include <asm/uaccess.h>
-#include <asm/spinlock.h>
+//#include <asm/spinlock.h>
 #endif
 
-#include "lmc.h"
 #include "lmc_ver.h"
+#include "lmc.h"
 #include "lmc_var.h"
 #include "lmc_ioctl.h"
+#include "lmc_debug.h"
 
 #define CONFIG_LMC_IGNORE_HARDWARE_HANDSHAKE 1
 
@@ -59,7 +60,7 @@
   */
 
 /*
- * For lack of a better place, put the T1 cable stuff here.
+ * For lack of a better place, put the SSI cable stuff here.
  */
 char *lmc_t1_cables[] = {
   "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
@@ -111,12 +112,16 @@
 static void lmc_t1_set_crc_length (lmc_softc_t * const, int);
 static void lmc_t1_set_clock (lmc_softc_t * const, int);
 static void lmc_t1_watchdog (lmc_softc_t * const);
+static int  lmc_t1_ioctl (lmc_softc_t * const, void *);
+static int  lmc_t1_got_interupt (lmc_softc_t * const);
 
 static void lmc_dummy_set_1 (lmc_softc_t * const, int);
 static void lmc_dummy_set2_1 (lmc_softc_t * const, lmc_ctl_t *);
+static int  lmc_dummy_ioctl (lmc_softc_t * const, void *);
+static int  lmc_dummy_got_interupt (lmc_softc_t * const);
 
 static inline void write_av9110_bit (lmc_softc_t *, int);
-static void write_av9110 (lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t,
+static void write_av9110 (lmc_softc_t *, u_int32_t, u_int32_t, u_int32_t, /*fold00*/
 			  u_int32_t, u_int32_t);
 
 lmc_media_t lmc_ds3_media = {
@@ -131,7 +136,9 @@
   lmc_dummy_set_1,		/* set link status */
   lmc_ds3_set_crc_length,	/* set CRC length */
   lmc_dummy_set_1,		/* set T1 or E1 circuit type */
-  lmc_ds3_watchdog
+  lmc_ds3_watchdog,
+  lmc_dummy_ioctl,
+  lmc_dummy_got_interupt,
 };
 
 lmc_media_t lmc_hssi_media = {
@@ -146,7 +153,10 @@
   lmc_hssi_set_link_status,	/* set link status */
   lmc_hssi_set_crc_length,	/* set CRC length */
   lmc_dummy_set_1,		/* set T1 or E1 circuit type */
-  lmc_hssi_watchdog
+  lmc_hssi_watchdog,
+  lmc_dummy_ioctl,
+  lmc_dummy_got_interupt,
+
 };
 
 lmc_media_t lmc_ssi_media = { lmc_ssi_init,	/* special media init stuff */
@@ -160,7 +170,10 @@
   lmc_ssi_set_link_status,	/* set link status */
   lmc_ssi_set_crc_length,	/* set CRC length */
   lmc_dummy_set_1,		/* set T1 or E1 circuit type */
-  lmc_ssi_watchdog
+  lmc_ssi_watchdog,
+  lmc_dummy_ioctl,
+  lmc_dummy_got_interupt,
+
 };
 
 lmc_media_t lmc_t1_media = {
@@ -175,25 +188,38 @@
   lmc_dummy_set_1,		/* set link status */
   lmc_t1_set_crc_length,	/* set CRC length */
   lmc_t1_set_circuit_type,	/* set T1 or E1 circuit type */
-  lmc_t1_watchdog
+  lmc_t1_watchdog,
+  lmc_t1_ioctl,
+  lmc_t1_got_interupt,
+
 };
 
-static void
-lmc_dummy_set_1 (lmc_softc_t * const sc, int a)
+static void lmc_dummy_set_1 (lmc_softc_t * const sc, int a) /*fold00*/
 {
 }
 
-static void
-lmc_dummy_set2_1 (lmc_softc_t * const sc, lmc_ctl_t * a)
+static void lmc_dummy_set2_1 (lmc_softc_t * const sc, lmc_ctl_t * a) /*fold00*/
 {
 }
 
+static int lmc_dummy_ioctl (lmc_softc_t * const sc, void *d) /*fold00*/
+{
+    return -ENOSYS;
+}
+
+static int lmc_dummy_got_interupt (lmc_softc_t * const sc) /*fold00*/
+{
+    return -ENOSYS;
+}
+
+
+
 /*
  *  HSSI methods
  */
 
 static void
-lmc_hssi_init (lmc_softc_t * const sc)
+lmc_hssi_init (lmc_softc_t * const sc) /*fold00*/
 {
   sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC5200;
 
@@ -201,7 +227,7 @@
 }
 
 static void
-lmc_hssi_default (lmc_softc_t * const sc)
+lmc_hssi_default (lmc_softc_t * const sc) /*fold00*/
 {
   sc->lmc_miireg16 = LMC_MII16_LED_ALL;
 
@@ -215,7 +241,7 @@
  * always reset the card if needed.
  */
 static void
-lmc_hssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl)
+lmc_hssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) /*fold00*/
 {
   if (ctl == NULL)
     {
@@ -246,21 +272,25 @@
  * 1 == internal, 0 == external
  */
 static void
-lmc_hssi_set_clock (lmc_softc_t * const sc, int ie)
+lmc_hssi_set_clock (lmc_softc_t * const sc, int ie) /*fold00*/
 {
+  int old;
+  old = sc->ictl.clock_source;
   if (ie == LMC_CTL_CLOCK_SOURCE_EXT)
     {
       sc->lmc_gpio |= LMC_GEP_HSSI_CLOCK;
       LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
       sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
-      printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS);
+      if(old != ie)
+        printk (KERN_INFO "%s: clock external\n", sc->name);
     }
   else
     {
       sc->lmc_gpio &= ~(LMC_GEP_HSSI_CLOCK);
       LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
       sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
-      printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS);
+      if(old != ie)
+        printk (KERN_INFO "%s: clock internal\n", sc->name);
     }
 }
 
@@ -269,7 +299,7 @@
  * 0 == link is down, 1 == link is up.
  */
 static int
-lmc_hssi_get_link_status (lmc_softc_t * const sc)
+lmc_hssi_get_link_status (lmc_softc_t * const sc) /*fold00*/
 {
     /*
      * We're using the same code as SSI since
@@ -279,7 +309,7 @@
 }
 
 static void
-lmc_hssi_set_link_status (lmc_softc_t * const sc, int state)
+lmc_hssi_set_link_status (lmc_softc_t * const sc, int state) /*fold00*/
 {
   if (state == LMC_LINK_UP)
     sc->lmc_miireg16 |= LMC_MII16_HSSI_TA;
@@ -293,26 +323,28 @@
  * 0 == 16bit, 1 == 32bit
  */
 static void
-lmc_hssi_set_crc_length (lmc_softc_t * const sc, int state)
+lmc_hssi_set_crc_length (lmc_softc_t * const sc, int state) /*FOLD00*/
 {
   if (state == LMC_CTL_CRC_LENGTH_32)
     {
       /* 32 bit */
       sc->lmc_miireg16 |= LMC_MII16_HSSI_CRC;
       sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
+      sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4;
     }
   else
     {
       /* 16 bit */
       sc->lmc_miireg16 &= ~LMC_MII16_HSSI_CRC;
       sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
+      sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2;
     }
 
   lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);
 }
 
 static void
-lmc_hssi_watchdog (lmc_softc_t * const sc)
+lmc_hssi_watchdog (lmc_softc_t * const sc) /*fold00*/
 {
   /* HSSI is blank */
 }
@@ -325,7 +357,7 @@
  * Set cable length
  */
 static void
-lmc_ds3_set_100ft (lmc_softc_t * const sc, int ie)
+lmc_ds3_set_100ft (lmc_softc_t * const sc, int ie) /*fold00*/
 {
   if (ie == LMC_CTL_CABLE_LENGTH_GT_100FT)
     {
@@ -341,7 +373,7 @@
 }
 
 static void
-lmc_ds3_default (lmc_softc_t * const sc)
+lmc_ds3_default (lmc_softc_t * const sc) /*fold00*/
 {
   sc->lmc_miireg16 = LMC_MII16_LED_ALL;
 
@@ -356,7 +388,7 @@
  * always reset the card if needed.
  */
 static void
-lmc_ds3_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl)
+lmc_ds3_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) /*fold00*/
 {
   if (ctl == NULL)
     {
@@ -387,7 +419,7 @@
 }
 
 static void
-lmc_ds3_init (lmc_softc_t * const sc)
+lmc_ds3_init (lmc_softc_t * const sc) /*fold00*/
 {
   int i;
 
@@ -422,7 +454,7 @@
  * 1 == DS3 payload scrambled, 0 == not scrambled
  */
 static void
-lmc_ds3_set_scram (lmc_softc_t * const sc, int ie)
+lmc_ds3_set_scram (lmc_softc_t * const sc, int ie) /*fold00*/
 {
   if (ie == LMC_CTL_ON)
     {
@@ -442,7 +474,7 @@
  * 0 == link is down, 1 == link is up.
  */
 static int
-lmc_ds3_get_link_status (lmc_softc_t * const sc)
+lmc_ds3_get_link_status (lmc_softc_t * const sc) /*fold00*/
 {
     u_int16_t link_status, link_status_11;
     int ret = 1;
@@ -528,34 +560,30 @@
  * 0 == 16bit, 1 == 32bit
  */
 static void
-lmc_ds3_set_crc_length (lmc_softc_t * const sc, int state)
+lmc_ds3_set_crc_length (lmc_softc_t * const sc, int state) /*FOLD00*/
 {
   if (state == LMC_CTL_CRC_LENGTH_32)
     {
       /* 32 bit */
       sc->lmc_miireg16 |= LMC_MII16_DS3_CRC;
       sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_32;
+      sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_4;
     }
   else
     {
       /* 16 bit */
       sc->lmc_miireg16 &= ~LMC_MII16_DS3_CRC;
       sc->ictl.crc_length = LMC_CTL_CRC_LENGTH_16;
+      sc->lmc_crcSize = LMC_CTL_CRC_BYTESIZE_2;
     }
 
   lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);
 }
 
 static void
-lmc_ds3_watchdog (lmc_softc_t * const sc)
+lmc_ds3_watchdog (lmc_softc_t * const sc) /*fold00*/
 {
-  sc->lmc_miireg16 = lmc_mii_readreg (sc, 0, 16);
-  if (sc->lmc_miireg16 & 0x0018) {
-      printk ("%s: AIS Recieved\n", sc->name);
-      lmc_led_on (sc, LMC_DS3_LED1 | LMC_DS3_LED2);
-  }
-  else{
-  }
+    
 }
 
 
@@ -564,7 +592,7 @@
  */
 
 static void
-lmc_ssi_init (lmc_softc_t * const sc)
+lmc_ssi_init (lmc_softc_t * const sc) /*fold00*/
 {
   u_int16_t mii17;
   int cable;
@@ -580,7 +608,7 @@
 }
 
 static void
-lmc_ssi_default (lmc_softc_t * const sc)
+lmc_ssi_default (lmc_softc_t * const sc) /*fold00*/
 {
   sc->lmc_miireg16 = LMC_MII16_LED_ALL;
 
@@ -600,7 +628,7 @@
  * always reset the card if needed.
  */
 static void
-lmc_ssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl)
+lmc_ssi_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) /*fold00*/
 {
   if (ctl == NULL)
     {
@@ -637,26 +665,30 @@
  * 1 == internal, 0 == external
  */
 static void
-lmc_ssi_set_clock (lmc_softc_t * const sc, int ie)
+lmc_ssi_set_clock (lmc_softc_t * const sc, int ie) /*fold00*/
 {
+  int old;
+  old = ie;
   if (ie == LMC_CTL_CLOCK_SOURCE_EXT)
     {
       sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK);
       LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
       sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
-      printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS);
+      if(ie != old)
+        printk (KERN_INFO "%s: clock external\n", sc->name);
     }
   else
     {
       sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK;
       LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
       sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
-      printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS);
+      if(ie != old)
+        printk (KERN_INFO "%s: clock internal\n", sc->name);
     }
 }
 
 static void
-lmc_ssi_set_speed (lmc_softc_t * const sc, lmc_ctl_t * ctl)
+lmc_ssi_set_speed (lmc_softc_t * const sc, lmc_ctl_t * ctl) /*fold00*/
 {
   lmc_ctl_t *ictl = &sc->ictl;
   lmc_av9110_t *av;
@@ -698,7 +730,7 @@
  * 0 == link is down, 1 == link is up.
  */
 static int
-lmc_ssi_get_link_status (lmc_softc_t * const sc)
+lmc_ssi_get_link_status (lmc_softc_t * const sc) /*fold00*/
 {
   u_int16_t link_status;
   u_int32_t ticks;
@@ -741,7 +773,7 @@
       ret = 0;
       if(sc->last_led_err[3] != 1){
           sc->stats.tx_lossOfClockCnt++;
-          printk(KERN_WARNING "%s: Lost Clock Card Down\n", sc->name);
+          printk(KERN_WARNING "%s: Lost Clock, Link Down\n", sc->name);
       }
       sc->last_led_err[3] = 1;
       lmc_led_on (sc, LMC_MII16_LED3);	/* turn ON red LED */
@@ -767,7 +799,7 @@
 
   if(hw_hdsk == 0){
       if(sc->last_led_err[1] != 1)
-          printk(KERN_WARNING "%s: DSR no asserted\n", sc->name);
+          printk(KERN_WARNING "%s: DSR not asserted\n", sc->name);
       sc->last_led_err[1] = 1;
       lmc_led_off(sc, LMC_MII16_LED1);
   }
@@ -786,17 +818,17 @@
 }
 
 static void
-lmc_ssi_set_link_status (lmc_softc_t * const sc, int state)
+lmc_ssi_set_link_status (lmc_softc_t * const sc, int state) /*fold00*/
 {
   if (state == LMC_LINK_UP)
     {
       sc->lmc_miireg16 |= (LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS);
-      printk (LMC_PRINTF_FMT ": asserting DTR and RTS\n", LMC_PRINTF_ARGS);
+//      printk (LMC_PRINTF_FMT ": asserting DTR and RTS\n", LMC_PRINTF_ARGS);
     }
   else
     {
       sc->lmc_miireg16 &= ~(LMC_MII16_SSI_DTR | LMC_MII16_SSI_RTS);
-      printk (LMC_PRINTF_FMT ": deasserting DTR and RTS\n", LMC_PRINTF_ARGS);
+//      printk (LMC_PRINTF_FMT ": deasserting DTR and RTS\n", LMC_PRINTF_ARGS);
     }
 
   lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);
@@ -807,7 +839,7 @@
  * 0 == 16bit, 1 == 32bit
  */
 static void
-lmc_ssi_set_crc_length (lmc_softc_t * const sc, int state)
+lmc_ssi_set_crc_length (lmc_softc_t * const sc, int state) /*FOLD00*/
 {
   if (state == LMC_CTL_CRC_LENGTH_32)
     {
@@ -832,51 +864,46 @@
  * These are bits to program the ssi frequency generator
  */
 static inline void
-write_av9110_bit (lmc_softc_t * sc, int c)
+write_av9110_bit (lmc_softc_t * sc, int c) /*fold00*/
 {
   /*
    * set the data bit as we need it.
    */
-  sc->lmc_gpio &= ~(LMC_GEP_SERIALCLK);
+  sc->lmc_gpio &= ~(LMC_GEP_CLK);
   if (c & 0x01)
-    sc->lmc_gpio |= LMC_GEP_SERIAL;
+    sc->lmc_gpio |= LMC_GEP_DATA;
   else
-    sc->lmc_gpio &= ~(LMC_GEP_SERIAL);
+    sc->lmc_gpio &= ~(LMC_GEP_DATA);
   LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
 
   /*
    * set the clock to high
    */
-  sc->lmc_gpio |= LMC_GEP_SERIALCLK;
+  sc->lmc_gpio |= LMC_GEP_CLK;
   LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
 
   /*
    * set the clock to low again.
    */
-  sc->lmc_gpio &= ~(LMC_GEP_SERIALCLK);
+  sc->lmc_gpio &= ~(LMC_GEP_CLK);
   LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
 }
 
 static void
-write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v,
+write_av9110 (lmc_softc_t * sc, u_int32_t n, u_int32_t m, u_int32_t v, /*fold00*/
 	      u_int32_t x, u_int32_t r)
 {
   int i;
 
-#if 0
-  printk (LMC_PRINTF_FMT ": speed %u, %d %d %d %d %d\n",
-	  LMC_PRINTF_ARGS, sc->ictl.clock_rate, n, m, v, x, r);
-#endif
-
   sc->lmc_gpio |= LMC_GEP_SSI_GENERATOR;
-  sc->lmc_gpio &= ~(LMC_GEP_SERIAL | LMC_GEP_SERIALCLK);
+  sc->lmc_gpio &= ~(LMC_GEP_DATA | LMC_GEP_CLK);
   LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
 
   /*
    * Set the TXCLOCK, GENERATOR, SERIAL, and SERIALCLK
    * as outputs.
    */
-  lmc_gpio_mkoutput (sc, (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK
+  lmc_gpio_mkoutput (sc, (LMC_GEP_DATA | LMC_GEP_CLK
 			  | LMC_GEP_SSI_GENERATOR));
 
   sc->lmc_gpio &= ~(LMC_GEP_SSI_GENERATOR);
@@ -902,12 +929,12 @@
    * stop driving serial-related signals
    */
   lmc_gpio_mkinput (sc,
-		    (LMC_GEP_SERIAL | LMC_GEP_SERIALCLK
+		    (LMC_GEP_DATA | LMC_GEP_CLK
 		     | LMC_GEP_SSI_GENERATOR));
 }
 
 static void
-lmc_ssi_watchdog (lmc_softc_t * const sc)
+lmc_ssi_watchdog (lmc_softc_t * const sc) /*fold00*/
 {
   u_int16_t mii17;
   struct ssicsr2
@@ -937,24 +964,24 @@
  * The framer regs are multiplexed through MII regs 17 & 18
  *  write the register address to MII reg 17 and the *  data to MII reg 18. */
 static void
-lmc_t1_write (lmc_softc_t * const sc, int a, int d)
+lmc_t1_write (lmc_softc_t * const sc, int a, int d) /*fold00*/
 {
   lmc_mii_writereg (sc, 0, 17, a);
   lmc_mii_writereg (sc, 0, 18, d);
 }
 
-/* Save a warning
+
 static int
-lmc_t1_read (lmc_softc_t * const sc, int a)
+lmc_t1_read (lmc_softc_t * const sc, int a) /*fold00*/
 {
   lmc_mii_writereg (sc, 0, 17, a);
   return lmc_mii_readreg (sc, 0, 18);
 }
-*/
+
 
 
 static void
-lmc_t1_init (lmc_softc_t * const sc)
+lmc_t1_init (lmc_softc_t * const sc) /*fold00*/
 {
   u_int16_t mii16;
   int i;
@@ -962,6 +989,10 @@
   sc->ictl.cardtype = LMC_CTL_CARDTYPE_LMC1200;
   mii16 = lmc_mii_readreg (sc, 0, 16);
 
+  mii16 &= ~LMC_MII16_T1_XOE;
+  lmc_mii_writereg (sc, 0, 16, mii16);
+  sc->lmc_miireg16 = mii16;
+
   /* reset 8370 */
   mii16 &= ~LMC_MII16_T1_RST;
   lmc_mii_writereg (sc, 0, 16, mii16 | LMC_MII16_T1_RST);
@@ -972,52 +1003,430 @@
   lmc_t1_set_circuit_type(sc, LMC_CTL_CIRCUIT_TYPE_T1);
   mii16 = sc->lmc_miireg16;
 
-  lmc_t1_write (sc, 0x01, 0x1B);	/* CR0     - primary control             */
-  lmc_t1_write (sc, 0x02, 0x42);	/* JAT_CR  - jitter atten config         */
-  lmc_t1_write (sc, 0x14, 0x00);	/* LOOP    - loopback config             */
-  lmc_t1_write (sc, 0x15, 0x00);	/* DL3_TS  - external data link timeslot */
+  /* Clear "foreced alarm" bis */
+  sc->yellow_alarm = 0;
+  sc->red_alarm = 0;
+  sc->blue_alarm = 0;
+
+  /*
+   * CR0
+   * - Set framing too ESF + Force CRC
+   * - Set T1
+   */
+  
+  lmc_t1_write (sc, 0x01, 0x1b);
+  /*
+   * JAT_CR
+   * - set Free Running JCLK and CLAD0
+   * - Reset Elastic store to center
+   * - 64 bit elastic store
+   */
+  lmc_t1_write (sc, 0x02, 0x4b);
+  
+  /*
+   * JAT_CR
+   * - Release Elastic store reset
+   */
+  lmc_t1_write (sc, 0x02, 0x43);
+  
+  /*
+   * Disable all interupts
+   * Except: BOP receive
+   */
+
+  lmc_t1_write (sc, 0x0C, 0x00);
+  lmc_t1_write (sc, 0x0D, 0x00);
+  lmc_t1_write (sc, 0x0E, 0x00);
+  lmc_t1_write (sc, 0x0F, 0x00);
+  lmc_t1_write (sc, 0x10, 0x00);
+  lmc_t1_write (sc, 0x11, 0x00);
+  lmc_t1_write (sc, 0x12, 0x80);
+  lmc_t1_write (sc, 0x13, 0x00);
+  
+  /*
+   * LOOP
+   * - No loopbacks set
+   */
+  lmc_t1_write (sc, 0x14, 0x00);
+  
+  /*
+   * DL3_TS
+   * - Disabled
+   */
+  lmc_t1_write (sc, 0x15, 0x00);
+  
+  /*
+   * PIO
+   * - ONESEC_IO, RDL_IO, TDL_IO, INDY_IO, RFSYNC_IO, RMSYNC_IO
+   *   TFSNYC_IO, TMSYNC_IO: Set for output
+   */
   lmc_t1_write (sc, 0x18, 0xFF);	/* PIO     - programmable I/O            */
+  
+  /*
+   * POE
+   * TDL_OE, RDL_OE: tri state output capable enable
+   * Rest: 2 level output
+   */
   lmc_t1_write (sc, 0x19, 0x30);	/* POE     - programmable OE             */
+  
+  /*
+   * CMUX - Clock Input Mux
+   * RSBCKLI: Normal RSB timebase
+   * TSBCKI: Normal TSB timebase
+   * CLADI: CLAD slaved to transmit
+   * TCKI: Internal CLAD
+   */
   lmc_t1_write (sc, 0x1A, 0x0F);	/* CMUX    - clock input mux             */
+  
+  /*
+   * LIU_CR
+   * RST_LIU: Reset LIU
+   * SQUELCH: Enable squelch
+   * Must be 1: Set to 1
+   */
+  lmc_t1_write (sc, 0x20, 0xC1);	/* LIU_CR  - RX LIU config               */
   lmc_t1_write (sc, 0x20, 0x41);	/* LIU_CR  - RX LIU config               */
-  lmc_t1_write (sc, 0x22, 0x76);	/* RLIU_CR - RX LIU config               */
+  /*
+   * RLIU_CR
+   * WHAT IS GOING ON HERE? USED TO BE 0x76
+   * FRZ_SHORT: don't update on strong signals
+   * AGC: 0x11 normal op
+   * LONG_EYE: normal
+   */
+  lmc_t1_write (sc, 0x22, 0xB1);	/* RLIU_CR - RX LIU config               */
+
+  /*
+   * VGA_MAX
+   * Setting of -20db sesitivity
+   */
+  lmc_t1_write (sc, 0x24, 0x21);
+
+  /*
+   * PRE_EQ
+   * Force off the pre-equilizer
+   * Load 0x26 in VTHRESH
+   */
+  lmc_t1_write (sc, 0x2A, 0xA6);
+
+  /*
+   * GAIN
+   * Equilizer Gain threshholds
+   * Number taken straight from David test code
+   */
+  lmc_t1_write (sc, 0x38, 0x24);  /* RX_TH0  - RX gain threshold 0         */
+  lmc_t1_write (sc, 0x39, 0x28);  /* RX_TH1  - RX gain threshold 0         */
+  lmc_t1_write (sc, 0x3A, 0x2C);  /* RX_TH2  - RX gain threshold 0         */
+  lmc_t1_write (sc, 0x3B, 0x30);  /* RX_TH3  - RX gain threshold 0         */
+  lmc_t1_write (sc, 0x3C, 0x34);  /* RX_TH4  - RX gain threshold 0         */
+
+  /*
+   *  LIU_CR
+   *  Reset the LIU so it'll load the new constants
+   */
+  lmc_t1_write (sc, 0x20, 0x81);  /* LIU_CR  - RX LIU config (reset RLIU)  */
+  lmc_t1_write (sc, 0x20, 0x01);  /* LIU_CR  - RX LIU config (clear reset) */
+  
+  /*
+   * RCR0
+   * Receive B8ZS and 2 out of 4 F-bit errors for reframe
+   */
   lmc_t1_write (sc, 0x40, 0x03);	/* RCR0    - RX config                   */
-  lmc_t1_write (sc, 0x45, 0x00);	/* RALM    - RX alarm config             */
-  lmc_t1_write (sc, 0x46, 0x05);	/* LATCH   - RX alarm/err/cntr latch     */
-  lmc_t1_write (sc, 0x68, 0x40);	/* TLIU_CR - TX LIU config               */
-  lmc_t1_write (sc, 0x70, 0x0D);	/* TCR0    - TX framer config            */
-  lmc_t1_write (sc, 0x71, 0x05);	/* TCR1    - TX config                   */
-  lmc_t1_write (sc, 0x72, 0x0B);	/* TFRM    - TX frame format             */
-  lmc_t1_write (sc, 0x73, 0x00);	/* TERROR  - TX error insert             */
-  lmc_t1_write (sc, 0x74, 0x00);	/* TMAN    - TX manual Sa/FEBE config    */
-  lmc_t1_write (sc, 0x75, 0x00);	/* TALM    - TX alarm signal config      */
-  lmc_t1_write (sc, 0x76, 0x00);	/* TPATT   - TX test pattern config      */
-  lmc_t1_write (sc, 0x77, 0x00);	/* TLB     - TX inband loopback config   */
-  lmc_t1_write (sc, 0x90, 0x05);	/* CLAD_CR - clock rate adapter config   */
+
+  /*
+   * RPATT
+   * Zero the test pattern generator
+   */
+  lmc_t1_write (sc, 0x41, 0x00);
+
+  /*
+   * RLB
+   * Loop back code detector
+   * DN_LEN: Down length is 8 bits
+   * UP_LEN: 5 bits
+   */
+  lmc_t1_write (sc, 0x42, 0x09);
+
+  /*
+   * LBA: Loopback activate
+   * LBA[6]: 1
+   * Loopback activate code
+   */
+  lmc_t1_write (sc, 0x43, 0x08);
+
+  /*
+   * LBD: Loopback deactivate
+   *
+   * Loopback deactivate code
+   */
+  lmc_t1_write (sc, 0x44, 0x24);
+
+  /*
+   * RALM: Receive Alarm Signal Configuration
+   *
+   * Set 0 which seems to be narmal alarms
+   */
+  lmc_t1_write (sc, 0x45, 0x00);
+
+  /*
+   * LATCH: Alarm/Error/Cournetr Latch register
+   *
+   * STOP_CNT: Stop error counters durring RLOF/RLOS/RAIS
+   */
+  lmc_t1_write (sc, 0x46, 0x08);
+
+  /*
+   * TLIU_CR: Transmit LIU Control Register
+   *
+   * TERM: External Transmit termination
+   * LBO: No line buildout
+   * Pulse shape from N8370DSE: 3-66
+   * // PULSE: 000 = 0 - 133ft 100 ohm twisted pair T1 DSX
+   * PULSE: 111 = Long Haul FCC Part 68 100 ohm twisted T1 CSU/NCTE
+   */
+  
+  lmc_t1_write (sc, 0x68, 0x4E);
+
+  /*
+   * TCR0: Transmit Framer Configuration
+   *
+   * TFRAME: 1101 == ESF + Froce CRC
+   */
+  lmc_t1_write (sc, 0x70, 0x0D);
+
+  /*
+   * TCR1: Transmit Configuration Registers
+   *
+   * TLOFA: 2 out of 4 bit errors = LOF
+   * TZCS: 000VB0VB Table 3-20 page 3-72
+   */
+  lmc_t1_write (sc, 0x71, 0x05);
+
+  /*
+   * TFRM: Transmit Frame Format
+   *
+   * INS_MF: Insert Multiframe aligement
+   * INS_CRC: Insert CRC
+   * INS_FBIT: Insert Framing
+   */
+  lmc_t1_write (sc, 0x72, 0x0B);
+
+  /*
+   * TERROR
+   *
+   * Don't xmit any errors
+   */
+  lmc_t1_write (sc, 0x73, 0x00);
+
+  /*
+   * TMAN: Tranimit Mahual Sa-byte/FEBE configuration
+   */
+  lmc_t1_write (sc, 0x74, 0x00);
+
+
+  /*
+   * TALM: Transmit Alarm Signal Configuration
+   *
+   * Don't use any of these auto alarms
+   */
+  lmc_t1_write (sc, 0x75, 0x00);
+
+
+  /*
+   * TPATT: Transmit Pattern Canfiguration
+   *
+   * No special test patterns
+   */
+  lmc_t1_write (sc, 0x76, 0x00);
+
+  /*
+   * TLB: Transmit Inband Loopback Codhe Configuration
+   *
+   * Not enabled
+   */
+  lmc_t1_write (sc, 0x77, 0x00);
+
+  /*
+   * CLAD_CR: Clack Rate Adapter Configuration
+   *
+   * LFGAIN: Loop filter gain 1/2^6
+   */
+  lmc_t1_write (sc, 0x90, 0x06);	/* CLAD_CR - clock rate adapter config   */
+
+  /*
+   * CSEL: CLAD Frequency Select
+   *
+   * CLADV: 0000 - 1024 kHz
+   * CLADO: 0101 - 1544 kHz
+   */
   lmc_t1_write (sc, 0x91, 0x05);	/* CSEL    - clad freq sel               */
-  lmc_t1_write (sc, 0xA6, 0x00);	/* DL1_CTL - DL1 control                 */
+
+  /*
+   * CPHASE: CLAD Phase detector
+   */
+  lmc_t1_write (sc, 0x92, 0x00);
+
+  /*
+   * CTEST: Clad Test
+   *
+   * No tests
+   */
+  lmc_t1_write (sc, 0x93, 0x00);
+
+  /*
+   * BOP: Bop receiver
+   *
+   * Enable, 25 messages receive, 25 send, BOP has priority over FDL
+   */
+  lmc_t1_write (sc, 0xA0, 0xea);        /* BOP     - Bit oriented protocol xcvr  */
+
+  /*
+   * Setup required to activae BOP.
+   * See table: 3-22 page 3-87
+   * See at the end
+   */
+  lmc_t1_write (sc, 0xA4, 0x40);        /* DL1_TS  - DL1 time slot enable        */
+  lmc_t1_write (sc, 0xA5, 0x00);        /* DL1_BIT - DL1 bit enable              */
+  lmc_t1_write (sc, 0xA6, 0x03);        /* DL1_CTL - DL1 control                 */
+  lmc_t1_write (sc, 0xA7, 0x00);        /* RDL1_FFC - DL1 FIFO Size */
+  lmc_t1_write (sc, 0xAB, 0x00);        /* TDL1_FFC - DL1 Empty Control*/
+
+  /*
+   * PRM: FDL PRM Messages
+   *
+   * Disable all automatic FDL messages
+   */
+  
+  lmc_t1_write (sc, 0xAA, 0x00);        /* PRM     - performance report message  */
+
+  /*
+   * DLC2 Control
+   *
+   * TDL2_EN: Disable transmit
+   * RDL2_EN: Disable receive
+   */
   lmc_t1_write (sc, 0xB1, 0x00);	/* DL2_CTL - DL2 control                 */
+  /*
+   * SBI_CR: System Bus Interface Configuration
+   *
+   * SBI_OE: Enable system bus
+   * SBI: T1 at 1544 with 24+fbit Page 3-113
+   */
   lmc_t1_write (sc, 0xD0, 0x47);	/* SBI_CR  - sys bus iface config        */
-  lmc_t1_write (sc, 0xD1, 0x70);	/* RSB_CR  - RX sys bus config           */
+  /*
+   * RSB_CR: Receive System Bus Coniguration
+   *
+   * SIG_OFF: RPCMO signalling off
+   * RPCM_NEG: Output on falling edge
+   * RSYN_NEG: Output sync an negative edge of clock
+   *
+   */
+  lmc_t1_write (sc, 0xD1, 0x70);
+
+  /*
+   * TSB_CR: Transmit System Bus  Configuration
+   *
+   * TPCM_NEG: Tranimettr multiframe follows TSB
+   * TSYN_NEG: TFSYNC or TMSYNC on falling edge output
+   */
   lmc_t1_write (sc, 0xD4, 0x30);	/* TSB_CR  - TX sys bus config           */
+
   for (i = 0; i < 32; i++)
     {
       lmc_t1_write (sc, 0x0E0 + i, 0x00);	/* SBCn - sys bus per-channel ctl    */
       lmc_t1_write (sc, 0x100 + i, 0x00);	/* TPCn - TX per-channel ctl         */
       lmc_t1_write (sc, 0x180 + i, 0x00);	/* RPCn - RX per-channel ctl         */
     }
+  for (i=1; i<25; i++)
+      lmc_t1_write (sc, 0x0E0 + i, 0x01);       /* SBCn - sys bus per-channel ctl    */
   for (i = 1; i < 25; i++)
     {
       lmc_t1_write (sc, 0x0E0 + i, 0x0D);	/* SBCn - sys bus per-channel ctl    */
     }
 
+  /*
+   * Seems to get lost sometimes
+   */
+  lmc_t1_write (sc, 0xA4, 0x40);        /* DL1_TS  - DL1 time slot enable        */
+  lmc_t1_write (sc, 0xA5, 0x00);        /* DL1_BIT - DL1 bit enable              */
+  lmc_t1_write (sc, 0xA6, 0x03);        /* DL1_CTL - DL1 control                 */
+  lmc_t1_write (sc, 0xA7, 0x00);        /* RDL1_FFC - DL1 FIFO Size */
+  lmc_t1_write (sc, 0xAB, 0x00);        /* TDL1_FFC - DL1 Empty Control*/
+
+  /*
+   * Basic setup is done, now setup modes like SF AMI, and
+   * Fractional T1.
+   */
+
+  if(sc->t1_amisf != 0){
+      /*
+       * Set ami line codeing
+       */
+      lmc_t1_write (sc, 0x40, 0x83);
+      lmc_t1_write (sc, 0x71, 0x07); // 0x03 is ami
+
+      /*
+       * Set SF framing
+       */
+      lmc_t1_write (sc, 0x70, 0x04);
+      lmc_t1_write (sc, 0x72, 0x09);
+      lmc_t1_write (sc, 0x01, 0x09);
+
+      lmc_t1_write (sc, 0x46,0x00);
+      lmc_t1_write (sc, 0xa6,0x00);
+      lmc_t1_write (sc, 0xa0,0x00);
+
+      /* Setup Loopback */
+      lmc_t1_write (sc, 0x0d, 0xc0);
+      lmc_t1_write (sc, 0x42, 0x09);
+      lmc_t1_write (sc, 0x43, 0x08);
+      lmc_t1_write (sc, 0x44, 0x24);
+
+
+      if(sc->t1_amisf == 2 && sc->t1_frac_mask == 0){
+          sc->t1_frac_mask = 0xfffffffe;
+      }
+  }
+
+  if(sc->t1_frac_mask){
+      u32 mask = sc->t1_frac_mask;
+      int i;
+      int onoff;
+      for(i = 24; i >= 1; i--){
+          onoff = mask & 0x1;
+          mask >>= 1;
+          if(onoff == 0){
+              lmc_t1_write(sc, 0x0e0+i,0x01);
+              lmc_t1_write(sc, 0x100+i,0x20);
+              lmc_t1_write(sc, 0x140+i,0x7f);
+          }
+          else{
+              lmc_t1_write(sc, 0x0e0+i,0x0D);
+              lmc_t1_write(sc, 0x100+i,0x00);
+              lmc_t1_write(sc, 0x140+i,0x00);
+          }
+      }
+      mii16 |= LMC_MII16_T1_INVERT;
+      lmc_mii_writereg (sc, 0, 16, mii16);
+  }
+  else {
+      mii16 &= ~LMC_MII16_T1_INVERT; /* Unless we're on AMI SF don't invert */
+  }
+
+  if(sc->t1_loop_time){
+	  lmc_t1_write(sc, 0x02, 0xa3);
+  }
+
+  lmc_gpio_mkoutput(sc, LMC_GEP_T1_INT);
+  sc->lmc_gpio |= LMC_GEP_T1_INT;
+  LMC_CSR_WRITE(sc, csr_gp, sc->lmc_gpio);
+
   mii16 |= LMC_MII16_T1_XOE;
   lmc_mii_writereg (sc, 0, 16, mii16);
   sc->lmc_miireg16 = mii16;
 }
 
 static void
-lmc_t1_default (lmc_softc_t * const sc)
+lmc_t1_default (lmc_softc_t * const sc) /*fold00*/
 {
   sc->lmc_miireg16 = LMC_MII16_LED_ALL;
   sc->lmc_media->set_link_status (sc, LMC_LINK_DOWN);
@@ -1029,7 +1438,7 @@
 /* * Given a user provided state, set ourselves up to match it.  This will * always reset the card if needed.
  */
 static void
-lmc_t1_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl)
+lmc_t1_set_status (lmc_softc_t * const sc, lmc_ctl_t * ctl) /*fold00*/
 {
   if (ctl == NULL)
     {
@@ -1053,7 +1462,7 @@
  * return hardware link status.
  * 0 == link is down, 1 == link is up.
  */ static int
-lmc_t1_get_link_status (lmc_softc_t * const sc)
+lmc_t1_get_link_status (lmc_softc_t * const sc) /*fold00*/
 {
     u_int16_t link_status;
     int ret = 1;
@@ -1067,19 +1476,23 @@
    * led3 red    = Loss of Signal (LOS) or out of frame (OOF)
    *               conditions detected on T3 receive signal
    */
-    
+    lmc_trace(sc->lmc_device, "lmc_t1_get_link_status in");
     lmc_led_on(sc, LMC_DS3_LED2);
 
     lmc_mii_writereg (sc, 0, 17, T1FRAMER_ALARM1_STATUS);
     link_status = lmc_mii_readreg (sc, 0, 18);
 
 
-    if (link_status & T1F_RAIS) {			/* turn on blue LED */
+    if ((link_status & T1F_RAIS) || sc->blue_alarm) {			/* turn on blue LED */
         ret = 0;
         if(sc->last_led_err[1] != 1){
             printk(KERN_WARNING "%s: Receive AIS/Blue Alarm. Far end in RED alarm\n", sc->name);
         }
+        if(sc->blue_alarm != 0){
+            sc->blue_alarm--;
+        }
         lmc_led_on(sc, LMC_DS3_LED1);
+        
         sc->last_led_err[1] = 1;
     }
     else {
@@ -1091,20 +1504,26 @@
     }
 
     /*
-     * Yellow Alarm is nasty evil stuff, looks at data patterns
+     * AMI: Yellow Alarm is nasty evil stuff, looks at data patterns
      * inside the channel and confuses it with HDLC framing
      * ignore all yellow alarms.
      *
+     * B8ZS: RAI/Yellow alarm is implemented via a continous BOP
+     * message.
+     *
      * Do listen to MultiFrame Yellow alarm which while implemented
      * different ways isn't in the channel and hence somewhat
      * more reliable
      */
 
-    if (link_status & T1F_RMYEL) {
+    if ((link_status & T1F_RMYEL) || sc->yellow_alarm) {
         ret = 0;
         if(sc->last_led_err[0] != 1){
             printk(KERN_WARNING "%s: Receive Yellow AIS Alarm\n", sc->name);
         }
+        if(sc->yellow_alarm > 0){
+            sc->yellow_alarm--;
+        }
         lmc_led_on(sc, LMC_DS3_LED0);
         sc->last_led_err[0] = 1;
     }
@@ -1120,10 +1539,21 @@
      * Loss of signal and los of frame
      * Use the green bit to identify which one lit the led
      */
-    if(link_status & T1F_RLOF){
+    if((link_status & T1F_RLOF) || sc->red_alarm){
         ret = 0;
         if(sc->last_led_err[3] != 1){
-            printk(KERN_WARNING "%s: Local Red Alarm: Loss of Framing\n", sc->name);
+            printk(KERN_WARNING "%s: Local Red Alarm: Loss of Framing (LOF)\n", sc->name);
+            /*
+             * Send AIS/Yellow
+             * So send continuous AIS/Yellom BOP messages
+             */
+            if(!sc->t1_amisf){
+                lmc_t1_write (sc, 0xA0, 0xee); /* Cont BOP */
+                lmc_t1_write (sc, 0xA1, 0x00); /* 0x00 is AIS/yellow BOP */
+            }
+        }
+        if(sc->red_alarm != 0){
+            sc->red_alarm--;
         }
         lmc_led_on(sc, LMC_DS3_LED3);
         sc->last_led_err[3] = 1;
@@ -1132,16 +1562,34 @@
     else {
         if(sc->last_led_err[3] != 0){
             printk(KERN_WARNING "%s: End Red Alarm (LOF)\n", sc->name);
+            /*
+             * Stop sending continuous BOP
+             * hence end yellow alarm
+             */
+            if(!sc->t1_amisf){
+                lmc_t1_write (sc, 0xA0, 0xea); /* Normal 25 BOP */
+            }
         }
         if( ! (link_status & T1F_RLOS))
             lmc_led_off(sc, LMC_DS3_LED3);
         sc->last_led_err[3] = 0;
     }
     
-    if(link_status & T1F_RLOS){
+    if((link_status & T1F_RLOS) || sc->red_alarm){
         ret = 0;
         if(sc->last_led_err[2] != 1){
-            printk(KERN_WARNING "%s: Local Red Alarm: Loss of Signal\n", sc->name);
+            printk(KERN_WARNING "%s: Local Red Alarm: Loss of Signal (LOS)\n", sc->name);
+            /*
+             * Send AIS/Yellow
+             * So send continuous AIS/Yellom BOP messages
+             */
+            if(!sc->t1_amisf){
+                lmc_t1_write (sc, 0xA0, 0xee); /* Cont BOP */
+                lmc_t1_write (sc, 0xA1, 0x00); /* 0x00 is AIS/yellow BOP */
+            }
+        }
+        if(sc->red_alarm != 0){
+            sc->red_alarm--;
         }
         lmc_led_on(sc, LMC_DS3_LED3);
         sc->last_led_err[2] = 1;
@@ -1150,6 +1598,14 @@
     else {
         if(sc->last_led_err[2] != 0){
             printk(KERN_WARNING "%s: End Red Alarm (LOS)\n", sc->name);
+            /*
+             * Stop sending continuous BOP
+             * hence end yellow alarm
+             */
+            if(!sc->t1_amisf){
+                lmc_t1_write (sc, 0xA0, 0xea); /* Normal 25 BOP */
+            }
+
         }
         if( ! (link_status & T1F_RLOF))
             lmc_led_off(sc, LMC_DS3_LED3);
@@ -1161,6 +1617,9 @@
     lmc_mii_writereg (sc, 0, 17, T1FRAMER_ALARM2_STATUS);
     sc->lmc_xinfo.t1_alarm2_status = lmc_mii_readreg (sc, 0, 18);
 
+    
+    lmc_trace(sc->lmc_device, "lmc_t1_get_link_status out");
+
     return ret;
 }
 
@@ -1168,17 +1627,19 @@
  * 1 == T1 Circuit Type , 0 == E1 Circuit Type
  */
 static void
-lmc_t1_set_circuit_type (lmc_softc_t * const sc, int ie)
+lmc_t1_set_circuit_type (lmc_softc_t * const sc, int ie) /*fold00*/
 {
+  int old;
+  old = sc->ictl.circuit_type;
   if (ie == LMC_CTL_CIRCUIT_TYPE_T1) {
-      sc->lmc_miireg16 |= LMC_MII16_T1_Z;
       sc->ictl.circuit_type = LMC_CTL_CIRCUIT_TYPE_T1;
-      printk(KERN_INFO "%s: In T1 Mode\n", sc->name);
+      if(old != sc->ictl.circuit_type)
+          printk(KERN_INFO "%s: In T1 Mode\n", sc->name);
   }
   else {
-      sc->lmc_miireg16 &= ~LMC_MII16_T1_Z;
       sc->ictl.circuit_type = LMC_CTL_CIRCUIT_TYPE_E1;
-      printk(KERN_INFO "%s: In E1 Mode\n", sc->name);
+      if(old != sc->ictl.circuit_type)
+          printk(KERN_INFO "%s: In E1 Mode (non functional)\n", sc->name);
   }
 
   lmc_mii_writereg (sc, 0, 16, sc->lmc_miireg16);
@@ -1188,7 +1649,7 @@
 /*
  * 0 == 16bit, 1 == 32bit */
 static void
-lmc_t1_set_crc_length (lmc_softc_t * const sc, int state)
+lmc_t1_set_crc_length (lmc_softc_t * const sc, int state) /*fold00*/
 {
   if (state == LMC_CTL_CRC_LENGTH_32)
     {
@@ -1213,31 +1674,167 @@
  * 1 == internal, 0 == external
  */
 static void
-lmc_t1_set_clock (lmc_softc_t * const sc, int ie)
+lmc_t1_set_clock (lmc_softc_t * const sc, int ie) /*fold00*/
 {
-  if (ie == LMC_CTL_CLOCK_SOURCE_EXT)
-    {
-      sc->lmc_gpio &= ~(LMC_GEP_SSI_TXCLOCK);
-      LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
-      sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_EXT;
-      printk (LMC_PRINTF_FMT ": clock external\n", LMC_PRINTF_ARGS);
-    }
-  else
-    {
-      sc->lmc_gpio |= LMC_GEP_SSI_TXCLOCK;
-      LMC_CSR_WRITE (sc, csr_gp, sc->lmc_gpio);
-      sc->ictl.clock_source = LMC_CTL_CLOCK_SOURCE_INT;
-      printk (LMC_PRINTF_FMT ": clock internal\n", LMC_PRINTF_ARGS);
-    }
+    /*
+     * Not set this way, done through T1 specific IOCTL
+     */
 }
 
-static void
-lmc_t1_watchdog (lmc_softc_t * const sc)
+static void lmc_t1_watchdog (lmc_softc_t * const sc) /*fold00*/
 {
+        if(sc->loop_timer != 0){
+                sc->loop_timer--;
+                if(sc->loop_timer == 0){
+                        if(lmc_t1_read(sc, 0x014) != 0x00){
+                                printk(KERN_DEBUG "%s: Timeout: Loop down\n", sc->name);
+                                lmc_t1_write(sc, 0x014, 0x00);
+                                /*
+                                 * If we're not loop timed
+                                 * go back to intelnal clack
+                                 */
+                                if(! sc->t1_loop_time){
+                                    lmc_t1_write(sc, 0x02, 0x4b);
+                                }
+                        }
+                }
+        }
+        /*
+         * Check for BOP messages on A2 rev boards
+         */
+        lmc_t1_got_interupt (sc);
+}
+
+static int lmc_t1_ioctl (lmc_softc_t * const sc, void *d) /*fold00*/
+{
+        struct lmc_st1f_control ctl;
+        int ret;
+
+        LMC_COPY_FROM_USER(&ctl, d, sizeof (struct lmc_st1f_control));
+
+        switch(ctl.command){
+        case lmc_st1f_write:
+                lmc_t1_write(sc, ctl.address, ctl.value);
+                ret = 0;
+                break;
+        case lmc_st1f_read:
+                ctl.value = lmc_t1_read(sc, ctl.address) & 0xff;
+                LMC_COPY_TO_USER(d, &ctl, sizeof (struct lmc_st1f_control));
+                ret = 0;
+                break;
+        case lmc_st1f_inv:
+                if(ctl.value == 1){
+                  sc->lmc_miireg16 |= LMC_MII16_T1_INVERT;
+                  lmc_mii_writereg (sc, 0, 16,   sc->lmc_miireg16);
+                  printk("%s: Request to invert data\n", sc->name);
+                }
+                else {
+                  sc->lmc_miireg16 &= ~LMC_MII16_T1_INVERT;
+                  lmc_mii_writereg (sc, 0, 16,   sc->lmc_miireg16);
+                  printk("%s: Request to non-invert data\n", sc->name);
+                }
+                ret = 0;
+                break;
+        case lmc_st1f_amisf:
+                sc->t1_amisf = ctl.value;
+                if(sc->lmc_ok){
+                 lmc_t1_init(sc);
+                }
+                ret = 0;
+                break;
+        case lmc_st1f_frac:
+                LMC_COPY_FROM_USER(&sc->t1_frac_mask, ctl.data, sizeof (u32));
+                if(sc->lmc_ok){
+                 lmc_t1_init(sc);
+                }
+                ret = 0;
+                break;
+        case lmc_st1f_loopt:
+		sc->t1_loop_time = ctl.value;
+		if(sc->lmc_ok){
+			lmc_t1_init(sc);
+		}
+		ret = 0;
+		break;
+        default:
+        ret = -ENOSYS;
+        }
+
+        return ret;
 }
 
-static void
-lmc_set_protocol (lmc_softc_t * const sc, lmc_ctl_t * ctl)
+static int lmc_t1_got_interupt (lmc_softc_t * const sc) /*fold00*/
+{
+        u8 reg;
+
+        /* And it with the mask in case we're polling
+         * and we have want the int disabsled
+         */
+        reg = lmc_t1_read(sc, 0x00a) & lmc_t1_read(sc, 0x12);
+
+        if(reg & 0x80){
+//                printk(KERN_DEBUG "%s: Got Inbound BOP message 0x%02x\n", sc->name, lmc_t1_read(sc, 0x0a2) & 0x3f);
+                switch(lmc_t1_read(sc, 0x0a2) & 0x3f) {
+                case 0x00: /* Yellow Alarm */
+                        sc->yellow_alarm = 5; /* Start Yellow Alarm for 3 seconds */
+                        break;
+
+                case 0x07: /* Loop up */
+                        printk(KERN_DEBUG "%s: BOP: Loop up\n", sc->name);
+                        sc->loop_timer = 305;
+                        lmc_t1_write(sc, 0x002, 0xa3); /* Enter loop timeing */
+                        lmc_t1_write(sc, 0x014, 0x04); /* Loop towards net */
+                        break;
+                        
+                case 0x0b: /* Pay load loop back */
+                        printk(KERN_DEBUG "%s: BOP: Payload Loop up\n", sc->name);
+                        sc->loop_timer = 305;
+                        lmc_t1_write(sc, 0x014, 0x08);
+                        break;
+                        
+                case 0x1a:
+                case 0x1c: /* Loop down T1.409, etc */
+                case 0x1d: /* Loop down T1.403 */
+                        printk(KERN_DEBUG "%s: BOP: Loop down\n", sc->name);
+                        lmc_t1_write(sc, 0x014, 0x00); /* Loop down */
+                        /*
+                         * If we're not loop timed
+                         * go back to intelnal clack
+                         */
+                        if(! sc->t1_loop_time){
+                            lmc_t1_write(sc, 0x02, 0x4b);
+                        }
+
+                        break;
+
+                }
+        }
+
+        reg = lmc_t1_read(sc, 0x005) & lmc_t1_read(sc, 0x0d);
+        
+        if(reg & 0x04){
+            printk(KERN_DEBUG "%s: Inband: Loop up\n", sc->name);
+            sc->loop_timer = 305;
+            lmc_t1_write(sc, 0x002, 0xa3); /* Enter loop timeing */
+            lmc_t1_write(sc, 0x014, 0x04); /* Loop up */
+        }
+        if(reg & 0x08){
+            printk(KERN_DEBUG "%s: Inband: Loop down\n", sc->name);
+            lmc_t1_write(sc, 0x014, 0x00);
+            /*
+             * If we're not loop timed
+             * go back to intelnal clack
+             */
+            if(! sc->t1_loop_time){
+                lmc_t1_write(sc, 0x02, 0x4b);
+            }
+        }
+        
+        return 0;
+}
+
+
+static void lmc_set_protocol (lmc_softc_t * const sc, lmc_ctl_t * ctl) /*fold00*/
 {
   if (ctl == 0)
     {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_proto.c linux.17p18/drivers/net/lmc/lmc_proto.c
--- linux.vanilla/drivers/net/lmc/lmc_proto.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/net/lmc/lmc_proto.c	Tue Aug  1 07:59:41 2000
@@ -0,0 +1,270 @@
+ /*
+  * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
+  * All rights reserved.  www.lanmedia.com
+  *
+  * This code is written by:
+  * Andrew Stanley-Jones (asj@cban.com)
+  *
+  * With Help By:
+  * David Boggs
+  * Ron Crane
+  * Allan Cox
+  *
+  * This software may be used and distributed according to the terms
+  * of the GNU Public License version 2, incorporated herein by reference.
+  *
+  * Driver for the LanMedia LMC5200, LMC5245, LMC1000, LMC1200 cards.
+  */
+
+#include <linux/version.h>
+//#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <asm/segment.h>
+#include <asm/smp.h>
+
+#include <linux/in.h>
+#include <linux/if_arp.h>
+#include <asm/processor.h>             /* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include "../syncppp.h"
+#include <linux/inet.h>
+#include <linux/tqueue.h>
+#include <linux/proc_fs.h>
+
+#include "lmc_ver.h"
+#include "lmc.h"
+#include "lmc_var.h"
+#include "lmc_debug.h"
+#include "lmc_ioctl.h"
+#include "lmc_proto.h"
+//#include "lmc_proto_raw.h"
+
+/*
+ * The compile-time variable SPPPSTUP causes the module to be
+ * compiled without referencing any of the sync ppp routines.
+ */
+#ifdef SPPPSTUB
+#define SYNC_PPP_init() (void)0
+#define SPPP_detach(d)	(void)0
+#define SPPP_open(d)	0
+#define SPPP_reopen(d)	(void)0
+#define SPPP_close(d)	(void)0
+#define SPPP_attach(d)	(void)0
+#define SPPP_do_ioctl(d,i,c)	-EOPNOTSUPP
+#else
+#if LINUX_VERSION_CODE < 0x20211
+#define SYNC_PPP_init	sync_ppp_init
+#define SPPP_attach(x)	sppp_attach((struct ppp_device *)(x)->lmc_device)
+#define SPPP_detach(x)	sppp_detach((x)->lmc_device)
+#define SPPP_open(x)	sppp_open((x)->lmc_device)
+#define SPPP_reopen(x)	sppp_reopen((x)->lmc_device)
+#define SPPP_close(x)	sppp_close((x)->lmc_device)
+#define SPPP_do_ioctl(x, y, z)	sppp_do_ioctl((x)->lmc_device, (y), (z))
+#else
+#define SYNC_PPP_init	sync_ppp_init
+#define SPPP_attach(x)	sppp_attach((x)->pd)
+#define SPPP_detach(x)	sppp_detach((x)->pd->dev)
+#define SPPP_open(x)	sppp_open((x)->pd->dev)
+#define SPPP_reopen(x)	sppp_reopen((x)->pd->dev)
+#define SPPP_close(x)	sppp_close((x)->pd->dev)
+#define SPPP_do_ioctl(x, y, z)	sppp_do_ioctl((x)->pd->dev, (y), (z))
+#endif
+#endif
+
+static int lmc_first_ppp_load = 0;
+
+// init
+void lmc_proto_init(lmc_softc_t *sc) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_init in");
+    switch(sc->if_type){
+    case LMC_PPP:
+        if(lmc_first_ppp_load == 0) {
+            lmc_first_ppp_load = 1;
+#ifndef MODULE
+            SYNC_PPP_init();
+#endif
+        }
+        
+#if LINUX_VERSION_CODE >= 0x20210
+        sc->pd = kmalloc(sizeof(struct ppp_device), GFP_KERNEL);
+        sc->pd->dev = sc->lmc_device;
+#endif
+        sc->if_ptr = sc->pd;
+        break;
+    case LMC_RAW:
+        break;
+    default:
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_init out");
+}
+
+// attach
+void lmc_proto_attach(lmc_softc_t *sc) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_attach in");
+    switch(sc->if_type){
+    case LMC_PPP:
+        {
+            struct net_device *dev = sc->lmc_device;
+            SPPP_attach(sc);
+            dev->do_ioctl = lmc_ioctl;
+        }
+        break;
+    case LMC_NET:
+        {
+            struct net_device *dev = sc->lmc_device;
+            /*
+             * They set a few basics because they don't use sync_ppp
+             */
+            dev->flags |= IFF_POINTOPOINT;
+            dev->hard_header = 0;
+            dev->hard_header_len = 0;
+            dev->addr_len = 0;
+        }
+    case LMC_RAW: /* Setup the task queue, maybe we should notify someone? */
+        {
+        }
+    default:
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_attach out");
+}
+
+// detach
+void lmc_proto_detach(lmc_softc_t *sc) /*FOLD00*/
+{
+    switch(sc->if_type){
+    case LMC_PPP:
+        SPPP_detach(sc);
+        break;
+    case LMC_RAW: /* Tell someone we're detaching? */
+        break;
+    default:
+        break;
+    }
+
+}
+
+// reopen
+void lmc_proto_reopen(lmc_softc_t *sc) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_reopen in");
+    switch(sc->if_type){
+    case LMC_PPP:
+        SPPP_reopen(sc);
+        break;
+    case LMC_RAW: /* Reset the interface after being down, prerape to receive packets again */
+        break;
+    default:
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_reopen out");
+}
+
+
+// ioctl
+int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_ioctl out");
+    switch(sc->if_type){
+    case LMC_PPP:
+        return SPPP_do_ioctl (sc, ifr, cmd);
+        break;
+    default:
+        return -EOPNOTSUPP;
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_ioctl out");
+}
+
+// open
+void lmc_proto_open(lmc_softc_t *sc) /*FOLD00*/
+{
+    int ret;
+
+    lmc_trace(sc->lmc_device, "lmc_proto_open in");
+    switch(sc->if_type){
+    case LMC_PPP:
+        ret = SPPP_open(sc);
+        if(ret < 0)
+            printk("%s: syncPPP open failed: %d\n", sc->name, ret);
+        break;
+    case LMC_RAW: /* We're about to start getting packets! */
+        break;
+    default:
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_open out");
+}
+
+// close
+
+void lmc_proto_close(lmc_softc_t *sc) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_close in");
+    switch(sc->if_type){
+    case LMC_PPP:
+        SPPP_close(sc);
+        break;
+    case LMC_RAW: /* Interface going down */
+        break;
+    default:
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_close out");
+}
+
+unsigned short lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_type in");
+    switch(sc->if_type){
+    case LMC_PPP:
+        return htons(ETH_P_WAN_PPP);
+        break;
+    case LMC_NET:
+        return htons(ETH_P_802_2);
+        break;
+    case LMC_RAW: /* Packet type for skbuff kind of useless */
+        return htons(ETH_P_802_2);
+        break;
+    default:
+        printk(KERN_WARNING "%s: No protocol set for this interface, assuming 802.2 (which is wrong!!)\n", sc->name);
+        return htons(ETH_P_802_2);
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_tye out");
+
+}
+
+void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb) /*FOLD00*/
+{
+    lmc_trace(sc->lmc_device, "lmc_proto_netif in");
+    switch(sc->if_type){
+    case LMC_PPP:
+    case LMC_NET:
+    default:
+        netif_rx(skb);
+        break;
+    case LMC_RAW:
+        break;
+    }
+    lmc_trace(sc->lmc_device, "lmc_proto_netif out");
+}
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_proto.h linux.17p18/drivers/net/lmc/lmc_proto.h
--- linux.vanilla/drivers/net/lmc/lmc_proto.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/net/lmc/lmc_proto.h	Tue Aug  1 07:59:41 2000
@@ -0,0 +1,15 @@
+#ifndef _LMC_PROTO_H_
+#define _LMC_PROTO_H_
+
+void lmc_proto_init(lmc_softc_t *sc);
+void lmc_proto_attach(lmc_softc_t *sc);
+void lmc_proto_detach(lmc_softc_t *sc);
+void lmc_proto_reopen(lmc_softc_t *sc);
+int lmc_proto_ioctl(lmc_softc_t *sc, struct ifreq *ifr, int cmd);
+void lmc_proto_open(lmc_softc_t *sc);
+void lmc_proto_close(lmc_softc_t *sc);
+unsigned short lmc_proto_type(lmc_softc_t *sc, struct sk_buff *skb);
+void lmc_proto_netif(lmc_softc_t *sc, struct sk_buff *skb);
+int lmc_skb_rawpackets(char *buf, char **start, off_t offset, int len, int unused);
+
+#endif
\ No newline at end of file
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_var.h linux.17p18/drivers/net/lmc/lmc_var.h
--- linux.vanilla/drivers/net/lmc/lmc_var.h	Fri Apr 21 23:18:39 2000
+++ linux.17p18/drivers/net/lmc/lmc_var.h	Thu Aug 17 18:01:51 2000
@@ -1,7 +1,7 @@
 #ifndef _LMC_VAR_H_
 #define _LMC_VAR_H_
 
-/* $Id: lmc_var.h,v 1.14 2000/01/21 13:29:50 asj Exp $ */
+/* $Id: lmc_var.h,v 1.24 2000/06/16 23:37:16 asj Exp $ */
 
  /*
   * Copyright (c) 1997-2000 LAN Media Corporation (LMC)
@@ -18,6 +18,7 @@
   */
 
 #include <linux/timer.h>
+#include <linux/version.h>
 
 #ifndef __KERNEL__
 typedef signed char s8;
@@ -32,6 +33,14 @@
 typedef signed long long s64;
 typedef unsigned long long u64;
 
+#if LINUX_VERSION_CODE >= 0x20363
+struct timer_list {
+};
+#endif
+
+typedef u32 spinlock_t;
+typedef u32 dma_addr_t;
+
 #define BITS_PER_LONG 32 
 
 #endif
@@ -44,7 +53,7 @@
 typedef struct lmc___media lmc_media_t;
 typedef struct lmc___ctl lmc_ctl_t;
 
-#define lmc_csrptr_t	u32
+#define lmc_csrptr_t    unsigned long
 #define u_int16_t	u16
 #define u_int8_t	u8
 #define tulip_uint32_t	u32
@@ -69,13 +78,13 @@
 #define LMC_CSR_READ(sc, csr) \
 	inl((sc)->lmc_csrs.csr)
 #define LMC_CSR_WRITE(sc, reg, val) \
-	outl(val, (sc)->lmc_csrs.reg)
+	outl((val), (sc)->lmc_csrs.reg)
 
-#ifdef _LINUX_DELAY_H
-	#define SLOW_DOWN_IO udelay(2);
-	#undef __SLOW_DOWN_IO
-	#define __SLOW_DOWN_IO udelay(2);
-#endif
+//#ifdef _LINUX_DELAY_H
+//	#define SLOW_DOWN_IO udelay(2);
+//	#undef __SLOW_DOWN_IO
+//	#define __SLOW_DOWN_IO udelay(2);
+//#endif
 
 #define DELAY(n) SLOW_DOWN_IO
 
@@ -83,10 +92,10 @@
 
 /* This macro sync's up with the mii so that reads and writes can take place */
 #define LMC_MII_SYNC(sc) do {int n=32; while( n >= 0 ) { \
-		LMC_CSR_WRITE((sc), csr_9, 0x20000); \
+                LMC_CSR_WRITE((sc), csr_9, 0x20000); \
 		lmc_delay(); \
 		LMC_CSR_WRITE((sc), csr_9, 0x30000); \
-		lmc_delay(); \
+                lmc_delay(); \
 		n--; }} while(0);
 
 struct lmc_regfile_t {
@@ -242,6 +251,8 @@
 	void	(* set_crc_length)(lmc_softc_t * const, int);
         void    (* set_circuit_type)(lmc_softc_t * const, int);
         void	(* watchdog)(lmc_softc_t * const);
+        int     (* ioctl)(lmc_softc_t * const, void *);
+        int     (* got_interupt)(lmc_softc_t * const);
 };
 
 
@@ -254,32 +265,32 @@
  */
 struct lmc_statistics
 {
-        int     rx_packets;             /* total packets received       */
-        int     tx_packets;             /* total packets transmitted    */
-	int     rx_bytes;
-        int     tx_bytes;
+        unsigned long     rx_packets;             /* total packets received       */
+        unsigned long     tx_packets;             /* total packets transmitted    */
+	unsigned long     rx_bytes;
+        unsigned long     tx_bytes;
         
-        int     rx_errors;              /* bad packets received         */
-        int     tx_errors;              /* packet transmit problems     */
-        int     rx_dropped;             /* no space in linux buffers    */
-        int     tx_dropped;             /* no space available in linux  */
-        int     multicast;              /* multicast packets received   */
-        int     collisions;
+        unsigned long     rx_errors;              /* bad packets received         */
+        unsigned long     tx_errors;              /* packet transmit problems     */
+        unsigned long     rx_dropped;             /* no space in linux buffers    */
+        unsigned long     tx_dropped;             /* no space available in linux  */
+        unsigned long     multicast;              /* multicast packets received   */
+        unsigned long     collisions;
 
         /* detailed rx_errors: */
-        int     rx_length_errors;
-        int     rx_over_errors;         /* receiver ring buff overflow  */
-        int     rx_crc_errors;          /* recved pkt with crc error    */
-        int     rx_frame_errors;        /* recv'd frame alignment error */
-        int     rx_fifo_errors;         /* recv'r fifo overrun          */
-        int     rx_missed_errors;       /* receiver missed packet       */
+        unsigned long     rx_length_errors;
+        unsigned long     rx_over_errors;         /* receiver ring buff overflow  */
+        unsigned long     rx_crc_errors;          /* recved pkt with crc error    */
+        unsigned long     rx_frame_errors;        /* recv'd frame alignment error */
+        unsigned long     rx_fifo_errors;         /* recv'r fifo overrun          */
+        unsigned long     rx_missed_errors;       /* receiver missed packet       */
 
         /* detailed tx_errors */
-        int     tx_aborted_errors;
-        int     tx_carrier_errors;
-        int     tx_fifo_errors;
-        int     tx_heartbeat_errors;
-        int     tx_window_errors;
+        unsigned long     tx_aborted_errors;
+        unsigned long     tx_carrier_errors;
+        unsigned long     tx_fifo_errors;
+        unsigned long     tx_heartbeat_errors;
+        unsigned long     tx_window_errors;
 
         /* for cslip etc */
         unsigned long rx_compressed;
@@ -296,6 +307,9 @@
         u_int32_t       tx_MaxXmtsB4Int;
         u_int32_t       tx_TimeoutCnt;
         u_int32_t       tx_OutOfSyncPtr;
+        u_int32_t       tx_tbusy0;
+        u_int32_t       tx_tbusy1;
+        u_int32_t       tx_tbusy_calls;
         u_int32_t       resetCount;
         u_int32_t       lmc_txfull;
         u_int32_t       tbusy;
@@ -353,10 +367,11 @@
  * forward decl
  */
 struct lmc___softc {
+        void                   *if_ptr;   /* General purpose pointer (used by SPPP >= 2.4) */
 	char                   *name;
 	u8			board_idx;
 	struct lmc_statistics   stats;
-	struct device          *lmc_device;
+	struct net_device          *lmc_device;
 
 	int                     hang, rxdesc, bad_packet, some_counter;
 	u_int32_t               txgo;
@@ -371,9 +386,12 @@
 	u_int32_t		lmc_gpio;	/* state of outputs */
 	struct sk_buff*		lmc_txq[LMC_TXDESCS];
 	struct sk_buff*		lmc_rxq[LMC_RXDESCS];
+	volatile
 	struct tulip_desc_t	lmc_rxring[LMC_RXDESCS];
+	volatile
 	struct tulip_desc_t	lmc_txring[LMC_TXDESCS];
 	unsigned int		lmc_next_rx, lmc_next_tx;
+	volatile
 	unsigned int		lmc_taint_tx, lmc_taint_rx;
 	int			lmc_tx_start, lmc_txfull;
 	int			lmc_txbusy;
@@ -382,27 +400,49 @@
 	int			last_link_status;
 	int			lmc_cardtype;
 	u_int32_t               last_frameerr;
-	lmc_media_t	       *lmc_media;
+        lmc_media_t	       *lmc_media;
 	struct timer_list	timer;
 	lmc_ctl_t		ictl;
 	u_int32_t		TxDescriptControlInit;  
-	struct device		*next_module;   /* Link to the next module  */
+	struct net_device      *next_module;   /* Link to the next module  */
 	int                     tx_TimeoutInd; /* additional driver state */
 	int                     tx_TimeoutDisplay;
 	unsigned int		lastlmc_taint_tx;
 	int                     lasttx_packets;
 	u_int32_t		tx_clockState;
 	u_int32_t		lmc_crcSize;
-	LMC_XINFO		lmc_xinfo; 
-	char                    lmc_yel, lmc_blue, lmc_red; /* for T1 and DS3 */
+	LMC_XINFO		lmc_xinfo;
         char                    lmc_timing; /* for HSSI and SSI */
         int                     got_irq;
 
         char                    last_led_err[4];
+        char                    yellow_alarm; /* Time in seconds to run yellow alarm for */
+        char                    red_alarm;    /* Time in seconds to run red alarm for */
+        char                    blue_alarm;   /* Time in seconds to run blue alarm for */
 
 #if LINUX_VERSION_CODE >= 0x20200
 	spinlock_t              lmc_lock;
 #endif
+#if LINUX_VERSION_CODE >= 0x20363
+        struct pci_dev          *pdev;
+        dma_addr_t              sc_dma_handle;
+        struct lmc___softc      *sc_dma;
+#endif
+        u_int16_t               if_type;       /* PPP or NET */
+        struct ppp_device       *pd;
+
+        /* Failure cases */
+        u8                       failed_ring;
+        u8                       failed_recv_alloc;
+
+        /* T1 Specicfic Variable */
+        u16                      loop_timer; /* Time out loop up requests */
+        u8                       t1_amisf;
+        u32                      t1_frac_mask;
+        u8                       t1_loop_time;
+
+        /* Structure check */
+        u32                     check;
 };
 
 #define LMC_PCI_TIME 1
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/lmc/lmc_ver.h linux.17p18/drivers/net/lmc/lmc_ver.h
--- linux.vanilla/drivers/net/lmc/lmc_ver.h	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/lmc/lmc_ver.h	Tue Aug  1 07:59:41 2000
@@ -29,8 +29,25 @@
   *
   */
 
+#if LINUX_VERSION_CODE < 0x20363
+#define net_device device
+#define dev_kfree_skb_irq LMC_DEV_KFREE_SKB
+#endif
+
+#if LINUX_VERSION_CODE < 0x20363
+#define LMC_XMITTER_BUSY(x) (x)->tbusy = 1
+#define LMC_XMITTER_FREE(x) (x)->tbusy = 0
+#define LMC_XMITTER_INIT(x) (x)->tbusy = 0
+#else
+#define LMC_XMITTER_BUSY(x) netif_stop_queue(x)
+#define LMC_XMITTER_FREE(x) netif_wake_queue(x)
+#define LMC_XMITTER_INIT(x) netif_start_queue(x)
+
+#endif
+
+
 #if LINUX_VERSION_CODE < 0x20100
-typedef unsigned int u_int32_t;
+//typedef unsigned int u_int32_t;
 
 #define  LMC_SETUP_20_DEV {\
                              int indx; \
@@ -41,7 +58,11 @@
                           dev->pa_addr = 0; \
                           dev->pa_brdaddr = 0; \
                           dev->pa_mask = 0xFCFFFFFF; \
-                          dev->pa_alen = 4;		/* IP addr.  sizeof(u32) */
+    dev->pa_alen = 4;		/* IP addr.  sizeof(u32) */
+
+#define cpu_to_le32(x) (x)
+#define le32_to_cpu(x) (x)
+#define le16_to_cpu(x) (x)
 
 #else
 
@@ -73,20 +94,20 @@
 #define LMC_SKB_FREE(skb, val)
 #endif
 
-#define LMC_SPIN_FLAGS                unsigned long flags;
 
-#if (LINUX_VERSION_CODE >= 0x20200)
+#if LINUX_VERSION_CODE >= 0x20200
 
+#define LMC_SPIN_FLAGS                unsigned long flags;
 #define LMC_SPIN_LOCK_INIT(x)         spin_lock_init(&(x)->lmc_lock);
 #define LMC_SPIN_UNLOCK(x)            ((x)->lmc_lock = SPIN_LOCK_UNLOCKED)
 #define LMC_SPIN_LOCK_IRQSAVE(x)      spin_lock_irqsave (&(x)->lmc_lock, flags);
 #define LMC_SPIN_UNLOCK_IRQRESTORE(x) spin_unlock_irqrestore (&(x)->lmc_lock, flags);
 #else
-#define LMC_SPIN_FLAGS
-#define LMC_SPIN_LOCK_INIT(x)
-#define LMC_SPIN_UNLOCK(x)
-#define LMC_SPIN_LOCK_IRQSAVE(x)
-#define LMC_SPIN_UNLOCK_IRQRESTORE(x)
+#define LMC_SPIN_FLAGS                unsigned long flags;
+#define LMC_SPIN_LOCK_INIT(x)         
+#define LMC_SPIN_UNLOCK(x)            
+#define LMC_SPIN_LOCK_IRQSAVE(x)      save_flags(flags); cli();
+#define LMC_SPIN_UNLOCK_IRQRESTORE(x) restore_flags(flags); 
 #endif
 
 
@@ -105,3 +126,19 @@
 
 
 #endif
+
+#if LINUX_VERSION_CODE >= 0x20200
+#else
+#define mdelay(x) { int j; for(j = 0; j < x; j++){ udelay(1000); } }
+
+#endif
+
+/*
+ * See DMA-mapping.txt for info
+ */
+
+#if LINUX_VERSION_CODE < 0x20363
+#else
+#define LMC_PCI_ALLOC_CONSISTENT(x, y, z) pci_alloc_consistent(x, y, z)
+#endif
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/mace.c linux.17p18/drivers/net/mace.c
--- linux.vanilla/drivers/net/mace.c	Fri Apr 21 12:46:18 2000
+++ linux.17p18/drivers/net/mace.c	Fri Aug  4 15:27:32 2000
@@ -266,7 +266,11 @@
     /* done changing address */
     out_8(&mb->iac, 0);
 
+#ifndef CONFIG_MACE_AAUI_PORT
     out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO);
+#else
+    out_8(&mb->plscc, PORTSEL_AUI + ENPLSIO);
+#endif /* CONFIG_MACE_AAUI_PORT */
 }
 
 static void __mace_set_address(struct device *dev, void *addr)
@@ -922,9 +926,9 @@
     struct mace_data *mp = (struct mace_data *) mace_devs->priv;
     unregister_netdev(mace_devs);
 
-    free_irq(mace_devs->irq, mace_interrupt);
-    free_irq(mp->tx_dma_intr, mace_txdma_intr);
-    free_irq(mp->rx_dma_intr, mace_rxdma_intr);
+    free_irq(mace_devs->irq, mace_devs);
+    free_irq(mp->tx_dma_intr, mace_devs);
+    free_irq(mp->rx_dma_intr, mace_devs);
 
     kfree(mace_devs);
     mace_devs = NULL;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/n2.c linux.17p18/drivers/net/n2.c
--- linux.vanilla/drivers/net/n2.c	Sun Jun 11 21:44:14 2000
+++ linux.17p18/drivers/net/n2.c	Thu Aug 17 17:48:22 2000
@@ -122,23 +122,23 @@
 
 
 
-#define sca_reg(reg, card) (0x8000 | card->io | \
+#define sca_reg(reg, card) (0x8000 | (card)->io | \
 			    ((reg)&0x0F) | (((reg)&0xF0) << 6))
-#define sca_in(reg, card)		readb(sca_reg(reg, card))
-#define sca_out(value, reg, card)	writeb(value, sca_reg(reg, card))
-#define sca_inw(reg, card)		readw(sca_reg(reg, card))
-#define sca_outw(value, reg, card)	writew(value, sca_reg(reg, card))
-
-#define port_to_card(port)		(port->card)
-#define log_node(port)			(port->log_node)
-#define phy_node(port)			(port->phy_node)
+#define sca_in(reg, card)		inb(sca_reg(reg, card))
+#define sca_out(value, reg, card)	outb(value, sca_reg(reg, card))
+#define sca_inw(reg, card)		inw(sca_reg(reg, card))
+#define sca_outw(value, reg, card)	outw(value, sca_reg(reg, card))
+
+#define port_to_card(port)		((port)->card)
+#define log_node(port)			((port)->log_node)
+#define phy_node(port)			((port)->phy_node)
 #define winsize(card)			(USE_WINDOWSIZE)
-#define winbase(card)      	     	(card->winbase)
-#define get_port(card, port)		(card->ports[port].valid ? \
-					 &card->ports[port] : NULL)
+#define winbase(card)      	     	((card)->winbase)
+#define get_port(card, port)		((card)->ports[port].valid ? \
+					 &(card)->ports[port] : NULL)
 
 
-static __inline__ u8 get_page(card_t *card)
+static __inline__ u8 sca_get_page(card_t *card)
 {
 	return inb(card->io+N2_PSR) & PSR_PAGEBITS;
 }
@@ -163,9 +163,9 @@
 	u8 mcr = inb(io+N2_MCR);
   
 	if (clock == LINE_EXT_CLOCK) /* External clock */
-		mcr |= port->phy_node ? CLOCK_OUT_PORT1 : CLOCK_OUT_PORT0;
-	else
 		mcr &= port->phy_node ? ~CLOCK_OUT_PORT1 : ~CLOCK_OUT_PORT0;
+	else
+		mcr |= port->phy_node ? CLOCK_OUT_PORT1 : CLOCK_OUT_PORT0;
 
 	outb(mcr, io+N2_MCR);
 	port->clkmode = clock;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/pc300.c linux.17p18/drivers/net/pc300.c
--- linux.vanilla/drivers/net/pc300.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/net/pc300.c	Tue Aug  1 07:59:45 2000
@@ -0,0 +1,2857 @@
+#define	USE_PCI_CLOCK
+static char rcsid[] =
+"$Revision: 3.1.0.2 $$Date: 2000/06/27 $";
+
+/*
+ * pc300.c	Cyclades-PC300(tm) Driver.
+ *
+ * Author:	Ivan Passos <ivan@cyclades.com>
+ *
+ * Copyright:	(c) 1999-2000 Cyclades Corp.
+ *
+ *	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.
+ * 
+ * $Log: pc300.c,v $
+ * Revision 3.1.0.2 2000/06/27 ivan
+ * Previous bugfix for the framing errors with external clock made X21 
+ * boards stop working. This version fixes it.
+ * 
+ * Revision 3.1.0.1 2000/06/23 ivan
+ * Revisited cpc_queue_xmit to prevent race conditions on Tx DMA buffer 
+ * handling when Tx timeouts occur.
+ * Revisited Rx statistics.
+ * Added support for loopback mode in the SCA-II.
+ * Fixed a bug in the SCA-II programming that would cause framing errors 
+ * when external clock was configured.
+ *
+ * Revision 3.1.0.0 2000/05/26 ivan
+ * Added Frame-Relay support.
+ * Driver now uses HDLC generic driver to provide protocol support.
+ * Added logic in the SCA interrupt handler so that no board can monopolize 
+ * the driver.
+ * Request PLX I/O region, although driver doesn't use it, to avoid
+ * problems with other drivers accessing it.
+ *
+ * Revision 3.0.0.0 2000/05/15 ivan
+ * Did some changes in the DMA programming implementation to avoid the 
+ * occurrence of a SCA-II bug in the second channel.
+ * Implemented workaround for PLX9050 bug that would cause a system lockup
+ * in certain systems, depending on the MMIO addresses allocated to the
+ * board.
+ * Fixed the FALC chip programming to avoid synchronization problems in the 
+ * second channel (TE only).
+ * Implemented a cleaner and faster Tx DMA descriptor cleanup procedure in 
+ * cpc_queue_xmit().
+ * Changed the built-in driver implementation so that the driver can use the 
+ * general 'hdlcN' naming convention instead of proprietary device names.
+ * Driver load messages are now device-centric, instead of board-centric.
+ * Dynamic allocation of device structures.
+ *
+ * Revision 2.0.0.0 2000/04/15 ivan
+ * Added support for the PC300/TE boards (T1/FT1/E1/FE1).
+ *
+ * Revision 1.1.0.0 2000/02/28 ivan
+ * Major changes in the driver architecture.
+ * Driver now reports physical instead of virtual memory addresses.
+ * Added cpc_change_mtu function.
+ *
+ * Revision 1.0.0.0 1999/12/16 ivan
+ * First official release.
+ * Support for 1- and 2-channel boards (which use distinct PCI Device ID's).
+ * Support for monolythic installation (i.e., drv built into the kernel).
+ * X.25 additional checking when lapb_[dis]connect_request returns an error.
+ * SCA programming now covers X.21 as well.
+ *
+ * Revision 0.3.1.0 1999/11/18 ivan
+ * Made X.25 support configuration-dependent (as it depends on external 
+ * modules to work).
+ * Changed X.25-specific function names to comply with adopted convention.
+ * Fixed typos in X.25 functions that would cause compile errors (Daniela).
+ * Fixed bug in ch_config that would disable interrupts on a previously 
+ * enabled channel if the other channel on the same board was enabled later.
+ *
+ * Revision 0.3.0.0 1999/11/16 Daniela Squassoni
+ * X.25 support.
+ *
+ * Revision 0.2.3.0 1999/11/15 ivan
+ * Function cpc_ch_status now provides more detailed information.
+ * Added support for X.21 clock configuration.
+ * Changed TNR1 setting in order to prevent Tx FIFO overaccesses by the SCA.
+ * Now using PCI clock instead of internal oscillator clock for the SCA.
+ *
+ * Revision 0.2.2.0 1999/11/10 ivan
+ * Changed the *_dma_buf_check functions so that they would print only 
+ * the useful info instead of the whole buffer descriptor bank.
+ * Fixed bug in cpc_queue_xmit that would eventually crash the system 
+ * in case of a packet drop.
+ * Implemented TX underrun handling.
+ * Improved SCA fine tuning to boost up its performance.
+ *
+ * Revision 0.2.1.0 1999/11/03 ivan
+ * Added functions *dma_buf_pt_init to allow independent initialization 
+ * of the next-descr. and DMA buffer pointers on the DMA descriptors.
+ * Kernel buffer release and tbusy clearing is now done in the interrupt 
+ * handler.
+ * Fixed bug in cpc_open that would cause an interface reopen to fail.
+ * Added a protocol-specific code section in cpc_net_rx.
+ * Removed printk level defs (they might be added back after the beta phase).
+ *
+ * Revision 0.2.0.0 1999/10/28 ivan
+ * Revisited the code so that new protocols can be easily added / supported. 
+ *
+ * Revision 0.1.0.1 1999/10/20 ivan
+ * Mostly "esthetic" changes.
+ *
+ * Revision 0.1.0.0 1999/10/11 ivan
+ * Initial version.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/sched.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/net.h>
+#include <linux/skbuff.h>
+#include <linux/if_arp.h>
+#include <linux/netdevice.h>
+#include <net/arp.h>
+#include <asm/io.h>
+#include <asm/uaccess.h>
+
+#ifdef CONFIG_PC300_X25
+#include <linux/lapb.h>
+#endif /* CONFIG_PC300_X25 */
+
+#include "syncppp.h"
+
+#include <linux/pc300.h>
+
+#include <asm/spinlock.h>
+
+#define	CPC_LOCK(card,flags)					\
+		do {						\
+		spin_lock_irqsave(&card->card_lock, flags);	\
+		} while (0)
+
+#define CPC_UNLOCK(card,flags)						\
+		do {							\
+		spin_unlock_irqrestore(&card->card_lock, flags);	\
+		} while (0)
+
+#undef	PC300_DEBUG_PCI
+#undef	PC300_DEBUG_INTR
+#undef	PC300_DEBUG_TX
+#undef	PC300_DEBUG_RX
+
+/* Hardware configuration options.
+ * These are arrays of configuration options used by verification routines.
+ * The first element of each array is its size (i.e. number of options).
+ */
+static unsigned short	cpc_pci_dev_id[] = {
+	PCI_DEVICE_ID_PC300_RX_1,	/* PC300/RSV or PC300/X21, 1 chan */
+	PCI_DEVICE_ID_PC300_RX_2,	/* PC300/RSV or PC300/X21, 2 chan */
+	PCI_DEVICE_ID_PC300_TE_1,	/* PC300/TE, 1 chan */
+	PCI_DEVICE_ID_PC300_TE_2,	/* PC300/TE, 2 chan */
+	0				/* end of table */
+};
+
+/* This is the per-card data structure containing mem. addresses, irq, etc.
+ * This driver supports a maximum of PC300_MAXCARDS cards.
+ */
+static pc300_t	cpc_card[PC300_MAXCARDS];
+
+static ucshort	cpc_nboards = 0;
+
+#ifndef min
+#define	min(a,b)	(((a)<(b))?(a):(b))
+#endif
+#ifndef max
+#define	max(a,b)	(((a)>(b))?(a):(b))
+#endif
+
+/************************/
+/***   DMA Routines   ***/
+/************************/
+static void 
+tx_dma_buf_pt_init(pc300_t *card, int ch)
+{
+    int i;
+    int ch_factor = ch * N_DMA_TX_BUF;
+    volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *)(card->hw.rambase 
+		+ DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+    for (i = 0 ; i < N_DMA_TX_BUF ; i++, ptdescr++) {
+	cpc_writel(&ptdescr->next, (uclong) (DMA_TX_BD_BASE + 
+		   (ch_factor + ((i + 1) & (N_DMA_TX_BUF - 1))) * 
+		   sizeof(pcsca_bd_t)));
+	cpc_writel(&ptdescr->ptbuf, 
+		   (uclong)(DMA_TX_BASE + (ch_factor + i)*BD_DEF_LEN));
+    }
+}
+
+static void 
+tx_dma_buf_init(pc300_t *card, int ch)
+{
+    int i;
+    int ch_factor = ch * N_DMA_TX_BUF;
+    volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *)(card->hw.rambase 
+		+ DMA_TX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+    for (i = 0 ; i < N_DMA_TX_BUF ; i++, ptdescr++) {
+	memset_io(ptdescr, 0, sizeof (pcsca_bd_t));
+	cpc_writew(&ptdescr->len, 0);
+	cpc_writeb(&ptdescr->status, 0);
+    }
+    tx_dma_buf_pt_init(card, ch);
+}
+
+static void 
+rx_dma_buf_pt_init(pc300_t *card, int ch)
+{
+    int i;
+    int ch_factor = ch * N_DMA_RX_BUF;
+    volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *)(card->hw.rambase 
+		+ DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+    for (i = 0 ; i < N_DMA_RX_BUF ; i++, ptdescr++) {
+	cpc_writel(&ptdescr->next, (uclong) (DMA_RX_BD_BASE + 
+		   (ch_factor + ((i + 1) & (N_DMA_RX_BUF - 1))) * 
+		   sizeof(pcsca_bd_t)));
+	cpc_writel(&ptdescr->ptbuf, 
+		   (uclong)(DMA_RX_BASE + (ch_factor + i)*BD_DEF_LEN));
+    }
+}
+
+static void 
+rx_dma_buf_init(pc300_t *card, int ch)
+{
+    int i;
+    int ch_factor = ch * N_DMA_RX_BUF;
+    volatile pcsca_bd_t *ptdescr = (pcsca_bd_t *)(card->hw.rambase 
+		+ DMA_RX_BD_BASE + ch_factor * sizeof(pcsca_bd_t));
+
+    for (i = 0 ; i < N_DMA_RX_BUF ; i++, ptdescr++) {
+	memset_io(ptdescr, 0, sizeof (pcsca_bd_t));
+	cpc_writew(&ptdescr->len, 0);
+	cpc_writeb(&ptdescr->status, 0);
+    }
+    rx_dma_buf_pt_init(card, ch);
+}
+
+static void
+tx_dma_buf_check(pc300_t *card, int ch)
+{
+    volatile pcsca_bd_t *ptdescr;
+    int i;
+    ucshort first_bd = card->chan[ch].tx_first_bd;
+    ucshort next_bd = card->chan[ch].tx_next_bd;
+
+    printk("#CH%d: f_bd = %d(0x%08x), n_bd = %d(0x%08x)\n", ch, 
+	   first_bd, TX_BD_ADDR(ch, first_bd), 
+	   next_bd, TX_BD_ADDR(ch, next_bd));
+    for (i = first_bd, 
+	  ptdescr = (pcsca_bd_t *)(card->hw.rambase + TX_BD_ADDR(ch, first_bd));
+	 i != ((next_bd + 1) & (N_DMA_TX_BUF - 1)) ;
+	 i = (i + 1) & (N_DMA_TX_BUF - 1), 
+	  ptdescr = (pcsca_bd_t *)(card->hw.rambase + TX_BD_ADDR(ch, i))) {
+	printk("\n CH%d TX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d", 
+	       ch, i,
+	       (uclong)cpc_readl(&ptdescr->next), 
+	       (uclong)cpc_readl(&ptdescr->ptbuf),
+	       cpc_readb(&ptdescr->status), 
+	       cpc_readw(&ptdescr->len));
+    }
+    printk("\n");
+}
+
+static void
+rx_dma_buf_check(pc300_t *card, int ch)
+{
+    volatile pcsca_bd_t *ptdescr;
+    int i;
+    ucshort first_bd = card->chan[ch].rx_first_bd;
+    ucshort last_bd = card->chan[ch].rx_last_bd;
+    int ch_factor;
+
+    ch_factor = ch * N_DMA_RX_BUF;
+    printk("#CH%d: f_bd = %d, l_bd = %d\n", ch, first_bd, last_bd);
+    for (i = 0, ptdescr = (pcsca_bd_t *)(card->hw.rambase +
+                        DMA_RX_BD_BASE + ch_factor*sizeof(pcsca_bd_t));
+	 i < N_DMA_RX_BUF ;
+	 i++, ptdescr++) {
+	if (cpc_readb(&ptdescr->status) & DST_OSB)
+	    printk("\n CH%d RX%d: next=0x%lx, ptbuf=0x%lx, ST=0x%x, len=%d", 
+		   ch, i,
+		   (uclong)cpc_readl(&ptdescr->next), 
+		   (uclong)cpc_readl(&ptdescr->ptbuf),
+		   cpc_readb(&ptdescr->status), 
+		   cpc_readw(&ptdescr->len));
+    }
+    printk("\n");
+}
+
+int 
+dma_get_rx_frame_size(pc300_t *card, int ch)
+{
+    volatile pcsca_bd_t *ptdescr;
+    ucshort first_bd = card->chan[ch].rx_first_bd;
+    int rcvd = 0;
+    volatile ucchar status;
+
+    ptdescr = (pcsca_bd_t *)(card->hw.rambase + RX_BD_ADDR(ch, first_bd));
+    while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
+	rcvd += cpc_readw(&ptdescr->len);
+	first_bd = (first_bd + 1) & (N_DMA_RX_BUF - 1);
+	if (status & DST_EOM)
+	    return (rcvd);
+	ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next));
+    }
+    return (-1);
+}
+
+/*
+ * dma_buf_write: writes a frame to the Tx DMA buffers
+ * NOTE: this function writes one frame at a time.
+ */ 
+int 
+dma_buf_write(pc300_t *card, int ch, ucchar *ptdata, int len)
+{
+    int i, nchar;
+    volatile pcsca_bd_t *ptdescr;
+    int tosend = len;
+    ucchar nbuf = ((len - 1)/BD_DEF_LEN) + 1;
+
+    for (i = 0 ; i < nbuf ; i++) {
+	ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+		TX_BD_ADDR(ch, card->chan[ch].tx_next_bd));
+	nchar = min(BD_DEF_LEN,tosend);
+	if (!(cpc_readb(&ptdescr->status) & DST_OSB)) {
+	    memcpy_toio((void *)(card->hw.rambase + 
+				 cpc_readl(&ptdescr->ptbuf)), 
+			&ptdata[len - tosend], 
+			nchar);
+	    if ((i + 1) == nbuf) {
+		/* This must be the last BD to be used */
+		cpc_writeb(&ptdescr->status, (DST_EOM | DST_EOT));
+	    } else {
+		cpc_writeb(&ptdescr->status, 0);
+	    }
+	    cpc_writew(&ptdescr->len, nchar);
+	} else {
+	    return -ENOMEM;
+	}
+	tosend -= nchar;
+	card->chan[ch].tx_next_bd = 
+		(card->chan[ch].tx_next_bd + 1) & (N_DMA_TX_BUF - 1);
+    }
+    /* If it gets to here, it means we have sent the whole frame */
+    return 0;
+}
+
+/*
+ * dma_buf_read: reads a frame from the Rx DMA buffers
+ * NOTE: this function reads one frame at a time.
+ */ 
+int 
+dma_buf_read(pc300_t *card, int ch, struct sk_buff *skb)
+{
+    int nchar;
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    volatile pcsca_bd_t *ptdescr;
+    int rcvd = 0;
+    volatile ucchar status;
+
+    ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+			     RX_BD_ADDR(ch, chan->rx_first_bd));
+    while ((status = cpc_readb(&ptdescr->status)) & DST_OSB) {
+	if (status & (DST_OVR | DST_CRC | DST_RBIT | DST_SHRT | DST_ABT)) {
+	    rcvd = -status;
+	    /* Discard remaining descriptors used by the bad frame */
+	    while(chan->rx_first_bd != chan->rx_last_bd) {
+		cpc_writeb(&ptdescr->status, 0);
+		chan->rx_first_bd = 
+			(chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1);
+		if(status & DST_EOM)
+		    break;
+		ptdescr = (pcsca_bd_t *)(card->hw.rambase + 
+					 cpc_readl(&ptdescr->next));
+		status = cpc_readb(&ptdescr->status);
+	    }
+	    break;
+	}
+	if ((nchar = cpc_readw(&ptdescr->len)) != 0) {
+	    memcpy_fromio(skb_put(skb, nchar), 
+			  (void *)(card->hw.rambase + 
+				   cpc_readl(&ptdescr->ptbuf)), 
+			  nchar);
+	    rcvd += nchar;
+	}
+	cpc_writeb(&ptdescr->status, 0);
+	cpc_writeb(&ptdescr->len, 0);
+	chan->rx_first_bd = (chan->rx_first_bd + 1) & (N_DMA_RX_BUF - 1);
+
+	if (status & DST_EOM)	break;
+
+	ptdescr = (pcsca_bd_t *)(card->hw.rambase + cpc_readl(&ptdescr->next));
+    }
+
+    if (rcvd != 0) {
+	/* Update pointer */
+	chan->rx_last_bd = (chan->rx_first_bd - 1) & (N_DMA_RX_BUF - 1);
+	/* Update EDA */
+	cpc_writel(card->hw.scabase + DRX_REG(EDAL, ch),
+		   RX_BD_ADDR(ch, chan->rx_last_bd));
+    }
+    return (rcvd);
+}
+
+void 
+tx_dma_stop(pc300_t *card, int ch)
+{
+    uclong scabase = card->hw.scabase;
+    ucchar drr_ena_bit = 1<<(5 + 2*ch);
+    ucchar drr_rst_bit = 1<<(1 + 2*ch);
+
+    /* Disable DMA */
+    cpc_writeb(scabase + DRR, drr_ena_bit);
+    cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
+}
+
+void 
+rx_dma_stop(pc300_t *card, int ch)
+{
+    uclong scabase = card->hw.scabase;
+    ucchar drr_ena_bit = 1<<(4 + 2*ch);
+    ucchar drr_rst_bit = 1<<(2*ch);
+
+    /* Disable DMA */
+    cpc_writeb(scabase + DRR, drr_ena_bit);
+    cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
+}
+
+/*************************/
+/***   FALC Routines   ***/
+/*************************/
+void 
+falc_issue_cmd(pc300_t *card, int ch, ucchar cmd)
+{
+    uclong falcbase = card->hw.falcbase;
+    unsigned long i = 0;
+
+    while (cpc_readb(falcbase + F_REG(SIS, ch)) & SIS_CEC) {
+        if (i++ >= PC300_FALC_MAXLOOP) {
+            printk("%s: FALC command locked(cmd=0x%x).\n", 
+		   card->chan[ch].d.name, cmd);
+            break;
+        }
+    }
+    cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
+}
+
+void 
+falc_intr_enable(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+
+    /* Interrupt pins are open-drain */
+    cpc_writeb(falcbase + F_REG(IPC, ch), 
+	       cpc_readb(falcbase + F_REG(IPC, ch)) & ~IPC_IC0);
+    /* Conters updated each second */
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_ECM);
+    /* Enable SEC and ES interrupts  */
+    cpc_writeb(falcbase + F_REG(IMR3, ch), 
+	       cpc_readb(falcbase + F_REG(IMR3, ch)) & ~(IMR3_SEC | IMR3_ES));
+    cpc_writeb(falcbase + F_REG(IMR4, ch), 
+	       cpc_readb(falcbase + F_REG(IMR4, ch)) & 
+    	       ~(IMR4_LFA | IMR4_AIS | IMR4_LOS | IMR4_SLIP));
+    if (conf->media == LINE_T1) {
+	cpc_writeb(falcbase + F_REG(IMR3, ch), 
+		   cpc_readb(falcbase + F_REG(IMR3, ch)) & ~IMR3_LLBSC);
+    } else {
+	cpc_writeb(falcbase + F_REG(IPC, ch), 
+		   cpc_readb(falcbase + F_REG(IPC, ch)) | IPC_SCI);
+	cpc_writeb(falcbase + F_REG(IMR2, ch), 
+		   cpc_readb(falcbase + F_REG(IMR2, ch)) & 
+		   ~(IMR2_FAR | IMR2_LFA | IMR2_AIS | IMR2_LOS));
+	cpc_writeb(falcbase + F_REG(IMR1, ch), 
+		   cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_LLBSC);
+	if (pfalc->multiframe_mode) {
+	    cpc_writeb(falcbase + F_REG(IMR2, ch), 
+		       cpc_readb(falcbase + F_REG(IMR2, ch)) & 
+		       ~(IMR2_T400MS | IMR2_MFAR));
+	} else {
+	    cpc_writeb(falcbase + F_REG(IMR2, ch), 
+		       cpc_readb(falcbase + F_REG(IMR2, ch)) | 
+		       IMR2_T400MS | IMR2_MFAR);
+	}
+    }
+}
+
+void 
+falc_open_timeslot(pc300_t *card, int ch, int timeslot)
+{
+    uclong falcbase = card->hw.falcbase;
+    ucchar tshf = card->chan[ch].falc.offset;
+
+    cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf)/8), ch),
+	       cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf)/8), ch)) & 
+	       ~(0x80 >> ((timeslot - tshf) & 0x07)));
+    cpc_writeb(falcbase + F_REG((TTR1 + timeslot/8), ch),
+	       cpc_readb(falcbase + F_REG((TTR1 + timeslot/8), ch)) | 
+	       (0x80 >> (timeslot & 0x07)));
+    cpc_writeb(falcbase + F_REG((RTR1 + timeslot/8), ch),
+	       cpc_readb(falcbase + F_REG((RTR1 + timeslot/8), ch)) | 
+	       (0x80 >> (timeslot & 0x07)));
+}
+
+void 
+falc_close_timeslot(pc300_t *card, int ch, int timeslot)
+{
+    uclong falcbase = card->hw.falcbase;
+    ucchar tshf = card->chan[ch].falc.offset;
+
+    cpc_writeb(falcbase + F_REG((ICB1 + (timeslot - tshf)/8), ch),
+	       cpc_readb(falcbase + F_REG((ICB1 + (timeslot - tshf)/8), ch)) | 
+	       (0x80 >> ((timeslot - tshf) & 0x07)));
+    cpc_writeb(falcbase + F_REG((TTR1 + timeslot/8), ch),
+	       cpc_readb(falcbase + F_REG((TTR1 + timeslot/8), ch)) & 
+	       ~(0x80 >> (timeslot & 0x07)));
+    cpc_writeb(falcbase + F_REG((RTR1 + timeslot/8), ch),
+	       cpc_readb(falcbase + F_REG((RTR1 + timeslot/8), ch)) & 
+	       ~(0x80 >> (timeslot & 0x07)));
+}
+
+void 
+falc_close_all_timeslots(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    uclong falcbase = card->hw.falcbase;
+
+    cpc_writeb(falcbase + F_REG(ICB1, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(TTR1, ch), 0);
+    cpc_writeb(falcbase + F_REG(RTR1, ch), 0);
+    cpc_writeb(falcbase + F_REG(ICB2, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(TTR2, ch), 0);
+    cpc_writeb(falcbase + F_REG(RTR2, ch), 0);
+    cpc_writeb(falcbase + F_REG(ICB3, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(TTR3, ch), 0);
+    cpc_writeb(falcbase + F_REG(RTR3, ch), 0);
+    if (conf->media == LINE_E1) {
+	cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(TTR4, ch), 0);
+	cpc_writeb(falcbase + F_REG(RTR4, ch), 0);
+    }
+}
+
+void 
+falc_open_all_timeslots(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    uclong falcbase = card->hw.falcbase;
+
+    /* Timeslot 0 is never enabled */
+    cpc_writeb(falcbase + F_REG(ICB1, ch), 0);
+    cpc_writeb(falcbase + F_REG(TTR1, ch), 0x7f);
+    cpc_writeb(falcbase + F_REG(RTR1, ch), 0x7f);
+    cpc_writeb(falcbase + F_REG(ICB2, ch), 0);
+    cpc_writeb(falcbase + F_REG(TTR2, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(RTR2, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(ICB3, ch), 0);
+    cpc_writeb(falcbase + F_REG(TTR3, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(RTR3, ch), 0xff);
+    if (conf->media == LINE_E1) {
+	cpc_writeb(falcbase + F_REG(ICB4, ch), 0);
+	cpc_writeb(falcbase + F_REG(TTR4, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(RTR4, ch), 0xff);
+    } else {
+	cpc_writeb(falcbase + F_REG(ICB4, ch), 0xff);
+	cpc_writeb(falcbase + F_REG(TTR4, ch), 0x80);
+	cpc_writeb(falcbase + F_REG(RTR4, ch), 0x80);
+    }
+}
+
+void 
+falc_init_timeslot(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    int tslot;
+
+    for (tslot = 0 ; tslot < pfalc->num_channels ; tslot++) {
+	if (conf->tslot_bitmap & (1<<tslot)) {
+	    // Channel enabled
+	    falc_open_timeslot(card, ch, tslot + 1);
+	} else {
+	    // Channel disabled
+	    falc_close_timeslot(card, ch, tslot + 1);
+	}
+    }
+}
+
+void 
+falc_enable_comm(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+
+    if (pfalc->full_bandwidth) {
+	falc_open_all_timeslots(card, ch);
+    } else {
+	falc_init_timeslot(card, ch);
+    }
+    // CTS/DCD ON
+    cpc_writeb(card->hw.falcbase + CPLD_REG1,
+	       cpc_readb(card->hw.falcbase + CPLD_REG1) | 
+	       ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2*ch)));
+}
+
+void 
+falc_disable_comm(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+
+    if (pfalc->loop_active != 2) {
+	falc_close_all_timeslots(card, ch);
+    }
+    // CTS/DCD OFF
+    cpc_writeb(card->hw.falcbase + CPLD_REG1,
+	       cpc_readb(card->hw.falcbase + CPLD_REG1) & 
+	       ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2*ch)));
+}
+
+void
+falc_init_t1(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+    ucchar dja = (ch ? (LIM2_DJA2|LIM2_DJA1) : 0);
+
+    /* Switch to T1 mode (PCM 24) */
+    cpc_writeb(falcbase + F_REG(FMR1, ch), FMR1_PMOD);
+
+    /* Wait 20 us for setup */
+    udelay(20);
+
+    /* Transmit Buffer Size (1 frame) */
+    cpc_writeb(falcbase + F_REG(SIC1, ch), SIC1_XBS0); 
+	
+    /* Clock mode */
+    if (conf->clkrate) {	/* Master mode */
+	cpc_writeb(falcbase + F_REG(LIM0, ch), 
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); 
+    } else {	/* Slave mode */
+	cpc_writeb(falcbase + F_REG(LIM0, ch), 
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); 
+	cpc_writeb(falcbase + F_REG(LOOP, ch), 
+		   cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); 
+    }
+
+    cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI);
+    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+	       cpc_readb(falcbase + F_REG(FMR0, ch)) & 
+	       ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1));
+
+    switch (conf->lcode) {
+	case PC300_LC_AMI:
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) | 
+		       FMR0_XC1 | FMR0_RC1);
+	    /* Clear Channel register to ON for all channels */
+	    cpc_writeb(falcbase + F_REG(CCB1, ch), 0xff);
+	    cpc_writeb(falcbase + F_REG(CCB2, ch), 0xff);
+	    cpc_writeb(falcbase + F_REG(CCB3, ch), 0xff);
+	    break;			
+
+	case PC300_LC_B8ZS:
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) | 
+		       FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1);
+	    break;
+
+	case PC300_LC_NRZ:
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) | 0x00);
+	    break;
+    }
+
+    cpc_writeb(falcbase + F_REG(LIM0, ch), 
+	       cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_ELOS); 
+    cpc_writeb(falcbase + F_REG(LIM0, ch), 
+	       cpc_readb(falcbase + F_REG(LIM0, ch)) &
+	       ~(LIM0_SCL1 | LIM0_SCL0)); 
+    /* Set interface mode to 2 MBPS */	
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); 
+
+    switch (conf->fr_mode) {
+	case PC300_FR_ESF:
+	    pfalc->multiframe_mode = 0;
+	    cpc_writeb(falcbase + F_REG(FMR4, ch), 
+		       cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_FM1);
+	    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+		       cpc_readb(falcbase + F_REG(FMR1, ch)) | 
+		       FMR1_CRC | FMR1_EDL);
+	    cpc_writeb(falcbase + F_REG(XDL1, ch), 0);
+	    cpc_writeb(falcbase + F_REG(XDL2, ch), 0);
+	    cpc_writeb(falcbase + F_REG(XDL3, ch), 0);
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) & ~FMR0_SRAF);
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) | 
+		       FMR2_MCSP | FMR2_SSP);
+	    break;
+
+	case PC300_FR_D4:
+	    pfalc->multiframe_mode = 1;
+	    cpc_writeb(falcbase + F_REG(FMR4, ch), 
+		       cpc_readb(falcbase + F_REG(FMR4, ch)) &
+	    	       ~(FMR4_FM1 | FMR4_FM0));
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) | FMR0_SRAF);
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_SSP);
+	    break;
+    }
+	
+    /* Enable Automatic Resynchronization */
+    cpc_writeb(falcbase + F_REG(FMR4, ch), 
+	       cpc_readb(falcbase + F_REG(FMR4, ch)) | FMR4_AUTO);
+
+    /* Transmit Automatic Remote Alarm */
+    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+	       cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA);
+
+    /* Channel translation mode 1 : one to one */
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_CTM);
+
+    /* No signaling */
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_SIGM);
+    cpc_writeb(falcbase + F_REG(FMR5, ch), 
+	       cpc_readb(falcbase + F_REG(FMR5, ch)) & 
+	       ~(FMR5_EIBR | FMR5_SRS));
+    cpc_writeb(falcbase + F_REG(CCR1, ch), 0);
+
+    cpc_writeb(falcbase + F_REG(LIM1, ch), 
+	       cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); 
+
+    switch (conf->lbo) {
+	/* Provides proper Line Build Out */
+	case PC300_LBO_0_DB:
+	    cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja));
+	    cpc_writeb(falcbase + F_REG(XPM0, ch), 0x5a);
+	    cpc_writeb(falcbase + F_REG(XPM1, ch), 0x8f);
+	    cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+	    break;
+	case PC300_LBO_7_5_DB:
+	    cpc_writeb(falcbase + F_REG(LIM2, ch), (0x40 | LIM2_LOS1 | dja));
+	    cpc_writeb(falcbase + F_REG(XPM0, ch), 0x11);
+	    cpc_writeb(falcbase + F_REG(XPM1, ch), 0x02);
+	    cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+	    break;
+	case PC300_LBO_15_DB:
+	    cpc_writeb(falcbase + F_REG(LIM2, ch), (0x80 | LIM2_LOS1 | dja));
+	    cpc_writeb(falcbase + F_REG(XPM0, ch), 0x8e);
+	    cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01);
+	    cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+	    break;
+	case PC300_LBO_22_5_DB:
+	    cpc_writeb(falcbase + F_REG(LIM2, ch), (0xc0 | LIM2_LOS1 | dja));
+	    cpc_writeb(falcbase + F_REG(XPM0, ch), 0x09);
+	    cpc_writeb(falcbase + F_REG(XPM1, ch), 0x01);
+	    cpc_writeb(falcbase + F_REG(XPM2, ch), 0x20);
+	    break;
+    }
+                                              
+    /* Transmit Clock-Slot Offset */
+    cpc_writeb(falcbase + F_REG(XC0, ch), 
+	       cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); 
+    /* Transmit Time-slot Offset */
+    cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e);
+    /* Receive  Clock-Slot offset */
+    cpc_writeb(falcbase + F_REG(RC0, ch), 0x05);
+    /* Receive  Time-slot offset */
+    cpc_writeb(falcbase + F_REG(RC1, ch), 0x00);
+
+    /* LOS Detection after 176 consecutive 0s */
+    cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a);
+    /* LOS Recovery after 22 ones in the time window of PCD */
+    cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15);
+
+    cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f);
+
+    if (conf->fr_mode == PC300_FR_ESF_JAPAN) {
+	cpc_writeb(falcbase + F_REG(RC1, ch), 
+		   cpc_readb(falcbase + F_REG(RC1, ch)) | 0x80);
+    }
+	
+    falc_close_all_timeslots(card, ch);
+}
+
+void
+falc_init_e1(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+    ucchar dja = (ch ? (LIM2_DJA2|LIM2_DJA1) : 0);
+
+    /* Switch to E1 mode (PCM 30) */
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_PMOD);
+
+    /* Clock mode */
+    if (conf->clkrate) {	/* Master mode */
+	cpc_writeb(falcbase + F_REG(LIM0, ch), 
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_MAS); 
+    } else {	/* Slave mode */
+	cpc_writeb(falcbase + F_REG(LIM0, ch), 
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_MAS); 
+    }
+    cpc_writeb(falcbase + F_REG(LOOP, ch), 
+	       cpc_readb(falcbase + F_REG(LOOP, ch)) & ~LOOP_RTM); 
+
+    cpc_writeb(falcbase + F_REG(IPC, ch), IPC_SCI);
+    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+	       cpc_readb(falcbase + F_REG(FMR0, ch)) & 
+	       ~(FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1));
+
+    switch (conf->lcode) {
+	case PC300_LC_AMI:
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) | 
+		       FMR0_XC1 | FMR0_RC1);
+	    break;			
+
+	case PC300_LC_HDB3:
+	    cpc_writeb(falcbase + F_REG(FMR0, ch), 
+		       cpc_readb(falcbase + F_REG(FMR0, ch)) | 
+		       FMR0_XC0 | FMR0_XC1 | FMR0_RC0 | FMR0_RC1);
+	    break;
+
+	case PC300_LC_NRZ:
+	    break;
+    }
+
+    cpc_writeb(falcbase + F_REG(LIM0, ch), 
+	       cpc_readb(falcbase + F_REG(LIM0, ch)) &
+	       ~(LIM0_SCL1 | LIM0_SCL0)); 
+    /* Set interface mode to 2 MBPS */	
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_IMOD); 
+
+    cpc_writeb(falcbase + F_REG(XPM0, ch), 0x18);
+    cpc_writeb(falcbase + F_REG(XPM1, ch), 0x03);
+    cpc_writeb(falcbase + F_REG(XPM2, ch), 0x00);
+
+    switch (conf->fr_mode) {
+	case PC300_FR_MF_CRC4:
+	    pfalc->multiframe_mode = 1;
+	    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+		       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_XFS);
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_RFS1);
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0);
+	    cpc_writeb(falcbase + F_REG(FMR3, ch), 
+		       cpc_readb(falcbase + F_REG(FMR3, ch)) & ~FMR3_EXTIW);
+			
+	    /* MultiFrame Resynchronization */
+	    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+		       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_MFCS);
+
+	    /* Automatic Loss of Multiframe > 914 CRC errors */
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_ALMF);
+
+	    /* S1 and SI1/SI2 spare Bits set to 1 */
+	    cpc_writeb(falcbase + F_REG(XSP, ch), 
+		       cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_AXS);
+	    cpc_writeb(falcbase + F_REG(XSP, ch), 
+		       cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_EBP);
+	    cpc_writeb(falcbase + F_REG(XSP, ch), 
+		       cpc_readb(falcbase + F_REG(XSP, ch)) | 
+		       XSP_XS13 | XSP_XS15);
+	    break;
+
+	case PC300_FR_MF_NON_CRC4:
+	case PC300_FR_D4:
+	    pfalc->multiframe_mode = 0;
+	    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+		       cpc_readb(falcbase + F_REG(FMR1, ch)) & ~FMR1_XFS);
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS1);
+	    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+		       cpc_readb(falcbase + F_REG(FMR2, ch)) & ~FMR2_RFS0);
+	    cpc_writeb(falcbase + F_REG(XSW, ch), 
+		       cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XSIS);
+	    cpc_writeb(falcbase + F_REG(XSP, ch), 
+		       cpc_readb(falcbase + F_REG(XSP, ch)) | XSP_XSIF);
+	    break;
+    }
+
+    /* Automatic Force Resynchronization */
+    cpc_writeb(falcbase + F_REG(FMR1, ch), 
+	       cpc_readb(falcbase + F_REG(FMR1, ch)) | FMR1_AFR);
+
+    /* Transmit Automatic Remote Alarm */
+    cpc_writeb(falcbase + F_REG(FMR2, ch), 
+	       cpc_readb(falcbase + F_REG(FMR2, ch)) | FMR2_AXRA);
+
+    /* No signaling */
+    cpc_writeb(falcbase + F_REG(XSP, ch), 
+	       cpc_readb(falcbase + F_REG(XSP, ch)) & ~XSP_CASEN);
+    cpc_writeb(falcbase + F_REG(CCR1, ch), 0);
+
+    cpc_writeb(falcbase + F_REG(LIM1, ch), 
+	       cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RIL0 | LIM1_RIL1); 
+    cpc_writeb(falcbase + F_REG(LIM2, ch), (LIM2_LOS1 | dja));
+
+    /* Transmit Clock-Slot Offset */
+    cpc_writeb(falcbase + F_REG(XC0, ch), 
+	       cpc_readb(falcbase + F_REG(XC0, ch)) | 0x01); 
+    /* Transmit Time-slot Offset */
+    cpc_writeb(falcbase + F_REG(XC1, ch), 0x3e);
+    /* Receive  Clock-Slot offset */
+    cpc_writeb(falcbase + F_REG(RC0, ch), 0x05);
+    /* Receive  Time-slot offset */
+    cpc_writeb(falcbase + F_REG(RC1, ch), 0x00);
+
+    /* LOS Detection after 176 consecutive 0s */
+    cpc_writeb(falcbase + F_REG(PCDR, ch), 0x0a);
+    /* LOS Recovery after 22 ones in the time window of PCD */
+    cpc_writeb(falcbase + F_REG(PCRR, ch), 0x15);
+
+    /* Transmit Spare Bits for National Use (Y-Bits, Sn-Bits, Sa-Bits) */
+    cpc_writeb(falcbase + F_REG(XSW, ch), 
+	       cpc_readb(falcbase + F_REG(XSW, ch)) | 
+	       XSW_XY0 | XSW_XY1 | XSW_XY2 | XSW_XY3 | XSW_XY4);
+
+    cpc_writeb(falcbase + F_REG(IDLE, ch), 0x7f);
+
+    falc_close_all_timeslots(card, ch);
+}
+
+void
+falc_init_hdlc(pc300_t *card, int ch)
+{
+    uclong falcbase = card->hw.falcbase;
+
+    /* Enable transparent data transfer */
+    cpc_writeb(falcbase + F_REG(MODE, ch), 
+	       cpc_readb(falcbase + F_REG(MODE, ch)) | MODE_HRAC | MODE_MDS2);
+    cpc_writeb(falcbase + F_REG(RAH2, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(RAH1, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(RAL2, ch), 0xff);
+    cpc_writeb(falcbase + F_REG(RAL1, ch), 0xff);
+
+    /* Tx/Rx reset  */
+    falc_issue_cmd(card, ch, CMDR_RRES | CMDR_XRES | CMDR_SRES);  
+
+    /* Enable interrupt sources */
+    falc_intr_enable(card, ch);
+}
+
+void 
+te_config(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+    ucchar dummy;
+    unsigned long flags;
+
+    memset(pfalc, 0, sizeof(falc_t));
+    switch (conf->media) {
+	case LINE_T1:
+	    pfalc->num_channels = NUM_OF_T1_CHANNELS;
+	    pfalc->offset = 1;
+	    break;
+	case LINE_E1:
+	    pfalc->num_channels = NUM_OF_E1_CHANNELS;
+	    pfalc->offset = 0;
+	    break;
+    }
+    if (conf->tslot_bitmap == 0xffffffffUL)
+	pfalc->full_bandwidth = 1;
+    else
+	pfalc->full_bandwidth = 0;
+
+    CPC_LOCK(card, flags);
+    /* Reset the FALC chip */
+    cpc_writeb(card->hw.falcbase + CPLD_REG1,
+	       cpc_readb(card->hw.falcbase + CPLD_REG1) | 
+	       (CPLD_REG1_FALC_RESET << (2*ch)));
+    udelay(10000);
+    cpc_writeb(card->hw.falcbase + CPLD_REG1,
+	       cpc_readb(card->hw.falcbase + CPLD_REG1) & 
+	       ~(CPLD_REG1_FALC_RESET << (2*ch)));
+
+    if (conf->media == LINE_T1) {
+	falc_init_t1(card, ch);
+    } else {
+	falc_init_e1(card, ch);
+    }
+    falc_init_hdlc(card, ch);
+    if (conf->rx_sens == PC300_RX_SENS_SH) {
+	cpc_writeb(falcbase + F_REG(LIM0, ch),
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) & ~LIM0_EQON);
+    } else {
+	cpc_writeb(falcbase + F_REG(LIM0, ch),
+		   cpc_readb(falcbase + F_REG(LIM0, ch)) | LIM0_EQON);
+    }
+    cpc_writeb(card->hw.falcbase + CPLD_REG2,
+	       cpc_readb(card->hw.falcbase + CPLD_REG2) | 
+	       ((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK) << (2*ch)));
+
+    /* Clear all interrupt registers */
+    dummy = cpc_readb(falcbase + F_REG(FISR0, ch)) +
+	    cpc_readb(falcbase + F_REG(FISR1, ch)) +
+	    cpc_readb(falcbase + F_REG(FISR2, ch)) +
+	    cpc_readb(falcbase + F_REG(FISR3, ch));
+    CPC_UNLOCK(card, flags);
+} 
+
+void 
+falc_check_status (pc300_t *card, int ch, unsigned char frs0)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+
+    /* Verify AIS alarm */
+    if (frs0 & FRS0_AIS) {
+	if (!pfalc->blue_alarm) {
+	    pfalc->blue_alarm = 1;
+	    pfalc->ais++;
+	    // EVENT_AIS
+	    if (conf->media == LINE_T1) {
+		/* Disable this interrupt as it may otherwise interfere with 
+		   other working boards. */
+		cpc_writeb(falcbase + F_REG(IMR0, ch), 
+			   cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);
+	    }
+	    falc_disable_comm(card, ch);
+	    // EVENT_AIS
+	}
+    } else {
+	pfalc->blue_alarm = 0;
+    }
+
+    /* Verify LOS */
+    if (frs0 & FRS0_LOS) {
+	if (! pfalc->red_alarm) {
+	    pfalc->red_alarm = 1;
+	    pfalc->los++;
+	    if (!pfalc->blue_alarm) {
+		// EVENT_FALC_ABNORMAL
+		if (conf->media == LINE_T1) {
+		    /* Disable this interrupt as it may otherwise interfere 
+		       with other working boards. */
+		    cpc_writeb(falcbase + F_REG(IMR0, ch), 
+			       cpc_readb(falcbase + F_REG(IMR0, ch)) | 
+			       IMR0_PDEN);
+		}
+		falc_disable_comm(card, ch);
+		// EVENT_FALC_ABNORMAL
+	    }
+	}
+    } else {
+	if (pfalc->red_alarm) {
+	    pfalc->red_alarm = 0;
+	    pfalc->losr++;
+	}
+    }
+
+    /* Verify LFA */
+    if (frs0 & FRS0_LFA) {
+	if (!pfalc->loss_fa) {
+	    pfalc->loss_fa = 1;
+	    pfalc->lfa++;
+	    if (!pfalc->blue_alarm && !pfalc->red_alarm) {
+		// EVENT_FALC_ABNORMAL
+		if (conf->media == LINE_T1) {
+		    /* Disable this interrupt as it may otherwise interfere 
+		       with other working boards. */
+		    cpc_writeb(falcbase + F_REG(IMR0, ch), 
+			       cpc_readb(falcbase + F_REG(IMR0, ch)) | 
+			       IMR0_PDEN);
+		}
+		falc_disable_comm(card, ch);
+		// EVENT_FALC_ABNORMAL
+	    }
+	}
+    } else {
+	if (pfalc->loss_fa) {
+	    pfalc->loss_fa = 0;
+	    pfalc->farec++;
+	}
+    }
+									
+    /* Verify LMFA */
+    if ((pfalc->multiframe_mode) && (frs0 & FRS0_LMFA)) { 
+	/* D4 or CRC4 frame mode */
+	if (! pfalc->loss_mfa) {
+	    pfalc->loss_mfa = 1;
+	    pfalc->lmfa++;
+	    if (!pfalc->blue_alarm && !pfalc->red_alarm && !pfalc->loss_fa) {
+		// EVENT_FALC_ABNORMAL
+		if (conf->media == LINE_T1) {
+		    /* Disable this interrupt as it may otherwise interfere 
+		       with other working boards. */
+		    cpc_writeb(falcbase + F_REG(IMR0, ch), 
+			       cpc_readb(falcbase + F_REG(IMR0, ch)) | 
+			       IMR0_PDEN);
+		}
+		falc_disable_comm(card, ch);
+		// EVENT_FALC_ABNORMAL
+	    }
+	}
+    } else {
+	pfalc->loss_mfa = 0;
+    }
+
+    if (pfalc->red_alarm || pfalc->loss_fa || 
+	pfalc->loss_mfa || pfalc->blue_alarm) {
+	if (pfalc->sync) {
+	    pfalc->sync = 0;
+	    cpc_writeb(falcbase + CPLD_REG2,
+		       cpc_readb(falcbase + CPLD_REG2) & 
+		       ~(CPLD_REG2_FALC_LED2 << (2*ch)));
+	}
+    } else {
+	if ((!pfalc->sync)) {
+	    pfalc->sync = 1;
+	    cpc_writeb(falcbase + CPLD_REG2,
+		       cpc_readb(falcbase + CPLD_REG2) |
+		       (CPLD_REG2_FALC_LED2 << (2*ch)));
+	}
+    }
+
+    /* Verify Remote Alarm */
+    if (frs0 & FRS0_RRA) {
+	if (! pfalc->yellow_alarm) {
+	    pfalc->yellow_alarm = 1;
+	    pfalc->rai++;
+	    if (pfalc->sync) {
+		// EVENT_RAI
+		falc_disable_comm(card, ch);
+		// EVENT_RAI
+	    }
+	}
+    } else {
+	pfalc->yellow_alarm = 0;
+    }
+
+    if ((pfalc->sync) && (!(pfalc->yellow_alarm))) {
+	if (! pfalc->active) {
+	    // EVENT_FALC_NORMAL
+	    if (pfalc->loop_active) {
+		return;
+	    }
+	    if (conf->media == LINE_T1) {
+		cpc_writeb(falcbase + F_REG(IMR0, ch), 
+			   cpc_readb(falcbase + F_REG(IMR0, ch)) & ~IMR0_PDEN);
+	    }
+	    falc_enable_comm(card, ch);
+	    // EVENT_FALC_NORMAL
+	    pfalc->active = 1;
+	}
+    } else {
+	if (pfalc->active) {
+	    pfalc->active = 0;
+	}
+    }
+}
+
+void 
+falc_update_stats(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+    ucshort counter;
+
+    counter = cpc_readb(falcbase + F_REG(FECL, ch));
+    counter |= cpc_readb(falcbase + F_REG(FECH, ch)) << 8;
+    pfalc->fec += counter;
+
+    counter = cpc_readb(falcbase + F_REG(CVCL, ch));
+    counter |= cpc_readb(falcbase + F_REG(CVCH, ch)) << 8;
+    pfalc->cvc += counter;
+
+    counter = cpc_readb(falcbase + F_REG(CECL, ch));
+    counter |= cpc_readb(falcbase + F_REG(CECH, ch)) << 8;
+    pfalc->cec += counter;
+
+    counter = cpc_readb(falcbase + F_REG(EBCL, ch));
+    counter |= cpc_readb(falcbase + F_REG(EBCH, ch)) << 8;
+    pfalc->ebc += counter;
+
+    if (cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) {
+	counter = cpc_readb(falcbase + F_REG(BECL, ch));
+	counter |= cpc_readb(falcbase + F_REG(BECH, ch)) << 8;
+	pfalc->bec += counter;
+
+	if (((conf->media == LINE_T1) && 
+	     (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_LLBAD) && 
+	     (!(cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN))) 
+	    ||
+	    ((conf->media == LINE_E1) && 
+	     (cpc_readb(falcbase + F_REG(RSP, ch)) & RSP_LLBAD))) {
+	    pfalc->prbs = 2;
+	} else {
+	    pfalc->prbs = 1;
+	}
+    }
+}
+
+void 
+falc_remote_loop(pc300_t *card, int ch, int loop_on)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+
+    if (loop_on) {
+	// EVENT_FALC_ABNORMAL
+	if (conf->media == LINE_T1) {
+	    /* Disable this interrupt as it may otherwise interfere with 
+	       other working boards. */
+	    cpc_writeb(falcbase + F_REG(IMR0, ch), 
+		       cpc_readb(falcbase + F_REG(IMR0, ch)) | IMR0_PDEN);
+	}
+	falc_disable_comm(card, ch);
+	// EVENT_FALC_ABNORMAL
+	cpc_writeb(falcbase + F_REG(LIM1, ch), 
+		   cpc_readb(falcbase + F_REG(LIM1, ch)) | LIM1_RL);
+	pfalc->loop_active = 1;
+    } else {
+	cpc_writeb(falcbase + F_REG(LIM1, ch), 
+		   cpc_readb(falcbase + F_REG(LIM1, ch)) & ~LIM1_RL);
+	pfalc->sync = 0;
+	cpc_writeb(falcbase + CPLD_REG2,
+		   cpc_readb(falcbase + CPLD_REG2) & 
+		   ~(CPLD_REG2_FALC_LED2 << (2*ch)));
+	pfalc->active = 0;
+	falc_issue_cmd(card, ch, CMDR_XRES);
+	pfalc->loop_active = 0;
+    }
+}
+
+/**********************************/
+/***   Net Interface Routines   ***/
+/**********************************/
+int cpc_queue_xmit(struct sk_buff *skb, struct device *dev)
+{
+    pc300dev_t *d = (pc300dev_t *)dev->priv;
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    struct enet_statistics *stats = &d->hdlc->stats;
+    int ch = chan->channel;
+    volatile pcsca_bd_t *ptdescr;
+    uclong flags;
+#ifdef PC300_DEBUG_TX
+    int i;
+#endif
+
+    if (dev->tbusy) {
+	ucchar ilar;
+
+	if (time_before(jiffies, dev->trans_start + PC300_TX_TIMEOUT))
+	    return 1;
+
+	stats->tx_errors++;
+	stats->tx_aborted_errors++;
+	printk("%s: transmit timed out, restarting channel.", dev->name);
+	CPC_LOCK(card, flags);
+	if ((ilar = cpc_readb(card->hw.scabase + ILAR)) != 0) {
+	    printk("(ILAR=0x%x)", ilar);
+	    cpc_writeb(card->hw.scabase + ILAR, ilar);
+	    cpc_writeb(card->hw.scabase + DMER, 0x80);
+	}
+	printk("\n");
+	cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_BUF_CLR);
+	if (d->tx_skb) {
+	    dev_kfree_skb(d->tx_skb);
+	    d->tx_skb = NULL;
+	}
+	if (card->hw.type == PC300_TE) {
+	    cpc_writeb(card->hw.falcbase + CPLD_REG2,
+		       cpc_readb(card->hw.falcbase + CPLD_REG2) &
+		       ~(CPLD_REG2_FALC_LED1 << (2*ch)));
+	}
+	CPC_UNLOCK(card, flags);
+	dev->tbusy = 0;
+    }
+    if (test_and_set_bit(0, (void*)&dev->tbusy)) {
+	printk("%s: transmitter access conflict.\n", dev->name);
+	return 1;
+    }
+
+    /* Clean up descriptors from previous transmission */
+    while (chan->tx_first_bd != chan->tx_next_bd) {
+	ptdescr = (pcsca_bd_t *)
+		   (card->hw.rambase + TX_BD_ADDR(ch, chan->tx_first_bd));
+	cpc_writeb(&ptdescr->status, 0);
+	chan->tx_first_bd = (chan->tx_first_bd + 1) & (N_DMA_TX_BUF - 1);
+    }
+    /* Clean up next free descriptor to avoid race problems with timeout
+       conditions */
+    ptdescr = (pcsca_bd_t *)
+		(card->hw.rambase + TX_BD_ADDR(ch, chan->tx_next_bd));
+    cpc_writeb(&ptdescr->status, 0);
+
+    /* Write buffer to DMA buffers */
+    if(dma_buf_write(card, ch, (ucchar *)skb->data, skb->len) != 0) {
+	CPC_LOCK(card, flags);
+//	printk("%s: write error. Dropping TX packet.\n", dev->name);
+	dev->tbusy = 0;
+	CPC_UNLOCK(card, flags);
+	stats->tx_dropped++;
+	return 1;
+    }
+
+#ifdef PC300_DEBUG_TX
+    printk("%s T:", dev->name);
+    for(i = 0 ; i < skb->len ; i++)
+	printk(" %02x", *(skb->data + i));
+    printk("\n");
+#endif
+
+    d->tx_skb = skb;
+    dev->trans_start = jiffies;
+
+    /* Start transmission */
+    CPC_LOCK(card, flags);
+    cpc_writel(card->hw.scabase + DTX_REG(EDAL, ch), 
+	       TX_BD_ADDR(ch, chan->tx_next_bd));
+    cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_TX_ENA);
+    cpc_writeb(card->hw.scabase + DSR_TX(ch), DSR_DE);
+    if (card->hw.type == PC300_TE) {
+	cpc_writeb(card->hw.falcbase + CPLD_REG2,
+		   cpc_readb(card->hw.falcbase + CPLD_REG2) |
+		   (CPLD_REG2_FALC_LED1 << (2*ch)));
+    }
+    CPC_UNLOCK(card, flags);
+
+    return 0;
+}
+
+void 
+cpc_net_rx(hdlc_device *hdlc)
+{
+    struct device *dev = hdlc_to_dev(hdlc);
+    pc300dev_t *d = (pc300dev_t *)dev->priv;
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    struct enet_statistics *stats = &hdlc->stats;
+    int ch = chan->channel;
+#ifdef PC300_DEBUG_RX
+    int i;
+#endif
+    int rxb;
+    struct sk_buff *skb;
+
+    while (1) {
+	if ((rxb = dma_get_rx_frame_size(card, ch)) == -1)
+	    return;
+
+	skb = dev_alloc_skb(rxb);
+	if (skb == NULL) {
+	    printk("%s: Memory squeeze!!\n", dev->name);
+	    return;
+	}
+	skb->dev = dev;
+
+	if((rxb = dma_buf_read(card, ch, skb)) <= 0) {
+	    if (rxb < 0) {	/* Invalid frame */
+		rxb = -rxb;
+		if (rxb & DST_OVR) {
+		    stats->rx_errors++;
+		    stats->rx_fifo_errors++;
+		}
+		if (rxb & DST_CRC) {
+		    stats->rx_errors++;
+		    stats->rx_crc_errors++;
+		}
+		if (rxb & (DST_RBIT | DST_SHRT | DST_ABT)) {
+		    stats->rx_errors++;
+		    stats->rx_frame_errors++;
+		}
+	    }
+	    dev_kfree_skb(skb);
+	    continue;
+	}
+
+#ifdef PC300_DEBUG_RX
+	printk("%s R:", dev->name);
+	for(i = 0 ; i < skb->len ; i++)
+	    printk(" %02x", *(skb->data + i));
+	printk("\n");
+#endif
+
+	switch(hdlc->mode & ~MODE_SOFT) {
+#ifdef CONFIG_PC300_X25
+	    case MODE_X25:
+	    {
+		int err;
+
+		skb->protocol=htons(ETH_P_X25);
+		skb->mac.raw=skb->data;
+		skb->dev=hdlc_to_dev(d->hdlc);
+
+		/* Send it to the upper layer */
+		if ((err = lapb_data_received(d, skb)) != LAPB_OK) {
+		    printk("%s: lapb_data_received err - %d\n", dev->name, err);
+		    dev_kfree_skb(skb);
+		}
+		stats->rx_bytes += rxb;
+		stats->rx_packets++;
+		break;
+	    }
+#endif /* CONFIG_PC300_X25 */
+	    default:
+		hdlc_netif_rx(hdlc, skb, 0);
+		break;
+	}
+    }
+}
+
+#ifdef CONFIG_PC300_X25
+/*********************************/
+/***   X.25 Support Routines   ***/
+/*********************************/
+int 
+cpc_x25_packetlayer_xmit(struct sk_buff *skb, struct device *dev)
+{
+    pc300dev_t *d = (pc300dev_t *)dev->priv;
+    int err;
+	
+    switch (skb->data[0]) {
+	case 0x00:
+	    break;
+
+	case 0x01:
+	    if ((err = lapb_connect_request(d)) != LAPB_OK) {
+		if (err == LAPB_CONNECTED) {
+		    /* Send connect confirm. msg to level 3 */
+		    cpc_lapb_connected(d, 0);
+		} else {
+		    printk("%s: lapb_connect_request error - %d\n",
+			   dev->name, err);
+		}
+	    }
+	    dev_kfree_skb(skb);
+	    return 0;
+
+	case 0x02:
+	    if ((err = lapb_disconnect_request(d)) != LAPB_OK) {
+		if (err == LAPB_NOTCONNECTED) {
+		    /* Send disconnect confirm. msg to level 3 */
+		    cpc_lapb_disconnected(d, 0);
+		} else {
+		    printk("%s: lapb_disconnect_request error - %d\n",
+			   dev->name, err);
+		}
+	    }
+	    dev_kfree_skb(skb);
+	    return 0;
+			
+	default:
+	    dev_kfree_skb(skb);
+	    return 0;
+    }
+
+    skb_pull(skb, 1);
+
+    if ((err = lapb_data_request(d, skb)) != LAPB_OK) {
+	printk("%s: lapb_data_request error - %d\n", dev->name, err);
+	dev_kfree_skb(skb);
+	return -ENOMEM;
+    }
+
+    return 0;
+}
+
+void 
+cpc_lapb_connected(void *token, int reason)
+{
+    pc300dev_t *d = (pc300dev_t *)token;
+    struct sk_buff *skb;
+    unsigned char *ptr;
+
+    if ((skb = dev_alloc_skb(1)) == NULL) {
+	printk("%s: out of memory\n", d->name);
+	return;
+    }
+
+    ptr  = skb_put(skb, 1);
+    *ptr = 0x01;
+
+    skb->dev      = hdlc_to_dev(d->hdlc);
+    skb->protocol = htons(ETH_P_X25);
+    skb->mac.raw  = skb->data;
+    skb->pkt_type = PACKET_HOST;
+
+    netif_rx(skb);
+}
+
+void 
+cpc_lapb_disconnected(void *token, int reason)
+{
+    pc300dev_t *d = (pc300dev_t *)token;
+    struct sk_buff *skb;
+    unsigned char *ptr;
+
+    if ((skb = dev_alloc_skb(1)) == NULL) {
+	printk("%s: out of memory\n", d->name);
+	return;
+    }
+
+    ptr  = skb_put(skb, 1);
+    *ptr = 0x02;
+
+    skb->dev      = hdlc_to_dev(d->hdlc);
+    skb->protocol = htons(ETH_P_X25);
+    skb->mac.raw  = skb->data;
+    skb->pkt_type = PACKET_HOST;
+
+    netif_rx(skb);
+}
+
+void 
+cpc_lapb_data_indication(void *token, struct sk_buff *skb)
+{
+    pc300dev_t *d = (pc300dev_t *)token;
+    unsigned char *ptr;
+
+    ptr  = skb_push(skb, 1);
+    *ptr = 0x00;
+
+    skb->dev      = hdlc_to_dev(d->hdlc);
+    skb->protocol = htons(ETH_P_X25);
+    skb->mac.raw  = skb->data;
+    skb->pkt_type = PACKET_HOST;
+
+    netif_rx(skb);
+}
+
+void 
+cpc_lapb_data_transmit(void *token, struct sk_buff *skb)
+{
+    pc300dev_t *d = (pc300dev_t *)token;
+    struct device *dev = hdlc_to_dev(d->hdlc);
+
+    cpc_queue_xmit (skb, dev);
+}
+#endif /* CONFIG_PC300_X25 */
+
+/************************************/
+/***   PC300 Interrupt Routines   ***/
+/************************************/
+static void 
+sca_intr(pc300_t *card)
+{
+    uclong scabase = card->hw.scabase;
+    volatile uclong status;
+    int ch;
+    int intr_count = 0;
+
+    while ((status = cpc_readl(scabase + ISR0)) != 0) {
+	for (ch = 0 ; ch < card->hw.nchan ; ch++) {
+	    pc300ch_t *chan = &card->chan[ch];
+	    pc300dev_t *d = &chan->d;
+	    hdlc_device *hdlc = d->hdlc;
+	    struct device *dev = hdlc_to_dev(hdlc);
+
+	    dev->interrupt = 1;
+
+	    /**** Reception ****/
+	    if (status & IR0_DRX((IR0_DMIA|IR0_DMIB), ch)) {
+		ucchar drx_stat = cpc_readb(scabase + DSR_RX(ch));
+
+		/* Clear RX interrupts */
+		cpc_writeb(scabase + DSR_RX(ch), drx_stat | DSR_DWE);
+
+#ifdef PC300_DEBUG_INTR
+	        printk("sca_intr: RX intr (st=0x%08lx, dsr=0x%02x)\n", 
+		       status, drx_stat);
+#endif
+		if (status & IR0_DRX(IR0_DMIA, ch)) {
+		    if (drx_stat & DSR_BOF) {
+			chan->rx_first_bd = 0;
+			chan->rx_last_bd = N_DMA_RX_BUF - 1;
+			cpc_writel(scabase + DRX_REG(CDAL, ch), 
+				   RX_BD_ADDR(ch, chan->rx_first_bd));
+			cpc_writel(scabase + DRX_REG(EDAL, ch), 
+				   RX_BD_ADDR(ch, chan->rx_last_bd));
+			cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN);
+			cpc_writeb(scabase + DSR_RX(ch), DSR_DE);
+		    }
+		}
+		if (status & IR0_DRX(IR0_DMIB, ch)) {
+		    if (drx_stat & DSR_EOM) {
+			if (card->hw.type == PC300_TE) {
+			    cpc_writeb(card->hw.falcbase + CPLD_REG2,
+				       cpc_readb(card->hw.falcbase + CPLD_REG2)
+				       | (CPLD_REG2_FALC_LED1 << (2*ch)));
+			}
+			cpc_net_rx(hdlc);
+			if (card->hw.type == PC300_TE) {
+			    cpc_writeb(card->hw.falcbase + CPLD_REG2,
+				       cpc_readb(card->hw.falcbase + CPLD_REG2)
+				       & ~(CPLD_REG2_FALC_LED1 << (2*ch)));
+			}
+		    }
+		}
+	    }
+
+	    /**** Transmission ****/
+	    if (status & IR0_DTX((IR0_EFT|IR0_DMIA|IR0_DMIB), ch)) {
+		ucchar dtx_stat = cpc_readb(scabase + DSR_TX(ch));
+
+		/* Clear TX interrupts */
+		cpc_writeb(scabase + DSR_TX(ch), dtx_stat | DSR_DWE);
+
+#ifdef PC300_DEBUG_INTR
+	        printk("sca_intr: TX intr (st=0x%08lx, dsr=0x%02x)\n", 
+		       status, dtx_stat);
+#endif
+		if (status & IR0_DTX(IR0_EFT, ch)) {
+		    if (dtx_stat & DSR_UDRF) {
+			if (cpc_readb(scabase + M_REG(TBN, ch)) != 0) {
+			    cpc_writeb(scabase + M_REG(CMD, ch), 
+				CMD_TX_BUF_CLR);
+			}
+			if (card->hw.type == PC300_TE) {
+			    cpc_writeb(card->hw.falcbase + CPLD_REG2,
+				       cpc_readb(card->hw.falcbase + CPLD_REG2)
+				       & ~(CPLD_REG2_FALC_LED1 << (2*ch)));
+			}
+			if (d->tx_skb) {
+			    struct sk_buff *skb = d->tx_skb;
+
+			    dev_kfree_skb(skb);
+			    d->tx_skb = NULL;
+			    hdlc->stats.tx_errors++;
+			    hdlc->stats.tx_fifo_errors++;
+			    /* Tell the upper layer we are ready to transmit
+			       more packets */
+			    dev->tbusy = 0;
+			    mark_bh(NET_BH);
+			}
+		    }
+		}
+		if (status & IR0_DTX(IR0_DMIA, ch)) {
+		    if (dtx_stat & DSR_BOF) {
+		    }
+		}
+		if (status & IR0_DTX(IR0_DMIB, ch)) {
+		    if (dtx_stat & DSR_EOM) {
+			if (card->hw.type == PC300_TE) {
+			    cpc_writeb(card->hw.falcbase + CPLD_REG2,
+				       cpc_readb(card->hw.falcbase + CPLD_REG2)
+				       & ~(CPLD_REG2_FALC_LED1 << (2*ch)));
+			}
+			if (d->tx_skb) {
+			    struct sk_buff *skb = d->tx_skb;
+
+			    dev_kfree_skb(skb);
+			    d->tx_skb = NULL;
+			    hdlc->stats.tx_bytes += skb->len;
+			    hdlc->stats.tx_packets++;
+			    /* Tell the upper layer we are ready to transmit
+			       more packets */
+			    dev->tbusy = 0;
+			    mark_bh(NET_BH);
+			}
+		    }
+		}
+	    }
+	    dev->interrupt = 0;
+	}
+	if (++intr_count == 10) 
+	    /* Too much work at this board. Force exit */
+	    break;
+    }
+}
+
+static void 
+falc_t1_loop_detection(pc300_t *card, int ch, ucchar frs1)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+
+    if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && 
+	!pfalc->loop_gen) {
+	if (frs1 & FRS1_LLBDD) {
+	    // A Line Loop Back Deactuation signal detected
+	    if (pfalc->loop_active) {
+		falc_remote_loop(card, ch, 0);
+	    }
+	} else {
+	    if ((frs1 & FRS1_LLBAD) && 
+		((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) {
+		// A Line Loop Back Actuation signal detected	
+		if (!pfalc->loop_active) {
+		    falc_remote_loop(card, ch, 1);
+		}
+	    }
+	}
+    }
+}
+
+static void 
+falc_e1_loop_detection(pc300_t *card, int ch, ucchar rsp)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+
+    if (((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_XPRBS) == 0) && 
+	!pfalc->loop_gen) {
+	if (rsp & RSP_LLBDD) {
+	    // A Line Loop Back Deactuation signal detected
+	    if (pfalc->loop_active) {
+		falc_remote_loop(card, ch, 0);
+	    }
+	} else {
+	    if ((rsp & RSP_LLBAD) && 
+		((cpc_readb(falcbase + F_REG(LCR1, ch)) & LCR1_EPRM) == 0)) {
+		// A Line Loop Back Actuation signal detected	
+		if (!pfalc->loop_active) {
+		    falc_remote_loop(card, ch, 1);
+		}
+	    }
+	}
+    }
+}
+
+static void 
+falc_t1_intr(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+    ucchar isr0, isr3, gis;
+    ucchar dummy;
+
+    while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
+	if (gis & GIS_ISR0) {
+	    isr0 = cpc_readb(falcbase + F_REG(FISR0, ch));
+	    if (isr0 & FISR0_PDEN)  { 
+		/* Read the bit to clear the situation */
+		if (cpc_readb(falcbase + F_REG(FRS1, ch)) & FRS1_PDEN) {
+			pfalc->pden++;
+		}
+	    }
+	}
+
+	if (gis & GIS_ISR1) {
+	    dummy = cpc_readb(falcbase + F_REG(FISR1, ch));
+	}
+	      
+	if (gis & GIS_ISR2) {
+	    dummy = cpc_readb(falcbase + F_REG(FISR2, ch));
+	}
+      
+	if (gis & GIS_ISR3) {
+	    isr3 = cpc_readb(falcbase + F_REG(FISR3, ch));
+	    if (isr3 & FISR3_SEC) {
+		pfalc->sec++;
+		falc_update_stats(card, ch);
+		falc_check_status(card, ch, 
+				  cpc_readb(falcbase + F_REG(FRS0, ch)));
+	    }
+	    if (isr3 & FISR3_ES) {
+		pfalc->es++;
+	    }
+	    if (isr3 & FISR3_LLBSC) {
+		falc_t1_loop_detection(card, ch, 
+				cpc_readb(falcbase + F_REG(FRS1, ch)));
+	    }
+	}
+    }
+}
+
+static void 
+falc_e1_intr(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = (pc300ch_t *)&card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong falcbase = card->hw.falcbase;
+    ucchar isr1, isr2, isr3, gis, rsp;
+    ucchar dummy;
+
+    while ((gis = cpc_readb(falcbase + F_REG(GIS, ch))) != 0) {
+	rsp = cpc_readb(falcbase + F_REG(RSP, ch));
+
+	if (gis & GIS_ISR0)  { 
+	    dummy = cpc_readb(falcbase + F_REG(FISR0, ch));
+	}
+	if (gis & GIS_ISR1) {
+	    isr1 = cpc_readb(falcbase + F_REG(FISR1, ch));
+	    if (isr1 & FISR1_XMB) {
+		if ((pfalc->xmb_cause & 2) && pfalc->multiframe_mode) {
+		    if (cpc_readb(falcbase + F_REG(FRS0, ch)) & 
+			(FRS0_LOS | FRS0_AIS | FRS0_LFA)) {
+			cpc_writeb(falcbase + F_REG(XSP, ch), 
+				   cpc_readb(falcbase + F_REG(XSP, ch)) & 
+				   ~XSP_AXS);
+		    } else {
+			cpc_writeb(falcbase + F_REG(XSP, ch), 
+				   cpc_readb(falcbase + F_REG(XSP, ch)) | 
+				   XSP_AXS);
+		    }
+		}
+		pfalc->xmb_cause = 0;
+		cpc_writeb(falcbase + F_REG(IMR1, ch), 
+			   cpc_readb(falcbase + F_REG(IMR1, ch)) | IMR1_XMB);
+	    }
+	    if (isr1 & FISR1_LLBSC) {
+		falc_e1_loop_detection(card, ch, rsp);
+	    }
+	}
+	if (gis & GIS_ISR2) {
+	    isr2 = cpc_readb(falcbase + F_REG(FISR2, ch));
+	    if (isr2 & FISR2_T400MS) {
+		cpc_writeb(falcbase + F_REG(XSW, ch), 
+			   cpc_readb(falcbase + F_REG(XSW, ch)) | XSW_XRA);
+	    }
+	    if (isr2 & FISR2_MFAR) {
+		cpc_writeb(falcbase + F_REG(XSW, ch), 
+			   cpc_readb(falcbase + F_REG(XSW, ch)) & ~XSW_XRA);
+	    }
+	    if (isr2 & (FISR2_FAR | FISR2_LFA | FISR2_AIS | FISR2_LOS)) {
+		pfalc->xmb_cause |= 2;
+		cpc_writeb(falcbase + F_REG(IMR1, ch), 
+			   cpc_readb(falcbase + F_REG(IMR1, ch)) & ~IMR1_XMB);
+	    }
+	}
+	if (gis & GIS_ISR3) {
+	    isr3 = cpc_readb(falcbase + F_REG(FISR3, ch));
+	    if (isr3 & FISR3_SEC) {
+		pfalc->sec++;
+		falc_update_stats(card, ch);
+		falc_check_status(card, ch, 
+				  cpc_readb(falcbase + F_REG(FRS0, ch)));
+	    }
+	    if (isr3 & FISR3_ES) {
+		pfalc->es++;
+	    }
+	}
+    }
+}
+
+static void
+falc_intr(pc300_t *card)
+{
+    int ch;
+
+    for (ch = 0 ; ch < card->hw.nchan ; ch++) {
+	pc300ch_t *chan = &card->chan[ch];
+	pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+
+	if (conf->media == LINE_T1) {
+	    falc_t1_intr(card, ch);
+	} else {
+	    falc_e1_intr(card, ch);
+	}
+    }
+}
+
+static void
+cpc_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+    pc300_t *card;
+    volatile ucchar plx_status;
+
+    if((card = (pc300_t *)dev_id) == 0){
+#ifdef PC300_DEBUG_INTR
+        printk("cpc_intr: spurious intr %d\n", irq);
+#endif
+        return; /* spurious intr */
+    }
+
+    switch (card->hw.type) {
+	case PC300_RSV:
+	case PC300_X21:
+	    sca_intr(card);
+	    break;
+
+	case PC300_TE:
+	    while ((plx_status = (cpc_readb(card->hw.plxbase + 0x4c) & 
+			(PLX_9050_LINT1_STATUS|PLX_9050_LINT2_STATUS))) != 0) {
+		if (plx_status & PLX_9050_LINT1_STATUS) { /* SCA Interrupt */
+		    sca_intr(card);
+		}
+		if (plx_status & PLX_9050_LINT2_STATUS) { /* FALC Interrupt */
+		    falc_intr(card);
+		}
+	    }
+	    break;
+    }
+}
+
+void 
+cpc_sca_status(pc300_t *card, int ch)
+{
+    ucchar ilar;
+    uclong scabase = card->hw.scabase;
+    uclong flags;
+
+    tx_dma_buf_check(card, ch);
+    rx_dma_buf_check(card, ch);
+    ilar = cpc_readb(scabase + ILAR);
+    printk("ILAR=0x%02x, WCRL=0x%02x, PCR=0x%02x, BTCR=0x%02x, BOLR=0x%02x\n", 
+	   ilar, cpc_readb(scabase + WCRL),
+	   cpc_readb(scabase + PCR),
+	   cpc_readb(scabase + BTCR),
+	   cpc_readb(scabase + BOLR));
+    printk("TX_CDA=0x%08lx, TX_EDA=0x%08lx\n", 
+	   (uclong)cpc_readl(scabase + DTX_REG(CDAL, ch)),
+	   (uclong)cpc_readl(scabase + DTX_REG(EDAL, ch)));
+    printk("RX_CDA=0x%08lx, RX_EDA=0x%08lx, BFL=0x%04x\n", 
+	   (uclong)cpc_readl(scabase + DRX_REG(CDAL, ch)),
+	   (uclong)cpc_readl(scabase + DRX_REG(EDAL, ch)),
+	   cpc_readw(scabase + DRX_REG(BFLL, ch)));
+    printk("DMER=0x%02x, DSR_TX=0x%02x, DSR_RX=0x%02x\n", 
+	   cpc_readb(scabase + DMER),
+	   cpc_readb(scabase + DSR_TX(ch)),
+	   cpc_readb(scabase + DSR_RX(ch)));
+    printk("DMR_TX=0x%02x, DMR_RX=0x%02x, DIR_TX=0x%02x, DIR_RX=0x%02x\n", 
+	   cpc_readb(scabase + DMR_TX(ch)),
+	   cpc_readb(scabase + DMR_RX(ch)),
+	   cpc_readb(scabase + DIR_TX(ch)),
+	   cpc_readb(scabase + DIR_RX(ch)));
+    printk("DCR_TX=0x%02x, DCR_RX=0x%02x, FCT_TX=0x%02x, FCT_RX=0x%02x\n", 
+	   cpc_readb(scabase + DCR_TX(ch)),
+	   cpc_readb(scabase + DCR_RX(ch)),
+	   cpc_readb(scabase + FCT_TX(ch)),
+	   cpc_readb(scabase + FCT_RX(ch)));
+    printk("MD0=0x%02x, MD1=0x%02x, MD2=0x%02x, MD3=0x%02x, IDL=0x%02x\n",
+	   cpc_readb(scabase + M_REG(MD0, ch)),
+	   cpc_readb(scabase + M_REG(MD1, ch)),
+	   cpc_readb(scabase + M_REG(MD2, ch)),
+	   cpc_readb(scabase + M_REG(MD3, ch)),
+	   cpc_readb(scabase + M_REG(IDL, ch)));
+    printk("CMD=0x%02x, SA0=0x%02x, SA1=0x%02x, TFN=0x%02x, CTL=0x%02x\n",
+	   cpc_readb(scabase + M_REG(CMD, ch)),
+	   cpc_readb(scabase + M_REG(SA0, ch)),
+	   cpc_readb(scabase + M_REG(SA1, ch)),
+	   cpc_readb(scabase + M_REG(TFN, ch)),
+	   cpc_readb(scabase + M_REG(CTL, ch)));
+    printk("ST0=0x%02x, ST1=0x%02x, ST2=0x%02x, ST3=0x%02x, ST4=0x%02x\n",
+	   cpc_readb(scabase + M_REG(ST0, ch)),
+	   cpc_readb(scabase + M_REG(ST1, ch)),
+	   cpc_readb(scabase + M_REG(ST2, ch)),
+	   cpc_readb(scabase + M_REG(ST3, ch)),
+	   cpc_readb(scabase + M_REG(ST4, ch)));
+    printk("CST0=0x%02x, CST1=0x%02x, CST2=0x%02x, CST3=0x%02x, FST=0x%02x\n",
+	   cpc_readb(scabase + M_REG(CST0, ch)),
+	   cpc_readb(scabase + M_REG(CST1, ch)),
+	   cpc_readb(scabase + M_REG(CST2, ch)),
+	   cpc_readb(scabase + M_REG(CST3, ch)),
+	   cpc_readb(scabase + M_REG(FST, ch)));
+    printk("TRC0=0x%02x, TRC1=0x%02x, RRC=0x%02x, TBN=0x%02x, RBN=0x%02x\n",
+	   cpc_readb(scabase + M_REG(TRC0, ch)),
+	   cpc_readb(scabase + M_REG(TRC1, ch)),
+	   cpc_readb(scabase + M_REG(RRC, ch)),
+	   cpc_readb(scabase + M_REG(TBN, ch)),
+	   cpc_readb(scabase + M_REG(RBN, ch)));
+    printk("TFS=0x%02x, TNR0=0x%02x, TNR1=0x%02x, RNR=0x%02x\n",
+	   cpc_readb(scabase + M_REG(TFS, ch)),
+	   cpc_readb(scabase + M_REG(TNR0, ch)),
+	   cpc_readb(scabase + M_REG(TNR1, ch)),
+	   cpc_readb(scabase + M_REG(RNR, ch)));
+    printk("TCR=0x%02x, RCR=0x%02x, TNR1=0x%02x, RNR=0x%02x\n",
+	   cpc_readb(scabase + M_REG(TCR, ch)),
+	   cpc_readb(scabase + M_REG(RCR, ch)),
+	   cpc_readb(scabase + M_REG(TNR1, ch)),
+	   cpc_readb(scabase + M_REG(RNR, ch)));
+    printk("TXS=0x%02x, RXS=0x%02x, EXS=0x%02x, TMCT=0x%02x, TMCR=0x%02x\n",
+	   cpc_readb(scabase + M_REG(TXS, ch)),
+	   cpc_readb(scabase + M_REG(RXS, ch)),
+	   cpc_readb(scabase + M_REG(EXS, ch)),
+	   cpc_readb(scabase + M_REG(TMCT, ch)),
+	   cpc_readb(scabase + M_REG(TMCR, ch)));
+    printk("IE0=0x%02x, IE1=0x%02x, IE2=0x%02x, IE4=0x%02x, FIE=0x%02x\n",
+	   cpc_readb(scabase + M_REG(IE0, ch)),
+	   cpc_readb(scabase + M_REG(IE1, ch)),
+	   cpc_readb(scabase + M_REG(IE2, ch)),
+	   cpc_readb(scabase + M_REG(IE4, ch)),
+	   cpc_readb(scabase + M_REG(FIE, ch)));
+    printk("IER0=0x%08lx\n", (uclong)cpc_readl(scabase + IER0)); 
+
+    if (ilar != 0) {
+	CPC_LOCK(card, flags);
+	cpc_writeb(scabase + ILAR, ilar);
+	cpc_writeb(scabase + DMER, 0x80);
+	CPC_UNLOCK(card, flags);
+    }
+}
+
+void 
+cpc_falc_status(pc300_t *card, int ch)
+{
+    pc300ch_t *chan = &card->chan[ch];
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    uclong flags;
+
+    CPC_LOCK(card, flags);
+    printk("CH%d:   %s %s  %d channels\n",
+	ch, (pfalc->sync ? "SYNC":""), (pfalc->active ? "ACTIVE":""), 
+	pfalc->num_channels);
+
+    printk("        pden=%d,  los=%d,  losr=%d,  lfa=%d,  farec=%d\n",
+        pfalc->pden, pfalc->los, pfalc->losr, pfalc->lfa, pfalc->farec);
+    printk("        lmfa=%d,  ais=%d,  sec=%d,  es=%d,  rai=%d\n",
+        pfalc->lmfa, pfalc->ais, pfalc->sec, pfalc->es, pfalc->rai);
+    printk("        bec=%d,  fec=%d,  cvc=%d,  cec=%d,  ebc=%d\n",
+        pfalc->bec, pfalc->fec, pfalc->cvc, pfalc->cec, pfalc->ebc);
+
+    printk("\n");
+    printk("        STATUS: %s  %s  %s  %s  %s  %s\n",
+	(pfalc->red_alarm ? "RED":""), 
+	(pfalc->blue_alarm ? "BLU":""), 
+	(pfalc->yellow_alarm ? "YEL":""), 
+	(pfalc->loss_fa ? "LFA":""), 
+	(pfalc->loss_mfa ? "LMF":""), 
+	(pfalc->prbs ? "PRB":""));
+    CPC_UNLOCK(card, flags);
+}
+
+int 
+cpc_ioctl(hdlc_device *hdlc, struct ifreq *ifr, int cmd)
+{
+    struct device *dev = hdlc_to_dev(hdlc);
+    pc300dev_t *d = (pc300dev_t *)dev->priv;
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    int ch = chan->channel;
+    int value;
+    void *arg = (void *) ifr->ifr_data;
+
+    if(!capable(CAP_NET_ADMIN))
+	return -EPERM;
+
+    switch(cmd) {
+	case SIOCGPC300CONF:
+	    conf->proto = hdlc->mode;
+	    if (!arg || copy_to_user(arg, conf, sizeof(pc300chconf_t)))
+		return -EINVAL;
+	    return 0;
+	case SIOCSPC300CONF:
+	    if (!suser())
+		return -EPERM;
+	    if (!arg || copy_from_user(conf, arg, sizeof(pc300chconf_t)))
+		return -EINVAL;
+	    return 0;
+	case SIOCGPC300STATUS:
+	    cpc_sca_status(card, ch);
+	    return 0;
+	case SIOCGPC300FALCSTATUS:
+	    cpc_falc_status(card, ch);
+	    return 0;
+	case HDLCSETLINE:
+	    value = ifr->ifr_ifru.ifru_ivalue;
+	    switch (value) {
+		case LINE_LOOPBACK:
+		    cpc_writeb(card->hw.scabase + M_REG(MD2, ch), 
+			       cpc_readb(card->hw.scabase + M_REG(MD2, ch)) | 
+			       MD2_LOOP_MIR);
+		    conf->loopback = 1;
+		    return 0;
+
+		case LINE_NOLOOPBACK:
+		    cpc_writeb(card->hw.scabase + M_REG(MD2, ch), 
+			       cpc_readb(card->hw.scabase + M_REG(MD2, ch)) & 
+			       ~MD2_LOOP_MIR);
+		    conf->loopback = 0;
+		    return 0;
+
+		case LINE_V35:
+		case LINE_X21:
+		case LINE_RS232:
+		case LINE_T1:
+		case LINE_E1:
+		    /* Media */
+		    conf->media = value;
+		    return 0;
+
+		default:
+		    /* Clock rate */
+		    conf->clkrate = value;
+		    return 0;
+	    }
+	
+	default:
+	    switch(hdlc->mode & ~MODE_SOFT) {
+#ifdef CONFIG_PC300_X25
+		case MODE_X25:
+		    /* There are no X.25-specific ioctls */
+		    return -EINVAL;
+#endif /* CONFIG_PC300_X25 */
+		default:
+		    return -EINVAL;
+	    }
+    }
+}
+
+static int
+clock_rate_calc(uclong rate, uclong clock, int *br_io)
+{
+    int br, tc;
+    int br_pwr, error;
+
+    if (rate == 0)
+	return (0);
+
+    for (br = 0, br_pwr = 1 ; br <= 9 ; br++, br_pwr <<= 1) {
+	if ((tc = clock / br_pwr / rate) <= 0xff) {
+	    *br_io = br;
+	    break;
+	}
+    }
+
+    if (tc <= 0xff) {
+	error = ((rate - (clock / br_pwr / rate)) / rate) * 1000;
+	/* Errors bigger than +/- 1% won't be tolerated */
+	if (error < -10 || error > 10)
+	    return (-1);
+	else
+	    return (tc);
+    } else {
+	return (-1);
+    }
+}
+
+int
+ch_config(pc300dev_t *d)
+{
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300chconf_t *conf = (pc300chconf_t *)&chan->conf;
+    pc300_t *card = (pc300_t *)chan->card;
+    uclong scabase = card->hw.scabase;
+    uclong plxbase = card->hw.plxbase;
+    int ch = chan->channel;
+    uclong clkrate = chan->conf.clkrate;
+    ucchar loopback = (conf->loopback ? MD2_LOOP_MIR : MD2_F_DUPLEX);
+    int tmc, br;
+
+    /* Reset the channel */
+    cpc_writeb(scabase + M_REG(CMD, ch), CMD_CH_RST);
+
+    /* Configure the SCA registers */
+    cpc_writeb(scabase + M_REG(MD0, ch),
+                (MD0_CRC_CCITT|MD0_CRCC0|MD0_BIT_SYNC));
+    cpc_writeb(scabase + M_REG(MD1, ch), 0);
+    cpc_writeb(scabase + M_REG(MD2, ch), (loopback|MD2_ADPLL_X8|MD2_NRZ));
+    cpc_writeb(scabase + M_REG(IDL, ch), 0x7e);
+    cpc_writeb(scabase + M_REG(CTL, ch), CTL_URSKP|CTL_IDLC);
+
+    /* Configure HW media */
+    switch(card->hw.type) {
+	case PC300_RSV:
+	    if(conf->media == LINE_V35) {
+		cpc_writel((plxbase+0x50),
+			cpc_readl(plxbase+0x50) | PC300_CHMEDIA_MASK(ch));
+	    } else {
+		cpc_writel((plxbase+0x50),
+			cpc_readl(plxbase+0x50) & ~PC300_CHMEDIA_MASK(ch));
+	    }
+	    break;
+
+	case PC300_X21:
+	    break;
+
+	case PC300_TE:
+	    te_config(card, ch);
+	    break;
+    }
+
+    switch(card->hw.type) {
+	case PC300_RSV:
+	case PC300_X21:
+	    if (clkrate) {
+		/* Calculate the clkrate rate parameters */
+		tmc = clock_rate_calc(clkrate, card->hw.clock, &br);
+		cpc_writeb(scabase + M_REG(TMCT, ch), tmc);
+		cpc_writeb(scabase + M_REG(TXS, ch), (TXS_DTRXC|TXS_IBRG|br));
+		cpc_writeb(scabase + M_REG(TMCR, ch), tmc);
+		cpc_writeb(scabase + M_REG(RXS, ch), (RXS_IBRG|br));
+		if (card->hw.type == PC300_X21) {
+		    cpc_writeb(scabase + M_REG(GPO, ch), 1);
+		    cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1|EXS_RES1);
+		} else {
+		    cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1);
+		}
+	    } else {
+		cpc_writeb(scabase + M_REG(TMCT, ch), 1);
+		cpc_writeb(scabase + M_REG(TXS, ch), TXS_DTRXC);
+		cpc_writeb(scabase + M_REG(TMCR, ch), 1);
+		cpc_writeb(scabase + M_REG(RXS, ch), 0);
+		if (card->hw.type == PC300_X21) {
+		    cpc_writeb(scabase + M_REG(GPO, ch), 0);
+		    cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1|EXS_RES1);
+		} else {
+		    cpc_writeb(scabase + M_REG(EXS, ch), EXS_TES1);
+		}
+	    }
+	    break;
+
+	case PC300_TE:
+	    /* SCA always receives clock from the FALC chip */
+	    cpc_writeb(scabase + M_REG(TMCT, ch), 1);
+	    cpc_writeb(scabase + M_REG(TXS, ch), 0);
+	    cpc_writeb(scabase + M_REG(TMCR, ch), 1);
+	    cpc_writeb(scabase + M_REG(RXS, ch), 0);
+	    cpc_writeb(scabase + M_REG(EXS, ch), 0);
+	    break;
+    }
+
+    /* Enable Interrupts */
+    cpc_writel(scabase + IER0, 
+	cpc_readl(scabase + IER0) |
+	IR0_DRX(IR0_EFT|IR0_DMIA|IR0_DMIB, ch) |
+	IR0_DTX(IR0_EFT|IR0_DMIA|IR0_DMIB, ch) );
+
+    return 0;
+}
+
+int
+rx_config(pc300dev_t *d)
+{
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    uclong scabase = card->hw.scabase;
+    int ch = chan->channel;
+
+    cpc_writeb(scabase + DSR_RX(ch), 0);
+
+    /* General RX settings */
+    cpc_writeb(scabase + M_REG(RRC, ch), 0);
+    cpc_writeb(scabase + M_REG(RNR, ch), 16);
+
+    /* Enable reception */
+    cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_CRC_INIT);
+    cpc_writeb(scabase + M_REG(CMD, ch), CMD_RX_ENA);
+
+    /* Initialize DMA stuff */
+    chan->rx_first_bd = 0;
+    chan->rx_last_bd = N_DMA_RX_BUF - 1;
+    rx_dma_buf_init(card, ch);
+    cpc_writeb(scabase + DCR_RX(ch), DCR_FCT_CLR);
+    cpc_writeb(scabase + DMR_RX(ch), (DMR_TMOD | DMR_NF));
+    cpc_writeb(scabase + DIR_RX(ch), (DIR_EOM | DIR_BOF));
+
+    /* Start DMA */
+    cpc_writel(scabase + DRX_REG(CDAL, ch), RX_BD_ADDR(ch, chan->rx_first_bd));
+    cpc_writel(scabase + DRX_REG(EDAL, ch), RX_BD_ADDR(ch, chan->rx_last_bd));
+    cpc_writew(scabase + DRX_REG(BFLL, ch), BD_DEF_LEN);
+    cpc_writeb(scabase + DSR_RX(ch), DSR_DE);
+
+    return 0;
+}
+
+int
+tx_config(pc300dev_t *d)
+{
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    uclong scabase = card->hw.scabase;
+    int ch = chan->channel;
+
+    cpc_writeb(scabase + DSR_TX(ch), 0);
+
+    /* General TX settings */
+    cpc_writeb(scabase + M_REG(TRC0, ch), 0);
+    cpc_writeb(scabase + M_REG(TFS, ch), 32);
+    cpc_writeb(scabase + M_REG(TNR0, ch), 20);
+    cpc_writeb(scabase + M_REG(TNR1, ch), 48);
+    cpc_writeb(scabase + M_REG(TCR, ch), 8);
+
+    /* Enable transmission */
+    cpc_writeb(scabase + M_REG(CMD, ch), CMD_TX_CRC_INIT);
+
+    /* Initialize DMA stuff */
+    chan->tx_first_bd = 0;
+    chan->tx_next_bd = 0;
+    tx_dma_buf_init(card, ch);
+    cpc_writeb(scabase + DCR_TX(ch), DCR_FCT_CLR);
+    cpc_writeb(scabase + DMR_TX(ch), (DMR_TMOD | DMR_NF));
+    cpc_writeb(scabase + DIR_TX(ch), (DIR_EOM | DIR_BOF | DIR_UDRF));
+    cpc_writel(scabase + DTX_REG(CDAL, ch), TX_BD_ADDR(ch, chan->tx_first_bd));
+    cpc_writel(scabase + DTX_REG(EDAL, ch), TX_BD_ADDR(ch, chan->tx_next_bd));
+
+    return 0;
+}
+
+int
+cpc_opench(pc300dev_t *d)
+{
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    int ch = chan->channel;
+    uclong scabase = card->hw.scabase;
+    int err = -1;
+
+    err = ch_config(d);
+    if (err)
+	return err;
+
+    err = rx_config(d);
+    if (err)
+	return err;
+
+    err = tx_config(d);
+    if (err)
+	return err;
+
+    /* Assert RTS and DTR */
+    cpc_writeb(scabase + M_REG(CTL, ch), 
+	cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
+
+    return 0;
+}
+
+void
+cpc_closech(pc300dev_t *d)
+{
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    falc_t *pfalc = (falc_t *)&chan->falc;
+    int ch = chan->channel;
+
+    cpc_writeb(card->hw.scabase + M_REG(CMD, ch), CMD_CH_RST);
+    if (card->hw.type == PC300_TE) {
+	memset(pfalc, 0, sizeof(falc_t));
+	cpc_writeb(card->hw.falcbase + CPLD_REG2,
+		   cpc_readb(card->hw.falcbase + CPLD_REG2) & 
+		   ~((CPLD_REG2_FALC_TX_CLK | CPLD_REG2_FALC_RX_CLK | 
+		      CPLD_REG2_FALC_LED2) << (2*ch)));
+	/* Reset the FALC chip */
+	cpc_writeb(card->hw.falcbase + CPLD_REG1,
+		   cpc_readb(card->hw.falcbase + CPLD_REG1) | 
+		   (CPLD_REG1_FALC_RESET << (2*ch)));
+	udelay(10000);
+	cpc_writeb(card->hw.falcbase + CPLD_REG1,
+		   cpc_readb(card->hw.falcbase + CPLD_REG1) & 
+		   ~(CPLD_REG1_FALC_RESET << (2*ch)));
+    }
+}
+
+int
+cpc_open(hdlc_device *hdlc)
+{
+    struct device *dev = hdlc_to_dev(hdlc);
+    pc300dev_t *d = (pc300dev_t *)dev->priv;
+    int err = -1;
+
+    err = cpc_opench(d);
+    if (err)
+	return err;
+
+    switch(hdlc->mode & ~MODE_SOFT) {
+#ifdef CONFIG_PC300_X25
+	case MODE_X25:
+	{
+	    struct lapb_register_struct cpc_lapb_callbacks;
+
+	    hdlc->ioctl = cpc_ioctl;
+	    cpc_lapb_callbacks.connect_confirmation = cpc_lapb_connected;
+	    cpc_lapb_callbacks.connect_indication = cpc_lapb_connected;
+	    cpc_lapb_callbacks.disconnect_confirmation = cpc_lapb_disconnected;
+	    cpc_lapb_callbacks.disconnect_indication = cpc_lapb_disconnected;
+	    cpc_lapb_callbacks.data_indication = cpc_lapb_data_indication;
+	    cpc_lapb_callbacks.data_transmit = cpc_lapb_data_transmit;
+
+	    if ((err = lapb_register(d, &cpc_lapb_callbacks)) != LAPB_OK) {
+		printk("%s: lapb_register error - %d\n", dev->name, err);
+		dev->tbusy = 1;
+		dev->start = 0;
+		return -ENODEV;
+	    }
+	    dev->hard_start_xmit = cpc_x25_packetlayer_xmit;
+	    dev->type = ARPHRD_X25;
+	    dev->hard_header_len = 2;
+	    dev->addr_len = 0;
+	    break;
+	}
+#endif /* CONFIG_PC300_X25 */
+	default:
+	    break;
+    }
+    dev->tbusy = 0;
+    dev->interrupt = 0;
+    dev->start = 1;
+    MOD_INC_USE_COUNT;
+    return 0;
+}
+
+void
+cpc_close(hdlc_device *hdlc)
+{
+    struct device *dev = hdlc_to_dev(hdlc);
+    pc300dev_t *d = (pc300dev_t *)dev->priv;
+    pc300ch_t *chan = (pc300ch_t *)d->chan;
+    pc300_t *card = (pc300_t *)chan->card;
+    uclong flags;
+
+    CPC_LOCK(card, flags);
+    switch(hdlc->mode & ~MODE_SOFT) {
+#ifdef CONFIG_PC300_X25
+	case MODE_X25:
+	{
+	    int err;
+
+	    if ((err = lapb_unregister(d)) != LAPB_OK) {
+		printk("%s: lapb_unregister error - %d\n", dev->name, err);
+	    }
+	    break;
+	}
+#endif /* CONFIG_PC300_X25 */
+	default:
+	    break;
+    }
+    if (d->tx_skb) {
+	dev_kfree_skb(d->tx_skb);
+	d->tx_skb = NULL;
+    }
+    dev->tbusy = 1;
+    dev->start = 0;
+    cpc_closech(d);
+    CPC_UNLOCK(card, flags);
+
+    MOD_DEC_USE_COUNT;
+}
+
+static uclong
+detect_ram(pc300_t *card)
+{
+    uclong i;
+    ucchar data;
+    uclong rambase = card->hw.rambase;
+
+    card->hw.ramsize = PC300_RAMSIZE;
+    /* Let's find out how much RAM is present on this board */
+    for (i = 0; i < card->hw.ramsize ; i++) {
+        data = (ucchar)(i & 0xff);
+        cpc_writeb(rambase + i, data);
+        if (cpc_readb(rambase + i) != data) {
+            break;
+        }
+    }
+    return (i);
+}
+
+static void
+plx_init(pc300_t *card)
+{
+  struct RUNTIME_9050 *plx_ctl = (struct RUNTIME_9050 *)card->hw.plxbase;
+
+    /* Reset PLX */
+    cpc_writel(&plx_ctl->init_ctrl, cpc_readl(&plx_ctl->init_ctrl)|0x40000000);
+    udelay(10000L);
+    cpc_writel(&plx_ctl->init_ctrl, cpc_readl(&plx_ctl->init_ctrl)&~0x40000000);
+
+    /* Reload Config. Registers from EEPROM */
+    cpc_writel(&plx_ctl->init_ctrl, cpc_readl(&plx_ctl->init_ctrl)|0x20000000);
+    udelay(10000L);
+    cpc_writel(&plx_ctl->init_ctrl, cpc_readl(&plx_ctl->init_ctrl)&~0x20000000);
+
+}
+
+__initfunc(static int  
+cpc_detect(void))
+{
+#ifdef CONFIG_PCI
+    static struct pci_dev	*pdev = NULL;
+    ucchar	cpc_rev_id;
+    ucchar	cpc_irq = 0;
+    uclong	cpc_plxphys, cpc_ramphys, cpc_scaphys, cpc_falcphys, cpc_iophys;
+    uclong	cpc_plxbase, cpc_rambase, cpc_scabase, cpc_falcbase;
+    ucshort	i, j, eeprom_outdated = 0;
+    ucshort	device_id, dev_index = 0;
+    pc300_t	*card;
+
+    if(pci_present() == 0) {    /* PCI bus not present */
+	return 0;
+    }
+    for (i = 0 ; i < PC300_MAXCARDS ; i++) {
+	/* look for a Cyclades card by vendor and device id */
+	while((device_id = cpc_pci_dev_id[dev_index]) != 0) {
+	    if((pdev = pci_find_device(PCI_VENDOR_ID_CYCLADES, 
+				       device_id, pdev)) == NULL) {
+		dev_index++;    /* try next device id */
+	    } else {
+		break;    /* found a board */
+	    }
+	}
+	if (device_id == 0)
+	    break;
+
+	/* read PCI configuration area */
+	cpc_irq = pdev->irq;
+	cpc_iophys = pdev->base_address[1];
+	cpc_scaphys = pdev->base_address[2];
+	cpc_ramphys = pdev->base_address[3];
+	cpc_falcphys = pdev->base_address[4];
+	cpc_plxphys = pdev->base_address[5];
+	pci_read_config_byte(pdev, PCI_REVISION_ID, &cpc_rev_id);
+
+	if ((device_id == PCI_DEVICE_ID_PC300_RX_1) ||
+	    (device_id == PCI_DEVICE_ID_PC300_RX_2) ||
+	    (device_id == PCI_DEVICE_ID_PC300_TE_1) ||
+	    (device_id == PCI_DEVICE_ID_PC300_TE_2)) {
+#ifdef PC300_DEBUG_PCI
+	    printk("cpc (bus=0x0%x, pci_id=0x%x, ",
+		   pdev->bus->number, pdev->devfn);
+	    printk("rev_id=%d) IRQ%d\n", cpc_rev_id, (int)cpc_irq);
+	    printk("cpc:found  ramaddr=0x%lx plxaddr=0x%lx "
+		   "ctladdr=0x%lx falcaddr=0x%lx\n",
+		   (ulong)cpc_ramphys, (ulong)cpc_plxphys, 
+		   (ulong)cpc_scaphys, (ulong)cpc_falcphys);
+#endif
+	    cpc_iophys &= PCI_BASE_ADDRESS_IO_MASK;
+	    cpc_plxphys &= PCI_BASE_ADDRESS_MEM_MASK;
+	    cpc_ramphys &= PCI_BASE_ADDRESS_MEM_MASK;
+	    cpc_scaphys &= PCI_BASE_ADDRESS_MEM_MASK;
+	    cpc_falcphys &= PCI_BASE_ADDRESS_MEM_MASK;
+
+	    /* Although we don't use this I/O region, we should
+	       request it from the kernel anyway, to avoid problems
+	       with other drivers accessing it. */
+	    request_region(cpc_iophys, PC300_PLX_WIN, "Cyclades-PC300");
+
+	    if (cpc_plxphys) {
+		pdev->base_address[0] = cpc_plxphys;
+		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, cpc_plxphys);
+	    } else {
+		eeprom_outdated = 1;
+		cpc_plxphys = pdev->base_address[0];
+		cpc_plxphys &= PCI_BASE_ADDRESS_MEM_MASK;
+	    }
+
+	    cpc_plxbase = (uclong) ioremap(cpc_plxphys, PC300_PLX_WIN);
+	    cpc_rambase = (uclong) ioremap(cpc_ramphys, PC300_RAMSIZE);
+	    cpc_scabase = (uclong) ioremap(cpc_scaphys, PC300_SCASIZE);
+	    switch(device_id) {
+		case PCI_DEVICE_ID_PC300_TE_1:
+		case PCI_DEVICE_ID_PC300_TE_2:
+		    cpc_falcbase = (uclong) ioremap(cpc_falcphys, 
+						    PC300_FALCSIZE);
+		    break;
+
+		case PCI_DEVICE_ID_PC300_RX_1:
+		case PCI_DEVICE_ID_PC300_RX_2:
+		default:
+		    cpc_falcbase = 0;
+		    break;
+	    }
+
+#ifdef PC300_DEBUG_PCI
+	    printk("cpc: relocate ramaddr=0x%lx plxaddr=0x%lx "
+		   "ctladdr=0x%lx falcaddr=0x%lx\n",
+		   (ulong)cpc_rambase, (ulong)cpc_plxbase, 
+		   (ulong)cpc_scabase, (ulong)cpc_falcbase);
+#endif
+	    /* Fill the next card structure available */
+	    for (j = 0 ; j < PC300_MAXCARDS ; j++) {
+		if (cpc_card[j].hw.rambase == 0)  break;
+	    }
+
+	    if (j == PC300_MAXCARDS) {	/* No more cards available */
+		printk("PC300 found at RAM 0x%lx, "
+		       "but no more cards can be used.\n",
+		       (ulong) cpc_ramphys);
+		printk("Change PC300_MAXCARDS in pc300drv.c and "
+		       "recompile your kernel.\n");
+		return(i);
+	    }
+
+	    /* Allocate IRQ */
+	    if(request_irq(cpc_irq, cpc_intr, SA_SHIRQ, "Cyclades-PC300", 
+			   &cpc_card[j]))
+	    {
+		printk("PC300 found at RAM 0x%lx, "
+		       "but could not allocate IRQ%d.\n",
+		       (ulong) cpc_ramphys, cpc_irq);
+		return(i);
+	    }
+
+	    card = &cpc_card[j];
+
+	    /* Set PC300 HW structure */
+	    card->hw.plxphys = cpc_plxphys;
+	    card->hw.plxbase = cpc_plxbase;
+	    card->hw.plxsize = (uclong)PC300_PLX_WIN;
+	    card->hw.scaphys = cpc_scaphys;
+	    card->hw.scabase = cpc_scabase;
+	    card->hw.scasize = (uclong)PC300_SCASIZE;
+	    card->hw.ramphys = cpc_ramphys;
+	    card->hw.rambase = cpc_rambase;
+	    card->hw.ramsize = detect_ram(card);
+	    card->hw.falcphys = cpc_falcphys;
+	    card->hw.falcbase = cpc_falcbase;
+	    card->hw.falcsize = (uclong)PC300_FALCSIZE;
+	    card->hw.irq = (int)cpc_irq;
+	    switch(device_id) {
+		case PCI_DEVICE_ID_PC300_RX_1:
+		case PCI_DEVICE_ID_PC300_TE_1:
+		    card->hw.nchan = 1;
+		    break;
+
+		case PCI_DEVICE_ID_PC300_RX_2:
+		case PCI_DEVICE_ID_PC300_TE_2:
+		default:
+		    card->hw.nchan = PC300_MAXCHAN;
+		    break;
+	    }
+
+	    /* Enable interrupts on the PCI bridge */
+	    plx_init(&cpc_card[j]);
+	    cpc_writew(card->hw.plxbase+0x4c, 
+		cpc_readw(card->hw.plxbase+0x4c) | 0x0040);
+
+#ifdef USE_PCI_CLOCK
+	    /* Set board clock to PCI clock */
+	    cpc_writel(card->hw.plxbase+0x50, 
+		cpc_readl(card->hw.plxbase+0x50) | 0x00000004UL);
+	    card->hw.clock = PC300_PCI_CLOCK;
+#else
+	    /* Set board clock to internal oscillator clock */
+	    cpc_writel(card->hw.plxbase+0x50, 
+		cpc_readl(card->hw.plxbase+0x50) & ~0x00000004UL);
+	    card->hw.clock = PC300_OSC_CLOCK;
+#endif
+
+	    /* Set Global SCA-II registers */
+	    cpc_writeb(card->hw.scabase + PCR, PCR_PR2);
+	    cpc_writeb(card->hw.scabase + BTCR, 0x10);
+	    cpc_writeb(card->hw.scabase + WCRL, 0);
+	    cpc_writeb(card->hw.scabase + DMER, 0x80);
+
+	    /* Set board type */
+	    switch(device_id) {
+		case PCI_DEVICE_ID_PC300_TE_1:
+		case PCI_DEVICE_ID_PC300_TE_2:
+		    card->hw.type = PC300_TE;
+		    /* Enable the board's global clock */
+		    cpc_writeb(card->hw.falcbase + CPLD_REG1,
+			       cpc_readb(card->hw.falcbase + CPLD_REG1) | 
+			       CPLD_REG1_GLOBAL_CLK);
+		    break;
+
+		case PCI_DEVICE_ID_PC300_RX_1:
+		case PCI_DEVICE_ID_PC300_RX_2:
+		default:
+		    if((cpc_readl(card->hw.plxbase+0x50) & PC300_CTYPE_MASK)) {
+			card->hw.type = PC300_X21;
+		    } else {
+			card->hw.type = PC300_RSV;
+		    }
+		    break;
+	    }
+	}
+    }
+    if (eeprom_outdated)
+	printk("WARNING: detected at least one PC300 with an outdated "
+	       "EEPROM.\n");
+    return i;
+#else
+    printk("cpc: WARNING: your kernel does not have PCI support.\n");
+    return 0;
+#endif /* CONFIG_PCI */
+}
+
+/*
+ * This routine prints out the appropriate serial driver version number
+ * and identifies which options were configured into this driver.
+ */
+static inline void
+show_version(void)
+{
+  char *rcsvers, *rcsdate, *tmp;
+    rcsvers = strchr(rcsid, ' '); rcsvers++;
+    tmp = strchr(rcsvers, ' '); *tmp++ = '\0';
+    rcsdate = strchr(tmp, ' '); rcsdate++;
+    tmp = strrchr(rcsdate, ' '); *tmp = '\0';
+    printk("Cyclades-PC300 driver %s %s\n", rcsvers, rcsdate);
+    printk("        built %s %s\n", __DATE__, __TIME__);
+} /* show_version */
+
+__initfunc(int 
+cpc_init(void))
+{
+    int i, j, devcount = 0;
+
+    show_version();
+    memset(&cpc_card, 0, (PC300_MAXCARDS * sizeof(pc300_t)));
+    if((cpc_nboards = cpc_detect()) == 0) {
+	printk("** No boards were found.\n");
+	return -ENODEV;
+    }
+
+    /* Fill in valid structures and invalidate the remaining */
+    for (i = 0 ; i < PC300_MAXCARDS ; i++) {
+	pc300_t *card = &cpc_card[i];
+
+	if (card->hw.rambase != 0) {
+	    for(j = 0; j < card->hw.nchan; j++) {
+		pc300ch_t *chan = &card->chan[j];
+		pc300dev_t *d = &chan->d;
+		hdlc_device *hdlc;
+		struct device *dev;
+
+		memset(chan, 0, sizeof(pc300ch_t));
+
+		chan->card = card;
+		chan->channel = j;
+		chan->conf.clkrate = 64000;
+		chan->conf.loopback = 0;
+		switch(card->hw.type) {
+		    case PC300_TE:
+			chan->conf.media = LINE_T1;
+			chan->conf.lcode = PC300_LC_B8ZS;
+			chan->conf.fr_mode = PC300_FR_ESF;
+			chan->conf.lbo = PC300_LBO_0_DB;
+			chan->conf.rx_sens = PC300_RX_SENS_SH;
+			chan->conf.tslot_bitmap = 0xffffffffUL;
+			break;
+
+		    case PC300_X21:
+			chan->conf.media = LINE_X21;
+			break;
+
+		    case PC300_RSV:
+		    default:
+			chan->conf.media = LINE_RS232;
+			break;
+		}
+		chan->tx_first_bd = 0;
+		chan->tx_next_bd = 0;
+		chan->rx_first_bd = 0;
+		chan->rx_last_bd = N_DMA_RX_BUF - 1;
+
+		d->chan = chan;
+		d->tx_skb = NULL;
+
+		d->hdlc = (hdlc_device *)
+			kmalloc(sizeof(hdlc_device), GFP_KERNEL);
+		if (d->hdlc == NULL)
+		    continue;
+		memset(d->hdlc, 0, sizeof(hdlc_device));
+
+		hdlc = d->hdlc;
+		hdlc->open = cpc_open;
+		hdlc->close = cpc_close;
+		hdlc->ioctl = cpc_ioctl;
+		d->if_ptr = &hdlc->pppdev;
+
+		dev = hdlc_to_dev(d->hdlc);
+		dev->mem_start = card->hw.ramphys;
+		dev->mem_end = card->hw.ramphys + card->hw.ramsize - 1;
+		dev->irq = card->hw.irq;
+		dev->interrupt = 0;
+		dev->start = 0;
+		dev->tx_queue_len = PC300_TX_QUEUE_LEN;
+		dev->hard_start_xmit = cpc_queue_xmit;
+		dev->set_multicast_list = NULL;
+		dev->set_mac_address = NULL;
+
+		if(register_hdlc_device(hdlc) == 0) {
+		    dev->priv = d;	/* We need 'priv', hdlc doesn't */
+		    printk("%s: PC300/", hdlc->name);
+		    switch(card->hw.type) {
+			case PC300_TE:
+			    printk("TE ");
+			    break;
+
+			case PC300_X21:
+			    printk("X21");
+			    break;
+
+			case PC300_RSV:
+			default:
+			    printk("RSV");
+			    break;
+		    }
+		    printk(" #%d, %ldKB of RAM at 0x%lx, IRQ%d, channel %d.\n",
+			   i + 1, card->hw.ramsize/1024, card->hw.ramphys, 
+			   card->hw.irq, j + 1);
+		    devcount++;
+		} else {
+		    *(d->name) = 0;
+		    kfree(d->hdlc);
+		    continue;
+		}
+	    }
+	    spin_lock_init(&card->card_lock);
+	} else {
+	    memset(&card->hw, 0, sizeof (pc300hw_t));
+	}
+    }
+
+    return 0;
+}
+
+#ifdef MODULE
+int init_module (void)
+{
+    return (cpc_init());
+} /* init_module */
+
+void cleanup_module (void)
+{
+    int i, j;
+
+    for (i = 0 ; i < PC300_MAXCARDS ; i++) {
+	pc300_t *card = &cpc_card[i];
+
+        if (card->hw.rambase != 0) {
+	    for(j = 0 ; j < card->hw.nchan ; j++) {
+		unregister_hdlc_device(card->chan[j].d.hdlc);
+	    }
+
+	    iounmap((void *)card->hw.plxbase);
+	    iounmap((void *)card->hw.scabase);
+	    iounmap((void *)card->hw.rambase);
+	    if (card->hw.type == PC300_TE)
+		iounmap((void *)card->hw.falcbase);
+	    if (card->hw.irq)
+		free_irq(card->hw.irq, card);
+        }
+    }
+}
+#endif
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/ppp.c linux.17p18/drivers/net/ppp.c
--- linux.vanilla/drivers/net/ppp.c	Fri Apr 21 12:46:19 2000
+++ linux.17p18/drivers/net/ppp.c	Tue Aug  1 07:59:45 2000
@@ -49,6 +49,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/types.h>
@@ -94,8 +95,8 @@
  * Local functions
  */
 
+int ppp_register_compressor (struct compressor *cp);
 #ifdef CONFIG_MODULES
-static int ppp_register_compressor (struct compressor *cp);
 static void ppp_unregister_compressor (struct compressor *cp);
 #endif
 
@@ -317,6 +318,10 @@
 
 
 #ifndef MODULE
+
+extern int bsd_comp_install(void);
+extern int ppp_deflate_install(void);
+
 /*
  * Called at boot time if the PPP driver is compiled into the kernel.
  */
@@ -328,7 +333,11 @@
 
 	if (first_time) {
 		first_time = 0;
-		answer	   = ppp_first_time();
+		answer = ppp_first_time();
+		if (answer == 0) {
+			bsd_comp_install();
+			ppp_deflate_install();
+		}
 	}
 	if (answer == 0)
 		answer = -ENODEV;
@@ -861,9 +870,8 @@
 
 	if (test_and_set_bit(XMITFULL, &ppp->state))
 		return -1;
-	ppp->tpkt = skb;
 
-	data = ppp->tpkt->data;
+	data = skb->data;
 	
 	/*
 	 * LCP packets with code values between 1 (configure-reqest)
@@ -877,14 +885,14 @@
 	if (PPP_PROTOCOL(data) < 0x8000)
 		ppp->last_xmit = jiffies;
 	++ppp->stats.ppp_opackets;
-	ppp->stats.ppp_ooctects += ppp->tpkt->len;
+	ppp->stats.ppp_ooctects += skb->len;
 
 	if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) {
 		/* compress protocol field */
 		data[2] = data[1];
 		data[1] = data[0];
-		skb_pull(ppp->tpkt,1);
-		data = ppp->tpkt->data;
+		skb_pull(skb,1);
+		data = skb->data;
 	}
 	
 	/*
@@ -894,9 +902,10 @@
 	    && PPP_ADDRESS(data) == PPP_ALLSTATIONS
 	    && PPP_CONTROL(data) == PPP_UI) {
 		/* strip addr and control field */
-		skb_pull(ppp->tpkt,2);
+		skb_pull(skb,2);
 	}
 
+	ppp->tpkt = skb;
 	return ppp_tty_sync_push(ppp);
 }
 
@@ -3041,8 +3050,10 @@
 	return (struct compressor *) 0;
 }
 
-#ifdef CONFIG_MODULES
-static int ppp_register_compressor (struct compressor *cp)
+/* 
+ * If PPP is built-in then so are compressors, so __initfunc is okay here.
+ */
+__initfunc(int ppp_register_compressor (struct compressor *cp))
 {
 	struct compressor_link *new;
 	unsigned long flags;
@@ -3070,6 +3081,7 @@
 	return 0;
 }
 
+#ifdef CONFIG_MODULES
 static void ppp_unregister_compressor (struct compressor *cp)
 {
 	struct compressor_link *prev = (struct compressor_link *) 0;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/ppp_deflate.c linux.17p18/drivers/net/ppp_deflate.c
--- linux.vanilla/drivers/net/ppp_deflate.c	Fri Apr 21 12:46:19 2000
+++ linux.17p18/drivers/net/ppp_deflate.c	Tue Aug  1 07:59:45 2000
@@ -33,6 +33,7 @@
 
 #include <linux/module.h>
 #include <linux/kernel.h>
+#include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/types.h>
 #include <linux/fcntl.h>
@@ -656,13 +657,7 @@
 	z_comp_stats,		/* decomp_stat */
 };
 
-#ifdef MODULE
-/*************************************************************
- * Module support routines
- *************************************************************/
-
-int
-init_module(void)
+__initfunc(int ppp_deflate_install(void))
 {  
         int answer = ppp_register_compressor (&ppp_deflate);
         if (answer == 0)
@@ -670,6 +665,14 @@
 			"PPP Deflate Compression module registered\n");
 	ppp_register_compressor(&ppp_deflate_draft);
         return answer;
+}
+
+#ifdef MODULE
+
+int
+init_module(void)
+{
+	return ppp_deflate_install();
 }
      
 void
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/rtl8139.c linux.17p18/drivers/net/rtl8139.c
--- linux.vanilla/drivers/net/rtl8139.c	Fri Apr 21 12:46:19 2000
+++ linux.17p18/drivers/net/rtl8139.c	Tue Aug  1 07:59:46 2000
@@ -1265,8 +1265,8 @@
 			} else {
 #if 1  /* USE_IP_COPYSUM */
 				eth_copy_and_sum(skb, &rx_ring[ring_offset + 4],
-								 rx_size, 0);
-				skb_put(skb, rx_size);
+						 rx_size - 4, 0);
+				skb_put(skb, rx_size - 4);
 #else
 				memcpy(skb_put(skb, rx_size), &rx_ring[ring_offset + 4],
 					   rx_size);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/sealevel.c linux.17p18/drivers/net/sealevel.c
--- linux.vanilla/drivers/net/sealevel.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/net/sealevel.c	Wed Aug 16 21:42:30 2000
@@ -325,6 +325,7 @@
 	if(z8530_init(dev)!=0)
 	{
 		printk(KERN_ERR "Z8530 series device not found.\n");
+		restore_flags(flags);
 		goto dmafail2;
 	}
 	if(dev->type==Z85C30)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/slhc.c linux.17p18/drivers/net/slhc.c
--- linux.vanilla/drivers/net/slhc.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/net/slhc.c	Tue Aug  1 07:59:46 2000
@@ -56,6 +56,7 @@
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <net/slhc_vj.h>
 
 #ifdef CONFIG_INET
 /* Entire module is for IP only */
@@ -79,7 +80,6 @@
 #include <asm/uaccess.h>
 #include <linux/mm.h>
 #include <net/checksum.h>
-#include <net/slhc_vj.h>
 #include <asm/unaligned.h>
 
 int last_retran;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/sunhme.c linux.17p18/drivers/net/sunhme.c
--- linux.vanilla/drivers/net/sunhme.c	Fri Apr 21 12:46:21 2000
+++ linux.17p18/drivers/net/sunhme.c	Tue Aug  1 07:59:47 2000
@@ -2336,6 +2336,11 @@
 
 	dev->interrupt = 1;
 
+	if ((happy_status & (GREG_STAT_TXALL | GREG_STAT_RXTOHOST)) &&
+	    (hp->happy_flags & HFLAG_QUATTRO) != 0 &&
+	    pci_dma_wsync != NULL)
+		(void) *(pci_dma_wsync);
+
 	if(happy_status & GREG_STAT_ERRORS) {
 		HMD(("ERRORS "));
 		if(happy_meal_is_not_so_happy(hp, gregs, /* un- */ happy_status)) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/tlan.c linux.17p18/drivers/net/tlan.c
--- linux.vanilla/drivers/net/tlan.c	Fri Apr 21 12:46:21 2000
+++ linux.17p18/drivers/net/tlan.c	Tue Aug  1 07:59:47 2000
@@ -42,8 +42,21 @@
  * 				  to overwrite timers like TLAN_TIMER_ACTIVITY
  * 				  Patch from John Cagle <john.cagle@compaq.com>
  * 				- Removed dependency of HZ being 100.
- *				- Statistics is now fixed.
+ *				- Statistics are now fixed.
  *				- Minor stuff.
+ *
+ *	v1.3 June 9, 2000	- Updated for better SMP performance.
+ *				- Fixed forced speed/duplex settings.
+ *				- Added support for custom MII ioctls.
+ *				- Code clean up.
+ *				- Thanks to Herman Bos <hbos@mih.net> and 
+ *				  Martin Lathoud <nytral@endirect.qc.ca> 
+ *				  for providing me with extensive debug information.
+ *
+ *	v1.3a June 21, 2000     - Minor fixes when driver build as module.
+ *
+ * 	v1.3b June 28, 2000	- Clean ups.
+ *
  ********************************************************************************/
 
 
@@ -55,29 +68,28 @@
 #include <linux/pci.h>
 #include <linux/etherdevice.h>
 #include <linux/delay.h>
-
+#include <asm/spinlock.h>
 
 
 typedef u32 (TLanIntVectorFunc)( struct device *, u16 );
 
-
-#ifdef MODULE
+#ifdef MODULE   
 
 static	struct device	*TLanDevices = NULL;
 static	int		TLanDevicesInstalled = 0;
 
 static	int		aui = 0;
-static	int		sa_int = 0;
 static	int		duplex = 0;
 static	int		speed = 0;
+static const char *tlan_banner = "ThunderLAN driver v1.3b\n";
 
+MODULE_AUTHOR("Maintainer: Torben Mathiasen <torben.mathiasen@compaq.com>");
+MODULE_DESCRIPTION("Driver for TI ThunderLAN based ethernet adapters");
 MODULE_PARM(aui, "i");
-MODULE_PARM(sa_int, "i");
 MODULE_PARM(duplex, "i");
 MODULE_PARM(speed, "i");
 MODULE_PARM(debug, "i");
 EXPORT_NO_SYMBOLS;
-
 #endif
 
 
@@ -85,8 +97,6 @@
 static	int		bbuf = 0;
 static	u8		*TLanPadBuffer;
 static	char		TLanSignature[] = "TLAN";
-static	int		TLanVersionMajor = 1;
-static	int		TLanVersionMinor = 2;
 
 
 static	TLanAdapterEntry TLanAdapterList[] = {
@@ -185,6 +195,7 @@
 static int	TLan_Close(struct device *);
 static struct	net_device_stats *TLan_GetStats( struct device * );
 static void	TLan_SetMulticastList( struct device * );
+static int	TLan_ioctl(struct device *dev, struct ifreq *req, int cmd);
 
 static u32	TLan_HandleInvalid( struct device *, u16 );
 static u32	TLan_HandleTxEOF( struct device *, u16 );
@@ -246,14 +257,16 @@
 TLan_SetTimer( struct device *dev, u32 ticks, u32 type )
 {
 	TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
+	unsigned long flags;
 
-	cli();
+	spin_lock_irqsave(&priv->lock, flags);
 	if ( priv->timer.function != NULL && 
 		priv->timerType != TLAN_TIMER_ACTIVITY) {
+		spin_unlock_irqrestore(&priv->lock, flags);
 		return;
 	}
 	priv->timer.function = &TLan_Timer;
-	sti();
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	priv->timer.data = (unsigned long) dev;
 	priv->timer.expires = jiffies + ticks;
@@ -305,10 +318,8 @@
 	u8		irq;
 	u8		rev;
 
-	printk(KERN_INFO "TLAN driver, v%d.%d, (C) 1997-8 Caldera, Inc.\n",
-		TLanVersionMajor,
-		TLanVersionMinor
-	      );
+	printk(KERN_INFO "%s", tlan_banner);
+	
 	TLanPadBuffer = (u8 *) kmalloc( TLAN_MIN_FRAME_SIZE,
 					( GFP_KERNEL | GFP_DMA )
 				      );
@@ -347,11 +358,12 @@
 			speed = 0;
 		}
 		priv->speed =      speed;
-		priv->sa_int =     sa_int;
 		priv->debug =      debug;
-
+			
 		ether_setup( dev );
 
+		spin_lock_init(&priv->lock);
+
 		failed = register_netdev( dev );
 
 		if ( failed ) {
@@ -496,13 +508,9 @@
 	} else if ( priv->speed == 0x2 ) {
 		priv->speed = TLAN_SPEED_100;
 	}
-	priv->sa_int =     dev->mem_start & 0x02;
 	priv->debug =      dev->mem_end;
 
-
-	printk(KERN_INFO "TLAN %d.%d:  %s irq=%2d io=%04x, %s, Rev. %d\n",
-		TLanVersionMajor,
-		TLanVersionMinor,
+	printk(KERN_INFO "TLAN 1.3b: %s irq=%2d io=%04x, %s, Rev. %d\n",
 		dev->name, 
 		(int) irq, 
 		io_base,
@@ -691,7 +699,7 @@
 	dev->stop = &TLan_Close;
 	dev->get_stats = &TLan_GetStats;
 	dev->set_multicast_list = &TLan_SetMulticastList;
-
+	dev->do_ioctl = &TLan_ioctl;
 
 	return 0;
 
@@ -726,12 +734,8 @@
 	
 	MOD_INC_USE_COUNT;
 
-	if ( priv->sa_int ) {
-		TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN:   Using SA_INTERRUPT\n" ); 
-		err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ | SA_INTERRUPT, TLanSignature, dev );
-	} else {
-		err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ, TLanSignature, dev );
-	}
+	err = request_irq( dev->irq, TLan_HandleInterrupt, SA_SHIRQ, TLanSignature, dev );
+	
 	if ( err ) {
 		printk( "TLAN:  Cannot open %s because IRQ %d is already in use.\n", dev->name, dev->irq );
 		return -EAGAIN;
@@ -754,6 +758,33 @@
 } /* TLan_Open */
 
 
+static int TLan_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+	TLanPrivateInfo *priv = (TLanPrivateInfo *) dev->priv;
+	u16 *data = (u16 *)&rq->ifr_data;
+	u32 phy = priv->phy[priv->phyNum];
+	
+	if (!priv->phyOnline)
+		return -EAGAIN;
+
+	switch(cmd) {
+		case SIOCDEVPRIVATE:
+			data[0] = phy;
+
+                case SIOCDEVPRIVATE+1: /* Read MII register */
+                        TLan_MiiReadReg(dev, data[0], data[1], &data[3]);
+                        return 0;
+
+                case SIOCDEVPRIVATE+2: /* Write MII register */
+                        if (!capable(CAP_NET_ADMIN))
+				return -EPERM;
+			TLan_MiiWriteReg(dev, data[0], data[1], data[2]);
+			return 0;
+	       default:
+			return -EOPNOTSUPP;
+       }
+} /* tlan_ioctl */
+
 
 
 	/***************************************************************
@@ -783,6 +814,7 @@
 	TLanList	*tail_list;
 	u8		*tail_buffer;
 	int		pad;
+	unsigned long   flags;
 
 	if ( ! priv->phyOnline ) {
 		TLAN_DBG( TLAN_DEBUG_TX, "TLAN TRANSMIT:  %s PHY is not ready\n", dev->name );
@@ -823,7 +855,7 @@
 		tail_list->buffer[1].address = 0;
 	}
 
-	cli();
+	spin_lock_irqsave(&priv->lock, flags);
 	tail_list->cStat = TLAN_CSTAT_READY;
 	if ( ! priv->txInProgress ) {
 		priv->txInProgress = 1;
@@ -839,7 +871,7 @@
 			( priv->txList + ( priv->txTail - 1 ) )->forward = virt_to_bus( tail_list );
 		}
 	}
-	sti();
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	CIRC_INC( priv->txTail, TLAN_NUM_TX_LISTS );
 
@@ -883,14 +915,11 @@
 	u32		host_cmd;
 	u16		host_int;
 	int		type;
+	TLanPrivateInfo *priv;
 
 	dev = (struct device *) dev_id;
-
-	cli();
-	if ( dev->interrupt ) {
-		printk( "TLAN:   Re-entering interrupt handler for %s: %ld.\n" , dev->name, dev->interrupt );
-	}
-	dev->interrupt++;
+	priv = (TLanPrivateInfo *) dev->priv;
+	spin_lock(&priv->lock);
 
 	host_int = inw( dev->base_addr + TLAN_HOST_INT );
 	outw( host_int, dev->base_addr + TLAN_HOST_INT );
@@ -905,7 +934,7 @@
 	}
 
 	dev->interrupt--;
-	sti();
+	spin_unlock(&priv->lock);
 
 } /* TLan_HandleInterrupts */
 
@@ -1092,7 +1121,7 @@
 u32 TLan_HandleInvalid( struct device *dev, u16 host_int )
 {
 	host_int = 0;
-	/* printk( "TLAN:  Invalid interrupt on %s.\n", dev->name ); */
+	printk( "TLAN:  Invalid interrupt on %s.\n", dev->name ); 
 	return 0;
 
 } /* TLan_HandleInvalid */
@@ -1163,7 +1192,12 @@
 	if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
 		TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
 		if ( priv->timer.function == NULL ) {
-			TLan_SetTimer( dev, TLAN_TIMER_ACT_DELAY, TLAN_TIMER_ACTIVITY );
+			priv->timer.function = &TLan_Timer;
+			priv->timer.data = (unsigned long) dev;
+			priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
+			priv->timerSetAt = jiffies;
+			priv->timerType = TLAN_TIMER_ACTIVITY;
+			add_timer(&priv->timer);
 		} else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
 			priv->timerSetAt = jiffies;
 		}
@@ -1319,7 +1353,12 @@
 	if ( priv->adapter->flags & TLAN_ADAPTER_ACTIVITY_LED ) {
 		TLan_DioWrite8( dev->base_addr, TLAN_LED_REG, TLAN_LED_LINK | TLAN_LED_ACT );
 		if ( priv->timer.function == NULL )  {
-			TLan_SetTimer( dev, TLAN_TIMER_ACT_DELAY, TLAN_TIMER_ACTIVITY );
+			priv->timer.function = &TLan_Timer;
+			priv->timer.data = (unsigned long) dev;
+			priv->timer.expires = jiffies + TLAN_TIMER_ACT_DELAY;
+			priv->timerSetAt = jiffies;
+			priv->timerType = TLAN_TIMER_ACTIVITY;
+			add_timer(&priv->timer);
 		} else if ( priv->timerType == TLAN_TIMER_ACTIVITY ) {
 			priv->timerSetAt = jiffies;
 		}
@@ -1567,6 +1606,7 @@
 	struct device	*dev = (struct device *) data;
 	TLanPrivateInfo	*priv = (TLanPrivateInfo *) dev->priv;
 	u32		elapsed;
+	unsigned long   flags = 0;
 
 	priv->timer.function = NULL;
 
@@ -1590,7 +1630,7 @@
 			TLan_FinishReset( dev );
 			break;
 		case TLAN_TIMER_ACTIVITY:
-			cli();
+			spin_lock_irqsave(&priv->lock, flags);
 			if ( priv->timer.function == NULL ) {
 				elapsed = jiffies - priv->timerSetAt;
 				if ( elapsed >= TLAN_TIMER_ACT_DELAY ) {
@@ -1598,11 +1638,11 @@
 				} else  {
 					priv->timer.function = &TLan_Timer;
 					priv->timer.expires = priv->timerSetAt + TLAN_TIMER_ACT_DELAY;
-					sti();
+					spin_unlock_irqrestore(&priv->lock, flags);
 					add_timer( &priv->timer );
 				}
 			}
-			sti();
+			spin_unlock_irqrestore(&priv->lock, flags);
 			break;
 		default:
 			break;
@@ -2224,6 +2264,7 @@
 	TLan_MiiSync( dev->base_addr );
 	value = MII_GC_LOOPBK;
 	TLan_MiiWriteReg( dev, priv->phy[priv->phyNum], MII_GEN_CTL, value );
+	TLan_MiiSync(dev->base_addr);  
 
 	/* Wait for 500 ms and reset the
 	 * tranceiver.  The TLAN docs say both 50 ms and
@@ -2252,7 +2293,6 @@
 	while ( value & MII_GC_RESET ) {
 		TLan_MiiReadReg( dev, phy, MII_GEN_CTL, &value );
 	}
-	TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0 );
 
 	/* Wait for 500 ms and initialize.
 	 * I don't remember why I wait this long.
@@ -2275,39 +2315,46 @@
 	u16		tctl;
 
 	phy = priv->phy[priv->phyNum];
-
 	TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN:  %s: Trying to activate link.\n", dev->name );
 	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &status );
-	if ( ( status & MII_GS_AUTONEG ) && 
-	     ( priv->duplex == TLAN_DUPLEX_DEFAULT ) && 
-	     ( priv->speed == TLAN_SPEED_DEFAULT ) &&
-	     ( ! priv->aui ) ) {
+	TLan_MiiReadReg( dev, phy, MII_GEN_STS, &ability );
+
+	if ( ( status & MII_GS_AUTONEG ) &&
+	     ( !priv->aui ) ) {
+
 		ability = status >> 11;
+		if ( priv->speed  == TLAN_SPEED_10 &&
+		     priv->duplex == TLAN_DUPLEX_HALF ) {
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0000);
+		} else if ( priv->speed  == TLAN_SPEED_10 &&
+			    priv->duplex == TLAN_DUPLEX_FULL ) {
+			priv->tlanFullDuplex = TRUE;
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x0100);
+		} else if ( priv->speed  == TLAN_SPEED_100 &&
+			    priv->duplex == TLAN_DUPLEX_HALF ) {
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2000);
+		} else if ( priv->speed  == TLAN_SPEED_100 &&
+			    priv->duplex == TLAN_DUPLEX_FULL ) {
+			priv->tlanFullDuplex = TRUE;
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x2100);
+		} else {
 
-		if ( priv->speed == TLAN_SPEED_10 ) {
-			ability &= 0x0003;
-		} else if ( priv->speed == TLAN_SPEED_100 ) {
-			ability &= 0x001C;
-		}
-
-		if ( priv->duplex == TLAN_DUPLEX_FULL ) {
-			ability &= 0x000A;
-		} else if ( priv->duplex == TLAN_DUPLEX_HALF ) {
-			ability &= 0x0005;
-		}
-
-		TLan_MiiWriteReg( dev, phy, MII_AN_ADV, ( ability << 5 ) | 1 );
-       		TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
-		TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
-
-		/* Wait for 4 sec for autonegotiation
-		 * to complete.  The max spec time is less than this
-		 * but the card need additional time to start AN.
-		 * .5 sec should be plenty extra.
-		 */
-		printk(KERN_INFO "TLAN:  %s: Starting autonegotiation.\n", dev->name );
-		TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_PHY_FINISH_AN );
-		return;
+			/* Set Auto-Neg advertisement */
+			TLan_MiiWriteReg( dev, phy, MII_AN_ADV, ( ability << 5 ) | 1 );
+       			/* Enable Auto-Neg */
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1000 );
+			/* Restart Auto-Neg */
+			TLan_MiiWriteReg( dev, phy, MII_GEN_CTL, 0x1200 );
+
+			/* Wait for 4 sec for autonegotiation
+		 	* to complete.  The max spec time is less than this
+		 	* but the card need additional time to start AN.
+		 	* .5 sec should be plenty extra.
+		 	*/
+			printk(KERN_INFO "TLAN:  %s: Starting autonegotiation.\n", dev->name );
+			TLan_SetTimer( dev, (4*HZ), TLAN_TIMER_PHY_FINISH_AN );
+			return;
+		}
 	}
 
 	if ( ( priv->aui ) && ( priv->phyNum != 0 ) ) {
@@ -2338,7 +2385,7 @@
 	/* Wait for 1 sec to give the tranceiver time
 	 * to establish link.
 	 */
-	TLan_SetTimer( dev, HZ, TLAN_TIMER_FINISH_RESET );
+	TLan_SetTimer( dev, (2*HZ), TLAN_TIMER_FINISH_RESET );
 
 } /* TLan_PhyStartLink */
 
@@ -2447,14 +2494,15 @@
 	u32	i;
 	int	err;
 	int	minten;
+	TLanPrivateInfo *priv;
+	unsigned long flags = 0;
 
 	err = FALSE;
 	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
 	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-	if ( dev->interrupt == 0 )
-		cli();
-	dev->interrupt++;
+	
+	priv = (TLanPrivateInfo *) dev->priv;
+	spin_lock_irqsave(&priv->lock, flags);
 
 	TLan_MiiSync(dev->base_addr);
 
@@ -2501,9 +2549,7 @@
 
 	*val = tmp;
 
-	dev->interrupt--;
-	if ( dev->interrupt == 0 )
-		sti();
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	return err;
 
@@ -2615,13 +2661,14 @@
 {
 	u16	sio;
 	int	minten;
+	unsigned long flags;
+	TLanPrivateInfo *priv; 
 
 	outw(TLAN_NET_SIO, dev->base_addr + TLAN_DIO_ADR);
 	sio = dev->base_addr + TLAN_DIO_DATA + TLAN_NET_SIO;
-
-	if ( dev->interrupt == 0 )
-		cli();
-	dev->interrupt++;
+	
+	priv = (TLanPrivateInfo *) dev->priv;
+	spin_lock_irqsave(&priv->lock, flags);
 
 	TLan_MiiSync( dev->base_addr );
 
@@ -2643,9 +2690,7 @@
 	if ( minten )
 		TLan_SetBit( TLAN_NET_SIO_MINTEN, sio );
 
-	dev->interrupt--;
-	if ( dev->interrupt == 0 )
-		sti();
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 } /* TLan_MiiWriteReg */
 
@@ -2843,29 +2888,38 @@
 int TLan_EeReadByte( struct device *dev, u8 ee_addr, u8 *data )
 {
 	int err;
+	TLanPrivateInfo *priv;
+	unsigned long flags = 0;
+	int ret = 0;
 
-	if ( dev->interrupt == 0 )
-		cli();
-	dev->interrupt++;
-
+	priv = (TLanPrivateInfo *) dev->priv;
+	spin_lock_irqsave(&priv->lock, flags);
+	
 	TLan_EeSendStart( dev->base_addr );
 	err = TLan_EeSendByte( dev->base_addr, 0xA0, TLAN_EEPROM_ACK );
 	if (err)
-		return 1;
+	{
+		ret=1;
+		goto fail;
+	}
 	err = TLan_EeSendByte( dev->base_addr, ee_addr, TLAN_EEPROM_ACK );
 	if (err)
-		return 2;
+	{
+		ret=2;
+		goto fail;
+	}
 	TLan_EeSendStart( dev->base_addr );
 	err = TLan_EeSendByte( dev->base_addr, 0xA1, TLAN_EEPROM_ACK );
 	if (err)
-		return 3;
+	{
+		ret=3;
+		goto fail;
+	}
 	TLan_EeReceiveByte( dev->base_addr, data, TLAN_EEPROM_STOP );
 
-	dev->interrupt--;
-	if ( dev->interrupt == 0 )
-		sti();
-
-	return 0;
+fail:
+	spin_unlock_irqrestore(&priv->lock, flags);
+	return ret;
 
 } /* TLan_EeReadByte */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/net/tlan.h linux.17p18/drivers/net/tlan.h
--- linux.vanilla/drivers/net/tlan.h	Fri Apr 21 23:17:27 2000
+++ linux.17p18/drivers/net/tlan.h	Wed Aug  9 22:44:44 2000
@@ -1,5 +1,6 @@
 #ifndef TLAN_H
 #define TLAN_H
+
 /********************************************************************
  *
  *  Linux ThunderLAN Driver
@@ -24,11 +25,6 @@
 #include <asm/types.h>
 #include <linux/netdevice.h>
 
-#if LINUX_VERSION_CODE <= 0x20100
-#define net_device_stats	enet_statistics
-#endif
-
-
 
 
 	/*****************************************************************
@@ -190,6 +186,7 @@
 	u8			tlanRev;
 	u8			tlanFullDuplex;
 	char                    devName[8];
+	spinlock_t		lock;
 } TLanPrivateInfo;
 
 
@@ -541,4 +538,5 @@
 } 
 
 #endif /* I_LIKE_A_FAST_HASH_FUNCTION */
+
 #endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/pci/oldproc.c linux.17p18/drivers/pci/oldproc.c
--- linux.vanilla/drivers/pci/oldproc.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/pci/oldproc.c	Wed Aug  9 22:31:08 2000
@@ -105,6 +105,7 @@
 	DEVICE( DEC,		DEC_21153,	"DC21153"),
 	DEVICE( DEC,		DEC_21154,	"DC21154"),
 	DEVICE( DEC,		DEC_21285,	"DC21285 Footbridge"),
+	DEVICE( DEC,		DEC_21554,	"DC21554 DrawBridge"),
 	DEVICE( CIRRUS,		CIRRUS_7548,	"GD 7548"),
 	DEVICE( CIRRUS,		CIRRUS_5430,	"GD 5430"),
 	DEVICE( CIRRUS,		CIRRUS_5434_4,	"GD 5434"),
@@ -224,9 +225,11 @@
 	DEVICE( X,		X_AGX016,	"ITT AGX016"),
 	DEVICE( PICOP,		PICOP_PT86C52X,	"PT86C52x Vesuvius"),
 	DEVICE( PICOP,		PICOP_PT80C524,	"PT80C524 Nile"),
-	DEVICE( MYLEX,		MYLEX_DAC960P_V2,"DAC960P V2"),
-	DEVICE( MYLEX,		MYLEX_DAC960P_V3,"DAC960P V3"),
-	DEVICE( MYLEX,		MYLEX_DAC960P_V4,"DAC960P V4"),
+	DEVICE( MYLEX,		MYLEX_DAC960_P, "DAC960 P Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_PD,"DAC960 PD Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_PG,"DAC960 PG Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_LP,"DAC960 LP Series"),
+	DEVICE( MYLEX,		MYLEX_DAC960_BA,"DAC960 BA Series"),
 	DEVICE( APPLE,		APPLE_BANDIT,	"Bandit"),
 	DEVICE( APPLE,		APPLE_GC,	"Grand Central"),
 	DEVICE( APPLE,		APPLE_HYDRA,	"Hydra"),
@@ -458,6 +461,10 @@
 	DEVICE( CYCLADES,	CYCLOM_8Y_Hi,	"Cyclom-8Y above 1Mbyte"),
 	DEVICE( CYCLADES,	CYCLOM_Z_Lo,	"Cyclades-Z below 1Mbyte"),
 	DEVICE( CYCLADES,	CYCLOM_Z_Hi,	"Cyclades-Z above 1Mbyte"),
+	DEVICE( CYCLADES,	PC300_RX_2,	"PC300/RSV or /X21 (2 ports)"),
+	DEVICE( CYCLADES,	PC300_RX_1,	"PC300/RSV or /X21 (1 port)"),
+	DEVICE( CYCLADES,	PC300_TE_2,	"PC300/TE (2 ports)"),
+	DEVICE( CYCLADES,	PC300_TE_1,	"PC300/TE (1 port)"),
 	DEVICE( ESSENTIAL,	ESSENTIAL_ROADRUNNER,"Roadrunner serial HIPPI"),
 	DEVICE( O2,		O2_6832,	"6832"),
 	DEVICE( 3DFX,		3DFX_VOODOO,	"Voodoo"),
@@ -523,6 +530,7 @@
 	DEVICE( INTEL,		INTEL_82430,	"82430ZX Aries"),
 	DEVICE( INTEL,		INTEL_82434,	"82434LX Mercury/Neptune"),
 	DEVICE( INTEL,		INTEL_I960,	"i960"),
+	DEVICE( INTEL,		INTEL_I960RN,	"i960 RN"),
 	DEVICE( INTEL,		INTEL_82559ER,	"82559ER"),
 	DEVICE( INTEL,		INTEL_82092AA_0,"82092AA PCMCIA bridge"),
 	DEVICE( INTEL,		INTEL_82092AA_1,"82092AA EIDE"),
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/pnp/parport_probe.c linux.17p18/drivers/pnp/parport_probe.c
--- linux.vanilla/drivers/pnp/parport_probe.c	Fri Apr 21 12:46:24 2000
+++ linux.17p18/drivers/pnp/parport_probe.c	Tue Aug  1 07:59:48 2000
@@ -7,6 +7,7 @@
 
 #include <linux/tasks.h>
 #include <linux/parport.h>
+#include <linux/parport_pc.h>
 #include <linux/delay.h>
 #include <linux/errno.h>
 #include <linux/interrupt.h>
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/Config.in linux.17p18/drivers/s390/Config.in
--- linux.vanilla/drivers/s390/Config.in	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/Config.in	Tue Aug  1 07:59:49 2000
@@ -15,6 +15,7 @@
 if [ "$CONFIG_MD_LINEAR" = "y" -o "$CONFIG_MD_STRIPED" = "y" ]; then
   bool '      Boot support (linear, striped)' CONFIG_MD_BOOT
 fi
+
 tristate 'RAM disk support' CONFIG_BLK_DEV_RAM
 if [ "$CONFIG_BLK_DEV_RAM" = "y" -o "$CONFIG_BLK_DEV_RAM" = "m" ]; then
   int '   Default RAM disk size' CONFIG_BLK_DEV_RAM_SIZE 8192
@@ -50,7 +51,6 @@
   comment 'S/390 Network device support'
   bool 'Network device support' CONFIG_NETDEVICES
   if [ "$CONFIG_NETDEVICES" = "y" ]; then
-    menu_option next_comment
     comment 'S390 Network devices'
     bool 'CTC device support' CONFIG_CTC
     bool 'IUCV device support (VM only)' CONFIG_IUCV
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/Makefile linux.17p18/drivers/s390/Makefile
--- linux.vanilla/drivers/s390/Makefile	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/Makefile	Tue Aug  1 07:59:49 2000
@@ -11,7 +11,7 @@
 
 CFLAGS += 
 O_TARGET := io.o
-O_OBJS    :=         
+O_OBJS   := ccwcache.o
 M_OBJS   :=
 
 SUBDIRS := $(SUBDIRS) arch/s390/drivers/block arch/s390/drivers/char \
@@ -21,7 +21,8 @@
 O_OBJS := block/s390-block.o \
   char/s390-char.o \
   misc/s390-misc.o \
-  net/s390-net.o 
+  net/s390-net.o \
+  ccwcache.o
 
 io.o: $(O_OBJS)
 
@@ -36,5 +37,6 @@
 
 net/s390-net.o: dummy
 	$(MAKE) -C net
+
 
 include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/Makefile linux.17p18/drivers/s390/block/Makefile
--- linux.vanilla/drivers/s390/block/Makefile	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/Makefile	Tue Aug  1 07:59:48 2000
@@ -7,18 +7,15 @@
 D_OBJS   :=
 
 ifeq ($(CONFIG_DASD),y)
-  O_OBJS += dasd.o dasd_ccwstuff.o dasd_erp.o dasd_setup.o
-  ifeq ($(CONFIG_PROC_FS),y)
-   O_OBJS += dasd_proc.o dasd_profile.o
-  endif 
+  O_OBJS += dasd.o
   ifeq ($(CONFIG_DASD_ECKD),y)
-   O_OBJS += dasd_eckd.o dasd_eckd_erp.o dasd_3990_erp.o dasd_9343_erp.o
+   O_OBJS += dasd_eckd.o  dasd_3990_erp.o dasd_9343_erp.o
   endif 
   ifeq ($(CONFIG_DASD_FBA),y)
-   O_OBJS += dasd_fba.o
+   O_OBJS += dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
   endif 
   ifeq ($(CONFIG_DASD_MDSK),y)
-   O_OBJS += dasd_mdsk.o
+   O_OBJS += dasd_diag.o
   endif 
 #  ifeq ($(CONFIG_DASD_CKD),y)
 #   O_OBJS += dasd_ckd.o
@@ -27,21 +24,18 @@
 
 ifeq ($(CONFIG_DASD),m)
   M_OBJS += dasd_mod.o
-  D_OBJS += dasd.o dasd_ccwstuff.o dasd_erp.o dasd_setup.o
-  ifeq ($(CONFIG_PROC_FS),y)
-   D_OBJS += dasd_proc.o dasd_profile.o
-  endif 
+  D_OBJS += dasd.o 
   ifeq ($(CONFIG_DASD_ECKD),y)
-   D_OBJS += dasd_eckd.o dasd_eckd_erp.o dasd_3990_erp.o dasd_9343_erp.o
+   D_OBJS += dasd_eckd.o  dasd_3990_erp.o dasd_9343_erp.o
   endif 
   ifeq ($(CONFIG_DASD_FBA),y)
-   D_OBJS += dasd_fba.o
+   D_OBJS += dasd_fba.o dasd_3370_erp.o dasd_9336_erp.o
   endif 
   ifeq ($(CONFIG_DASD_MDSK),y)
-   D_OBJS += dasd_mdsk.o
+   D_OBJS += dasd_diag.o
   endif 
 #  ifeq ($(CONFIG_DASD_CKD),y)
-#   D_OBJS += dasd_ckd.o
+#   O_OBJS += dasd_ckd.o
 #  endif 
 endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd.c linux.17p18/drivers/s390/block/dasd.c
--- linux.vanilla/drivers/s390/block/dasd.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd.c	Tue Aug  1 07:59:48 2000
@@ -3,11 +3,30 @@
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+
+ * History of changes (starts July 2000)
+ * 07/03/00 Adapted code to compile with 2.2 and 2.4 kernels
+ * 07/05/00 Added some missing cases when shutting down a device
+ * 07/07/00 Fixed memory leak in ccw allocation
+            Adapted request function to make it work on 2.4
+ * 07/10/00 Added some code to the request function to dequeue requests
+            that cannot be handled due to errors
+ * 07/10/00 Moved linux/ccwcache.h to asm/
+ * 07/10/00 Fixed a bug when formatting a 'new' device       
+ * 07/10/00 Removed an annoying message from dasd_format 
+ * 07/11/00 Reanimated probeonly mode    
+ * 07/11/00 Reanimated autodetection mode
+ * 07/12/00 fixed a bug in module cleanup
+ * 07/12/00 fixed a bug in dasd_devices_open when having 'unknown' devices
+ * 07/13/00 fixed error message when having no device
+ * 07/13/00 added code for dynamic device recognition
  */
 
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/blkdev.h>
 #include <linux/stddef.h>
 #include <linux/kernel.h>
-
 #include <linux/tqueue.h>
 #include <linux/timer.h>
 #include <linux/malloc.h>
@@ -15,1330 +34,1653 @@
 #include <linux/hdreg.h>
 #include <linux/interrupt.h>
 #include <linux/ctype.h>
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
+#include <linux/blk.h>
+#include <asm/debug.h>
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+#include <linux/devfs_fs_kernel.h>
+#endif /* LINUX_IS_24 */
+
+#ifdef CONFIG_PROC_FS
+#include <linux/proc_fs.h>
+#endif				/* CONFIG_PROC_FS */
+
+#include <asm/atomic.h>
+#include <asm/delay.h>
 #include <asm/io.h>
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
 #include <asm/spinlock.h>
+#endif /* LINUX_IS_24 */
 #include <asm/semaphore.h>
 #include <asm/ebcdic.h>
 #include <asm/uaccess.h>
-
 #include <asm/irq.h>
 #include <asm/s390_ext.h>
+#include <asm/s390dyn.h>
 
-#include <linux/dasd.h>
-#include <linux/blk.h>
-
-#include "dasd_erp.h"
-#include "dasd_types.h"
-#include "dasd_ccwstuff.h"
-
-#include "../../../arch/s390/kernel/debug.h"
-
-#define PRINTK_HEADER DASD_NAME":"
-
-#define DASD_SSCH_RETRIES 2
+#include "dasd.h"
+#ifdef CONFIG_DASD_ECKD
+#include "dasd_eckd.h"
+#endif				/*  CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_FBA
+#include "dasd_fba.h" 
+#endif				/*  CONFIG_DASD_FBA */
+#ifdef CONFIG_DASD_MDSK
+#include "dasd_diag.h" 
+#endif				/*  CONFIG_DASD_MDSK */
 
-/* This macro is a little tricky, but makes the code more easy to read... */
-#define MATCH(info,ct,cm,dt,dm) ( \
-(( info -> sid_data.cu_type  ct ) && ( info -> sid_data.cu_model cm )) && \
-(( info -> sid_data.dev_type dt ) && ( info -> sid_data.dev_model dm )) )
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static struct block_device_operations dasd_device_operations;
+#endif /* VERSION_CODE */
 
 #ifdef MODULE
+#define EXPORT_SYMTAB
 #include <linux/module.h>
 
-char *dasd[DASD_MAX_DEVICES] =
-{NULL,};
-#ifdef CONFIG_DASD_MDSK
-char *dasd_force_mdsk[DASD_MAX_DEVICES] =
-{NULL,};
-#endif
-
-kdev_t ROOT_DEV;
-
 EXPORT_NO_SYMBOLS;
 MODULE_AUTHOR ("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
 MODULE_DESCRIPTION ("Linux on S/390 DASD device driver, Copyright 2000 IBM Corporation");
-MODULE_PARM (dasd, "1-" __MODULE_STRING (DASD_MAX_DEVICES) "s");
-#ifdef CONFIG_DASD_MDSK
-MODULE_PARM (dasd_force_mdsk, "1-" __MODULE_STRING (DASD_MAX_DEVICES) "s");
-#endif
-#endif
+MODULE_SUPPORTED_DEVICE("dasd");
+MODULE_PARM (dasd, "1-" __MODULE_STRING (256)"s");
+EXPORT_SYMBOL (dasd_discipline_enq);
+EXPORT_SYMBOL (dasd_discipline_deq);
+EXPORT_SYMBOL (dasd_start_IO);
+EXPORT_SYMBOL (dasd_int_handler);
+EXPORT_SYMBOL (dasd_alloc_request);
+EXPORT_SYMBOL (dasd_free_request);
 
-/* Prototypes for the functions called from external */
-void dasd_partn_detect (int di);
-int devindex_from_devno (int devno);
-int dasd_is_accessible (int devno);
-void dasd_add_devno_to_ranges (int devno);
+#else
+#endif				/* MODULE */
 
-#ifdef CONFIG_DASD_MDSK
-extern int dasd_force_mdsk_flag[DASD_MAX_DEVICES];
-extern void do_dasd_mdsk_interrupt (struct pt_regs *regs, __u16 code);
-extern int dasd_parse_module_params (void);
-extern void (**ext_mdisk_int) (void);
+/* SECTION: Constant definitions to be used within this file */
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
 #endif
+#define PRINTK_HEADER DASD_NAME":"
 
-void dasd_debug (unsigned long tag);
-void dasd_profile_add (cqr_t *cqr);
-void dasd_proc_init (void);
-
-static int dasd_format (int dev, format_data_t * fdata);
-
-static struct file_operations dasd_device_operations;
-
-spinlock_t dasd_lock;		/* general purpose lock for the dasd driver */
-
-/* All asynchronous I/O should waint on this wait_queue */
-struct wait_queue *dasd_waitq = NULL;
-
-extern dasd_chanq_t *cq_head;
-extern int dasd_probeonly;
-
-debug_info_t *dasd_debug_info;
+#define DASD_QUEUE_LIMIT 10
+#define DASD_SSCH_RETRIES 5
+#define QUEUE_SECTORS 128
+
+/* SECTION: prototypes for static functions of dasd.c (try to eliminate!) */
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static void do_dasd_request (request_queue_t *);
+#else
+static void do_dasd_request (void);
+#endif /* LINUX_IS_24 */
+static void dasd_do_chanq (void);
+static void schedule_request_fn (void (*func) (void));
+static int dasd_set_device_level (unsigned int, int, dasd_discipline_t *, int);
+static int dasd_oper_handler ( int irq, devreg_t *devreg );
+
+/* SECTION: managing setup of dasd_driver */
+typedef struct dasd_range_t {
+	unsigned int from;
+	unsigned int to;
+	char discipline[4];
+        struct dasd_range_t *next;
+} __attribute__ ((packed)) dasd_range_t;
+
+typedef struct dasd_devreg_t {
+        devreg_t devreg;
+        struct dasd_devreg_t *next;
+} dasd_devreg_t;
+
+static int dasd_probeonly = 1;
+static int dasd_autodetect = 1;
+ 
+static dasd_range_t *dasd_range_head = NULL;
+static dasd_devreg_t *dasd_devreg_head = NULL;
+
+static dasd_devreg_t *
+dasd_create_devreg ( int devno ) {
+        dasd_devreg_t *r = kmalloc ( sizeof(dasd_devreg_t), GFP_KERNEL);
+        memset (r,0,sizeof(dasd_devreg_t));
+        if ( r != NULL ) {
+                r -> devreg.ci.devno = devno;
+                r -> devreg.flag = DEVREG_TYPE_DEVNO;
+                r -> devreg.oper_func = dasd_oper_handler;
+        }
+        return r;
+}
 
-extern dasd_information_t **dasd_information;
+static void
+dasd_add_range (int from, int to)
+{
+        dasd_range_t *temp,*range;
+        int i;
 
-dasd_information_t *dasd_info[DASD_MAX_DEVICES] =
-{NULL,};
-static struct hd_struct dd_hdstruct[DASD_MAX_DEVICES << PARTN_BITS];
-static int dasd_blks[256] =
-{0,};
-static int dasd_secsize[256] =
-{0,};
-static int dasd_blksize[256] =
-{0,};
-static int dasd_maxsecs[256] =
-{0,};
+        range = (dasd_range_t *)kmalloc(sizeof(dasd_range_t),GFP_KERNEL);
+        if ( range == NULL )
+                return;
+        memset(range,0,sizeof(dasd_range_t));
+        range -> from = from;
+        if (to == 0) { /* single devno ? */
+                range -> to = from;
+        }  else {
+                range -> to = to;
+        }
 
-void
-dasd_geninit (struct gendisk *dd)
-{
+        /* chain current range to end of list */
+        if ( dasd_range_head == NULL ) {
+                dasd_range_head = range;
+        } else {
+                for ( temp = dasd_range_head; 
+                      temp && temp->next; 
+                      temp = temp->next );
+                temp->next = range;
+        }
+        /* allocate and chain devreg infos for the devnos... */
+        for ( i = range->from; i <= range->to; i ++ ){
+                dasd_devreg_t *reg = dasd_create_devreg(i);
+                s390_device_register(&reg->devreg);
+                reg->next = dasd_devreg_head;
+                dasd_devreg_head = reg;
+        }
 }
 
-struct gendisk dd_gendisk =
+static int
+dasd_strtoul (char *str, char **stra)
 {
-	major:MAJOR_NR,		/* Major number */
-	major_name:"dasd",	/* Major name */
-	minor_shift:PARTN_BITS,	/* Bits to shift to get real from partn */
-	max_p:1 << PARTN_BITS,	/* Number of partitions per real */
-	max_nr:0,		/* number */
-	init:dasd_geninit,
-	part:dd_hdstruct,	/* hd struct */
-	sizes:dasd_blks,	/* sizes in blocks */
-	nr_real:0,
-	real_devices:NULL,	/* internal */
-	next:NULL		/* next */
-};
+	char *temp = str;
+	int val;
+	if (*temp == '0') {
+		temp++;		/* strip leading zero */
+		if (*temp == 'x')
+			temp++;	/* strip leading x */
+	}
+	val = simple_strtoul (temp, &temp, 16);		/* interpret anything as hex */
+	*stra = temp;
+	return val;
+}
 
-static atomic_t bh_scheduled = ATOMIC_INIT (0);
+char *dasd[256] = {NULL,}; /* maximum of 256 ranges supplied on parmline */
 
-void
-dasd_schedule_bh (void (*func) (void))
+#ifndef MODULE
+static void 
+dasd_split_parm_string ( char * str ) 
 {
-	static struct tq_struct dasd_tq =
-	{0,};
-	/* Protect against rescheduling, when already running */
-	if (atomic_compare_and_swap (0, 1, &bh_scheduled))
-		return;
-	dasd_tq.routine = (void *) (void *) func;
-	queue_task (&dasd_tq, &tq_immediate);
-	mark_bh (IMMEDIATE_BH);
-		return;
+        char *tmp=str;
+        int count = 0;
+        do {
+                char * end;
+                int len;
+                end = strchr(tmp,',');
+                if ( end == NULL ) { 
+                        len = strlen(tmp) + 1;
+                } else {
+                        len = (long) end - (long) tmp + 1;
+                        *end = '\0';
+                        end ++;
+                }
+                dasd[count] = kmalloc(len * sizeof(char),GFP_ATOMIC);
+                if ( dasd == NULL ) {
+                        printk (KERN_WARNING PRINTK_HEADER
+                                "No memory to store dasd= parameter no %d\n",count+1);
+                        break;
+                }
+                memset( dasd[count], 0, len * sizeof(char));
+                memcpy( dasd[count], tmp, len * sizeof(char));
+                count ++;
+                tmp = end;
+        } while ( tmp != NULL && *tmp != '\0' );
 	}
 
-void
-sleep_done (struct semaphore *sem)
+static char dasd_parm_string[1024] = {0,};
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static int
+dasd_setup (char *str) 
 {
-	if (sem != NULL) {
-		up (sem);
+        static int first_time = 1;
+        if ( ! first_time ) {
+                *(dasd_parm_string+strlen(dasd_parm_string))=',';
+        }  else {
+                first_time = 0;
 	}
+        memcpy(dasd_parm_string+strlen(dasd_parm_string),str,strlen(str)+1);
+        return 1;
 }
-
+#else
 void
-sleep (int timeout)
+dasd_setup (char *str, int *ints) 
 {
-	struct semaphore sem = MUTEX_LOCKED;
-	struct timer_list timer;
-
-	init_timer (&timer);
-	timer.data = (unsigned long) &sem;
-	timer.expires = jiffies + timeout;
-	timer.function = (void (*)(unsigned long)) sleep_done;
-	printk (KERN_DEBUG PRINTK_HEADER
-		"Sleeping for timer tics %d\n", timeout);
-	add_timer (&timer);
-	down (&sem);
-	del_timer (&timer);
+        static int first_time = 1;
+        if ( ! first_time ) {
+                *(dasd_parm_string+strlen(dasd_parm_string))=',';
+        }  else {
+                first_time = 0;
+        }
+        memcpy(dasd_parm_string+strlen(dasd_parm_string),str,strlen(str)+1);
 }
+#endif /* LINUX_IS_24 */
 
-#ifdef CONFIG_DASD_ECKD
-extern dasd_operations_t dasd_eckd_operations;
-#endif				/* CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_FBA
-extern dasd_operations_t dasd_fba_operations;
-#endif				/* CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_MDSK
-extern dasd_operations_t dasd_mdsk_operations;
-#endif				/* CONFIG_DASD_MDSK */
 
-dasd_operations_t *dasd_disciplines[] =
-{
-#ifdef CONFIG_DASD_ECKD
-	&dasd_eckd_operations,
-#endif				/* CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_FBA
-	&dasd_fba_operations,
-#endif				/* CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_MDSK
-	&dasd_mdsk_operations,
-#endif				/* CONFIG_DASD_MDSK */
-#ifdef CONFIG_DASD_CKD
-	&dasd_ckd_operations,
-#endif				/* CONFIG_DASD_CKD */
-	NULL
-};
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+__setup("dasd=", dasd_setup);
+#endif /* LINUX_IS_24 */
 
-char *dasd_name[] =
-{
-#ifdef CONFIG_DASD_ECKD
-	"ECKD",
-#endif				/* CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_FBA
-	"FBA",
-#endif				/* CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_MDSK
-	"MDSK",
-#endif				/* CONFIG_DASD_MDSK */
-#ifdef CONFIG_DASD_CKD
-	"CKD",
-#endif				/* CONFIG_DASD_CKD */
-	"END"
-};
+#endif
 
-static int
-do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data)
+void
+dasd_parse (char **str) 
 {
-	int rc;
-	int di;
-	dasd_information_t *dev;
+	char *temp;
+	int from, to;
 
-	di = DEVICE_NR (inp->i_rdev);
-	if (!dasd_info[di]) {
-		PRINT_WARN ("No device registered as %d\n", inp->i_rdev);
-		return -EINVAL;
-	}
-	if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) {
-		PRINT_DEBUG ("empty data ptr");
-		return -EINVAL;
-	}
-	dev = dasd_info[di];
-	if (!dev) {
-		PRINT_WARN ("No device registered as %d\n", inp->i_rdev);
-		return -EINVAL;
+      	if ( *str ) { 
+        dasd_probeonly = 0;
 	}
-	PRINT_INFO ("ioctl 0x%08x %s'0x%x'%d(%d) on dev %d/%d (%d) with data %8lx\n", no,
-		    _IOC_DIR (no) == _IOC_NONE ? "0" :
-		    _IOC_DIR (no) == _IOC_READ ? "r" :
-		    _IOC_DIR (no) == _IOC_WRITE ? "w" :
-		    _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
-		    _IOC_TYPE (no), _IOC_NR (no), _IOC_SIZE (no),
-		    MAJOR (inp->i_rdev), MINOR (inp->i_rdev), di, data);
-
-	switch (no) {
-	case BLKGETSIZE:{	/* Return device size */
-			int blocks = dasd_blks[MINOR (inp->i_rdev)] << 1;
-			rc = copy_to_user ((long *) data,
-					   &blocks,
-					   sizeof (long));
+        while (*str) {
+                temp = *str;
+		from = 0;
+		to = 0;
+                if ( strncmp ( *str,"autodetect",strlen("autodetect"))== 0) {
+                        dasd_autodetect = 1;
+                        printk (KERN_INFO "turning to autodetection mode\n");
+                        break;
+                } else if ( strncmp ( *str,"probeonly",strlen("probeonly"))== 0) {
+                        dasd_probeonly = 1;
+                        printk (KERN_INFO "turning to probeonly mode\n");
 			break;
+                } else {
+                        dasd_autodetect = 0;
+                        from = dasd_strtoul (temp, &temp);          
+                        if (*temp == '-') {
+                                temp++;
+                                to = dasd_strtoul (temp, &temp);
 		}
-	case BLKFLSBUF:{
-			rc = fsync_dev (inp->i_rdev);
-			break;
+                        dasd_add_range (from, to);
 		}
-	case BLKRAGET:{
-			rc = copy_to_user ((long *) data,
-					read_ahead + MAJOR_NR, sizeof (long));
-			break;
+                str ++;
 		}
-	case BLKRASET:{
-			rc = copy_from_user (read_ahead + MAJOR_NR,
-					     (long *) data, sizeof (long));
-			break;
 		}
-	case BLKRRPART:{
-			dasd_partn_detect (di);
-			rc = 0;
+
+int
+devindex_from_devno (int devno)
+{
+	int devindex = 0;
+        dasd_range_t *temp;
+        for ( temp = dasd_range_head; temp; temp = temp->next ) {
+		if (devno < temp -> from || devno > temp -> to) {
+			devindex += temp -> to - temp -> from + 1;
+		} else {
+			devindex += devno - temp -> from;
 			break;
 		}
-	case BIODASDRLB:{
-			rc = copy_to_user ((int *) data,
-					   &dasd_info[di]->sizes.label_block,
-					   sizeof (int));
-			break;
 		}
-	case BLKGETBSZ:{
-			rc = copy_to_user ((int *) data,
-					   &dasd_info[di]->sizes.bp_block,
-					   sizeof (int));
-			break;
+        if ( temp == NULL ) 
+                return -ENODEV;
+	return devindex;
 		}
-	case HDIO_GETGEO:{
-			struct hd_geometry geo;
-			dasd_disciplines[dev->type]->fill_geometry (di, &geo);
-			rc = copy_to_user ((struct hd_geometry *) data, &geo,
-					   sizeof (struct hd_geometry));
-			break;
+
+/* SECTION: ALl needed for multiple major numbers */
+
+static major_info_t dasd_major_info[] =
+{
+	{
+		next:NULL /* &dasd_major_info[1] */ ,
+		request_fn:do_dasd_request,
+		read_ahead:8,
+		gendisk:
+		{
+			major:94,
+			major_name:DASD_NAME,
+			minor_shift:DASD_PARTN_BITS,
+			max_p:1 << DASD_PARTN_BITS,
+#if ! (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+			max_nr:DASD_PER_MAJOR,
+#endif /* LINUX_IS_24 */
+			nr_real:DASD_PER_MAJOR,
 		}
-		RO_IOCTLS (inp->i_rdev, data);
-	case BIODASDRSID:{
-			rc = copy_to_user ((void *) data,
-					   &(dev->info.sid_data),
-					   sizeof (senseid_t));
-			break;
 		}
-	case BIODASDRWTB:{
-			int offset = 0;
-			int xlt;
-			rc = copy_from_user (&xlt, (void *) data,
-					     sizeof (int));
-#if 0
-                        PRINT_INFO("Xlating %d to",xlt);
-#endif
-			if (rc)
-				break;
-			offset = dd_gendisk.part[MINOR (inp->i_rdev)].start_sect >>
-			    dev->sizes.s2b_shift;
-			xlt += offset;
 #if 0
-                        printk(" %d \n",xlt);
-#endif
-			rc = copy_to_user ((void *) data, &xlt,
-					   sizeof (int));
-			break;
-		}
-	case BIODASDFORMAT:{
-			/* fdata == NULL is a valid arg to dasd_format ! */
-			format_data_t *fdata = NULL;
-			PRINT_WARN ("called format ioctl\n");
-			if (data) {
-				fdata = kmalloc (sizeof (format_data_t),
-						 GFP_ATOMIC);
-				if (!fdata) {
-					rc = -ENOMEM;
-					break;
-				}
-				rc = copy_from_user (fdata, (void *) data,
-						     sizeof (format_data_t));
-				if (rc)
-					break;
-			}
-			rc = dasd_format (inp->i_rdev, fdata);
-			if (fdata) {
-				kfree (fdata);
+        ,
+	{
+		next:NULL,
+		request_fn:do_dasd_request,
+		read_ahead:8,
+		gendisk:
+		{
+			major:95,
+			major_name:DASD_NAME,
+			minor_shift:DASD_PARTN_BITS,
+			max_p:1 << DASD_PARTN_BITS,
+#if ! (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+			max_nr:DASD_PER_MAJOR,
+#endif /* LINUX_IS_24 */
+			nr_real:DASD_PER_MAJOR,
 			}
-			break;
 		}
-	default:
-		PRINT_WARN ("unknown ioctl number %08x %08lx\n", no, BIODASDFORMAT);
-		rc = -EINVAL;
-		break;
+#endif
+};
+
+static dasd_device_t *
+find_dasd_device (int devindex)
+{
+	major_info_t *major_info = dasd_major_info;
+	while (major_info && devindex > DASD_PER_MAJOR) {
+		devindex -= DASD_PER_MAJOR;
+		major_info = major_info->next;
 	}
-	return rc;
+	if (!major_info)
+                return NULL;
+	return major_info->dasd_device[devindex];
 }
 
-static void
-dasd_end_request (struct request *req, int uptodate)
+static major_info_t *
+major_info_from_devindex (int devindex)
 {
-	struct buffer_head *bh;
-	FUNCTION_ENTRY ("dasd_end_request");
-#if DASD_PARANOIA > 2
-	if (!req) {
-		INTERNAL_CHECK ("end_request called with zero arg%s\n", "");
-	}
-#endif				/* DASD_PARANOIA */
-	while ((bh = req->bh) != NULL) {
-		req->bh = bh->b_reqnext;
-		bh->b_reqnext = NULL;
-		bh->b_end_io (bh, uptodate);
+	major_info_t *major_info = dasd_major_info;
+	while (major_info && devindex > DASD_PER_MAJOR) {
+		devindex -= DASD_PER_MAJOR;
+		major_info = major_info->next;
 	}
-	if (!end_that_request_first (req, uptodate, DEVICE_NAME)) {
-#ifndef DEVICE_NO_RANDOM
-		add_blkdev_randomness (MAJOR (req->rq_dev));
-#endif
-		DEVICE_OFF (req->rq_dev);
-		end_that_request_last (req);
+	return major_info;
 	}
-	FUNCTION_EXIT ("dasd_end_request");
-	return;
+
+int
+major_from_devindex (int devindex)
+{
+	major_info_t *major_info = major_info_from_devindex (devindex);
+	return major_info->gendisk.major;
 }
 
-void
-dasd_wakeup (void)
+static int
+devindex_from_kdev_t (kdev_t dev)
 {
-	wake_up (&dasd_waitq);
+	int devindex = 0;
+	major_info_t *major_info = dasd_major_info;
+	while (major_info &&
+	       MAJOR (dev) != major_info->gendisk.major) {
+		devindex += (1 << (MINORBITS - DASD_PARTN_BITS));
+		major_info = major_info->next;
+	}
+	if (!major_info)
+		devindex = -ENODEV;
+        devindex += MINOR(dev) >> DASD_PARTN_BITS;
+	return devindex;
 }
 
+/* SECTION: managing dasd disciplines */
 
-int
-dasd_watch_volume (int di)
-{
-        int rc = 0;
+static dasd_discipline_t *dasd_disciplines = NULL;
+static spinlock_t discipline_lock;
 
-        return rc;
-}
+/* 
+ * void dasd_discipline_enq (dasd_discipline_t * d)
+ */
 
 void 
-dasd_watcher (void) 
+dasd_discipline_enq (dasd_discipline_t * d)
 {
-        int i = 0;
-        int rc; 
-        do {
-                for ( i = 0; i < DASD_MAX_DEVICES; i++ ) {
-                        if ( dasd_info [i] ) {
-                                rc = dasd_watch_volume ( i );
-                        }
-                }
-                interruptible_sleep_on(&dasd_waitq);
-        } while(1);
+	spin_lock (&discipline_lock);
+	d->next = dasd_disciplines;
+	dasd_disciplines = d;
+	spin_unlock (&discipline_lock);
 }
 
+/* 
+ * int dasd_discipline_deq (dasd_discipline_t * d)
+ */
+
 int
-dasd_unregister_dasd (int di)
+dasd_discipline_deq (dasd_discipline_t * d)
 {
 	int rc = 0;
-	int minor;
-	int i;
-
-	minor = di << PARTN_BITS;
-	if (!dasd_info[di]) {	/* devindex is not free */
-		INTERNAL_CHECK ("trying to free unallocated device %d\n", di);
-		return -ENODEV;
+	spin_lock (&discipline_lock);
+	if (dasd_disciplines == d) {
+		dasd_disciplines = dasd_disciplines->next;
+	} else {
+		dasd_discipline_t *b;
+		b = dasd_disciplines;
+		while (b && b->next != d)
+			b = b->next;
+		if (b != NULL) {
+			b->next = b->next->next;
+		} else {
+			rc = -ENOENT;
+		}
 	}
-	/* delete all that partition stuff */
-	for (i = 0; i < (1 << PARTN_BITS); i++) {
-		dasd_blks[minor] = 0;
-		dasd_secsize[minor + i] = 0;
-		dasd_blksize[minor + i] = 0;
-		dasd_maxsecs[minor + i] = 0;
-	}
-	/* reset DASD to unknown statuss */
-	atomic_set (&dasd_info[di]->status, DASD_INFO_STATUS_UNKNOWN);
-
-	free_irq (dasd_info[di]->info.irq, &(dasd_info[di]->dev_status));
-	if (dasd_info[di]->rdc_data)
-		kfree (dasd_info[di]->rdc_data);
-	kfree (dasd_info[di]);
-	PRINT_INFO ("%04d deleted from list of valid DASDs\n",
-		    dasd_info[di]->info.devno);
+	spin_unlock (&discipline_lock);
 	return rc;
 }
 
-/* Below you find the functions already cleaned up */
-static dasd_type_t
-check_type (dev_info_t * info)
-{
-	dasd_type_t type = dasd_none;
-	int di;
+/* SECTION: (de)queueing of requests to channel program queues */
 
-	FUNCTION_ENTRY ("check_type");
-	di = devindex_from_devno (info->devno);
+/* 
+ * void dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr)
+ */
 
-#ifdef CONFIG_DASD_MDSK
-	if (MACHINE_IS_VM && dasd_force_mdsk_flag[di] == 1) {
-		type = dasd_mdsk;
+static void
+dasd_chanq_enq (dasd_chanq_t * q, ccw_req_t * cqr)
+{
+	if (q->head != NULL) {
+		q->tail->next = cqr;
 	} else
-#endif				/* CONFIG_DASD_MDSK */
+		q->head = cqr;
+	cqr->next = NULL;
+	q->tail = cqr;
+	q->queued_requests++;
+	atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
+}
 
-#ifdef CONFIG_DASD_ECKD
-	if (MATCH (info, == 0x3990, ||1, == 0x3390, ||1) ||
-	    MATCH (info, == 0x9343, ||1, == 0x9345, ||1) ||
-	    MATCH (info, == 0x3990, ||1, == 0x3380, ||1)) {
-		type = dasd_eckd;
-	} else
-#endif				/* CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_FBA
-	if (MATCH (info, == 0x6310, ||1, == 0x9336, ||1)) {
-		type = dasd_fba;
-	} else
-#endif				/* CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_MDSK
-	if (MACHINE_IS_VM) {
-		type = dasd_mdsk;
-	} else
-#endif				/* CONFIG_DASD_MDSK */
+/* 
+ * void dasd_chanq_enq_head (dasd_chanq_t * q, ccw_req_t * cqr)
+ */
+
+static void
+dasd_chanq_enq_head (dasd_chanq_t * q, ccw_req_t * cqr)
 	{
-		type = dasd_none;
+	cqr->next = q->head;
+	q->head = cqr;
+	if (q->tail == NULL)
+		q->tail = cqr;
+	q->queued_requests++;
+	atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
 	}
 
-	FUNCTION_EXIT ("check_type");
-	return type;
-}
+/* 
+ * int dasd_chanq_deq (dasd_chanq_t * q, ccw_req_t * cqr)
+ */
 
 static int
-dasd_read_characteristics (dasd_information_t * info)
+dasd_chanq_deq (dasd_chanq_t * q, ccw_req_t * cqr)
 {
-	int rc = 0;
-	int ct = 0;
-	dev_info_t *di;
-	dasd_type_t dt;
+	ccw_req_t *prev;
 
-	FUNCTION_ENTRY ("read_characteristics");
-	if (info == NULL) {
-		return -ENODEV;
-	}
-	di = &(info->info);
-	if (di == NULL) {
-		return -ENODEV;
-	}
-	dt = check_type (di);
-	/* Some cross-checks, if the cu supports RDC */
-	if (MATCH (di, == 0x2835, ||1, ||1, ||1) ||
-	    MATCH (di, == 0x3830, ||1, ||1, ||1) ||
-	    MATCH (di, == 0x3830, ||1, ||1, ||1) ||
-	    MATCH (di, == 0x3990, <=0x03, == 0x3380, <=0x0d)) {
-		PRINT_WARN ("Device %d (%x/%x at %x/%x) supports no RDC\n",
-			    info->info.irq,
-			    di->sid_data.dev_type,
-			    di->sid_data.dev_model,
-			    di->sid_data.cu_type,
-			    di->sid_data.cu_model);
-		return -EINVAL;
+	if (cqr == NULL)
+		return -ENOENT;
+	if (cqr == (ccw_req_t *) q->head) {
+		q->head = cqr->next;
+		if (q->head == NULL)
+			q->tail = NULL;
+	} else {
+		prev = (ccw_req_t *) q->head;
+		while (prev && prev->next != cqr)
+			prev = prev->next;
+		if (prev == NULL)
+			return -ENOENT;
+		prev->next = cqr->next;
+		if (prev->next == NULL)
+			q->tail = prev;
+	}
+	cqr->next = NULL;
+	q->queued_requests--;
+	return 0;
+}
+
+/* SECTION: Handling of the queue of queues */
+
+#ifdef CONFIG_SMP
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static spinlock_t cq_lock;		/* spinlock for cq_head */
+#else
+static spinlock_t cq_lock = SPIN_LOCK_UNLOCKED;		/* spinlock for cq_head */
+#endif /* LINUX_IS_24 */
+#endif				/* __SMP__ */
+static dasd_chanq_t *qlist_head = NULL;		/* head of queue of queues */
+
+/* 
+ * void qlist_enq (dasd_chanq_t * q)
+ * queues argument to head of the queue of queues
+ * and marks queue to be active
+ */
+
+static void
+qlist_enq (dasd_chanq_t * q)
+{
+	if (q == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER " NULL queue to be queued to queue of queues\n");
+		return;
 	}
-	switch (dt) {
-#ifdef CONFIG_DASD_ECKD
-	case dasd_eckd:
-		ct = 64;
-		rc = read_dev_chars (info->info.irq,
-				     (void *) &(info->rdc_data), ct);
-		break;
-#endif				/*  CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_FBA
-	case dasd_fba:
-		ct = 32;
-		rc = read_dev_chars (info->info.irq,
-				     (void *) &(info->rdc_data), ct);
-		break;
-#endif				/*  CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_MDSK
-	case dasd_mdsk:
-		ct = 0;
-		break;
-#endif				/*  CONFIG_DASD_FBA */
-	default:
-		INTERNAL_ERROR ("don't know dasd type %d\n", dt);
-	}
-	if (rc) {
-		PRINT_WARN ("RDC resulted in rc=%d\n", rc);
-	}
-	FUNCTION_EXIT ("read_characteristics");
-	return rc;
+	spin_lock (&cq_lock);
+	if (atomic_read (&q->flags) & DASD_CHANQ_ACTIVE) {
+		printk (KERN_WARNING PRINTK_HEADER " Queue already active");
+	}
+	atomic_set_mask (DASD_CHANQ_ACTIVE, &q->flags);
+	q->next_q = qlist_head;
+	qlist_head = q;
+	spin_unlock (&cq_lock);
 }
 
-/* How many sectors must be in a request to dequeue it ? */
-#define QUEUE_BLOCKS 25
-#define QUEUE_SECTORS (QUEUE_BLOCKS << dasd_info[di]->sizes.s2b_shift)
-
-/* How often to retry an I/O before raising an error */
-#define DASD_MAX_RETRIES 5
-
-static inline
- cqr_t *
-dasd_cqr_from_req (struct request *req)
-{
-	cqr_t *cqr = NULL;
-	int di;
-	dasd_information_t *info;
-
-	if (!req) {
-		PRINT_ERR ("No request passed!");
-		return NULL;
-	}
-	di = DEVICE_NR (req->rq_dev);
-	info = dasd_info[di];
-	if (!info)
-		return NULL;
-	/* if applicable relocate block */
-	if (MINOR (req->rq_dev) & ((1 << PARTN_BITS) - 1)) {
-		req->sector +=
-		    dd_gendisk.part[MINOR (req->rq_dev)].start_sect;
-	}
-	/* Now check for consistency */
-	if (!req->nr_sectors) {
-		PRINT_WARN ("req: %p dev: %08x sector: %ld nr_sectors: %ld bh: %p\n",
-		     req, req->rq_dev, req->sector, req->nr_sectors, req->bh);
-		return NULL;
-	}
-	if (((req->sector + req->nr_sectors) >> 1) > info->sizes.kbytes) {
-		printk (KERN_ERR PRINTK_HEADER
-			"Requesting I/O past end of device %d\n",
-			di);
-		return NULL;
-	}
-	cqr = dasd_disciplines[info->type]->get_req_ccw (di, req);
-	if (!cqr) {
-		PRINT_WARN ("empty CQR generated\n");
-	} else {
-		cqr->req = req;
-		cqr->int4cqr = cqr;
-		cqr->devindex = di;
-#ifdef DASD_PROFILE
-		asm volatile ("STCK %0":"=m" (cqr->buildclk));
-#endif				/* DASD_PROFILE */
-		ACS (cqr->status, CQR_STATUS_EMPTY, CQR_STATUS_FILLED);
+/* 
+ * void qlist_deq (dasd_chanq_t * q)
+ * dequeues argument from the queue of queues
+ * and marks queue to be inactive
+ */
+
+static void
+qlist_deq (dasd_chanq_t * q)
+{
+
+	if (qlist_head == NULL) {
+		printk (KERN_ERR PRINTK_HEADER "Channel queue is empty%s\n", "");
+		return;
 	}
-	return cqr;
+	if (q == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER " NULL queue to be dequeued from queue of queues\n");
+		return;
+	}
+	spin_lock (&cq_lock);
+	if (!(atomic_read (&q->flags) & DASD_CHANQ_ACTIVE)) {
+		printk (KERN_WARNING PRINTK_HEADER " Queue not active\n");
+	} else if (qlist_head == q) {
+		qlist_head = q->next_q;
+	} else {
+		dasd_chanq_t *c = qlist_head;
+		while (c->next_q && c->next_q != q)
+			c = c->next_q;
+		if (c->next_q == NULL)
+			printk (KERN_WARNING PRINTK_HEADER " Queue %p not in queue of queues\n", q);
+		else
+			c->next_q = q->next_q;
+	}
+	atomic_clear_mask (DASD_CHANQ_ACTIVE, &q->flags);
+	q->next_q = NULL;
+	spin_unlock (&cq_lock);
 }
 
-int
-dasd_start_IO (cqr_t * cqr)
+/* SECTION: All the gendisk stuff */
+
+
+static int
+dasd_partn_detect (int devindex)
 {
 	int rc = 0;
-	int retries = DASD_SSCH_RETRIES;
-	int di, irq;
-
-	dasd_debug ((unsigned long) cqr);	/* cqr */
 
-	if (!cqr) {
-		PRINT_WARN ("(start_IO) no cqr passed\n");
-		return -EINVAL;
-	}
-#ifdef CONFIG_DASD_MDSK
-	if (cqr->magic == MDSK_MAGIC) {
-		return dasd_mdsk_start_IO (cqr);
-	}
-#endif				/* CONFIG_DASD_MDSK */
-	if (cqr->magic != DASD_MAGIC && cqr->magic != ERP_MAGIC) {
-		PRINT_ERR ("(start_IO) magic number mismatch\n");
-		return -EINVAL;
+	major_info_t *major_info = major_info_from_devindex (devindex);
+	struct gendisk *dd = &major_info->gendisk;
+	int minor = ( devindex & 
+                      (( 1 << (MINORBITS-DASD_PARTN_BITS) ) - 1)) << dd->minor_shift;
+	struct dasd_device_t *device = find_dasd_device (devindex);
+        
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        register_disk(dd,
+                      MKDEV (dd->major, minor),
+                      1 << DASD_PARTN_BITS,
+                      &dasd_device_operations,
+                      (device->sizes.blocks << device->sizes.s2b_shift));
+#else
+        dd->sizes[minor] = (device->sizes.blocks << device->sizes.s2b_shift) >> 1;
+        resetup_one_dev(dd,minor>>DASD_PARTN_BITS);
+#endif /* LINUX_IS_24 */
+	return rc;
 	}
-	ACS (cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_IN_IO);
-        di = cqr->devindex;
-	irq = dasd_info[di]->info.irq;
-	do {
-		asm volatile ("STCK %0":"=m" (cqr->startclk));
-		rc = do_IO (irq, cqr->cpaddr, (long) cqr, 0x00, cqr->options);
-		switch (rc) {
-		case 0:
-			if (!(cqr->options & DOIO_WAIT_FOR_INTERRUPT))
-                        	atomic_set_mask (DASD_CHANQ_BUSY,
-                                	         &dasd_info[di]->queue.flags);
-			break;
-		case -ENODEV:
-			PRINT_WARN ("cqr %p: 0x%04x error, %d retries left\n",
-				    cqr, dasd_info[di]->info.devno, retries);
-			break;
-		case -EIO:
-			PRINT_WARN ("cqr %p: 0x%04x I/O, %d retries left\n",
-				    cqr, dasd_info[di]->info.devno, retries);
-			break;
-		case -EBUSY:	/* set up timer, try later */
 
-			PRINT_WARN ("cqr %p: 0x%04x busy, %d retries left\n",
-				    cqr, dasd_info[di]->info.devno, retries);
-			break;
-		default:
+/* SECTION: Managing wrappers for ccwcache */
 
-			PRINT_WARN ("cqr %p: 0x%04x %d, %d retries left\n",
-				    cqr, rc, dasd_info[di]->info.devno,
-                                    retries);
-			break;
+#define DASD_EMERGENCY_REQUESTS 16
+
+static ccw_req_t *dasd_emergency_req[DASD_EMERGENCY_REQUESTS]={NULL,};
+static spinlock_t dasd_emergency_req_lock = SPIN_LOCK_UNLOCKED;
+
+static void
+dasd_init_emergency_req ( void ) 
+{
+        int i;
+        for ( i = 0; i < DASD_EMERGENCY_REQUESTS; i++) {
+          dasd_emergency_req[i] = (ccw_req_t*)get_free_page(GFP_KERNEL);
 		}
-	} while (rc && --retries);
-	if (rc) {
-		ACS (cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_ERROR);
         }
-	return rc;
+
+static void
+dasd_cleanup_emergency_req ( void ) 
+{
+        int i;
+        for ( i = 0; i < DASD_EMERGENCY_REQUESTS; i++) {
+                if (dasd_emergency_req[i])
+                        free_page((long)(dasd_emergency_req[i]));
+                else
+                        printk (KERN_WARNING PRINTK_HEADER "losing one page for 'in-use' emergency request\n");
+        }
 }
 
-static inline
-void
-dasd_end_cqr (cqr_t * cqr, int uptodate)
+ccw_req_t *
+dasd_alloc_request (char *magic, int cplength, int datasize)
 {
-	struct request *req = cqr->req;
-	asm volatile ("STCK %0":"=m" (cqr->endclk));
-#ifdef DASD_PROFILE
-	dasd_profile_add (cqr);
-#endif				/* DASD_PROFILE */
-	dasd_chanq_deq (&dasd_info[cqr->devindex]->queue, cqr);
-        if (req) {
-                dasd_end_request (req, uptodate);
+        ccw_req_t *rv = NULL;
+        int i;
+        if ( ( rv = ccw_alloc_request(magic,cplength,datasize )) != NULL ) {
+                return rv;
+        }
+        if ( cplength * sizeof(ccw1_t) + datasize + sizeof(ccw_req_t) > PAGE_SIZE ) {
+                return NULL;
+        }
+        spin_lock(&dasd_emergency_req_lock);
+        for ( i = 0; i < DASD_EMERGENCY_REQUESTS; i++) {
+                if ( dasd_emergency_req[i] != NULL ) {
+                        rv = dasd_emergency_req[i];
+                        dasd_emergency_req[i] = NULL;
+                }
         }
+        spin_unlock(&dasd_emergency_req_lock);
+        if ( rv ) {
+                memset (rv,0, PAGE_SIZE);
+                rv -> cache = (kmem_cache_t *)(dasd_emergency_req + i);
+                strncpy ( (char *)(&rv->magic), magic, 4);
+                ASCEBC((char *)(&rv->magic),4);
+                rv -> cplength = cplength;
+                rv -> datasize = datasize;
+                rv -> data = (void *)((long)rv + PAGE_SIZE - datasize);
+                rv -> cpaddr = (ccw1_t *)((long)rv +  sizeof(ccw_req_t));
+        }
+        return rv;
 }
 
 void
-dasd_dump_sense (devstat_t * stat)
+dasd_free_request (ccw_req_t * request)
 {
-	int sl, sct;
-	if (!stat->flag | DEVSTAT_FLAG_SENSE_AVAIL) {
-		PRINT_INFO ("I/O status w/o sense data\n");
+        if ( request -> cache >= (kmem_cache_t *)dasd_emergency_req &&
+             request -> cache <= (kmem_cache_t *)(dasd_emergency_req + DASD_EMERGENCY_REQUESTS) ) {
+                *((ccw_req_t **)(request -> cache)) = request;
 	} else {
-	printk (KERN_INFO PRINTK_HEADER
-			"-------------------I/O result:-----------\n");
-	for (sl = 0; sl < 4; sl++) {
-		printk (KERN_INFO PRINTK_HEADER "Sense:");
-		for (sct = 0; sct < 8; sct++) {
-			printk (" %2d:0x%02X", 8 * sl + sct,
-				stat->ii.sense.data[8 * sl + sct]);
-		}
-		printk ("\n");
+                ccw_free_request(request);
 	}
 }
+
+/* SECTION: Managing the device queues etc. */
+
+static atomic_t bh_scheduled = ATOMIC_INIT (0);
+static atomic_t request_fn_scheduled = ATOMIC_INIT (0);
+
+static void
+run_bh (void)
+{
+	atomic_set (&bh_scheduled, 0);
+	dasd_do_chanq ();
 }
 
-int
-register_dasd_last (int di)
+void
+dasd_schedule_bh ( void )
 {
-	int rc = 0;
-	int minor;
-	int i;
+	static struct tq_struct bh_tq =
+	{0,};
+	/* Protect against rescheduling, when already running */
+	if (atomic_compare_and_swap (0, 1, &bh_scheduled))
+		return;
+	bh_tq.routine = (void *) (void *) run_bh;
+	queue_task (&bh_tq, &tq_immediate);
+	mark_bh (IMMEDIATE_BH);
+	return;
+}
 
-	rc = dasd_disciplines[dasd_info[di]->type]->fill_sizes_last (di);
-	if (!rc) {
-		ACS (dasd_info[di]->status,
-		     DASD_INFO_STATUS_DETECTED, DASD_INFO_STATUS_FORMATTED);
-	} else {		/* -EMEDIUMTYPE: */
-		ACS (dasd_info[di]->status,
-		     DASD_INFO_STATUS_DETECTED, DASD_INFO_STATUS_ANALYSED);
-	}
-	PRINT_INFO ("%04X (dasd%c):%ld kB <- block: %d on sector %d B\n",
-		    dasd_info[di]->info.devno,
-		    'a' + di,
-		    dasd_info[di]->sizes.kbytes,
-		    dasd_info[di]->sizes.bp_block,
-		    dasd_info[di]->sizes.bp_sector);
-	minor = di << PARTN_BITS;
-	dasd_blks[minor] = dasd_info[di]->sizes.kbytes;
-	for (i = 0; i < (1 << PARTN_BITS); i++) {
-		dasd_secsize[minor + i] = dasd_info[di]->sizes.bp_sector;
-		dasd_blksize[minor + i] = dasd_info[di]->sizes.bp_block;
-		dasd_maxsecs[minor + i] = 252 << dasd_info[di]->sizes.s2b_shift;
+static void
+try_request_fn (void)
+{
+        long flags;
+        spin_lock_irqsave (&io_request_lock,flags);
+	atomic_set (&request_fn_scheduled, 0);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        {
+          major_info_t *mi;
+          for (mi=dasd_major_info; mi != NULL; mi = mi->next ) {
+            do_dasd_request(BLK_DEFAULT_QUEUE(mi->gendisk.major));
 	}
-	return rc;
+        }
+#else
+        do_dasd_request ();
+#endif /* LINUX_IS_24 */
+        spin_unlock_irqrestore (&io_request_lock,flags);
 }
 
-void
-dasd_partn_detect (int di)
+static void
+schedule_request_fn (void (*func) (void))
 {
-        int minor = di << PARTN_BITS;
-	while (atomic_read (&dasd_info[di]->status) !=
-	       DASD_INFO_STATUS_FORMATTED) {
-                interruptible_sleep_on(&dasd_info[di]->wait_q);
+	static struct tq_struct req_tq =
+	{0,};
+	/* Protect against rescheduling, when already running */
+	if (func != try_request_fn) {
+		panic (PRINTK_HEADER "Programming error! must call schedule_request_fn (try_request_fn)\n");
 	}
-	dd_gendisk.part[minor].nr_sects = dasd_info[di]->sizes.kbytes << 1;
-	resetup_one_dev (&dd_gendisk, di);
+	if (atomic_compare_and_swap (0, 1, &request_fn_scheduled))
+		return;
+	req_tq.routine = (void *) (void *) func;
+	queue_task (&req_tq, &tq_immediate);
+	mark_bh (IMMEDIATE_BH);
+	return;
 }
 
-void
-dasd_do_chanq (void)
+int
+dasd_start_IO (ccw_req_t * cqr)
 {
-	dasd_chanq_t *qp = NULL;
-	cqr_t *cqr, *next;
-        long flags;
-        int irq;
-        int tasks;
+	int rc = 0;
+	int retries = DASD_SSCH_RETRIES;
+	dasd_device_t *device = cqr->device;
+	int irq, devno;
+	int devindex, partn;
+	major_info_t *major_info;
+	struct request *req;
 
-	atomic_set (&bh_scheduled, 0);
-	dasd_debug (0xc4c40000);	/* DD */
-	for (qp = cq_head; qp != NULL;) {
-/* Get first request */
-		dasd_debug ((unsigned long) qp);
-		cqr = (cqr_t *) (qp->head);
-/* empty queue -> dequeue and proceed */
 		if (!cqr) {
-			dasd_chanq_t *nqp = qp->next_q;
-			cql_deq (qp);
-			qp = nqp;
-			continue;
+		printk (KERN_WARNING PRINTK_HEADER "No request passed to start_io function");
+		return -EINVAL;
 		}
-/* process all requests on that queue */
+	irq = device->devinfo.irq;
+	devno = device->devinfo.devno;
+	req = (struct request *) cqr->req;
+	devindex = devindex_from_kdev_t (req->rq_dev);
+	major_info = major_info_from_devindex (devindex);
+	partn = MINOR (req->rq_dev) & ((1 << major_info->gendisk.minor_shift) - 1);
+	if (strncmp ((char *) &cqr->magic, device->discipline->ebcname, 4)) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"0x%04X on sch %d = /dev/%s (%d:%d)"
+			" magic number of ccw_req_t 0x%08lX doesn't match"
+			" discipline 0x%08lX\n",
+			devno, irq, device->name,
+			major_from_devindex (devindex),
+			devindex << DASD_PARTN_BITS,
+			cqr->magic, *(long *) device->discipline->name);
+		return -EINVAL;
+	}
+	atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_IN_IO);
 		do {
-                        next = NULL;
-			dasd_debug ((unsigned long) cqr);	/* cqr */
-			if (cqr->magic != DASD_MAGIC &&
-			    cqr->magic != MDSK_MAGIC &&
-			    cqr->magic != ERP_MAGIC) {
-				dasd_debug (0xc4c46ff2);	/* DD?2 */
-				panic ( PRINTK_HEADER "do_cq:"
-					"magic mismatch %p -> %x\n", 
-					cqr, cqr -> magic);
-                                break;
+		asm volatile ("STCK %0":"=m" (cqr->startclk));
+		rc = do_IO (irq, cqr->cpaddr, (long) cqr, 0x00, cqr->options);
+		switch (rc) {
+		case 0:
+                        if (!(cqr->options & DOIO_WAIT_FOR_INTERRUPT)) {
+				atomic_set_mask (DASD_CHANQ_BUSY, &device->queue.flags);
 			}
-                        irq = dasd_info[cqr->devindex]->info.irq;
-                        s390irq_spin_lock_irqsave (irq, flags);
-			switch (atomic_read (&cqr->status)) {
-			case CQR_STATUS_IN_IO:
-                                dasd_debug (0xc4c4c9d6);	/* DDIO */
-                                break;
-			case CQR_STATUS_QUEUED:
-                                dasd_debug (0xc4c4e2e3);	/* DDST */
-				if (dasd_start_IO (cqr) != 0) {
-                                  PRINT_WARN("start_io failed\n");
+                        if ( cqr->expires ) {
+                                cqr->expires += cqr->startclk;
                                 }
                                 break;
-			case CQR_STATUS_ERROR:{
-                                dasd_debug (0xc4c4c5d9);	/* DDER */
-                                if ( ++ cqr->retries  < 2 ) {
-                                        atomic_set (&cqr->status,
-                                                    CQR_STATUS_QUEUED);
-                                        dasd_debug (0xc4c4e2e3);
-                                        if (dasd_start_IO (cqr) == 0) {
-                                                atomic_dec (&qp->
-                                                            dirty_requests);
-                                                break;
-                                        }
-                                }
-                                ACS (cqr->status,
-                                     CQR_STATUS_ERROR,
-                                     CQR_STATUS_FAILED);
+		case -ENODEV:
+			printk (KERN_WARNING PRINTK_HEADER
+			    " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+				" appears not to be present %d retries left\n",
+				devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS,
+				retries);
                                 break;
-                        }
-			case CQR_STATUS_ERP_PEND:{
-					/* This case is entered, when an interrupt
-					   ended with a condittion */
-					dasd_erp_action_t erp_action;
-					erp_t *erp = NULL;
-
-                                        if ( cqr -> magic != ERP_MAGIC ) {
-                                                erp = request_er ();
-                                                if (erp == NULL) {
-                                                        PRINT_WARN ("No memory for ERP%s\n", "");
-                                                        break;
-                                                }
-                                                memset (erp, 0, sizeof (erp_t));
-                                                erp->cqr.magic = ERP_MAGIC;
-                                                erp->cqr.int4cqr = cqr;
-                                                erp->cqr.devindex= cqr->devindex;
-                                                erp_action = dasd_erp_action (cqr);
-                                                if (erp_action) {
-                                                        PRINT_WARN ("Taking ERP action %p\n", erp_action);
-                                                        erp_action (erp);
-                                                }
-                                                dasd_chanq_enq_head(qp, (cqr_t *) erp);
-                                                next = (cqr_t *) erp;
-                                } else {
-                                                PRINT_WARN("ERP_ACTION failed\n");
-                                                ACS (cqr->status,
-                                                     CQR_STATUS_ERP_PEND,
-                                                    CQR_STATUS_FAILED);
-                                }
+		case -EIO:
+			printk (KERN_WARNING PRINTK_HEADER
+			    " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+				" I/O error %d retries left\n",
+				devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS,
+				retries);
                                 break;
-                        }
-			case CQR_STATUS_ERP_ACTIVE:
+		case -EBUSY:	/* set up timer, try later */
+			printk (KERN_WARNING PRINTK_HEADER
+			    " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+				" is busy %d retries left\n",
+				devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS,
+				retries);
 				break;
-			case CQR_STATUS_DONE:{
-                                next = cqr->next;
-                                if (cqr->magic == DASD_MAGIC) {
-                                        dasd_debug (0xc4c49692);
-                                } else if (cqr->magic == ERP_MAGIC) {
-                                        dasd_erp_action_t erp_postaction;
-                                        erp_t *erp = (erp_t *) cqr;
-                                        erp_postaction =
-                                                dasd_erp_postaction (erp);
-                                        if (erp_postaction)
-                                                erp_postaction (erp);
-                                        atomic_dec (&qp->dirty_requests);
-                                } else if (cqr->magic == MDSK_MAGIC) {
-                                } else {
-                                        PRINT_WARN ("unknown magic%s\n", "");
-                                }
-                                dasd_end_cqr (cqr, 1);
+		default:
+			printk (KERN_WARNING PRINTK_HEADER
+			    " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+				" unknown return code %d, %d retries left."
+			  " Pls report this message to linux390@de.ibm.com\n",
+				devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS,
+				rc, retries);
                                 break;
                         }
-			case CQR_STATUS_FAILED: {
-                                next = cqr->next;
-                                if (cqr->magic == DASD_MAGIC) {
-                                        dasd_debug (0xc4c49692);
-                                } else if (cqr->magic == ERP_MAGIC) {
-                                        dasd_erp_action_t erp_postaction;
-                                        erp_t *erp = (erp_t *) cqr;
-                                        erp_postaction =
-                                                dasd_erp_postaction (erp);
-                                        if (erp_postaction)
-                                                erp_postaction (erp);
-                                } else if (cqr->magic == MDSK_MAGIC) {
-                                } else {
-                                        PRINT_WARN ("unknown magic%s\n", "");
+	} while (rc && retries--);
+	if (rc) {
+                atomic_compare_and_swap_debug (&cqr->status, 
+                                               CQR_STATUS_IN_IO, 
+                                               CQR_STATUS_ERROR);
                                 }
-                                dasd_end_cqr (cqr, 0);
-                                atomic_dec (&qp->dirty_requests);
-                                break;
+	return rc;
                         }
-			default:
-                                PRINT_WARN ("unknown cqrstatus\n");
+
+static void
+dasd_end_request (struct request *req, int uptodate)
+{
+	struct buffer_head *bh;
+	while ((bh = req->bh) != NULL) {
+		req->bh = bh->b_reqnext;
+		bh->b_reqnext = NULL;
+		bh->b_end_io (bh, uptodate);
 			}
-                        s390irq_spin_unlock_irqrestore (irq, flags);
-		} while ((cqr = next) != NULL);
-		qp = qp->next_q;
+	if (!end_that_request_first (req, uptodate, DASD_NAME)) {
+#ifndef DEVICE_NO_RANDOM
+		add_blkdev_randomness (MAJOR (req->rq_dev));
+#endif
+		end_that_request_last (req);
 	}
-	spin_lock (&io_request_lock);
-	do_dasd_request ();
-	spin_unlock (&io_request_lock);
-	dasd_debug (0xc4c46d6d);	/* DD__ */
+	return;
 }
 
-/* 
-   The request_fn is called from ll_rw_blk for any new request.
-   We use it to feed the chanqs.
-   This implementation assumes we are serialized by the io_request_lock.
- */
+#undef CURRENT
+#define CURRENT (blk_dev[major].current_request)
 
-#define QUEUE_THRESHOLD 5
-
-void
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static void
+do_dasd_request (request_queue_t * queue)
+#else
+static void
 do_dasd_request (void)
+#endif /* LINUX_IS_24 */
 {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+	struct request *req;
+        int go;
+#else
 	struct request *req, *next, *prev;
-	cqr_t *cqr;
+#endif /* LINUX_IS_24 */
+	ccw_req_t *cqr;
 	dasd_chanq_t *q;
 	long flags;
-	int di, irq;
+	int devindex, irq, partn;
 	int broken, busy;
+	dasd_device_t *device;
+	major_info_t *major_info;
+	int devno;
+        int major;
         
-	dasd_debug (0xc4d90000);	/* DR */
-	dasd_debug ((unsigned long) __builtin_return_address (0));
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        {
+                if ( queue == NULL ) {
+			printk(KERN_ERR PRINTK_HEADER "Null queue !!\n");
+                        return;
+                }
+                go = 1;
+                while (go && !list_empty (&queue->queue_head)) {
+                        req = blkdev_entry_next_request (&queue->queue_head);
+                        major = MAJOR(req->rq_dev);
+                        for (major_info = dasd_major_info; major_info != NULL; major_info = major_info->next ) {
+                                if ( major_info->gendisk.major == major )
+                                        break;
+                        }
+                        if ( major_info == NULL ) {
+                                printk (KERN_ERR PRINTK_HEADER "No major_info\n");
+                                return;
+                        }
+#else
+        for ( major_info = dasd_major_info; major_info != NULL; major_info = major_info->next ) {
+                major = major_info->gendisk.major;
 	prev = NULL;
 	for (req = CURRENT; req != NULL; req = next) {
 		next = req->next;
-		di = DEVICE_NR (req->rq_dev);
-		dasd_debug ((unsigned long) req);	/* req */
-		dasd_debug (0xc4d90000 +	/* DR## */
-                            ((((di/16)<9?(di/16)+0xf0:(di/16)+0xc1))<<8) +
-                            (((di%16)<9?(di%16)+0xf0:(di%16)+0xc1)));
-                irq = dasd_info[di]->info.irq;
-                s390irq_spin_lock_irqsave (irq, flags);
-                q = &dasd_info[di]->queue;
-		busy = atomic_read (&q->flags) & DASD_CHANQ_BUSY;
-		broken = atomic_read (&q->flags) & DASD_REQUEST_Q_BROKEN;
-		if (!busy ||
-		    (!broken &&
-		     (req->nr_sectors >= QUEUE_SECTORS))) {
+                        if (req == &blk_dev[major].plug) { /* remove plug if applicable */
+                                req->next = NULL;
                         if (prev) {
                                 prev->next = next;
                         } else {
                                 CURRENT = next;
                         }
-			req->next = NULL;
-			if (req == &blk_dev[MAJOR_NR].plug) {
-					dasd_debug (0xc4d99787); /* DRpg */
-				goto cont;
-			}
-			cqr = dasd_cqr_from_req (req);
-			if (!cqr) {
-					dasd_debug (0xc4d96ff1); /* DR?1 */
+                                continue;
+			}
+#endif /* LINUX_IS_24 */
+                        devindex = devindex_from_kdev_t(req->rq_dev);
+                        if ( devindex < 0 ) {
+                                printk ( KERN_WARNING PRINTK_HEADER 
+                                         "requesting I/O on nonexistent device %d -> %d\n",
+                                         devindex,req->rq_dev);
 				dasd_end_request (req, 0);
-				goto cont;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                                blkdev_dequeue_request (req);
+#else
+                                req->next = NULL;
+                                if (prev) {
+                                        prev->next = next;
+					} else {
+                                        CURRENT = next;
                         }
-                        dasd_debug ((unsigned long) cqr);	/* cqr */
-                        dasd_chanq_enq (q, cqr);
-			if (!(atomic_read (&q->flags) & DASD_CHANQ_ACTIVE)) {
-                                cql_enq_head (q);
+#endif /* LINUX_IS_24 */
+                                continue;
                         }
-			if (!busy) {
-				atomic_clear_mask (DASD_REQUEST_Q_BROKEN,
-						   &q->flags);
-				if ( atomic_read (&q->dirty_requests) == 0 ) {
-					if (dasd_start_IO (cqr) == 0) {
-					} else {
-						dasd_schedule_bh (dasd_do_chanq);
+                        device = find_dasd_device (devindex);
+                        if ( device == NULL ) {
+                                printk ( KERN_WARNING PRINTK_HEADER 
+                                         "requesting I/O on nonexistent device\n");
+				dasd_end_request(req,0);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                                blkdev_dequeue_request (req);
+#else
+                                req->next = NULL;
+                                if (prev) {
+                                        prev->next = next;
+                                } else {
+                                        CURRENT = next;
+                                }
+#endif /* LINUX_IS_24 */
+                                continue;
+                        }
+                        irq = device->devinfo.irq;
+                        s390irq_spin_lock_irqsave (irq, flags);
+                        devno = device->devinfo.devno;
+                        q = & device->queue;
+                        busy = atomic_read (&q->flags) & DASD_CHANQ_BUSY;
+                        broken = atomic_read (&q->flags) & DASD_REQUEST_Q_BROKEN;
+                        partn = MINOR (req->rq_dev) & ((1 << major_info->gendisk.minor_shift) - 1);
+                        if ( ! busy ||
+                             ( ! broken &&
+                               (req->nr_sectors >= QUEUE_SECTORS))) {
+                                if (device->discipline == NULL) {
+                                        printk (KERN_WARNING PRINTK_HEADER
+                                                " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+                                                " is not assigned to a discipline\n",
+                                                devno, irq, device->name, major, devindex << DASD_PARTN_BITS);
+                                        dasd_end_request (req, 0);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                                        blkdev_dequeue_request (req);
+#else
+                                        req->next = NULL;
+                                       	if (prev) {
+                                                prev->next = next;
+                         	        } else {
+                                       	        CURRENT = next;
+                                        }
+#endif /* LINUX_IS_24 */	
+					s390irq_spin_unlock_irqrestore (irq, flags);
+                                	continue;
+                                }
+                                if (device->discipline->build_cp_from_req == NULL) {
+                                        printk (KERN_WARNING PRINTK_HEADER
+                                                " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+                                                " discipline %s hast no builder function\n",
+                                                devno, irq, device->name,major, devindex << DASD_PARTN_BITS,
+                                                device->discipline->name);
+                                        dasd_end_request (req, 0);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                        	        blkdev_dequeue_request (req);
+#else
+                                	req->next = NULL;
+                                	if (prev) {
+                                        	prev->next = next;
+                                	} else {
+                                        	CURRENT = next;
+                                	}
+#endif /* LINUX_IS_24 */
+					s390irq_spin_unlock_irqrestore (irq, flags);
+					continue;                 
+		                }
+                                req->sector += major_info->gendisk.part[MINOR(req->rq_dev)].start_sect;
+                                cqr = device->discipline->build_cp_from_req (device, req);
+                                if (cqr == NULL) {
+                                        atomic_set_mask (DASD_REQUEST_Q_BROKEN, &q->flags);
+                                        printk (KERN_WARNING PRINTK_HEADER
+                                                " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+                                                " Could not create channel program for request %p\n",
+                                                devno, irq, device->name, major, devindex << DASD_PARTN_BITS, req);
+                                /* put request back to queue*/
+                                        req->sector -= major_info->gendisk.part[MINOR(req->rq_dev)].start_sect;
+                                        s390irq_spin_unlock_irqrestore (irq, flags);
+                                        continue;
+                                } 
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                                blkdev_dequeue_request (req);
+#else
+                                req->next = NULL;
+                                if (prev) {
+                                        prev->next = next;
+                                } else {
+                                        CURRENT = next;
                                 }
+#endif /* LINUX_IS_24 */
+                                dasd_chanq_enq (q, cqr);
+                                if (!(atomic_read (&q->flags) & DASD_CHANQ_ACTIVE)) {
+                                        qlist_enq (q);
+                                }
+                                if (!busy) {
+                                        atomic_clear_mask (DASD_REQUEST_Q_BROKEN, &q->flags);
+                                        if (atomic_read (&q->dirty_requests) == 0) {
+                                                if (device->discipline->start_IO == NULL) {
+                                                        printk (KERN_WARNING PRINTK_HEADER
+                                                                " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+                                                                " dicsipline %s has no starter function\n",
+                                                                devno, irq, device->name, major, devindex << DASD_PARTN_BITS,
+                                                                device->discipline->name);
+                                                } else {
+                                                        if (device->discipline->start_IO (cqr) != 0) {
+                                                                printk (KERN_DEBUG PRINTK_HEADER
+                                                                        " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+                                                                        " starting of request from req_fn failed, postponing\n",
+                                                                        devno, irq, device->name, major, devindex << DASD_PARTN_BITS);
+                                                                dasd_schedule_bh ();	/* initiate bh to run */
+                                                        }
+                                                }
+                                        } else {
+						dasd_schedule_bh();
+                                        } 
+                                }
+                        } else {
+                                atomic_set_mask (DASD_REQUEST_Q_BROKEN, &q->flags);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                                go = 0;
+#else
+                                prev = req;
+#endif /* LINUX_IS_24 */
                         }
+                        s390irq_spin_unlock_irqrestore (irq, flags);
+                }
+        }
+        return;
+}
+
+static void
+dasd_do_chanq (void)
+{
+	dasd_chanq_t *qp = NULL;
+	dasd_chanq_t *nqp;
+	dasd_device_t *device;
+	ccw_req_t *cqr, *next;
+	long flags;
+	int irq;
+	int devno, devindex;
+	int rc = -1;
+	volatile int cqrstatus;
+
+	for (qp = qlist_head; qp != NULL; qp = nqp) {
+		/* Get first request */
+		cqr = (ccw_req_t *) (qp->head);
+		nqp = qp->next_q;
+/* empty queue -> dequeue and proceed */
+		if (!cqr) {
+			qlist_deq (qp);
+			continue;
+		}
+/* process all requests on that queue */
+		do {
+			dasd_discipline_t *discipline;
+			next = NULL;
+			/* Sanity check... walk through disciplines */
+			for (discipline = dasd_disciplines;
+			     discipline != NULL;
+			     discipline = discipline->next)
+				if (!strncmp ((char *) &cqr->magic, discipline->ebcname, 4))
+					break;
+			if (!discipline) {	/* 1st sanity check */
+				panic (PRINTK_HEADER
+				       "in dasd_do_chanq: magic no mismatch %p -> 0x%lX\n",
+				       cqr, cqr->magic);
+			}
+			device = (dasd_device_t *) (cqr->device);
+			if (discipline != device->discipline) {		/* 1st sanity check */
+				printk (KERN_WARNING PRINTK_HEADER
+					"in dasd_do_chanq: discipline mismatch %p -> 0x%lX\n",
+					cqr, cqr->magic);
+				discipline = device->discipline;
+			}
+			irq = device->devinfo.irq;
+			devno = device->devinfo.devno;
+			devindex = devindex_from_devno (devno);
+
+			s390irq_spin_lock_irqsave (irq, flags);
+
+			cqrstatus = atomic_read (&cqr->status);
+			switch (cqrstatus) {
+			case CQR_STATUS_QUEUED:
+				if (discipline->start_IO &&
+				    ((rc = discipline->start_IO (cqr)) == 0)) {
+                                } else {
+					printk (KERN_WARNING PRINTK_HEADER
+						" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+						" Failing to start I/O operation with rc %d\n",
+						devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, rc);
+					switch (rc) {
+					case EBUSY:
+						if (cqr->retries--) {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" retrying %d retries left\n",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, cqr->retries);
+							break;
+						}
+					default:{	/* Fallthrough ?? */
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" Giving up this request!\n",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+							atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_FAILED);
+							break;
+						}
+					}
+				}
+				break;
+			case CQR_STATUS_IN_IO:{
+					unsigned long long now;
+					unsigned long long delta;
+
+					asm volatile ("STCK %0":"=m" (now));
+					if (cqr->expires && cqr->startclk &&
+					    cqr->expires < now) {
+                                                delta = cqr->expires - cqr->startclk;
+						printk (KERN_ERR PRINTK_HEADER
+							" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+							" I/O operation outstanding longer than %Ld usecs on req %p\n",
+							devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, delta >> 12, cqr);
+						if ( cqr->retries-- ) {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" waiting %d more times\n",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, cqr->retries);
+							cqr->expires += delta;
+							break;
+						} else {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" You should disable that device by issueing '@#?!'\n",		/* FIXME */
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+							atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_FAILED);
+							break;
+						}
+					}
+					break;
+				}
+			case CQR_STATUS_ERROR:{
+					dasd_erp_action_fn_t erp_action;
+					ccw_req_t *erp_cqr = NULL;
+					if (discipline->erp_action &&
+					    ((erp_action = discipline->erp_action (cqr)) != NULL)) {
+                                                printk (KERN_WARNING PRINTK_HEADER
+                                                        " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+							" Taking error recovery action %p on req %p \n",
+							devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, erp_action,cqr);
+						erp_cqr = erp_action (cqr);
+					} else {
+						printk (KERN_WARNING PRINTK_HEADER
+							" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+                                                        " No error recovery action\n",
+							devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+						atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_ERROR, CQR_STATUS_FAILED);
+					}
+					if ( erp_cqr != NULL ) {
+						dasd_chanq_enq_head (qp, erp_cqr);
+						next = erp_cqr;		/* prefer execution of erp ccw */
+					}
+					break;
+				}
+			case CQR_STATUS_DONE:{
+                                        dasd_erp_postaction_fn_t erp_postaction;
+                                        next = cqr->next;
+					if (cqr->refers && cqr->function) {	/* we deal with an ERP */
+						if (discipline->erp_postaction &&
+						    ((erp_postaction = discipline->erp_postaction (cqr)) != NULL)) {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" postprocessing successful error recovery action %p\n",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, erp_postaction);
+							erp_postaction (cqr, 1);
+                                                        atomic_dec (&device->queue.dirty_requests);
+						} else {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" No procedure to postprocess error recovery action"
+                                                                " giving up request",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+							atomic_compare_and_swap_debug (&cqr->refers->status, CQR_STATUS_ERROR, CQR_STATUS_FAILED);
+						}
+					} else if ( cqr->req ) {
+						asm volatile ("STCK %0":"=m" (cqr->endclk));
+						dasd_end_request (cqr->req, 1);
+#ifdef DASD_PROFILE
+						dasd_profile_add (cqr);
+#endif				/* DASD_PROFILE */
+					} 
+					dasd_chanq_deq (&device->queue, cqr);
+                                        dasd_free_request(cqr);
+					break;
+				}
+			case CQR_STATUS_FAILED:{
+					dasd_erp_postaction_fn_t erp_postaction;
+					next = cqr->next;
+					if (cqr->refers && cqr->function) {	/* we deal with an ERP */
+						if (discipline->erp_postaction &&
+						    ((erp_postaction = discipline->erp_postaction (cqr)) != NULL)) {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" postprocessing unsuccessful error recovery action %p\n",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, erp_postaction);
+							erp_postaction (cqr, 0);
+                                                        atomic_dec (&device->queue.dirty_requests);
+
+						} else {
+							printk (KERN_WARNING PRINTK_HEADER
+								" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+								" No procedure to postprocess unsuccessful error recovery action"
+							 " giving up request",
+								devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+							atomic_compare_and_swap_debug (&cqr->refers->status, CQR_STATUS_ERROR, CQR_STATUS_FAILED);
+						}
+					} else if (cqr->req) {
+						asm volatile ("STCK %0":"=m" (cqr->endclk));
+						dasd_end_request (cqr->req, 0);
+#ifdef DASD_PROFILE
+						dasd_profile_add (cqr);
+#endif				/* DASD_PROFILE */
+					} else {
+						printk (KERN_WARNING PRINTK_HEADER
+							"Internal error in " __FILE__ " on line %d."
+							" inconsistent content of ccw_req_t"
+							" refers = %p,function = %p, request = %p"
+							" Pls send this message and your System.map to"
+						     " linux390@de.ibm.com\n",
+							__LINE__, cqr->refers, cqr->function, cqr->req);
+					}
+					dasd_chanq_deq (&device->queue, cqr);
+                                        dasd_free_request(cqr);
+					break;
+				}
+			default:{
+					printk (KERN_WARNING PRINTK_HEADER
+						"Internal error in " __FILE__ " on line %d."
+					  " inconsistent content of ccw_req_t"
+						" cqrstatus = %d"
+						" Pls send this message and your System.map to"
+						" linux390@de.ibm.com\n",
+						__LINE__, cqrstatus);
 			}
-                } else {
-                        dasd_debug (0xc4d9c2d9);	/* DRBR */
-			atomic_set_mask (DASD_REQUEST_Q_BROKEN, &q->flags);
-			prev = req;
 		}
-        cont:
                 s390irq_spin_unlock_irqrestore (irq, flags);
+		} while ((cqr = next) != NULL);
 	}
-	dasd_debug (0xc4d96d6d);	/* DR__ */
+	schedule_request_fn (try_request_fn);
+        return;
 }
 
 void
-dasd_handler (int irq, void *ds, struct pt_regs *regs)
+dasd_int_handler (int irq, void *ds, struct pt_regs *regs)
 {
 	devstat_t *stat = (devstat_t *) ds;
 	int ip;
-	cqr_t *cqr;
+	ccw_req_t *cqr;
 	int done_fast_io = 0;
-	dasd_era_t era;
+	dasd_era_t era = dasd_era_fatal;
+	dasd_device_t *device;
+	int devno = -1, devindex = -1;
+        
+#undef ERP_DEBUG
+#ifdef ERP_DEBUG 
         static int counter = 0; 
+#endif
 
-	dasd_debug (0xc4c80000);	/* DH */
 	if (!stat) {
 		PRINT_ERR ("handler called without devstat");
 		return;
 	}
 	ip = stat->intparm;
-	dasd_debug (ip);	/* intparm */
 	if (!ip) {		/* no intparm: unsolicited interrupt */
-		dasd_debug (0xc4c8a489);	/* DHui */
 		PRINT_INFO ("%04X caught unsolicited interrupt\n",
 			    stat->devno);
 		return;
 	}
 		if (ip & 0x80000001) {
-			dasd_debug (0xc4c8a489);	/* DHui */
 		PRINT_INFO ("%04X  caught spurious interrupt with parm %08x\n",
 			    stat->devno, ip);
 			return;
 		}
-		cqr = (cqr_t *) ip;
-	if (cqr->magic == DASD_MAGIC || cqr->magic == ERP_MAGIC) {
+	cqr = (ccw_req_t *) ip;
+	device = (dasd_device_t *) cqr->device;
+	devno = device->devinfo.devno;
+	devindex = devindex_from_devno (devno);
+	if (device == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+		     " IRQ on devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+			" belongs to NULL device\n",
+			devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+	}
+	if (device->devinfo.irq != irq) {
+		printk (KERN_WARNING PRINTK_HEADER
+		     " IRQ on devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+			" doesn't belong to device irq %d\n",
+			devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS,
+			device->devinfo.irq);
+		return;
+	}
+	if (device->discipline == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+			" is not assigned to a discipline\n",
+			devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+	}
+	if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"0x%04X on sch %d : /dev/%s (%d:%d)"
+			" magic number of ccw_req_t 0x%08lX doesn't match"
+			" discipline 0x%08X\n",
+			devno, irq, device->name,
+			major_from_devindex (devindex),
+			devindex << DASD_PARTN_BITS,
+			cqr->magic, *(int *) (&device->discipline->name));
+		return;
+	}
 		asm volatile ("STCK %0":"=m" (cqr->stopclk));
 		if ((stat->cstat == 0x00 &&
 		     stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) ||
-		    ((era = dasd_erp_examine (cqr, stat)) == dasd_era_none)) {
-			dasd_debug (0xc4c89692);	/* DHok */
-#if 0
-                        if ( counter < 20 || cqr -> magic == ERP_MAGIC) {
-                                counter ++;
-#endif
-                                ACS (cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_DONE);
-#if 0
-                        } else {
-                                counter=0;
-                                PRINT_WARN ("Faking I/O error\n");
-                                ACS (cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_ERP_PEND);
-                                atomic_inc (&dasd_info[cqr->devindex]->
-                                            queue.dirty_requests);
+	    (device->discipline->examine_error &&
+	     (era = device->discipline->examine_error (cqr, stat)) == dasd_era_none)) {
+#ifdef ERP_DEBUG
+                if ( ++counter % 137 == 0 ) {
+                        printk ( KERN_INFO PRINTK_HEADER "Faking I/O error to recover from\n");
+                        era = dasd_era_recover;
+                        stat->flag |= DEVSTAT_FLAG_SENSE_AVAIL;
+                        stat->dstat |= 0x02;
+                        goto error_fake_done;
                         }
 #endif
-			if (atomic_read (&dasd_info[cqr->devindex]->status) ==
-			    DASD_INFO_STATUS_DETECTED) {
-				register_dasd_last (cqr->devindex);
-                                if ( dasd_info[cqr->devindex]->wait_q ) {
-                                        wake_up( &dasd_info[cqr->devindex]->
-                                                wait_q);
-                                }
-			}
+		atomic_compare_and_swap_debug (&cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_DONE);
+                atomic_compare_and_swap (DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+					 DASD_DEVICE_LEVEL_ANALYSIS_PREPARED,
+                                         &device->level);
 			if (cqr->next &&
 			    (atomic_read (&cqr->next->status) ==
 			     CQR_STATUS_QUEUED)) {
-				dasd_debug (0xc4c8e2e3);	/* DHST */
 				if (dasd_start_IO (cqr->next) == 0) {
 					done_fast_io = 1;
-				} else {
 			}
 		}
 		} else {	/* only visited in case of error ! */
-		dasd_debug (0xc4c8c5d9);	/* DHER */
-                        dasd_dump_sense (stat);
-		if (!cqr->dstat)
-			cqr->dstat = kmalloc (sizeof (devstat_t),
-					      GFP_ATOMIC);
+#ifdef ERP_DEBUG
+        error_fake_done:
+#endif
+		if (cqr->dstat == NULL)
+			cqr->dstat = kmalloc (sizeof (devstat_t), GFP_ATOMIC);
 		if (cqr->dstat) {
 			memcpy (cqr->dstat, stat, sizeof (devstat_t));
 		} else {
 				PRINT_ERR ("no memory for dstat\n");
 		}
-                        atomic_inc (&dasd_info[cqr->devindex]->
-                                    queue.dirty_requests);
+		if (device->discipline &&
+		    device->discipline->dump_sense) {
+			char *errmsg = device->discipline->dump_sense (device, cqr);
+			if (errmsg != NULL) {
+				printk ("%s", errmsg);
+				free_page ((unsigned long) errmsg);
+			} else {
+				printk (KERN_WARNING PRINTK_HEADER
+					"No memory to dump error message\n");
+			}
+		}
+		atomic_inc (&device->queue.dirty_requests);
 		/* errorprocessing */
 			if (era == dasd_era_fatal) {
 				PRINT_WARN ("ERP returned fatal error\n");
-				ACS (cqr->status,
+			atomic_compare_and_swap_debug (&cqr->status,
 				     CQR_STATUS_IN_IO, CQR_STATUS_FAILED);
 			} else {
-                                ACS (cqr->status,
-                                     CQR_STATUS_IN_IO, CQR_STATUS_ERP_PEND);
+			atomic_compare_and_swap_debug (&cqr->status,
+                                                       CQR_STATUS_IN_IO, CQR_STATUS_ERROR);
                         }
 	}
 	if (done_fast_io == 0)
-		atomic_clear_mask (DASD_CHANQ_BUSY,
-				   &dasd_info[cqr->devindex]->
-				   queue.flags);
+		atomic_clear_mask (DASD_CHANQ_BUSY, &device->queue.flags);
         
-	if (cqr->flags & DASD_DO_IO_SLEEP) {
-		dasd_debug (0xc4c8a6a4);	/* DHwu */
-		dasd_wakeup ();
-	} else if (! (cqr->options & DOIO_WAIT_FOR_INTERRUPT) ){
-                dasd_debug (0xc4c8a293);	/* DHsl */
-                        dasd_schedule_bh (dasd_do_chanq);
-	} else {
-                dasd_debug (0x64686f6f);	/* DH_g */
-                dasd_debug (cqr->flags);	/* DH_g */
-        }
-        } else {
-                dasd_debug (0xc4c86ff1);	/* DH?1 */
-                PRINT_ERR ("handler:magic mismatch on %p %08x\n",
-                           cqr, cqr->magic);
-                return;
-        }
-	dasd_debug (0xc4c86d6d);	/* DHwu */
-}
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        wake_up (&device->wait_q);
+#else
+	if (device->wait_q) {
+		wake_up (&device->wait_q);
+	}
+#endif /* LINUX_IS_24 */
+	dasd_schedule_bh ();
+}
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static wait_queue_head_t watcher_queue;
+#else
+static struct wait_queue watcher_queue_Qend = {NULL,};
+static struct wait_queue *watcher_queue = &watcher_queue_Qend;
+#endif /* LINUX_IS_24 */
 
-static int
-dasd_format (int dev, format_data_t * fdata)
+static void
+dasd_watcher (void)
 {
-	int rc;
-	int devindex = DEVICE_NR (dev);
-	dasd_chanq_t *q;
-	cqr_t *cqr;
-	int irq;
-	long flags;
-	PRINT_INFO ("%04X called format on %x\n",
-		    dasd_info[devindex]->info.devno, dev);
-	if (MINOR (dev) & (0xff >> (8 - PARTN_BITS))) {
-		PRINT_WARN ("Can't format partition! minor %x %x\n",
-			    MINOR (dev), 0xff >> (8 - PARTN_BITS));
-		return -EINVAL;
+	do {
+		dasd_schedule_bh ();
+		schedule_request_fn (try_request_fn);
+		interruptible_sleep_on_timeout (&watcher_queue, 5 * HZ);
+	} while (1);
+        }
+
+/* SECTION: Some stuff related to error recovery */
+
+ccw_req_t *
+default_erp_action (ccw_req_t * cqr)
+{
+	ccw_req_t *erp = ccw_alloc_request ((char *) &cqr->magic, 1, 0);
+
+	erp->cpaddr->cmd_code = CCW_CMD_NOOP;
+	erp->function = default_erp_action;
+	erp->refers = cqr;
+	erp->device = cqr->device;
+        erp->magic = cqr->magic;
+	atomic_set (&erp->status, CQR_STATUS_FILLED);
+        if ( cqr->startclk && cqr->expires )
+                cqr->expires -= cqr->startclk;
+        
+	if (cqr->retries++ <= 16) {
+                atomic_compare_and_swap_debug (&cqr->status,
+                                               CQR_STATUS_ERROR,
+					       CQR_STATUS_QUEUED);
+        } else {
+		printk (KERN_WARNING PRINTK_HEADER "ERP retry count exceeded\n");
+		atomic_compare_and_swap_debug (&cqr->status,
+					       CQR_STATUS_ERROR,
+					       CQR_STATUS_FAILED);
 	}
-	down (&dasd_info[devindex]->sem);
-	atomic_set (&dasd_info[devindex]->status,
-		    DASD_INFO_STATUS_UNKNOWN);
-	if (dasd_info[devindex]->open_count == 1) {
-		rc = dasd_disciplines[dasd_info[devindex]->type]->
-		    dasd_format (devindex, fdata);
-		if (rc) {
-			PRINT_WARN ("Formatting failed rc=%d\n", rc);
-			up (&dasd_info[devindex]->sem);
-			return rc;
-		}
-	} else {
-		PRINT_WARN ("device is open! %d\n", dasd_info[devindex]->open_count);
-		up (&dasd_info[devindex]->sem);
+	return erp;
+}
+
+int
+default_erp_postaction (ccw_req_t * cqr, int success)
+{
+	int rc = 0;
+	if (cqr->refers == NULL || cqr->function == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"ERP postaction called for non ERP cqr\n");
 		return -EINVAL;
 	}
-#if DASD_PARANOIA > 1
-	if (!dasd_disciplines[dasd_info[devindex]->type]->fill_sizes_first) {
-		INTERNAL_CHECK ("No fill_sizes for dt=%d\n", dasd_info[devindex]->type);
-	} else
-#endif				/* DASD_PARANOIA */
-	{
-		ACS (dasd_info[devindex]->status,
-		     DASD_INFO_STATUS_UNKNOWN, DASD_INFO_STATUS_DETECTED);
-		irq = dasd_info[devindex]->info.irq;
-		PRINT_INFO ("%04X reacessing, irq %x, index %d\n",
-			    get_devno_by_irq (irq), irq, devindex);
-		s390irq_spin_lock_irqsave (irq, flags);
-		q = &dasd_info[devindex]->queue;
-		cqr = dasd_disciplines[dasd_info[devindex]->type]->
-		    fill_sizes_first (devindex);
-		dasd_chanq_enq (q, cqr);
-		if (!(atomic_read (&q->flags) & DASD_CHANQ_ACTIVE)) {
-			cql_enq_head (q);
-		}
-		dasd_schedule_bh (dasd_do_chanq);
-		s390irq_spin_unlock_irqrestore (irq, flags);
-	}
-	up (&dasd_info[devindex]->sem);
+	if (cqr->function != default_erp_action) {
+		printk (KERN_WARNING PRINTK_HEADER
+                        "default ERP postaction called for non default ERP cqr\n");
+		return -EINVAL;
+        }
 	return rc;
 }
 
+/* SECTION: The helpers of the struct file_operations */
+
 static int
-register_dasd (int irq, dasd_type_t dt, dev_info_t * info)
+dasd_format (dasd_device_t * device, format_data_t * fdata)
 {
 	int rc = 0;
-	int di;
-	unsigned long flags;
-	dasd_chanq_t *q;
-	cqr_t *cqr;
-	static spinlock_t register_lock = SPIN_LOCK_UNLOCKED;
-	spin_lock (&register_lock);
-	FUNCTION_ENTRY ("register_dasd");
-	di = devindex_from_devno (info->devno);
-	if (di < 0) {
-		INTERNAL_CHECK ("Can't get index for devno %d\n", info->devno);
-		return -ENODEV;
-	}
-	if (dasd_info[di]) {	/* devindex is not free */
-		INTERNAL_CHECK ("reusing allocated deviceindex %d\n", di);
-		return -ENODEV;
-	}
-	dasd_info[di] = (dasd_information_t *)
-	    kmalloc (sizeof (dasd_information_t), GFP_ATOMIC);
-	if (dasd_info[di] == NULL) {
-		PRINT_WARN ("No memory for dasd_info_t on irq %d\n", irq);
-		return -ENOMEM;
-	}
-	memset (dasd_info[di], 0, sizeof (dasd_information_t));
-	memcpy (&(dasd_info[di]->info), info, sizeof (dev_info_t));
-	spin_lock_init (&dasd_info[di]->queue.f_lock);
-	spin_lock_init (&dasd_info[di]->queue.q_lock);
-	dasd_info[di]->type = dt;
-	dasd_info[di]->irq = irq;
-	dasd_info[di]->sem = MUTEX;
-#ifdef CONFIG_DASD_MDSK
-	if (dt == dasd_mdsk) {
-		dasd_info[di]->rdc_data = kmalloc (
-				 sizeof (dasd_characteristics_t), GFP_ATOMIC);
-		if (!dasd_info[di]->rdc_data) {
-			PRINT_WARN ("No memory for char on irq %d\n", irq);
-			goto unalloc;
-		}
-		dasd_info[di]->rdc_data->mdsk.dev_nr = dasd_info[di]->
-		    info.devno;
-		dasd_info[di]->rdc_data->mdsk.rdc_len =
-		    sizeof (dasd_mdsk_characteristics_t);
-	} else
-#endif				/* CONFIG_DASD_MDSK */
-	rc = dasd_read_characteristics (dasd_info[di]);
-	if (rc) {
-		PRINT_WARN ("RDC returned error %d\n", rc);
-		rc = -ENODEV;
-		goto unalloc;
-	}
-#if DASD_PARANOIA > 1
-	if (dasd_disciplines[dt]->ck_characteristics)
-#endif				/* DASD_PARANOIA */
-		rc = dasd_disciplines[dt]->
-		    ck_characteristics (dasd_info[di]->rdc_data);
-
-	if (rc) {
-		INTERNAL_CHECK ("Discipline returned non-zero when"
-				"checking device characteristics%s\n", "");
-		rc = -ENODEV;
-		goto unalloc;
-	}
-#ifdef CONFIG_DASD_MDSK
-	if (dt == dasd_mdsk) {
+	int devno = device->devinfo.devno;
+	int irq = device->devinfo.irq;
+	int devindex = devindex_from_devno (devno);
 
-	} else
-#endif				/* CONFIG_DASD_MDSK */
-	rc = request_irq (irq, dasd_handler, 0, "dasd",
-			  &(dasd_info[di]->dev_status));
-	ACS (dasd_info[di]->status,
-	     DASD_INFO_STATUS_UNKNOWN, DASD_INFO_STATUS_DETECTED);
-	if (rc) {
-#if DASD_PARANOIA > 0
+	if (device->open_count != 1) {
 		printk (KERN_WARNING PRINTK_HEADER
-			"Cannot register irq %d, rc=%d\n",
-			irq, rc);
-#endif				/* DASD_PARANOIA */
-		rc = -ENODEV;
-		goto unalloc;
-	}
-#if DASD_PARANOIA > 1
-	if (!dasd_disciplines[dt]->fill_sizes_first) {
-		INTERNAL_CHECK ("No fill_sizes for dt=%d\n", dt);
-		goto unregister;
-	}
-#endif				/* DASD_PARANOIA */
-	irq = dasd_info[di]->info.irq;
-	PRINT_INFO ("%04X trying to access, irq %x, index %d\n",
-		    get_devno_by_irq (irq), irq, di);
-	s390irq_spin_lock_irqsave (irq, flags);
-	q = &dasd_info[di]->queue;
-	cqr = dasd_disciplines[dt]->fill_sizes_first (di);
-	dasd_chanq_enq (q, cqr);
-	if (!(atomic_read (&q->flags) & DASD_CHANQ_ACTIVE)) {
-		cql_enq_head (q);
-	}
-	if (dasd_start_IO (cqr) != 0) {
-		dasd_schedule_bh (dasd_do_chanq);
+			" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+		      " you shouldn't format a device that is already open\n",
+			devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+		return -EINVAL;
 	}
-	s390irq_spin_unlock_irqrestore (irq, flags);
-
-	goto exit;
-
-      unregister:
-	free_irq (irq, &(dasd_info[di]->dev_status));
-      unalloc:
-	kfree (dasd_info[di]);
-	dasd_info[di] = NULL;
-      exit:
-	spin_unlock (&register_lock);
-	FUNCTION_EXIT ("register_dasd");
+        dasd_set_device_level( device->devinfo.irq,
+                               DASD_DEVICE_LEVEL_RECOGNIZED,
+                               device->discipline,
+                               0);
+	if (device->discipline->format_device)
+          rc = device->discipline->format_device (device, fdata);
+		if (rc) {
+                printk (KERN_WARNING PRINTK_HEADER
+                        " devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+			" Formatting failed with rc = %d\n",
+			devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, rc);
+			return rc;
+		}
+	printk (KERN_WARNING PRINTK_HEADER
+		" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+		" Formatting finished successfully rc = %d\n",
+		devno, irq, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS, rc);
+        dasd_set_device_level( device->devinfo.irq,
+                               DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+                               device->discipline,
+                               0);
+        udelay(1500000);
+        dasd_set_device_level( device->devinfo.irq,
+                               DASD_DEVICE_LEVEL_ANALYSED,
+                               device->discipline,
+                               0);
 	return rc;
 }
 
 static int
-probe_for_dasd (int irq)
+do_dasd_ioctl (struct inode *inp, /* unsigned */ int no, unsigned long data)
 {
-	int rc;
-	dev_info_t info;
-	dasd_type_t dt;
-
-	rc = get_dev_info_by_irq (irq, &info);
-
-	if (rc == -ENODEV) {	/* end of device list */
-		return rc;
-	} else if ((info.status & DEVSTAT_DEVICE_OWNED)) {
-		return -EBUSY;
-	} else if ((info.status & DEVSTAT_NOT_OPER)) {
-		return -ENODEV;
-	}
-#if DASD_PARANOIA > 2
-	else {
-		INTERNAL_CHECK ("unknown rc %d of get_dev_info", rc);
-		return rc;
+	int rc = 0;
+	int devindex = devindex_from_kdev_t (inp->i_rdev);
+	dasd_device_t *device = find_dasd_device (devindex);
+	major_info_t *major_info = major_info_from_devindex (devindex);
+        
+	if (!device) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"No device registered as 0x%04x (%d)\n",
+			inp->i_rdev, devindex);
+		return -EINVAL;
 	}
-#endif				/* DASD_PARANOIA */
-
-	dt = check_type (&info);	/* make a first guess */
-
-	if (dt == dasd_none) {
-		return -ENODEV;
+	if ((_IOC_DIR (no) != _IOC_NONE) && (data == 0)) {
+		PRINT_DEBUG ("empty data ptr");
+		return -EINVAL;
 	}
-		if (!dasd_is_accessible (info.devno)) {
-			return -ENODEV;
+#if 0
+	printk (KERN_DEBUG PRINTK_HEADER
+		"ioctl 0x%08x %s'0x%x'%d(%d) on /dev/%s (%d:%d,"
+		" devno 0x%04X on irq %d) with data %8lx\n",
+		no,
+		_IOC_DIR (no) == _IOC_NONE ? "0" :
+		_IOC_DIR (no) == _IOC_READ ? "r" :
+		_IOC_DIR (no) == _IOC_WRITE ? "w" :
+		_IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
+		_IOC_TYPE (no), _IOC_NR (no), _IOC_SIZE (no),
+		device->name, MAJOR (inp->i_rdev), MINOR (inp->i_rdev),
+		device->devinfo.devno, device->devinfo.irq,
+		data);
+#endif
+	switch (no) {
+	case BLKGETSIZE:{	/* Return device size */
+			int blocks = blk_size[MAJOR (inp->i_rdev)][MINOR (inp->i_rdev)] << 1;
+			rc = copy_to_user ((long *) data, &blocks, sizeof (long));
+			break;
 		}
-	if (!dasd_disciplines[dt]->ck_devinfo) {
-			INTERNAL_ERROR ("no ck_devinfo function%s\n", "");
-			return -ENODEV;
+	case BLKFLSBUF:{
+			rc = fsync_dev (inp->i_rdev);
+			break;
 		}
-	rc = dasd_disciplines[dt]->ck_devinfo (&info);
-	if (rc) {
-			return rc;
+	case BLKRAGET:{
+			rc = copy_to_user ((long *) data, read_ahead + MAJOR (inp->i_rdev), sizeof (long));
+			break;
 		}
-	if (dasd_probeonly) {
-		PRINT_INFO ("%04X not enabled due to probeonly mode\n",
-			    info.devno);
-		dasd_add_devno_to_ranges (info.devno);
-			return -ENODEV;
-	} else {
-		rc = register_dasd (irq, dt, &info);
-	}
-		if (rc) {
-		PRINT_WARN ("%04X not enabled due to errors\n",
-			    info.devno);
-		} else {
-		PRINT_INFO ("%04X is (dasd%c) minor %d (%s)\n",
-				    info.devno,
-			    'a' + devindex_from_devno (info.devno),
-			       devindex_from_devno (info.devno) << PARTN_BITS,
-				    dasd_name[dt]);
+	case BLKRASET:{
+			rc = copy_from_user (read_ahead + MAJOR (inp->i_rdev), (long *) data, sizeof (long));
+			break;
 		}
+	case BLKRRPART:{
+			dasd_partn_detect (devindex);
+			rc = 0;
+			break;
+		}
+	case BLKGETBSZ:{
+			rc = copy_to_user ((int *) data, &blksize_size[MAJOR (inp->i_rdev)][MINOR (inp->i_rdev)],
+					   sizeof (int));
+			break;
+		}
+	case HDIO_GETGEO:{
+			struct hd_geometry geo =
+			{0,};
+			if (device->discipline->fill_geometry)
+				device->discipline->fill_geometry (device, &geo);
+			rc = copy_to_user ((struct hd_geometry *) data, &geo,
+					   sizeof (struct hd_geometry));
+			break;
+		}
+#if ! (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+		RO_IOCTLS (inp->i_rdev, data);
+#endif /* LINUX_IS_24 */
+	case BIODASDRSID:{
+			rc = copy_to_user ((void *) data,
+					   &(device->devinfo.sid_data),
+					   sizeof (senseid_t));
+			break;
+		}
+	case BIODASDRWTB:{
+			int offset = 0;
+			int xlt;
 
-	return rc;
-}
-
-static int
-register_major (int major)
-{
-	int rc = 0;
-
-	FUNCTION_ENTRY ("register_major");
-	rc = register_blkdev (major, DASD_NAME, &dasd_device_operations);
-#if DASD_PARANOIA > 1
-	if (rc) {
-		PRINT_WARN ("registering major -> rc=%d aborting... \n", rc);
-		return rc;
+			rc = copy_from_user (&xlt, (void *) data,
+					     sizeof (int));
+			if (rc)
+				break;
+			offset = major_info->gendisk.part[MINOR (inp->i_rdev)].start_sect >>
+			    device->sizes.s2b_shift;
+			xlt += offset;
+			rc = copy_to_user ((void *) data, &xlt,
+					   sizeof (int));
+			break;
+		}
+	case BIODASDFORMAT:{
+			/* fdata == NULL is a valid arg to dasd_format ! */
+			int partn;
+			format_data_t *fdata = NULL;
+			if (data) {
+				fdata = kmalloc (sizeof (format_data_t),
+						 GFP_ATOMIC);
+				if (!fdata) {
+					rc = -ENOMEM;
+					break;
+				}
+				rc = copy_from_user (fdata, (void *) data,
+						     sizeof (format_data_t));
+				if (rc)
+					break;
+			}
+			partn = MINOR (inp->i_rdev) & ((1 << major_info->gendisk.minor_shift) - 1);
+			if (partn != 0) {
+				printk (KERN_WARNING PRINTK_HEADER
+					" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+				     " Cannot low-level format a partition\n",
+					device->devinfo.devno, device->devinfo.irq, device->name,
+				    MAJOR (inp->i_rdev), MINOR (inp->i_rdev));
+				return -EINVAL;
+			}
+			rc = dasd_format (device, fdata);
+			if (fdata) {
+				kfree (fdata);
+			}
+			break;
+		}
+	case BIODASDEXCP:{
+			printk (KERN_WARNING PRINTK_HEADER
+				"Unsupported ioctl BIODASDEXCP\n");
+                        break;
+		}
+        default:{
+          printk (KERN_WARNING PRINTK_HEADER
+                  "unknown ioctl 0x%08x %s'0x%x'%d(%d) on /dev/%s (%d:%d,"
+                  " devno 0x%04X on irq %d) with data %8lx\n",
+                  no,
+                  _IOC_DIR (no) == _IOC_NONE ? "0" :
+                  _IOC_DIR (no) == _IOC_READ ? "r" :
+                  _IOC_DIR (no) == _IOC_WRITE ? "w" :
+                  _IOC_DIR (no) == (_IOC_READ | _IOC_WRITE) ? "rw" : "u",
+                  _IOC_TYPE (no), _IOC_NR (no), _IOC_SIZE (no),
+                  device->name, MAJOR (inp->i_rdev), MINOR (inp->i_rdev),
+                  device->devinfo.devno, device->devinfo.irq,
+                  data);
+          rc = -EINVAL;
+          break;
+		}
 	}
-#endif				/* DASD_PARANOIA */
-	blk_dev[major].request_fn = do_dasd_request;
-	FUNCTION_CONTROL ("successfully registered major: %d\n", major);
-	FUNCTION_EXIT ("register_major");
 	return rc;
 }
 
-/* 
-   Below you find functions which are called from outside. Some of them may be
-   static, because they are called by their function pointers only. Thus static
-   modifier is to make sure, that they are only called via the kernel's methods
- */
+/* SECTION: The members of the struct file_operations */
 
 static int
 dasd_ioctl (struct inode *inp, struct file *filp,
 	    unsigned int no, unsigned long data)
-{
+	{
 	int rc = 0;
-	FUNCTION_ENTRY ("dasd_ioctl");
 	if ((!inp) || !(inp->i_rdev)) {
 		return -EINVAL;
-	}
+		}
 	rc = do_dasd_ioctl (inp, no, data);
-	FUNCTION_EXIT ("dasd_ioctl");
 	return rc;
 }
 
@@ -1346,31 +1688,45 @@
 dasd_open (struct inode *inp, struct file *filp)
 {
 	int rc = 0;
-	dasd_information_t *dev;
-	FUNCTION_ENTRY ("dasd_open");
+	int devindex;
+	int partn;
+	dasd_device_t *device;
+	major_info_t *major_info;
+
 	if ((!inp) || !(inp->i_rdev)) {
 		return -EINVAL;
 	}
-	dev = dasd_info[DEVICE_NR (inp->i_rdev)];
-	if (!dev) {
-		PRINT_DEBUG ("No device registered as %d (%d)\n",
-			    inp->i_rdev, DEVICE_NR (inp->i_rdev));
+	if ( dasd_probeonly ) {
+		printk ("\n" KERN_INFO PRINTK_HEADER "No access to device (%d:%d) due to probeonly mode\n",MAJOR(inp->i_rdev),MINOR(inp->i_rdev));
+		return -EPERM;
+	}
+	devindex = devindex_from_kdev_t (inp->i_rdev);
+	if (devindex < 0) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"No device registered as %d\n", inp->i_rdev);
+		return devindex;
+	}
+	device = find_dasd_device (devindex);
+	major_info = major_info_from_devindex (devindex);
+	partn = MINOR (inp->i_rdev) & ((1 << major_info->gendisk.minor_shift) - 1);
+	if (device == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"No device registered as %d\n", inp->i_rdev);
+		return -EINVAL;
+	}
+	if (atomic_read (&device->level) < DASD_DEVICE_LEVEL_RECOGNIZED ||
+	    device->discipline == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			" devno 0x%04X on subchannel %d = /dev/%s (%d:%d)"
+			" Cannot open unrecognized device\n",
+		     device->devinfo.devno, device->devinfo.irq, device->name,
+			MAJOR (inp->i_rdev), MINOR (inp->i_rdev));
 		return -EINVAL;
 	}
-	down (&dev->sem);
-	up (&dev->sem);
 #ifdef MODULE
 	MOD_INC_USE_COUNT;
 #endif				/* MODULE */
-#if DASD_PARANOIA > 2
-	if (dev->open_count < 0) {
-		INTERNAL_ERROR ("open count cannot be less than 0: %d",
-				dev->open_count);
-		return -EINVAL;
-	}
-#endif				/* DASD_PARANOIA */
-	dev->open_count++;
-	FUNCTION_EXIT ("dasd_open");
+	device->open_count++;
 	return rc;
 }
 
@@ -1378,37 +1734,38 @@
 dasd_release (struct inode *inp, struct file *filp)
 {
 	int rc = 0;
-	dasd_information_t *dev;
-	FUNCTION_ENTRY ("dasd_release");
+	dasd_device_t *device;
+	int devindex;
+
 	if ((!inp) || !(inp->i_rdev)) {
 		return -EINVAL;
 	}
-	dev = dasd_info[DEVICE_NR (inp->i_rdev)];
-	if (!dev) {
-		PRINT_WARN ("No device registered as %d\n", inp->i_rdev);
+	devindex = devindex_from_kdev_t (inp->i_rdev);
+	device = find_dasd_device (devindex);
+	if (device == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"No device registered as %d:%d\n",
+			MAJOR(inp->i_rdev),MINOR(inp->i_rdev));
 		return -EINVAL;
 	}
+	if(device->open_count--) {
 #ifdef MODULE
 	MOD_DEC_USE_COUNT;
 #endif				/* MODULE */
-#if DASD_PARANOIA > 2
-	if (!dev->open_count) {
-		PRINT_WARN ("device %d has not been opened before:\n",
-			    inp->i_rdev);
-	}
-#endif				/* DASD_PARANOIA */
-	dev->open_count--;
-#if DASD_PARANOIA > 2
-	if (dev->open_count < 0) {
-		INTERNAL_ERROR ("open count cannot be less than 0: %d",
-				dev->open_count);
-		return -EINVAL;
 	}
-#endif				/* DASD_PARANOIA */
-	FUNCTION_EXIT ("dasd_release");
 	return rc;
 }
 
+/* SECTION: All that stuff related to major numbers */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static struct
+block_device_operations dasd_device_operations =
+{
+	ioctl:dasd_ioctl,
+	open:dasd_open,
+	release:dasd_release,
+};
+#else
 static struct
 file_operations dasd_device_operations =
 {
@@ -1419,156 +1776,894 @@
 	open:dasd_open,
 	release:dasd_release,
 };
+#endif /* LINUX_IS_24 */
 
-int
-dasd_init (void)
+static major_info_t *
+get_new_major_info (void)
 {
+	major_info_t *major_info = NULL;
+	major_info = kmalloc (sizeof (major_info_t), GFP_KERNEL);
+	if (major_info) {
+                major_info_t *temp = dasd_major_info;
+                while (temp->next)
+                        temp = temp->next;
+		temp->next = major_info;
+                
+		memset (major_info, 0, sizeof (major_info_t));
+		major_info->read_ahead = 8;
+		major_info->request_fn = do_dasd_request;
+                
+		major_info->gendisk.major_name = DASD_NAME;
+		major_info->gendisk.minor_shift = DASD_PARTN_BITS;
+		major_info->gendisk.max_p = 1 << DASD_PARTN_BITS;
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+		major_info->gendisk.max_nr= 1 << DASD_PARTN_BITS;
+#endif /* LINUX_IS_24 */
+		major_info->gendisk.nr_real=DASD_PER_MAJOR;
+	}
+	return major_info;
+}
+
+static int
+dasd_register_major (major_info_t * major_info)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        request_queue_t *q;
+#endif /* LINUX_IS_24 */
 	int rc = 0;
-	int i;
+	int major;
 
-	PRINT_INFO ("initializing...\n");
-	atomic_set (&bh_scheduled, 0);
-	spin_lock_init (&dasd_lock);
-#ifdef CONFIG_DASD_MDSK
-	/*
-	 * enable service-signal external interruptions,
-	 * Control Register 0 bit 22 := 1
-	 * (besides PSW bit 7 must be set to 1 somewhere for external
-	 * interruptions)
-	 */
-	ctl_set_bit (0, 9);
-	register_external_interrupt (0x2603, do_dasd_mdsk_interrupt);
-#endif
-	dasd_debug_info = debug_register ("dasd", 1, 4);
-	/* First register to the major number */
+	if (major_info == NULL) {
+		major_info = get_new_major_info ();
+		if (!major_info) {
+			printk (KERN_WARNING PRINTK_HEADER
+				"Cannot get memory to allocate another major number\n");
+			return -ENOMEM;
+		} else {
+			printk (KERN_INFO PRINTK_HEADER
+				"Created another major number\n");
+		}
+	}
+	major = major_info->gendisk.major;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+	rc = devfs_register_blkdev (major, DASD_NAME, &dasd_device_operations);
+#else
+	rc = register_blkdev (major, DASD_NAME, &dasd_device_operations);
+#endif /* LINUX_IS_24 */
+	if (rc < 0) {
+		printk (KERN_WARNING PRINTK_HEADER
+		      "Cannot register to major no %d, rc = %d\n", major, rc);
+	return rc;
+	} else if (rc > 0) {
+		if (major == 0) {
+			major = rc;
+			rc = 0;
+		} else {
+			printk (KERN_DEBUG PRINTK_HEADER
+			    "Unknown condition when registering major number."
+			  "Please report this line to Linux390@de.ibm.com\n");
+		}
+	} else {
+		if (major == 0) {
+			printk (KERN_DEBUG PRINTK_HEADER
+				"Unknown condition when registering to dynamic major number."
+			  "Please report this line to Linux390@de.ibm.com\n");
 
-	rc = register_major (MAJOR_NR);
-#if DASD_PARANOIA > 1
-	if (rc) {
-		PRINT_WARN ("registering major_nr returned rc=%d\n", rc);
+		}
+	}
+        major_info->dasd_device = (dasd_device_t **) kmalloc( DASD_PER_MAJOR * sizeof(dasd_device_t*), 
+                                                              GFP_ATOMIC);
+        memset ( major_info->dasd_device ,0,DASD_PER_MAJOR * sizeof(dasd_device_t*));
+        blk_size[major] = major_info->blk_size = 
+                (int *) kmalloc( (1<<MINORBITS) * sizeof(int), GFP_ATOMIC);
+        memset ( major_info->blk_size ,0,(1<<MINORBITS) * sizeof(int));
+        blksize_size[major] = major_info->blksize_size = 
+                (int *) kmalloc( (1<<MINORBITS) * sizeof(int), GFP_ATOMIC);
+        memset ( major_info->blksize_size ,0,(1<<MINORBITS) * sizeof(int));
+        hardsect_size[major] = major_info->hardsect_size = 
+                (int *) kmalloc( (1<<MINORBITS) * sizeof(int), GFP_ATOMIC);
+        memset ( major_info->hardsect_size ,0,(1<<MINORBITS) * sizeof(int));
+        max_sectors[major] = major_info->max_sectors = 
+                (int *) kmalloc( (1<<MINORBITS) * sizeof(int), GFP_ATOMIC);
+        memset ( major_info->max_sectors ,0,(1<<MINORBITS) * sizeof(int));
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        q = BLK_DEFAULT_QUEUE (major);
+        blk_init_queue (q, do_dasd_request);
+        blk_queue_headactive (BLK_DEFAULT_QUEUE (major), 0);
+#else
+	blk_dev[major].request_fn = major_info->request_fn;
+#endif /* LINUX_IS_24 */
+
+        
+	/* finally do the gendisk stuff */
+        major_info->gendisk.part = kmalloc ((1 << MINORBITS) * 
+                                            sizeof (struct hd_struct),
+                                            GFP_ATOMIC);
+        memset (major_info->gendisk.part,0,(1 << MINORBITS) * 
+                sizeof (struct hd_struct));
+	major_info->gendisk.major = major;
+	major_info->gendisk.next = gendisk_head;
+        major_info->gendisk.sizes = major_info->blk_size;
+	gendisk_head = &major_info->gendisk;
+	return major;
+}
+
+static int
+dasd_unregister_major (major_info_t * major_info)
+{
+	int rc = 0;
+	int major;
+        struct gendisk *dd,*prev=NULL;
+
+	if (major_info == NULL) {
+                return -EINVAL;
+	}
+	major = major_info->gendisk.major;
+	rc = unregister_blkdev (major, DASD_NAME);
+	if (rc < 0) {
+		printk (KERN_WARNING PRINTK_HEADER
+                        "Cannot unregister from major no %d, rc = %d\n", major, rc);
 		return rc;
+	} 
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        blk_dev[major].request_fn = NULL;
+#endif /* LINUX_IS_24 */
+        blk_size[major]= NULL;
+        blksize_size[major]= NULL;
+        hardsect_size[major]= NULL;
+        max_sectors[major]= NULL;
+
+        kfree(major_info->dasd_device);
+        kfree(major_info->blk_size);
+        kfree(major_info->blksize_size);
+        kfree(major_info->hardsect_size);
+        kfree(major_info->max_sectors);
+        kfree(major_info->gendisk.part);
+        
+	/* finally do the gendisk stuff */
+        for (dd = gendisk_head; dd ; dd = dd -> next ) {
+                if ( dd == &major_info->gendisk ) {
+                        if ( prev )
+                                prev->next = dd->next;
+                        else 
+                                gendisk_head = dd->next;
+                        break;
+                }
+                prev = dd;
+        }
+        if ( dd == NULL ) {
+                return -ENOENT;
+        }
+        if  ( major_info->gendisk.major > 128 )
+                kfree(major_info);
+	return rc;
+}
+/* SECTION: Management of device list */
+
+/* This one is needed for naming 18000+ possible dasd devices */
+int
+dasd_device_name (char *str, int index, int partition, struct gendisk *hd)
+{
+	int len = 0;
+        char first,second,third;
+
+        if ( hd ) {
+                index = devindex_from_kdev_t (MKDEV(hd->major,index<<hd->minor_shift));
+}
+        third = index % 26;
+        second = (index / 26) % 27;
+	first = ((index / 26) / 27) % 27;
+
+	len = sprintf (str, "dasd");
+	if (first) {
+                len += sprintf (str + len, "%c", first + 'a' - 1 );
 	}
-#endif	/* DASD_PARANOIA */ read_ahead[MAJOR_NR] = 8;
-        blk_size[MAJOR_NR] = dasd_blks;
-	hardsect_size[MAJOR_NR] = dasd_secsize;
-	blksize_size[MAJOR_NR] = dasd_blksize;
-	max_sectors[MAJOR_NR] = dasd_maxsecs;
-#ifdef CONFIG_PROC_FS
-	dasd_proc_init ();
-#endif				/* CONFIG_PROC_FS */
-	/* Now scan the device list for DASDs */
-	for (i = 0; i < NR_IRQS; i++) {
-		int irc;	/* Internal return code */
-		irc = probe_for_dasd (i);
-		switch (irc) {
-		case 0:
-			break;
-		case -ENODEV:
-		case -EBUSY:
-			break;
-		case -EMEDIUMTYPE:
-			PRINT_WARN ("DASD not formatted%s\n", "");
+	if (second) {
+                len += sprintf (str + len, "%c", second + 'a' - 1 );
+	}
+        len += sprintf (str + len, "%c", third + 'a' );
+	if (partition) {
+		if (partition > 9) {
+			return -EINVAL;
+		} else {
+			len += sprintf (str + len, "%d", partition);
+	}
+	}
+	str[len] = '\0';
+	return 0;
+}
+
+static void
+dasd_not_oper_handler ( int irq, int status ) {
+        int devno,devindex;
+        dasd_device_t *device;
+        devno = get_devno_by_irq(irq);
+        if ( devno < 0 ) {
+		printk (KERN_WARNING PRINTK_HEADER
+                         "not_oper_handler called on irq %d no devno!\n", irq);
+                return;
+	}
+        printk ( KERN_INFO PRINTK_HEADER
+                 "not_oper_handler called on irq %d devno %04X\n", irq,devno);
+        devindex = devindex_from_devno(devno);
+        device = find_dasd_device(devindex);
+        dasd_set_device_level( irq, DASD_DEVICE_LEVEL_UNKNOWN, NULL, 0 );
+	}
+
+static int
+dasd_enable_single_volume ( int irq ) {
+        int rc = 0;
+        dasd_set_device_level (irq, DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+                               NULL, 0);
+	printk (KERN_INFO PRINTK_HEADER "waiting for response...\n");
+        {
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                static wait_queue_head_t wait_queue;
+                init_waitqueue_head(&wait_queue);
+#else
+                static struct wait_queue *wait_queue = NULL;
+#endif /* LINUX_IS_24 */
+                interruptible_sleep_on_timeout (&wait_queue, (5 * HZ) >> 1 );
+        }
+        dasd_set_device_level (irq, DASD_DEVICE_LEVEL_ANALYSED,
+                               NULL, 0);
+	return rc;
+}
+
+static int
+dasd_oper_handler ( int irq, devreg_t *devreg ) {
+        int devno;
+        int devindex;
+	int rc;
+        devno = get_devno_by_irq(irq);
+        if ( devno == -ENODEV )
+                return -ENODEV;
+        do {
+                devindex = devindex_from_devno(devno);
+                if ( dasd_autodetect ) {
+                        dasd_add_range(devno,0);
+                } else {
+		return -ENODEV;
+	}
+        } while ( devindex == -ENODEV );
+        rc = dasd_enable_single_volume(irq);
+		return rc;
+	}
+
+/* 
+ * int
+ * dasd_set_device_level (unsigned int irq, int desired_level,
+ *                        dasd_discipline_t * discipline, int flags)
+ */
+
+static int
+dasd_set_device_level (unsigned int irq, int desired_level,
+		       dasd_discipline_t * discipline, int flags)
+{
+	int rc = 0;
+	int devno;
+	int devindex;
+	dasd_device_t *device;
+	int current_level;
+	major_info_t *major_info = NULL;
+	int i, minor;
+	ccw_req_t *cqr = NULL;
+        int ind;
+        dasd_discipline_t *temp;
+        struct gendisk *dd;
+
+	devno = get_devno_by_irq (irq);
+	if (devno < 0) {
+		printk (KERN_WARNING PRINTK_HEADER " no device appears to be connected to SCH %d\n", irq);
+		return -ENODEV;
+	}
+	devindex = devindex_from_devno (devno);
+	if (devindex < 0) {
+		printk (KERN_WARNING PRINTK_HEADER " device %d is not in list of known DASDs\n", irq);
+			return -ENODEV;
+		}
+	device = find_dasd_device (devindex);
+        while ( (major_info = major_info_from_devindex (devindex)) == NULL ) {
+                if ((rc = dasd_register_major (major_info)) > 0) {
+                        printk (KERN_INFO PRINTK_HEADER
+                                "Registered successfully to another major number: %u\n", rc);
+                } else {
+                        printk (KERN_WARNING PRINTK_HEADER
+                                "Couldn't register successfully to another major no\n");
+                        return -ERANGE;
+		}
+		}
+        ind = devindex & (DASD_PER_MAJOR-1);
+        device = major_info->dasd_device[ind];
+        if (!device) {		/* allocate device descriptor */
+                device = kmalloc (sizeof (dasd_device_t), GFP_ATOMIC);
+		if (!device) {
+			printk (KERN_WARNING PRINTK_HEADER " No memory for device descriptor\n");
+			goto nomem;
+		}
+		memset (device, 0, sizeof (dasd_device_t));
+                major_info->dasd_device[ind] = device;
+                dasd_device_name (device->name, devindex, 0,NULL);
+	}
+        device->kdev = MKDEV(major_info->gendisk.major,ind << DASD_PARTN_BITS);
+        device->major_info = major_info;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        init_waitqueue_head(&device->wait_q);
+#endif /* KERNEL_VERSION */
+        minor = MINOR(device->kdev);
+	current_level = atomic_read (&device->level);
+	if (desired_level > current_level) {
+		switch (current_level) {
+		case DASD_DEVICE_LEVEL_UNKNOWN:	/* Find a discipline */
+			rc = get_dev_info_by_irq (irq, &device->devinfo);
+			if (rc < 0) {
+				break;
+			}
+                        for ( temp = dasd_disciplines; temp != NULL; temp = temp->next ) {
+                                if ( discipline == NULL || temp == discipline ) {
+                                        if (temp->id_check)
+                                                if (temp->id_check (&device->devinfo))
+                                                        continue;
+                                        if (temp->check_characteristics) {
+                                                if (temp->check_characteristics (device)) 
+                                                        continue;
+	}
+                                        discipline = temp;
+                                        break;
+                                }
+                        }
+			if (discipline && !rc) {
+				printk (KERN_INFO PRINTK_HEADER
+					" devno 0x%04X on subchannel %d (%s) is /dev/%s (%d:%d)\n",
+					devno, irq, discipline->name,
+                                        device->name, major_from_devindex (devindex),
+					(devindex % 64) << DASD_PARTN_BITS);
+		} else {
+				break;
+		}
+			device->discipline = discipline;
+			if (device->discipline->int_handler) {
+                                s390_request_irq_special(irq, 
+                                                         device->discipline->int_handler, 
+                                                         dasd_not_oper_handler,
+                                                         0, 
+                                                         DASD_NAME, 
+                                                         &device->dev_status);
+			}
+			atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_UNKNOWN,
+                                                       DASD_DEVICE_LEVEL_RECOGNIZED);
+			if (desired_level == DASD_DEVICE_LEVEL_RECOGNIZED)
+				break;
+		case DASD_DEVICE_LEVEL_RECOGNIZED:	/* Fallthrough ?? */
+			if (device->discipline->init_analysis) {
+				cqr = device->discipline->init_analysis (device);
+                                if (cqr != NULL) {
+                                        dasd_chanq_enq (&device->queue, cqr);
+                                        if (device->discipline->start_IO) {
+                                                long flags;
+                                                s390irq_spin_lock_irqsave (irq, flags);
+                                                device->discipline->start_IO (cqr);
+                                                atomic_compare_and_swap_debug (&device->level,
+                                                                               DASD_DEVICE_LEVEL_RECOGNIZED,
+                                                                               DASD_DEVICE_LEVEL_ANALYSIS_PENDING);
+                                                s390irq_spin_unlock_irqrestore (irq, flags);
+}
+                                }
+                        } else {
+                                atomic_compare_and_swap_debug (& device->level,DASD_DEVICE_LEVEL_RECOGNIZED,
+                                                               DASD_DEVICE_LEVEL_ANALYSIS_PREPARED);
+                        }
+			if (desired_level == DASD_DEVICE_LEVEL_ANALYSIS_PENDING)
+				break;
+		case DASD_DEVICE_LEVEL_ANALYSIS_PENDING:	/* Fallthrough ?? */
+			return -EAGAIN;
+		case DASD_DEVICE_LEVEL_ANALYSIS_PREPARED:	/* Re-entering here ! */
+                        if (device->discipline->do_analysis) 
+                                if (device->discipline->do_analysis (device))
+					return -ENODEV;
+			switch (device->sizes.bp_block) {
+			case 512:
+			case 1024:
+			case 2048:
+			case 4096:
+				break;
+			default:
+{
+					printk (KERN_INFO PRINTK_HEADER
+						"/dev/%s (devno 0x%04X): Detected invalid blocksize of %d bytes"
+						" Did you format the drive?\n",
+						device->name, devno, device->sizes.bp_block);
+					return -EMEDIUMTYPE;
+                        }
+			}
+			for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
+                                if (i == 0)
+					major_info->blk_size[minor] = (device->sizes.blocks << device->sizes.s2b_shift) >> 1;
+				else
+					major_info->blk_size[minor + i] = 0;
+				major_info->hardsect_size[minor + i] = device->sizes.bp_block;
+				major_info->blksize_size[minor + i] = device->sizes.bp_block;
+                                if (major_info->blksize_size[minor + i] < 1024 )
+                                        major_info->blksize_size[minor + i] = 1024;
+                                
+				major_info->max_sectors[minor + i] = 200 << device->sizes.s2b_shift;	/* FIXME !!! */
+			}
+			atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_ANALYSIS_PREPARED,
+                                                       DASD_DEVICE_LEVEL_ANALYSED);
+                        dd = &major_info->gendisk;
+                        dd->sizes[minor] = ( device->sizes.blocks << 
+                                             device->sizes.s2b_shift) >> 1;
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+#ifndef MODULE
+                        if ( flags & 0x80 )
+#endif
+#endif /* KERNEL_VERSION */
+                                dasd_partn_detect(devindex);
+			if (desired_level == DASD_DEVICE_LEVEL_ANALYSED)
+				break;
+		case DASD_DEVICE_LEVEL_ANALYSED:	/* Fallthrough ?? */
+
 			break;
 		default:
-			INTERNAL_CHECK ("probe_for_dasd: unknown rc=%d", irc);
+			printk (KERN_WARNING PRINTK_HEADER
+				"Internal error in " __FILE__ " on line %d."
+				" validate_dasd called from %p with "
+				" desired_level = %d, current_level =%d"
+				" Pls send this message and your System.map to"
+				" linux390@de.ibm.com\n",
+				__LINE__, __builtin_return_address (0),
+				desired_level, current_level);
+			break;
+		}
+	} else 	if (desired_level < current_level) {		/* donwgrade device status */
+		switch (current_level) {
+		case DASD_DEVICE_LEVEL_PARTITIONED:	/* Fallthrough ?? */
+                        /* delete the partition information */
+			for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
+                                struct hd_struct *p = &major_info->gendisk.part[minor+i];
+                                p->start_sect = 0;
+                                p->nr_sects = 0;
+                                p->type = 0;
+                        }
+			atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_PARTITIONED,
+                                                       DASD_DEVICE_LEVEL_ANALYSED);
+			if (desired_level == DASD_DEVICE_LEVEL_ANALYSED)
+				break;
+		case DASD_DEVICE_LEVEL_ANALYSED:	/* Fallthrough ?? */
+			atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_ANALYSED,
+                                                       DASD_DEVICE_LEVEL_ANALYSIS_PREPARED);
+                        if (desired_level == DASD_DEVICE_LEVEL_ANALYSIS_PREPARED)
+                                break;
+		case DASD_DEVICE_LEVEL_ANALYSIS_PREPARED:
+			for (i = 0; i < (1 << DASD_PARTN_BITS); i++) {
+                                major_info->blk_size[minor] = 0;
+                                major_info->hardsect_size[minor + i] = 0;
+                                major_info->blksize_size[minor + i] = 0;
+                                major_info->max_sectors[minor + i] = 0;
+			}
+                        memset( &device->sizes,0,sizeof(dasd_sizes_t));
+                        atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_ANALYSIS_PREPARED,
+                                                       DASD_DEVICE_LEVEL_ANALYSIS_PENDING);
+			if (desired_level == DASD_DEVICE_LEVEL_ANALYSIS_PENDING)
+				break;
+		case DASD_DEVICE_LEVEL_ANALYSIS_PENDING:	/* Fallthrough ?? */
+			atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+                                                       DASD_DEVICE_LEVEL_RECOGNIZED);
+			if (desired_level == DASD_DEVICE_LEVEL_RECOGNIZED)
+				break;
+		case DASD_DEVICE_LEVEL_RECOGNIZED:	/* Fallthrough ?? */
+                        if (device->discipline->int_handler) {
+                                free_irq (irq, &device->dev_status);
+			}
+			device->discipline = NULL;
+			atomic_compare_and_swap_debug (&device->level,
+                                                       DASD_DEVICE_LEVEL_RECOGNIZED,
+                                                       DASD_DEVICE_LEVEL_UNKNOWN);
+			if (desired_level == DASD_DEVICE_LEVEL_UNKNOWN)
+				break;
+		case DASD_DEVICE_LEVEL_UNKNOWN:	
+                        break;
+		default:
+			printk (KERN_WARNING PRINTK_HEADER
+				"Internal error in " __FILE__ " on line %d."
+				" validate_dasd called from %p with "
+				" desired_level = %d, current_level =%d"
+				" Pls send this message and your System.map to"
+				" linux390@de.ibm.com\n",
+				__LINE__, __builtin_return_address (0),
+				desired_level, current_level);
 			break;
 		}
 	}
-	FUNCTION_CONTROL ("detection loop completed %s partn check...\n", "");
-/* Finally do the genhd stuff */
-	dd_gendisk.next = gendisk_head;
-	gendisk_head = &dd_gendisk;
-	dasd_information = dasd_info;	/* to enable genhd to know about DASD */
-        tod_wait (1000000);
-
-	/* wait on root filesystem before detecting partitions */
-	if (MAJOR (ROOT_DEV) == DASD_MAJOR) {
-		int count = 10;
-		i = DEVICE_NR (ROOT_DEV);
-		if (dasd_info[i] == NULL) {
-			panic ("root device not accessible\n");
-		}
-                while ((atomic_read (&dasd_info[i]->status) !=
-                        DASD_INFO_STATUS_FORMATTED) &&
-                       count ) {
-                        PRINT_INFO ("Waiting on root volume...%d seconds left\n", count);
-			tod_wait (1000000);
-			count--;
-		}
-		if (count == 0) {
-			panic ("Waiting on root volume...giving up!\n");
-		}
-	}
-	for (i = 0; i < DASD_MAX_DEVICES; i++) {
-		if (dasd_info[i]) {
-			if (atomic_read (&dasd_info[i]->status) ==
-			    DASD_INFO_STATUS_FORMATTED) {
-				dasd_partn_detect (i);
-			} else {	/* start kernel thread for devices not ready now */
-				kernel_thread (dasd_partn_detect, (void *) i,
-                                               CLONE_FS | CLONE_FILES | CLONE_SIGHAND);
+	if (rc) {
+		goto exit;
+	}
+      nomem:
+	rc = -ENOMEM;
+      exit:
+	return 0;
+}
+
+
+/* SECTION: Procfs stuff */
+typedef struct {
+        char *data;
+        int len;
+} tempinfo_t;
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+static struct proc_dir_entry *dasd_proc_root_entry = NULL;
+#else
+static struct proc_dir_entry dasd_proc_root_entry =
+{
+	low_ino:0,
+	namelen:4,
+	name:"dasd",
+	mode:S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
+	nlink:1,
+	uid:0,
+	gid:0,
+	size:0
+};
+#endif /* KERNEL_VERSION */
+static struct proc_dir_entry* dasd_devices_entry;
+
+
+static int
+dasd_devices_open (struct inode* inode, struct file*  file )
+{
+	int rc = 0;
+	int size = 0;
+	int len = 0;
+	major_info_t * temp = dasd_major_info;
+        tempinfo_t *info;
+
+	info = (tempinfo_t *)vmalloc(sizeof(tempinfo_t)); 
+        if( info == NULL ) {
+                printk ( KERN_WARNING "No memory available for data\n");
+                return -ENOMEM;
+	} else {
+                file->private_data = (void *)info;
+	}
+        while ( temp ) {
+                int i;
+                for ( i = 0; i < 1 << (MINORBITS - DASD_PARTN_BITS); i ++ ) {
+                        dasd_device_t *device = temp->dasd_device[i];
+                        if ( device ) {
+				size+=128;
+			}
+		}
+		temp = temp->next;
+	}
+	temp = dasd_major_info;
+	info->data=(char*)vmalloc(size); /* FIXME! determine space needed in a better way */
+        if( size && info->data == NULL ) {
+		printk ( KERN_WARNING "No memory available for data\n");
+                vfree ( info );
+		return -ENOMEM;
+	}
+	while ( temp ) {
+		int i;
+		for ( i = 0; i < 1 << (MINORBITS - DASD_PARTN_BITS); i ++ ) {
+			dasd_device_t *device = temp->dasd_device[i];
+			if ( device ) {
+				len += sprintf ( info->data + len,
+						 "%04X(%s) at (%d:%d) is %7s:",
+						 device->devinfo.devno,
+						 device->discipline ? device->discipline->name : "none",
+						 temp->gendisk.major,i<<DASD_PARTN_BITS,
+						 device->name);
+                                switch ( atomic_read(&device->level) ) {
+                                case DASD_DEVICE_LEVEL_UNKNOWN:
+                                        len += sprintf ( info->data + len,"unknown\n");
+                                        break;
+                                case DASD_DEVICE_LEVEL_RECOGNIZED:
+                                        len += sprintf ( info->data + len,"passive");
+                                        len += sprintf ( info->data + len," at blocksize: %d, %d blocks, %d MB\n",
+                                                         device->sizes.bp_block,
+                                                         device->sizes.blocks,
+                                                         ((device->sizes.bp_block>>9)*device->sizes.blocks)>>11);
+                                        break;
+                                case DASD_DEVICE_LEVEL_ANALYSIS_PENDING:
+                                        len += sprintf ( info->data + len,"busy   \n");
+                                        break;
+				case DASD_DEVICE_LEVEL_ANALYSIS_PREPARED:
+					len += sprintf ( info->data + len,"n/f    \n");
+					break;
+                                case DASD_DEVICE_LEVEL_ANALYSED:
+                                        len += sprintf ( info->data + len,"active ");
+                                        len += sprintf ( info->data + len," at blocksize: %d, %d blocks, %d MB\n",
+                                                         device->sizes.bp_block,
+                                                         device->sizes.blocks,
+                                                         ((device->sizes.bp_block>>9)*device->sizes.blocks)>>11);
+                                        break;
+                                default:
+                                        len += sprintf ( info->data + len,"no stat\n");
+                                        break;
+                                }
 			}
 		}
+		temp = temp->next;
 	}
+        info->len=len;
 	return rc;
 }
 
-#ifdef MODULE
+#define MIN(a,b) ((a)<(b)?(a):(b))
 
-int
-init_module (void)
+static ssize_t 
+dasd_devices_read (  struct  file *file, char*   user_buf,  size_t  user_len, loff_t* offset )
 {
-	int rc = 0;
+        loff_t len;
+        tempinfo_t* p_info = (tempinfo_t*)file->private_data;
 
-	PRINT_INFO ("Initializing module\n");
-	rc = dasd_parse_module_params ();
-	if (rc == 0) {
-		PRINT_INFO ("module parameters parsed successfully\n");
-	} else {
-		PRINT_WARN ("parsing parameters returned rc=%d\n", rc);
+        if(*offset >= p_info->len)
+        {
+                return 0; /* EOF */
+	}
+        else
+        {
+                len = MIN(user_len, (p_info->len - *offset));
+                copy_to_user(user_buf, &(p_info->data[*offset]), len);
+                (*offset) += len;
+                return len;  /* number of bytes "read" */
 	}
-	rc = dasd_init ();
-	if (rc == 0) {
-		PRINT_INFO ("module initialized successfully\n");
-	} else {
-		PRINT_WARN ("initializing module returned rc=%d\n", rc);
+}
+
+static int
+dasd_devices_close (struct inode* inode, struct file*  file)
+{
+	int rc = 0;
+        tempinfo_t* p_info = (tempinfo_t*)file->private_data;
+        if ( p_info ) {
+                if ( p_info->data ) vfree(p_info->data);
+                vfree(p_info);
 	}
-	FUNCTION_EXIT ("init_module");
 	return rc;
 }
 
+
+static struct file_operations dasd_devices_file_ops =
+{
+  NULL,          /* lseek */
+  dasd_devices_read,  /* read */
+  NULL, /* dasd_devices_write, */   /* write */
+  NULL,          /* readdir */
+  NULL,          /* select */
+  NULL,          /* ioctl */
+  NULL,          /* mmap */
+  dasd_devices_open,    /* open */
+  NULL,          /* flush */
+  dasd_devices_close,   /* close */
+};
+
+static struct inode_operations dasd_devices_inode_ops =
+{
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+  default_file_ops: &dasd_devices_file_ops /* file ops */
+#endif /* LINUX_IS_24 */
+};
+
+void
+dasd_proc_init (void)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        dasd_proc_root_entry = create_proc_entry("dasd", 
+                                                 S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR,
+                                                 &proc_root);
+        dasd_devices_entry = create_proc_entry("devices", 
+                                               S_IFREG | S_IRUGO | S_IWUSR,
+                                               dasd_proc_root_entry);
+#else
+	proc_register (&proc_root, &dasd_proc_root_entry);
+	dasd_devices_entry = (struct proc_dir_entry*)kmalloc(sizeof(struct proc_dir_entry), GFP_ATOMIC);
+        if ( dasd_devices_entry) {
+                memset(dasd_devices_entry, 0, sizeof(struct proc_dir_entry));
+                dasd_devices_entry->name     = "devices";
+                dasd_devices_entry->namelen  = strlen("devices");
+                dasd_devices_entry->low_ino  = 0;
+                dasd_devices_entry->mode     = (S_IFREG | S_IRUGO | S_IWUSR);
+                dasd_devices_entry->nlink    = 1;
+                dasd_devices_entry->uid      = 0;
+                dasd_devices_entry->gid      = 0;
+                dasd_devices_entry->size     = 0;
+                dasd_devices_entry->get_info = NULL;
+                dasd_devices_entry->ops      = &dasd_devices_inode_ops;
+                proc_register(&dasd_proc_root_entry, dasd_devices_entry);
+        }
+#endif /* LINUX_IS_24 */
+}
+
 void
-cleanup_module (void)
+dasd_proc_cleanup (void)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        remove_proc_entry("devices", dasd_proc_root_entry);
+        remove_proc_entry("dasd", &proc_root);
+#else
+        proc_unregister(&dasd_proc_root_entry, dasd_devices_entry->low_ino);
+	kfree(dasd_devices_entry);
+	proc_unregister (&proc_root, dasd_proc_root_entry.low_ino);
+#endif /* LINUX_IS_24 */
+}
+
+/* SECTION: Initializing the driver */
+
+int
+dasd_init (void)
 {
 	int rc = 0;
-	struct gendisk *genhd = gendisk_head, *prev = NULL;
+	int irq;
+	int j;
+	major_info_t *major_info;
+        dasd_range_t *range;
+
+	printk (KERN_INFO PRINTK_HEADER "initializing...\n");
+        genhd_dasd_name = dasd_device_name;
+#ifndef MODULE
+        dasd_split_parm_string(dasd_parm_string);
+#endif /* ! MODULE */
+        dasd_parse(dasd);
+
+        dasd_proc_init();
+        dasd_init_emergency_req();
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        init_waitqueue_head(&watcher_queue);
+        spin_lock_init(&cq_lock);
+#endif /* LINUX_IS_24 */
+
+	for (major_info = dasd_major_info; major_info; major_info = major_info->next) {
+		if ((rc = dasd_register_major (major_info)) > 0) {
+			printk (KERN_INFO PRINTK_HEADER
+				"Registered successfully to major no %u\n", major_info->gendisk.major);
+		} else {
+			printk (KERN_WARNING PRINTK_HEADER
+				"Couldn't register successfully to major no %d\n", major_info->gendisk.major);
+	}
+		}
+        
+#ifdef CONFIG_DASD_ECKD
+	rc = dasd_eckd_init ();
+	if (rc==0)  {
+		printk (KERN_INFO PRINTK_HEADER
+			"Registered ECKD discipline successfully\n");
+	}
+#endif				/* CONFIG_DASD_ECKD */
+#ifdef CONFIG_DASD_FBA
+	rc = dasd_fba_init ();
+	if (rc == 0) {
+		printk (KERN_INFO PRINTK_HEADER
+			"Registered FBA discipline successfully\n");
+	}
+#endif				/* CONFIG_DASD_FBA */
+#ifdef CONFIG_DASD_MDSK
+	rc = dasd_diag_init ();
+	if (rc == 0)  {
+		printk (KERN_INFO PRINTK_HEADER
+			"Registered MDSK discipline successfully\n");
+	}
+#endif				/* CONFIG_DASD_MDSK */
+	rc = 0;
+	for (range = dasd_range_head; range; range= range->next) {
+		for (j = range->from; j <= range->to; j++) {
+			irq = get_irq_by_devno (j);
+			if (irq >= 0)
+				dasd_set_device_level (irq, DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+						       NULL, 0);
+	}
+			}
+        if ( dasd_autodetect ) {
+                for ( irq = get_irq_first(); irq != -ENODEV; irq = get_irq_next(irq) ) {
+                        int devno = get_devno_by_irq(irq);
+                        int index = devindex_from_devno(devno);
+                        if ( index == -ENODEV ) { /* not included in ranges */
+                                dasd_add_range (devno,0);
+				dasd_set_device_level (irq, DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+						       NULL, 0);
+		}
+	}
+}
+	printk (KERN_INFO PRINTK_HEADER "waiting for responses...\n");
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                static wait_queue_head_t wait_queue;
+                init_waitqueue_head(&wait_queue);
+#else
+                static struct wait_queue *wait_queue = NULL;
+#endif /* LINUX_IS_24 */
+                interruptible_sleep_on_timeout (&wait_queue, (5 * HZ) >> 1 );
+	}
+	for (range = dasd_range_head; range; range= range->next) {
+		for (j = range->from; j <= range->to; j++) {
+			irq = get_irq_by_devno (j);
+			if (irq >= 0) {
+				dasd_set_device_level (irq, DASD_DEVICE_LEVEL_ANALYSED,
+						       NULL, 0);
+	}
+		}
+	}
 
-	PRINT_INFO ("trying to unload module \n");
+	printk (KERN_INFO PRINTK_HEADER "initialization completed\n");
+	return rc;
+}
 
-	/* unregister gendisk stuff */
-	for (genhd = gendisk_head; genhd; prev = genhd, genhd = genhd->next) {
-		if (genhd == dd_gendisk) {
-			if (prev)
-				prev->next = genhd->next;
-			else {
-				gendisk_head = genhd->next;
+void
+cleanup_dasd (void)
+{
+        int j,rc=0;
+        int irq;
+        major_info_t *major_info;
+        dasd_range_t *range,*next;
+        dasd_devreg_t *reg;
+
+	printk (KERN_INFO PRINTK_HEADER "shutting down\n");
+
+        dasd_proc_cleanup();
+
+	for (range = dasd_range_head; range; range= range->next) {
+		for (j = range->from; j <= range->to; j++) {
+			irq = get_irq_by_devno (j);
+			if (irq >= 0) {
+				dasd_set_device_level (irq, DASD_DEVICE_LEVEL_UNKNOWN,
+						       NULL, 0);
+                                kfree(find_dasd_device(devindex_from_devno(j)));
 			}
-			break;
 		}
 	}
-	/* unregister devices */
-	for (i = 0; i = DASD_MAX_DEVICES; i++) {
-		if (dasd_info[i])
-			dasd_unregister_dasd (i);
+	for (major_info = dasd_major_info; major_info; major_info = major_info->next) {
+		if ((rc = dasd_unregister_major (major_info)) == 0) {
+			printk (KERN_INFO PRINTK_HEADER
+				"Unregistered successfully from major no %u\n", major_info->gendisk.major);
+		} else {
+			printk (KERN_WARNING PRINTK_HEADER
+				"Couldn't unregister successfully from major no %d rc = %d\n", major_info->gendisk.major,rc);
+		}
+	}
+        dasd_cleanup_emergency_req();
+        
+        range = dasd_range_head;
+        while ( range ) {
+                next = range -> next;
+                kfree (range);
+                if ( next == NULL )
+			break;
+                else
+                        range = next;
+		}
+        dasd_range_head = NULL;
+
+        while ( dasd_devreg_head ) {
+                reg = dasd_devreg_head->next;
+                kfree ( dasd_devreg_head );
+                dasd_devreg_head = reg;
+	}
+	printk (KERN_INFO PRINTK_HEADER "shutdown completed\n");
 	}
 
-	if (rc == 0) {
-		PRINT_INFO ("module unloaded successfully\n");
-	} else {
-		PRINT_WARN ("module unloaded with errors\n");
+#ifdef MODULE
+int
+init_module ( void )
+{
+        int rc=0;
+        return dasd_init(); 
+        return rc;
 	}
+
+void 
+cleanup_module ( void ) 
+{
+        cleanup_dasd();
+        return;
 }
-#endif				/* MODULE */
+#endif
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd.h linux.17p18/drivers/s390/block/dasd.h
--- linux.vanilla/drivers/s390/block/dasd.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd.h	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,10 @@
+ccw_req_t *default_erp_action (ccw_req_t *);
+int default_erp_postaction ( ccw_req_t *, int);
+int dasd_start_IO (ccw_req_t * cqr);
+void dasd_int_handler (int , void *, struct pt_regs *);
+ccw_req_t * dasd_alloc_request (char *, int , int ) ;
+void dasd_free_request(ccw_req_t *);
+int (*genhd_dasd_name)(char*,int,int,struct gendisk*);
+
+
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_3370_erp.c linux.17p18/drivers/s390/block/dasd_3370_erp.c
--- linux.vanilla/drivers/s390/block/dasd_3370_erp.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd_3370_erp.c	Tue Aug  1 07:59:48 2000
@@ -0,0 +1,105 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_3370_erp.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ */
+
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
+
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
+#define PRINTK_HEADER "dasd_erp(3370)"
+#endif /* PRINTK_HEADER */
+
+/*
+ * DASD_3370_ERP_EXAMINE 
+ *
+ * DESCRIPTION
+ *   Checks only for fatal/no/recover error. 
+ *   A detailed examination of the sense data is done later outside
+ *   the interrupt handler.
+ *
+ *   The logic is based on the 'IBM 3880 Storage Control Reference' manual
+ *   'Chapter 7. 3370 Sense Data'.
+ *
+ * RETURN VALUES
+ *   dasd_era_none      no error 
+ *   dasd_era_fatal     for all fatal (unrecoverable errors)
+ *   dasd_era_recover   for all others.
+ */
+dasd_era_t
+dasd_3370_erp_examine (ccw_req_t * cqr, devstat_t * stat)
+{
+	char *sense = stat->ii.sense.data;
+
+	/* check for successful execution first */
+	if ( stat->cstat == 0x00 &&
+             stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))             
+                return dasd_era_none;
+        if ( sense[0] & 0x80 ) { /* CMD reject */
+                return dasd_era_fatal;
+        }
+        if ( sense[0] & 0x40 ) { /* Drive offline */
+                return dasd_era_recover;
+        }
+        if ( sense[0] & 0x20 ) { /* Bus out parity */
+                return dasd_era_recover;
+        }
+        if ( sense[0] & 0x10 ) { /* equipment check */
+                if ( sense[1] & 0x80 ) {
+                        return dasd_era_fatal;
+                }
+                return dasd_era_recover;
+        }
+        if ( sense[0] & 0x08 ) { /* data check */
+                if ( sense[1] & 0x80 ) {
+                        return dasd_era_fatal;
+                }
+                return dasd_era_recover;
+        }
+        if ( sense[0] & 0x04 ) { /* overrun */
+                if ( sense[1] & 0x80 ) {
+                        return dasd_era_fatal;
+                }
+                return dasd_era_recover;
+        }
+        if ( sense[1] & 0x40 ) { /* invalid blocksize */
+                return dasd_era_fatal;
+        }
+        if ( sense[1] & 0x04 ) { /* file protected */
+                return dasd_era_recover;
+        }
+        if ( sense[1] & 0x01 ) { /* operation incomplete */
+                return dasd_era_recover;
+        }
+        if ( sense[2] & 0x80 ) { /* check data erroor */
+                return dasd_era_recover;
+        }
+        if ( sense[2] & 0x10 ) { /* Env. data present */
+                return dasd_era_recover;
+        }
+        /* examine the 24 byte sense data */
+        return dasd_era_recover;
+        
+}				/* END dasd_3370_erp_examine */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_3990_erp.c linux.17p18/drivers/s390/block/dasd_3990_erp.c
--- linux.vanilla/drivers/s390/block/dasd_3990_erp.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_3990_erp.c	Tue Aug  1 07:59:49 2000
@@ -6,10 +6,13 @@
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
  */
 
-#include <linux/dasd.h>
-#include "dasd_erp.h"
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
 
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
 #define PRINTK_HEADER "dasd_erp(3990)"
+#endif /* PRINTK_HEADER */
 
 /*
  * DASD_3990_ERP_EXAMINE_32 
@@ -95,7 +98,7 @@
  *   dasd_era_recover   for all others.
  */
 dasd_era_t
-dasd_3990_erp_examine (cqr_t * cqr, devstat_t * stat)
+dasd_3990_erp_examine (ccw_req_t * cqr, devstat_t * stat)
 {
 
 	char *sense = stat->ii.sense.data;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_9336_erp.c linux.17p18/drivers/s390/block/dasd_9336_erp.c
--- linux.vanilla/drivers/s390/block/dasd_9336_erp.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd_9336_erp.c	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,64 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_9336_erp.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ */
+
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
+
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
+#define PRINTK_HEADER "dasd_erp(9336)"
+#endif /* PRINTK_HEADER */
+
+/*
+ * DASD_9336_ERP_EXAMINE 
+ *
+ * DESCRIPTION
+ *   Checks only for fatal/no/recover error. 
+ *   A detailed examination of the sense data is done later outside
+ *   the interrupt handler.
+ *
+ *   The logic is based on the 'IBM 3880 Storage Control Reference' manual
+ *   'Chapter 7. 9336 Sense Data'.
+ *
+ * RETURN VALUES
+ *   dasd_era_none      no error 
+ *   dasd_era_fatal     for all fatal (unrecoverable errors)
+ *   dasd_era_recover   for all others.
+ */
+dasd_era_t
+dasd_9336_erp_examine (ccw_req_t * cqr, devstat_t * stat)
+{
+	char *sense = stat->ii.sense.data;
+
+	/* check for successful execution first */
+	if (stat->cstat == 0x00 &&
+	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+                return dasd_era_none;
+        
+        /* examine the 24 byte sense data */
+        return dasd_era_recover;
+        
+}				/* END dasd_9336_erp_examine */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_9343_erp.c linux.17p18/drivers/s390/block/dasd_9343_erp.c
--- linux.vanilla/drivers/s390/block/dasd_9343_erp.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_9343_erp.c	Tue Aug  1 07:59:49 2000
@@ -5,13 +5,16 @@
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
  */
 
-#include <linux/dasd.h>
-#include "dasd_erp.h"
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
 
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
 #define PRINTK_HEADER "dasd_erp(9343)"
+#endif /* PRINTK_HEADER */
 
 dasd_era_t
-dasd_9343_erp_examine (cqr_t * cqr, devstat_t * stat)
+dasd_9343_erp_examine (ccw_req_t * cqr, devstat_t * stat)
 {
 	if (stat->cstat == 0x00 &&
 	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_ccwstuff.c linux.17p18/drivers/s390/block/dasd_ccwstuff.c
--- linux.vanilla/drivers/s390/block/dasd_ccwstuff.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_ccwstuff.c	Thu Jan  1 01:00:00 1970
@@ -1,546 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_ccwstuff.c
- * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
- */
-
-#include <linux/stddef.h>
-#include <linux/kernel.h>
-#include <linux/malloc.h>
-#include <asm/spinlock.h>
-#include <linux/dasd.h>
-#include <asm/atomic.h>
-
-#include "dasd_types.h"
-
-#define PRINTK_HEADER "dasd_ccw:"
-#define MAX_CP_POWER 9		/* Maximum allowed index */
-#define CP_PER_PAGE_POWER 9	/* Maximum index, fitting on page */
-
-#define get_free_pages __get_free_pages
-
-/* Stuff for the handling task_list */
-dasd_chanq_t *cq_head = NULL;	/* head of task_list */
-atomic_t chanq_tasks;
-
-/* Array of freelists for the channel programs' -space */
-static ccw1_t *ccwarea[CP_PER_PAGE_POWER + 1] =
-{NULL,};
-
-/* array of pages retrieved for internal use */
-#define MAX_DASD_PAGES 64
-static int dasd_page_count = 0;
-static long dasd_page[MAX_DASD_PAGES];
-
-#ifdef __SMP__
-static spinlock_t ccw_lock=SPIN_LOCK_UNLOCKED;	/* spinlock for ccwareas */
-static spinlock_t cq_lock=SPIN_LOCK_UNLOCKED;	/* spinlock for cq_head */
-#endif				/* __SMP__ */
-
-void
-ccwarea_enq (int index, ccw1_t * area)
-{
-	FUNCTION_ENTRY ("ccwarea_enq");
-#if DASD_PARANOIA > 2
-	if (!area) {
-		INTERNAL_CHECK ("zero area %s\n", "");
-	}
-	if (index > CP_PER_PAGE_POWER) {
-		INTERNAL_CHECK ("index too large %d\n", index);
-	}
-#endif
-	*(ccw1_t **) area = ccwarea[index];
-	ccwarea[index] = area;
-	FUNCTION_EXIT ("ccwarea_enq");
-	return;
-}
-
-ccw1_t *
-ccwarea_deq (int index)
-{
-	ccw1_t *cp;
-	FUNCTION_ENTRY ("ccwarea_deq");
-#if DASD_PARANOIA > 2
-	if (index > CP_PER_PAGE_POWER) {
-		INTERNAL_CHECK ("index too large %d\n", index);
-	}
-#endif
-	cp = ccwarea[index];
-	ccwarea[index] = *(ccw1_t **) ccwarea[index];
-#if DASD_PARANOIA > 2
-	if (!cp) {
-		INTERNAL_CHECK ("returning NULL %s\n", "");
-	}
-#endif
-	FUNCTION_EXIT ("ccwarea_deq");
-	return cp;
-}
-
-ccw1_t *
-request_cpa (int index)
-{
-	ccw1_t *freeblk;
-	FUNCTION_ENTRY ("request_cpa");
-	if (index > MAX_CP_POWER) {
-		INTERNAL_ERROR ("index too large %d\n", index);
-		freeblk = NULL;
-		goto exit;
-	}
-	if (index > CP_PER_PAGE_POWER) {
-		int pc = 1 << (index - CP_PER_PAGE_POWER);
-		do {
-			freeblk = (ccw1_t *) get_free_pages (GFP_ATOMIC, index - CP_PER_PAGE_POWER);
-			if (dasd_page_count + pc >= MAX_DASD_PAGES) {
-				PRINT_WARN ("Requesting too many pages...");
-			} else {
-				int i;
-				for (i = 0; i < pc; i++)
-					dasd_page[dasd_page_count++] =
-						(long) freeblk + i * PAGE_SIZE;
-			}
-			FUNCTION_CONTROL ("requesting index %d", index);
-			if ( ! freeblk ) {
-				panic ("No memory received\n");
-			}
-		} while (!freeblk);
-		memset(freeblk,0,PAGE_SIZE<<(index-CP_PER_PAGE_POWER));
-		goto exit;
-	}
-	while (ccwarea[index] == NULL) {
-		ccw1_t *blk;
-		if (index == CP_PER_PAGE_POWER) {
-			do {
-				blk = (ccw1_t *) get_free_page (GFP_ATOMIC);
-				if (dasd_page_count + 1 >= MAX_DASD_PAGES) {
-					PRINT_WARN ("Requesting too many pages...");
-				} else {
-					dasd_page[dasd_page_count++] =
-						(long) blk;
-				}
-				if (blk == NULL) {
-					PRINT_WARN ("Can't allocate page!\n");
-				}
-			} while ( ! blk );
-			memset(blk,0,PAGE_SIZE);
-			ccwarea_enq (CP_PER_PAGE_POWER, blk);
-			continue;
-		}
-		blk = request_cpa (index + 1);
-#if DASD_PARANOIA > 1
-		if (!blk) {
-			PRINT_WARN ("retrieved NULL");
-		}
-#endif				/* DASD_PARANOIA */
-		ccwarea_enq (index, blk);
-		ccwarea_enq (index, blk + (1 << index));
-	}
-#if DASD_PARANOIA > 2
-	if (!ccwarea[index]) {
-		INTERNAL_ERROR ("ccwarea is NULL\n%s", "");
-	}
-#endif				/* DASD_PARANOIA */
-
-	freeblk = ccwarea_deq (index);
-#if DASD_PARANOIA > 1
-	if (!freeblk) {
-		INTERNAL_ERROR ("freeblk is NULL\n%s", "");
-	}
-#endif				/* DASD_PARANOIA */
-      exit:
-	return freeblk;
-}
-
-ccw1_t *
-request_cp (int size)
-{
-	ccw1_t *freeblk;
-	int index;
-	int blksize;
-	/* Determine the index of ccwarea to look at */
-	for (index = 0, blksize = 1;
-	     size > blksize;
-	     index++, blksize = blksize << 1) {
-	}
-	if (index > MAX_CP_POWER) {
-		INTERNAL_ERROR ("index too large %d\n", index);
-	}
-	spin_lock (&ccw_lock);
-	freeblk = request_cpa (index);
-	spin_unlock (&ccw_lock);
-	if (freeblk == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER
-			"No way to deliver free ccw space\n");
-	}
-	return freeblk;
-}
-
-void
-release_cp (int size, ccw1_t * area)
-{
-	int index;
-	int blksize;
-	/* Determine the index of ccwarea to look at */
-	for (index = 0, blksize = 1;
-	     size > blksize;
-	     index++, blksize = blksize << 1) {
-	}
-	if (index > MAX_CP_POWER) {
-		INTERNAL_ERROR ("index too large %d\n", index);
-	} else if (index > CP_PER_PAGE_POWER) {
-		free_pages ((unsigned long) area,
-			    index - CP_PER_PAGE_POWER);
-		INTERNAL_CHECK ("large index used: %d\n", index);
-	} else {
-		spin_lock (&ccw_lock);
-		ccwarea_enq (index, area);
-		spin_unlock (&ccw_lock);
-	}
-	return;
-}
-
-/* ---------------------------------------------------------- */
-
-static cqr_t *cqrp = NULL;
-#ifdef __SMP__
-static spinlock_t cqr_lock=SPIN_LOCK_UNLOCKED;
-#endif				/* __SMP__ */
-
-void
-cqf_enq (cqr_t * cqf)
-{
-	*(cqr_t **) cqf = cqrp;
-	cqrp = cqf;
-}
-
-cqr_t *
-cqf_deq (void)
-{
-	cqr_t *cqr = cqrp;
-	cqrp = *(cqr_t **) cqrp;
-	return cqr;
-}
-
-cqr_t *
-request_cq (void)
-{
-	cqr_t *cqr = NULL;
-	int i;
-	cqr_t *area;
-
-	spin_lock (&cqr_lock);
-	while (cqrp == NULL) {
-		do {
-			area = (cqr_t *) get_free_page (GFP_ATOMIC);
-			if (area == NULL) {
-				printk (KERN_WARNING PRINTK_HEADER
-					"No memory for chanq area\n");
-			}
-		} while ( ! area );
-		memset(area,0,PAGE_SIZE);
-		if (dasd_page_count + 1 >= MAX_DASD_PAGES) {
-			PRINT_WARN ("Requesting too many pages...");
-		} else {
-			dasd_page[dasd_page_count++] =
-				(long) area;
-		}
-		for (i = 0; i < 4096 / sizeof (cqr_t); i++) {
-				cqf_enq (area + i);
-		}
-	}
-	cqr = cqf_deq ();
-	spin_unlock (&cqr_lock);
-	return cqr;
-}
-
-void
-release_cq (cqr_t * cqr)
-{
-	spin_lock (&cqr_lock);
-	cqf_enq (cqr);
-	spin_unlock (&cqr_lock);
-	return;
-}
-
-/* ---------------------------------------------------------- */
-
-static erp_t *erpp = NULL;
-#ifdef __SMP__
-static spinlock_t erp_lock = SPIN_LOCK_UNLOCKED;
-#endif				/* __SMP__ */
-
-void
-erf_enq (erp_t * cqf)
-{
-	*(erp_t **) cqf = erpp;
-	erpp = cqf;
-}
-
-erp_t *
-erf_deq (void)
-{
-	erp_t *erp = erpp;
-	erpp = *(erp_t **) erpp;
-	return erp;
-}
-
-erp_t *
-request_er (void)
-{
-	erp_t *erp = NULL;
-	int i;
-	erp_t *area;
-
-	spin_lock (&erp_lock);
-	while (erpp == NULL) {
-		do {
-			area = (erp_t *) get_free_page (GFP_ATOMIC);
-			if (area == NULL) {
-				printk (KERN_WARNING PRINTK_HEADER
-					"No memory for chanq area\n");
-			}
-		} while (!area);
-		memset (area, 0, PAGE_SIZE);
-		if (dasd_page_count + 1 >= MAX_DASD_PAGES) {
-			PRINT_WARN ("Requesting too many pages...");
-		} else {
-			dasd_page[dasd_page_count++] =
-			    (long) area;
-		}
-		for (i = 0; i < 4096 / sizeof (erp_t); i++) {
-			erf_enq (area + i);
-		}
-	}
-	erp = erf_deq ();
-	spin_unlock (&erp_lock);
-	return erp;
-}
-
-void
-release_er (erp_t * erp)
-{
-	spin_lock (&erp_lock);
-	erf_enq (erp);
-	spin_unlock (&erp_lock);
-	return;
-}
-
-/* ----------------------------------------------------------- */
-cqr_t *
-request_cqr (int cpsize, int datasize)
-{
-	cqr_t *cqr = NULL;
-	cqr = request_cq ();
-	if (cqr == NULL) {
-		printk (KERN_WARNING PRINTK_HEADER __FILE__
-			"No memory for chanq request\n");
-		goto exit;
-	}
-	memset (cqr, 0, sizeof (cqr_t));
-	cqr -> magic = DASD_MAGIC;
-	if (cpsize) {
-		cqr->cpaddr = request_cp (cpsize);
-		if (cqr->cpaddr == NULL) {
-			printk (KERN_WARNING PRINTK_HEADER __FILE__
-				"No memory for channel program\n");
-			goto nocp;
-		}
-		cqr->cplength = cpsize;
-	}
-	if (datasize) {
-		do {
-			cqr->data = (char *) kmalloc (datasize, GFP_ATOMIC);
-			if (cqr->data == NULL) {
-				printk (KERN_WARNING PRINTK_HEADER __FILE__
-					"No memory for cqr data area\n");
-			}
-		} while (!cqr->data);
-		memset (cqr->data,0,datasize);
-	}
-	goto exit;
-      nocp:
-	release_cq (cqr);
-	cqr = NULL;
-      exit:
-	return cqr;
-}
-
-int
-release_cqr (cqr_t * cqr)
-{
-	int rc = 0;
-	if (cqr == NULL) {
-		rc = -ENOENT;
-		return rc;
-	}
-	if (cqr->data) {
-		kfree (cqr->data);
-	}
-	if (cqr->dstat) {
-		kfree (cqr->dstat);
-	}
-	if (cqr->cpaddr) {
-		release_cp (cqr->cplength, cqr->cpaddr);
-	}
-	cqr -> magic = dasd_MAGIC;
-	release_cq (cqr);
-	return rc;
-}
-
-/* ----------------------------------------------------------- */
-erp_t *
-allloc_erp (erp_t * erp, int cpsize, int datasize)
-{
-	if (cpsize) {
-		erp->cqr.cpaddr = request_cp (cpsize);
-		if (erp->cqr.cpaddr == NULL) {
-			printk (KERN_WARNING PRINTK_HEADER __FILE__
-				"No memory for channel program\n");
-			goto nocp;
-		}
-		erp->cqr.cplength = cpsize;
-	}
-	if (datasize) {
-		do {
-			erp->cqr.data = (char *) kmalloc (datasize, GFP_ATOMIC);
-			if (erp->cqr.data == NULL) {
-				printk (KERN_WARNING PRINTK_HEADER __FILE__
-					"No memory for ERP data area\n");
-			}
-		} while (!erp->cqr.data);
-		memset (erp->cqr.data, 0, datasize);
-	}
-	goto exit;
-      nocp:
-	release_er (erp);
-	erp = NULL;
-      exit:
-	return erp;
-}
-
-int
-release_erp (erp_t * erp)
-{
-	int rc = 0;
-	if (erp == NULL) {
-		rc = -ENOENT;
-		return rc;
-	}
-	if (erp->cqr.data) {
-		kfree (erp->cqr.data);
-	}
-	if (erp->cqr.dstat) {
-		kfree (erp->cqr.dstat);
-	}
-	if (erp->cqr.cpaddr) {
-		release_cp (erp->cqr.cplength, erp->cqr.cpaddr);
-	}
-	erp->cqr.magic = dasd_MAGIC;
-	release_er (erp);
-	return rc;
-}
-
-/* -------------------------------------------------------------- */
-void
-dasd_chanq_enq (dasd_chanq_t * q, cqr_t * cqr)
-{
-	if (q->head != NULL) {
-		q->tail->next = cqr;
-	} else
-		q->head = cqr;
-	cqr->next = NULL;
-	q->tail = cqr;
-	q->queued_requests ++;
-	ACS (cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
-	}
-
-void
-dasd_chanq_enq_head (dasd_chanq_t * q, cqr_t * cqr)
-{
-	cqr->next = q->head;
-	q->head = cqr;
-	if (q->tail == NULL)
-		q->tail = cqr;
-	q->queued_requests++;
-	ACS (cqr->status, CQR_STATUS_FILLED, CQR_STATUS_QUEUED);
-}
-
-int
-dasd_chanq_deq (dasd_chanq_t * q, cqr_t * cqr)
-{
-	cqr_t *prev;
-
-	if (cqr == NULL)
-		return -ENOENT;
-	if (cqr == (cqr_t *) q->head) {
-		q->head = cqr->next;
-		if (q->head == NULL)
-			q->tail = NULL;
-	} else {
-		prev = (cqr_t *) q->head; 
-		while (prev && prev->next != cqr)
-			prev = prev->next;
-		if (prev == NULL)
-			return -ENOENT;
-		prev->next = cqr->next;
-		if (prev->next == NULL)
-			q->tail = prev;
-	}
-	cqr->next = NULL;
-	q->queued_requests --;
-	if (cqr->magic == ERP_MAGIC)
-		return release_erp ((erp_t *) cqr);
-	else
-	return release_cqr(cqr);
-}
-
-/* -------------------------------------------------------------------------- */
-void
-cql_enq_head (dasd_chanq_t * q)
-{
-	if (q == NULL) {
-		INTERNAL_ERROR ("NULL queue passed%s\n", "");
-		return;
-	}
-	if (atomic_read(&q->flags) & DASD_CHANQ_ACTIVE) {
-		PRINT_WARN("Queue already active");
-		return;
-	}
-	spin_lock(&cq_lock);
-	atomic_set_mask(DASD_CHANQ_ACTIVE,&q->flags);
-	q->next_q = cq_head;
-	cq_head = q;
-	spin_unlock(&cq_lock);
-}
-
-void
-cql_deq (dasd_chanq_t * q)
-{
-	dasd_chanq_t *c;
-
-        if (cq_head == NULL) {
-                INTERNAL_ERROR ("Channel queue is empty%s\n", "");
-		return;
-	}
-	if (q == NULL) {
-		INTERNAL_ERROR ("NULL queue passed%s\n", "");
-		return;
-	}
-	spin_lock(&cq_lock);
-	if (! (atomic_read(&q->flags) & DASD_CHANQ_ACTIVE)) {
-		PRINT_WARN("Queue not active\n");
-	} else if (cq_head == q) {
-		cq_head = q->next_q;
-	} else {
-		c = cq_head;
-		while (c->next_q && c->next_q != q)
-			c = c->next_q;
-		if (c->next_q != q)
-			INTERNAL_ERROR ("Entry not in queue%s\n", "");
-		else
-			c->next_q = q->next_q;
-	}
-	q->next_q = NULL;
-	atomic_clear_mask(DASD_CHANQ_ACTIVE,&q->flags);
-	spin_unlock(&cq_lock);
-}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_ccwstuff.h linux.17p18/drivers/s390/block/dasd_ccwstuff.h
--- linux.vanilla/drivers/s390/block/dasd_ccwstuff.h	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_ccwstuff.h	Thu Jan  1 01:00:00 1970
@@ -1,11 +0,0 @@
-extern atomic_t chanq_tasks;
-extern dasd_chanq_t *cq_head;
-
-cqr_t *request_cqr (int, int);
-int release_cqr (cqr_t *);
-erp_t *request_er (void);
-int release_er (erp_t *);
-int dasd_chanq_enq (dasd_chanq_t *, cqr_t *);
-int dasd_chanq_deq (dasd_chanq_t *, cqr_t *);
-void cql_enq_head (dasd_chanq_t * q);
-void cql_deq (dasd_chanq_t * q);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_diag.c linux.17p18/drivers/s390/block/dasd_diag.c
--- linux.vanilla/drivers/s390/block/dasd_diag.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd_diag.c	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,555 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_diag.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Based on.......: linux/drivers/s390/block/mdisk.c
+ * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ */
+
+#include <linux/stddef.h>
+#include <linux/kernel.h>
+#include <asm/debug.h>
+
+#include <linux/malloc.h>
+#include <linux/hdreg.h>	/* HDIO_GETGEO                      */
+#include <linux/blk.h>
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
+
+#include <asm/ebcdic.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "dasd.h"
+#include "dasd_diag.h"
+
+
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
+#endif				/* PRINTK_HEADER */
+#define PRINTK_HEADER DASD_NAME"(diag):"
+
+dasd_discipline_t dasd_diag_discipline;
+
+
+
+typedef struct
+dasd_diag_private_t {
+        dasd_diag_characteristics_t rdc_data;
+	diag_rw_io_t iob;
+	diag_init_io_t iib;
+	unsigned long *label;
+} dasd_diag_private_t;
+
+static __inline__ int
+dia210 (void *devchar)
+{
+	int rc;
+
+	__asm__ __volatile__ ("    lr    2,%1\n"
+                              "    .long 0x83200210\n"
+                              "0:  ipm   %0\n"
+                              "    srl   %0,28"
+                              :"=d" (rc)
+                              :"d" ((void *) __pa (devchar))
+                              :"2");
+	return rc;
+}
+
+static __inline__ int
+dia250 (void *iob, int cmd)
+{
+	int rc;
+
+	__asm__ __volatile__ ("    lr    2,%1\n"
+                              "    lr    3,%2\n"
+                              "    .long 0x83230250\n"
+                              "    lr    %0,3"
+                              :"=d" (rc)
+                              :"d" ((void *) __pa (iob)), "d" (cmd)
+                              :"2", "3");
+	return rc;
+}
+
+static __inline__ int
+mdsk_init_io (dasd_device_t *device, int blocksize, int offset, int size)
+{
+        dasd_diag_private_t *private = (dasd_diag_private_t *)device->private;
+	diag_init_io_t *iib = &private->iib;
+	int rc;
+
+	memset (iib, 0, sizeof (diag_init_io_t));
+
+	iib->dev_nr = device->devinfo.devno;
+	iib->block_size = blocksize;
+	iib->offset = offset;
+	iib->start_block = 0;
+	iib->end_block = size;
+
+	rc = dia250 (iib, INIT_BIO);
+
+	return rc;
+}
+
+static __inline__ int
+mdsk_term_io (dasd_device_t *device)
+{
+        dasd_diag_private_t *private = (dasd_diag_private_t *)device->private;
+	diag_init_io_t *iib = &private->iib;
+	int rc;
+	
+	memset (iib, 0, sizeof (diag_init_io_t));
+	iib->dev_nr = device->devinfo.devno;
+	rc = dia250 (iib, TERM_BIO);
+	return rc;
+}
+
+int
+dasd_start_diag (ccw_req_t * cqr)
+{
+	int rc;
+	dasd_device_t *device = cqr->device;
+        dasd_diag_private_t *private;
+	diag_rw_io_t *iob;
+
+        private = (dasd_diag_private_t *)device->private;
+	iob = &private->iob;
+
+	iob->dev_nr = device->devinfo.devno;
+	iob->key = 0;
+	iob->flags = 2;
+	iob->block_count = cqr->cplength >> 1;
+	iob->interrupt_params = (u32) cqr;
+	iob->bio_list = __pa (cqr->cpaddr);
+
+	asm volatile ("STCK %0":"=m" (cqr->startclk));
+	rc = dia250 (iob, RW_BIO);
+	if (rc > 8) {
+		PRINT_WARN ("dia250 returned CC %d\n", rc);
+		atomic_compare_and_swap_debug(&cqr->status, 
+                                              CQR_STATUS_QUEUED, 
+                                              CQR_STATUS_ERROR);
+	} else {
+		if ( cqr->expires ) {
+			cqr->expires += cqr->startclk;
+		}
+		atomic_compare_and_swap_debug(&cqr->status, 
+                                              CQR_STATUS_QUEUED, 
+                                              CQR_STATUS_IN_IO);
+                rc = 0;
+	}
+	return rc;
+}
+
+void 
+dasd_ext_handler (struct pt_regs *regs, __u16 code)
+{
+	ccw_req_t *cqr;
+	int ip = S390_lowcore.ext_params;
+	char status = *((char *) S390_lowcore.ext_params + 5);
+        dasd_device_t *device;
+	int done_fast_io = 0;
+        int devno,devindex;
+
+	if (!ip) {		/* no intparm: unsolicited interrupt */
+		printk ( KERN_WARNING PRINTK_HEADER
+			 "caught unsolicited interrupt\n");
+		return;
+	}
+	if (ip & 0x80000001) {
+		printk ( KERN_WARNING PRINTK_HEADER
+			 "caught spurious interrupt with parm %08x\n",
+			 ip);
+		return;
+	}
+	cqr = (ccw_req_t *) ip;
+	device = (dasd_device_t *) cqr->device;
+	devno = device->devinfo.devno;
+	devindex = devindex_from_devno (devno);
+	if (device == NULL) {
+		printk (KERN_WARNING PRINTK_HEADER
+			" INT on devno 0x%04X  = /dev/%s (%d:%d)"
+			" belongs to NULL device\n",
+			devno, device->name, major_from_devindex (devindex), devindex << DASD_PARTN_BITS);
+	}
+	if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {
+		printk (KERN_WARNING PRINTK_HEADER
+			"0x%04X : /dev/%s (%d:%d)"
+			" magic number of ccw_req_t 0x%08lX doesn't match"
+			" discipline 0x%08X\n",
+			devno, device->name,
+			major_from_devindex (devindex),
+			devindex << DASD_PARTN_BITS,
+			cqr->magic, *(int *) (&device->discipline->name));
+		return;
+	}
+	asm volatile ("STCK %0":"=m" (cqr->stopclk));
+	switch (status) {
+	case 0x00:
+		atomic_compare_and_swap_debug (&cqr->status, 
+					       CQR_STATUS_IN_IO, 
+					       CQR_STATUS_DONE);
+		atomic_compare_and_swap (DASD_DEVICE_LEVEL_ANALYSIS_PENDING,
+					 DASD_DEVICE_LEVEL_ANALYSIS_PREPARED,
+					 &device->level);
+		if (cqr->next &&
+		    (atomic_read (&cqr->next->status) ==
+		     CQR_STATUS_QUEUED)) {
+			if (dasd_start_diag (cqr->next) == 0) {
+				done_fast_io = 1;
+			}
+		}
+
+		break;
+	case 0x01:
+	case 0x02:
+	case 0x03:
+	default:
+		atomic_compare_and_swap_debug (&cqr->status, 
+					       CQR_STATUS_IN_IO, 
+					       CQR_STATUS_FAILED);
+		atomic_inc (&device->queue.dirty_requests);
+		break;
+	}
+	if (done_fast_io == 0)
+		atomic_clear_mask (DASD_CHANQ_BUSY, &device->queue.flags);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        wake_up (&device->wait_q);
+#else
+	if (device->wait_q) {
+		wake_up (&device->wait_q);
+	}
+#endif /* LINUX_VERSION_CODE */
+	dasd_schedule_bh ();
+}
+
+static int
+dasd_diag_check_characteristics (struct dasd_device_t *device)
+{
+	int rc = 0;
+	int bsize;
+	int label_block;
+        dasd_diag_private_t *private;
+	dasd_diag_characteristics_t *rdc_data;
+        ccw_req_t *cqr;
+	long *label;
+        int sb;
+
+        if ( device == NULL ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "Null device pointer passed to characteristics checker\n");
+                return -ENODEV;
+        }
+        if ( device->private == NULL ) {
+		device->private = kmalloc(sizeof(dasd_diag_private_t),GFP_KERNEL);
+		if ( device->private == NULL ) {
+			printk ( KERN_WARNING PRINTK_HEADER
+				 "memory allocation failed for private data\n");
+			return -ENOMEM;
+		}
+        }
+        private = (dasd_diag_private_t *)device->private;
+        rdc_data = (void *)&(private->rdc_data);
+	
+	rdc_data->dev_nr = device->devinfo.devno;
+	rdc_data->rdc_len = sizeof (dasd_diag_characteristics_t);
+	
+	if (dia210 (rdc_data) != 0) {
+	  return -ENODEV;
+	}
+	if (rdc_data->vdev_class != DEV_CLASS_FBA &&
+	    rdc_data->vdev_class != DEV_CLASS_ECKD &&
+	    rdc_data->vdev_class != DEV_CLASS_CKD) {
+		return -ENODEV;
+	}
+#if 0
+	printk ( KERN_INFO PRINTK_HEADER 
+		 "%04X: %04X on real %04X/%02X\n",
+		 rdc_data->dev_nr,
+		 rdc_data->vdev_type,
+		 rdc_data->rdev_type,rdc_data->rdev_model);
+#endif
+	/* Figure out position of label block */
+	if (private->rdc_data.vdev_class == DEV_CLASS_FBA) {
+		label_block = 1;
+	} else if (private->rdc_data.vdev_class == DEV_CLASS_ECKD ||
+		   private->rdc_data.vdev_class == DEV_CLASS_CKD) {
+		label_block = 2;
+	} else {
+		return -ENODEV;
+	}
+	private->label = (long *) get_free_page (GFP_KERNEL);
+        label = private->label;	
+	mdsk_term_io (device); /* first terminate all outstanding operations */
+	/* figure out blocksize of device */
+	for (bsize = 512; bsize <= PAGE_SIZE; bsize <<= 1) {
+                diag_bio_t *bio;
+                diag_rw_io_t *iob = &private ->iob;
+        
+                rc = mdsk_init_io (device, bsize, 0, 64);
+                if (rc > 4) {
+                        continue;
+		}
+                cqr = ccw_alloc_request (dasd_diag_discipline.name, 2,0);
+                if ( cqr == NULL ) {
+                        printk ( KERN_WARNING PRINTK_HEADER
+                                 "No memory to allocate initialization request\n");
+                        return -ENOMEM;
+                }
+                bio = (diag_bio_t *) (cqr->cpaddr);
+                memset (bio, 0, sizeof (diag_bio_t));
+                bio->type = MDSK_READ_REQ;
+                bio->block_number = label_block + 1;
+                bio->buffer = __pa (private->label);
+                cqr->device = device;
+                atomic_set (&cqr->status, CQR_STATUS_FILLED);
+                memset (iob, 0, sizeof(diag_rw_io_t));
+                iob->dev_nr      = rdc_data->dev_nr;
+                iob->key         = 0;
+                iob->flags       = 0;
+                iob->block_count = 1;
+                iob->interrupt_params = cqr;
+                iob->bio_list     = virt_to_phys(bio);
+                rc = dia250(iob,RW_BIO);
+                if ( rc == 0 ) {
+                        if (label[3] != bsize) {
+/*                                printk ( KERN_INFO PRINTK_HEADER 
+                                         "%04X mismatching blocksizes disk %d, reserved file %d\n", 
+                                         device->devinfo.devno, bsize, label[3]);
+*/  
+                              return -EINVAL; 
+                        }
+                        if (label[0] != 0xc3d4e2f1) {	/* CMS1 */
+/*                                PRINT_WARN ("volume %04X is not CMS formatted, accessing anyway\n", 
+                                            device->devinfo.devno);
+*/
+                                return -ENODEV;
+                        }
+                        if (label[13] == 0) {
+/*                                PRINT_WARN ("%04X is not reserved, accessing anyway\n",  
+                                  device->devinfo.devno); */
+                                return -ENODEV;
+                        }
+                        
+                        break;
+                }
+		mdsk_term_io (device);
+	}
+	device->sizes.bp_block = bsize;
+        device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
+	for (sb = 512; sb < bsize; sb = sb << 1)
+		device->sizes.s2b_shift++;
+
+	return rc;
+}
+
+
+static int
+dasd_diag_do_analysis (struct dasd_device_t *device)
+{
+	int sb;
+        dasd_diag_private_t *private = (dasd_diag_private_t *)device->private;
+
+	long *label = private->label;
+	
+	/* real size of the volume */
+        device->sizes.blocks = label[7];
+	
+        printk ( KERN_INFO PRINTK_HEADER 
+                 "/dev/%s (%04X): capacity (%dkB blks): %dkB\n",
+                 device->name, device->devinfo.devno,
+                 (device->sizes.bp_block>>10),
+		 (device->sizes.blocks<<device->sizes.s2b_shift)>>1);
+	return 0;
+}
+
+
+static int
+dasd_diag_fill_geometry(struct dasd_device_t *device, struct hd_geometry *geo)
+{
+        int rc = 0;
+        dasd_diag_private_t *private = (dasd_diag_private_t *)device->private;
+	unsigned long sectors = device->sizes.blocks << device->sizes.s2b_shift;
+	unsigned long tracks = sectors >> 6;
+	unsigned long trk_rem = sectors & ((1<<6)-1); /* 64k per track */
+	unsigned long cyls = tracks >> 4;
+	unsigned long cyls_rem = tracks & ((1<<4)-1); /* 16 head per cyl */
+	
+        switch(device->sizes.bp_block) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+                break;
+        default:
+                return -EINVAL;
+        }
+	geo->cylinders = cyls;
+	geo->heads = 16;
+	geo->sectors = 128 >> device->sizes.s2b_shift;
+	if (private->rdc_data.vdev_class == DEV_CLASS_FBA) {
+		geo->start = 1;
+	} else if (private->rdc_data.vdev_class == DEV_CLASS_ECKD ||
+		   private->rdc_data.vdev_class == DEV_CLASS_CKD) {
+		geo->start = 2;
+	} else {
+		return -EINVAL;
+	}
+        return rc;
+}
+
+static dasd_era_t
+dasd_diag_examine_error  (ccw_req_t *cqr, devstat_t * stat)
+{
+	return dasd_era_fatal;
+}
+
+static dasd_erp_action_fn_t 
+dasd_diag_erp_action ( ccw_req_t * cqr ) 
+{
+        return default_erp_action;
+}
+
+static dasd_erp_postaction_fn_t
+dasd_diag_erp_postaction (ccw_req_t * cqr)
+{
+        if ( cqr -> function == default_erp_action)
+                return default_erp_postaction;
+        printk ( KERN_WARNING PRINTK_HEADER
+                 "unknown ERP action %p\n",
+                 cqr -> function);
+	return NULL;
+}
+
+static ccw_req_t *
+dasd_diag_build_cp_from_req (dasd_device_t *device, struct request *req)
+{
+	ccw_req_t *rw_cp = NULL;
+	struct buffer_head *bh;
+	int rw_cmd;
+	int noblk = req->nr_sectors >> device->sizes.s2b_shift;
+	int byt_per_blk = device->sizes.bp_block;
+	int block;
+	diag_bio_t *bio;
+	int bhct;
+	long size;
+
+	if (!noblk) {
+		PRINT_ERR ("No blocks to read/write...returning\n");
+		return NULL;
+	}
+	if (req->cmd == READ) {
+		rw_cmd = MDSK_READ_REQ;
+	} else
+	if (req->cmd == WRITE)
+	{
+		rw_cmd = MDSK_WRITE_REQ;
+	}
+	bhct = 0;
+	for (bh = req->bh; bh; bh = bh->b_reqnext) {
+		if (bh->b_size > byt_per_blk)
+			for (size = 0; size < bh->b_size; size += byt_per_blk)
+				bhct++;
+		else
+			bhct++;
+	}
+	/* Build the request */
+        rw_cp = dasd_alloc_request (dasd_diag_discipline.name, 2 * bhct, 0);
+	if (!rw_cp) {
+		return NULL;
+	}
+	bio = (diag_bio_t *) (rw_cp->cpaddr);
+	
+	block = req->sector >> device->sizes.s2b_shift;
+	for (bh = req->bh; bh; bh = bh->b_reqnext) {
+		if (bh->b_size >= byt_per_blk) {
+			memset (bio, 0, sizeof (diag_bio_t));
+			for (size = 0; size < bh->b_size; size += byt_per_blk) {
+				bio->type = rw_cmd;
+				bio->block_number = block + 1;
+				bio->buffer = __pa (bh->b_data + size);
+				bio++;
+				block++;
+			}
+		} else {
+			PRINT_WARN ("Cannot fulfill request smaller than block\n");
+			ccw_free_request (rw_cp);
+			return NULL;
+		}
+	}
+        rw_cp->device = device;
+        rw_cp->expires = 5 * 0xf424000; /* 5 seconds */
+        rw_cp->req = req;
+        atomic_compare_and_swap_debug(&rw_cp->status,CQR_STATUS_EMPTY,CQR_STATUS_FILLED);
+	return rw_cp;
+}
+
+static char *
+dasd_diag_dump_sense(struct dasd_device_t *device, ccw_req_t *req)
+{
+        char *page = (char *)get_free_page(GFP_KERNEL);
+        int len;
+        if ( page == NULL ) {
+                return NULL;
+        }
+
+        len = sprintf ( page, KERN_WARNING PRINTK_HEADER 
+                        "device %04X on irq %d: I/O status report:\n",
+                        device->devinfo.devno,device->devinfo.irq);
+                        
+
+        return page;
+}
+
+dasd_discipline_t dasd_diag_discipline = {
+	name :                          "DIAG",
+	ebcname :                       "DIAG",
+        check_characteristics:          dasd_diag_check_characteristics,
+        do_analysis:                    dasd_diag_do_analysis,          
+        fill_geometry:                  dasd_diag_fill_geometry,
+        start_IO:                       dasd_start_diag,           
+        examine_error:                  dasd_diag_examine_error,          
+        erp_action:                     dasd_diag_erp_action,             
+        erp_postaction:                 dasd_diag_erp_postaction,         
+        build_cp_from_req:              dasd_diag_build_cp_from_req,      
+        dump_sense:                     dasd_diag_dump_sense,            
+        int_handler:                    dasd_ext_handler            
+};
+
+int
+dasd_diag_init( void ) {
+        int rc = 0;
+        if ( MACHINE_IS_VM ) {
+          printk ( KERN_INFO PRINTK_HEADER
+                   "%s discipline initializing\n", dasd_diag_discipline.name);
+          ASCEBC(dasd_diag_discipline.ebcname,4);
+          ctl_set_bit (0, 9);
+          register_external_interrupt (0x2603, dasd_ext_handler);
+          dasd_discipline_enq(&dasd_diag_discipline);
+        } else {
+          printk ( KERN_INFO PRINTK_HEADER
+                   "Machine is not VM: %s discipline not initializing\n", dasd_diag_discipline.name);
+          rc = -EINVAL;
+        }
+        return rc;
+}
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_diag.h linux.17p18/drivers/s390/block/dasd_diag.h
--- linux.vanilla/drivers/s390/block/dasd_diag.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd_diag.h	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,67 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_diag.h
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Based on.......: linux/drivers/s390/block/mdisk.h
+ * ...............: by Hartmunt Penner <hpenner@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ */
+
+#define MDSK_WRITE_REQ 0x01
+#define MDSK_READ_REQ  0x02
+
+#define INIT_BIO        0x00
+#define RW_BIO          0x01
+#define TERM_BIO        0x02
+
+#define DEV_CLASS_FBA   0x01
+#define DEV_CLASS_ECKD  0x04
+#define DEV_CLASS_CKD   0x04	
+
+typedef struct dasd_diag_characteristics_t {
+	u16 dev_nr;
+	u16 rdc_len;
+	u8 vdev_class;
+	u8 vdev_type;
+	u8 vdev_status;
+	u8 vdev_flags;
+	u8 rdev_class;
+	u8 rdev_type;
+	u8 rdev_model;
+	u8 rdev_features;
+} __attribute__ ((packed, aligned (4))) dasd_diag_characteristics_t;
+
+typedef struct diag_bio_t {
+	u8 type;
+	u8 status;
+	u16 spare1;
+	u32 block_number;
+	u32 alet;
+	u32 buffer;
+} __attribute__ ((packed, aligned (8))) diag_bio_t;
+
+typedef struct diag_init_io_t{
+	u16 dev_nr;
+	u16 spare1[11];
+	u32 block_size;
+	u32 offset;
+	u32 start_block;
+	u32 end_block;
+	u32 spare2[6];
+} __attribute__ ((packed, aligned (8))) diag_init_io_t;
+
+
+typedef struct diag_rw_io_t{
+	u16 dev_nr;
+	u16 spare1[11];
+	u8 key;
+	u8 flags;
+	u16 spare2;
+	u32 block_count;
+	u32 alet;
+	u32 bio_list;
+	u32 interrupt_params;
+	u32 spare3[5];
+} __attribute__ ((packed, aligned (8))) diag_rw_io_t;
+
+int dasd_diag_init(void);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_eckd.c linux.17p18/drivers/s390/block/dasd_eckd.c
--- linux.vanilla/drivers/s390/block/dasd_eckd.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_eckd.c	Tue Aug  1 07:59:49 2000
@@ -3,26 +3,33 @@
  * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
  * Bugreports.to..: <Linux390@de.ibm.com>
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+
+ * History of changes (starts July 2000)
+ * 07/11/00 Enabled rotational position sensing
  */
 
 #include <linux/stddef.h>
 #include <linux/kernel.h>
+#include <asm/debug.h>
 
 #include <linux/malloc.h>
-#include <linux/dasd.h>
 #include <linux/hdreg.h>	/* HDIO_GETGEO                      */
+#include <linux/blk.h>
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
 
+#include <asm/ebcdic.h>
 #include <asm/io.h>
-
 #include <asm/irq.h>
 
-#include "dasd_types.h"
-#include "dasd_ccwstuff.h"
+#include "dasd.h"
+#include "dasd_eckd.h"
+
 
 #ifdef PRINTK_HEADER
 #undef PRINTK_HEADER
 #endif				/* PRINTK_HEADER */
-#define PRINTK_HEADER "dasd(eckd):"
+#define PRINTK_HEADER DASD_NAME"(eckd):"
 
 #define ECKD_C0(i) (i->home_bytes)
 #define ECKD_F(i) (i -> formula)
@@ -35,255 +42,45 @@
 #define ECKD_F7(i) (i -> factor7)
 #define ECKD_F8(i) (i -> factor8)
 
-#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
-
-#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
+#define DASD_ECKD_CCW_WRITE 0x05
+#define DASD_ECKD_CCW_READ 0x06
 #define DASD_ECKD_CCW_WRITE_HOME_ADDRESS 0x09
-
-#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
-#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
-
+#define DASD_ECKD_CCW_READ_HOME_ADDRESS 0x0a
 #define DASD_ECKD_CCW_READ_COUNT 0x12
-#define DASD_ECKD_CCW_READ 0x06
-#define DASD_ECKD_CCW_READ_MT 0x86
-#define DASD_ECKD_CCW_WRITE 0x05
-#define DASD_ECKD_CCW_WRITE_MT 0x85
+#define DASD_ECKD_CCW_WRITE_RECORD_ZERO 0x15
+#define DASD_ECKD_CCW_READ_RECORD_ZERO 0x16
+#define DASD_ECKD_CCW_WRITE_CKD 0x1d
 #define DASD_ECKD_CCW_READ_CKD 0x1e
+#define DASD_ECKD_CCW_LOCATE_RECORD 0x47
+#define DASD_ECKD_CCW_DEFINE_EXTENT 0x63
+#define DASD_ECKD_CCW_WRITE_MT 0x85
+#define DASD_ECKD_CCW_READ_MT 0x86
 #define DASD_ECKD_CCW_READ_CKD_MT 0x9e
-#define DASD_ECKD_CCW_WRITE_CKD 0x1d
 #define DASD_ECKD_CCW_WRITE_CKD_MT 0x9d
 
-typedef
-struct {
-	__u16 cyl;
-	__u16 head;
-} __attribute__ ((packed))
-
-ch_t;
-
-typedef
-struct {
-	__u16 cyl;
-	__u16 head;
-	__u32 sector;
-} __attribute__ ((packed))
-
-chs_t;
-
-typedef
-struct {
-	__u16 cyl;
-	__u16 head;
-	__u8 record;
-} __attribute__ ((packed))
-
-chr_t;
-
-typedef
-struct {
-	__u16 cyl;
-	__u16 head;
-	__u32 sector;
-} geom_t;
-
-typedef struct {
-	struct {
-		struct {
-			unsigned char identifier:2;
-			unsigned char token_id:1;
-			unsigned char sno_valid:1;
-			unsigned char subst_sno:1;
-			unsigned char recNED:1;
-			unsigned char emuNED:1;
-			unsigned char reserved:1;
-		} __attribute__ ((packed)) flags;
-		__u8 descriptor;
-		__u8 dev_class;
-		__u8 reserved;
-		unsigned char dev_type[6];
-		unsigned char dev_model[3];
-		unsigned char HDA_manufacturer[3];
-		unsigned char HDA_location[2];
-		unsigned char HDA_seqno[12];
-		__u16 ID;
-	} __attribute__ ((packed)) ned1;
-	struct {
-		struct {
-			unsigned char identifier:2;
-			unsigned char token_id:1;
-			unsigned char sno_valid:1;
-			unsigned char subst_sno:1;
-			unsigned char recNED:1;
-			unsigned char emuNED:1;
-			unsigned char reserved:1;
-		} __attribute__ ((packed)) flags;
-		__u8 descriptor;
-		__u8 reserved[2];
-		unsigned char dev_type[6];
-		unsigned char dev_model[3];
-		unsigned char DASD_manufacturer[3];
-		unsigned char DASD_location[2];
-		unsigned char DASD_seqno[12];
-		__u16 ID;
-	} __attribute__ ((packed)) ned2;
-	struct {
-		struct {
-			unsigned char identifier:2;
-			unsigned char token_id:1;
-			unsigned char sno_valid:1;
-			unsigned char subst_sno:1;
-			unsigned char recNED:1;
-			unsigned char emuNED:1;
-			unsigned char reserved:1;
-		} __attribute__ ((packed)) flags;
-		__u8 descriptor;
-		__u8 reserved[2];
-		unsigned char cont_type[6];
-		unsigned char cont_model[3];
-		unsigned char cont_manufacturer[3];
-		unsigned char cont_location[2];
-		unsigned char cont_seqno[12];
-		__u16 ID;
-	} __attribute__ ((packed)) ned3;
-	struct {
-		struct {
-			unsigned char identifier:2;
-			unsigned char token_id:1;
-			unsigned char sno_valid:1;
-			unsigned char subst_sno:1;
-			unsigned char recNED:1;
-			unsigned char emuNED:1;
-			unsigned char reserved:1;
-		} __attribute__ ((packed)) flags;
-		__u8 descriptor;
-		__u8 reserved[2];
-		unsigned char cont_type[6];
-		unsigned char empty[3];
-		unsigned char cont_manufacturer[3];
-		unsigned char cont_location[2];
-		unsigned char cont_seqno[12];
-		__u16 ID;
-	} __attribute__ ((packed)) ned4;
-	unsigned char ned5[32];
-	unsigned char ned6[32];
-	unsigned char ned7[32];
-	struct {
-		struct {
-			unsigned char identifier:2;
-			unsigned char reserved:6;
-		} __attribute__ ((packed)) flags;
-		__u8 selector;
-		__u16 interfaceID;
-		__u32 reserved;
-		__u16 subsystemID;
-		struct {
-			unsigned char sp0:1;
-			unsigned char sp1:1;
-			unsigned char reserved:5;
-			unsigned char scluster:1;
-		} __attribute__ ((packed)) spathID;
-		__u8 unit_address;
-		__u8 dev_ID;
-		__u8 dev_address;
-		__u8 adapterID;
-		__u16 link_address;
-		struct {
-			unsigned char parallel:1;
-			unsigned char escon:1;
-			unsigned char reserved:1;
-			unsigned char ficon:1;
-			unsigned char reserved2:4;
-		} __attribute__ ((packed)) protocol_type;
-		struct {
-			unsigned char PID_in_236:1;
-			unsigned char reserved:7;
-		} __attribute__ ((packed)) format_flags;
-		__u8 log_dev_address;
-		unsigned char reserved2[12];
-	} __attribute__ ((packed)) neq;
-
-} __attribute__ ((packed))
-
-eckd_confdata_t;
-
-typedef
-struct {
-	struct {
-		unsigned char perm:2;	/* Permissions on this extent */
-		unsigned char reserved:1;
-		unsigned char seek:2;	/* Seek control */
-		unsigned char auth:2;	/* Access authorization */
-		unsigned char pci:1;	/* PCI Fetch mode */
-	} __attribute__ ((packed)) mask;
-	struct {
-		unsigned char mode:2;	/* Architecture mode */
-		unsigned char ckd:1;	/* CKD Conversion */
-		unsigned char operation:3;	/* Operation mode */
-		unsigned char cfw:1;	/* Cache fast write */
-		unsigned char dfw:1;	/* DASD fast write */
-	} __attribute__ ((packed)) attributes;
-	__u16 short blk_size;	/* Blocksize */
-	__u16 fast_write_id;
-	__u8 unused;
-	__u8 reserved;
-	ch_t beg_ext;
-	ch_t end_ext;
-} __attribute__ ((packed, aligned (32)))
-
-DE_eckd_data_t;
-
-typedef
-struct {
-	struct {
-		unsigned char orientation:2;
-		unsigned char operation:6;
-	} __attribute__ ((packed)) operation;
-	struct {
-		unsigned char last_bytes_used:1;
-		unsigned char reserved:6;
-		unsigned char read_count_suffix:1;
-	} __attribute__ ((packed)) auxiliary;
-	__u8 unused;
-	__u8 count;
-	ch_t seek_addr;
-	chr_t search_arg;
-	__u8 sector;
-	__u16 length;
-} __attribute__ ((packed, aligned (32)))
-
-LO_eckd_data_t;
-
-/* Stuff for handling home addresses */
-typedef struct {
-	__u8 skip_control[14];
-	__u16 cell_number;
-	__u8 physical_addr[3];
-	__u8 flag;
-	ch_t track_addr;
-	__u8 reserved;
-	__u8 key_length;
-	__u8 reserved2[2];
-} __attribute__ ((packed, aligned (32)))
+dasd_discipline_t dasd_eckd_discipline;
 
-eckd_home_t;
+typedef struct
+dasd_eckd_private_t {
+        dasd_eckd_characteristics_t rdc_data;
+        dasd_eckd_confdata_t conf_data;
+        eckd_count_t count_area;
+} dasd_eckd_private_t;
 
-dasd_era_t dasd_eckd_erp_examine (cqr_t *, devstat_t *);
-
-static unsigned int
+static inline unsigned int
 round_up_multiple (unsigned int no, unsigned int mult)
 {
 	int rem = no % mult;
 	return (rem ? no - rem + mult : no);
-/*      return (no % mult ? no - (no % mult) + mult : no); */
 }
 
-static unsigned int
+static inline unsigned int
 ceil_quot (unsigned int d1, unsigned int d2)
 {
 	return (d1 + (d2 - 1)) / d2;
 }
 
-static int
+static inline int
 bytes_per_record (dasd_eckd_characteristics_t * rdc,
 		  int kl,	/* key length */
 		  int dl /* data length */ )
@@ -330,7 +127,7 @@
 	return *(unsigned int *) (rdc->byte_per_track) >> 8;
 }
 
-static unsigned int
+static inline unsigned int
 recs_per_track (dasd_eckd_characteristics_t * rdc,
 		unsigned int kl, unsigned int dl)
 {
@@ -368,26 +165,26 @@
 	return rpt;
 }
 
-static
-void
+static inline void
 define_extent (ccw1_t * de_ccw,
 	       DE_eckd_data_t * data,
 	       int trk,
 	       int totrk,
 	       int cmd,
-	       dasd_information_t * info)
+	       dasd_device_t *device)
 {
 	ch_t geo, beg, end;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
 
-	geo.cyl = info->rdc_data->eckd.no_cyl;
-	geo.head = info->rdc_data->eckd.trk_per_cyl;
+	geo.cyl = private->rdc_data.no_cyl;
+	geo.head = private->rdc_data.trk_per_cyl;
 	beg.cyl = trk / geo.head;
 	beg.head = trk % geo.head;
 	end.cyl = totrk / geo.head;
 	end.head = totrk % geo.head;
 
 	memset (de_ccw, 0, sizeof (ccw1_t));
-	de_ccw->cmd_code = CCW_DEFINE_EXTENT;
+	de_ccw->cmd_code = DASD_ECKD_CCW_DEFINE_EXTENT;
 	de_ccw->count = 16;
 	de_ccw->cda = (void *) __pa (data);
 
@@ -436,14 +233,15 @@
 	       int rec_on_trk,
 	       int no_rec,
 	       int cmd,
-	       dasd_information_t * info)
+	       dasd_device_t * device)
 {
-	ch_t geo =
-	{info->rdc_data->eckd.no_cyl,
-	 info->rdc_data->eckd.trk_per_cyl};
-	ch_t seek =
-	{trk / (geo.head), trk % (geo.head)};
-	int reclen = info->sizes.bp_block;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
+	ch_t geo = {private->rdc_data.no_cyl,
+                    private->rdc_data.trk_per_cyl};
+	ch_t seek ={trk / (geo.head), trk % (geo.head)};
+	int reclen = device->sizes.bp_block;
+        int sector;
+
 	memset (lo_ccw, 0, sizeof (ccw1_t));
 	lo_ccw->cmd_code = DASD_ECKD_CCW_LOCATE_RECORD;
 	lo_ccw->count = 16;
@@ -499,100 +297,310 @@
 	default:
 		INTERNAL_ERROR ("unknown opcode 0x%x\n", cmd);
 	}
+        switch ( private -> rdc_data.dev_type == 0x3390 ) {
+        case 0x3390: {
+                int dn,d;
+                dn = ceil_quot(reclen + 6,232);
+                d = 9 + ceil_quot(reclen + 6 * (dn + 1),34);
+                sector = (49 + (rec_on_trk - 1) * ( 10 + d ))/8;
+                break;
+        }
+        case 0x3380: {
+                int d;
+                d = 7 + ceil_quot(reclen + 12, 32);
+                sector = (39 + (rec_on_trk - 1) * ( 8 + d ))/7;
+                break;
+        }
+        case 0x9345:
+        default:
+                sector = 0;
+        }
+        data -> sector = sector;
 	memcpy (&(data->seek_addr), &seek, sizeof (ch_t));
 	memcpy (&(data->search_arg), &seek, sizeof (ch_t));
 	data->search_arg.record = rec_on_trk;
 	data->count += no_rec;
 }
 
-void
-dasd_eckd_print_error (devstat_t * stat)
+static int 
+dasd_eckd_id_check ( dev_info_t *info )
 {
-	int sct, sl;
-	char *sense = stat->ii.sense.data;
-	PRINT_WARN ("IRQ on devno %x: with intparm:%x DS:0x%02x CS:0x%02x\n",
-		    stat->devno, stat->intparm, stat->dstat, stat->cstat);
-	PRINT_WARN ("Failing CCW: %p\n", (ccw1_t *) stat->cpa);
-	for (sl = 0; sl < 4; sl++) {
-		PRINT_DEBUG ("Sense:");
-		for (sct = 0; sct < 8; sct++) {
-			printk (" %2d:0x%02x",
-				8 * sl + sct, sense[8 * sl + sct]);
+        if ( info->sid_data.cu_type == 0x3990 )
+                if ( info->sid_data.dev_type == 0x3390 )
+                        return 0;
+        if ( info->sid_data.cu_type == 0x3990 )
+                if ( info->sid_data.dev_type == 0x3380 )
+                        return 0;
+        if ( info->sid_data.cu_type == 0x9343 )
+                if ( info->sid_data.dev_type == 0x9345 )
+                        return 0;
+        return -ENODEV;
 		}
-		printk ("\n");
-	}
-	if (sense[27] & 0x80) {	/* 32 Byte Sense Data */
-		PRINT_INFO ("Sense Data is 32 Byte information\n");
-		PRINT_INFO ("Format: %x Exception class %x\n",
-			    sense[6] & 0x0f, sense[22] >> 4);
-	} else {		/* 24 Byte Sense Data */
-		PRINT_INFO ("Sense Data is 24 Byte information\n");
-		PRINT_INFO ("FMT: %x MSG %x, %s MSGb to SYSOP\n",
-			    sense[7] >> 4, sense[7] & 0x0f,
-			    sense[1] & 0x10 ? "" : "no");
+
+static int
+dasd_eckd_check_characteristics (struct dasd_device_t *device)
+{
+        int rc = -ENODEV;
+        void *conf_data;
+        void *rdc_data;
+        int conf_len;
+        dasd_eckd_private_t *private;
+
+        if ( device == NULL ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "Null device pointer passed to characteristics checker\n");
+                return -ENODEV;
+        }
+        if ( device->private == NULL ) {
+          device->private = kmalloc(sizeof(dasd_eckd_private_t),GFP_KERNEL);
+          if ( device->private == NULL ) {
+            printk ( KERN_WARNING PRINTK_HEADER
+                     "memory allocation failed for private data\n");
+            return -ENOMEM;
+          }
+        }
+        private = (dasd_eckd_private_t *)device->private;
+        rdc_data = (void *)&(private->rdc_data);
+        rc = read_dev_chars (device->devinfo.irq, &rdc_data , 64);
+        if ( rc ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "Read device characteristics returned error %d\n",rc);
+                return rc;
+	}
+	printk ( KERN_INFO PRINTK_HEADER 
+                 "%04X on sch %d: %04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d\n",
+                 device->devinfo.devno, device->devinfo.irq,
+                 private->rdc_data.dev_type, private->rdc_data.dev_model,
+                 private->rdc_data.cu_type, private->rdc_data.cu_model.model,
+                 private->rdc_data.no_cyl, private->rdc_data.trk_per_cyl,
+                 private->rdc_data.sec_per_trk);
+        rc = read_conf_data(device->devinfo.irq, &conf_data, &conf_len, LPM_ANYPATH );
+        if ( rc ) {
+                if ( rc == -EOPNOTSUPP )
+                        return 0;
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "Read configuration data returned error %d\n",rc);
+                return rc;
+	}
+        if ( conf_len != sizeof(dasd_eckd_confdata_t)) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "sizes of configuration data mismatch %d (read) vs %ld (expected)\n",
+                         conf_len, sizeof(dasd_eckd_confdata_t));
+                return rc;
+        }
+        if ( conf_data == NULL ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "No configuration data retrieved\n");
+                return -ENOMEM;
+        }
+        memcpy (&private->conf_data,conf_data,sizeof(dasd_eckd_confdata_t));
+	printk ( KERN_INFO PRINTK_HEADER 
+                 "%04X on sch %d: %04X/%02X (CU: %04X/%02X): Configuration data read\n",
+                 device->devinfo.devno, device->devinfo.irq,
+                 private->rdc_data.dev_type, private->rdc_data.dev_model,
+                 private->rdc_data.cu_type, private->rdc_data.cu_model.model);
+        device->sizes.bp_block = 4096;
+        device->sizes.s2b_shift = 3;
+        device->sizes.blocks = ( private->rdc_data.no_cyl * 
+                                 private->rdc_data.trk_per_cyl *
+                                 recs_per_track (&private->rdc_data, 
+                                                 0, device->sizes.bp_block));
+        return 0;
+}
+
+static ccw_req_t *
+dasd_eckd_init_analysis (struct dasd_device_t *device)
+{
+	ccw_req_t *cqr = NULL;
+	ccw1_t *ccw;
+	DE_eckd_data_t *DE_data;
+	LO_eckd_data_t *LO_data;
+	eckd_count_t *count_data = &(((dasd_eckd_private_t *)(device->private))->count_area);
+
+        cqr = ccw_alloc_request (dasd_eckd_discipline.name, 3, sizeof (DE_eckd_data_t) + sizeof (LO_eckd_data_t));
+        if ( cqr == NULL ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "No memory to allocate initialization request\n");
+                return NULL;
+        }
+	DE_data = cqr->data;
+	LO_data = cqr->data + sizeof (DE_eckd_data_t);
+	ccw = cqr->cpaddr;
+	define_extent (ccw, DE_data, 0, 0, DASD_ECKD_CCW_READ_COUNT, device);
+	ccw->flags = CCW_FLAG_CC;
+	ccw++;
+	locate_record (ccw, LO_data, 0, 1, 1, DASD_ECKD_CCW_READ_COUNT, device);
+	ccw->flags = CCW_FLAG_CC;
+	ccw++;
+	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
+	ccw->count = 8;
+	ccw->cda = (void *) __pa (count_data);
+	cqr->device = device;
+	atomic_set (&cqr->status, CQR_STATUS_FILLED);
+        
+        return cqr;
+}
+
+static int
+dasd_eckd_do_analysis (struct dasd_device_t *device)
+{
+        int rc = 0;
+	int sb, rpt;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
+	int bs = private->count_area.dl;
+
+        memset (&(device->sizes), 0, sizeof (dasd_sizes_t));
+        switch ( bs ) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+		device->sizes.bp_block = bs;
+                break;
+        default:
+                printk ( KERN_INFO PRINTK_HEADER 
+                         "/dev/%s (%04X): invalid blocksize %d\n"
+                         KERN_INFO PRINTK_HEADER 
+                         "/dev/%s (%04X): capacity (at 4kB blks): %dkB at %dkB/trk\n",
+                         device->name, device->devinfo.devno,bs,
+                         device->name, device->devinfo.devno,
+                         ( private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl *
+                          recs_per_track (&private->rdc_data, 0, 4096)),
+                        recs_per_track (&private->rdc_data, 0, 4096));
+		return -EMEDIUMTYPE;
 	}
+	device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
+	for (sb = 512; sb < bs; sb = sb << 1)
+		device->sizes.s2b_shift++;
+        
+	rpt = recs_per_track (&private->rdc_data, 0, device->sizes.bp_block);
+        device->sizes.blocks = ( private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl *
+                                 recs_per_track (&private->rdc_data, 0, device->sizes.bp_block));
+                
+        printk ( KERN_INFO PRINTK_HEADER 
+                 "/dev/%s (%04X): capacity (%dkB blks): %dkB at %dkB/trk\n",
+                 device->name, device->devinfo.devno,
+                 (device->sizes.bp_block>>10),
+                 ( private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl *
+                   recs_per_track (&private->rdc_data, 0, device->sizes.bp_block)*
+                   (device->sizes.bp_block>>9))>>1,
+                 ( recs_per_track (&private->rdc_data, 0, device->sizes.bp_block)*device->sizes.bp_block) >> 10);
+	return 0;
+        
+        return rc;
 }
 
-int
-dasd_eckd_format_track (int di, int trk, int bs)
+static int
+dasd_eckd_fill_geometry(struct dasd_device_t *device, struct hd_geometry *geo)
+{
+        int rc = 0;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
+        switch(device->sizes.bp_block) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+                break;
+        default:
+                return -EINVAL;
+        }
+	geo->cylinders = private->rdc_data.no_cyl;
+	geo->heads = private->rdc_data.trk_per_cyl;
+	geo->sectors = recs_per_track (&(private->rdc_data), 0, device->sizes.bp_block);
+	geo->start = 2;
+        return rc;
+}
+
+static inline int
+dasd_eckd_format_track (dasd_device_t *device, int trk, int bs, int flags)
 {
 	int rc = 0;
 	int i;
-	int flags = 0x00;	/* FORMAT_R0 = 0x01, FORMAT_HA = 0x03 */
-        dasd_information_t * info=dasd_info[di];
-	cqr_t *fcp;
-	DE_eckd_data_t *DE_data;
-	LO_eckd_data_t *LO_data;
-	eckd_count_t *ct_data;
-	eckd_count_t *r0_data;
-	ccw1_t *last_ccw;
-        int retries = 5;
-
-	int rpt = recs_per_track (&(info->rdc_data->eckd), 0, bs);
-	int cyl = trk / info->rdc_data->eckd.trk_per_cyl;
-	int head = trk % info->rdc_data->eckd.trk_per_cyl;
-
-	fcp = request_cqr (2 + 1 + rpt,
-			   sizeof (DE_eckd_data_t) +
-			   sizeof (LO_eckd_data_t) +
-			   (rpt + 1) * sizeof (eckd_count_t));
-        fcp -> devindex=di;
-	DE_data = (DE_eckd_data_t *) fcp->data;
-	LO_data = (LO_eckd_data_t *) (((long) DE_data) +
-				      sizeof (DE_eckd_data_t));
-	r0_data = (eckd_count_t *) (((long) LO_data) +
-				    sizeof (LO_eckd_data_t));
-	ct_data = (eckd_count_t *) (((long) r0_data) +
-				    sizeof (eckd_count_t));
+	ccw_req_t *fcp = NULL;
+	DE_eckd_data_t *DE_data = NULL;
+	LO_eckd_data_t *LO_data = NULL;
+	eckd_count_t *ct_data = NULL;
+	eckd_count_t *r0_data = NULL;
+        eckd_home_t *ha_data = NULL;
+	ccw1_t *last_ccw = NULL;
+        void * last_data = NULL;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
+	int retries;
+
+	int rpt = recs_per_track (&(private->rdc_data), 0, bs);
+	int cyl = trk / private->rdc_data.trk_per_cyl;
+	int head = trk % private->rdc_data.trk_per_cyl;
+        int wrccws = rpt;
+        int datasize = sizeof (DE_eckd_data_t) + sizeof (LO_eckd_data_t);
+        
+        switch ( flags ) {
+        case 0x00:
+        case 0x01:
+        case 0x03:
+          break;
+        default:
+          return -EINVAL;
+        }
+        
+        if ( flags & 0x1 ) {
+          wrccws++;
+          datasize += sizeof(eckd_count_t);
+        }
+        if ( flags & 0x2 ) {
+          wrccws++;
+          datasize += sizeof(eckd_home_t);
+        }
+	fcp = ccw_alloc_request (dasd_eckd_discipline.name, 
+                                 wrccws + 2,
+                                 datasize+rpt*sizeof(eckd_count_t));
+	fcp->device = device;
+
+        last_data = fcp->data;
+	DE_data = (DE_eckd_data_t *) last_data;
+        last_data = (void*)(DE_data +1);
+	LO_data = (LO_eckd_data_t *) last_data;
+        last_data = (void*)(LO_data +1);
+        if ( flags & 0x2 ) {
+          ha_data = (eckd_home_t *) last_data;
+          last_data = (void*)(ha_data +1);
+        }
+        if ( flags & 0x1 ) {
+          r0_data = (eckd_count_t *) last_data;
+          last_data = (void*)(r0_data +1);
+        }
+	ct_data = (eckd_count_t *)last_data;
+
 	last_ccw = fcp->cpaddr;
+
 	switch (flags) {
 	case 0x03:
 		define_extent (last_ccw, DE_data, trk, trk,
-			       DASD_ECKD_CCW_WRITE_HOME_ADDRESS, info);
+                               DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device);
 		last_ccw->flags = CCW_FLAG_CC;
 		last_ccw++;
-		locate_record (last_ccw, LO_data, trk, 0, rpt,
-			       DASD_ECKD_CCW_WRITE_HOME_ADDRESS, info);
+		locate_record (last_ccw, LO_data, trk, 0, wrccws,
+			       DASD_ECKD_CCW_WRITE_HOME_ADDRESS, device);
 		last_ccw->flags = CCW_FLAG_CC;
 		last_ccw++;
 		break;
 	case 0x01:
 		define_extent (last_ccw, DE_data, trk, trk,
-			       DASD_ECKD_CCW_WRITE_RECORD_ZERO, info);
+			       DASD_ECKD_CCW_WRITE_RECORD_ZERO, device);
 		last_ccw->flags = CCW_FLAG_CC;
 		last_ccw++;
-		locate_record (last_ccw, LO_data, trk, 0, rpt,
-			       DASD_ECKD_CCW_WRITE_RECORD_ZERO, info);
+		locate_record (last_ccw, LO_data, trk, 0, wrccws,
+			       DASD_ECKD_CCW_WRITE_RECORD_ZERO, device);
 		last_ccw->flags = CCW_FLAG_CC;
 		last_ccw++;
+		memset (r0_data, 0, sizeof (eckd_count_t));
 		break;
 	case 0x00:
 		define_extent (last_ccw, DE_data, trk, trk,
-			       DASD_ECKD_CCW_WRITE_CKD, info);
+			       DASD_ECKD_CCW_WRITE_CKD, device);
 		last_ccw->flags = CCW_FLAG_CC;
 		last_ccw++;
-		locate_record (last_ccw, LO_data, trk, 0, rpt,
-			       DASD_ECKD_CCW_WRITE_CKD, info);
+		locate_record (last_ccw, LO_data, trk, 0, wrccws,
+			       DASD_ECKD_CCW_WRITE_CKD, device);
                 LO_data->length = bs;
 		last_ccw->flags = CCW_FLAG_CC;
 		last_ccw++;
@@ -606,7 +614,6 @@
 		return -EINVAL;
 	}
 	if (flags & 0x01) {	/* write record zero */
-		memset (r0_data, 0, sizeof (eckd_count_t));
 		r0_data->cyl = cyl;
 		r0_data->head = head;
 		r0_data->record = 0;
@@ -632,89 +639,204 @@
 		last_ccw->cda = (void *) __pa (ct_data + i);
 	}
 	(last_ccw - 1)->flags &= ~(CCW_FLAG_CC | CCW_FLAG_DC);
-        fcp -> devindex = di;
-        fcp -> flags = DASD_DO_IO_SLEEP;
+	fcp->device = device;
         do {
-		struct wait_queue wait =
-		{current, NULL};
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+                DECLARE_WAITQUEUE (wait,current);
+#else
+                struct wait_queue wait = {current, NULL};
+#endif /* LINUX_VERSION_CODE */
                 unsigned long flags;
-                int irq;
                 int cs;
 
-                irq = dasd_info[fcp->devindex]->info.irq;
-                s390irq_spin_lock_irqsave (irq, flags);
+                retries = 1;
+		s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
                 atomic_set(&fcp->status,CQR_STATUS_QUEUED);
-                rc = dasd_start_IO ( fcp );
-                add_wait_queue (&dasd_waitq, &wait);
                 do {
-                        current->state = TASK_UNINTERRUPTIBLE;
-                        s390irq_spin_unlock_irqrestore (irq, flags);
+                        rc = dasd_eckd_discipline.start_IO (fcp);
+                } while ( rc && retries-- );
+                if ( rc && retries == 0 )
+                        break;
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+		add_wait_queue (&device->wait_q, &wait);
+#endif /* LINUX_VERSION_CODE */
+		do {
+			current->state = TASK_INTERRUPTIBLE;
+			s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
                         schedule ();
-                        s390irq_spin_lock_irqsave (irq, flags);
-                } while (((cs = atomic_read (&fcp->status)) !=
-                          CQR_STATUS_DONE) &&
-                         (cs != CQR_STATUS_ERROR));
-                remove_wait_queue (&dasd_waitq, &wait);
-		s390irq_spin_unlock_irqrestore (irq, flags);
-
-                retries --;
+			s390irq_spin_lock_irqsave (device->devinfo.irq, flags);
+                        cs = atomic_read (&fcp->status);
+		} while ((cs != CQR_STATUS_DONE) && (cs != CQR_STATUS_ERROR));
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+		remove_wait_queue (&device->wait_q, &wait);
+#endif /* LINUX_VERSION_CODE */
+		s390irq_spin_unlock_irqrestore (device->devinfo.irq, flags);
 	} while ( (rc || (atomic_read(&fcp->status) != CQR_STATUS_DONE)) &&
-                  retries);
-        if ((rc || (atomic_read(&fcp->status) != CQR_STATUS_DONE)))
+                 retries--);
+	if ( retries == 0 )
                 rc = -EIO;
-	release_cqr (fcp);
+	ccw_free_request (fcp);
 	return rc;
 }
 
-int
-dasd_eckd_ck_devinfo (dev_info_t * info)
+static int
+dasd_eckd_format_device (struct dasd_device_t *device, struct format_data_t *fdata)
 {
-	return 0;
+        int rc = 0;
+	int i;
+	format_data_t fd;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
+        int last_track =private->rdc_data.no_cyl*private->rdc_data.trk_per_cyl-1;
+        int intensity;
+        kdev_t kdev = device->kdev;
+        int nr_tracks, blocksize;
+
+	if (fdata==NULL) {
+		fd.start_unit = 0;
+		fd.stop_unit = last_track;
+		fd.blksize = 4096;
+	} else {
+		memcpy (&fd, fdata, sizeof (format_data_t));
+		if (fd.stop_unit == -1) {
+			fd.stop_unit = last_track;
+		}
+		if (fd.blksize == 0) {
+			fd.blksize = 4096;
+		}
+	}
+	if (fd.start_unit > fd.stop_unit) {
+		return -EINVAL;
+	}
+	if (fd.start_unit > last_track ) {
+		return -EINVAL;
+	}
+	if (fd.stop_unit > last_track ) {
+		return -EINVAL;
+	}
+        switch(fd.blksize) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+                break;
+        default:
+                return -EINVAL;
+        }
+        fd.intensity = 0x0;
+        intensity = fd.intensity;
+        set_blocksize(kdev, fd.blksize);
+	printk (KERN_INFO PRINTK_HEADER
+                "Formatting device %04X from track %d to %d with bs %d\n",
+                device->devinfo.devno,fd.start_unit, fd.stop_unit, fd.blksize);
+        nr_tracks = fd.stop_unit-fd.start_unit+1;
+	for (i = 0; i <= nr_tracks; i++) {
+		/* print 20 messages per format cmd at all */
+                if ( i % (nr_tracks / 20) == 0 ) { 
+                        printk (KERN_INFO PRINTK_HEADER
+                                "Format %04X Cylinder: %d Track %d Intensity %d\n", 
+                                device->devinfo.devno,
+                                (i+fd.start_unit) / private->rdc_data.trk_per_cyl,
+                                (i+fd.start_unit) % private->rdc_data.trk_per_cyl,
+                                intensity);
+                }
+                do {
+                        if ( i == 0 ) {
+                                blocksize = 8;
+                        } else {
+                                blocksize = fd.blksize;
+                        }
+                        rc = dasd_eckd_format_track (device, 
+                                                     (i % nr_tracks) + fd.start_unit , 
+                                                     blocksize, intensity);
+                                /* fix VM controlled minidisk */
+                        if ( rc ) {
+                                if ( intensity ) {
+                                        intensity = intensity >> 1;
+                                }
+                                printk (KERN_WARNING PRINTK_HEADER
+                                        "decreasing format intensity to %d\n", 
+                                        intensity);
+                        }
+                } while ( rc && intensity > 0);
+                if (rc) {
+                        printk (KERN_WARNING PRINTK_HEADER
+                                "Formatting of device %04X Cylinder %d Track %d failed...exiting\n",
+                                device->devinfo.devno,
+                                i / private->rdc_data.trk_per_cyl,
+                                i % private->rdc_data.trk_per_cyl);
+                        break;
+		}
+	}
+	printk ( KERN_INFO PRINTK_HEADER
+                 "Formatting of device %04X completed from track %d to %d with bs %d\n",
+                 device->devinfo.devno, fd.start_unit, fd.stop_unit, fd.blksize);
+        return rc;
+}
+
+static dasd_era_t
+dasd_eckd_examine_error  (ccw_req_t *cqr, devstat_t * stat)
+{
+        dasd_device_t *device = (dasd_device_t *)cqr->device;
+        if (stat->cstat == 0x00 &&
+	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+		return dasd_era_none;
+        
+	switch (device->devinfo.sid_data.cu_model) {
+	case 0x3990:
+		return dasd_3990_erp_examine (cqr, stat);
+	case 0x9343:
+		return dasd_9343_erp_examine (cqr, stat);
+	default:
+		return dasd_era_recover;
+	}
 }
 
-cqr_t *
-dasd_eckd_build_req (int devindex,
-		     struct request * req)
+static dasd_erp_action_fn_t 
+dasd_eckd_erp_action ( ccw_req_t * cqr ) 
 {
-	cqr_t *rw_cp = NULL;
-	ccw1_t *ccw;
+        return default_erp_action;
+}
 
-	DE_eckd_data_t *DE_data;
-	LO_eckd_data_t *LO_data;
-	struct buffer_head *bh;
+static dasd_erp_postaction_fn_t
+dasd_eckd_erp_postaction (ccw_req_t * cqr)
+{
+        if ( cqr -> function == default_erp_action)
+                return default_erp_postaction;
+        printk ( KERN_WARNING PRINTK_HEADER
+                 "unknown ERP action %p\n",
+                 cqr -> function);
+	return NULL;
+}
+
+static ccw_req_t *
+dasd_eckd_build_cp_from_req (dasd_device_t *device, struct request *req)
+{
+        ccw_req_t *rw_cp = NULL;
 	int rw_cmd;
-	dasd_information_t *info = dasd_info[devindex];
-	int blk_per_trk = recs_per_track (&(info->rdc_data->eckd),
-					  0, info->sizes.bp_block);
-	int byt_per_blk = info->sizes.bp_block;
-	int btrk = (req->sector >> info->sizes.s2b_shift) / blk_per_trk;
-	int etrk = ((req->sector + req->nr_sectors - 1) >>
-		    info->sizes.s2b_shift) / blk_per_trk;
 	int bhct;
 	long size;
+        ccw1_t *ccw;
+	DE_eckd_data_t *DE_data;
+	LO_eckd_data_t *LO_data;
+	struct buffer_head *bh;
+        dasd_eckd_private_t *private = (dasd_eckd_private_t *)device->private;
+	int byt_per_blk = device->sizes.bp_block;
+        int shift = device->sizes.s2b_shift;
+	int blk_per_trk = recs_per_track (&(private->rdc_data), 0, byt_per_blk);
+	int btrk = (req->sector >> shift) / blk_per_trk;
+	int etrk = ((req->sector + req->nr_sectors - 1) >> shift) / blk_per_trk;
 
 	if (req->cmd == READ) {
 		rw_cmd = DASD_ECKD_CCW_READ_MT;
-	} else
-#if DASD_PARANOIA > 2
-	if (req->cmd == WRITE)
-#endif				/* DASD_PARANOIA */
-	{
+	} else if (req->cmd == WRITE) {
 		rw_cmd = DASD_ECKD_CCW_WRITE_MT;
-	}
-#if DASD_PARANOIA > 2
-	else {
+	} else {
 		PRINT_ERR ("Unknown command %d\n", req->cmd);
 		return NULL;
 	}
-#endif				/* DASD_PARANOIA */
 	/* Build the request */
-#if 0
-	PRINT_INFO ("req %d %d %d %d\n", devindex, req->cmd, req->sector, req->nr_sectors);
-#endif
 	/* count bhs to prevent errors, when bh smaller than block */
 	bhct = 0;
-
 	for (bh = req->bh; bh; bh = bh->b_reqnext) {
 		if (bh->b_size > byt_per_blk)
 			for (size = 0; size < bh->b_size; size += byt_per_blk)
@@ -723,7 +845,8 @@
 			bhct++;
 	}
 
-	rw_cp = request_cqr (2 + bhct,
+	rw_cp = dasd_alloc_request (dasd_eckd_discipline.name,
+                                   2 + bhct,
 			     sizeof (DE_eckd_data_t) +
 			     sizeof (LO_eckd_data_t));
         if ( ! rw_cp ) {
@@ -733,14 +856,11 @@
 	LO_data = rw_cp->data + sizeof (DE_eckd_data_t);
 	ccw = rw_cp->cpaddr;
 
-	define_extent (ccw, DE_data, btrk, etrk, rw_cmd, info);
+	define_extent (ccw, DE_data, btrk, etrk, rw_cmd, device);
 	ccw->flags = CCW_FLAG_CC;
 	ccw++;
-	locate_record (ccw, LO_data, btrk,
-		       (req->sector >> info->sizes.s2b_shift) %
-		       blk_per_trk + 1,
-		       req->nr_sectors >> info->sizes.s2b_shift,
-		       rw_cmd, info);
+	locate_record (ccw, LO_data, btrk, (req->sector >> shift) % blk_per_trk + 1,
+		       req->nr_sectors >> shift, rw_cmd, device);
 	ccw->flags = CCW_FLAG_CC;
 	for (bh = req->bh; bh != NULL;) {
 		if (bh->b_size > byt_per_blk) {
@@ -764,202 +884,93 @@
 	}
 			if (size != byt_per_blk) {
 				PRINT_WARN ("Cannot fulfill small request %d vs. %d (%d sects)\n", size, byt_per_blk, req->nr_sectors);
-				release_cqr (rw_cp);
+				ccw_free_request (rw_cp);
 		return NULL;
 	}
 			ccw->flags = CCW_FLAG_CC;
 		}
 	}
 	ccw->flags &= ~(CCW_FLAG_DC | CCW_FLAG_CC);
+        rw_cp->device = device;
+        rw_cp->expires = 5 * 0xf424000; /* 5 seconds */
+        rw_cp->req = req;
+        atomic_compare_and_swap_debug(&rw_cp->status,CQR_STATUS_EMPTY,CQR_STATUS_FILLED);
 	return rw_cp;
 }
 
-void
-dasd_eckd_print_char (dasd_characteristics_t * i)
-{
-        dasd_eckd_characteristics_t * c = 
-                (dasd_eckd_characteristics_t *)i;
-	PRINT_INFO ("%x/%x (%x/%x) Cyl: %d Head: %d Sec: %d \n",
-		    c->dev_type, c->dev_model,
-		    c->cu_type, c->cu_model.model,
-		    c->no_cyl, c->trk_per_cyl,
-		    c->sec_per_trk);
-	PRINT_INFO ("Estimate: %d Byte/trk %d byte/kByte %d kByte/trk \n",
-		    bytes_per_track (c),
-		    bytes_per_record (c, 0, 1024),
-		    recs_per_track (c, 0, 1024));
-};
-
-int
-dasd_eckd_ck_char (dasd_characteristics_t * i)
-{
-	int rc = 0;
-	dasd_eckd_print_char (i);
-	return rc;
-}
-
-int
-dasd_eckd_format (int devindex, format_data_t * fdata)
+static char *
+dasd_eckd_dump_sense(struct dasd_device_t *device, ccw_req_t *req)
 {
-	int rc = 0;
-	int i;
-	dasd_information_t *info = dasd_info[devindex];
-	format_data_t fd;
+        char *page = (char *)get_free_page(GFP_KERNEL);
+        devstat_t *stat = &device->dev_status;
+	char *sense = stat->ii.sense.data;
+        int len,sl,sct;
 
-	if (!fdata) {
-		fd.start_unit = 0;
-		fd.stop_unit = info->rdc_data->eckd.no_cyl *
-                        info->rdc_data->eckd.trk_per_cyl - 1;
-		fd.blksize = 4096;
-	} else {
-		memcpy (&fd, fdata, sizeof (format_data_t));
-		if ( fd.stop_unit == -1 ) {
-                        fd.stop_unit = info->rdc_data->eckd.no_cyl *
-                                info->rdc_data->eckd.trk_per_cyl - 1;
-		}
-                if ( fd.blksize == 0 ) {
-                        fd.blksize = 4096;
-                }
-	}
-        PRINT_INFO("Formatting device %d from %d to %d with bs %d\n",
-                   devindex,fd.start_unit,fd.stop_unit,fd.blksize);
-        if ( fd.start_unit > fd.stop_unit ) {
-                PRINT_WARN ("start unit .gt. stop unit\n");
-                return -EINVAL;
-        }
-        if ( (fd.start_unit > info->rdc_data->eckd.no_cyl *
-              info->rdc_data->eckd.trk_per_cyl - 1) ) {
-                PRINT_WARN ("start unit beyond end of disk\n");
-                return -EINVAL;
-        }
-        if ( (fd.stop_unit > info->rdc_data->eckd.no_cyl *
-              info->rdc_data->eckd.trk_per_cyl - 1) ) {
-                PRINT_WARN ("stop unit beyond end of disk\n");
-                return -EINVAL;
+        if ( page == NULL ) {
+                return NULL;
         }
-        switch (fd.blksize) {
-        case 512:
-        case 1024:
-        case 2048:
-        case 4096:
-                break;
-        default:
-                PRINT_WARN ("invalid blocksize\n");
-                return -EINVAL;
+        len = sprintf ( page, KERN_WARNING PRINTK_HEADER 
+                        "device %04X on irq %d: I/O status report:\n",
+                        device->devinfo.devno,device->devinfo.irq);
+        len += sprintf ( page + len, KERN_WARNING PRINTK_HEADER 
+                         "in req: %p CS: 0x%02X DS: 0x%02X\n",
+                         req,stat->cstat,stat->dstat);
+        len += sprintf ( page + len, KERN_WARNING PRINTK_HEADER 
+                         "Failing CCW: %p\n", (void *)stat->cpa);
+        if ( stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ) {
+                for (sl = 0; sl < 4; sl++) {
+                        len += sprintf ( page + len, KERN_WARNING PRINTK_HEADER 
+                                         "Sense:");
+                        for (sct = 0; sct < 8; sct++) {
+                                len += sprintf ( page + len," %2d:0x%02x",
+                                                 8 * sl + sct, sense[8 * sl + sct]);
         }
-	for (i = fd.start_unit; i <= fd.stop_unit; i++) {
-                /* print 20 messages per disk at all */
-                if ( ! ( i % (info->rdc_data->eckd.trk_per_cyl  *
-                                (info->rdc_data->eckd.no_cyl / 20 ) )))  {
-                        PRINT_INFO ("Format %d Cylinder: %d\n",devindex,
-                                    i/info->rdc_data->eckd.trk_per_cyl);
+                        len += sprintf ( page + len,"\n");
                 }
-		rc = dasd_eckd_format_track (devindex, i, fd.blksize);
-		if (rc) {
-			PRINT_WARN ("Formatting of Track %d failed...exiting\n", i);
-			break;
+                if (sense[27] & 0x80) {	
+                        /* 24 Byte Sense Data */
+                        len += sprintf ( page + len, KERN_WARNING PRINTK_HEADER 
+                                         "24 Byte: %x MSG %x, %s MSGb to SYSOP\n",
+                                         sense[7] >> 4, sense[7] & 0x0f,
+                                         sense[1] & 0x10 ? "" : "no");
+                } else {		
+                        /* 32 Byte Sense Data */
+                        len += sprintf ( page + len, KERN_WARNING PRINTK_HEADER 
+                                         "32 Byte: Format: %x Exception class %x\n",
+                                         sense[6] & 0x0f, sense[22] >> 4);
 		}
 	}
-        PRINT_INFO("Formated device %d from %d to %d with bs %d\n",
-                   devindex,fd.start_unit,fd.stop_unit,fd.blksize);
-	return rc;
+        return page;
 }
 
-cqr_t *
-dasd_eckd_fill_sizes_first (int di)
-{
-	cqr_t *rw_cp = NULL;
-	ccw1_t *ccw;
-	DE_eckd_data_t *DE_data;
-	LO_eckd_data_t *LO_data;
-	dasd_information_t *info = dasd_info[di];
-	eckd_count_t *count_data = &(info->private.eckd.count_data);
-
-	dasd_info[di]->sizes.label_block = 2;
-
-	rw_cp = request_cqr (3,
-			     sizeof (DE_eckd_data_t) +
-			     sizeof (LO_eckd_data_t));
-	DE_data = rw_cp->data;
-	LO_data = rw_cp->data + sizeof (DE_eckd_data_t);
-	ccw = rw_cp->cpaddr;
-	define_extent (ccw, DE_data, 0, 0, DASD_ECKD_CCW_READ_COUNT, info);
-	ccw->flags = CCW_FLAG_CC;
-	ccw++;
-	locate_record (ccw, LO_data, 0, 1, 1, DASD_ECKD_CCW_READ_COUNT, info);
-	ccw->flags = CCW_FLAG_CC;
-	ccw++;
-	ccw->cmd_code = DASD_ECKD_CCW_READ_COUNT;
-	ccw->count = 8;
-	ccw->cda = (void *) __pa (count_data);
-	rw_cp->devindex = di;
-	atomic_set (&rw_cp->status, CQR_STATUS_FILLED);
-	return rw_cp;
-}
+dasd_discipline_t dasd_eckd_discipline = {
+	name :                          "ECKD",
+	ebcname :                       "ECKD",
+        id_check:                       dasd_eckd_id_check,          
+        check_characteristics:          dasd_eckd_check_characteristics,
+        init_analysis:                  dasd_eckd_init_analysis,
+        do_analysis:                    dasd_eckd_do_analysis,          
+        fill_geometry:                  dasd_eckd_fill_geometry,
+        start_IO:                       dasd_start_IO,           
+        format_device:                  dasd_eckd_format_device,          
+        examine_error:                  dasd_eckd_examine_error,          
+        erp_action:                     dasd_eckd_erp_action,             
+        erp_postaction:                 dasd_eckd_erp_postaction,         
+        build_cp_from_req:              dasd_eckd_build_cp_from_req,      
+        dump_sense:                     dasd_eckd_dump_sense,            
+        int_handler:                    dasd_int_handler            
+};
 
 int
-dasd_eckd_fill_sizes_last (int devindex)
-{
-	int sb,rpt;
-	dasd_information_t *in = dasd_info[devindex];
-	int bs = in->private.eckd.count_data.dl;
-	if (bs <= 0) {
-                PRINT_INFO("Cannot figure out blocksize. did you format the disk?\n");
-                memset (&(in -> sizes), 0, sizeof(dasd_sizes_t ));
-                return -EMEDIUMTYPE;
-	} else {
-		in->sizes.bp_block = bs;
-	}
-	in->sizes.bp_sector = in->sizes.bp_block;
-        
-	if (bs & 511) {
-		PRINT_INFO ("Probably no Linux formatted device!\n");
-		return -EMEDIUMTYPE;
-	}
-	in->sizes.s2b_shift = 0; /* bits to shift 512 to get a block */
-	for (sb = 512; sb < bs; sb = sb << 1)
-                in->sizes.s2b_shift++;
+dasd_eckd_init( void ) {
+        int rc = 0;
+        printk ( KERN_INFO PRINTK_HEADER
+                 "%s discipline initializing\n", dasd_eckd_discipline.name);
+        ASCEBC(dasd_eckd_discipline.ebcname,4);
+        dasd_discipline_enq(&dasd_eckd_discipline);
         
-	in->sizes.blocks = in->rdc_data->eckd.no_cyl *
-                in->rdc_data->eckd.trk_per_cyl *
-                recs_per_track (&(in->rdc_data->eckd), 0, bs);
-
-        in->sizes.kbytes = ( in->sizes.blocks << in->sizes.s2b_shift) >> 1;
-
-        rpt = recs_per_track (&(in->rdc_data->eckd), 0, in->sizes.bp_block),
-        
-	PRINT_INFO ("Verified: %d B/trk %d B/Blk(%d B) %d Blks/trk %d kB/trk \n",
-		    bytes_per_track (&(in->rdc_data->eckd)),
-                    bytes_per_record (&(in->rdc_data->eckd), 0, 
-                                      in->sizes.bp_block),
-                    in->sizes.bp_block,
-                    rpt,
-                    (rpt << in->sizes.s2b_shift) >> 1);
-                    return 0;
-}
-
-void
-dasd_eckd_fill_geometry (int di, struct hd_geometry *geo)
-{
-	dasd_information_t *info = dasd_info[di];
-	geo->cylinders = info->rdc_data->eckd.no_cyl;
-	geo->heads = info->rdc_data->eckd.trk_per_cyl;
-	geo->sectors = recs_per_track (&(info->rdc_data->eckd),
-				       0, info->sizes.bp_block);
-	geo->start = info->sizes.label_block + 1;
-}
-
-dasd_operations_t dasd_eckd_operations =
-{
-	ck_devinfo:dasd_eckd_ck_devinfo,
-	get_req_ccw:dasd_eckd_build_req,
-	ck_characteristics:dasd_eckd_ck_char,
-	fill_sizes_first:dasd_eckd_fill_sizes_first,
-	fill_sizes_last:dasd_eckd_fill_sizes_last,
-	dasd_format:dasd_eckd_format,
-	fill_geometry:dasd_eckd_fill_geometry,
-	erp_examine:dasd_eckd_erp_examine
-};
+        return rc;
+}
 
 /*
  * Overrides for Emacs so that we follow Linus's tabbing style.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_eckd.h linux.17p18/drivers/s390/block/dasd_eckd.h
--- linux.vanilla/drivers/s390/block/dasd_eckd.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd_eckd.h	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,286 @@
+#ifndef DASD_ECKD_H
+#define DASD_ECKD_H
+
+typedef 
+struct eckd_count_t {
+	__u16 cyl;
+	__u16 head;
+	__u8 record;
+	__u8 kl;
+	__u16 dl;
+} __attribute__ ((packed)) eckd_count_t;
+
+typedef
+struct ch_t {
+	__u16 cyl;
+	__u16 head;
+} __attribute__ ((packed)) ch_t;
+
+typedef
+struct chs_t {
+	__u16 cyl;
+	__u16 head;
+	__u32 sector;
+} __attribute__ ((packed)) chs_t;
+
+typedef
+struct chr_t {
+	__u16 cyl;
+	__u16 head;
+	__u8 record;
+} __attribute__ ((packed)) chr_t;
+
+typedef
+struct geom_t {
+	__u16 cyl;
+	__u16 head;
+	__u32 sector;
+} __attribute__ ((packed)) geom_t;
+
+typedef struct eckd_home_t {
+	__u8 skip_control[14];
+	__u16 cell_number;
+	__u8 physical_addr[3];
+	__u8 flag;
+	ch_t track_addr;
+	__u8 reserved;
+	__u8 key_length;
+	__u8 reserved2[2];
+} __attribute__ ((packed)) eckd_home_t;
+
+typedef
+struct DE_eckd_data_t {
+	struct {
+		unsigned char perm:2;	/* Permissions on this extent */
+		unsigned char reserved:1;
+		unsigned char seek:2;	/* Seek control */
+		unsigned char auth:2;	/* Access authorization */
+		unsigned char pci:1;	/* PCI Fetch mode */
+	} __attribute__ ((packed)) mask;
+	struct {
+		unsigned char mode:2;	/* Architecture mode */
+		unsigned char ckd:1;	/* CKD Conversion */
+		unsigned char operation:3;	/* Operation mode */
+		unsigned char cfw:1;	/* Cache fast write */
+		unsigned char dfw:1;	/* DASD fast write */
+	} __attribute__ ((packed)) attributes;
+	__u16 short blk_size;	/* Blocksize */
+	__u16 fast_write_id;
+	__u8 unused;
+	__u8 reserved;
+	ch_t beg_ext;
+	ch_t end_ext;
+} __attribute__ ((packed)) DE_eckd_data_t;
+
+typedef
+struct LO_eckd_data_t {
+	struct {
+		unsigned char orientation:2;
+		unsigned char operation:6;
+	} __attribute__ ((packed)) operation;
+	struct {
+		unsigned char last_bytes_used:1;
+		unsigned char reserved:6;
+		unsigned char read_count_suffix:1;
+	} __attribute__ ((packed)) auxiliary;
+	__u8 unused;
+	__u8 count;
+	ch_t seek_addr;
+	chr_t search_arg;
+	__u8 sector;
+	__u16 length;
+} __attribute__ ((packed)) LO_eckd_data_t;
+
+typedef
+struct dasd_eckd_characteristics_t {
+	__u16 cu_type;
+	struct {
+		unsigned char support:2;
+		unsigned char async:1;
+		unsigned char reserved:1;
+		unsigned char cache_info:1;
+		unsigned char model:3;
+	} __attribute__ ((packed)) cu_model;
+	__u16 dev_type;
+	__u8 dev_model;
+	struct {
+		unsigned char mult_burst:1;
+		unsigned char RT_in_LR:1;
+		unsigned char reserved1:1;
+		unsigned char RD_IN_LR:1;
+		unsigned char reserved2:4;
+		unsigned char reserved3:8;
+		unsigned char defect_wr:1;
+		unsigned char reserved4:2;
+		unsigned char striping:1;
+		unsigned char reserved5:4;
+		unsigned char cfw:1;
+		unsigned char reserved6:2;
+		unsigned char cache:1;
+		unsigned char dual_copy:1;
+		unsigned char dfw:1;
+		unsigned char reset_alleg:1;
+		unsigned char sense_down:1;
+	} __attribute__ ((packed)) facilities;
+	__u8 dev_class;
+	__u8 unit_type;
+	__u16 no_cyl;
+	__u16 trk_per_cyl;
+	__u8 sec_per_trk;
+	__u8 byte_per_track[3];
+	__u16 home_bytes;
+	__u8 formula;
+	union {
+		struct {
+			__u8 f1;
+			__u16 f2;
+			__u16 f3;
+		} __attribute__ ((packed)) f_0x01;
+		struct {
+			__u8 f1;
+			__u8 f2;
+			__u8 f3;
+			__u8 f4;
+			__u8 f5;
+		} __attribute__ ((packed)) f_0x02;
+	} __attribute__ ((packed)) factors;
+	__u16 first_alt_trk;
+	__u16 no_alt_trk;
+	__u16 first_dia_trk;
+	__u16 no_dia_trk;
+	__u16 first_sup_trk;
+	__u16 no_sup_trk;
+	__u8 MDR_ID;
+	__u8 OBR_ID;
+	__u8 director;
+	__u8 rd_trk_set;
+	__u16 max_rec_zero;
+	__u8 reserved1;
+	__u8 RWANY_in_LR;
+	__u8 factor6;
+	__u8 factor7;
+	__u8 factor8;
+	__u8 reserved2[3];
+	__u8 reserved3[10];
+} __attribute__ ((packed)) dasd_eckd_characteristics_t;
+
+typedef struct dasd_eckd_confdata_t {
+	struct {
+		struct {
+			unsigned char identifier:2;
+			unsigned char token_id:1;
+			unsigned char sno_valid:1;
+			unsigned char subst_sno:1;
+			unsigned char recNED:1;
+			unsigned char emuNED:1;
+			unsigned char reserved:1;
+		} __attribute__ ((packed)) flags;
+		__u8 descriptor;
+		__u8 dev_class;
+		__u8 reserved;
+		unsigned char dev_type[6];
+		unsigned char dev_model[3];
+		unsigned char HDA_manufacturer[3];
+		unsigned char HDA_location[2];
+		unsigned char HDA_seqno[12];
+		__u16 ID;
+	} __attribute__ ((packed)) ned1;
+	struct {
+		struct {
+			unsigned char identifier:2;
+			unsigned char token_id:1;
+			unsigned char sno_valid:1;
+			unsigned char subst_sno:1;
+			unsigned char recNED:1;
+			unsigned char emuNED:1;
+			unsigned char reserved:1;
+		} __attribute__ ((packed)) flags;
+		__u8 descriptor;
+		__u8 reserved[2];
+		unsigned char dev_type[6];
+		unsigned char dev_model[3];
+		unsigned char DASD_manufacturer[3];
+		unsigned char DASD_location[2];
+		unsigned char DASD_seqno[12];
+		__u16 ID;
+	} __attribute__ ((packed)) ned2;
+	struct {
+		struct {
+			unsigned char identifier:2;
+			unsigned char token_id:1;
+			unsigned char sno_valid:1;
+			unsigned char subst_sno:1;
+			unsigned char recNED:1;
+			unsigned char emuNED:1;
+			unsigned char reserved:1;
+		} __attribute__ ((packed)) flags;
+		__u8 descriptor;
+		__u8 reserved[2];
+		unsigned char cont_type[6];
+		unsigned char cont_model[3];
+		unsigned char cont_manufacturer[3];
+		unsigned char cont_location[2];
+		unsigned char cont_seqno[12];
+		__u16 ID;
+	} __attribute__ ((packed)) ned3;
+	struct {
+		struct {
+			unsigned char identifier:2;
+			unsigned char token_id:1;
+			unsigned char sno_valid:1;
+			unsigned char subst_sno:1;
+			unsigned char recNED:1;
+			unsigned char emuNED:1;
+			unsigned char reserved:1;
+		} __attribute__ ((packed)) flags;
+		__u8 descriptor;
+		__u8 reserved[2];
+		unsigned char cont_type[6];
+		unsigned char empty[3];
+		unsigned char cont_manufacturer[3];
+		unsigned char cont_location[2];
+		unsigned char cont_seqno[12];
+		__u16 ID;
+	} __attribute__ ((packed)) ned4;
+	unsigned char ned5[32];
+	unsigned char ned6[32];
+	unsigned char ned7[32];
+	struct {
+		struct {
+			unsigned char identifier:2;
+			unsigned char reserved:6;
+		} __attribute__ ((packed)) flags;
+		__u8 selector;
+		__u16 interfaceID;
+		__u32 reserved;
+		__u16 subsystemID;
+		struct {
+			unsigned char sp0:1;
+			unsigned char sp1:1;
+			unsigned char reserved:5;
+			unsigned char scluster:1;
+		} __attribute__ ((packed)) spathID;
+		__u8 unit_address;
+		__u8 dev_ID;
+		__u8 dev_address;
+		__u8 adapterID;
+		__u16 link_address;
+		struct {
+			unsigned char parallel:1;
+			unsigned char escon:1;
+			unsigned char reserved:1;
+			unsigned char ficon:1;
+			unsigned char reserved2:4;
+		} __attribute__ ((packed)) protocol_type;
+		struct {
+			unsigned char PID_in_236:1;
+			unsigned char reserved:7;
+		} __attribute__ ((packed)) format_flags;
+		__u8 log_dev_address;
+		unsigned char reserved2[12];
+	} __attribute__ ((packed)) neq;
+} __attribute__ ((packed)) dasd_eckd_confdata_t;
+
+int dasd_eckd_init( void );
+
+#endif /* DASD_ECKD_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_eckd_erp.c linux.17p18/drivers/s390/block/dasd_eckd_erp.c
--- linux.vanilla/drivers/s390/block/dasd_eckd_erp.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_eckd_erp.c	Tue Aug  1 07:59:49 2000
@@ -5,7 +5,7 @@
  * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
  */
 
-#include <linux/dasd.h>
+#include <asm/dasd.h>
 #include "dasd_erp.h"
 
 #define PRINTK_HEADER "dasd_erp(eckd)"
@@ -14,16 +14,4 @@
 dasd_eckd_erp_examine (cqr_t * cqr, devstat_t * stat)
 {
 
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
-		return dasd_era_none;
-
-	switch (dasd_info[cqr->devindex]->info.sid_data.cu_model) {
-	case 0x3990:
-		return dasd_3990_erp_examine (cqr, stat);
-	case 0x9343:
-		return dasd_9343_erp_examine (cqr, stat);
-	default:
-		return dasd_era_recover;
-	}
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_erp.c linux.17p18/drivers/s390/block/dasd_erp.c
--- linux.vanilla/drivers/s390/block/dasd_erp.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_erp.c	Thu Jan  1 01:00:00 1970
@@ -1,77 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_erp.c
- * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
- */
-
-#include <asm/irq.h>
-#include <linux/dasd.h>
-#include "dasd_erp.h"
-
-#define PRINTK_HEADER "dasd_erp"
-
-dasd_era_t
-dasd_erp_examine (cqr_t * cqr, devstat_t * stat)
-{
-	int rc;
-	if (stat->cstat == 0x00 &&
-	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {
-		PRINT_WARN ("No error detected\n");
-		rc = dasd_era_none;
-	} else if (!(stat->flag & DEVSTAT_FLAG_SENSE_AVAIL)) {
-		PRINT_WARN ("No sense data available, try to recover anyway\n");
-		rc = dasd_era_recover;
-	} else
-#if DASD_PARANOIA > 1
-	if (!dasd_disciplines[dasd_info[cqr->devindex]->type]->
-		 erp_examine) {
-		INTERNAL_CHECK ("No erp_examinator for dt=%d\n",
-				dasd_info[cqr->devindex]->type);
-		rc = dasd_era_fatal;
-	} else
-#endif
-	{
-		PRINT_WARN ("calling examinator\n");
-		rc = dasd_disciplines[dasd_info[cqr->devindex]->type]->
-			erp_examine (cqr, stat);
-	}
-	PRINT_WARN("ERP action code = %d\n",rc);
-	return rc;
-}
-
-void
-default_erp_action (erp_t * erp)
-{
-	cqr_t *cqr = erp->cqr.int4cqr;
-	ccw1_t *cpa = request_cp(1,0);
-
-	memset (cpa,0,sizeof(ccw1_t));
-
-	cpa -> cmd_code = CCW_CMD_NOOP;
-	
-	((cqr_t *) erp)->cpaddr = cpa;
-	if (cqr->retries++ <= 16) {
-		ACS (cqr->status,
-		     CQR_STATUS_ERP_PEND,
-		     CQR_STATUS_QUEUED);
-	} else {
-		PRINT_WARN ("ERP retry count exceeded\n");
-		ACS (cqr->status,
-		     CQR_STATUS_ERP_PEND,
-		     CQR_STATUS_FAILED);
-	}
-	atomic_set (&(((cqr_t *) erp)->status), CQR_STATUS_FILLED);
-}
-
-dasd_erp_action_t
-dasd_erp_action (struct cqr_t *cqr)
-{
-	return default_erp_action;
-}
-
-dasd_erp_action_t
-dasd_erp_postaction (struct erp_t * erp)
-{
-	return NULL;
-}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_erp.h linux.17p18/drivers/s390/block/dasd_erp.h
--- linux.vanilla/drivers/s390/block/dasd_erp.h	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_erp.h	Thu Jan  1 01:00:00 1970
@@ -1,32 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_erp.h
- * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
- */
-
-#ifndef DASD_ERP_H
-#define DASD_ERP_H
-
-typedef enum {
-	dasd_era_fatal = -1,	/* no chance to recover              */
-	dasd_era_none = 0,	/* don't recover, everything alright */
-	dasd_era_msg = 1,	/* don't recover, just report...     */
-	dasd_era_recover = 2	/* recovery action recommended       */
-} dasd_era_t;
-
-#include "dasd_types.h"
-
-typedef struct erp_t {
-	struct cqr_t cqr;
-} __attribute__ ((packed)) 
-
-erp_t;
-
-typedef void (*dasd_erp_action_t) (erp_t *);
-
-dasd_era_t dasd_erp_examine (struct cqr_t *, devstat_t *);
-dasd_erp_action_t dasd_erp_action (struct cqr_t *);
-dasd_erp_action_t dasd_erp_postaction (struct erp_t *);
-
-#endif				/* DASD_ERP_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_fba.c linux.17p18/drivers/s390/block/dasd_fba.c
--- linux.vanilla/drivers/s390/block/dasd_fba.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_fba.c	Tue Aug  1 07:59:49 2000
@@ -1,68 +1,51 @@
+/* 
+ * File...........: linux/drivers/s390/block/dasd_fba.c
+ * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+ * Bugreports.to..: <Linux390@de.ibm.com>
+ * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
+ */
 
 #include <linux/stddef.h>
 #include <linux/kernel.h>
-
-#ifdef MODULE
-#include <linux/module.h>
-#endif				/* MODULE */
+#include <asm/debug.h>
 
 #include <linux/malloc.h>
-#include <linux/dasd.h>
 #include <linux/hdreg.h>	/* HDIO_GETGEO                      */
+#include <linux/blk.h>
+#include <asm/ccwcache.h>
+#include <asm/dasd.h>
 
+#include <asm/ebcdic.h>
 #include <asm/io.h>
-
 #include <asm/irq.h>
 
-#include "dasd_types.h"
-#include "dasd_ccwstuff.h"
+#include "dasd.h"
+#include "dasd_fba.h"
 
-#define DASD_FBA_CCW_LOCATE 0x43
-#define DASD_FBA_CCW_READ   0x42
-#define DASD_FBA_CCW_WRITE  0x41
 
 #ifdef PRINTK_HEADER
 #undef PRINTK_HEADER
 #endif				/* PRINTK_HEADER */
-#define PRINTK_HEADER "dasd(fba):"
+#define PRINTK_HEADER DASD_NAME"(fba):"
 
-typedef
-struct {
-	struct {
-		unsigned char perm:2;	/* Permissions on this extent */
-		unsigned char zero:2;	/* Must be zero */
-		unsigned char da:1;	/* usually zero */
-		unsigned char diag:1;	/* allow diagnose */
-		unsigned char zero2:2;	/* zero */
-	} __attribute__ ((packed)) mask;
-	unsigned char zero;	/* Must be zero */
-	unsigned short blk_size;	/* Blocksize */
-	unsigned long ext_loc;	/* Extent locator */
-	unsigned long ext_beg;	/* logical number of block 0 in extent */
-	unsigned long ext_end;	/* logocal number of last block in extent */
-} __attribute__ ((packed, aligned (32)))
-
-DE_fba_data_t;
-
-typedef
-struct {
-	struct {
-		unsigned char zero:4;
-		unsigned char cmd:4;
-	} __attribute__ ((packed)) operation;
-	unsigned char auxiliary;
-	unsigned short blk_ct;
-	unsigned long blk_nr;
-} __attribute__ ((packed, aligned (32)))
+#define DASD_FBA_CCW_WRITE 0x41
+#define DASD_FBA_CCW_READ 0x42
+#define DASD_FBA_CCW_LOCATE 0x43
+#define DASD_FBA_CCW_DEFINE_EXTENT 0x63
+
+dasd_discipline_t dasd_fba_discipline;
 
-LO_fba_data_t;
+typedef struct
+dasd_fba_private_t {
+        dasd_fba_characteristics_t rdc_data;
+} dasd_fba_private_t;
 
-static void
+static inline void
 define_extent (ccw1_t * ccw, DE_fba_data_t * DE_data, int rw,
 	       int blksize, int beg, int nr)
 {
 	memset (DE_data, 0, sizeof (DE_fba_data_t));
-	ccw->cmd_code = CCW_DEFINE_EXTENT;
+	ccw->cmd_code = DASD_FBA_CCW_DEFINE_EXTENT;
 	ccw->count = 16;
 	ccw->cda = (void *) __pa (DE_data);
 	if (rw == WRITE)
@@ -76,7 +59,7 @@
 	DE_data->ext_end = nr - 1;
 }
 
-static void
+static inline void
 locate_record (ccw1_t * ccw, LO_fba_data_t * LO_data, int rw, int block_nr,
 	       int block_ct)
 {
@@ -94,46 +77,174 @@
 	LO_data->blk_ct = block_ct;
 }
 
-int
-dasd_fba_ck_devinfo (dev_info_t * info)
+
+static int 
+dasd_fba_id_check ( dev_info_t *info )
 {
+	if ( info->sid_data.cu_type == 0x3880 ) 
+                if ( info->sid_data.dev_type == 0x3370 )
+                        return 0;
+        if ( info->sid_data.cu_type == 0x6310 )
+                if ( info->sid_data.dev_type == 0x9336 )
 	return 0;
+        return -ENODEV;
 }
 
-cqr_t *
-dasd_fba_build_req (int devindex,
-		    struct request * req)
+static int
+dasd_fba_check_characteristics (struct dasd_device_t *device)
 {
-	cqr_t *rw_cp = NULL;
-	ccw1_t *ccw;
+        int rc = -ENODEV;
+        void *rdc_data;
+        dasd_fba_private_t *private;
+
+        if ( device == NULL ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "Null device pointer passed to characteristics checker\n");
+                return -ENODEV;
+        }
+        if ( device->private == NULL ) {
+		device->private = kmalloc(sizeof(dasd_fba_private_t),GFP_KERNEL);
+		if ( device->private == NULL ) {
+			printk ( KERN_WARNING PRINTK_HEADER
+				 "memory allocation failed for private data\n");
+			return -ENOMEM;
+		}
+        }
+        private = (dasd_fba_private_t *)device->private;
+        rdc_data = (void *)&(private->rdc_data);
+        rc = read_dev_chars (device->devinfo.irq, &rdc_data , 32);
+        if ( rc ) {
+                printk ( KERN_WARNING PRINTK_HEADER
+                         "Read device characteristics returned error %d\n",rc);
+                return rc;
+        }
+	printk ( KERN_INFO PRINTK_HEADER 
+		 "%04X on sch %d: %04X/%02X(CU:%04X/%02X) %dMB at(%d B/blk)\n",
+                 device->devinfo.devno, device->devinfo.irq,
+                 device->devinfo.sid_data.dev_type, device->devinfo.sid_data.dev_model,
+                 device->devinfo.sid_data.cu_type, device->devinfo.sid_data.cu_model,
+		 (private->rdc_data.blk_bdsa * 
+		  (private->rdc_data.blk_size >> 9)) >> 11,
+		 private->rdc_data.blk_size);
+        return 0;
+}
 
-	DE_fba_data_t *DE_data;
-	LO_fba_data_t *LO_data;
-	struct buffer_head *bh;
+static int
+dasd_fba_do_analysis (struct dasd_device_t *device)
+{
+	int rc = 0;
+	int sb;
+        dasd_fba_private_t *private = (dasd_fba_private_t *)device->private;
+	int bs = private->rdc_data.blk_size;
+
+        memset (&(device->sizes), 0, sizeof (dasd_sizes_t));
+        switch ( bs ) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+		device->sizes.bp_block = bs;
+                break;
+        default:
+                printk ( KERN_INFO PRINTK_HEADER 
+                         "/dev/%s (%04X): unknown blocksize %d\n",
+                         device->name, device->devinfo.devno,bs);
+		return -EMEDIUMTYPE;
+	}
+	device->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
+	for (sb = 512; sb < bs; sb = sb << 1)
+		device->sizes.s2b_shift++;
+	
+	device->sizes.blocks = (private->rdc_data.blk_bdsa);
+
+	return rc;
+}
+
+static int
+dasd_fba_fill_geometry(struct dasd_device_t *device, struct hd_geometry *geo)
+{
+        int rc = 0;
+	unsigned long sectors = device->sizes.blocks << device->sizes.s2b_shift;
+	unsigned long tracks = sectors >> 6;
+	unsigned long trk_rem = sectors & ((1<<6)-1);
+	unsigned long cyls = tracks >> 4;
+	unsigned long cyls_rem = tracks & ((1<<4)-1);
+
+        switch(device->sizes.bp_block) {
+        case 512:
+        case 1024:
+        case 2048:
+        case 4096:
+                break;
+        default:
+                return -EINVAL;
+        }
+	geo->cylinders = cyls;
+	geo->heads = 16;
+	geo->sectors = 128 >> device->sizes.s2b_shift;
+	geo->start = 1;
+        return rc;
+}
+
+static dasd_era_t
+dasd_fba_examine_error  (ccw_req_t *cqr, devstat_t * stat)
+{
+        dasd_device_t *device = (dasd_device_t *)cqr->device;
+        if (stat->cstat == 0x00 &&
+	    stat->dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END))
+		return dasd_era_none;
+        
+	switch (device->devinfo.sid_data.dev_model) {
+	case 0x3370:
+		return dasd_3370_erp_examine (cqr, stat);
+	case 0x9336:
+		return dasd_9336_erp_examine (cqr, stat);
+	default:
+		return dasd_era_recover;
+	}
+}
+
+static dasd_erp_action_fn_t 
+dasd_fba_erp_action ( ccw_req_t * cqr ) 
+{
+        return default_erp_action;
+}
+
+static dasd_erp_postaction_fn_t
+dasd_fba_erp_postaction (ccw_req_t * cqr)
+{
+        if ( cqr -> function == default_erp_action)
+                return default_erp_postaction;
+        printk ( KERN_WARNING PRINTK_HEADER
+                 "unknown ERP action %p\n",
+                 cqr -> function);
+	return NULL;
+}
+
+static ccw_req_t *
+dasd_fba_build_cp_from_req (dasd_device_t *device, struct request *req)
+{
+        ccw_req_t *rw_cp = NULL;
 	int rw_cmd;
-	int byt_per_blk = dasd_info[devindex]->sizes.bp_block;
 	int bhct;
 	long size;
+        ccw1_t *ccw;
+	DE_fba_data_t *DE_data;
+	LO_fba_data_t *LO_data;
+	struct buffer_head *bh;
+        dasd_fba_private_t *private = (dasd_fba_private_t *)device->private;
+	int byt_per_blk = device->sizes.bp_block;
 
-	if (!req->nr_sectors) {
-		PRINT_ERR ("No blocks to write...returning\n");
-		return NULL;
-	}
 	if (req->cmd == READ) {
 		rw_cmd = DASD_FBA_CCW_READ;
-	} else
-#if DASD_PARANOIA > 2
-	if (req->cmd == WRITE)
-#endif				/* DASD_PARANOIA */
-	{
+	} else if (req->cmd == WRITE) {
 		rw_cmd = DASD_FBA_CCW_WRITE;
-	}
-#if DASD_PARANOIA > 2
-	else {
+	} else {
 		PRINT_ERR ("Unknown command %d\n", req->cmd);
 		return NULL;
 	}
-#endif				/* DASD_PARANOIA */
+	/* Build the request */
+	/* count bhs to prevent errors, when bh smaller than block */
 	bhct = 0;
 	for (bh = req->bh; bh; bh = bh->b_reqnext) {
 		if (bh->b_size > byt_per_blk)
@@ -143,8 +254,8 @@
 			bhct++;
 	}
 
-	/* Build the request */
-	rw_cp = request_cqr (2 + bhct,
+	rw_cp = dasd_alloc_request (dasd_fba_discipline.name,
+                                   2 + bhct,
 			     sizeof (DE_fba_data_t) +
 			     sizeof (LO_fba_data_t));
 	if (!rw_cp) {
@@ -160,11 +271,12 @@
 	ccw++;
 	locate_record (ccw, LO_data, req->cmd, 0, req->nr_sectors);
 	ccw->flags = CCW_FLAG_CC;
+
 	for (bh = req->bh; bh;) {
 		if (bh->b_size > byt_per_blk) {
 			for (size = 0; size < bh->b_size; size += byt_per_blk) {
 				ccw++;
-				if (dasd_info[devindex]->rdc_data->fba.mode.bits.data_chain) {
+				if (private->rdc_data.mode.bits.data_chain) {
 					ccw->flags = CCW_FLAG_DC;
 				} else {
 					ccw->flags = CCW_FLAG_CC;
@@ -177,11 +289,11 @@
 		} else {	/* group N bhs to fit into byt_per_blk */
 			for (size = 0; bh != NULL && size < byt_per_blk;) {
 				ccw++;
-				if (dasd_info[devindex]->rdc_data->fba.mode.bits.data_chain) {
+				if (private->rdc_data.mode.bits.data_chain) {
 					ccw->flags = CCW_FLAG_DC;
 				} else {
 					PRINT_WARN ("Cannot chain chunks smaller than one block\n");
-					release_cqr (rw_cp);
+					ccw_free_request (rw_cp);
 					return NULL;
 				}
 				ccw->cmd_code = rw_cmd;
@@ -193,164 +305,80 @@
 			ccw->flags = CCW_FLAG_CC;
 			if (size != byt_per_blk) {
 				PRINT_WARN ("Cannot fulfill request smaller than block\n");
-				release_cqr (rw_cp);
+				ccw_free_request (rw_cp);
 				return NULL;
 			}
 		}
 	}
 	ccw->flags &= ~(CCW_FLAG_DC | CCW_FLAG_CC);
+
+        rw_cp->device = device;
+        rw_cp->expires = 5 * 0xf424000; /* 5 seconds */
+        rw_cp->req = req;
+        atomic_compare_and_swap_debug(&rw_cp->status,CQR_STATUS_EMPTY,CQR_STATUS_FILLED);
 	return rw_cp;
 }
 
-void
-dasd_fba_print_char (dasd_characteristics_t * ct)
-{
-	dasd_fba_characteristics_t *c =
-	(dasd_fba_characteristics_t *) ct;
-	PRINT_INFO ("%d blocks of %d bytes %d MB\n",
-		    c->blk_bdsa, c->blk_size,
-		    (c->blk_bdsa * (c->blk_size >> 9)) >> 11);
-	PRINT_INFO ("%soverrun, %s mode, data chains %sallowed\n"
-		    "%sremovable, %sshared\n",
-		    (c->mode.bits.overrunnable ? "" : "no "),
-		    (c->mode.bits.burst_byte ? "burst" : "byte"),
-		    (c->mode.bits.data_chain ? "" : "not "),
-		    (c->features.bits.removable ? "" : "not "),
-		    (c->features.bits.shared ? "" : "not "));
-};
-
-int
-dasd_fba_ck_char (dasd_characteristics_t * rdc)
+static char *
+dasd_fba_dump_sense(struct dasd_device_t *device, ccw_req_t *req)
 {
-	int rc = 0;
-	dasd_fba_print_char (rdc);
-	return rc;
+        char *page = (char *)get_free_page(GFP_KERNEL);
+        int len;
+        if ( page == NULL ) {
+                return NULL;
 }
 
-cqr_t *
-dasd_fba_fill_sizes_first (int di)
-{
-	cqr_t *rw_cp = NULL;
-	ccw1_t *ccw;
-	DE_fba_data_t *DE_data;
-	LO_fba_data_t *LO_data;
-	dasd_information_t *info = dasd_info[di];
-	static char buffer[8];
-
-	dasd_info[di]->sizes.label_block = 1;
+        len = sprintf ( page, KERN_WARNING PRINTK_HEADER 
+                        "device %04X on irq %d: I/O status report:\n",
+                        device->devinfo.devno,device->devinfo.irq);
+                        
 
-	rw_cp = request_cqr (3,
-			     sizeof (DE_fba_data_t) +
-			     sizeof (LO_fba_data_t));
-	DE_data = rw_cp->data;
-	LO_data = rw_cp->data + sizeof (DE_fba_data_t);
-	ccw = rw_cp->cpaddr;
-	define_extent (ccw, DE_data, READ, info->sizes.bp_block, 1, 1);
-	ccw->flags = CCW_FLAG_CC;
-	ccw++;
-	locate_record (ccw, LO_data, READ, 0, 1);
-	ccw->flags = CCW_FLAG_CC;
-	ccw++;
-	ccw->cmd_code = DASD_FBA_CCW_READ;
-	ccw->flags = CCW_FLAG_SLI;
-	ccw->count = 8;
-	ccw->cda = (void *) __pa (buffer);
-	rw_cp->devindex = di;
-	atomic_set (&rw_cp->status, CQR_STATUS_FILLED);
-	return rw_cp;
+        return page;
 }
 
-int
-dasd_fba_fill_sizes_last (int devindex)
-{
-	int rc = 0;
-	int sb;
-	dasd_information_t *info = dasd_info[devindex];
-
-	info->sizes.bp_sector = info->rdc_data->fba.blk_size;
-	info->sizes.bp_block = info->sizes.bp_sector;
-
-	info->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
-	for (sb = 512; sb < info->sizes.bp_sector; sb = sb << 1)
-		info->sizes.s2b_shift++;
-
-	info->sizes.blocks = (info->rdc_data->fba.blk_bdsa);
-
-	if (info->sizes.s2b_shift >= 1)
-		info->sizes.kbytes = info->sizes.blocks <<
-		    (info->sizes.s2b_shift - 1);
-	else
-		info->sizes.kbytes = info->sizes.blocks >>
-		    (-(info->sizes.s2b_shift - 1));
-
-	return rc;
-}
+dasd_discipline_t dasd_fba_discipline = {
+	name :                          "FBA ",
+	ebcname :                       "FBA ",
+        id_check:                       dasd_fba_id_check,          
+        check_characteristics:          dasd_fba_check_characteristics,
+        do_analysis:                    dasd_fba_do_analysis,          
+        fill_geometry:                  dasd_fba_fill_geometry,
+        start_IO:                       dasd_start_IO,           
+        examine_error:                  dasd_fba_examine_error,          
+        erp_action:                     dasd_fba_erp_action,             
+        erp_postaction:                 dasd_fba_erp_postaction,         
+        build_cp_from_req:              dasd_fba_build_cp_from_req,      
+        dump_sense:                     dasd_fba_dump_sense,            
+        int_handler:                    dasd_int_handler            
+};
 
 int
-dasd_fba_format (int devindex, format_data_t * fdata)
-{
+dasd_fba_init( void ) {
 	int rc = 0;
+        printk ( KERN_INFO PRINTK_HEADER
+                 "%s discipline initializing\n", dasd_fba_discipline.name);
+        ASCEBC(dasd_fba_discipline.ebcname,4);
+        dasd_discipline_enq(&dasd_fba_discipline);
+
 	return rc;
 }
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
 
-void
-dasd_fba_fill_geometry (int di, struct hd_geometry *geo)
-{
-	int bfactor, nr_sectors, sec_size;
-	int trk_cap, trk_low, trk_high, tfactor, nr_trks, trk_size;
-	int cfactor, nr_cyls, cyl_size;
-	int remainder;
-
-	dasd_information_t *info = dasd_info[di];
-	PRINT_INFO ("FBA has no geometry! Faking one...\n%s", "");
-
-	/* determine the blocking factor of sectors */
-	for (bfactor = 8; bfactor > 0; bfactor--) {
-		remainder = info->rdc_data->fba.blk_bdsa % bfactor;
-		PRINT_INFO ("bfactor %d remainder %d\n", bfactor, remainder);
-		if (!remainder)
-			break;
-	}
-	nr_sectors = info->rdc_data->fba.blk_bdsa / bfactor;
-	sec_size = info->rdc_data->fba.blk_size * bfactor;
-	
-	geo -> sectors = bfactor;
 
-	/* determine the nr of sectors per track */
-	trk_cap = (64 * 1 << 10) / sec_size;	/* 64k in sectors */
-	trk_low = trk_cap * 2 / 3;
-	trk_high = trk_cap * 4 / 3;
-	for (tfactor = trk_high; tfactor > trk_low; tfactor--) {
-		PRINT_INFO ("remainder %d\n", remainder);
-		remainder = nr_sectors % bfactor;
-		if (!remainder)
-			break;
-	}
-	nr_trks = nr_sectors / tfactor;
-	trk_size = sec_size * tfactor;
-
-	/* determine the nr of trks per cylinder */
-	for (cfactor = 31; cfactor > 0; cfactor--) {
-		PRINT_INFO ("remainder %d\n", remainder);
-		remainder = nr_trks % bfactor;
-		if (!remainder)
-			break;
-	}
-	nr_cyls = nr_trks / cfactor;
-	sec_size = info->rdc_data->fba.blk_size * bfactor;
-
-	geo -> heads = nr_trks;
-	geo -> cylinders = nr_cyls;
-	geo -> start = info->sizes.label_block + 1;
-}
-
-dasd_operations_t dasd_fba_operations =
-{
-	ck_devinfo:dasd_fba_ck_devinfo,
-	get_req_ccw:dasd_fba_build_req,
-	ck_characteristics:dasd_fba_ck_char,
-	fill_sizes_first:dasd_fba_fill_sizes_first,
-	fill_sizes_last:dasd_fba_fill_sizes_last,
-	dasd_format:dasd_fba_format,
-	fill_geometry:dasd_fba_fill_geometry
-};
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_fba.h linux.17p18/drivers/s390/block/dasd_fba.h
--- linux.vanilla/drivers/s390/block/dasd_fba.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/block/dasd_fba.h	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,70 @@
+#ifndef DASD_FBA_H
+#define DASD_FBA_H
+
+typedef 
+struct DE_fba_data_t {
+	struct {
+		unsigned char perm:2;	/* Permissions on this extent */
+		unsigned char zero:2;	/* Must be zero */
+		unsigned char da:1;	/* usually zero */
+		unsigned char diag:1;	/* allow diagnose */
+		unsigned char zero2:2;	/* zero */
+	} __attribute__ ((packed)) mask;
+	__u8 zero;	/* Must be zero */
+	__u16 blk_size;	/* Blocksize */
+	__u32 ext_loc;	/* Extent locator */
+	__u32 ext_beg;	/* logical number of block 0 in extent */
+	__u32 ext_end;	/* logocal number of last block in extent */
+} __attribute__ ((packed)) DE_fba_data_t;
+
+typedef 
+struct LO_fba_data_t {
+	struct {
+		unsigned char zero:4;
+		unsigned char cmd:4;
+	} __attribute__ ((packed)) operation;
+	__u8 auxiliary;
+	__u16 blk_ct;
+	__u32 blk_nr;
+} __attribute__ ((packed)) LO_fba_data_t; 
+
+
+typedef 
+struct dasd_fba_characteristics_t {
+	union {
+		__u8 c;
+		struct {
+			unsigned char reserved:1;
+			unsigned char overrunnable:1;
+			unsigned char burst_byte:1;
+			unsigned char data_chain:1;
+			unsigned char zeros:4;
+		} __attribute__ ((packed)) bits;
+	} __attribute__ ((packed)) mode;
+	union {
+		__u8 c;
+		struct {
+			unsigned char zero0:1;
+			unsigned char removable:1;
+			unsigned char shared:1;
+			unsigned char zero1:1;
+			unsigned char mam:1;
+			unsigned char zeros:3;
+		} __attribute__ ((packed)) bits;
+	} __attribute__ ((packed)) features;
+	__u8 dev_class;
+	__u8 unit_type;
+	__u16 blk_size;
+	__u32 blk_per_cycl;
+	__u32 blk_per_bound;
+	__u32 blk_bdsa;
+	__u32 reserved0;
+	__u16 reserved1;
+	__u16 blk_ce;
+	__u32 reserved2;
+	__u16 reserved3;
+} __attribute__ ((packed)) dasd_fba_characteristics_t;
+
+int dasd_fba_init( void );
+
+#endif /* DASD_FBA_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_mdsk.c linux.17p18/drivers/s390/block/dasd_mdsk.c
--- linux.vanilla/drivers/s390/block/dasd_mdsk.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_mdsk.c	Thu Jan  1 01:00:00 1970
@@ -1,366 +0,0 @@
-#include <linux/dasd.h>
-#include <linux/malloc.h>
-#include <linux/ctype.h>
-#include "dasd_types.h"
-#include "dasd_ccwstuff.h"
-#include "dasd_mdsk.h"
-
-#ifdef PRINTK_HEADER
-#undef PRINTK_HEADER
-#endif				/* PRINTK_HEADER */
-#define PRINTK_HEADER "dasd(mdsk):"
-
-int dasd_is_accessible (int devno);
-void dasd_insert_range (int start, int end);
-
-/*
- * The device characteristics function
- */
-static __inline__ int
-dia210 (void *devchar)
-{
-	int rc;
-
-	asm volatile ("    lr    2,%1\n"
-		      "    .long 0x83200210\n"
-		      "    ipm   %0\n"
-		      "    srl   %0,28"
-		      :"=d" (rc)
-		      :"d" ((void *) __pa (devchar))
-		      :"2");
-	return rc;
-}
-
-static __inline__ int
-dia250 (void *iob, int cmd)
-{
-	int rc;
-
-	asm volatile ("    lr    2,%1\n"
-		      "    lr    3,%2\n"
-		      "    .long 0x83230250\n"
-		      "    lr    %0,3"
-		      :"=d" (rc)
-		      :"d" ((void *) __pa (iob)), "d" (cmd)
-		      :"2", "3");
-	return rc;
-}
-
-/*
- * Init of minidisk device
- */
-
-static __inline__ int
-mdsk_init_io (int di, int blocksize, int offset, int size)
-{
-	mdsk_init_io_t *iib = &(dasd_info[di]->private.mdsk.iib);
-	int rc;
-
-	memset (iib, 0, sizeof (mdsk_init_io_t));
-
-	iib->dev_nr = dasd_info[di]->info.devno;
-	iib->block_size = blocksize;
-	iib->offset = offset;
-	iib->start_block = 0;
-	iib->end_block = size;
-
-	rc = dia250 (iib, INIT_BIO);
-
-	return rc;
-}
-
-/*
- * release of minidisk device
- */
-
-static __inline__ int
-mdsk_term_io (int di)
-{
-	mdsk_init_io_t *iib = &(dasd_info[di]->private.mdsk.iib);
-	int rc;
-
-	memset (iib, 0, sizeof (mdsk_init_io_t));
-	iib->dev_nr = dasd_info[di]->info.devno;
-	rc = dia250 (iib, TERM_BIO);
-	return rc;
-}
-
-void dasd_do_chanq (void);
-void dasd_schedule_bh (void (*func) (void));
-int register_dasd_last (int di);
-
-int
-dasd_mdsk_start_IO (cqr_t * cqr)
-{
-	int rc;
-	mdsk_rw_io_t *iob = &(dasd_info[cqr->devindex]->private.mdsk.iob);
-
-	iob->dev_nr = dasd_info[cqr->devindex]->info.devno;
-	iob->key = 0;
-	iob->flags = 2;
-	iob->block_count = cqr->cplength >> 1;
-	iob->interrupt_params = (u32) cqr;
-	iob->bio_list = __pa (cqr->cpaddr);
-
-	asm volatile ("STCK %0":"=m" (cqr->startclk));
-	rc = dia250 (iob, RW_BIO);
-	if (rc > 8) {
-		PRINT_WARN ("dia250 returned CC %d\n", rc);
-		ACS (cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_ERROR);
-	} else {
-		ACS (cqr->status, CQR_STATUS_QUEUED, CQR_STATUS_IN_IO);
-		atomic_dec (&chanq_tasks);
-	}
-	return rc;
-}
-
-void 
-do_dasd_mdsk_interrupt (struct pt_regs *regs, __u16 code)
-{
-	int intparm = S390_lowcore.ext_params;
-	char status = *((char *) S390_lowcore.ext_params + 5);
-	cqr_t *cqr = (cqr_t *) intparm;
-	if (!intparm)
-		return;
-	if (cqr->magic != MDSK_MAGIC) {
-		panic ("unknown magic number\n");
-	}
-	asm volatile ("STCK %0":"=m" (cqr->stopclk));
-	if (atomic_read (&dasd_info[cqr->devindex]->status) ==
-	    DASD_INFO_STATUS_DETECTED) {
-		register_dasd_last (cqr->devindex);
-	}
-	switch (status) {
-	case 0x00:
-		ACS (cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_DONE);
-		break;
-	case 0x01:
-	case 0x02:
-	case 0x03:
-	default:
-		ACS (cqr->status, CQR_STATUS_IN_IO, CQR_STATUS_FAILED);
-		atomic_inc (&dasd_info[cqr->devindex]->
-			    queue.dirty_requests);
-		break;
-	}
-	atomic_inc (&chanq_tasks);
-	dasd_schedule_bh (dasd_do_chanq);
-}
-
-cqr_t *
-dasd_mdsk_build_req (int devindex,
-		     struct request *req)
-{
-	cqr_t *rw_cp = NULL;
-	struct buffer_head *bh;
-	int rw_cmd;
-	dasd_information_t *info = dasd_info[devindex];
-	int noblk = req->nr_sectors >> info->sizes.s2b_shift;
-	int byt_per_blk = info->sizes.bp_block;
-	int block;
-	mdsk_bio_t *bio;
-	int bhct;
-	long size;
-
-	if (!noblk) {
-		PRINT_ERR ("No blocks to write...returning\n");
-		return NULL;
-	}
-	if (req->cmd == READ) {
-		rw_cmd = MDSK_READ_REQ;
-	} else
-#if DASD_PARANOIA > 2
-	if (req->cmd == WRITE)
-#endif				/* DASD_PARANOIA */
-	{
-		rw_cmd = MDSK_WRITE_REQ;
-	}
-#if DASD_PARANOIA > 2
-	else {
-		PRINT_ERR ("Unknown command %d\n", req->cmd);
-		return NULL;
-	}
-#endif				/* DASD_PARANOIA */
-	bhct = 0;
-	for (bh = req->bh; bh; bh = bh->b_reqnext) {
-		if (bh->b_size > byt_per_blk)
-			for (size = 0; size < bh->b_size; size += byt_per_blk)
-				bhct++;
-		else
-			bhct++;
-	}
-	/* Build the request */
-	rw_cp = request_cqr (MDSK_BIOS (bhct), 0);
-	if (!rw_cp) {
-		return NULL;
-	}
-	rw_cp->magic = MDSK_MAGIC;
-	bio = (mdsk_bio_t *) (rw_cp->cpaddr);
-
-	block = req->sector >> info->sizes.s2b_shift;
-	for (bh = req->bh; bh; bh = bh->b_reqnext) {
-		if (bh->b_size >= byt_per_blk) {
-			memset (bio, 0, sizeof (mdsk_bio_t));
-			for (size = 0; size < bh->b_size; size += byt_per_blk) {
-				bio->type = rw_cmd;
-				bio->block_number = block + 1;
-				bio->buffer = __pa (bh->b_data + size);
-				bio++;
-				block++;
-			}
-		} else {
-			PRINT_WARN ("Cannot fulfill request smaller than block\n");
-			release_cqr (rw_cp);
-			return NULL;
-		}
-	}
-	return rw_cp;
-}
-
-int
-dasd_mdsk_ck_devinfo (dev_info_t * info)
-{
-	int rc = 0;
-
-	dasd_mdsk_characteristics_t devchar =
-	{0,};
-
-	devchar.dev_nr = info->devno;
-	devchar.rdc_len = sizeof (dasd_mdsk_characteristics_t);
-
-	if (dia210 (&devchar) != 0) {
-		return -ENODEV;
-	}
-	if (devchar.vdev_class == DEV_CLASS_FBA ||
-	    devchar.vdev_class == DEV_CLASS_ECKD ||
-	    devchar.vdev_class == DEV_CLASS_CKD) {
-		return 0;
-	} else {
-		return -ENODEV;
-	}
-	return rc;
-}
-
-int
-dasd_mdsk_ck_characteristics (dasd_characteristics_t * dchar)
-{
-	int rc = 0;
-	dasd_mdsk_characteristics_t *devchar =
-	(dasd_mdsk_characteristics_t *) dchar;
-
-	if (dia210 (devchar) != 0) {
-		return -ENODEV;
-	}
-	if (devchar->vdev_class != DEV_CLASS_FBA &&
-	    devchar->vdev_class != DEV_CLASS_ECKD &&
-	    devchar->vdev_class != DEV_CLASS_CKD) {
-		return -ENODEV;
-	}
-	return rc;
-}
-
-cqr_t *
-dasd_mdsk_fill_sizes_first (int di)
-{
-	cqr_t *cqr = NULL;
-	dasd_information_t *info = dasd_info[di];
-	mdsk_bio_t *bio;
-	int bsize;
-	int rc;
-	/* Figure out position of label block */
-	if (info->rdc_data->mdsk.vdev_class == DEV_CLASS_FBA) {
-		info->sizes.label_block = 1;
-	} else if (info->rdc_data->mdsk.vdev_class == DEV_CLASS_ECKD ||
-		   info->rdc_data->mdsk.vdev_class == DEV_CLASS_CKD) {
-		dasd_info[di]->sizes.label_block = 2;
-	} else {
-		return NULL;
-	}
-
-	/* figure out blocksize of device */
-	mdsk_term_io (di);
-	for (bsize = 512; bsize <= PAGE_SIZE; bsize = bsize << 1) {
-		rc = mdsk_init_io (di, bsize, 0, 64);
-		if (rc <= 4) {
-			break;
-		}
-	}
-	if (bsize > PAGE_SIZE) {
-		PRINT_INFO ("Blocksize larger than 4096??\n");
-		rc = mdsk_term_io (di);
-		return NULL;
-	}
-	dasd_info[di]->sizes.bp_sector = bsize;
-
-	info->private.mdsk.label = (long *) get_free_page (GFP_KERNEL);
-	cqr = request_cqr (MDSK_BIOS (1), 0);
-	cqr->magic = MDSK_MAGIC;
-	bio = (mdsk_bio_t *) (cqr->cpaddr);
-	memset (bio, 0, sizeof (mdsk_bio_t));
-	bio->type = MDSK_READ_REQ;
-	bio->block_number = info->sizes.label_block + 1;
-	bio->buffer = __pa (info->private.mdsk.label);
-	cqr->devindex = di;
-	atomic_set (&cqr->status, CQR_STATUS_FILLED);
-
-	return cqr;
-}
-
-int
-dasd_mdsk_fill_sizes_last (int di)
-{
-	int sb;
-	dasd_information_t *info = dasd_info[di];
-	long *label = info->private.mdsk.label;
-	int bs = info->private.mdsk.iib.block_size;
-
-	info->sizes.s2b_shift = 0;	/* bits to shift 512 to get a block */
-	for (sb = 512; sb < bs; sb = sb << 1)
-		info->sizes.s2b_shift++;
-
-	if (label[3] != bs) {
-		PRINT_WARN ("%04X mismatching blocksizes\n", info->info.devno);
-		atomic_set (&dasd_info[di]->status,
-			    DASD_INFO_STATUS_DETECTED);
-		return -EINVAL;
-	}
-	if (label[0] != 0xc3d4e2f1) {	/* CMS1 */
-		PRINT_WARN ("%04X is not CMS formatted\n", info->info.devno);
-	}
-	if (label[13] == 0) {
-		PRINT_WARN ("%04X is not reserved\n", info->info.devno);
-	}
-	/* defaults for first partition */
-	info->private.mdsk.setup.size =
-	    (label[7] - 1 - label[13]) * (label[3] >> 9) >> 1;
-	info->private.mdsk.setup.blksize = label[3];
-	info->private.mdsk.setup.offset = label[13] + 1;
-
-	/* real size of the volume */
-	info->sizes.bp_block = label[3];
-	info->sizes.kbytes = label[7] * (label[3] >> 9) >> 1;
-
-	if (info->sizes.s2b_shift >= 1)
-		info->sizes.blocks = info->sizes.kbytes >>
-		    (info->sizes.s2b_shift - 1);
-	else
-		info->sizes.blocks = info->sizes.kbytes <<
-		    (-(info->sizes.s2b_shift - 1));
-
-	PRINT_INFO ("%ld kBytes in %d blocks of %d Bytes\n",
-		    info->sizes.kbytes,
-		    info->sizes.blocks,
-		    info->sizes.bp_sector);
-	return 0;
-
-}
-
-dasd_operations_t dasd_mdsk_operations =
-{
-	ck_devinfo:dasd_mdsk_ck_devinfo,
-	get_req_ccw:dasd_mdsk_build_req,
-	ck_characteristics:dasd_mdsk_ck_characteristics,
-	fill_sizes_first:dasd_mdsk_fill_sizes_first,
-	fill_sizes_last:dasd_mdsk_fill_sizes_last,
-	dasd_format:NULL
-};
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_mdsk.h linux.17p18/drivers/s390/block/dasd_mdsk.h
--- linux.vanilla/drivers/s390/block/dasd_mdsk.h	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_mdsk.h	Thu Jan  1 01:00:00 1970
@@ -1,63 +0,0 @@
-#ifndef DASD_MDSK_H
-#define DASD_MDSK_H
-
-#define MDSK_WRITE_REQ 0x01
-#define MDSK_READ_REQ  0x02
-
-#define INIT_BIO        0x00
-#define RW_BIO          0x01
-#define TERM_BIO        0x02
-
-#define DEV_CLASS_FBA   0x01
-#define DEV_CLASS_ECKD   0x02	/* sure ?? */
-#define DEV_CLASS_CKD   0x04	/* sure ?? */
-
-#define MDSK_BIOS(x) (2*(x))
-
-typedef struct mdsk_dev_char_t {
-	u8 type;
-	u8 status;
-	u16 spare1;
-	u32 block_number;
-	u32 alet;
-	u32 buffer;
-} __attribute__ ((packed, aligned (8))) 
-
-mdsk_bio_t;
-
-typedef struct {
-	u16 dev_nr;
-	u16 spare1[11];
-	u32 block_size;
-	u32 offset;
-	u32 start_block;
-	u32 end_block;
-	u32 spare2[6];
-} __attribute__ ((packed, aligned (8))) 
-
-mdsk_init_io_t;
-
-typedef struct {
-	u16 dev_nr;
-	u16 spare1[11];
-	u8 key;
-	u8 flags;
-	u16 spare2;
-	u32 block_count;
-	u32 alet;
-	u32 bio_list;
-	u32 interrupt_params;
-	u32 spare3[5];
-} __attribute__ ((packed, aligned (8))) 
-
-mdsk_rw_io_t;
-
-typedef struct {
-	long vdev;
-	long size;
-	long offset;
-	long blksize;
-	int force_mdsk;
-} mdsk_setup_data_t;
-
-#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_proc.c linux.17p18/drivers/s390/block/dasd_proc.c
--- linux.vanilla/drivers/s390/block/dasd_proc.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_proc.c	Thu Jan  1 01:00:00 1970
@@ -1,135 +0,0 @@
-/*
-  Structure of the proc filesystem:
-  /proc/dasd/
-  /proc/dasd/devices                  # List of devices
-  /proc/dasd/ddabcd                   # Device node for devno abcd            
-  /proc/dasd/ddabcd1                  # Device node for partition abcd  
-  /proc/dasd/abcd                     # Device information for devno abcd
-*/
-
-#include <linux/proc_fs.h>
-
-#include <linux/dasd.h>
-
-#include "dasd_types.h"
-
-int dasd_proc_read_devices ( char *, char **, off_t, int, int);
-#ifdef DASD_PROFILE
-extern int dasd_proc_read_statistics ( char *, char **, off_t, int, int);
-extern int dasd_proc_read_debug ( char *, char **, off_t, int, int);
-#endif /* DASD_PROFILE */
-
-struct proc_dir_entry dasd_proc_root_entry =
-{
-	low_ino:0,
-	namelen:4,
-	name:"dasd",
-	mode:S_IFDIR | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
-	nlink:1,
-	uid:0,
-	gid:0,
-	size:0
-};
-
-struct proc_dir_entry dasd_proc_devices_entry =
-{
-	low_ino:0,
-	namelen:7,
-	name:"devices",
-	mode:S_IFREG | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
-	nlink:1,
-	uid:0,
-	gid:0,
-	size:0,
-	get_info:&dasd_proc_read_devices,
-};
-
-#ifdef DASD_PROFILE
-struct proc_dir_entry dasd_proc_stats_entry =
-{
-	low_ino:0,
-	namelen:10,
-	name:"statistics",
-	mode:S_IFREG | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
-	nlink:1,
-	uid:0,
-	gid:0,
-	size:0,
-	get_info:&dasd_proc_read_statistics
-};
-
-struct proc_dir_entry dasd_proc_debug_entry =
-{
-	low_ino:0,
-	namelen:5,
-	name:"debug",
-	mode:S_IFREG | S_IRUGO | S_IXUGO | S_IWUSR | S_IWGRP,
-	nlink:1,
-	uid:0,
-	gid:0,
-	size:0,
-	get_info:&dasd_proc_read_debug
-};
-#endif /* DASD_PROFILE */
-
-struct proc_dir_entry dasd_proc_device_template =
-{
-	0,
-	6,"dd????",
-	S_IFBLK | S_IRUGO | S_IWUSR | S_IWGRP,
-	1,0,0,
-	0,
-	NULL,
-};
-
-void
-dasd_proc_init ( void )
-{
-	proc_register( & proc_root, & dasd_proc_root_entry);
-	proc_register( & dasd_proc_root_entry, & dasd_proc_devices_entry);
-#ifdef DASD_PROFILE
- 	proc_register( & dasd_proc_root_entry, & dasd_proc_stats_entry); 
- 	proc_register( & dasd_proc_root_entry, & dasd_proc_debug_entry); 
-#endif /* DASD_PROFILE */
-}
-
-int 
-dasd_proc_read_devices ( char * buf, char **start, off_t off, int len, int d)
-{
-	int i;
-	len = sprintf ( buf, "dev# MAJ minor node        Format\n");
-	for ( i = 0; i < DASD_MAX_DEVICES; i++ ) {
-		dasd_information_t *info = dasd_info[i];
-		if ( ! info ) 
-			continue;
-		if ( len >= PAGE_SIZE - 80 )
-			len += sprintf ( buf + len, "terminated...\n");
-		len += sprintf ( buf + len,
-				 "%04X %3d %5d /dev/dasd%c",
-				 dasd_info[i]->info.devno,
-				 DASD_MAJOR,
-				 i << PARTN_BITS,
-				 'a' + i );
-		switch (atomic_read (&info->status)) {
-		case DASD_INFO_STATUS_UNKNOWN:
-			len += sprintf (buf + len, " unknown");
-			break;
-		case DASD_INFO_STATUS_DETECTED:
-			len += sprintf (buf + len, "   avail");
-			break;
-		case DASD_INFO_STATUS_ANALYSED:
-			len += sprintf (buf + len, "     n/f");
-			break;
-		default:
-			len += sprintf (buf + len, " %7d",
-					 info->sizes.bp_block);
-		}
-		len += sprintf ( buf + len, "\n");
-	} 
-	return len;
-}
-
-void 
-dasd_proc_add_node (int di) 
-{
-}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_profile.c linux.17p18/drivers/s390/block/dasd_profile.c
--- linux.vanilla/drivers/s390/block/dasd_profile.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_profile.c	Thu Jan  1 01:00:00 1970
@@ -1,212 +0,0 @@
-
-#include <linux/mm.h>
-#include <asm/spinlock.h>
-
-#include <linux/dasd.h>
-
-#include "dasd_types.h"
-
-#define PRINTK_HEADER "dasd_profile:"
-
-static long dasd_io_reqs=0; /* number of requests processed at all */
-static long dasd_io_secs[16]; /* histogram of request's sizes */
-static long dasd_io_times[16]; /* histogram of requests's times */
-static long dasd_io_timps[16]; /* histogram of requests's times per sector */
-static long dasd_io_time1[16]; /* histogram of time from build to start */
-static long dasd_io_time2[16]; /* histogram of time from start to irq */
-static long dasd_io_time2ps[16]; /* histogram of time from start to irq */
-static long dasd_io_time3[16]; /* histogram of time from irq to end */
-
-void
-dasd_profile_add ( cqr_t *cqr )
-{
-	int ind;
-	long strtime,irqtime,endtime,tottime;
-	long tottimeps,sectors;
-	long help;
-	if ( ! cqr -> req ) 
-	  return;
-	sectors = cqr -> req -> nr_sectors;
-	strtime = ((cqr->startclk - cqr->buildclk) >> 12);
-	irqtime = ((cqr->stopclk - cqr->startclk) >> 12);
-	endtime = ((cqr->endclk - cqr->stopclk) >> 12);
-	tottime = ((cqr->endclk - cqr->buildclk) >> 12);
-	tottimeps = tottime / sectors;
-
-	if (! dasd_io_reqs ++){
-	  for ( ind = 0; ind < 16; ind ++) {
-		dasd_io_secs[ind] = 0;
-		dasd_io_times[ind]=0;
-		dasd_io_timps[ind]=0;
-		dasd_io_time1[ind]=0;
-		dasd_io_time2[ind]=0;
-		dasd_io_time2ps[ind]=0;
-		dasd_io_time3[ind]=0;
-	  }
-	};
-	
-	for ( ind = 0, help = sectors >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_secs[ind] ++;
-
-	for ( ind = 0, help = tottime >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_times[ind] ++;
-
-	for ( ind = 0, help = tottimeps >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_timps[ind] ++;
-
-	for ( ind = 0, help = strtime >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_time1[ind] ++;
-
-	for ( ind = 0, help = irqtime >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_time2[ind] ++;
-
-	for ( ind = 0, help = (irqtime/sectors) >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_time2ps[ind] ++;
-
-	for ( ind = 0, help = endtime >> 3; 
-	      ind < 15 && help; 
-	      help = help >> 1,ind ++);
-	dasd_io_time3[ind] ++;
-}
-
-int 
-dasd_proc_read_statistics ( char * buf, char **start, 
-			    off_t off, int len, int d)
-{
-	int i;
-	int shift, help;
-	
-	for ( shift = 0, help = dasd_io_reqs; 
-	      help > 8192; 
-	      help = help >> 1,shift ++);
-	len = sprintf ( buf, "%ld dasd I/O requests\n", dasd_io_reqs); 
-	len += sprintf ( buf+len, "__<4 ___8 __16 __32 __64 _128 _256 _512 __1k __2k __4k __8k _16k _32k _64k >64k\n");
-	len += sprintf ( buf+len, "Histogram of sizes (512B secs)\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_secs[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	len += sprintf ( buf+len, "Histogram of I/O times\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_times[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	len += sprintf ( buf+len, "Histogram of I/O times per sector\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_timps[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	len += sprintf ( buf+len, "Histogram of I/O time till ssch\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_time1[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	len += sprintf ( buf+len, "Histogram of I/O time between ssch and irq\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_time2[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	len += sprintf ( buf+len, "Histogram of I/O time between ssch and irq per sector\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_time2ps[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	len += sprintf ( buf+len, "Histogram of I/O time between irq and end\n");
-	for ( i = 0; i < 16; i ++) {
-		len += sprintf ( buf+len, "%4ld ",dasd_io_time3[i] >> shift );
-	}
-	len += sprintf ( buf+len, "\n");
-	return len;
-}
-typedef
-struct {
-	union {
-		unsigned long long  clock;
-		struct {
-			unsigned int ts1;
-			unsigned int ts2 : 20;
-			unsigned int unused : 8;
-			unsigned int cpu : 4;
-		} __attribute__ ((packed)) s;
-	} __attribute__ ((packed)) u;
-	unsigned long caller_address;
-	unsigned long tag;
-} __attribute__ ((packed))
-
-dasd_debug_entry;
-
-static dasd_debug_entry *dasd_debug_area = NULL;
-static dasd_debug_entry *dasd_debug_actual;
-static spinlock_t debug_lock = SPIN_LOCK_UNLOCKED;
-
-void 
-dasd_debug ( unsigned long tag )
-{
-	long flags;
-	dasd_debug_entry *d;
-	/* initialize in first call ... */
-	if ( ! dasd_debug_area ) {
-		dasd_debug_actual = dasd_debug_area = 
-		    (dasd_debug_entry *) get_free_page (GFP_ATOMIC);
-		if ( ! dasd_debug_area ) {
-			PRINT_WARN("No debug area allocated\n");
-			return;
-		}
-		memset (dasd_debug_area,0,PAGE_SIZE);
-	}
-	/* renormalize to page */
-	spin_lock_irqsave(&debug_lock,flags);
-	dasd_debug_actual = (dasd_debug_entry *)
-		( (unsigned long) dasd_debug_area +
-		  ( ( (unsigned long)dasd_debug_actual -
-		      (unsigned long)dasd_debug_area ) % PAGE_SIZE ) );
-	d = dasd_debug_actual ++;
-	spin_unlock_irqrestore(&debug_lock,flags);
-	/* write CPUID to lowest 12 bits of clock... */
-	__asm__ __volatile__ ( "STCK  %0"
-			       :"=m" (d->u.clock));
-	d->tag = tag;
-	d->caller_address = (unsigned long) __builtin_return_address (0);
-	d->u.s.cpu = smp_processor_id();
-}
-
-int 
-dasd_proc_read_debug ( char * buf, char **start, 
-		       off_t off, int len, int dd)
-{
-	dasd_debug_entry *d;
-	char tag[9] =
-	{0,};
-	long flags;
-	spin_lock_irqsave(&debug_lock,flags);
-	len = 0;
-       	for( d = dasd_debug_area; 
-	     len < 4068 ;
-	     d ++ ) {
-		if ( *(char*)(&d->tag) == 'D' ) {
-			memcpy(tag,&(d->tag),4);
-			tag[4]=0;
-		} else {
-			sprintf (tag, "%08lx", d->tag);
-			tag[8]=0;
-		}
-		len += sprintf ( buf+len,
-				"%x %08x%05x %08lx (%8s)\n",
-				 d->u.s.cpu, d->u.s.ts1, d->u.s.ts2,
-				 d->caller_address,tag);
-	}
-	spin_unlock_irqrestore(&debug_lock,flags);
-	return len;
-}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_setup.c linux.17p18/drivers/s390/block/dasd_setup.c
--- linux.vanilla/drivers/s390/block/dasd_setup.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_setup.c	Thu Jan  1 01:00:00 1970
@@ -1,343 +0,0 @@
-/* 
- * File...........: linux/drivers/s390/block/dasd_setup.c
- * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- *                : Utz Bacher <utz.bacher@de.ibm.com>
- * Bugreports.to..: <Linux390@de.ibm.com>
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
- */
-
-#include <linux/ctype.h>
-#include <linux/malloc.h>
-
-#include <linux/dasd.h>
-#include "dasd_types.h"
-
-#define PRINTK_HEADER "dasd(setup):"
-
-#define MIN(a,b) (((a)<(b))?(a):(b))
-
-static int dasd_autodetect = 0;
-int dasd_probeonly = 1;
-static int dasd_count = 0;
-static int dasd_devno[DASD_MAX_DEVICES] =
-{0,};
-int dasd_force_mdsk_flag[DASD_MAX_DEVICES] =
-{0,};
-
-extern char *dasd[DASD_MAX_DEVICES];
-#ifdef CONFIG_DASD_MDSK
-extern char *dasd_force_mdsk[DASD_MAX_DEVICES];
-#endif
-
-typedef struct dasd_range {
-	int from, to;
-	struct dasd_range *next;
-} dasd_range;
-
-static dasd_range *first_range = NULL;
-
-void 
-dasd_add_devno_to_ranges (int devno)
-{
-	dasd_range *p, *prev;
-	for (p = first_range; p; prev = p, p = prev->next) {
-		if (devno >= p->from && devno <= p->to) {
-			PRINT_WARN ("devno %04X already in range %04X-%04X\n",
-				    devno, p->from, p->to);
-			return;
-		}
-		if (devno == (p->from - 1)) {
-			p->from--;
-			return;
-		}
-		if (devno == (p->to + 1)) {
-			p->to++;
-			return;
-		}
-	}
-	prev = kmalloc (sizeof (dasd_range), GFP_ATOMIC);
-	prev->from = prev->to = devno;
-	if (!first_range) {
-		first_range = prev;
-	}
-	return;
-}
-
-int
-dasd_proc_print_probed_ranges (char *buf, char **start, off_t off, int len, int d)
-{
-	dasd_range *p;
-	len = sprintf (buf, "Probed ranges of the DASD driver\n");
-	for (p = first_range; p; p = p->next) {
-		if (len >= PAGE_SIZE - 80)
-			len += sprintf (buf + len, "terminated...\n");
-		if (p != first_range) {
-			len += sprintf (buf + len, ",");
-		}
-		if (p->from == p->to) {
-			len += sprintf (buf + len, "%04x", p->from);
-		} else {
-			len += sprintf (buf + len, "%04x-%04x",
-					p->from, p->to);
-		}
-	}
-	len += sprintf (buf + len, "\n");
-	return len;
-}
-
-static int
-dasd_get_hexdigit (char c)
-{
-	if ((c >= '0') && (c <= '9'))
-		return c - '0';
-	if ((c >= 'a') && (c <= 'f'))
-		return c + 10 - 'a';
-	if ((c >= 'A') && (c <= 'F'))
-		return c + 10 - 'A';
-	return -1;
-}
-
-/* sets the string pointer after the next comma */
-static void
-dasd_scan_for_next_comma (char **strptr)
-{
-	while (((**strptr) != ',') && (**strptr))
-		(*strptr)++;
-
-	/* set the position AFTER the comma */
-	if (**strptr == ',')
-		(*strptr)++;
-}
-
-/*sets the string pointer after the next comma, if a parse error occured */
-static int
-dasd_get_next_int (char **strptr)
-{
-	int j, i = -1;		/* for cosmetic reasons first -1, then 0 */
-	if (isxdigit (**strptr)) {
-		for (i = 0; isxdigit (**strptr);) {
-			i <<= 4;
-			j = dasd_get_hexdigit (**strptr);
-			if (j == -1) {
-				PRINT_ERR ("no integer: skipping range.\n");
-				dasd_scan_for_next_comma (strptr);
-				i = -1;
-				break;
-			}
-			i += j;
-			(*strptr)++;
-			if (i > 0xffff) {
-				PRINT_ERR (" value too big, skipping range.\n");
-				dasd_scan_for_next_comma (strptr);
-				i = -1;
-				break;
-			}
-		}
-	}
-	return i;
-}
-
-int
-devindex_from_devno (int devno)
-{
-	int i;
-	if (dasd_probeonly) {
-		return 0;
-	}
-	for (i = 0; i < dasd_count; i++) {
-		if (dasd_devno[i] == devno)
-			return i;
-	}
-	if (dasd_autodetect) {
-		if (dasd_count < DASD_MAX_DEVICES) {
-			dasd_devno[dasd_count] = devno;
-			return dasd_count++;
-		}
-		return -EOVERFLOW;
-	}
-	return -ENODEV;
-}
-
-/* returns 1, if dasd_no is in the specified ranges, otherwise 0 */
-int
-dasd_is_accessible (int devno)
-{
-	return (devindex_from_devno (devno) >= 0);
-}
-
-/* dasd_insert_range skips ranges, if the start or the end is -1 */
-void
-dasd_insert_range (int start, int end)
-{
-	int curr;
-	if (dasd_count >= DASD_MAX_DEVICES) {
-		PRINT_ERR (" too many devices specified, ignoring some.\n");
-		return;
-	}
-	if ((start == -1) || (end == -1)) {
-		PRINT_ERR
-		    ("invalid format of parameter, skipping range\n");
-		return;
-	}
-	if (end < start) {
-		PRINT_ERR (" ignoring range from %x to %x - start value " \
-			   "must be less than end value.\n", start, end);
-		return;
-	}
-/* concurrent execution would be critical, but will not occur here */
-	for (curr = start; curr <= end; curr++) {
-		if (dasd_is_accessible (curr)) {
-			PRINT_WARN (" %x is already in list as device %d\n",
-				    curr, devindex_from_devno (curr));
-		}
-		dasd_devno[dasd_count] = curr;
-		dasd_count++;
-		if (dasd_count >= DASD_MAX_DEVICES) {
-			PRINT_ERR (" too many devices specified, ignoring some.\n");
-			break;
-		}
-	}
-	PRINT_INFO (" added dasd range from %x to %x.\n",
-		    start, dasd_devno[dasd_count - 1]);
-
-}
-
-void
-dasd_setup (char *str, int *ints)
-{
-	int devno, devno2;
-	static const char *adstring = "autodetect";
-	static const char *prstring = "probeonly";
-	if (!strncmp (str, prstring,
-		      MIN (strlen (str), strlen (prstring)))) {
-		dasd_autodetect = 1;
-		return;
-	}
-	if (!strncmp (str, adstring,
-		      MIN (strlen (str), strlen (adstring)))) {
-		dasd_autodetect = 1;
-		dasd_probeonly = 0;
-		return;
-	}
-	dasd_probeonly = 0;
-	while (*str && *str != 1) {
-		if (!isxdigit (*str)) {
-			str++;	/* to avoid looping on two commas */
-			PRINT_ERR (" kernel parameter in invalid format.\n");
-			continue;
-		}
-		devno = dasd_get_next_int (&str);
-
-		/* range was skipped? -> scan for comma has been done */
-		if (devno == -1)
-			continue;
-
-		if (*str == ',') {
-			str++;
-			dasd_insert_range (devno, devno);
-			continue;
-		}
-		if (*str == '-') {
-			str++;
-			devno2 = dasd_get_next_int (&str);
-			if (devno2 == -1) {
-				PRINT_ERR (" invalid character in " \
-					   "kernel parameters.");
-			} else {
-				dasd_insert_range (devno, devno2);
-			}
-			dasd_scan_for_next_comma (&str);
-			continue;
-		}
-		if (*str == 0) {
-			dasd_insert_range (devno, devno);
-			break;
-		}
-		PRINT_ERR (" unexpected character in kernel parameter, " \
-			   "skipping range.\n");
-	}
-}
-#ifdef CONFIG_DASD_MDSK
-int dasd_force_mdsk_flag[DASD_MAX_DEVICES];
-
-/*
- * Parameter parsing function, called from init/main.c
- * size    : size in kbyte
- * offset  : offset after which minidisk is available
- * blksize : blocksize minidisk is formated
- * Format is: mdisk=<vdev>,<vdev>,...
- */
-void
-dasd_mdsk_setup (char *str, int *ints)
-{
-	int devno, devno2;
-	int di, i;
-
-	while (*str && *str != 1) {
-		if (!isxdigit (*str)) {
-			str++;	/* to avoid looping on two commas */
-			PRINT_ERR (" kernel parameter in invalid format.\n");
-			continue;
-		}
-		devno = dasd_get_next_int (&str);
-
-		/* range was skipped? -> scan for comma has been done */
-		if (devno == -1)
-			continue;
-
-		if (*str == ',') {
-			str++;
-			di = devindex_from_devno (devno);
-			if (di >= DASD_MAX_DEVICES) {
-				return;
-			} else if (di < 0)
-				dasd_insert_range (devno, devno);
-			dasd_force_mdsk_flag[di] = 1;
-			continue;
-		}
-		if (*str == '-') {
-			str++;
-			devno2 = dasd_get_next_int (&str);
-			if (devno2 == -1) {
-				PRINT_ERR (" invalid character in " \
-					   "kernel parameters.");
-			} else {
-				for (i = devno; i <= devno2; i++) {
-					di = devindex_from_devno (i);
-					if (di >= DASD_MAX_DEVICES) {
-						return;
-					} else if (di < 0)
-						dasd_insert_range (i, i);
-					dasd_force_mdsk_flag[di] = 1;
-				}
-			}
-			dasd_scan_for_next_comma (&str);
-			continue;
-		}
-		if (*str == 0) {
-			di = devindex_from_devno (devno);
-			if (di >= DASD_MAX_DEVICES) {
-				return;
-			} else if (di < 0)
-				dasd_insert_range (devno, devno);
-			dasd_force_mdsk_flag[di] = 1;
-			break;
-		}
-		PRINT_ERR (" unexpected character in kernel parameter, " \
-			   "skipping range.\n");
-	}
-}
-#endif
-
-#ifdef MODULE
-int
-dasd_parse_module_params (void)
-{
-	while (dasd)
-		dasd_setup (dasd, NULL);
-#ifdef CONFIG_DASD_MDSK
-	while (dasd_force_mdsk)
-		dasd_mdsk_setup (dasd_force_mdsk, NULL);
-#endif
-}
-#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/block/dasd_types.h linux.17p18/drivers/s390/block/dasd_types.h
--- linux.vanilla/drivers/s390/block/dasd_types.h	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/block/dasd_types.h	Thu Jan  1 01:00:00 1970
@@ -1,359 +0,0 @@
-
-/*
- * File...........: linux/drivers/s390/block/dasd_types.h
- * Author.........: Holger Smolinski <Holger.Smolinski@de.ibm.com>
- * Created........: 08/31/1999
- * Last Modified..: 09/29/1999
- * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000
-
- * List of Changes:
- - Initial Release as of 09/29/1999
-
- * Description
-
- * Restrictions
-
- * Known Bugs
-
- * Todo-List
-
- */
-
-#ifndef DASD_TYPES_H
-#define DASD_TYPES_H
-
-#include <linux/dasd.h>
-
-#include <linux/blkdev.h>
-
-#include <linux/hdreg.h>
-
-#include <asm/irq.h>
-
-#include "dasd_mdsk.h"
-
-#define ACS(where,from,to) if (atomic_compare_and_swap (from, to, &where)) {\
-	PRINT_WARN ("%s/%d atomic %s from %d(%s) to %d(%s) failed, was %d\n",\
-		    __FILE__,__LINE__,#where,from,#from,to,#to,\
-                    atomic_read (&where));\
-        atomic_set(&where,to);}
-
-#define CCW_DEFINE_EXTENT 0x63
-#define CCW_LOCATE_RECORD 0x43
-#define CCW_READ_DEVICE_CHARACTERISTICS 0x64
-
-typedef
-enum {
-	dasd_none = -1,
-#ifdef CONFIG_DASD_ECKD
-	dasd_eckd,
-#endif				/* CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_FBA
-	dasd_fba,
-#endif				/* CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_MDSK
-	dasd_mdsk,
-#endif				/* CONFIG_DASD_MDSK */
-#ifdef CONFIG_DASD_CKD
-	dasd_ckd,
-#endif				/* CONFIG_DASD_CKD */
-	dasd_end
-} dasd_type_t;
-
-typedef
-struct {
-	union {
-		__u8 c;
-		struct {
-			unsigned char reserved:1;
-			unsigned char overrunnable:1;
-			unsigned char burst_byte:1;
-			unsigned char data_chain:1;
-			unsigned char zeros:4;
-		} __attribute__ ((packed)) bits;
-	} __attribute__ ((packed)) mode;
-	union {
-		__u8 c;
-		struct {
-			unsigned char zero0:1;
-			unsigned char removable:1;
-			unsigned char shared:1;
-			unsigned char zero1:1;
-			unsigned char mam:1;
-			unsigned char zeros:3;
-		} __attribute__ ((packed)) bits;
-	} __attribute__ ((packed)) features;
-	__u8 dev_class;
-	__u8 unit_type;
-	__u16 blk_size;
-	__u32 blk_per_cycl;
-	__u32 blk_per_bound;
-	__u32 blk_bdsa;
-	__u32 reserved0;
-	__u16 reserved1;
-	__u16 blk_ce;
-	__u32 reserved2;
-	__u16 reserved3;
-} __attribute__ ((packed, aligned (32))) 
-
-dasd_fba_characteristics_t;
-
-typedef
-struct {
-	__u16 cu_type;
-	struct {
-		unsigned char support:2;
-		unsigned char async:1;
-		unsigned char reserved:1;
-		unsigned char cache_info:1;
-		unsigned char model:3;
-	} __attribute__ ((packed)) cu_model;
-	__u16 dev_type;
-	__u8 dev_model;
-	struct {
-		unsigned char mult_burst:1;
-		unsigned char RT_in_LR:1;
-		unsigned char reserved1:1;
-		unsigned char RD_IN_LR:1;
-		unsigned char reserved2:4;
-		unsigned char reserved3:8;
-		unsigned char defect_wr:1;
-		unsigned char reserved4:2;
-		unsigned char striping:1;
-		unsigned char reserved5:4;
-		unsigned char cfw:1;
-		unsigned char reserved6:2;
-		unsigned char cache:1;
-		unsigned char dual_copy:1;
-		unsigned char dfw:1;
-		unsigned char reset_alleg:1;
-		unsigned char sense_down:1;
-	} __attribute__ ((packed)) facilities;
-	__u8 dev_class;
-	__u8 unit_type;
-	__u16 no_cyl;
-	__u16 trk_per_cyl;
-	__u8 sec_per_trk;
-	__u8 byte_per_track[3];
-	__u16 home_bytes;
-	__u8 formula;
-	union {
-		struct {
-			__u8 f1;
-			__u16 f2;
-			__u16 f3;
-		} __attribute__ ((packed)) f_0x01;
-		struct {
-			__u8 f1;
-			__u8 f2;
-			__u8 f3;
-			__u8 f4;
-			__u8 f5;
-		} __attribute__ ((packed)) f_0x02;
-	} __attribute__ ((packed)) factors;
-	__u16 first_alt_trk;
-	__u16 no_alt_trk;
-	__u16 first_dia_trk;
-	__u16 no_dia_trk;
-	__u16 first_sup_trk;
-	__u16 no_sup_trk;
-	__u8 MDR_ID;
-	__u8 OBR_ID;
-	__u8 director;
-	__u8 rd_trk_set;
-	__u16 max_rec_zero;
-	__u8 reserved1;
-	__u8 RWANY_in_LR;
-	__u8 factor6;
-	__u8 factor7;
-	__u8 factor8;
-	__u8 reserved2[3];
-	__u8 reserved3[10];
-} __attribute__ ((packed, aligned (32))) 
-
-dasd_eckd_characteristics_t;
-
-typedef struct {
-	u16 dev_nr;
-	u16 rdc_len;
-	u8 vdev_class;
-	u8 vdev_type;
-	u8 vdev_status;
-	u8 vdev_flags;
-	u8 rdev_class;
-	u8 rdev_type;
-	u8 rdev_model;
-	u8 rdev_features;
-} __attribute__ ((packed, aligned (32)))
-
-dasd_mdsk_characteristics_t;
-
-/* eckd count area */
-typedef struct {
-	__u16 cyl;
-	__u16 head;
-	__u8 record;
-	__u8 kl;
-	__u16 dl;
-} __attribute__ ((packed))
-
-eckd_count_t;
-
-#ifdef CONFIG_DASD_CKD
-struct dasd_ckd_characteristics {
-	char info[64];
-};
-
-#endif				/* CONFIG_DASD_CKD */
-
-typedef
-union {
-	char __attribute__ ((aligned (32))) bytes[64];
-#ifdef CONFIG_DASD_FBA
-	dasd_fba_characteristics_t fba;
-#endif				/* CONFIG_DASD_FBA */
-#ifdef CONFIG_DASD_CKD
-	struct dasd_ckd_characteristics ckd;
-#endif				/* CONFIG_DASD_CKD */
-#ifdef CONFIG_DASD_ECKD
-	dasd_eckd_characteristics_t eckd;
-#endif				/* CONFIG_DASD_ECKD */
-#ifdef CONFIG_DASD_MDSK
-	dasd_mdsk_characteristics_t mdsk;
-#endif				/* CONFIG_DASD_ECKD */
-} __attribute__ ((aligned (32))) 
-
-dasd_characteristics_t;
-
-#define CQR_STATUS_EMPTY  0x00
-#define CQR_STATUS_FILLED 0x01
-#define CQR_STATUS_QUEUED 0x02
-#define CQR_STATUS_IN_IO  0x04
-#define CQR_STATUS_DONE   0x08
-#define CQR_STATUS_ERROR  0x10
-#define CQR_STATUS_ERP_PEND  0x20
-#define CQR_STATUS_ERP_ACTIVE  0x40
-#define CQR_STATUS_FAILED 0x80
-
-#define CQR_FLAGS_SLEEP   0x01
-#define CQR_FLAGS_WAIT    0x02
-#define CQR_FLAGS_NOLOCK  0x04
-#define CQR_FLAGS_NORETRY 0x08
-
-typedef
-struct cqr_t {
-	unsigned int    magic;    /* magic number should be "DASD" */
-	atomic_t status;	/* current status of request */
-	unsigned short retries; /* counter for retry in error case */
-	unsigned short cplength;/* Length of channel program  (CP) */
-	unsigned short devindex;/* device number */
-	unsigned short flags;    /* Flags for execution */
-	
-	void * data;		/* additional data area for CP */
-	ccw1_t *cpaddr;		/* Address of CP */
-	struct request *req;	/* backpointer to struct request */
-	struct cqr_t *next;     /* forward chain in chanq */
-	struct cqr_t *int4cqr;  /* which cqr ist the nect PCI for? */
-	unsigned long long buildclk;
-	unsigned long long startclk;
-	unsigned long long stopclk;
-	unsigned long long endclk;
-	devstat_t *dstat;	/* savearea for devstat */
-	spinlock_t lock;
-	int options;
-} __attribute__ ((packed)) 
-
-cqr_t;
-
-typedef
-struct {
-	unsigned long int kbytes;
-	unsigned int bp_sector;
-	unsigned int bp_block;
-	unsigned int blocks;
-	unsigned int s2b_shift;
-	unsigned int label_block;
-} dasd_sizes_t;
-
-#define DASD_CHANQ_ACTIVE 0x01
-#define DASD_CHANQ_BUSY 0x02
-#define DASD_REQUEST_Q_BROKEN 0x04
-
-typedef
-struct dasd_chanq_t {
-	volatile cqr_t *head;
-	volatile cqr_t *tail;
-	spinlock_t q_lock;	/* lock for queue operations */
-	spinlock_t f_lock;	/* lock for flag operations */
-	int queued_requests;
-	atomic_t flags;
-	atomic_t dirty_requests;
-	struct dasd_chanq_t *next_q;	/* pointer to next queue */
-} __attribute__ ((packed, aligned (16))) 
-
-dasd_chanq_t;
-
-#define DASD_INFO_STATUS_UNKNOWN 0x00	/* nothing known about DASD */
-#define DASD_INFO_STATUS_DETECTED 0x01	/* DASD identified as DASD, irq taken */
-#define DASD_INFO_STATUS_ANALYSED 0x02	/* first block read, filled sizes */
-#define DASD_INFO_STATUS_FORMATTED 0x04		/* identified valid format */
-#define DASD_INFO_STATUS_PARTITIONED 0x08	/* identified partitions */
-
-typedef
-struct dasd_information_t {
-	devstat_t dev_status;
-	dasd_characteristics_t *rdc_data;
-	dasd_volume_label_t *label;
-	dasd_type_t type;
-	dev_info_t info;
-	dasd_sizes_t sizes;
-	dasd_chanq_t queue;
-	int open_count;
-	spinlock_t lock;
-	struct semaphore sem;
-	atomic_t status;
-	int irq;
-	mdsk_setup_data_t *mdsk_setup;
-	struct proc_dir_entry *proc_device;
-	union {
-		struct {
-			eckd_count_t count_data;
-		} eckd;
-		struct {
-			char dummy;
-		} fba;
-		struct {
-			mdsk_init_io_t iib;
-			mdsk_rw_io_t iob;
-			mdsk_setup_data_t setup;
-			long *label;
-		} mdsk;
-		struct {
-			char dummy;
-		} ckd;
-	} private;
-	struct wait_queue *wait_q;
-} dasd_information_t;
-
-extern dasd_information_t *dasd_info[];
-
-#include "dasd_erp.h"
-
-typedef
-struct {
-	int (*ck_devinfo) (dev_info_t *);
-	cqr_t *(*get_req_ccw) (int, struct request *);
-	int (*ck_characteristics) (dasd_characteristics_t *);
-	cqr_t *(*fill_sizes_first) (int);
-	int (*fill_sizes_last) (int);
-	int (*dasd_format) (int, format_data_t *);
-	void (*fill_geometry) (int, struct hd_geometry *);
-	 dasd_era_t (*erp_examine) (cqr_t *, devstat_t *);
-} dasd_operations_t;
-
-extern dasd_operations_t *dasd_disciplines[];
-
-/* Prototypes */
-int dasd_start_IO (cqr_t * cqr);
-
-#endif				/* DASD_TYPES_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/ccwcache.c linux.17p18/drivers/s390/ccwcache.c
--- linux.vanilla/drivers/s390/ccwcache.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/s390/ccwcache.c	Tue Aug  1 07:59:49 2000
@@ -0,0 +1,381 @@
+/* 
+   * File...........: linux/drivers/s390/block/ccwcache.c
+   * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+   * Bugreports.to..: <Linux390@de.ibm.com>
+   * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000a
+   
+   * History of changes
+   * 07/10/00 moved ccwcache.h from linux/ to asm/
+ */
+
+#include <linux/malloc.h>
+#include <asm/debug.h>
+#include <asm/ccwcache.h>
+
+#include <asm/ebcdic.h>
+#include <asm/spinlock.h>
+
+
+#ifdef PRINTK_HEADER
+#undef PRINTK_HEADER
+#endif
+#define PRINTK_HEADER "ccwcache"
+
+#ifdef MODULE
+MODULE_AUTHOR ("Holger Smolinski <Holger.Smolinski@de.ibm.com>");
+MODULE_DESCRIPTION ("Linux on S/390 CCW cache,"
+		    "Copyright 2000 IBM Corporation");
+EXPORT_NO_SYMBOLS; 
+EXPORT_SYMBOL(ccw_alloc_request);
+EXPORT_SYMBOL(ccw_free_request);
+#endif /* MODULE */
+
+
+/* pointer to list of allocated requests */
+static ccw_req_t *ccwreq_actual = NULL;
+
+/* pointer to debug area */
+static debug_info_t *debug_area = NULL;
+
+/* SECTION: Handling of the dynamically allocated kmem slabs */
+
+/* a name template for the cache-names */
+static char ccw_name_template[] = "ccwcache-\0\0\0\0"; /* fill name with zeroes! */
+/* the cache's names */
+static char ccw_cache_name[CCW_NUMBER_CACHES][sizeof(ccw_name_template)+1]; 
+/* the caches itself*/
+static kmem_cache_t *ccw_cache[CCW_NUMBER_CACHES]; 
+
+/* SECTION: (de)allocation of ccw_req_t */
+
+/* 
+ * void dechain ( ccw_req_t *request )
+ * dechains the request from the ringbuffer
+ */
+
+static void 
+dechain ( ccw_req_t *request )
+{
+	/* Sanity checks */
+	if ( request == NULL ) {
+		printk( KERN_WARNING PRINTK_HEADER
+			"Trying to deallocate NULL request\n");
+		return;
+	}
+	/* first deallocate request from list of allocates requests */
+	if ( request -> int_next && request -> int_prev ) {
+		if ( request -> int_next == request -> int_prev ) {
+			ccwreq_actual = NULL;
+		} else {
+			if ( ccwreq_actual == request ) {
+				ccwreq_actual = request->int_next;
+			}
+			request->int_prev->int_next = request->int_next;
+			request->int_next->int_prev = request->int_prev;
+		}
+	} else if ( request -> int_next || request -> int_prev ) {
+	}
+	return;
+}
+
+/* 
+ * ccw_req_t *ccw_alloc_request ( int cplength, int datasize )
+ * allocates a ccw_req_t, that 
+ * - can hold a CP of cplength CCWS
+ * - can hold additional data up to datasize 
+ */
+ccw_req_t *
+ccw_alloc_request ( char *magic, int cplength, int datasize )
+{
+	ccw_req_t * request = NULL;
+	int cachind = 0;
+	int size_needed = 0;
+
+	debug_text_event ( debug_area, 1, "ALLC");
+	if ( magic ) {
+		debug_text_event ( debug_area, 1, magic);
+	}
+	debug_event ( debug_area, 1, cplength);
+	debug_event ( debug_area, 1, datasize);
+
+	/* Sanity checks */
+	if ( cplength == 0 ) {
+		printk (KERN_DEBUG PRINTK_HEADER
+			"called ccw_alloc_request with cplength of 0 from %p\n",
+			     __builtin_return_address(0));
+		return NULL;
+	}
+	if ( (cplength << 3 ) > PAGE_SIZE ) {
+		printk(KERN_WARNING PRINTK_HEADER
+		       "Channel program to large to fit on one page\n");
+		return NULL;
+	}
+	if ( datasize > PAGE_SIZE ) {
+		printk(KERN_WARNING PRINTK_HEADER
+		       "Data size to large to fit on one page\n");
+		return NULL;
+	}
+	
+	/* Try to keep things together in memory */
+	if ( sizeof (ccw_req_t) + 
+	     (((datasize + 7) >> 3) << 3) +  /* align upper end of data to 8 */
+	     (cplength << 3 ) < PAGE_SIZE ) {
+		/* All fit on one page, is preferred. */
+		size_needed = sizeof (ccw_req_t) + datasize + (cplength << 3 );
+	} else if ( sizeof (ccw_req_t) + (cplength << 3 ) < PAGE_SIZE ) {
+		/* Try to keep CCWs with request */
+		size_needed = sizeof (ccw_req_t) + (cplength << 3 );
+	} else if ( sizeof (ccw_req_t) + datasize < PAGE_SIZE ) {
+		/* Try to keep at least the data with request */
+		size_needed = sizeof (ccw_req_t) + datasize;
+	} else {
+		/* Fall back to hold only the request in cache */
+		size_needed = sizeof (ccw_req_t);
+	}
+	/* determine cache index for the requested size */
+	for (cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) {
+	   if ( size_needed < (SMALLEST_SLAB << cachind) ) 
+			break;
+	}
+	/* Try to fulfill the request from a cache */
+	while (  cachind < CCW_NUMBER_CACHES ) { /* Now try to get an entry from a cache above or equal to cachind */
+	  if ( ccw_cache[cachind] == NULL ){
+	    printk("cache=%p index %d\n",cachind,cachind);
+	  }
+	  request = kmem_cache_alloc ( ccw_cache[cachind], GFP_ATOMIC );
+	  if ( request != NULL ) {
+	    memset ( request, 0, (SMALLEST_SLAB << cachind));
+	    request->cache = ccw_cache[cachind];
+	    break;
+	  } else {
+	    printk (KERN_DEBUG PRINTK_HEADER "Proceeding to next cache");
+	  }
+ 	  cachind++;
+	} 
+	/* if no success, fall back to kmalloc */
+	if ( request == NULL ) {
+	  printk (KERN_DEBUG PRINTK_HEADER "Falling back to kmalloc");
+		request = kmalloc ( sizeof(ccw_req_t), GFP_ATOMIC );
+		if ( request != NULL ) {
+			memset ( request, 0, sizeof(ccw_req_t));
+		}
+	}
+	/* Initialize request */
+	if ( request == NULL ) {  
+		printk(KERN_WARNING PRINTK_HEADER "Couldn't allocate request");
+	} else {
+		if ( request -> cache != NULL ) {
+			/* Three cases when coming from a cache */
+			if ( sizeof (ccw_req_t) + 
+			     (((datasize + 7) >> 3) << 3) +
+			     (cplength << 3 ) < 
+			     PAGE_SIZE ) {
+				request->data= (void*)(request + 1);
+				request->cpaddr= (ccw1_t *)(((((long)(request + 1))+ 
+							     datasize + 7)
+							    >> 3) << 3);
+			} else if ( sizeof (ccw_req_t) + (cplength << 3 ) < 
+				    PAGE_SIZE ) {
+				request->cpaddr=(ccw1_t *)(((((long)(request)) + 
+							     sizeof(ccw_req_t) + 7)
+							    >> 3) << 3);
+			} else if ( sizeof (ccw_req_t) + datasize < PAGE_SIZE ) {
+				request->data= (void *)(request + 1);
+			} else {} 
+		}
+		/* Have the rest be done by kmalloc */
+		if ( request -> cpaddr == NULL ) {
+			printk(KERN_DEBUG PRINTK_HEADER "Falling back to kmalloc for CCW area\n");
+			request->cpaddr=(ccw1_t *) kmalloc(sizeof(ccw1_t) * cplength,
+							  GFP_ATOMIC);
+			if ( request -> cpaddr == NULL ) {
+				printk(KERN_WARNING PRINTK_HEADER "Couldn't allocate ccw area\n");
+				ccw_free_request(request);
+				return NULL;
+			}
+		}
+		if ( request -> data == NULL ) {
+			printk(KERN_DEBUG PRINTK_HEADER"Falling back to kmalloc for data area\n");
+			request->data=(void *)kmalloc(datasize, GFP_ATOMIC);
+			if ( request -> data == NULL ) {
+				printk(KERN_WARNING PRINTK_HEADER "Couldn't allocate data area\n");
+				ccw_free_request(request);
+				return NULL;
+			}
+		}
+		memset ( request->data,0,datasize );
+		memset ( request->cpaddr,0,cplength*sizeof(ccw1_t) );
+		if ( magic ) {
+			strncpy ( (char *)(&request->magic), magic, 4);
+		}
+		else {
+			strncpy ( (char *)(&request->magic), "CCWC", 4);
+		}
+		ASCEBC((char *)(&request->magic),4);
+		request -> cplength = cplength;
+		request -> datasize = datasize;
+		/* enqueue request to list of allocated requests */
+		if ( ccwreq_actual == NULL ) { /* queue empty */
+			ccwreq_actual = request;
+			request->int_prev = ccwreq_actual;
+			request->int_next = ccwreq_actual;
+		} else {
+			request->int_next = ccwreq_actual;
+			request->int_prev = ccwreq_actual->int_prev;
+			request->int_prev->int_next = request;
+			request->int_next->int_prev = request;
+		}
+	}
+	debug_event ( debug_area, 1, (long)request);
+	return request;
+}
+
+/* 
+ * void ccw_free_request ( ccw_req_t * )
+ * deallocates the ccw_req_t, given as argument
+ */
+
+void
+ccw_free_request ( ccw_req_t * request )
+{
+	int cachind;
+	int slabsize;
+
+	debug_text_event ( debug_area, 1, "FREE");
+	debug_event ( debug_area, 1, (long)request);
+	/* Sanity checks */
+	if ( request == NULL ) {
+		printk(KERN_DEBUG PRINTK_HEADER"Trying to deallocate NULL request\n");
+		return;
+	}
+	if ( request -> cache == NULL ) {
+		printk (KERN_WARNING PRINTK_HEADER "Deallocating uncached request\n");
+		if ( request -> data ) {
+			kfree ( request -> data );
+		}
+		if ( request ->cpaddr ) {
+			kfree ( request -> cpaddr );
+		}
+		dechain ( request);
+		kfree ( request );
+	} else {
+		/* Find which area has been allocated by kmalloc */
+		for (cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ )
+			if ( request->cache == ccw_cache[cachind] )
+				break;
+		if ( request->cache != ccw_cache[cachind] ) {
+			printk(KERN_WARNING PRINTK_HEADER"Cannot find cache in list\n");
+		}
+		slabsize = SMALLEST_SLAB << cachind;
+		if ( request -> data &&
+		     (((unsigned long)(request -> data) >
+		       ((unsigned long)request) + slabsize) ||
+		      ((unsigned long)(request -> data) < 
+		       ((unsigned long)request)))) {
+			kfree ( request -> data );
+		}
+		if ( request ->cpaddr &&
+		     (((unsigned long)(request -> cpaddr) >
+		       ((unsigned long)request) + slabsize) ||
+		      (unsigned long)(request -> cpaddr) < 
+		      ((unsigned long)request))) {
+			kfree ( request -> cpaddr );
+		}
+		dechain ( request);
+		kmem_cache_free(request -> cache, request);
+	}
+}
+
+/* SECTION: initialization and cleanup functions */
+
+/* 
+ * ccwcache_init
+ * called as an initializer function for the ccw memory management
+ */
+
+int
+ccwcache_init (void)
+{
+	int rc = 0;
+	int cachind;
+
+	/* allocate a debug area */
+	debug_area = debug_register( "ccwcache", 2, 4);
+	if ( ! debug_area ) {
+		printk ( KERN_WARNING PRINTK_HEADER"cannot allocate debug area\n" );
+	} else {
+		printk (KERN_DEBUG PRINTK_HEADER "debug area is 0x%8p\n", debug_area );
+	}
+	debug_text_event ( debug_area, 0, "INIT");
+	
+	/* First allocate the kmem caches */
+	for ( cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) {
+		int slabsize = SMALLEST_SLAB << cachind;
+		debug_text_event ( debug_area, 1, "allc");
+		debug_event ( debug_area, 1, slabsize);
+		sprintf ( ccw_cache_name[cachind], 
+			  "%s%d%c", ccw_name_template, slabsize, 0);
+		ccw_cache[cachind] = kmem_cache_create( ccw_cache_name[cachind], 
+							slabsize, 0,
+							SLAB_HWCACHE_ALIGN, 
+							NULL, NULL );
+		debug_event ( debug_area, 1, (long)ccw_cache[cachind]);
+		if ( ! ccw_cache [cachind] ) {
+			printk (KERN_WARNING PRINTK_HEADER "Allocation of CCW cache failed\n");
+		}
+	}
+	return rc;
+}
+
+/* 
+ * ccwcache_cleanup
+ * called as a cleanup function for the ccw memory management
+ */
+
+void
+ccwcache_cleanup (void)
+{
+	int cachind;
+
+	/* Shrink the caches, if available */
+	for ( cachind = 0; cachind < CCW_NUMBER_CACHES; cachind ++ ) {
+		if ( ccw_cache[cachind] ) {
+			if ( kmem_cache_shrink(ccw_cache[cachind]) == 0 ) {
+				ccw_cache[cachind] = NULL;
+			}
+		}
+	}
+	debug_unregister( debug_area ,"ccwcache");
+}
+
+#ifdef MODULE
+int
+init_module ( void )
+{
+	int rc;
+	int i;
+	rc = ccwcache_init();
+	for ( i = 0; i < 200; i ++) {
+		PRINT_INFO ("allocated %p\n",ccw_alloc_request("test",i,200-i));
+	}
+	return rc;
+}
+
+void
+cleanup_module ( void )
+{
+	while ( ccwreq_actual ) {
+		PRINT_INFO ("freeing %p\n",ccwreq_actual -> int_next);
+		ccw_free_request( ccwreq_actual -> int_next );
+		if ( ccwreq_actual ) {
+			PRINT_INFO ("freeing %p\n",ccwreq_actual -> int_prev);
+			ccw_free_request( ccwreq_actual -> int_prev );
+		}
+		if ( ccwreq_actual ) {
+			PRINT_INFO ("freeing %p\n",ccwreq_actual);
+			ccw_free_request( ccwreq_actual);
+		}
+	}
+	ccwcache_cleanup();
+}
+#endif /* MODULE */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/char/con3215.c linux.17p18/drivers/s390/char/con3215.c
--- linux.vanilla/drivers/s390/char/con3215.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/char/con3215.c	Tue Aug  1 07:59:49 2000
@@ -30,8 +30,9 @@
 #define RAW3215_INBUF_SIZE  256	      /* input buffer size */
 #define RAW3215_MIN_SPACE   128	      /* minimum free space for wakeup */
 #define RAW3215_MIN_WRITE   1024      /* min. length for immediate output */
-#define RAW3215_MAX_CCWLEN  3968      /* max. bytes to write with one ccw */
-#define RAW3215_NR_CCWS	    ((RAW3215_BUFFER_SIZE/RAW3215_MAX_CCWLEN)+2)
+#define RAW3215_MAX_BYTES   3968      /* max. bytes to write with one ssch */
+#define RAW3215_MAX_NEWLINE 50        /* max. lines to write with one ssch */
+#define RAW3215_NR_CCWS	    3
 #define RAW3215_TIMEOUT	    HZ/10     /* time for delayed output */
 
 #define RAW3215_FIXED	    1	      /* 3215 console device is not be freed */
@@ -60,7 +61,8 @@
  */
 typedef struct _raw3215_req {
 	raw3215_type type;	      /* type of the request */
-	int start, end;		      /* start/end index into output buffer */
+	int start, len;		      /* start index & len in output buffer */
+        int delayable;                /* indication to wait for more data */
 	int residual;		      /* residual count for read request */
 	ccw1_t ccws[RAW3215_NR_CCWS]; /* space for the channel program */
 	struct _raw3215_info *info;   /* pointer to main structure */
@@ -74,6 +76,7 @@
 	char *inbuf;		      /* pointer to input buffer */
 	int head;		      /* first free byte in output buffer */
 	int count;		      /* number of bytes in output buffer */
+        int written;                  /* number of bytes in write requests */
 	devstat_t devstat;	      /* device status structure for do_IO */
 	struct tty_struct *tty;	      /* pointer to tty structure if present */
 	struct tq_struct tqueue;      /* task queue to bottom half */
@@ -104,7 +107,7 @@
 {
         int vdev;
 
-        vdev = simple_strtoul(str,&str,16);
+        vdev = simple_strtoul(str,&str,10);
         if (vdev >= 0 && vdev < 65536)
                 raw3215_condevice = vdev;
         return;
@@ -140,61 +143,83 @@
 }
 
 /*
- * Get a write request structure. That is either a new or the last
- * queued write request. The request structure is set up in 
- * raw3215_mk_write_ccw.
+ * Set up a read request that reads up to 160 byte from the 3215 device.
+ * If there is a queued read request it is used, but that shouldn't happen
+ * because a 3215 terminal won't accept a new read before the old one is
+ * completed.
  */
-static raw3215_req *raw3215_mk_write_req(raw3215_info *raw)
+static void raw3215_mk_read_req(raw3215_info *raw)
 {
 	raw3215_req *req;
+        ccw1_t *ccw;
 
-	/* check if there is a queued write request */
-	req = raw->queued_write;
+	/* there can only be ONE read request at a time */
+	req = raw->queued_read;
 	if (req == NULL) {
-		/* no queued write request, use new req structure */
+		/* no queued read request, use new req structure */
 		req = raw3215_alloc_req();
-		req->type = RAW3215_WRITE;
+		req->type = RAW3215_READ;
 		req->info = raw;
-		req->start = raw->head;
-	} else
-		raw->queued_write = NULL;
-	return req;
+                raw->queued_read = req;
+	}
+
+        ccw = req->ccws;
+        ccw->cmd_code = 0x0A; /* read inquiry */
+        ccw->flags = 0x20;    /* ignore incorrect length */
+        ccw->count = 160;
+        ccw->cda = (void *) virt_to_phys(raw->inbuf);
 }
 
 /*
- * Get a read request structure. If there is a queued read request
- * it is used, but that shouldn't happen because a 3215 terminal
- * won't accept a new read before the old one is completed.
+ * Set up a write request with the information from the main structure.
+ * A ccw chain is created that writes as much as possible from the output
+ * buffer to the 3215 device. If a queued write exists it is replaced by
+ * the new, probably lengthened request.
  */
-static raw3215_req *raw3215_mk_read_req(raw3215_info *raw)
+static void raw3215_mk_write_req(raw3215_info *raw)
 {
 	raw3215_req *req;
+	ccw1_t *ccw;
+	int len, count, ix, lines;
 
-	/* there can only be ONE read request at a time */
-	req = raw->queued_read;
+        if (raw->count <= raw->written)
+                return;
+        /* check if there is a queued write request */
+        req = raw->queued_write;
 	if (req == NULL) {
-		/* no queued read request, use new req structure */
+                /* no queued write request, use new req structure */
 		req = raw3215_alloc_req();
-		req->type = RAW3215_READ;
+                req->type = RAW3215_WRITE;
 		req->info = raw;
-	} else
-		raw->queued_read = NULL;
-	return req;
+                raw->queued_write = req;
+        } else {
+                raw->written -= req->len;
 }
 
+	ccw = req->ccws;
+        req->start = (raw->head - raw->count + raw->written) &
+                     (RAW3215_BUFFER_SIZE - 1);
 /*
- * Set up a write request with the information from the main structure.
- * A ccw chain is created that writes everything in the output buffer
- * to the 3215 device.
- */
-static int raw3215_mk_write_ccw(raw3215_info *raw, raw3215_req *req)
-{
-	ccw1_t *ccw;
-	int len, count, ix;
+         * now we have to count newlines. We can at max accept
+         * RAW3215_MAX_NEWLINE newlines in a single ssch due to
+         * a restriction in VM
+ */
+        lines = 0;
+        ix = req->start;
+        while (lines < RAW3215_MAX_NEWLINE && ix != raw->head) {
+                if (raw->buffer[ix] == '\n')
+                        lines++;
+                ix = (ix + 1) & (RAW3215_BUFFER_SIZE - 1);
+        }
+	len = ((ix - 1 - req->start) & (RAW3215_BUFFER_SIZE - 1)) + 1;
+        if (len > RAW3215_MAX_BYTES)
+                len = RAW3215_MAX_BYTES;
+        req->len = len;
+        raw->written += len;
+
+        /* set the indication if we should try to enlarge this request */
+        req->delayable = (ix == raw->head) && (len < RAW3215_MIN_WRITE);
 
-	ccw = req->ccws;
-	req->end = (raw->head - 1) & (RAW3215_BUFFER_SIZE - 1);
-	len = ((req->end - req->start) & (RAW3215_BUFFER_SIZE - 1)) + 1;
 	ix = req->start;
 	while (len > 0) {
 		if (ccw > req->ccws)
@@ -203,8 +228,7 @@
 		ccw->flags = 0x20;    /* ignore incorrect length ind.  */
 		ccw->cda =
 			(void *) virt_to_phys(raw->buffer + ix);
-		count = (len > RAW3215_MAX_CCWLEN) ? 
-			RAW3215_MAX_CCWLEN : len;
+		count = len;
 		if (ix + count > RAW3215_BUFFER_SIZE)
 			count = RAW3215_BUFFER_SIZE-ix;
 		ccw->count = count;
@@ -212,21 +236,17 @@
 		ix = (ix + count) & (RAW3215_BUFFER_SIZE - 1);
 		ccw++;
 	}
-	return len;
-}
-
 /*
- * Set up a read request that reads up to 160 byte from the 3215 device.
- */
-static void raw3215_mk_read_ccw(raw3215_info *raw, raw3215_req *req)
-{
-	ccw1_t *ccw;
-
-	ccw = req->ccws;
-	ccw->cmd_code = 0x0A; /* read inquiry */
-	ccw->flags = 0x20;    /* ignore incorrect length */
-	ccw->count = 160;
-	ccw->cda = (void *) virt_to_phys(raw->inbuf);
+         * Add a NOP to the channel program. 3215 devices are purely
+         * emulated and its much better to avoid the channel end 
+         * interrupt in this case.
+ */
+        if (ccw > req->ccws)
+                ccw[-1].flags |= 0x40; /* use command chaining */
+        ccw->cmd_code = 0x03; /* NOP */
+        ccw->flags = 0;
+        ccw->cda = 0;
+        ccw->count = 1;
 }
 
 /*
@@ -277,6 +297,7 @@
 	if (raw->flags & RAW3215_TIMER_RUNS) {
 		del_timer(&raw->timer);
 		raw->flags &= ~RAW3215_TIMER_RUNS;
+                raw3215_mk_write_req(raw);
 		raw3215_start_io(raw);
 	}
 	s390irq_spin_unlock_irqrestore(raw->irq, flags);
@@ -295,7 +316,7 @@
 	if (raw->queued_read != NULL)
 		raw3215_start_io(raw);
 	else if (raw->queued_write != NULL) {
-		if (raw->count >= RAW3215_MIN_WRITE ||
+		if ((raw->queued_write->delayable == 0) ||
 		    (raw->flags & RAW3215_FLUSHING)) {
 			/* execute write requests bigger than minimum size */
 			raw3215_start_io(raw);
@@ -327,7 +348,8 @@
 
 	raw = (raw3215_info *) data;
 	s390irq_spin_lock_irqsave(raw->irq, flags);
-	raw3215_try_io((raw3215_info *) data);
+        raw3215_mk_write_req(raw);
+        raw3215_try_io(raw);
         raw->flags &= ~RAW3215_BH_PENDING;
 	s390irq_spin_unlock_irqrestore(raw->irq, flags);
 	/* Check for pending message from raw3215_irq */
@@ -415,9 +437,7 @@
 		if ((raw = raw3215_find_info(irq)) == NULL)
 			return;              /* That shouldn't happen ... */
 		/* Setup a read request */
-		req = raw3215_mk_read_req(raw);
-		raw3215_mk_read_ccw(raw, req);
-		raw->queued_read = req;
+		raw3215_mk_read_req(raw);
                 if (MACHINE_IS_P390)
                         memset(raw->inbuf, 0, RAW3215_INBUF_SIZE);
                 raw3215_sched_bh(raw);
@@ -425,7 +445,8 @@
 	case 0x08:
 	case 0x0C:
 		/* Channel end interrupt. */
-		raw = req->info;
+		if ((raw = req->info) == NULL)
+                        return;              /* That shouldn't happen ... */
 		if (req->type == RAW3215_READ) {
 			/* store residual count, then wait for device end */
 			req->residual = stat->rescnt;
@@ -434,7 +455,8 @@
 			break;
 	case 0x04:
 		/* Device end interrupt. */
-		raw = req->info;
+                if ((raw = req->info) == NULL)
+                        return;              /* That shouldn't happen ... */
 		if (req->type == RAW3215_READ && raw->tty != NULL) {
 			tty = raw->tty;
 			count = 160 - req->residual;
@@ -493,8 +515,8 @@
 				tty_flip_buffer_push(raw->tty);
 			}
 		} else if (req->type == RAW3215_WRITE) {
-			raw->count -= ((req->end - req->start) &
-				       (RAW3215_BUFFER_SIZE - 1)) + 1;
+			raw->count -= req->len;
+                        raw->written -= req->len;
 		}
 		raw->flags &= ~RAW3215_WORKING;
 		raw3215_free_req(req);
@@ -511,11 +533,11 @@
 			/* Strange interrupt, I'll do my best to clean up */
                 if ((raw = raw3215_find_info(irq)) == NULL)
                         return;              /* That shouldn't happen ... */
-                if (raw == NULL) break;
 		if (req != NULL && req->type != RAW3215_FREE) {
-		        if (req->type == RAW3215_WRITE) 
-			        raw->count -= ((req->end - req->start) &
-					            (RAW3215_BUFFER_SIZE-1))+1;
+		        if (req->type == RAW3215_WRITE) {
+			        raw->count -= req->len;
+                                raw->written -= req->len;
+                        }
                         raw->flags &= ~RAW3215_WORKING;
                         raw3215_free_req(req);
 			}
@@ -536,7 +558,6 @@
 raw3215_write(raw3215_info *raw, const char *str,
 	      int from_user, unsigned int length)
 {
-	raw3215_req *req;
 	unsigned long flags;
 	int ret, c;
 	int count;
@@ -550,14 +571,15 @@
 
 		while (RAW3215_BUFFER_SIZE - raw->count < count) {
 			/* there might be a request pending */
+                        raw3215_mk_write_req(raw);
 			raw3215_try_io(raw);
 			if (wait_cons_dev(raw->irq) != 0) {
 				/* that shouldn't happen */
 				raw->count = 0;
+                                raw->written = 0;
 			} 
 		}
 
-		req = raw3215_mk_write_req(raw);
 		/* copy string to output buffer and convert it to EBCDIC */
 		if (from_user) {
 			while (1) {
@@ -598,12 +620,12 @@
 				ret += c;
 			}
 		}
-		raw3215_mk_write_ccw(raw, req);
-		raw->queued_write = req;
+                if (!(raw->flags & RAW3215_WORKING)) {
+                        raw3215_mk_write_req(raw);
 		/* start or queue request */
 		raw3215_try_io(raw);
+                }
 		s390irq_spin_unlock_irqrestore(raw->irq, flags);
-
 	}
 
 	return ret;
@@ -614,27 +636,28 @@
  */
 static void raw3215_putchar(raw3215_info *raw, unsigned char ch)
 {
-	raw3215_req *req;
 	unsigned long flags;
 
 	s390irq_spin_lock_irqsave(raw->irq, flags);
 	while (RAW3215_BUFFER_SIZE - raw->count < 1) {
 		/* there might be a request pending */
+                raw3215_mk_write_req(raw);
 		raw3215_try_io(raw);
 		if (wait_cons_dev(raw->irq) != 0) {
 			/* that shouldn't happen */
 			raw->count = 0;
+                        raw->written = 0;
 		}
 	}
 
-	req = raw3215_mk_write_req(raw);
 	raw->buffer[raw->head] = (char) _ascebc[(int) ch];
 	raw->head = (raw->head + 1) & (RAW3215_BUFFER_SIZE - 1);
 	raw->count++;
-	raw3215_mk_write_ccw(raw, req);
-	raw->queued_write = req;
+        if (!(raw->flags & RAW3215_WORKING)) {
+                raw3215_mk_write_req(raw);
 	/* start or queue request */
 	raw3215_try_io(raw);
+        }
 	s390irq_spin_unlock_irqrestore(raw->irq, flags);
 }
 
@@ -781,6 +804,7 @@
 		if (wait_cons_dev(raw->irq) != 0) {
 			/* that shouldn't happen */
 			raw->count = 0;
+                        raw->written = 0;
 		}
 		raw->flags &= ~RAW3215_FLUSHING;
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/char/hwc_tty.c linux.17p18/drivers/s390/char/hwc_tty.c
--- linux.vanilla/drivers/s390/char/hwc_tty.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/char/hwc_tty.c	Tue Aug  1 07:59:49 2000
@@ -73,8 +73,6 @@
 	return 0;
 }
 
-#if 0
-
 static void 
 hwc_tty_close (struct tty_struct *tty,
                            struct file *filp)
@@ -84,11 +82,13 @@
 			"do not close hwc tty because of wrong device number");
 		return;
 	}
+	if (tty->count > 1)
+		return;
+
 	hwc_tty_data.tty = NULL;
 
 	hwc_unregister_calls (&(hwc_tty_data.calls));
 }
-#endif
 
 static int 
 hwc_tty_write_room (struct tty_struct *tty)
@@ -316,7 +316,7 @@
 	hwc_tty_driver.termios_locked = hwc_tty_termios_locked;
 
 	hwc_tty_driver.open = hwc_tty_open;
-	hwc_tty_driver.close = NULL /* hwc_tty_close */;
+	hwc_tty_driver.close = hwc_tty_close;
 	hwc_tty_driver.write = hwc_tty_write;
 	hwc_tty_driver.put_char = hwc_tty_put_char;
 	hwc_tty_driver.flush_chars = hwc_tty_flush_chars;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/net/ctc.c linux.17p18/drivers/s390/net/ctc.c
--- linux.vanilla/drivers/s390/net/ctc.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/net/ctc.c	Tue Aug  1 07:59:49 2000
@@ -35,7 +35,7 @@
  *    0.50  Initial release shipped
  *    0.51  Bug fixes
  *          - CTC / ESCON network device can now handle up to 64 channels 
- *          - 3088-61 info message supperssed - CISCO 7206 - CLAW - ESCON 
+ *          - 3088-61 info message suppressed - CISCO 7206 - CLAW - ESCON 
  *          - 3088-62 info message suppressed - OSA/D   
  *          - channel: def ffffffed ... error message suppressed 
  *          - CTC / ESCON device was not recoverable after a lost connection with 
@@ -45,6 +45,19 @@
  *    0.52  Bug fixes 
  *          - Subchannel check message enhanced 
  *          - Read / Write retry routine check for CTC_STOP added  
+ *    0.53  Enhancement 
+ *          - Connect time changed from 150 to 300 seconds
+ *            This gives more a better chance to connect during IPL 
+ *    0.54  Bug fixes 
+ *          - Out of memory message enhanced 
+ *          - Zero buffer problem in ctc_irq_hb solved
+ *            A zero buffer could bring the ctc_irq_bh into a sk buffer allocation loop,
+ *            which could end in a out of memory situation.  
+ *    0.55  Bug fixes 
+ *          - Connect problems with systems which IPL later
+ *            SystemA is IPLed and issues a IFCONFIG ctcx against systemB which is currently
+ *            not available. When systemB comes up it is nearly inpossible to setup a 
+ *            connection.  
  */
 #include <linux/version.h>
 #include <linux/init.h>
@@ -617,6 +630,7 @@
                         kfree(p);
                         return -ENOMEM;
                 }
+                p->block->length = 0; 
         }
    
         if (ctc->free_anchor == NULL) 
@@ -912,9 +926,14 @@
         struct  ctc_priv  *privptr = NULL;
         net_device        *dev = NULL;    
         
-        ccw1_t            ccw_set_x_mode[2] = {{CCW_CMD_SET_EXTENDED, CCW_FLAG_SLI | CCW_FLAG_CC, 0, NULL},
+       /* ccw1_t            ccw_set_x_mode[2] = {{CCW_CMD_SET_EXTENDED, CCW_FLAG_SLI | CCW_FLAG_CC, 0, NULL},
+                                               {CCW_CMD_NOOP, CCW_FLAG_SLI, 0, NULL}};    */
+                                               
+       ccw1_t            ccw_set_x_mode[2] = {{CCW_CMD_SET_EXTENDED, CCW_FLAG_SLI , 0, NULL},
                                                {CCW_CMD_NOOP, CCW_FLAG_SLI, 0, NULL}}; 
 
+
+
         devstat_t *devstat = ((devstat_t *)initparm);
 
         /* Bypass all 'unsolicited interrupts' */
@@ -990,6 +1009,7 @@
                 case CTC_START_SELECT:
                         if (!ctc->flag & CTC_WRITE) {
                                 ctc->state = CTC_START_READ_TEST;
+                                ctc->free_anchor->block->length = 0;    
                                 ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->free_anchor->block);
                                 parm = (__u32) ctc;
                                 rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
@@ -1000,7 +1020,8 @@
                         } else {
                                 ctc->state = CTC_START_WRITE_TEST;
                                 /* ADD HERE THE RIGHT PACKET TO ISSUE A ROUND TRIP - PART 1 */
-                                ctc->ccw[1].count = 0;
+                                ctc->free_anchor->block->length = 0;    
+                                ctc->ccw[1].count = 2;              /* Transfer only length */
                                 ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->free_anchor->block);
                                 parm = (__u32) ctc; 
                                 rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags);
@@ -1072,6 +1093,7 @@
                         ctc_buffer_swap(&ctc->free_anchor, &ctc->proc_anchor);
 
                         if (ctc->free_anchor != NULL) {  
+                                ctc->free_anchor->block->length = 0;
                                 ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->free_anchor->block);
                                 parm = (__u32) ctc;
                                 rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
@@ -1195,8 +1217,9 @@
 
         while (ctc->proc_anchor != NULL) { 
 
-                lp = &ctc->proc_anchor->block->data;
+                if (ctc->proc_anchor->block->length != 0) {
 
+                        lp = &ctc->proc_anchor->block->data;
                 while ((__u8 *) lp < (__u8 *) &ctc->proc_anchor->block->length + ctc->proc_anchor->block->length) {
                         data_len = lp->length - PACKET_HEADER_LENGTH;
                         skb = dev_alloc_skb(data_len); 
@@ -1210,10 +1233,11 @@
                                 privptr->stats.rx_packets++;
                         } else {
                                 privptr->stats.rx_dropped++; 
-                                printk(KERN_WARNING "%s: is low on memory\n",dev->name);
+                                        printk(KERN_WARNING "%s: is low on memory (sk buffer)\n",dev->name);
                         }
                         (__u8 *)lp += lp->length;
                 }
+                }
 
                 s390irq_spin_lock_irqsave(ctc->irq, saveflags);
                 ctc_buffer_swap(&ctc->proc_anchor, &ctc->free_anchor);
@@ -1251,6 +1275,7 @@
         if (ctc->state == CTC_STOP)
                 return;
         s390irq_spin_lock_irqsave(ctc->irq, saveflags);
+        ctc->free_anchor->block->length = 0;
         ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->free_anchor->block);
         parm = (__u32) ctc; 
         rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
@@ -1276,8 +1301,15 @@
 #endif 
         if (ctc->state == CTC_STOP)
                 return;
+ 
+        while (ctc->proc_anchor != NULL) { 
+                ctc->proc_anchor->block->length = 0;
+                ctc_buffer_swap(&ctc->proc_anchor, &ctc->free_anchor);
+        } 
+
+        ctc_buffer_swap(&ctc->free_anchor, &ctc->proc_anchor);
         s390irq_spin_lock_irqsave(ctc->irq, saveflags);
-        ctc->ccw[1].count = 0;
+        ctc->ccw[1].count = 2;
         ctc->ccw[1].cda  = (char *)virt_to_phys(ctc->proc_anchor->block);
         parm = (__u32) ctc; 
         rc = do_IO (ctc->irq, &ctc->ccw[0], parm, 0xff, flags );
@@ -1354,7 +1386,7 @@
                 init_timer(&timer);
                 timer.function = (void *)ctc_timer; 
                 timer.data = (__u32)&privptr->channel[i];
-                timer.expires = jiffies + 150*HZ;                        /* time to connect with the remote side */
+                timer.expires = jiffies + 300*HZ;                        /* time to connect with the remote side */
                 add_timer(&timer);
 
                 s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);
@@ -1382,13 +1414,13 @@
                 printk(KERN_INFO "%s: remote side is currently not ready\n", dev->name);
                 
                 for (i = 0; i < 2;  i++) {
-                        s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);
+                     /* s390irq_spin_lock_irqsave(privptr->channel[i].irq, saveflags);
                         parm = (unsigned long) &privptr->channel[i];
                         privptr->channel[i].state = CTC_STOP;
-                        rc = halt_IO(privptr->channel[i].irq, parm, flags);
+                        rc = halt_IO(privptr->channel[i].irq, parm, flags); /
                         s390irq_spin_unlock_irqrestore(privptr->channel[i].irq, saveflags);
                         if (rc != 0)
-                                ccw_check_return_code(dev, rc);
+                                ccw_check_return_code(dev, rc);     */
                         for (j = 0; j < CTC_BLOCKS;  j++) 
                                 ctc_buffer_free(&privptr->channel[i]);
                 }
@@ -1421,7 +1453,6 @@
 static int ctc_release(net_device *dev)
 {   
         int                rc;
-        int                x; 
         int                i;
         int                j;
         __u8               flags = 0x00;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/s390/net/iucv.c linux.17p18/drivers/s390/net/iucv.c
--- linux.vanilla/drivers/s390/net/iucv.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/s390/net/iucv.c	Tue Aug  1 07:59:49 2000
@@ -7,8 +7,10 @@
  *    Author(s): Stefan Hegewald <hegewald@de.ibm.com>
  *               Hartmut Penner <hpenner@de.ibm.com> 
  * 
+ *    
  *    2.3 Updates Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com)
  *                Martin Schwidefsky (schwidefsky@de.ibm.com)
+ *                Alan Altmark (Alan_Altmark@us.ibm.com)
  *                
 
  */
@@ -42,10 +44,10 @@
 
 
 
-
 #define DEBUG123
 #define MAX_DEVICES  10
 
+
 extern char _ascebc[];
 
 /* 
@@ -496,8 +498,6 @@
   /* get own buffer: */
   extern_int_buffer = (INTERRUPT_T*) iucv_ext_int_buffer;
   
-  netif_enter_interrupt(dev);        /* lock ! */
-  
 #ifdef DEBUG
   printk(  "iucv: do_iucv_interrupt %x received; pathid: %02X\n",
 	   extern_int_buffer->iptype,extern_int_buffer->ippathid);
@@ -505,6 +505,14 @@
   dumpit((char *)&extern_int_buffer[0],40);
 #endif
   
+  if (extern_int_buffer->iptype == 0x01)
+    dev = get_device_from_userid(&((char*) extern_int_buffer)[8]);
+  else
+    dev = get_device_from_pathid(extern_int_buffer->ippathid);
+
+  netif_enter_interrupt(dev);        /* lock ! */
+  privptr = (struct iucv_priv *)(dev->priv);
+  
   switch (extern_int_buffer->iptype)
     {
     case 0x01: /* connection pending ext interrrupt */
@@ -519,11 +527,7 @@
 	iucv_retrieve_buffer(glob_command_buffer);
 	break;
       }
-#ifdef DEBUG
-      dumpit(&((char *)extern_int_buffer)[8],8);
-#endif
-      dev = get_device_from_userid(&((char*)extern_int_buffer)[8]);
-      privptr = (struct iucv_priv *)(dev->priv);
+
       privptr->pathid =  extern_int_buffer->ippathid;
       
 #ifdef DEBUG
@@ -542,8 +546,6 @@
       if( extern_int_buffer->ipmsgtag !=0)
 	{
 	  /* get ptr's to kernel struct with local & broadcast address */
-	  dev = get_device_from_pathid(extern_int_buffer->ippathid);
-	  privptr = (struct iucv_priv *)(dev->priv);
 	  indev = dev->ip_ptr;
 	  inaddr = (struct in_ifaddr*) indev->ifa_list;
 	}
@@ -595,8 +597,6 @@
 		   (unsigned int)extern_int_buffer->ipaudit);
 	}
       /* a transmission is over: tell we are no more busy */
-      dev = get_device_from_pathid(extern_int_buffer->ippathid);
-      privptr = (struct iucv_priv *)(dev->priv);
       privptr->stats.tx_packets++;
       netif_wake_queue(dev);                /* transmission is no longer busy*/
       break;
@@ -607,8 +607,6 @@
 #ifdef DEBUG
       printk(  "message pending.\n");
 #endif
-      dev = get_device_from_pathid(extern_int_buffer->ippathid);
-      privptr = (struct iucv_priv *)(dev->priv);
       rcvptr = &privptr->receive_buffer[0];
       
       /* re-set receive buffer */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sbus/char/Makefile linux.17p18/drivers/sbus/char/Makefile
--- linux.vanilla/drivers/sbus/char/Makefile	Fri Apr 21 12:46:24 2000
+++ linux.17p18/drivers/sbus/char/Makefile	Tue Aug  1 08:13:46 2000
@@ -37,6 +37,14 @@
   endif
 endif
 
+ifeq ($(CONFIG_DISPLAY7SEG),y)
+O_OBJS += display7seg.o
+else
+  ifeq ($(CONFIG_DISPLAY7SEG),m)
+  M_OBJS += display7seg.o
+  endif
+endif
+
 endif # eq($(CONFIG_PCI,y)
 
 ifeq ($(CONFIG_OBP_FLASH),y)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sbus/char/display7seg.c linux.17p18/drivers/sbus/char/display7seg.c
--- linux.vanilla/drivers/sbus/char/display7seg.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sbus/char/display7seg.c	Tue Aug  1 08:13:46 2000
@@ -0,0 +1,264 @@
+/* $Id: display7seg.c,v 1.1.2.1 2000/07/27 01:50:59 davem Exp $
+ *
+ * display7seg - Driver implementation for the 7-segment display
+ * present on Sun Microsystems CP1400 and CP1500
+ *
+ * Copyright (c) 2000 Eric Brower (ebrower@usa.net)
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/fs.h>
+#include <linux/errno.h>
+#include <linux/major.h>
+#include <linux/init.h>
+#include <linux/miscdevice.h>
+#include <linux/ioport.h>		/* request_region, check_region */
+#include <asm/ebus.h>			/* EBus device			*/
+#include <asm/oplib.h>			/* OpenProm Library 		*/
+#include <asm/uaccess.h>		/* put_/get_user_ret		*/
+
+#include <asm/display7seg.h>
+
+#define D7S_MINOR	193
+#define D7S_OBPNAME	"display7seg"
+#define D7S_DEVNAME "d7s"
+
+static int sol_compat = 0;		/* Solaris compatibility mode	*/
+
+#ifdef MODULE
+EXPORT_NO_SYMBOLS;
+
+/* Solaris compatibility flag -
+ * The Solaris implementation omits support for several
+ * documented driver features (ref Sun doc 806-0180-03).  
+ * By default, this module supports the documented driver 
+ * abilities, rather than the Solaris implementation:
+ *
+ * 	1) Device ALWAYS reverts to OBP-specified FLIPPED mode
+ * 	   upon closure of device or module unload.
+ * 	2) Device ioctls D7SIOCRD/D7SIOCWR honor toggling of
+ * 	   FLIP bit
+ *
+ * If you wish the device to operate as under Solaris,
+ * omitting above features, set this parameter to non-zero.
+ */
+MODULE_PARM
+	(sol_compat, "1i");
+MODULE_PARM_DESC
+	(sol_compat, 
+	 "Disables documented functionality omitted from Solaris driver");
+
+MODULE_AUTHOR
+	("Eric Brower <ebrower@usa.net>");
+MODULE_DESCRIPTION
+	("7-Segment Display driver for Sun Microsystems CP1400/1500");
+MODULE_SUPPORTED_DEVICE
+	("d7s");
+#endif /* ifdef MODULE */
+
+/*
+ * Register block- see header for details
+ * -----------------------------------------
+ * | DP | ALARM | FLIP | 4 | 3 | 2 | 1 | 0 |
+ * -----------------------------------------
+ *
+ * DP 		- Toggles decimal point on/off 
+ * ALARM	- Toggles "Alarm" LED green/red
+ * FLIP		- Inverts display for upside-down mounted board
+ * bits 0-4	- 7-segment display contents
+ */
+
+struct d7s_regs {
+	volatile __u8 regblk;
+};
+
+volatile struct d7s_regs *regs;
+
+static inline void d7s_free(void)
+{
+	release_region((unsigned long)regs, sizeof(*regs));
+}
+
+static inline int d7s_obpflipped(void)
+{
+	int opt_node, ret;
+
+	opt_node = prom_getchild(prom_root_node);
+	opt_node = prom_searchsiblings(opt_node, "options");
+
+	ret = prom_getintdefault(opt_node, "d7s-flipped?", -1);
+	if (ret != -1)
+		ret = 0;
+	else
+		ret = 1;
+
+	return ret;
+}
+
+static int d7s_open(struct inode *inode, struct file *f)
+{
+	if (D7S_MINOR != MINOR(inode->i_rdev))
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int d7s_release(struct inode *inode, struct file *f)
+{
+	if (D7S_MINOR != MINOR(inode->i_rdev))
+		return -ENODEV;
+	
+	MOD_DEC_USE_COUNT;
+
+	/* Reset flipped state to OBP default only if
+	 * no other users have the device open and we
+	 * are not operating in solaris-compat mode.
+	 */
+	if (MOD_IN_USE == 0 && sol_compat == 0) {
+		if (d7s_obpflipped() == 0)
+			regs->regblk |= D7S_FLIP;
+		else
+			regs->regblk &= ~D7S_FLIP;
+	}
+
+	return 0;
+}
+
+static int d7s_ioctl(struct inode *inode, struct file *f, 
+		     unsigned int cmd, unsigned long arg)
+{
+	__u8 ireg = 0;
+
+	if (D7S_MINOR != MINOR(inode->i_rdev))
+		return -ENODEV;
+
+	switch (cmd) {
+	case D7SIOCWR:
+		/* Assign device register values,
+		 * we mask-out D7S_FLIP if in sol_compat mode.
+		 */
+		get_user_ret(ireg, (int *) arg, -EFAULT);
+		if (sol_compat != 0) {
+			if (regs->regblk & D7S_FLIP)
+				ireg |= D7S_FLIP;
+			else
+				ireg &= ~D7S_FLIP;
+		}
+		regs->regblk = ireg;
+		break;
+	case D7SIOCRD:
+		/* Retrieve device register values.
+		 *
+		 * NOTE: Solaris implementation returns D7S_FLIP bit
+		 * as toggled by user, even though it does not honor it.
+		 * This driver will not misinform you about the state
+		 * of your hardware while in sol_compat mode.
+		 */
+		put_user_ret(regs->regblk, (int *) arg, -EFAULT);
+		break;
+	case D7SIOCTM:
+		/* Toggle device mode-- flip display orientation. */
+		if (regs->regblk & D7S_FLIP)
+			regs->regblk &= ~D7S_FLIP;
+		else
+			regs->regblk |= D7S_FLIP;
+		break;
+	};
+
+	return 0;
+}
+
+static struct file_operations d7s_fops = {
+	NULL,			/* lseek 		*/
+	NULL,			/* read			*/
+	NULL,			/* write		*/
+	NULL,			/* readdir		*/
+	NULL,			/* select 		*/
+	d7s_ioctl,
+	NULL,			/* mmap 		*/
+	d7s_open,
+	NULL,			/* flush 		*/
+	d7s_release,
+ 	NULL,			/* fsync 		*/
+	NULL,			/* fasync 		*/
+	NULL,			/* chk media chg*/
+	NULL,			/* revalidate 	*/
+ 	NULL,			/* lock 		*/
+};
+
+static struct miscdevice d7s_miscdev = { D7S_MINOR, D7S_DEVNAME, &d7s_fops };
+
+#ifdef MODULE
+int init_module(void)
+#else
+__initfunc(int d7s_init(void))
+#endif
+{
+	struct linux_ebus *ebus = NULL;
+	struct linux_ebus_device *edev = NULL;
+	int iTmp = 0;
+
+	for_each_ebus(ebus) {
+		for_each_ebusdev(edev, ebus) {
+			if (!strcmp(edev->prom_name, D7S_OBPNAME))
+				goto ebus_done;
+		}
+	}
+
+ebus_done:
+	if (!edev) {
+		printk("%s: unable to locate device\n", D7S_DEVNAME);
+		return -ENODEV;
+	}
+
+	if (check_region(edev->base_address[0], sizeof(*regs))) {
+		printk("%s: Can't get region %lx, %d\n",
+		       __FUNCTION__, edev->base_address[0], (int)sizeof(*regs));
+		return -ENODEV;
+	}
+
+	regs = (struct d7s_regs *) edev->base_address[0];
+	request_region((unsigned long) regs, sizeof(*regs), D7S_OBPNAME);
+	iTmp = misc_register(&d7s_miscdev);
+	if (iTmp != 0) {
+		printk("%s: unable to acquire miscdevice minor %i\n",
+		       D7S_DEVNAME, D7S_MINOR);
+		return iTmp;
+	}
+
+	/* OBP option "d7s-flipped?" is honored as default
+	 * for the device, and reset default when detached
+	 */
+	iTmp = d7s_obpflipped();
+	if (iTmp == 0)
+		regs->regblk |= D7S_FLIP;
+	else
+		regs->regblk &= ~D7S_FLIP;
+
+	printk("%s: 7-Segment Display%s at 0x%lx %s\n", 
+		D7S_DEVNAME,
+		(iTmp == 0) ? (" (FLIPPED)") : (""),
+		edev->base_address[0],
+		(sol_compat != 0) ? ("in sol_compat mode") : (""));
+	return 0;
+}
+
+#ifdef MODULE
+void cleanup_module(void)
+{
+	/* Honor OBP d7s-flipped? unless operating in solaris-compat mode. */
+	if (sol_compat == 0) {
+		if (d7s_obpflipped() == 0)
+			regs->regblk |= D7S_FLIP;
+		else
+			regs->regblk &= ~D7S_FLIP;
+	}
+
+	misc_deregister(&d7s_miscdev);
+	d7s_free();
+}
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/3w-xxxx.c linux.17p18/drivers/scsi/3w-xxxx.c
--- linux.vanilla/drivers/scsi/3w-xxxx.c	Fri Apr 21 12:46:26 2000
+++ linux.17p18/drivers/scsi/3w-xxxx.c	Fri Aug  4 15:30:49 2000
@@ -2,6 +2,8 @@
    3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
 
    Written By: Adam Radford <linux@3ware.com>
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
    Copyright (C) 1999-2000 3ware Inc.
 
    Kernel compatablity By: 	Andre Hedrick <andre@suse.com>
@@ -47,6 +49,21 @@
 
    For more information, goto:
    http://www.3ware.com
+
+   History
+   -------
+   0.1.000 -     Initial release.
+   0.4.000 -     Added support for Asynchronous Event Notification through
+                 ioctls for 3DM.
+   1.0.000 -     Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
+                 to disable drive write-cache before writes.
+   1.1.000 -     Fixed performance bug with DPO & FUA not existing for WRITE_6.
+   1.2.000 -     Added support for clean shutdown notification/feature table.
+   1.02.00.001 - Added support for full command packet posts through ioctls
+                 for 3DM.
+                 Bug fix so hot spare drives don't show up.
+   1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
+                 systems.
 */
 
 #include <linux/module.h>
@@ -65,6 +82,7 @@
 #include <linux/string.h>
 #include <linux/delay.h>
 #include <linux/smp.h>
+#include <linux/reboot.h>
 
 #include <asm/spinlock.h>
 #include <asm/errno.h>
@@ -83,6 +101,12 @@
 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);
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
+
+/* Notifier block to get a notify on system shutdown/halt/reboot */
+static struct notifier_block tw_notifier = {
+  tw_halt, NULL, 0
+};
 
 struct proc_dir_entry tw_scsi_proc_entry = {
 	PROC_SCSI_3W_XXXX,
@@ -91,7 +115,7 @@
 };
 
 /* Globals */
-char *tw_driver_version="1.1.000";
+char *tw_driver_version="1.02.00.002";
 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
 int tw_device_extension_count = 0;
 
@@ -230,7 +254,7 @@
 				if (command_packet->status != 0) {
 					if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
 						/* Bad response */
-						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, flags = 0x%x.\n", command_packet->flags);
+						printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 						return 1;
 					} else {
 						/* We know this is a 3w-1x00, and doesn't support aen's */
@@ -568,6 +592,7 @@
 	TW_Device_Extension *tw_dev2;
 	struct pci_dev *tw_pci_dev = pci_devices;
 	u32 status_reg_value;
+	unsigned char c = 1;
 
 	dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
 	while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, TW_DEVICE_ID, tw_pci_dev))) {
@@ -666,7 +691,7 @@
 			continue;
 		}
 
-		error = tw_initconnection(tw_dev);
+		error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 		if (error) {
 			printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
 			release_region((tw_dev->tw_pci_dev->base_address[0]), TW_IO_ADDRESS_RANGE);
@@ -726,10 +751,14 @@
 		/* Free the temporary device extension */
 		if (tw_dev)
 			kfree(tw_dev);
+		/* Tell the firmware we support shutdown notification*/
+		tw_setfeature(tw_dev2, 2, 1, &c);
 	}
 
 	if (numcards == 0) 
 		printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
+	else
+	  register_reboot_notifier(&tw_notifier);
 
 	return numcards;
 } /* End tw_findcards() */
@@ -751,8 +780,22 @@
 	}
 } /* End tw_free_device_extension() */
 
+/* Clean shutdown routine */
+static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
+{
+	int i;
+	
+	for (i=0;i<tw_device_extension_count;i++) {
+		printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i);
+		tw_shutdown_device(tw_device_extension_list[i]);
+	}
+	unregister_reboot_notifier(&tw_notifier);
+	
+	return NOTIFY_OK;
+} /* End tw_halt() */
+
 /* This function will send an initconnection command to controller */
-int tw_initconnection(TW_Device_Extension *tw_dev) 
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits) 
 {
 	u32 command_que_addr, command_que_value;
 	u32 status_reg_addr, status_reg_value;
@@ -784,7 +827,7 @@
 	command_packet->byte3.host_id = 0x0;
 	command_packet->status = 0x0;
 	command_packet->flags = 0x0;
-	command_packet->byte6.message_credits = TW_INIT_MESSAGE_CREDITS; 
+	command_packet->byte6.message_credits = message_credits; 
 	command_packet->byte8.init_connection.response_queue_pointer = 0x0;
 	command_que_value = tw_dev->command_packet_physical_address[request_id];
 
@@ -815,7 +858,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, flags = 0x%x.\n", command_packet->flags);
+				printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				return 1;
 			}
 			break;	/* Response was okay, so we exit */
@@ -962,7 +1005,7 @@
 			}
 			if (command_packet->status != 0) {
 				/* bad response */
-				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, flags = 0x%x.\n", command_packet->flags);
+				printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				return 1;
 			}
 			found = 1;
@@ -984,9 +1027,11 @@
 		if (is_unit_present[i] == 0) {
 			tw_dev->is_unit_present[i] = FALSE;
 		} else {
+		  if (is_unit_present[i] & TW_UNIT_ONLINE) {
 			dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
 			tw_dev->is_unit_present[i] = TRUE;
 			num_units++;
+		  }
 		}
 	}
 	tw_dev->num_units = num_units;
@@ -1090,7 +1135,7 @@
 				request_id = response_que.u.response_id;
 				command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 				if (command_packet->status != 0) {
-					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, flags = 0x%x.\n", command_packet->flags);
+					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
 				}
 				if (tw_dev->state[request_id] != TW_S_POSTED) {
 					printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode);
@@ -1186,7 +1231,7 @@
 	/* Initialize command packet */
 	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
 	if (command_packet == NULL) {
-		printk(KERN_WARNING "3w-xxxx: twioctl(): Bad command packet virtual address.\n");
+		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
 		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);
@@ -1256,6 +1301,12 @@
 			tw_dev->srb[request_id]->result = (DID_OK << 16);
 			tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
 			return 0;
+		case TW_CMD_PACKET:
+		  memcpy(command_packet, ioctl->data, sizeof(TW_Command));
+		  command_packet->request_id = request_id;
+		  tw_post_command_packet(tw_dev, request_id);
+		
+		  return 0;
 		default:
 			printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
 			tw_dev->state[request_id] = TW_S_COMPLETED;
@@ -1480,7 +1531,7 @@
 		return 1;
 	}
 
-	error = tw_initconnection(tw_dev);
+	error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
 	if (error) {
 		printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
 		return 1;
@@ -1804,6 +1855,11 @@
 	/* Tell kernel scsi-layer we are gone */
 	scsi_unregister(tw_host);
 
+	/* Fake like we just shut down, so notify the card that
+	 * we "shut down cleanly".
+	 */
+	tw_halt(0, 0, 0);  // parameters aren't actually used
+
 	return 0;
 } /* End tw_scsi_release() */
 
@@ -1901,8 +1957,10 @@
 		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);
+		  }
 		}
 	}
 
@@ -2125,6 +2183,92 @@
 	return 0;
 } /* End tw_scsiop_test_unit_ready() */
 
+/* Set a value in the features table */
+int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
+                  unsigned char *val)
+{
+	TW_Param *param;
+	TW_Command  *command_packet;
+	TW_Response_Queue response_queue;
+	int request_id = 0;
+	u32 command_que_value, command_que_addr;
+	u32 status_reg_addr, status_reg_value;
+	u32 response_que_addr;
+	u32 param_value;
+	int imax, i;
+
+	/* Initialize SetParam command packet */
+	if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
+		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
+		return 1;
+	}
+	command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
+	memset(command_packet, 0, sizeof(TW_Sector));
+	param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
+
+	command_packet->byte0.opcode = TW_OP_SET_PARAM;
+	command_packet->byte0.sgl_offset  = 2;
+	param->table_id = 0x404;  /* Features table */
+	param->parameter_id = parm;
+	param->parameter_size_bytes = param_size;
+	memcpy(param->data, val, param_size);
+
+	param_value = tw_dev->alignment_physical_address[request_id];
+	if (param_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
+		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]);
+	}
+	command_packet->byte8.param.sgl[0].address = param_value;
+	command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
+
+	command_packet->size = 4;
+	command_packet->request_id = request_id;
+	command_packet->byte6.parameter_count = 1;
+
+	command_que_value = tw_dev->command_packet_physical_address[request_id];
+	if (command_que_value == 0) {
+		printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
+		return 1;
+	}
+	command_que_addr = tw_dev->registers.command_que_addr;
+	status_reg_addr = tw_dev->registers.status_reg_addr;
+	response_que_addr = tw_dev->registers.response_que_addr;
+
+	/* Send command packet to the board */
+	outl(command_que_value, command_que_addr);
+
+	/* Poll for completion */
+	imax = TW_POLL_MAX_RETRIES;
+	for (i=0;i<imax;i++) {
+		mdelay(10);
+		status_reg_value = inl(status_reg_addr);
+		if (tw_check_bits(status_reg_value)) {
+			printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
+			return 1;
+		}
+		if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
+			response_queue.value = inl(response_que_addr);
+			request_id = (unsigned char)response_queue.u.response_id;
+			if (request_id != 0) {
+				/* unexpected request id */
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
+				return 1;
+			}
+			if (command_packet->status != 0) {
+				/* bad response */
+				printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
+				return 1;
+			}
+			break; /* Response was okay, so we exit */
+		}
+	}
+
+	return 0;
+} /* End tw_setfeature() */
+
 /* This function will setup the interrupt handler */
 int tw_setup_irq(TW_Device_Extension *tw_dev)
 {
@@ -2140,6 +2284,29 @@
 	}
 	return 0;
 } /* End tw_setup_irq() */
+
+/* This function will tell the controller we're shutting down by sending
+   initconnection with a 1 */
+int tw_shutdown_device(TW_Device_Extension *tw_dev)
+{
+	int error;
+
+	/* Disable interrupts */
+	tw_disable_interrupts(tw_dev);
+
+	/* poke the board */
+	error = tw_initconnection(tw_dev, 1);
+	if (error) {
+		printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
+	} else {
+		printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
+	}
+
+	/* Re-enable interrupts */
+	tw_enable_interrupts(tw_dev);
+
+	return 0;
+} /* End tw_shutdown_device() */
 
 /* This function will soft reset the controller */
 void tw_soft_reset(TW_Device_Extension *tw_dev) 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/3w-xxxx.h linux.17p18/drivers/scsi/3w-xxxx.h
--- linux.vanilla/drivers/scsi/3w-xxxx.h	Wed May  3 22:31:20 2000
+++ linux.17p18/drivers/scsi/3w-xxxx.h	Thu Aug 17 18:11:50 2000
@@ -2,7 +2,9 @@
    3w-xxxx.h -- 3ware Storage Controller device driver for Linux.
    
    Written By: Adam Radford <linux@3ware.com>
-   Copyright (C) 1999 3ware Inc.
+   Modifications By: Joel Jacobson <linux@3ware.com>
+
+   Copyright (C) 1999, 2000 3ware Inc.
 
    Kernel compatablity By:	Andre Hedrick <andre@suse.com>
    Non-Copyright (C) 2000	Andre Hedrick <andre@suse.com>
@@ -106,6 +108,7 @@
 #define TW_OP_SET_PARAM	      0x13
 #define TW_OP_SECTOR_INFO     0x1a
 #define TW_OP_AEN_LISTEN      0x1c
+#define TW_CMD_PACKET         0x1d
 
 /* Asynchronous Event Notification (AEN) Codes */
 #define TW_AEN_QUEUE_EMPTY       0x0000
@@ -135,7 +138,7 @@
 #define TW_BLOCK_SIZE			      0x200 /* 512-byte blocks */
 #define TW_IOCTL                              0x80
 #define TW_MAX_AEN_TRIES                      100
-
+#define TW_UNIT_ONLINE                        1
 #define TW_IN_INTR                            1
 
 /* Macros */
@@ -305,7 +308,7 @@
 void tw_enable_interrupts(TW_Device_Extension *tw_dev);
 int tw_findcards(Scsi_Host_Template *tw_host);
 void tw_free_device_extension(TW_Device_Extension *tw_dev);
-int tw_initconnection(TW_Device_Extension *tw_dev);
+int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits);
 int tw_initialize_device_extension(TW_Device_Extension *tw_dev);
 int tw_initialize_units(TW_Device_Extension *tw_dev);
 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id);
@@ -328,7 +331,9 @@
 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id);
 int tw_scsiop_test_unit_ready(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);
+int tw_shutdown_device(TW_Device_Extension *tw_dev);
 void tw_soft_reset(TW_Device_Extension *tw_dev);
 int tw_state_request_finish(TW_Device_Extension *tw_dev,int request_id);
 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id);
@@ -351,6 +356,8 @@
 	eh_strategy_handler : NULL,			\
 	eh_abort_handler : tw_scsi_eh_abort,		\
 	eh_device_reset_handler : NULL,			\
+        eh_bus_reset_handler : NULL,                    \
+        eh_host_reset_handler : tw_scsi_eh_reset,       \
 	abort : NULL,					\
 	reset : NULL,					\
 	slave_attach : NULL,				\
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/aic7xxx/aic7xxx.seq linux.17p18/drivers/scsi/aic7xxx/aic7xxx.seq
--- linux.vanilla/drivers/scsi/aic7xxx/aic7xxx.seq	Fri Apr 21 12:46:27 2000
+++ linux.17p18/drivers/scsi/aic7xxx/aic7xxx.seq	Tue Aug  1 07:59:51 2000
@@ -60,11 +60,7 @@
 	clr	SCSISIGO;		/* De-assert BSY */
 	and	SXFRCTL1, ~BITBUCKET;
 	/* Always allow reselection */
-	if ((p->flags & AHC_TARGETMODE) != 0) {
-		mvi	SCSISEQ, ENSELI|ENRSELI|ENAUTOATNP;
-	} else {
-		mvi	SCSISEQ, ENRSELI|ENAUTOATNP;
-	}
+	mvi	SCSISEQ, ENRSELI|ENAUTOATNP;
 
 	if ((p->features & AHC_CMD_CHAN) != 0) {
 		/* Ensure that no DMA operations are in progress */
@@ -236,118 +232,6 @@
 
 selection:
 	test	SSTAT0,SELDO	jnz select_out;
-select_in:
-	if ((p->flags & AHC_TARGETMODE) != 0) {
-		test	SSTAT0, TARGET	jz initiator_reselect;
-		/*
-		 * We've just been selected.  Assert BSY and
-		 * setup the phase for receiving the messages
-		 * from the target.
-		 */
-		mvi	SCSISIGO, P_MESGOUT|BSYO;
-		mvi	CLRSINT0, CLRSELDO;
-
-		/*
-		 * If ATN isn't asserted, go directly to bus free.
-		 */
-		test	SCSISIGI, ATNI	jz	target_busfree;
-
-		/*
-		 * Setup the DMA for sending the identify and
-		 * command information.
-		 */
-		mov	A, TMODE_CMDADDR_NEXT;
-		mvi	DINDEX, HADDR;
-		mvi	TMODE_CMDADDR call set_32byte_addr;
-		mvi	DFCNTRL, FIFORESET;
-
-		clr	SINDEX;
-		/* Watch ATN closely now */
-message_loop:
-		or	SXFRCTL0, SPIOEN;
-		test	SSTAT0, SPIORDY jz .;
-		and	SXFRCTL0, ~SPIOEN;
-		mov	DINDEX, SCSIDATL;
-		mov	DFDAT, DINDEX;
-		inc	SINDEX;
-
-		/* Message Testing... */
-		test	DINDEX, MSG_IDENTIFYFLAG jz . + 2;
-		mov	ARG_1, DINDEX;
-
-		test	SCSISIGI, ATNI	jnz	message_loop;
-		add	A, -4, SINDEX;
-		jc	target_cmdphase;
-		mvi	DFDAT, SCB_LIST_NULL;	/* Terminate the message list */
-
-target_cmdphase:
-		add	HCNT[0], 1, A;
-		clr	HCNT[1];
-		clr	HCNT[2];
-		mvi	SCSISIGO, P_COMMAND|BSYO;
-		or	SXFRCTL0, SPIOEN;
-		test	SSTAT0, SPIORDY jz .;
-		mov	A, SCSIDATL;
-		mov	DFDAT, A;	/* Store for host */
-
-		/*
-		 * Determine the number of bytes to read
-		 * based on the command group code.  Count is
-		 * one less than the total since we've already
-		 * fetched the first byte.
-		 */
-		clr	SINDEX;
-		shr	A, CMD_GROUP_CODE_SHIFT;
-		add	SEQADDR0, A;
-
-		add	SINDEX, CMD_GROUP0_BYTE_DELTA;
-		nop;	/* Group 1 and 2 are the same */
-		add	SINDEX, CMD_GROUP2_BYTE_DELTA;
-		nop;	/* Group 3 is reserved */
-		add	SINDEX, CMD_GROUP4_BYTE_DELTA;
-		add	SINDEX, CMD_GROUP5_BYTE_DELTA;
-		/* Group 6 and 7 are not handled yet */
-
-		mov	A, SINDEX;
-		add	HCNT[0], A;
-
-command_loop:
-		test	SSTAT0, SPIORDY jz .;
-		cmp	SINDEX, 1 jne . + 2;
-		and	SXFRCTL0, ~SPIOEN;	/* Last Byte */
-		mov	DFDAT, SCSIDATL;
-		dec	SINDEX;
-		test	SINDEX, 0xFF jnz command_loop;
-
-		or	DFCNTRL, HDMAEN|FIFOFLUSH;
-	
-		call	dma_finish;
-
-		test	ARG_1, MSG_IDENTIFY_DISCFLAG jz selectin_post;
-
-		mvi	SCSISIGO, P_MESGIN|BSYO;
-
-		or	SXFRCTL0, SPIOEN;
-
-		mvi	MSG_DISCONNECT call target_outb;
-	
-selectin_post:
-		inc	TMODE_CMDADDR_NEXT;
-		cmp	TMODE_CMDADDR_NEXT, TMODE_NUMCMDS jne . + 2;
-		clr	TMODE_CMDADDR_NEXT;
-		mvi	QOUTFIFO, SCB_LIST_NULL;
-		mvi	INTSTAT,CMDCMPLT;
-
-		test	ARG_1, MSG_IDENTIFY_DISCFLAG jnz target_busfree;
-
-		/* Busy loop on something then go to data or status phase */
-
-target_busfree:
-		clr	SCSISIGO;
-		jmp	poll_for_work;
-
-	}
-
 /*
  * Reselection has been initiated by a target. Make a note that we've been
  * reselected, but haven't seen an IDENTIFY message from the target yet.
@@ -453,14 +337,14 @@
  * STCNT may have been cleared, so restore it from the residual field.
  */
 data_phase_reinit:
-	if ((p->features & AHC_CMD_CHAN) != 0) {
-		if ((p->features & AHC_ULTRA2) != 0) {
-			bmov	HADDR, SHADDR, 4;
-			bmov    HCNT, SCB_RESID_DCNT, 3;
-		} else {
-			bmov    STCNT, SCB_RESID_DCNT, 3;
-		}
-	} else {
+	if ((p->features & AHC_ULTRA2) != 0) {
+		bmov	HADDR, SHADDR, 4;
+		bmov    HCNT, SCB_RESID_DCNT, 3;
+	}
+	if ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895) {
+		bmov    STCNT, SCB_RESID_DCNT, 3;
+	}
+	if ((p->features & AHC_CMD_CHAN) == 0) {
 		mvi	DINDEX, STCNT;
 		mvi	SCB_RESID_DCNT	call bcopy_3;
 	}
@@ -687,10 +571,13 @@
 		test	DFSTATUS, FIFOEMP jz ultra2_dmafifoflush;
 		test	DFSTATUS, MREQPEND	jnz .;
 ultra2_dmahalt:
-		and     DFCNTRL, ~HDMAEN;
-		test	DFCNTRL, HDMAEN jnz .;
-		and     DFCNTRL, ~SCSIEN;
-		test	DFCNTRL, SCSIEN jnz .;
+		test	SCSIOFFSET, 0x7f	jnz ultra2_shutdown;
+ultra2_await_nreq:
+		test	SCSISIGI, REQI	jz ultra2_shutdown;
+		test	SSTAT1, (PHASEMIS|REQINIT)	jz ultra2_await_nreq;
+ultra2_shutdown:
+		and     DFCNTRL, ~(HDMAEN|SCSIEN);
+		test	DFCNTRL, (HDMAEN|SCSIEN) jnz .;
 		bmov	SCB_RESID_DCNT, STCNT, 3;
 		mov	SCB_RESID_SGCNT, SG_COUNT;
 		or	SXFRCTL0, CLRSTCNT|CLRCHN;
@@ -729,10 +616,11 @@
 		test	SSTAT0, SDONE jnz p_command_ultra2_dma_done;
 		test	SSTAT1,PHASEMIS	jz p_command_dma_loop;	/* ie. underrun */
 p_command_ultra2_dma_done:
-		and     DFCNTRL, ~HDMAEN;
-		test	DFCNTRL, HDMAEN jnz .;
-		and	DFCNTRL, ~SCSIEN;
-		test	DFCNTRL, SCSIEN jnz .;
+		test	SCSISIGI, REQI	jz p_command_ultra2_shutdown;
+		test	SSTAT1, (PHASEMIS|REQINIT)	jz p_command_ultra2_dma_done;
+p_command_ultra2_shutdown:
+		and     DFCNTRL, ~(HDMAEN|SCSIEN);
+		test	DFCNTRL, (HDMAEN|SCSIEN) jnz .;
 		or	SXFRCTL0, CLRSTCNT|CLRCHN;
 	}
 	jmp	ITloop;
@@ -1079,22 +967,12 @@
 	mvi	ARG_1	call inb_next; /* ACK the wide_residue and get */
 				       /* the size byte */
 /*
- * See if we'll ignore this wide residue (because it's an overrun byte)
- */
-	test	SCB_RESID_SGCNT,0xff jnz wide_residue_int;
-	test	SCB_RESID_DCNT[0],0xff jnz wide_residue_int;
-	test	SCB_RESID_DCNT[1],0xff jnz wide_residue_int;
-	test	SCB_RESID_DCNT[2],0xff jnz wide_residue_int;
-	jmp	mesgin_done;
-
-wide_residue_int:
-/*
  * In order for this to be reliable, we have to do all sorts of horrible
  * magic in terms of resetting the datafifo and reloading the shadow layer
  * with the correct new values (so that a subsequent save data pointers
  * message will do the right thing).  We let the kernel do that work.
  */
- 	mvi	INTSTAT,WIDE_RESIDUE;
+ 	mvi	INTSTAT, WIDE_RESIDUE;
 	jmp	mesgin_done;
 	
 /*
@@ -1143,17 +1021,6 @@
 inb_last:
 	mov	NONE,SCSIDATL ret;		/*dummy read from latch to ACK*/
 
-if ((p->flags & AHC_TARGETMODE) != 0) {
-	/*
-	 * Send a byte to an initiator in Automatic PIO mode.
-	 * SPIOEN must be on prior to calling this routine.
-	 */
-target_outb:
-	mov	SCSIDATL, SINDEX;
-	test	SSTAT0, SPIORDY	jz .;
-	ret;
-}
-	
 mesgin_phasemis:
 /*
  * We expected to receive another byte, but the target changed phase
@@ -1198,6 +1065,12 @@
  * actually off first lest we get an ILLSADDR.
  */
 dma_dmadone:
+	cmp	LASTPHASE, P_COMMAND	je dma_await_nreq;
+	test	SCSIRATE, 0x0f	jnz dma_shutdown;
+dma_await_nreq:
+	test	SCSISIGI, REQI	jz dma_shutdown;
+	test	SSTAT1, (PHASEMIS|REQINIT)	jz dma_await_nreq;
+dma_shutdown:
 	and	DFCNTRL, ~(SCSIEN|SDMAEN|HDMAEN);
 dma_halt:
 	/*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/aic7xxx.c linux.17p18/drivers/scsi/aic7xxx.c
--- linux.vanilla/drivers/scsi/aic7xxx.c	Fri Apr 21 12:46:27 2000
+++ linux.17p18/drivers/scsi/aic7xxx.c	Tue Aug  1 07:59:55 2000
@@ -270,7 +270,7 @@
     0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
 };
 
-#define AIC7XXX_C_VERSION  "5.1.28"
+#define AIC7XXX_C_VERSION  "5.1.31"
 
 #define NUMBER(arr)     (sizeof(arr) / sizeof(arr[0]))
 #define MIN(a,b)        (((a) < (b)) ? (a) : (b))
@@ -576,7 +576,7 @@
  * AIC-7770 I/O range to reserve for a card
  */
 #define MINREG                0xC00
-#define MAXREG                0xCBF
+#define MAXREG                0xCFF
 
 #define INTDEF                0x5C      /* Interrupt Definition Register */
 
@@ -1491,10 +1491,10 @@
   {
     outb(val, p->base + port);
     mb(); /* locked operation in order to force ordering */
-    inb(p->base + HCNTRL); /* dummy read to flush the write */
   }
 #else
   outb(val, p->base + port);
+  mb(); /* locked operation in order to force ordering */
 #endif
 }
 
@@ -1664,6 +1664,10 @@
   {
     ;
   }
+  if(p->features & AHC_ULTRA2)
+  {
+    aic_inb(p, CCSCBCTL);
+  }
 }
 
 /*+F*************************************************************************
@@ -2133,7 +2137,7 @@
      * Use async transfers for this target
      */
     *options = 0;
-    *period = 0;
+    *period = 255;
     syncrate = NULL;
   }
   return (syncrate);
@@ -2901,6 +2905,7 @@
 #define WIDE_INQUIRY_BITS 0x60
 #define SYNC_INQUIRY_BITS 0x10
 #define SCSI_VERSION_BITS 0x07
+#define SCSI_DT_BIT       0x04
       if ( (buffer[7] & WIDE_INQUIRY_BITS) &&
            (p->features & AHC_WIDE) )
       {
@@ -2919,61 +2924,66 @@
                                                    AHC_TRANS_CUR) );
         unpause_sequencer(p, FALSE);
       }
-      if (buffer[7] & SYNC_INQUIRY_BITS)
+      if ( (buffer[7] & SYNC_INQUIRY_BITS) &&
+            p->transinfo[tindex].user_offset )
       {
-        p->needsdtr |= (1<<tindex);
-        p->needsdtr_copy |= (1<<tindex);
-
         p->transinfo[tindex].goal_period = p->transinfo[tindex].user_period;
         p->transinfo[tindex].goal_options = p->transinfo[tindex].user_options;
-        if (p->transinfo[tindex].user_offset)
+        if (p->features & AHC_ULTRA2)
+          p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
+        else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT)
+          p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
+        else
+          p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+        if ( (((buffer[2] & SCSI_VERSION_BITS) == 3) ||
+               (buffer[56] & SCSI_DT_BIT) ||
+	       (p->dev_flags[tindex] & DEVICE_SCSI_3) ) &&
+               (p->transinfo[tindex].user_period <= 9) &&
+               (p->transinfo[tindex].user_options) )
         {
-          if (p->features & AHC_ULTRA2)
-            p->transinfo[tindex].goal_offset = MAX_OFFSET_ULTRA2;
-          else if (p->transinfo[tindex].goal_width == MSG_EXT_WDTR_BUS_16_BIT)
-            p->transinfo[tindex].goal_offset = MAX_OFFSET_16BIT;
-          else
-            p->transinfo[tindex].goal_offset = MAX_OFFSET_8BIT;
+          p->needppr |= (1<<tindex);
+          p->needppr_copy |= (1<<tindex);
+          p->needsdtr &= ~(1<<tindex);
+          p->needsdtr_copy &= ~(1<<tindex);
+          p->needwdtr &= ~(1<<tindex);
+          p->needwdtr_copy &= ~(1<<tindex);
+          p->dev_flags[tindex] |= DEVICE_SCSI_3;
+        }
+        else
+        {
+          p->needsdtr |= (1<<tindex);
+          p->needsdtr_copy |= (1<<tindex);
+          p->transinfo[tindex].goal_period = 
+            MAX(10, p->transinfo[tindex].goal_period);
+          p->transinfo[tindex].goal_options = 0;
         }
       }
       else
       {
         p->needsdtr &= ~(1<<tindex);
         p->needsdtr_copy &= ~(1<<tindex);
-        p->transinfo[tindex].goal_period = 0;
+        p->transinfo[tindex].goal_period = 255;
         p->transinfo[tindex].goal_offset = 0;
         p->transinfo[tindex].goal_options = 0;
       }
-      if ( (buffer[2] & SCSI_VERSION_BITS) == 3 )
+      /*
+       * This is needed to work around a sequencer bug for now.  Regardless
+       * of the controller in use, if we have a Quantum drive, we need to
+       * limit the speed to 80MByte/sec.  As soon as I get a fixed version
+       * of the sequencer, this code will get yanked.
+       */
+      if(!strncmp(buffer + 8, "QUANTUM", 7) &&
+         p->transinfo[tindex].goal_options )
       {
-        p->dev_flags[tindex] |= DEVICE_SCSI_3;
-        /*
-         * OK, we are a SCSI 3 device and we are in need of negotiation.
-         * Use PPR messages instead of WDTR and SDTR messages.
-         */
-        if ( (p->needsdtr & (1<<tindex)) ||
-             (p->needwdtr & (1<<tindex)) )
-        {
-          p->needppr |= (1<<tindex);
-          p->needppr_copy |= (1<<tindex);
-        }
-        p->needwdtr &= ~(1<<tindex);
-        p->needwdtr_copy &= ~(1<<tindex);
-        p->needsdtr &= ~(1<<tindex);
-        p->needsdtr_copy &= ~(1<<tindex);
-        /*
-         * This is needed to work around a sequencer bug for now.  Regardless
-         * of the controller in use, if we have a Quantum drive, we need to
-         * limit the speed to 80MByte/sec.  As soon as I get a fixed version
-         * of the sequencer, this code will get yanked.
-         */
-        if(!strncmp(buffer + 8, "QUANTUM", 7) &&
-           p->transinfo[tindex].goal_options )
-        {
-          p->transinfo[tindex].goal_period = 
-            MAX(p->transinfo[tindex].goal_period, 10);
-          p->transinfo[tindex].goal_options = 0;
-        }
+        p->transinfo[tindex].goal_period = 
+          MAX(p->transinfo[tindex].goal_period, 10);
+        p->transinfo[tindex].goal_options = 0;
+        p->needppr &= ~(1<<tindex);
+        p->needppr_copy &= ~(1<<tindex);
+        p->needsdtr |= (1<<tindex);
+        p->needsdtr_copy |= (1<<tindex);
+        p->needwdtr |= (1<<tindex);
+        p->needwdtr_copy |= (1<<tindex);
       }
       /*
        * Get the INQUIRY checksum.  We use this on Ultra 160/m
@@ -3003,6 +3013,7 @@
 #undef WIDE_INQUIRY_BITS
 #undef SYNC_INQUIRY_BITS
 #undef SCSI_VERSION_BITS
+#undef SCSI_DT_BIT
     }
   }
   else if ((scb->flags & SCB_MSGOUT_BITS) != 0)
@@ -4639,7 +4650,9 @@
            * As per the draft specs, any device capable of supporting any of
            * the option values other than 0 are not allowed to reject the
            * PPR message.  Instead, they must negotiate out what they do
-           * support instead of rejecting our offering.
+           * support instead of rejecting our offering or else they cause
+           * a parity error during msg_out phase to signal that they don't
+           * like our settings.
            */
           p->needppr &= ~target_mask;
           p->needppr_copy &= ~target_mask;
@@ -4817,51 +4830,6 @@
                 scb->sg_count = hscb->SG_segment_count = 1;
                 scb->sg_length = sizeof(cmd->sense_buffer);
                 scb->tag_action = 0;
-                /*
-                 * This problem could be caused if the target has lost power
-                 * or found some other way to loose the negotiation settings,
-                 * so if needed, we'll re-negotiate while doing the sense cmd.
-                 * However, if this SCB already was attempting to negotiate,
-                 * then we assume this isn't the problem and skip this part.
-                 */
-                if ( (scb->cmd->cmnd[0] != TEST_UNIT_READY) &&
-                     (p->dev_flags[tindex] & DEVICE_SCANNED) &&
-                     !(p->dtr_pending & target_mask) ) 
-                {
-                  p->needppr |= (p->needppr_copy & target_mask);
-                  p->needwdtr |= (p->needwdtr_copy & target_mask);
-                  p->needsdtr |= (p->needsdtr_copy & target_mask);
-                }
-                else if ( scb->cmd == p->dev_dtr_cmnd[tindex] )
-                {
-                  /*
-                   * This is already a negotiation command, so we must have
-                   * already done PPR, WDTR or SDTR.  Since our negotiation
-                   * could have gotten rejected, we don't really know the
-                   * full state of things.  Don't do anything here, and allow
-                   * the negotiation_complete() handler to do the right
-                   * thing.
-                   */
-
-                  /*
-                   * This is the important part though.  We are getting sense
-                   * info back from this device.  It's going into a fake
-                   * command.  We need to put that into the real command
-                   * instead so that the mid level SCSI code can act upon it.
-                   * So, when we set up these fake commands, the next pointer
-                   * is used to point to the real command.  Use that to change
-                   * the address of our sense_buffer[] to the real command.
-                   * However, don't do this if the real command is also a
-                   * TEST_UNIT_READY as it will most likely pull down its own
-                   * SENSE information anyway.
-                   */
-                  if (cmd->next->cmnd[0] != TEST_UNIT_READY)
-                  {
-                    scb->sg_list[0].address = 
-                      cpu_to_le32(VIRT_TO_BUS(&cmd->next->sense_buffer[0]));
-                    hscb->data_pointer = scb->sg_list[0].address;
-                  }
-                }
                 scb->flags |= SCB_SENSE;
                 /*
                  * Ensure the target is busy since this will be an
@@ -4884,7 +4852,7 @@
                 aic7xxx_error(cmd) = DID_OK;
                 break;
               }  /* first time sense, no errors */
-              aic7xxx_error(cmd) = DID_OK;
+              aic7xxx_error(cmd) = DID_ERROR;
               scb->flags &= ~SCB_SENSE;
               break;
 
@@ -5135,51 +5103,14 @@
         }
         else if (scb->flags & SCB_MSGOUT_PPR)
         {
-          unsigned int max_sync, period;
-          unsigned char options = 0;
-
-          if (p->features & AHC_ULTRA2)
-          {
-            if ( (aic_inb(p, SBLKCTL) & ENAB40) &&
-                !(aic_inb(p, SSTAT2) & EXP_ACTIVE) )
-            {
-              if( (p->features & AHC_ULTRA3) &&
-                  (p->dev_flags[tindex] & DEVICE_SCSI_3) &&
-                  (p->transinfo[tindex].goal_width ==
-                   MSG_EXT_WDTR_BUS_16_BIT) &&
-                  (p->transinfo[tindex].goal_options != 0) )
-              {
-                max_sync = AHC_SYNCRATE_ULTRA3;
-                options = p->transinfo[tindex].goal_options;
-              }
-              else
-              {
-                max_sync = AHC_SYNCRATE_ULTRA2;
-              }
-            }
-            else
-            {
-              max_sync = AHC_SYNCRATE_ULTRA;
-            }
-          }
-          else if (p->features & AHC_ULTRA)
-          {
-            max_sync = AHC_SYNCRATE_ULTRA;
-          }
-          else
-          {
-            max_sync = AHC_SYNCRATE_FAST;
-          }
-          period = p->transinfo[tindex].goal_period;
-          aic7xxx_find_syncrate(p, &period, max_sync, &options);
-          p->transinfo[tindex].goal_period = period;
-          p->transinfo[tindex].goal_options = options;
           if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
           {
             printk(INFO_LEAD "Sending PPR (%d/%d/%d/%d) message.\n",
-                   p->host_no, CTL_OF_SCB(scb), period,
+                   p->host_no, CTL_OF_SCB(scb),
+                   p->transinfo[tindex].goal_period,
                    p->transinfo[tindex].goal_offset,
-                   p->transinfo[tindex].goal_width, options);
+                   p->transinfo[tindex].goal_width,
+                   p->transinfo[tindex].goal_options);
           }
           aic7xxx_construct_ppr(p, scb);
         }
@@ -5225,8 +5156,7 @@
           if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
           {
             printk(INFO_LEAD "Sending SDTR %d/%d message.\n", p->host_no,
-                   CTL_OF_SCB(scb),
-                   p->transinfo[tindex].goal_period,
+                   CTL_OF_SCB(scb), period,
                    p->transinfo[tindex].goal_offset);
           }
           aic7xxx_construct_sdtr(p, period,
@@ -5339,7 +5269,7 @@
         resid_sgcnt = aic_inb(p, SCB_RESID_SGCNT);
         resid_dcnt = aic_inb(p, SCB_RESID_DCNT) |
           (aic_inb(p, SCB_RESID_DCNT + 1) << 8) |
-          (aic_inb(p, SCB_RESID_DCNT + 2) << 24);
+          (aic_inb(p, SCB_RESID_DCNT + 2) << 16);
         index = scb->sg_count - (resid_sgcnt + 1);
         native_addr = le32_to_cpu(scb->sg_list[index].address);
         native_length = le32_to_cpu(scb->sg_list[index].length);
@@ -5347,7 +5277,7 @@
          * Make sure this is a valid sg_seg for the given pointer
          */
         if(cur_addr < native_addr ||
-           cur_addr > (native_addr + native_length))
+           cur_addr > (native_addr + native_length + 1))
         {
           printk(WARN_LEAD "invalid cur_addr:0x%x during WIDE_RESIDUE\n",
                  p->host_no, CTL_OF_SCB(scb), cur_addr);
@@ -5364,16 +5294,31 @@
                    p->host_no, CTL_OF_SCB(scb),
                    le32_to_cpu(scb->sg_list[index + 1].address),
                    le32_to_cpu(scb->sg_list[index + 1].length));
+          printk(WARN_LEAD "  cur_address:0x%x resid_dcnt:0x%06x\n",
+                 p->host_no, CTL_OF_SCB(scb),
+                 cur_addr, resid_dcnt);
           break;
         }
 
-        /*
-         * If our current address matches the sg_seg->address then we
-         * have to back up the sg array to the previous segment and set
-         * it up to have only one byte of transfer left to go.
-         */
-        if(cur_addr == native_addr)
+        if( (resid_sgcnt == 0) &&
+            ((resid_dcnt == 0) || (resid_dcnt == 0xffffff)))
         {
+          /*
+           * We are at the end of the transfer and this is about a byte
+           * we ignored already (because the sequencer knew this was
+           * the last segment and set the adapter to ignore any wide
+           * residue bytes that might come through, which is only done
+           * on the last scatter gather segment of transfers).
+           */
+          break;
+        }
+        else if(cur_addr == native_addr)
+        {
+          /*
+           * If our current address matches the sg_seg->address then we
+           * have to back up the sg array to the previous segment and set
+           * it up to have only one byte of transfer left to go.
+           */
           if(index == 0)
           {
             printk(WARN_LEAD "bogus WIDE_RESIDUE message, no data has been "
@@ -5403,39 +5348,6 @@
           aic_outb(p, (cur_addr >> 8) & 0xff, HADDR + 1);
           aic_outb(p, (cur_addr >> 16) & 0xff, HADDR + 2);
           aic_outb(p, (cur_addr >> 24) & 0xff, HADDR + 3);
-          /*
-           * The sequencer actually wants to find the new address and byte
-           * count in the SHCNT and SHADDR register sets.  These registers
-           * are a shadow of the regular HCNT and HADDR registers.  On the
-           * Ultra2 controllers, these registers are read only and the way
-           * we have to set their values is to put the values we want into
-           * the HCNT and HADDR registers and then output PRELOADEN into
-           * the DFCNTRL register which causes the card to latch the current
-           * values in the HADDR and HCNT registers and drop it through to
-           * the shadow registers.  On older cards we copy them directly
-           * across by hand.
-           */
-          if(p->features & AHC_ULTRA2)
-          {
-            aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
-            i=0;
-            udelay(1);
-            while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000))
-            {
-              aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
-              udelay(1);
-            }
-          }
-          else
-          {
-            aic_outb(p, 1, STCNT); 
-            aic_outb(p, 0, STCNT + 1); 
-            aic_outb(p, 0, STCNT + 2); 
-            aic_outb(p, cur_addr & 0xff, SHADDR);
-            aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1);
-            aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2);
-            aic_outb(p, (cur_addr >> 24) & 0xff, SHADDR + 3);
-          }
         }
         else
         {
@@ -5455,28 +5367,46 @@
           aic_outb(p, (cur_addr >> 8) & 0xff, HADDR + 1);
           aic_outb(p, (cur_addr >> 16) & 0xff, HADDR + 2);
           aic_outb(p, (cur_addr >> 24) & 0xff, HADDR + 3);
-          if(p->features & AHC_ULTRA2)
+        }
+        /*
+         * The sequencer actually wants to find the new address and byte
+         * count in the SHCNT and SHADDR register sets.  These registers
+         * are a shadow of the regular HCNT and HADDR registers.  On the
+         * Ultra2 controllers, these registers are read only and the way
+         * we have to set their values is to put the values we want into
+         * the HCNT and HADDR registers and then output PRELOADEN into
+         * the DFCNTRL register which causes the card to latch the current
+         * values in the HADDR and HCNT registers and drop it through to
+         * the shadow registers.  On older cards we copy them directly
+         * across by hand.
+         */
+        if(p->features & AHC_ULTRA2)
+        {
+          aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
+          i=0;
+          udelay(1);
+          while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000))
           {
-            aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
-            i=0;
             udelay(1);
-            while(((aic_inb(p, SSTAT0) & SDONE) != 0) && (i++ < 1000))
-            {
-              aic_outb(p, aic_inb(p, DMAPARAMS), DFCNTRL);
-              udelay(1);
-            }
           }
-          else
+          aic_outb(p, aic_inb(p, DMAPARAMS) & ~(SCSIEN|HDMAEN), DFCNTRL);
+          i=0;
+          udelay(1);
+          while(((aic_inb(p, DFCNTRL) & (SCSIEN|HDMAEN)) != 0) && (i++ < 1000))
           {
-            aic_outb(p, resid_dcnt & 0xff, STCNT); 
-            aic_outb(p, (resid_dcnt >> 8) & 0xff, STCNT + 1); 
-            aic_outb(p, (resid_dcnt >> 16) & 0xff, STCNT + 2); 
-            aic_outb(p, cur_addr & 0xff, SHADDR);
-            aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1);
-            aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2);
-            aic_outb(p, (cur_addr >> 24) & 0xff, SHADDR + 3);
+            udelay(1);
           }
         }
+        else
+        {
+          aic_outb(p, resid_dcnt & 0xff, STCNT); 
+          aic_outb(p, (resid_dcnt >> 8) & 0xff, STCNT + 1); 
+          aic_outb(p, (resid_dcnt >> 16) & 0xff, STCNT + 2); 
+          aic_outb(p, cur_addr & 0xff, SHADDR);
+          aic_outb(p, (cur_addr >> 8) & 0xff, SHADDR + 1);
+          aic_outb(p, (cur_addr >> 16) & 0xff, SHADDR + 2);
+          aic_outb(p, (cur_addr >> 24) & 0xff, SHADDR + 3);
+        }
       }
       break;
 
@@ -5885,6 +5815,7 @@
           reply = TRUE;
           scb->flags &= ~SCB_MSGOUT_BITS;
           scb->flags |= SCB_MSGOUT_PPR;
+	  p->dev_flags[tindex] |= DEVICE_SCSI_3;
           if (!(p->dev_flags[tindex] & DEVICE_SCANNED))
           {
             /*
@@ -5918,7 +5849,6 @@
               p->transinfo[tindex].user_width;
             p->transinfo[tindex].goal_options =
               p->transinfo[tindex].user_options;
-            p->needppr_copy |= target_mask;
           }
           if (aic7xxx_verbose & VERBOSE_NEGOTIATION2)
           {
@@ -5952,6 +5882,25 @@
               break;
             }
           }
+          if ( (p->transinfo[tindex].goal_period > 9) ||
+               (p->transinfo[tindex].goal_options == 0) )
+          {
+            scb->flags &= ~SCB_MSGOUT_BITS;
+            reject = TRUE;
+            reply = FALSE;
+            p->needppr &= ~(1 << tindex);
+            p->needppr_copy &= ~(1 << tindex);
+            if ( p->transinfo[tindex].goal_offset )
+            {
+              p->needsdtr |= (1 << tindex);
+              p->needsdtr_copy |= (1 << tindex);
+            }
+            if ( p->transinfo[tindex].goal_width )
+            {
+              p->needwdtr |= (1 << tindex);
+              p->needwdtr_copy |= (1 << tindex);
+            }
+          }
         }
         else
         {
@@ -5959,7 +5908,7 @@
           {
             default:
             {
-              reply = TRUE;
+              reject = TRUE;
               if ( (aic7xxx_verbose & VERBOSE_NEGOTIATION2) &&
                    ((p->dev_flags[tindex] & DEVICE_PRINT_DTR) ||
                     (aic7xxx_verbose > 0xffff)) )
@@ -5985,27 +5934,18 @@
           }
         }
 
-        aic7xxx_set_width(p, target, channel, lun, bus_width,
-                          AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
-        syncrate = aic7xxx_find_syncrate(p, &period, maxsync,
-                                         &new_trans_options);
-        aic7xxx_validate_offset(p, syncrate, &offset, bus_width);
-        aic7xxx_set_syncrate(p, syncrate, target, channel, period,
-                             offset, new_trans_options,
-                             AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
-
-        if( (offset != saved_offset) ||
-            (trans_options != new_trans_options) ||
-            ((scb->flags & (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) !=
-             (SCB_MSGOUT_SENT|SCB_MSGOUT_PPR)) )
+        if ( !reject )
         {
           aic7xxx_set_width(p, target, channel, lun, bus_width,
-                            AHC_TRANS_GOAL|AHC_TRANS_QUITE);
+                            AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
+          syncrate = aic7xxx_find_syncrate(p, &period, maxsync,
+                                           &new_trans_options);
+          aic7xxx_validate_offset(p, syncrate, &offset, bus_width);
           aic7xxx_set_syncrate(p, syncrate, target, channel, period,
                                offset, new_trans_options,
-                               AHC_TRANS_GOAL|AHC_TRANS_QUITE);
-          reply = TRUE;
+                               AHC_TRANS_ACTIVE|AHC_TRANS_CUR);
         }
+
         p->dtr_pending &= ~target_mask;
         p->needppr &= ~target_mask;
         if(reply)
@@ -6411,20 +6351,14 @@
     /*
      * Keep the sequencer from trying to restart any selections
      */
-    aic_outb(p, 0, SCSISEQ);
+    aic_outb(p, aic_inb(p, SCSISEQ) & ~ENSELO, SCSISEQ);
     /*
      * Make sure the data bits on the bus are released
+     * Don't do this on 7770 chipsets, it makes them give us
+     * a BRKADDRINT and kills the card.
      */
-    if(p->features & AHC_WIDE)
-      aic_outb(p, 0, SCSIBUSH);
-    aic_outb(p, 0, SCSIBUSL);
-    /*
-     * Clear the target id bit from the SCSI bus
-     */
-    if(p->features & AHC_ULTRA2)
-      aic_outb(p, aic_inb(p, SCSIID_ULTRA2) & 0x0f, SCSIID_ULTRA2);
-    else
-      aic_outb(p, aic_inb(p, SCSIID) & 0x0f, SCSIID);
+    if( (p->chip & ~AHC_CHIPID_MASK) == AHC_PCI )
+      aic_outb(p, 0, SCSIBUSL);
 
     /*
      * Delay for the selection timeout delay period then stop the selection
@@ -6507,7 +6441,9 @@
      * A parity error has occurred during a data
      * transfer phase. Flag it and continue.
      */
-    if( (aic_inb(p, SCSIRATE) & AHC_SYNCRATE_CRC) && (lastphase == P_DATAIN) )
+    if( (p->features & AHC_ULTRA3) && 
+        (aic_inb(p, SCSIRATE) & AHC_SYNCRATE_CRC) &&
+        (lastphase == P_DATAIN) )
     {
       printk(WARN_LEAD "CRC error during %s phase.\n",
              p->host_no, CTL_OF_SCB(scb), phase);
@@ -6532,13 +6468,50 @@
                p->host_no, CTL_OF_SCB(scb));
       }
     }
-    else
+    else if( (lastphase == P_MESGOUT) &&
+             (cmd == p->dev_dtr_cmnd[tindex]) &&
+             (scb->flags & SCB_MSGOUT_PPR) )
     {
-      printk(WARN_LEAD "Parity error during %s phase.\n",
-             p->host_no, CTL_OF_SCB(scb), phase);
+      /*
+       * As per the draft specs, any device capable of supporting any of
+       * the option values other than 0 are not allowed to reject the
+       * PPR message.  Instead, they must negotiate out what they do
+       * support instead of rejecting our offering or else they cause
+       * a parity error during msg_out phase to signal that they don't
+       * like our settings.
+       */
+      p->needppr &= ~(1 << tindex);
+      p->needppr_copy &= ~(1 << tindex);
+      aic7xxx_set_width(p, scb->cmd->target, scb->cmd->channel, scb->cmd->lun,
+                        MSG_EXT_WDTR_BUS_8_BIT,
+                        (AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE));
+      aic7xxx_set_syncrate(p, NULL, scb->cmd->target, scb->cmd->channel, 0, 0,
+                           0, AHC_TRANS_ACTIVE|AHC_TRANS_CUR|AHC_TRANS_QUITE);
+      p->transinfo[tindex].goal_options = 0;
+      p->dtr_pending &= ~(1 << tindex);
+      scb->flags &= ~SCB_MSGOUT_BITS;
+      if(aic7xxx_verbose & VERBOSE_NEGOTIATION2)
+      {
+        printk(INFO_LEAD "parity error during PPR message, reverting "
+               "to WDTR/SDTR\n", p->host_no, CTL_OF_SCB(scb));
+      }
+      if ( p->transinfo[tindex].goal_width )
+      {
+        p->needwdtr |= (1 << tindex);
+        p->needwdtr_copy |= (1 << tindex);
+      }
+      if ( p->transinfo[tindex].goal_offset )
+      {
+        if( p->transinfo[tindex].goal_period <= 9 )
+        {
+          p->transinfo[tindex].goal_period = 10;
+        }
+        p->needsdtr |= (1 << tindex);
+        p->needsdtr_copy |= (1 << tindex);
+      }
+      scb = NULL;
     }
-
-    if(p->dev_flags[tindex] & DEVICE_PARITY_ERROR)
+    else if(p->dev_flags[tindex] & DEVICE_PARITY_ERROR)
     {
       struct aic7xxx_syncrate *syncrate;
       unsigned int period = p->transinfo[tindex].cur_period;
@@ -6550,6 +6523,8 @@
        * instead of slowing down if those exist.  That's hard to do with simple
        * checksums though.
        */
+      printk(WARN_LEAD "Parity error during %s phase.\n",
+             p->host_no, CTL_OF_SCB(scb), phase);
       if((syncrate = aic7xxx_find_syncrate(p, &period, 0, &options)) != NULL)
       {
         syncrate++;
@@ -6557,20 +6532,59 @@
             (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) )
         {
           p->transinfo[tindex].goal_period = syncrate->period;
-          if( !(syncrate->sxfr_ultra2 & 0x40) )
+          if( p->transinfo[tindex].goal_period > 9 )
           {
             p->transinfo[tindex].goal_options = 0;
+            p->needppr &= ~(1<<tindex);
+            p->needsdtr |= (1<<tindex);
+            p->needppr_copy &= ~(1<<tindex);
+            p->needsdtr_copy |= (1<<tindex);
+            if (p->transinfo[tindex].goal_width)
+            {
+              p->needwdtr |= (1<<tindex);
+              p->needwdtr_copy |= (1<<tindex);
+            }
+          }
+        }
+        else if (p->transinfo[tindex].goal_width)
+        {
+          p->transinfo[tindex].goal_width = 0;
+          p->needwdtr &= ~(1<<tindex);
+          p->needwdtr_copy &= ~(1<<tindex);
+          p->transinfo[tindex].goal_offset =
+            p->transinfo[tindex].user_offset;
+          p->transinfo[tindex].goal_period =
+            p->transinfo[tindex].user_period;
+          p->transinfo[tindex].goal_options =
+            p->transinfo[tindex].user_options;
+          if( p->transinfo[tindex].goal_period <= 9 )
+          {
+            p->needppr |= (1<<tindex);
+            p->needsdtr &= ~(1<<tindex);
+            p->needppr_copy |= (1<<tindex);
+            p->needsdtr_copy &= ~(1<<tindex);
+          }
+          else
+          {
+            p->needppr &= ~(1<<tindex);
+            p->needsdtr |= (1<<tindex);
+            p->needppr_copy &= ~(1<<tindex);
+            p->needsdtr_copy |= (1<<tindex);
           }
         }
         else
         {
           p->transinfo[tindex].goal_offset = 0;
-          p->transinfo[tindex].goal_period = 0;
+          p->transinfo[tindex].goal_period = 255;
           p->transinfo[tindex].goal_options = 0;
+          p->transinfo[tindex].goal_width = 0;
+          p->needppr &= ~(1<<tindex);
+          p->needsdtr &= ~(1<<tindex);
+          p->needwdtr &= ~(1<<tindex);
+          p->needppr_copy &= ~(1<<tindex);
+          p->needsdtr_copy &= ~(1<<tindex);
+          p->needwdtr_copy &= ~(1<<tindex);
         }
-        p->needppr |= (p->needppr_copy & (1<<tindex));
-        p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
-        p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
       }
       p->dev_flags[tindex] &= ~DEVICE_PARITY_ERROR;
     }
@@ -6588,6 +6602,7 @@
     if (mesg_out != MSG_NOOP)
     {
       aic_outb(p, mesg_out, MSG_OUT);
+      aic_outb(p, aic_inb(p, SCSISIGI) | ATNO, SCSISIGO);
       scb = NULL;
     }
     aic_outb(p, CLRSCSIPERR, CLRSINT1);
@@ -6779,7 +6794,7 @@
 {
   struct aic7xxx_scb *scb = NULL;
   Scsi_Cmnd *cmd;
-  unsigned char scb_index;
+  unsigned char scb_index, tindex;
 
 #ifdef AIC7XXX_VERBOSE_DEBUGGING
   if( (p->isr_count < 16) && (aic7xxx_verbose > 0xffff) )
@@ -6805,23 +6820,21 @@
     scb_index = p->qoutfifo[p->qoutfifonext];
     p->qoutfifo[p->qoutfifonext++] = SCB_LIST_NULL;
     if ( scb_index >= p->scb_data->numscbs )
-      scb = NULL;
-    else
-      scb = p->scb_data->scb_array[scb_index];
-    if (scb == NULL)
     {
       printk(WARN_LEAD "CMDCMPLT with invalid SCB index %d\n", p->host_no,
         -1, -1, -1, scb_index);
       continue;
     }
-    else if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
+    scb = p->scb_data->scb_array[scb_index];
+    if (!(scb->flags & SCB_ACTIVE) || (scb->cmd == NULL))
     {
       printk(WARN_LEAD "CMDCMPLT without command for SCB %d, SCB flags "
         "0x%x, cmd 0x%lx\n", p->host_no, -1, -1, -1, scb_index, scb->flags,
         (unsigned long) scb->cmd);
       continue;
     }
-    else if (scb->flags & SCB_QUEUED_ABORT)
+    tindex = TARGET_INDEX(scb->cmd);
+    if (scb->flags & SCB_QUEUED_ABORT)
     {
       pause_sequencer(p);
       if ( ((aic_inb(p, LASTPHASE) & PHASE_MASK) != P_BUSFREE) &&
@@ -6844,6 +6857,43 @@
        */
       scb->flags &= ~(SCB_ABORT|SCB_RESET);
     }
+    else if (scb->flags & SCB_SENSE)
+    {
+      char *buffer = &scb->cmd->sense_buffer[0];
+      if (scb->cmd == p->dev_dtr_cmnd[tindex])
+      {
+        struct aic7xxx_scb *old_scb;
+        /*
+         * We have valid sense data, send it back immediately.
+         */
+        old_scb = p->scb_data->scb_array[scb->cmd->next->tag];
+        *old_scb->cmd->sense_buffer = *scb->cmd->sense_buffer;
+        old_scb->hscb->target_status = scb->hscb->target_status;
+        old_scb->cmd->result = scb->hscb->target_status;
+        old_scb->cmd->result |= (DID_ERROR << 16);
+        aic7xxx_status(old_scb->cmd) = scb->hscb->target_status;
+        scbq_remove(&p->waiting_scbs, old_scb);
+        scbq_remove(&p->delayed_scbs[tindex], old_scb);
+        scb->cmd->next = NULL;
+	aic7xxx_done(p, scb);
+        aic7xxx_done(p, old_scb);
+	continue;
+      } 
+      else if (buffer[12] == 0x47 || buffer[12] == 0x54)
+      {
+        /*
+         * SCSI errors, run domain validation and re-run negotiation
+         */
+        p->needdv |= (1<<tindex);
+        /*
+         * Signal that we need to re-negotiate things, this also gets us our
+         * INQUIRY command to re-checksum off of.
+         */
+        p->needppr |= (p->needppr_copy & (1<<tindex));
+        p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
+        p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
+      }
+    }
     switch (status_byte(scb->hscb->target_status))
     {
       case QUEUE_FULL:
@@ -6973,6 +7023,13 @@
 
   if (intstat & SEQINT)
   {
+    /*
+     * Read the CCSCBCTL register to work around a bug in the Ultra2 cards
+     */
+    if(p->features & AHC_ULTRA2)
+    {
+      aic_inb(p, CCSCBCTL);
+    }
     aic7xxx_handle_seqint(p, intstat);
   }
 
@@ -7055,7 +7112,7 @@
  *   with queue depths for individual devices.  It also allows tagged
  *   queueing to be [en|dis]abled for a specific adapter.
  *-F*************************************************************************/
-static void
+static int
 aic7xxx_device_queue_depth(struct aic7xxx_host *p, Scsi_Device *device)
 {
   int default_depth = 3;
@@ -7065,6 +7122,14 @@
   tindex = device->id | (device->channel << 3);
   target_mask = (1 << tindex);
 
+  if (p->dev_max_queue_depth[tindex] > 1)
+  {
+    /*
+     * We've already scanned this device, leave it alone
+     */
+    return(p->dev_max_queue_depth[tindex]);
+  }
+
   device->queue_depth = default_depth;
   p->dev_temp_queue_depth[tindex] = 1;
   p->dev_max_queue_depth[tindex] = 1;
@@ -7133,6 +7198,7 @@
       }
     }
   }
+  return(p->dev_max_queue_depth[tindex]);
 }
 
 /*+F*************************************************************************
@@ -7160,8 +7226,7 @@
   {
     if (device->host == host)
     {
-      aic7xxx_device_queue_depth(p, device);
-      scbnum += device->queue_depth;
+      scbnum += aic7xxx_device_queue_depth(p, device);
     }
   }
   while (scbnum > p->scb_data->numscbs)
@@ -8371,23 +8436,8 @@
   }
   aic_outb(p, 0, SEQ_FLAGS);
 
-  /*
-   * We are starting to do real work on the card....it's possible we could
-   * generate some spurious interrupts at this point, especially in the
-   * event of a PCI error or some such.  If there are other devices already
-   * registered on the same interrupt as us, this could cause the machine
-   * to lock up.  So, we disable the interrupt this card is on until we
-   * finish our card setup.  We only need to do this for modules, if we are
-   * compiled into the kernel then interrupts are already off during this
-   * part of the code.
-   */
-#ifdef MODULE
-  disable_irq(p->irq);
-#endif
-
   detect_maxscb(p);
 
-
   printk("%d/%d SCBs\n", p->scb_data->maxhscbs, p->scb_data->maxscbs);
   if (aic7xxx_verbose & VERBOSE_PROBE2)
   {
@@ -8616,9 +8666,6 @@
       printk("(scsi%d) Unable to allocate hardware SCB array; "
              "failing detection.\n", p->host_no);
       aic_outb(p, 0, SIMODE1);
-#ifdef MODULE
-      enable_irq(p->irq);
-#endif
       p->irq = 0;
       return(0);
     }
@@ -8796,9 +8843,6 @@
     printk(KERN_WARNING "(scsi%d) Couldn't register IRQ %d, ignoring "
            "controller.\n", p->host_no, p->irq);
     aic_outb(p, 0, SIMODE1);
-#ifdef MODULE
-    enable_irq(p->irq);
-#endif
     p->irq = 0;
     return (0);
   }
@@ -8808,10 +8852,6 @@
       p->host_no, -1, -1 , -1);
   aic7xxx_clear_intstat(p);
 
-#ifdef MODULE
-  enable_irq(p->irq);
-#endif
-
   unpause_sequencer(p, /* unpause_always */ TRUE);
 
   return (found);
@@ -8920,7 +8960,7 @@
     p->orderedtag = 0;
     for (i=0; i<MAX_TARGETS; i++)
     {
-      p->transinfo[i].goal_period = 0;
+      p->transinfo[i].goal_period = 255;
       p->transinfo[i].goal_offset = 0;
       p->transinfo[i].goal_options = 0;
       p->transinfo[i].goal_width = MSG_EXT_WDTR_BUS_8_BIT;
@@ -9709,7 +9749,8 @@
           {
             if ( ((current_p->pci_bus == temp_p->pci_bus) &&
                   (current_p->pci_device_fn == temp_p->pci_device_fn)) ||
-                  (current_p->base == temp_p->base) )
+                 (temp_p->base && (current_p->base == temp_p->base)) ||
+                 (temp_p->mbase && (current_p->mbase == temp_p->mbase)) )
             {
               /* duplicate PCI entry, skip it */
               kfree(temp_p);
@@ -9769,7 +9810,8 @@
           {
             if ( ((current_p->pci_bus == temp_p->pci_bus) &&
                   (current_p->pci_device_fn == temp_p->pci_device_fn)) ||
-                  (current_p->base == temp_p->base) )
+                 (temp_p->base && (current_p->base == temp_p->base)) ||
+                 (temp_p->mbase && (current_p->mbase == temp_p->mbase)) )
             {
               /* duplicate PCI entry, skip it */
               kfree(temp_p);
@@ -9812,7 +9854,7 @@
 #endif /* AIC7XXX_STRICT_PCI_SETUP */
 #endif /* LINUIX_VERSION_CODE > KERNEL_VERSION(2,1,92) */
 
-          if(check_region(temp_p->base, MAXREG - MINREG))
+          if(temp_p->base && check_region(temp_p->base, MAXREG - MINREG))
           {
             printk("aic7xxx: <%s> at PCI %d/%d/%d\n", 
               board_names[aic_pdevs[i].board_name_index],
@@ -9843,7 +9885,7 @@
           }
 
 #ifdef MMAPIO
-          if ( !(temp_p->flags & AHC_MULTI_CHANNEL) ||
+          if ( !(temp_p->base) || !(temp_p->flags & AHC_MULTI_CHANNEL) ||
                ((temp_p->chip != (AHC_AIC7870 | AHC_PCI)) &&
                 (temp_p->chip != (AHC_AIC7880 | AHC_PCI))) )
           {
@@ -9881,6 +9923,18 @@
                 vfree((void *) (((unsigned long) temp_p->maddr) & PAGE_MASK));
 #endif
                 temp_p->maddr = 0;
+                if(temp_p->base == 0)
+                {
+                  printk("aic7xxx: <%s> at PCI %d/%d/%d\n", 
+                    board_names[aic_pdevs[i].board_name_index],
+                    temp_p->pci_bus,
+                    PCI_SLOT(temp_p->pci_device_fn),
+                    PCI_FUNC(temp_p->pci_device_fn));
+                  printk("aic7xxx: Controller disabled by BIOS, ignoring.\n");
+                  kfree(temp_p);
+                  temp_p = NULL;
+                  continue;
+                }
               }
             }
           }
@@ -9889,7 +9943,8 @@
           /*
            * Lock out other contenders for our i/o space.
            */
-          request_region(temp_p->base, MAXREG - MINREG, "aic7xxx");
+          if(temp_p->base)
+            request_region(temp_p->base, MAXREG - MINREG, "aic7xxx");
 
           /*
            * We HAVE to make sure the first pause_sequencer() and all other
@@ -10801,20 +10856,59 @@
               (!(p->features & AHC_ULTRA2) || (syncrate->sxfr_ultra2 == 0)) )
           {
             p->transinfo[tindex].goal_period = syncrate->period;
-            if( !(syncrate->sxfr_ultra2 & 0x40) )
+            if( p->transinfo[tindex].goal_period > 9 )
             {
               p->transinfo[tindex].goal_options = 0;
+              p->needppr &= ~(1<<tindex);
+              p->needsdtr |= (1<<tindex);
+              p->needppr_copy &= ~(1<<tindex);
+              p->needsdtr_copy |= (1<<tindex);
+              if (p->transinfo[tindex].goal_width)
+              {
+                p->needwdtr |= (1<<tindex);
+                p->needwdtr_copy |= (1<<tindex);
+              }
+            }
+          }
+          else if (p->transinfo[tindex].goal_width)
+          {
+            p->transinfo[tindex].goal_width = 0;
+            p->needwdtr &= ~(1<<tindex);
+            p->needwdtr_copy &= ~(1<<tindex);
+            p->transinfo[tindex].goal_offset =
+              p->transinfo[tindex].user_offset;
+            p->transinfo[tindex].goal_period =
+              p->transinfo[tindex].user_period;
+            p->transinfo[tindex].goal_options =
+              p->transinfo[tindex].user_options;
+            if( p->transinfo[tindex].goal_period <= 9 )
+            {
+              p->needppr |= (1<<tindex);
+              p->needsdtr &= ~(1<<tindex);
+              p->needppr_copy |= (1<<tindex);
+              p->needsdtr_copy &= ~(1<<tindex);
+            }
+            else
+            {
+              p->needppr &= ~(1<<tindex);
+              p->needsdtr |= (1<<tindex);
+              p->needppr_copy &= ~(1<<tindex);
+              p->needsdtr_copy |= (1<<tindex);
             }
           }
           else
           {
             p->transinfo[tindex].goal_offset = 0;
-            p->transinfo[tindex].goal_period = 0;
+            p->transinfo[tindex].goal_period = 255;
             p->transinfo[tindex].goal_options = 0;
+            p->transinfo[tindex].goal_width = 0;
+            p->needppr &= ~(1<<tindex);
+            p->needsdtr &= ~(1<<tindex);
+            p->needwdtr &= ~(1<<tindex);
+            p->needppr_copy &= ~(1<<tindex);
+            p->needsdtr_copy &= ~(1<<tindex);
+            p->needwdtr_copy &= ~(1<<tindex);
           }
-          p->needppr |= (p->needppr_copy & (1<<tindex));
-          p->needsdtr |= (p->needsdtr_copy & (1<<tindex));
-          p->needwdtr |= (p->needwdtr_copy & (1<<tindex));
         }
         p->needdv &= ~(1<<tindex);
       }
@@ -10865,8 +10959,16 @@
    * and we didn't follow up with SDTR yet, then this will get it started.
    * For all other cases, this should work out to be a no-op, unless we are
    * doing domain validation and happen to need a new negotiation command.
+   *
+   * In case we don't want this to go any further, the cmdcmplt interrupt
+   * handler will NULL out the cmd->next entry so that the real SCSI command
+   * can be sent back to the mid layer code with SENSE data intact.  We'll
+   * finish things up when the cmd gets sent back down to us, so no worries.
    */
-  aic7xxx_build_negotiation_cmnd(p, cmd->next, tindex);
+  if(cmd->next)
+  {
+    aic7xxx_build_negotiation_cmnd(p, cmd->next, tindex);
+  }
   return;
 }
 
@@ -10988,13 +11090,13 @@
    */
   hscb->control = 0;
   scb->tag_action = 0;
+  cmd->tag = hscb->tag;
   if (p->discenable & mask)
   {
     hscb->control |= DISCENB;
     if ( (p->tagenable & mask) &&
          (cmd->cmnd[0] != TEST_UNIT_READY) )
     {
-      cmd->tag = hscb->tag;
       p->dev_commands_sent[tindex]++;
       if (p->dev_commands_sent[tindex] < 200)
       {
@@ -12275,7 +12377,8 @@
 
   if(p->irq)
     free_irq(p->irq, p);
-  release_region(p->base, MAXREG - MINREG);
+  if(p->base)
+    release_region(p->base, MAXREG - MINREG);
 #ifdef MMAPIO
   if(p->maddr)
   {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/aic7xxx_seq.c linux.17p18/drivers/scsi/aic7xxx_seq.c
--- linux.vanilla/drivers/scsi/aic7xxx_seq.c	Fri Apr 21 12:46:27 2000
+++ linux.17p18/drivers/scsi/aic7xxx_seq.c	Tue Aug  1 07:59:55 2000
@@ -4,34 +4,33 @@
 static unsigned char seqprog[] = {
 	0xff, 0x6a, 0x06, 0x08,
 	0x7f, 0x02, 0x04, 0x08,
-	0x32, 0x6a, 0x00, 0x00,
 	0x12, 0x6a, 0x00, 0x00,
 	0xff, 0x6a, 0xd6, 0x09,
 	0xff, 0x6a, 0xdc, 0x09,
-	0x00, 0x65, 0x44, 0x59,
+	0x00, 0x65, 0xca, 0x58,
 	0xf7, 0x01, 0x02, 0x08,
 	0xff, 0x4e, 0xc8, 0x08,
 	0xbf, 0x60, 0xc0, 0x08,
-	0x60, 0x0b, 0x88, 0x68,
-	0x40, 0x00, 0x0e, 0x68,
+	0x60, 0x0b, 0x86, 0x68,
+	0x40, 0x00, 0x0c, 0x68,
 	0x08, 0x1f, 0x3e, 0x10,
-	0x60, 0x0b, 0x88, 0x68,
-	0x40, 0x00, 0x0e, 0x68,
+	0x60, 0x0b, 0x86, 0x68,
+	0x40, 0x00, 0x0c, 0x68,
 	0x08, 0x1f, 0x3e, 0x10,
-	0xff, 0x3e, 0x4a, 0x60,
-	0x40, 0xfa, 0x12, 0x78,
+	0xff, 0x3e, 0x48, 0x60,
+	0x40, 0xfa, 0x10, 0x78,
 	0xff, 0xf6, 0xd4, 0x08,
 	0x01, 0x4e, 0x9c, 0x18,
 	0x40, 0x60, 0xc0, 0x00,
-	0x00, 0x4d, 0x12, 0x70,
+	0x00, 0x4d, 0x10, 0x70,
 	0x01, 0x4e, 0x9c, 0x18,
 	0xbf, 0x60, 0xc0, 0x08,
-	0x00, 0x6a, 0xbe, 0x5c,
+	0x00, 0x6a, 0x3e, 0x5c,
 	0xff, 0x4e, 0xc8, 0x18,
-	0x02, 0x6a, 0xd4, 0x5b,
+	0x02, 0x6a, 0x54, 0x5b,
 	0xff, 0x52, 0x20, 0x09,
 	0x0d, 0x6a, 0x6a, 0x00,
-	0x00, 0x52, 0x4a, 0x5c,
+	0x00, 0x52, 0xca, 0x5b,
 	0x03, 0xb0, 0x52, 0x31,
 	0xff, 0xb0, 0x52, 0x09,
 	0xff, 0xb1, 0x54, 0x09,
@@ -40,8 +39,8 @@
 	0xff, 0x3e, 0x74, 0x09,
 	0xff, 0x90, 0x7c, 0x08,
 	0xff, 0x3e, 0x20, 0x09,
-	0x00, 0x65, 0x50, 0x58,
-	0x00, 0x65, 0x0e, 0x40,
+	0x00, 0x65, 0x4e, 0x58,
+	0x00, 0x65, 0x0c, 0x40,
 	0xf7, 0x1f, 0xca, 0x08,
 	0x08, 0xa1, 0xc8, 0x08,
 	0x00, 0x65, 0xca, 0x00,
@@ -56,88 +55,28 @@
 	0x5a, 0x6a, 0x00, 0x04,
 	0x12, 0x65, 0x02, 0x00,
 	0x31, 0x6a, 0xca, 0x00,
-	0x80, 0x37, 0x70, 0x68,
+	0x80, 0x37, 0x6e, 0x68,
 	0xff, 0x65, 0xca, 0x18,
 	0xff, 0x37, 0xdc, 0x08,
 	0xff, 0x6e, 0xc8, 0x08,
-	0x00, 0x6c, 0x78, 0x78,
+	0x00, 0x6c, 0x76, 0x78,
 	0x20, 0x01, 0x02, 0x00,
 	0x4c, 0x37, 0xc8, 0x28,
-	0x08, 0x1f, 0x80, 0x78,
+	0x08, 0x1f, 0x7e, 0x78,
 	0x08, 0x37, 0x6e, 0x00,
 	0x08, 0x64, 0xc8, 0x00,
 	0x70, 0x64, 0xca, 0x18,
 	0xff, 0x6c, 0x0a, 0x08,
 	0x20, 0x64, 0xca, 0x18,
 	0xff, 0x6c, 0x08, 0x0c,
-	0x40, 0x0b, 0x10, 0x69,
-	0x80, 0x0b, 0x02, 0x79,
-	0xa4, 0x6a, 0x06, 0x00,
-	0x40, 0x6a, 0x16, 0x00,
-	0x10, 0x03, 0xfe, 0x78,
-	0xff, 0x50, 0xc8, 0x08,
-	0x88, 0x6a, 0xcc, 0x00,
-	0x49, 0x6a, 0x3a, 0x5c,
-	0x01, 0x6a, 0x26, 0x01,
-	0xff, 0x6a, 0xca, 0x08,
-	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0x9e, 0x78,
-	0xf7, 0x01, 0x02, 0x08,
-	0xff, 0x06, 0xcc, 0x08,
-	0xff, 0x66, 0x32, 0x09,
-	0x01, 0x65, 0xca, 0x18,
-	0x80, 0x66, 0xac, 0x78,
-	0xff, 0x66, 0xa2, 0x08,
-	0x10, 0x03, 0x9c, 0x68,
-	0xfc, 0x65, 0xc8, 0x18,
-	0x00, 0x65, 0xb4, 0x48,
-	0xff, 0x6a, 0x32, 0x01,
-	0x01, 0x64, 0x18, 0x19,
-	0xff, 0x6a, 0x1a, 0x09,
-	0xff, 0x6a, 0x1c, 0x09,
-	0x84, 0x6a, 0x06, 0x00,
-	0x08, 0x01, 0x02, 0x00,
-	0x02, 0x0b, 0xbe, 0x78,
-	0xff, 0x06, 0xc8, 0x08,
-	0xff, 0x64, 0x32, 0x09,
-	0xff, 0x6a, 0xca, 0x08,
-	0x5b, 0x64, 0xc8, 0x28,
-	0x00, 0x62, 0xc4, 0x18,
-	0xfc, 0x65, 0xca, 0x18,
-	0xff, 0x6a, 0xd4, 0x08,
-	0xfa, 0x65, 0xca, 0x18,
-	0xff, 0x6a, 0xd4, 0x08,
-	0x04, 0x65, 0xca, 0x18,
-	0x0b, 0x65, 0xca, 0x18,
-	0xff, 0x65, 0xc8, 0x08,
-	0x00, 0x8c, 0x18, 0x19,
-	0x02, 0x0b, 0xda, 0x78,
-	0x01, 0x65, 0xe0, 0x60,
-	0xf7, 0x01, 0x02, 0x08,
-	0xff, 0x06, 0x32, 0x09,
-	0xff, 0x65, 0xca, 0x18,
-	0xff, 0x65, 0xda, 0x68,
-	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xb0, 0x5c,
-	0x40, 0x51, 0xf2, 0x78,
-	0xe4, 0x6a, 0x06, 0x00,
-	0x08, 0x01, 0x02, 0x00,
-	0x04, 0x6a, 0x6c, 0x5b,
-	0x01, 0x50, 0xa0, 0x18,
-	0x00, 0x50, 0xf8, 0xe0,
-	0xff, 0x6a, 0xa0, 0x08,
-	0xff, 0x6a, 0x3a, 0x01,
-	0x02, 0x6a, 0x22, 0x01,
-	0x40, 0x51, 0xfe, 0x68,
-	0xff, 0x6a, 0x06, 0x08,
-	0x00, 0x65, 0x0e, 0x40,
+	0x40, 0x0b, 0x96, 0x68,
 	0x20, 0x6a, 0x16, 0x00,
 	0xf0, 0x19, 0x6e, 0x08,
 	0x08, 0x6a, 0x18, 0x00,
 	0x08, 0x11, 0x22, 0x00,
-	0x08, 0x6a, 0x68, 0x58,
+	0x08, 0x6a, 0x66, 0x58,
 	0x08, 0x6a, 0x68, 0x00,
-	0x00, 0x65, 0x24, 0x41,
+	0x00, 0x65, 0xaa, 0x40,
 	0x12, 0x6a, 0x00, 0x00,
 	0x40, 0x6a, 0x16, 0x00,
 	0xff, 0x3e, 0x20, 0x09,
@@ -145,24 +84,24 @@
 	0xff, 0xa1, 0x6e, 0x08,
 	0x08, 0x6a, 0x18, 0x00,
 	0x08, 0x11, 0x22, 0x00,
-	0x08, 0x6a, 0x68, 0x58,
+	0x08, 0x6a, 0x66, 0x58,
 	0x80, 0x6a, 0x68, 0x00,
 	0x80, 0x36, 0x6c, 0x00,
-	0x00, 0x65, 0x1e, 0x5c,
+	0x00, 0x65, 0x9e, 0x5b,
 	0xff, 0x3d, 0xc8, 0x08,
-	0xbf, 0x64, 0x5c, 0x79,
-	0x80, 0x64, 0x24, 0x72,
-	0xa0, 0x64, 0x54, 0x72,
-	0xc0, 0x64, 0x4c, 0x72,
-	0xe0, 0x64, 0x94, 0x72,
+	0xbf, 0x64, 0xe2, 0x78,
+	0x80, 0x64, 0xac, 0x71,
+	0xa0, 0x64, 0xdc, 0x71,
+	0xc0, 0x64, 0xd4, 0x71,
+	0xe0, 0x64, 0x1c, 0x72,
 	0x01, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0x24, 0x41,
+	0x00, 0x65, 0xaa, 0x40,
 	0xf7, 0x11, 0x22, 0x08,
-	0x00, 0x65, 0x44, 0x59,
+	0x00, 0x65, 0xca, 0x58,
 	0xff, 0x06, 0xd4, 0x08,
 	0xf7, 0x01, 0x02, 0x08,
-	0x09, 0x0c, 0x3e, 0x79,
-	0x08, 0x0c, 0x0e, 0x68,
+	0x09, 0x0c, 0xc4, 0x78,
+	0x08, 0x0c, 0x0c, 0x68,
 	0x01, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0x26, 0x09,
 	0x02, 0x6a, 0x08, 0x30,
@@ -174,25 +113,25 @@
 	0x03, 0xa9, 0x18, 0x31,
 	0x03, 0xa9, 0x10, 0x30,
 	0x08, 0x6a, 0xcc, 0x00,
-	0xa9, 0x6a, 0x34, 0x5c,
-	0x00, 0x65, 0x7c, 0x41,
+	0xa9, 0x6a, 0xb4, 0x5b,
+	0x00, 0x65, 0x02, 0x41,
 	0xa8, 0x6a, 0x6a, 0x00,
 	0x79, 0x6a, 0x6a, 0x00,
-	0x40, 0x3d, 0x64, 0x69,
+	0x40, 0x3d, 0xea, 0x68,
 	0x04, 0x35, 0x6a, 0x00,
-	0x00, 0x65, 0x8e, 0x5b,
+	0x00, 0x65, 0x0e, 0x5b,
 	0x80, 0x6a, 0xd4, 0x01,
-	0x10, 0x36, 0x50, 0x69,
+	0x10, 0x36, 0xd6, 0x68,
 	0x10, 0x36, 0x6c, 0x00,
 	0x07, 0xac, 0x10, 0x31,
 	0x03, 0x8c, 0x10, 0x30,
 	0x05, 0xa3, 0x70, 0x30,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xac, 0x6a, 0x2c, 0x5c,
-	0x00, 0x65, 0x26, 0x5c,
+	0xac, 0x6a, 0xac, 0x5b,
+	0x00, 0x65, 0xa6, 0x5b,
 	0x38, 0x6a, 0xcc, 0x00,
-	0xa3, 0x6a, 0x30, 0x5c,
-	0xff, 0x38, 0x8c, 0x69,
+	0xa3, 0x6a, 0xb0, 0x5b,
+	0xff, 0x38, 0x12, 0x69,
 	0x80, 0x02, 0x04, 0x00,
 	0xe7, 0x35, 0x6a, 0x08,
 	0x03, 0x69, 0x18, 0x31,
@@ -200,337 +139,334 @@
 	0xff, 0x6a, 0x10, 0x00,
 	0xff, 0x6a, 0x12, 0x00,
 	0xff, 0x6a, 0x14, 0x00,
-	0x01, 0x38, 0x92, 0x61,
+	0x01, 0x38, 0x18, 0x61,
 	0xbf, 0x35, 0x6a, 0x08,
 	0x02, 0x6a, 0xf8, 0x01,
 	0xff, 0x69, 0xca, 0x08,
 	0xff, 0x35, 0x26, 0x09,
-	0x04, 0x0b, 0x96, 0x69,
-	0x04, 0x0b, 0xa2, 0x69,
-	0x10, 0x0c, 0x98, 0x79,
-	0x04, 0x0b, 0xa2, 0x69,
+	0x04, 0x0b, 0x1c, 0x69,
+	0x04, 0x0b, 0x28, 0x69,
+	0x10, 0x0c, 0x1e, 0x79,
+	0x04, 0x0b, 0x28, 0x69,
 	0xff, 0x6a, 0xca, 0x08,
-	0x00, 0x35, 0x76, 0x5b,
-	0x80, 0x02, 0xf6, 0x69,
-	0xff, 0x65, 0xe6, 0x79,
+	0x00, 0x35, 0xee, 0x5a,
+	0x80, 0x02, 0x7c, 0x69,
+	0xff, 0x65, 0x6c, 0x79,
 	0xff, 0x38, 0x70, 0x18,
-	0xff, 0x38, 0xe6, 0x79,
-	0x80, 0xea, 0xc2, 0x61,
+	0xff, 0x38, 0x6c, 0x79,
+	0x80, 0xea, 0x48, 0x61,
 	0xef, 0x38, 0xc8, 0x18,
 	0x80, 0x6a, 0xc8, 0x00,
-	0x00, 0x65, 0xb4, 0x49,
+	0x00, 0x65, 0x3a, 0x49,
 	0x33, 0x38, 0xc8, 0x28,
 	0xff, 0x64, 0xd0, 0x09,
 	0x04, 0x39, 0xc0, 0x31,
 	0x09, 0x6a, 0xd6, 0x01,
-	0x80, 0xeb, 0xba, 0x79,
+	0x80, 0xeb, 0x40, 0x79,
 	0xf7, 0xeb, 0xd6, 0x09,
-	0x08, 0xeb, 0xbe, 0x69,
+	0x08, 0xeb, 0x44, 0x69,
 	0x01, 0x6a, 0xd6, 0x01,
 	0x08, 0xe9, 0x10, 0x31,
 	0x03, 0x8c, 0x10, 0x30,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x39, 0x6a, 0x32, 0x5c,
+	0x39, 0x6a, 0xb2, 0x5b,
 	0x08, 0x6a, 0x18, 0x01,
 	0xff, 0x6a, 0x1a, 0x09,
 	0xff, 0x6a, 0x1c, 0x09,
 	0x0d, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xb0, 0x5c,
-	0x88, 0x6a, 0xa0, 0x5c,
-	0x00, 0x65, 0x26, 0x5c,
+	0x00, 0x65, 0x30, 0x5c,
+	0x88, 0x6a, 0x20, 0x5c,
+	0x00, 0x65, 0xa6, 0x5b,
 	0xff, 0x6a, 0xc8, 0x08,
 	0x08, 0x39, 0x72, 0x18,
 	0x00, 0x3a, 0x74, 0x20,
-	0x01, 0x0c, 0xde, 0x79,
-	0x10, 0x0c, 0x7c, 0x79,
+	0x01, 0x0c, 0x64, 0x79,
+	0x10, 0x0c, 0x02, 0x79,
 	0xff, 0x35, 0x26, 0x09,
-	0x04, 0x0b, 0xe4, 0x69,
-	0x00, 0x65, 0xfe, 0x59,
+	0x04, 0x0b, 0x6a, 0x69,
+	0x00, 0x65, 0x84, 0x59,
 	0x03, 0x08, 0x52, 0x31,
 	0xff, 0x38, 0x50, 0x09,
 	0xff, 0x08, 0x52, 0x09,
 	0xff, 0x09, 0x54, 0x09,
 	0xff, 0x0a, 0x56, 0x09,
 	0xff, 0x38, 0x50, 0x09,
-	0x00, 0x65, 0x24, 0x41,
-	0x00, 0x65, 0xfe, 0x59,
+	0x00, 0x65, 0xaa, 0x40,
+	0x00, 0x65, 0x84, 0x59,
 	0x7f, 0x02, 0x04, 0x08,
 	0xe1, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0x24, 0x41,
-	0x04, 0x93, 0x14, 0x6a,
+	0x00, 0x65, 0xaa, 0x40,
+	0x04, 0x93, 0x9a, 0x69,
 	0xdf, 0x93, 0x26, 0x09,
-	0x20, 0x93, 0x02, 0x6a,
+	0x20, 0x93, 0x88, 0x69,
 	0x02, 0x93, 0x26, 0x01,
-	0x01, 0x94, 0x04, 0x7a,
-	0x01, 0x94, 0x04, 0x7a,
-	0x01, 0x94, 0x04, 0x7a,
-	0x01, 0x94, 0x04, 0x7a,
-	0x01, 0x94, 0x04, 0x7a,
-	0x01, 0x94, 0x04, 0x7a,
-	0x10, 0x94, 0x12, 0x6a,
-	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0x16, 0x6a,
-	0xdf, 0x93, 0x26, 0x09,
-	0x20, 0x93, 0x1a, 0x6a,
+	0x01, 0x94, 0x8a, 0x79,
+	0x01, 0x94, 0x8a, 0x79,
+	0x01, 0x94, 0x8a, 0x79,
+	0x01, 0x94, 0x8a, 0x79,
+	0x01, 0x94, 0x8a, 0x79,
+	0x01, 0x94, 0x8a, 0x79,
+	0x10, 0x94, 0x98, 0x69,
+	0x7f, 0x05, 0xa0, 0x69,
+	0x02, 0x03, 0xa0, 0x79,
+	0x11, 0x0c, 0x9c, 0x79,
+	0xd7, 0x93, 0x26, 0x09,
+	0x28, 0x93, 0xa2, 0x69,
 	0x03, 0x08, 0x52, 0x31,
 	0xff, 0x38, 0x50, 0x09,
 	0x12, 0x01, 0x02, 0x00,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x00, 0x65, 0x8e, 0x5b,
+	0x00, 0x65, 0x0e, 0x5b,
 	0x05, 0xb4, 0x10, 0x31,
 	0x02, 0x6a, 0x1a, 0x31,
 	0x03, 0x8c, 0x10, 0x30,
 	0x88, 0x6a, 0xcc, 0x00,
-	0xb4, 0x6a, 0x30, 0x5c,
+	0xb4, 0x6a, 0xb0, 0x5b,
 	0xff, 0x6a, 0x1a, 0x09,
 	0xff, 0x6a, 0x1c, 0x09,
-	0x00, 0x65, 0x26, 0x5c,
-	0x3d, 0x6a, 0x76, 0x5b,
+	0x00, 0x65, 0xa6, 0x5b,
+	0x3d, 0x6a, 0xee, 0x5a,
 	0xac, 0x6a, 0x26, 0x01,
-	0x04, 0x0b, 0x3a, 0x6a,
-	0x04, 0x0b, 0x40, 0x6a,
-	0x10, 0x0c, 0x3c, 0x7a,
-	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0x42, 0x6a,
-	0xdf, 0x93, 0x26, 0x09,
-	0x20, 0x93, 0x46, 0x6a,
+	0x04, 0x0b, 0xc2, 0x69,
+	0x04, 0x0b, 0xc8, 0x69,
+	0x10, 0x0c, 0xc4, 0x79,
+	0x02, 0x03, 0xcc, 0x79,
+	0x11, 0x0c, 0xc8, 0x79,
+	0xd7, 0x93, 0x26, 0x09,
+	0x28, 0x93, 0xce, 0x69,
 	0x12, 0x01, 0x02, 0x00,
-	0x00, 0x65, 0x24, 0x41,
-	0x00, 0x65, 0x8e, 0x5b,
+	0x00, 0x65, 0xaa, 0x40,
+	0x00, 0x65, 0x0e, 0x5b,
 	0xff, 0x06, 0x44, 0x09,
-	0x00, 0x65, 0x24, 0x41,
+	0x00, 0x65, 0xaa, 0x40,
 	0x10, 0x3d, 0x06, 0x00,
 	0xff, 0x34, 0xca, 0x08,
-	0x80, 0x65, 0x78, 0x62,
+	0x80, 0x65, 0x00, 0x62,
 	0x0f, 0xa1, 0xca, 0x08,
 	0x07, 0xa1, 0xca, 0x08,
 	0x40, 0xa0, 0xc8, 0x08,
 	0x00, 0x65, 0xca, 0x00,
 	0x80, 0x65, 0xca, 0x00,
-	0x80, 0xa0, 0x68, 0x7a,
+	0x80, 0xa0, 0xf0, 0x79,
 	0xff, 0x65, 0x0c, 0x08,
-	0x00, 0x65, 0x7a, 0x42,
-	0x20, 0xa0, 0x80, 0x7a,
+	0x00, 0x65, 0x02, 0x42,
+	0x20, 0xa0, 0x08, 0x7a,
 	0xff, 0x65, 0x0c, 0x08,
-	0x00, 0x65, 0x1e, 0x5c,
-	0xa0, 0x3d, 0x88, 0x62,
+	0x00, 0x65, 0x9e, 0x5b,
+	0xa0, 0x3d, 0x10, 0x62,
 	0x23, 0xa0, 0x0c, 0x08,
-	0x00, 0x65, 0x1e, 0x5c,
-	0xa0, 0x3d, 0x88, 0x62,
-	0x00, 0xb9, 0x80, 0x42,
-	0xff, 0x65, 0x80, 0x62,
+	0x00, 0x65, 0x9e, 0x5b,
+	0xa0, 0x3d, 0x10, 0x62,
+	0x00, 0xb9, 0x08, 0x42,
+	0xff, 0x65, 0x08, 0x62,
 	0xa1, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
-	0x10, 0x51, 0x88, 0x72,
+	0x10, 0x51, 0x10, 0x72,
 	0x40, 0x6a, 0x18, 0x00,
 	0xff, 0x65, 0x0c, 0x08,
-	0x00, 0x65, 0x1e, 0x5c,
-	0xa0, 0x3d, 0x52, 0x72,
+	0x00, 0x65, 0x9e, 0x5b,
+	0xa0, 0x3d, 0xda, 0x71,
 	0x40, 0x6a, 0x18, 0x00,
 	0xff, 0x34, 0xa6, 0x08,
-	0x80, 0x34, 0x90, 0x62,
+	0x80, 0x34, 0x18, 0x62,
 	0x7f, 0xa0, 0x40, 0x09,
 	0x08, 0x6a, 0x68, 0x00,
-	0x00, 0x65, 0x24, 0x41,
-	0x64, 0x6a, 0x66, 0x5b,
-	0x80, 0x64, 0x06, 0x6b,
-	0x04, 0x64, 0xe8, 0x72,
-	0x02, 0x64, 0xee, 0x72,
-	0x00, 0x6a, 0xb0, 0x72,
-	0x03, 0x64, 0x02, 0x73,
-	0x01, 0x64, 0xe4, 0x72,
-	0x07, 0x64, 0x44, 0x73,
-	0x08, 0x64, 0xac, 0x72,
-	0x23, 0x64, 0x48, 0x73,
+	0x00, 0x65, 0xaa, 0x40,
+	0x64, 0x6a, 0xe4, 0x5a,
+	0x80, 0x64, 0x8e, 0x6a,
+	0x04, 0x64, 0x70, 0x72,
+	0x02, 0x64, 0x76, 0x72,
+	0x00, 0x6a, 0x38, 0x72,
+	0x03, 0x64, 0x8a, 0x72,
+	0x01, 0x64, 0x6c, 0x72,
+	0x07, 0x64, 0xcc, 0x72,
+	0x08, 0x64, 0x34, 0x72,
+	0x23, 0x64, 0xd0, 0x72,
 	0x11, 0x6a, 0x22, 0x01,
-	0x07, 0x6a, 0x58, 0x5b,
+	0x07, 0x6a, 0xd6, 0x5a,
 	0xff, 0x06, 0xd4, 0x08,
-	0x00, 0x65, 0x24, 0x41,
-	0xff, 0xa8, 0xb4, 0x6a,
-	0xff, 0xa2, 0xcc, 0x7a,
+	0x00, 0x65, 0xaa, 0x40,
+	0xff, 0xa8, 0x3c, 0x6a,
+	0xff, 0xa2, 0x54, 0x7a,
 	0x01, 0x6a, 0x6a, 0x00,
-	0x00, 0xb9, 0x4a, 0x5c,
-	0xff, 0xa2, 0xcc, 0x7a,
+	0x00, 0xb9, 0xca, 0x5b,
+	0xff, 0xa2, 0x54, 0x7a,
 	0x71, 0x6a, 0x22, 0x01,
 	0xff, 0x6a, 0xd4, 0x08,
-	0x40, 0x51, 0xcc, 0x62,
+	0x40, 0x51, 0x54, 0x62,
 	0x0d, 0x6a, 0x6a, 0x00,
-	0x00, 0xb9, 0x4a, 0x5c,
+	0x00, 0xb9, 0xca, 0x5b,
 	0xff, 0x3e, 0x74, 0x09,
 	0xff, 0x90, 0x7c, 0x08,
-	0x00, 0x65, 0x50, 0x58,
-	0x00, 0x65, 0x36, 0x41,
-	0x20, 0xa0, 0xd4, 0x6a,
+	0x00, 0x65, 0x4e, 0x58,
+	0x00, 0x65, 0xbc, 0x40,
+	0x20, 0xa0, 0x5c, 0x6a,
 	0xff, 0x37, 0xc8, 0x08,
-	0x00, 0x6a, 0xf4, 0x5b,
-	0xff, 0x6a, 0x0a, 0x5c,
+	0x00, 0x6a, 0x74, 0x5b,
+	0xff, 0x6a, 0x8a, 0x5b,
 	0xff, 0xf8, 0xc8, 0x08,
 	0xff, 0x4f, 0xc8, 0x08,
-	0x01, 0x6a, 0xf4, 0x5b,
-	0x00, 0xb9, 0x0a, 0x5c,
+	0x01, 0x6a, 0x74, 0x5b,
+	0x00, 0xb9, 0x8a, 0x5b,
 	0x01, 0x4f, 0x9e, 0x18,
 	0x02, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0xb8, 0x5c,
-	0x00, 0x65, 0x36, 0x41,
+	0x00, 0x65, 0x38, 0x5c,
+	0x00, 0x65, 0xbc, 0x40,
 	0x41, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0x24, 0x41,
+	0x00, 0x65, 0xaa, 0x40,
 	0x04, 0xa0, 0x40, 0x01,
-	0x00, 0x65, 0xd0, 0x5c,
-	0x00, 0x65, 0x36, 0x41,
-	0x10, 0x36, 0xac, 0x7a,
+	0x00, 0x65, 0x50, 0x5c,
+	0x00, 0x65, 0xbc, 0x40,
+	0x10, 0x36, 0x34, 0x7a,
 	0x05, 0x38, 0x46, 0x31,
 	0x04, 0x14, 0x58, 0x31,
 	0x03, 0xa9, 0x60, 0x31,
 	0xa3, 0x6a, 0xcc, 0x00,
-	0x38, 0x6a, 0x30, 0x5c,
+	0x38, 0x6a, 0xb0, 0x5b,
 	0xac, 0x6a, 0xcc, 0x00,
-	0x14, 0x6a, 0x32, 0x5c,
-	0xa9, 0x6a, 0x34, 0x5c,
-	0x00, 0x65, 0xac, 0x42,
+	0x14, 0x6a, 0xb2, 0x5b,
+	0xa9, 0x6a, 0xb4, 0x5b,
+	0x00, 0x65, 0x34, 0x42,
 	0xef, 0x36, 0x6c, 0x08,
-	0x00, 0x65, 0xac, 0x42,
+	0x00, 0x65, 0x34, 0x42,
 	0x0f, 0x64, 0xc8, 0x08,
 	0x07, 0x64, 0xc8, 0x08,
 	0x00, 0x37, 0x6e, 0x00,
 	0xff, 0x6a, 0xa4, 0x00,
-	0x00, 0x65, 0xc4, 0x5b,
-	0xff, 0x51, 0x18, 0x73,
-	0x20, 0x36, 0x22, 0x7b,
-	0x00, 0x90, 0xb2, 0x5b,
-	0x00, 0x65, 0x24, 0x43,
+	0x00, 0x65, 0x44, 0x5b,
+	0xff, 0x51, 0xa0, 0x72,
+	0x20, 0x36, 0xaa, 0x7a,
+	0x00, 0x90, 0x32, 0x5b,
+	0x00, 0x65, 0xac, 0x42,
 	0xff, 0x06, 0xd4, 0x08,
-	0x00, 0x65, 0x1e, 0x5c,
-	0xe0, 0x3d, 0x3e, 0x63,
-	0x20, 0x12, 0x3e, 0x63,
-	0x51, 0x6a, 0x5c, 0x5b,
-	0x00, 0x65, 0xac, 0x5b,
+	0x00, 0x65, 0x9e, 0x5b,
+	0xe0, 0x3d, 0xc6, 0x62,
+	0x20, 0x12, 0xc6, 0x62,
+	0x51, 0x6a, 0xda, 0x5a,
+	0x00, 0x65, 0x2c, 0x5b,
 	0xff, 0x37, 0xc8, 0x08,
-	0x00, 0xa1, 0x36, 0x63,
-	0x04, 0xa0, 0x36, 0x7b,
+	0x00, 0xa1, 0xbe, 0x62,
+	0x04, 0xa0, 0xbe, 0x7a,
 	0xfb, 0xa0, 0x40, 0x09,
 	0x80, 0x36, 0x6c, 0x00,
-	0x80, 0xa0, 0xac, 0x7a,
+	0x80, 0xa0, 0x34, 0x7a,
 	0x7f, 0xa0, 0x40, 0x09,
-	0xff, 0x6a, 0x58, 0x5b,
-	0x00, 0x65, 0xac, 0x42,
-	0x04, 0xa0, 0x3c, 0x7b,
-	0x00, 0x65, 0xd0, 0x5c,
-	0x00, 0x65, 0x3e, 0x43,
-	0x00, 0x65, 0xb8, 0x5c,
+	0xff, 0x6a, 0xd6, 0x5a,
+	0x00, 0x65, 0x34, 0x42,
+	0x04, 0xa0, 0xc4, 0x7a,
+	0x00, 0x65, 0x50, 0x5c,
+	0x00, 0x65, 0xc6, 0x42,
+	0x00, 0x65, 0x38, 0x5c,
 	0x31, 0x6a, 0x22, 0x01,
-	0x0c, 0x6a, 0x58, 0x5b,
-	0x00, 0x65, 0xac, 0x42,
+	0x0c, 0x6a, 0xd6, 0x5a,
+	0x00, 0x65, 0x34, 0x42,
 	0x61, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0xac, 0x42,
-	0x51, 0x6a, 0x5c, 0x5b,
-	0xff, 0xa8, 0x54, 0x6b,
-	0xff, 0xa9, 0x54, 0x6b,
-	0xff, 0xaa, 0x54, 0x6b,
-	0xff, 0xab, 0x54, 0x6b,
-	0x00, 0x65, 0xac, 0x42,
+	0x00, 0x65, 0x34, 0x42,
+	0x51, 0x6a, 0xda, 0x5a,
 	0x51, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0xac, 0x42,
+	0x00, 0x65, 0x34, 0x42,
 	0x10, 0x3d, 0x06, 0x00,
 	0xff, 0x65, 0x68, 0x0c,
 	0xff, 0x06, 0xd4, 0x08,
-	0x01, 0x0c, 0x5e, 0x7b,
-	0x04, 0x0c, 0x60, 0x6b,
+	0x01, 0x0c, 0xdc, 0x7a,
+	0x04, 0x0c, 0xde, 0x6a,
 	0xe0, 0x03, 0x7a, 0x08,
-	0xe0, 0x3d, 0x72, 0x63,
+	0xe0, 0x3d, 0xea, 0x62,
 	0xff, 0x65, 0xcc, 0x08,
 	0xff, 0x12, 0xda, 0x0c,
 	0xff, 0x06, 0xd4, 0x0c,
-	0xff, 0x65, 0x0c, 0x08,
-	0x02, 0x0b, 0x6e, 0x7b,
-	0xff, 0x6a, 0xd4, 0x0c,
 	0xd1, 0x6a, 0x22, 0x01,
-	0x00, 0x65, 0x24, 0x41,
+	0x00, 0x65, 0xaa, 0x40,
 	0xff, 0x65, 0x26, 0x09,
-	0x01, 0x0b, 0x86, 0x6b,
-	0x10, 0x0c, 0x78, 0x7b,
-	0x04, 0x0b, 0x80, 0x6b,
+	0x01, 0x0b, 0xfe, 0x6a,
+	0x10, 0x0c, 0xf0, 0x7a,
+	0x04, 0x0b, 0xf8, 0x6a,
 	0xff, 0x6a, 0xca, 0x08,
-	0x04, 0x93, 0x84, 0x6b,
-	0x01, 0x94, 0x82, 0x7b,
-	0x10, 0x94, 0x84, 0x6b,
+	0x04, 0x93, 0xfc, 0x6a,
+	0x01, 0x94, 0xfa, 0x7a,
+	0x10, 0x94, 0xfc, 0x6a,
+	0x80, 0x3d, 0x02, 0x73,
+	0x0f, 0x04, 0x06, 0x6b,
+	0x02, 0x03, 0x06, 0x7b,
+	0x11, 0x0c, 0x02, 0x7b,
 	0xc7, 0x93, 0x26, 0x09,
 	0xff, 0x99, 0xd4, 0x08,
-	0x38, 0x93, 0x88, 0x6b,
+	0x38, 0x93, 0x08, 0x6b,
 	0xff, 0x6a, 0xd4, 0x0c,
-	0x80, 0x36, 0x8c, 0x6b,
+	0x80, 0x36, 0x0c, 0x6b,
 	0x21, 0x6a, 0x22, 0x05,
 	0xff, 0x65, 0x20, 0x09,
-	0xff, 0x51, 0x9a, 0x63,
+	0xff, 0x51, 0x1a, 0x63,
 	0xff, 0x37, 0xc8, 0x08,
-	0xa1, 0x6a, 0xa6, 0x43,
+	0xa1, 0x6a, 0x26, 0x43,
 	0xff, 0x51, 0xc8, 0x08,
-	0xb9, 0x6a, 0xa6, 0x43,
+	0xb9, 0x6a, 0x26, 0x43,
 	0xff, 0x90, 0xa4, 0x08,
-	0xff, 0xba, 0xaa, 0x73,
+	0xff, 0xba, 0x2a, 0x73,
 	0xff, 0xba, 0x20, 0x09,
 	0xff, 0x65, 0xca, 0x18,
-	0x00, 0x6c, 0x9e, 0x63,
+	0x00, 0x6c, 0x1e, 0x63,
 	0xff, 0x90, 0xca, 0x0c,
 	0xff, 0x6a, 0xca, 0x04,
-	0x20, 0x36, 0xbe, 0x7b,
-	0x00, 0x90, 0x92, 0x5b,
-	0xff, 0x65, 0xbe, 0x73,
-	0xff, 0x52, 0xbc, 0x73,
+	0x20, 0x36, 0x3e, 0x7b,
+	0x00, 0x90, 0x12, 0x5b,
+	0xff, 0x65, 0x3e, 0x73,
+	0xff, 0x52, 0x3c, 0x73,
 	0xff, 0xba, 0xcc, 0x08,
 	0xff, 0x52, 0x20, 0x09,
 	0xff, 0x66, 0x74, 0x09,
 	0xff, 0x65, 0x20, 0x0d,
 	0xff, 0xba, 0x7e, 0x0c,
-	0x00, 0x6a, 0xbe, 0x5c,
+	0x00, 0x6a, 0x3e, 0x5c,
 	0x0d, 0x6a, 0x6a, 0x00,
-	0x00, 0x51, 0x4a, 0x44,
-	0xff, 0x3f, 0x18, 0x74,
+	0x00, 0x51, 0xca, 0x43,
+	0xff, 0x3f, 0x98, 0x73,
 	0xff, 0x6a, 0xa2, 0x00,
-	0x00, 0x3f, 0x92, 0x5b,
-	0xff, 0x65, 0x18, 0x74,
+	0x00, 0x3f, 0x12, 0x5b,
+	0xff, 0x65, 0x98, 0x73,
 	0x20, 0x36, 0x6c, 0x00,
-	0x20, 0xa0, 0xd2, 0x6b,
+	0x20, 0xa0, 0x52, 0x6b,
 	0xff, 0xb9, 0xa2, 0x0c,
 	0xff, 0x6a, 0xa2, 0x04,
 	0xff, 0x65, 0xa4, 0x08,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x45, 0x6a, 0x3e, 0x5c,
+	0x45, 0x6a, 0xbe, 0x5b,
 	0x01, 0x6a, 0xd0, 0x01,
 	0x09, 0x6a, 0xd6, 0x01,
-	0x80, 0xeb, 0xde, 0x7b,
+	0x80, 0xeb, 0x5e, 0x7b,
 	0x01, 0x6a, 0xd6, 0x01,
 	0x01, 0xe9, 0xa4, 0x34,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x45, 0x6a, 0x3e, 0x5c,
+	0x45, 0x6a, 0xbe, 0x5b,
 	0x01, 0x6a, 0x18, 0x01,
 	0xff, 0x6a, 0x1a, 0x09,
 	0xff, 0x6a, 0x1c, 0x09,
 	0x0d, 0x6a, 0x26, 0x01,
-	0x00, 0x65, 0xb0, 0x5c,
+	0x00, 0x65, 0x30, 0x5c,
 	0xff, 0x99, 0xa4, 0x0c,
 	0xff, 0x65, 0xa4, 0x08,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x45, 0x6a, 0x3e, 0x5c,
+	0x45, 0x6a, 0xbe, 0x5b,
 	0x01, 0x6a, 0xd0, 0x01,
 	0x01, 0x6a, 0xdc, 0x05,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x45, 0x6a, 0x3e, 0x5c,
+	0x45, 0x6a, 0xbe, 0x5b,
 	0x01, 0x6a, 0x18, 0x01,
 	0xff, 0x6a, 0x1a, 0x09,
 	0xff, 0x6a, 0x1c, 0x09,
 	0x01, 0x6a, 0x26, 0x05,
 	0x01, 0x65, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0x0e, 0x7c,
+	0x80, 0xee, 0x8e, 0x7b,
 	0xff, 0x6a, 0xdc, 0x0d,
 	0xff, 0x65, 0x32, 0x09,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xb0, 0x44,
+	0x00, 0x65, 0x30, 0x44,
 	0xff, 0x37, 0xc8, 0x08,
-	0x00, 0x6a, 0xd4, 0x5b,
+	0x00, 0x6a, 0x54, 0x5b,
 	0xff, 0x52, 0xa2, 0x0c,
-	0x01, 0x0c, 0x1e, 0x7c,
-	0x04, 0x0c, 0x1e, 0x6c,
+	0x01, 0x0c, 0x9e, 0x7b,
+	0x04, 0x0c, 0x9e, 0x6b,
 	0xe0, 0x03, 0x06, 0x08,
 	0xe0, 0x03, 0x7a, 0x0c,
 	0xff, 0x8c, 0x10, 0x08,
@@ -553,29 +489,29 @@
 	0x00, 0x6c, 0xda, 0x24,
 	0xff, 0x65, 0xc8, 0x08,
 	0xe0, 0x6a, 0xcc, 0x00,
-	0x41, 0x6a, 0x3a, 0x5c,
+	0x41, 0x6a, 0xba, 0x5b,
 	0xff, 0x90, 0xe2, 0x09,
 	0x20, 0x6a, 0xd0, 0x01,
-	0x04, 0x35, 0x5c, 0x7c,
+	0x04, 0x35, 0xdc, 0x7b,
 	0x1d, 0x6a, 0xdc, 0x01,
-	0xdc, 0xee, 0x58, 0x64,
-	0x00, 0x65, 0x68, 0x44,
+	0xdc, 0xee, 0xd8, 0x63,
+	0x00, 0x65, 0xe8, 0x43,
 	0x01, 0x6a, 0xdc, 0x01,
 	0x20, 0xa0, 0xd8, 0x31,
 	0x09, 0xee, 0xdc, 0x01,
-	0x80, 0xee, 0x62, 0x7c,
+	0x80, 0xee, 0xe2, 0x7b,
 	0x19, 0x6a, 0xdc, 0x01,
-	0xd8, 0xee, 0x66, 0x64,
+	0xd8, 0xee, 0xe6, 0x63,
 	0xff, 0x6a, 0xdc, 0x09,
-	0x18, 0xee, 0x6a, 0x6c,
+	0x18, 0xee, 0xea, 0x6b,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0x88, 0x6a, 0xcc, 0x00,
-	0x41, 0x6a, 0x3a, 0x5c,
+	0x41, 0x6a, 0xba, 0x5b,
 	0x20, 0x6a, 0x18, 0x01,
 	0xff, 0x6a, 0x1a, 0x09,
 	0xff, 0x6a, 0x1c, 0x09,
 	0xff, 0x35, 0x26, 0x09,
-	0x04, 0x35, 0x94, 0x6c,
+	0x04, 0x35, 0x14, 0x6c,
 	0xa0, 0x6a, 0xca, 0x00,
 	0x20, 0x65, 0xc8, 0x18,
 	0xff, 0x6c, 0x32, 0x09,
@@ -586,14 +522,14 @@
 	0xff, 0x6c, 0x32, 0x09,
 	0xff, 0x6c, 0x32, 0x09,
 	0xff, 0x6c, 0x32, 0x09,
-	0x00, 0x65, 0x80, 0x64,
+	0x00, 0x65, 0x00, 0x64,
 	0x0a, 0x93, 0x26, 0x01,
-	0x00, 0x65, 0xb0, 0x5c,
-	0x04, 0x35, 0x8c, 0x7b,
-	0xa0, 0x6a, 0xa0, 0x5c,
-	0x00, 0x65, 0xa2, 0x5c,
-	0x00, 0x65, 0xa2, 0x5c,
-	0x00, 0x65, 0xa2, 0x44,
+	0x00, 0x65, 0x30, 0x5c,
+	0x04, 0x35, 0x0c, 0x7b,
+	0xa0, 0x6a, 0x20, 0x5c,
+	0x00, 0x65, 0x22, 0x5c,
+	0x00, 0x65, 0x22, 0x5c,
+	0x00, 0x65, 0x22, 0x44,
 	0xff, 0x65, 0xcc, 0x08,
 	0xff, 0x99, 0xda, 0x08,
 	0xff, 0x99, 0xda, 0x08,
@@ -602,19 +538,19 @@
 	0xff, 0x99, 0xda, 0x08,
 	0xff, 0x99, 0xda, 0x08,
 	0xff, 0x99, 0xda, 0x0c,
-	0x08, 0x94, 0xb0, 0x7c,
+	0x08, 0x94, 0x30, 0x7c,
 	0xf7, 0x93, 0x26, 0x09,
-	0x08, 0x93, 0xb4, 0x6c,
+	0x08, 0x93, 0x34, 0x6c,
 	0xff, 0x6a, 0xd4, 0x0c,
 	0xff, 0x40, 0x74, 0x09,
 	0xff, 0x90, 0x80, 0x08,
 	0xff, 0x6a, 0x72, 0x05,
-	0xff, 0x40, 0xcc, 0x64,
-	0xff, 0x3f, 0xc4, 0x64,
+	0xff, 0x40, 0x4c, 0x64,
+	0xff, 0x3f, 0x44, 0x64,
 	0xff, 0x6a, 0xca, 0x04,
 	0xff, 0x3f, 0x20, 0x09,
 	0x01, 0x6a, 0x6a, 0x00,
-	0x00, 0xb9, 0x4a, 0x5c,
+	0x00, 0xb9, 0xca, 0x5b,
 	0xff, 0xba, 0x7e, 0x0c,
 	0xff, 0x40, 0x20, 0x09,
 	0xff, 0xba, 0x80, 0x0c,
@@ -622,20 +558,12 @@
 	0xff, 0x90, 0x7e, 0x0c,
 };
 
-static int aic7xxx_patch13_func(struct aic7xxx_host *p);
-
-static int
-aic7xxx_patch13_func(struct aic7xxx_host *p)
-{
-	return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895);
-}
-
 static int aic7xxx_patch12_func(struct aic7xxx_host *p);
 
 static int
 aic7xxx_patch12_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_CMD_CHAN) == 0);
+	return ((p->features & AHC_WIDE) != 0);
 }
 
 static int aic7xxx_patch11_func(struct aic7xxx_host *p);
@@ -643,7 +571,7 @@
 static int
 aic7xxx_patch11_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_WIDE) != 0);
+	return ((p->features & AHC_ULTRA2) == 0);
 }
 
 static int aic7xxx_patch10_func(struct aic7xxx_host *p);
@@ -651,7 +579,7 @@
 static int
 aic7xxx_patch10_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_ULTRA2) == 0);
+	return ((p->features & AHC_CMD_CHAN) == 0);
 }
 
 static int aic7xxx_patch9_func(struct aic7xxx_host *p);
@@ -659,7 +587,7 @@
 static int
 aic7xxx_patch9_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_ULTRA) != 0);
+	return ((p->chip & AHC_CHIPID_MASK) == AHC_AIC7895);
 }
 
 static int aic7xxx_patch8_func(struct aic7xxx_host *p);
@@ -667,7 +595,7 @@
 static int
 aic7xxx_patch8_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_ULTRA2) != 0);
+	return ((p->features & AHC_ULTRA) != 0);
 }
 
 static int aic7xxx_patch7_func(struct aic7xxx_host *p);
@@ -675,7 +603,7 @@
 static int
 aic7xxx_patch7_func(struct aic7xxx_host *p)
 {
-	return ((p->flags & AHC_PAGESCBS) == 0);
+	return ((p->features & AHC_ULTRA2) != 0);
 }
 
 static int aic7xxx_patch6_func(struct aic7xxx_host *p);
@@ -683,7 +611,7 @@
 static int
 aic7xxx_patch6_func(struct aic7xxx_host *p)
 {
-	return ((p->flags & AHC_PAGESCBS) != 0);
+	return ((p->flags & AHC_PAGESCBS) == 0);
 }
 
 static int aic7xxx_patch5_func(struct aic7xxx_host *p);
@@ -691,7 +619,7 @@
 static int
 aic7xxx_patch5_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_QUEUE_REGS) != 0);
+	return ((p->flags & AHC_PAGESCBS) != 0);
 }
 
 static int aic7xxx_patch4_func(struct aic7xxx_host *p);
@@ -699,7 +627,7 @@
 static int
 aic7xxx_patch4_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_TWIN) != 0);
+	return ((p->features & AHC_QUEUE_REGS) != 0);
 }
 
 static int aic7xxx_patch3_func(struct aic7xxx_host *p);
@@ -707,7 +635,7 @@
 static int
 aic7xxx_patch3_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_QUEUE_REGS) == 0);
+	return ((p->features & AHC_TWIN) != 0);
 }
 
 static int aic7xxx_patch2_func(struct aic7xxx_host *p);
@@ -715,7 +643,7 @@
 static int
 aic7xxx_patch2_func(struct aic7xxx_host *p)
 {
-	return ((p->features & AHC_CMD_CHAN) != 0);
+	return ((p->features & AHC_QUEUE_REGS) == 0);
 }
 
 static int aic7xxx_patch1_func(struct aic7xxx_host *p);
@@ -723,7 +651,7 @@
 static int
 aic7xxx_patch1_func(struct aic7xxx_host *p)
 {
-	return ((p->flags & AHC_TARGETMODE) != 0);
+	return ((p->features & AHC_CMD_CHAN) != 0);
 }
 
 static int aic7xxx_patch0_func(struct aic7xxx_host *p);
@@ -740,83 +668,78 @@
 			skip_instr :10,
 			skip_patch :12;
 } sequencer_patches[] = {
-	{ aic7xxx_patch1_func, 2, 1, 2 },
-	{ aic7xxx_patch0_func, 3, 1, 1 },
-	{ aic7xxx_patch2_func, 4, 2, 1 },
-	{ aic7xxx_patch3_func, 8, 1, 1 },
-	{ aic7xxx_patch3_func, 9, 1, 1 },
-	{ aic7xxx_patch4_func, 12, 4, 1 },
-	{ aic7xxx_patch5_func, 17, 3, 2 },
-	{ aic7xxx_patch0_func, 20, 4, 1 },
-	{ aic7xxx_patch6_func, 24, 1, 1 },
-	{ aic7xxx_patch7_func, 27, 1, 1 },
-	{ aic7xxx_patch2_func, 30, 1, 2 },
-	{ aic7xxx_patch0_func, 31, 3, 1 },
-	{ aic7xxx_patch4_func, 40, 4, 1 },
-	{ aic7xxx_patch8_func, 44, 3, 2 },
-	{ aic7xxx_patch0_func, 47, 3, 1 },
-	{ aic7xxx_patch9_func, 53, 7, 1 },
-	{ aic7xxx_patch4_func, 61, 3, 1 },
-	{ aic7xxx_patch8_func, 64, 2, 1 },
-	{ aic7xxx_patch1_func, 69, 60, 1 },
-	{ aic7xxx_patch8_func, 163, 1, 2 },
-	{ aic7xxx_patch0_func, 164, 2, 1 },
-	{ aic7xxx_patch2_func, 168, 3, 4 },
-	{ aic7xxx_patch8_func, 168, 2, 2 },
-	{ aic7xxx_patch0_func, 170, 1, 1 },
-	{ aic7xxx_patch0_func, 171, 2, 1 },
-	{ aic7xxx_patch8_func, 174, 1, 2 },
-	{ aic7xxx_patch0_func, 175, 1, 1 },
-	{ aic7xxx_patch2_func, 179, 1, 1 },
-	{ aic7xxx_patch2_func, 182, 3, 2 },
-	{ aic7xxx_patch0_func, 185, 5, 1 },
-	{ aic7xxx_patch2_func, 193, 2, 3 },
-	{ aic7xxx_patch8_func, 193, 1, 1 },
-	{ aic7xxx_patch0_func, 195, 3, 1 },
-	{ aic7xxx_patch10_func, 199, 1, 2 },
-	{ aic7xxx_patch0_func, 200, 1, 1 },
-	{ aic7xxx_patch8_func, 201, 7, 2 },
-	{ aic7xxx_patch0_func, 208, 1, 1 },
-	{ aic7xxx_patch2_func, 213, 14, 3 },
-	{ aic7xxx_patch10_func, 226, 1, 1 },
-	{ aic7xxx_patch0_func, 227, 9, 1 },
-	{ aic7xxx_patch8_func, 241, 2, 1 },
-	{ aic7xxx_patch8_func, 243, 1, 1 },
-	{ aic7xxx_patch10_func, 244, 6, 3 },
-	{ aic7xxx_patch2_func, 244, 2, 2 },
-	{ aic7xxx_patch0_func, 246, 4, 1 },
-	{ aic7xxx_patch8_func, 251, 1, 1 },
-	{ aic7xxx_patch8_func, 255, 19, 1 },
-	{ aic7xxx_patch2_func, 275, 3, 3 },
-	{ aic7xxx_patch10_func, 277, 1, 1 },
-	{ aic7xxx_patch0_func, 278, 5, 1 },
-	{ aic7xxx_patch10_func, 283, 1, 2 },
-	{ aic7xxx_patch0_func, 284, 9, 1 },
-	{ aic7xxx_patch11_func, 300, 1, 2 },
-	{ aic7xxx_patch0_func, 301, 1, 1 },
-	{ aic7xxx_patch5_func, 362, 1, 2 },
-	{ aic7xxx_patch0_func, 363, 1, 1 },
-	{ aic7xxx_patch3_func, 366, 1, 1 },
-	{ aic7xxx_patch2_func, 376, 3, 2 },
-	{ aic7xxx_patch0_func, 379, 5, 1 },
-	{ aic7xxx_patch11_func, 387, 1, 2 },
-	{ aic7xxx_patch0_func, 388, 1, 1 },
-	{ aic7xxx_patch6_func, 393, 1, 1 },
-	{ aic7xxx_patch1_func, 438, 3, 1 },
-	{ aic7xxx_patch10_func, 443, 11, 1 },
-	{ aic7xxx_patch2_func, 491, 7, 2 },
-	{ aic7xxx_patch0_func, 498, 8, 1 },
-	{ aic7xxx_patch2_func, 507, 4, 2 },
-	{ aic7xxx_patch0_func, 511, 6, 1 },
-	{ aic7xxx_patch2_func, 517, 4, 2 },
-	{ aic7xxx_patch0_func, 521, 3, 1 },
-	{ aic7xxx_patch12_func, 531, 10, 1 },
-	{ aic7xxx_patch2_func, 550, 17, 4 },
-	{ aic7xxx_patch13_func, 558, 4, 2 },
-	{ aic7xxx_patch0_func, 562, 2, 1 },
-	{ aic7xxx_patch0_func, 567, 33, 1 },
-	{ aic7xxx_patch12_func, 600, 4, 1 },
-	{ aic7xxx_patch6_func, 604, 2, 1 },
-	{ aic7xxx_patch6_func, 607, 9, 1 },
+	{ aic7xxx_patch1_func, 3, 2, 1 },
+	{ aic7xxx_patch2_func, 7, 1, 1 },
+	{ aic7xxx_patch2_func, 8, 1, 1 },
+	{ aic7xxx_patch3_func, 11, 4, 1 },
+	{ aic7xxx_patch4_func, 16, 3, 2 },
+	{ aic7xxx_patch0_func, 19, 4, 1 },
+	{ aic7xxx_patch5_func, 23, 1, 1 },
+	{ aic7xxx_patch6_func, 26, 1, 1 },
+	{ aic7xxx_patch1_func, 29, 1, 2 },
+	{ aic7xxx_patch0_func, 30, 3, 1 },
+	{ aic7xxx_patch3_func, 39, 4, 1 },
+	{ aic7xxx_patch7_func, 43, 3, 2 },
+	{ aic7xxx_patch0_func, 46, 3, 1 },
+	{ aic7xxx_patch8_func, 52, 7, 1 },
+	{ aic7xxx_patch3_func, 60, 3, 1 },
+	{ aic7xxx_patch7_func, 63, 2, 1 },
+	{ aic7xxx_patch7_func, 102, 1, 2 },
+	{ aic7xxx_patch0_func, 103, 2, 1 },
+	{ aic7xxx_patch7_func, 107, 2, 1 },
+	{ aic7xxx_patch9_func, 109, 1, 1 },
+	{ aic7xxx_patch10_func, 110, 2, 1 },
+	{ aic7xxx_patch7_func, 113, 1, 2 },
+	{ aic7xxx_patch0_func, 114, 1, 1 },
+	{ aic7xxx_patch1_func, 118, 1, 1 },
+	{ aic7xxx_patch1_func, 121, 3, 2 },
+	{ aic7xxx_patch0_func, 124, 5, 1 },
+	{ aic7xxx_patch1_func, 132, 2, 3 },
+	{ aic7xxx_patch7_func, 132, 1, 1 },
+	{ aic7xxx_patch0_func, 134, 3, 1 },
+	{ aic7xxx_patch11_func, 138, 1, 2 },
+	{ aic7xxx_patch0_func, 139, 1, 1 },
+	{ aic7xxx_patch7_func, 140, 7, 2 },
+	{ aic7xxx_patch0_func, 147, 1, 1 },
+	{ aic7xxx_patch1_func, 152, 14, 3 },
+	{ aic7xxx_patch11_func, 165, 1, 1 },
+	{ aic7xxx_patch0_func, 166, 9, 1 },
+	{ aic7xxx_patch7_func, 180, 2, 1 },
+	{ aic7xxx_patch7_func, 182, 1, 1 },
+	{ aic7xxx_patch11_func, 183, 6, 3 },
+	{ aic7xxx_patch1_func, 183, 2, 2 },
+	{ aic7xxx_patch0_func, 185, 4, 1 },
+	{ aic7xxx_patch7_func, 190, 1, 1 },
+	{ aic7xxx_patch7_func, 194, 20, 1 },
+	{ aic7xxx_patch1_func, 215, 3, 3 },
+	{ aic7xxx_patch11_func, 217, 1, 1 },
+	{ aic7xxx_patch0_func, 218, 5, 1 },
+	{ aic7xxx_patch11_func, 223, 1, 2 },
+	{ aic7xxx_patch0_func, 224, 9, 1 },
+	{ aic7xxx_patch12_func, 240, 1, 2 },
+	{ aic7xxx_patch0_func, 241, 1, 1 },
+	{ aic7xxx_patch4_func, 302, 1, 2 },
+	{ aic7xxx_patch0_func, 303, 1, 1 },
+	{ aic7xxx_patch2_func, 306, 1, 1 },
+	{ aic7xxx_patch1_func, 316, 3, 2 },
+	{ aic7xxx_patch0_func, 319, 5, 1 },
+	{ aic7xxx_patch12_func, 327, 1, 2 },
+	{ aic7xxx_patch0_func, 328, 1, 1 },
+	{ aic7xxx_patch5_func, 333, 1, 1 },
+	{ aic7xxx_patch11_func, 375, 15, 1 },
+	{ aic7xxx_patch1_func, 427, 7, 2 },
+	{ aic7xxx_patch0_func, 434, 8, 1 },
+	{ aic7xxx_patch1_func, 443, 4, 2 },
+	{ aic7xxx_patch0_func, 447, 6, 1 },
+	{ aic7xxx_patch1_func, 453, 4, 2 },
+	{ aic7xxx_patch0_func, 457, 3, 1 },
+	{ aic7xxx_patch10_func, 467, 10, 1 },
+	{ aic7xxx_patch1_func, 486, 17, 4 },
+	{ aic7xxx_patch9_func, 494, 4, 2 },
+	{ aic7xxx_patch0_func, 498, 2, 1 },
+	{ aic7xxx_patch0_func, 503, 33, 1 },
+	{ aic7xxx_patch10_func, 536, 4, 1 },
+	{ aic7xxx_patch5_func, 540, 2, 1 },
+	{ aic7xxx_patch5_func, 543, 9, 1 },
 
 };
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/eata.c linux.17p18/drivers/scsi/eata.c
--- linux.vanilla/drivers/scsi/eata.c	Fri Apr 21 12:46:28 2000
+++ linux.17p18/drivers/scsi/eata.c	Tue Aug  1 07:59:55 2000
@@ -915,7 +915,7 @@
    if (info.sign != EATA_SIGNATURE) return FALSE;
 
    if (DEV2H(info.data_len) < EATA_2_0A_SIZE) {
-      printk("%s: config structure size (%ld bytes) too short, detaching.\n",
+      printk("%s: config structure size (%d bytes) too short, detaching.\n",
              name, DEV2H(info.data_len));
       return FALSE;
       }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/hosts.c linux.17p18/drivers/scsi/hosts.c
--- linux.vanilla/drivers/scsi/hosts.c	Fri Apr 21 12:46:28 2000
+++ linux.17p18/drivers/scsi/hosts.c	Tue Aug  1 07:59:56 2000
@@ -343,6 +343,10 @@
 #include "3w-xxxx.h"
 #endif
 
+#ifdef CONFIG_I2O_SCSI
+#include "../i2o/i2o_scsi.h"
+#endif
+
 /*
  * Moved ppa driver to the end of the probe list
  * since it is a removable host adapter.
@@ -617,7 +621,10 @@
 #ifdef CONFIG_BLK_DEV_3W_XXXX_RAID
 	TWXXXX,
 #endif
-
+/* Put I2O after specific adapters */
+#ifdef CONFIG_I2O_SCSI
+	I2OSCSI,
+#endif
 /* "Removable host adapters" below this line (Parallel Port/USB/other) */
 #ifdef CONFIG_SCSI_PPA
     PPA,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/imm.c linux.17p18/drivers/scsi/imm.c
--- linux.vanilla/drivers/scsi/imm.c	Fri Apr 21 12:46:28 2000
+++ linux.17p18/drivers/scsi/imm.c	Tue Aug  1 07:59:56 2000
@@ -32,6 +32,7 @@
 typedef struct {
     struct pardevice *dev;	/* Parport device entry         */
     int base;			/* Actual port address          */
+    int base_hi;		/* Hi Base address for ECP-ISA chipset */
     int mode;			/* Transfer mode                */
     int host;			/* Host number (for proc)       */
     Scsi_Cmnd *cur_cmd;		/* Current queued command       */
@@ -46,6 +47,7 @@
 #define IMM_EMPTY \
 {	dev:		NULL,		\
 	base:		-1,		\
+	base_hi:	0,		\
 	mode:		IMM_AUTODETECT,	\
 	host:		-1,		\
 	cur_cmd:	NULL,		\
@@ -63,6 +65,7 @@
 {IMM_EMPTY, IMM_EMPTY, IMM_EMPTY, IMM_EMPTY};
 
 #define IMM_BASE(x)	imm_hosts[(x)].base
+#define IMM_BASE_HI(x)     imm_hosts[(x)].base_hi
 
 int parbus_base[NO_HOSTS] =
 {0x03bc, 0x0378, 0x0278, 0x0000};
@@ -133,7 +136,7 @@
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-	int modes, ppb;
+	int modes, ppb, ppb_hi;
 
 	imm_hosts[i].dev =
 	    parport_register_device(pb, "imm", NULL, imm_wakeup,
@@ -158,6 +161,7 @@
 	    }
 	}
 	ppb = IMM_BASE(i) = imm_hosts[i].dev->port->base;
+	ppb_hi = IMM_BASE_HI(i) = imm_hosts[i].dev->port->base_hi;
 	w_ctr(ppb, 0x0c);
 	modes = imm_hosts[i].dev->port->modes;
 
@@ -169,12 +173,12 @@
 	if (modes & PARPORT_MODE_PCPS2)
 	    imm_hosts[i].mode = IMM_PS2;
 
-	if (modes & PARPORT_MODE_PCECPPS2) {
-	    w_ecr(ppb, 0x20);
+	if (ppb_hi && modes & PARPORT_MODE_PCECPPS2) {
+	    w_ecr(ppb_hi, 0x20);
 	    imm_hosts[i].mode = IMM_PS2;
 	}
-	if (modes & PARPORT_MODE_PCECPEPP)
-	    w_ecr(ppb, 0x80);
+	if (ppb_hi && modes & PARPORT_MODE_PCECPEPP)
+	    w_ecr(ppb_hi, 0x80);
 
 	/* Done configuration */
 	imm_pb_release(i);
@@ -381,6 +385,9 @@
     return a;
 }
 
+/* 
+ * Clear EPP timeout bit. 
+ */
 static inline void epp_reset(unsigned short ppb)
 {
     int i;
@@ -390,19 +397,23 @@
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=IMM_BASE_HI(hostno);
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-	return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-	if (r_ecr(ppb) & 0x01)
-	    return;
-	udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+	    if (r_ecr(ppb_hi) & 0x01)
+	        return;
+	    udelay(5);
+	}
+        printk("imm: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("imm: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int imm_byte_out(unsigned short base, const char *buffer, int len)
@@ -490,7 +501,7 @@
 	w_ctr(ppb, 0xc);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0xc);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     case IMM_NIBBLE:
@@ -552,7 +563,7 @@
 	w_ctr(ppb, 0x2c);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0x2c);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -1246,7 +1257,7 @@
 	    return 1;
 	}
 	imm_disconnect(host_no);
-	printk("imm: Communication established with ID %i using %s\n", loop,
+	printk("imm: Communication established at 0x%x with ID %i using %s\n", ppb, loop,
 	       IMM_MODE_STRING[imm_hosts[host_no].mode]);
 	imm_connect(host_no, CONNECT_EPP_MAYBE);
 	imm_reset_pulse(IMM_BASE(host_no));
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/imm.h linux.17p18/drivers/scsi/imm.h
--- linux.vanilla/drivers/scsi/imm.h	Wed May  3 22:31:20 2000
+++ linux.17p18/drivers/scsi/imm.h	Thu Aug 17 18:11:50 2000
@@ -125,14 +125,15 @@
 #define r_str(x)        (unsigned char)inb((x)+1)
 #define r_ctr(x)        (unsigned char)inb((x)+2)
 #define r_epp(x)        (unsigned char)inb((x)+4)
-#define r_fifo(x)       (unsigned char)inb((x)+0x400)
-#define r_ecr(x)        (unsigned char)inb((x)+0x402)
+#define r_fifo(x)       (unsigned char)inb((x))   /* x must be base_hi */
+					/* On PCI is: base+0x400 != base_hi */
+#define r_ecr(x)        (unsigned char)inb((x)+2) /* x must be base_hi */
 
 #define w_dtr(x,y)      outb(y, (x))
 #define w_str(x,y)      outb(y, (x)+1)
 #define w_epp(x,y)      outb(y, (x)+4)
-#define w_fifo(x,y)     outb(y, (x)+0x400)
-#define w_ecr(x,y)      outb(y, (x)+0x402)
+#define w_fifo(x,y)     outb(y, (x))     /* x must be base_hi */
+#define w_ecr(x,y)      outb(y, (x)+0x2) /* x must be base_hi */
 
 #ifdef CONFIG_SCSI_IZIP_SLOW_CTR
 #define w_ctr(x,y)      outb_p(y, (x)+2)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/ini9100u.c linux.17p18/drivers/scsi/ini9100u.c
--- linux.vanilla/drivers/scsi/ini9100u.c	Sun Jun 11 21:44:15 2000
+++ linux.17p18/drivers/scsi/ini9100u.c	Tue Aug  1 07:59:56 2000
@@ -545,8 +545,6 @@
 #if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(2,1,95)
 		pHCB->pSRB_lock = SPIN_LOCK_UNLOCKED;	/* SRB save queue lock */
 #endif
-		request_region(pHCB->HCS_Base, 0x100, "i91u");	/* Register */
-
 		get_tulipPCIConfig(pHCB, i);
 
 		dBiosAdr = pHCB->HCS_BIOS;
@@ -557,6 +555,8 @@
 #endif
 
 		init_tulip(pHCB, tul_scb + (i * tul_num_scb), tul_num_scb, pbBiosAdr, 10);
+		request_region(pHCB->HCS_Base, 256, "i91u"); /* Register */ 
+
 		pHCB->HCS_Index = i;	/* 7/29/98 */
 		hreg = scsi_register(tpnt, sizeof(HCS));
 		hreg->io_port = pHCB->HCS_Base;
@@ -1086,4 +1086,14 @@
 {
 	printk("\ni91u_panic: %s\n", msg);
 	panic("i91u panic");
+}
+
+/*
+ * Release ressources
+ */
+int i91u_release(struct Scsi_Host *hreg)
+{
+	free_irq(hreg->irq, hreg);
+	release_region(hreg->io_port, 256);
+	return 0;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/ini9100u.h linux.17p18/drivers/scsi/ini9100u.h
--- linux.vanilla/drivers/scsi/ini9100u.h	Wed May  3 22:31:20 2000
+++ linux.17p18/drivers/scsi/ini9100u.h	Thu Aug 17 18:11:50 2000
@@ -78,6 +78,7 @@
 #include "sd.h"
 
 extern int i91u_detect(Scsi_Host_Template *);
+extern int i91u_release(struct Scsi_Host *);
 extern int i91u_command(Scsi_Cmnd *);
 extern int i91u_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 extern int i91u_abort(Scsi_Cmnd *);
@@ -148,7 +149,7 @@
 	proc_info:	NULL,				\
 	name:		i91u_REVID, \
 	detect:		i91u_detect, \
-	release:	NULL, \
+	release:	i91u_release, \
 	info:		NULL,					\
 	command:	i91u_command, \
 	queuecommand:	i91u_queue, \
@@ -174,7 +175,9 @@
 #endif
 
 
+#ifndef VIRT_TO_BUS
 #define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#endif
 #define ULONG   unsigned long
 #define USHORT  unsigned short
 #define UCHAR   unsigned char
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/inia100.c linux.17p18/drivers/scsi/inia100.c
--- linux.vanilla/drivers/scsi/inia100.c	Fri Apr 21 12:46:28 2000
+++ linux.17p18/drivers/scsi/inia100.c	Tue Aug  1 07:59:56 2000
@@ -466,7 +466,6 @@
 		memset((unsigned char *) pHCB->HCS_virEscbArray, 0, sz);
 		pHCB->HCS_physEscbArray = (U32) VIRT_TO_BUS(pHCB->HCS_virEscbArray);
 
-		request_region(pHCB->HCS_Base, 0x100, "inia100");	/* Register */
 		get_orcPCIConfig(pHCB, i);
 
 		dBiosAdr = pHCB->HCS_BIOS;
@@ -480,6 +479,8 @@
 			printk("inia100: initial orchid fail!!\n");
 			return (0);
 		}
+		request_region(pHCB->HCS_Base, 256, "inia100");	/* Register */
+
 		hreg = scsi_register(tpnt, sizeof(ORC_HCS));
 		if (hreg == NULL) {
 			printk("Invalid scsi_register pointer.\n");
@@ -512,28 +513,28 @@
 		switch (i) {
 #if LINUX_VERSION_CODE >= CVT_LINUX_VERSION(1,3,0)
 		case 0:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr0, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 1:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr1, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 2:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr2, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 3:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr3, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 4:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr4, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 5:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr5, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 6:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr6, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		case 7:
-			ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", NULL);
+			ok = request_irq(pHCB->HCS_Intr, inia100_intr7, SA_INTERRUPT | SA_SHIRQ, "inia100", hreg);
 			break;
 		default:
 			inia100_panic("inia100: Too many host adapters\n");
@@ -936,5 +937,15 @@
 	printk("\ninia100_panic: %s\n", msg);
 	panic("inia100 panic");
 }
+
+/*
+ * Release ressources
+ */
+int inia100_release(struct Scsi_Host *hreg)
+{
+        free_irq(hreg->irq, hreg);
+        release_region(hreg->io_port, 256);
+        return 0;
+} 
 
 /*#include "inia100scsi.c" */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/inia100.h linux.17p18/drivers/scsi/inia100.h
--- linux.vanilla/drivers/scsi/inia100.h	Wed May  3 22:31:20 2000
+++ linux.17p18/drivers/scsi/inia100.h	Thu Aug 17 18:11:50 2000
@@ -71,6 +71,7 @@
 #include "sd.h"
 
 extern int inia100_detect(Scsi_Host_Template *);
+extern int inia100_release(struct Scsi_Host *);
 extern int inia100_command(Scsi_Cmnd *);
 extern int inia100_queue(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 extern int inia100_abort(Scsi_Cmnd *);
@@ -142,7 +143,7 @@
 	proc_info:	NULL,				\
 	name:		inia100_REVID, \
 	detect:		inia100_detect, \
-	release:	NULL, \
+	release:	inia100_release, \
 	info:		NULL,					\
 	command:	inia100_command, \
 	queuecommand:	inia100_queue, \
@@ -167,7 +168,9 @@
 #endif
 #endif
 
+#ifndef VIRT_TO_BUS
 #define VIRT_TO_BUS(i)  (unsigned int) virt_to_bus((void *)(i))
+#endif
 #define ULONG   unsigned long
 #define PVOID   void *
 #define USHORT  unsigned short
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/mac53c94.c linux.17p18/drivers/scsi/mac53c94.c
--- linux.vanilla/drivers/scsi/mac53c94.c	Fri Apr 21 12:46:28 2000
+++ linux.17p18/drivers/scsi/mac53c94.c	Tue Aug  1 07:59:56 2000
@@ -7,6 +7,7 @@
  * Paul Mackerras, August 1996.
  * Copyright (C) 1996 Paul Mackerras.
  */
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -542,3 +543,9 @@
 		return 0;
 	}
 }
+
+#ifdef MODULE
+Scsi_Host_Template driver_template = SCSI_MAC53C94;
+
+#include "scsi_module.c"
+#endif /* MODULE */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/mesh.c linux.17p18/drivers/scsi/mesh.c
--- linux.vanilla/drivers/scsi/mesh.c	Fri Apr 21 12:46:30 2000
+++ linux.17p18/drivers/scsi/mesh.c	Tue Aug  1 07:59:56 2000
@@ -8,6 +8,7 @@
  * Copyright (C) 1996 Paul Mackerras.
  */
 #include <linux/config.h>
+#include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
 #include <linux/types.h>
@@ -1910,6 +1911,12 @@
 		return 0;
 	}
 }
+
+#ifdef MODULE
+Scsi_Host_Template driver_template = SCSI_MESH;
+
+#include "scsi_module.c"
+#endif /* MODULE */
 
 #ifdef MESH_DBG
 static inline u32 readtb(void)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/ppa.c linux.17p18/drivers/scsi/ppa.c
--- linux.vanilla/drivers/scsi/ppa.c	Fri Apr 21 12:46:31 2000
+++ linux.17p18/drivers/scsi/ppa.c	Tue Aug  1 07:59:56 2000
@@ -125,7 +125,7 @@
     }
   retry_entry:
     for (i = 0; pb; i++, pb = pb->next) {
-	int modes, ppb;
+	int modes, ppb, ppb_hi;
 
 	ppa_hosts[i].dev =
 	    parport_register_device(pb, "ppa", NULL, ppa_wakeup,
@@ -150,6 +150,7 @@
 	    }
 	}
 	ppb = PPA_BASE(i) = ppa_hosts[i].dev->port->base;
+	ppb_hi =  ppa_hosts[i].dev->port->base_hi;
 	w_ctr(ppb, 0x0c);
 	modes = ppa_hosts[i].dev->port->modes;
 
@@ -162,11 +163,11 @@
 	    ppa_hosts[i].mode = PPA_PS2;
 
 	if (modes & PARPORT_MODE_PCECPPS2) {
-	    w_ecr(ppb, 0x20);
+	    w_ecr(ppb_hi, 0x20);
 	    ppa_hosts[i].mode = PPA_PS2;
 	}
 	if (modes & PARPORT_MODE_PCECPEPP)
-	    w_ecr(ppb, 0x80);
+	    w_ecr(ppb_hi, 0x80);
 
 	/* Done configuration */
 	ppa_pb_release(i);
@@ -322,8 +323,7 @@
 }
 
 /*
- * output a string, in whatever mode is available, according to the
- * PPA protocol. 
+ * Clear EPP Timeout Bit 
  */
 static inline void epp_reset(unsigned short ppb)
 {
@@ -334,19 +334,23 @@
     w_str(ppb, i & 0xfe);
 }
 
-static inline void ecp_sync(unsigned short ppb)
+/* 
+ * Wait for empty ECP fifo (if we are in ECP fifo mode only)
+ */
+static inline void ecp_sync(unsigned short hostno)
 {
-    int i;
+    int i, ppb_hi=ppa_hosts[hostno].dev->port->base_hi;
 
-    if ((r_ecr(ppb) & 0xe0) != 0x80)
-	return;
+    if (ppb_hi == 0) return;
 
-    for (i = 0; i < 100; i++) {
-	if (r_ecr(ppb) & 0x01)
-	    return;
-	udelay(5);
+    if ((r_ecr(ppb_hi) & 0xe0) == 0x60) { /* mode 011 == ECP fifo mode */
+        for (i = 0; i < 100; i++) {
+            if (r_ecr(ppb_hi) & 0x01)
+                return;
+            udelay(5);
+        }
+        printk("ppa: ECP sync failed as data still present in FIFO.\n");
     }
-    printk("ppa: ECP sync failed as data still present in FIFO.\n");
 }
 
 static int ppa_byte_out(unsigned short base, const char *buffer, int len)
@@ -421,7 +425,7 @@
 	w_ctr(ppb, 0xc);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0xc);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
@@ -474,7 +478,7 @@
 	w_ctr(ppb, 0x2c);
 	r = !(r_str(ppb) & 0x01);
 	w_ctr(ppb, 0x2c);
-	ecp_sync(ppb);
+	ecp_sync(host_no);
 	break;
 
     default:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/ppa.h linux.17p18/drivers/scsi/ppa.h
--- linux.vanilla/drivers/scsi/ppa.h	Wed May  3 22:31:20 2000
+++ linux.17p18/drivers/scsi/ppa.h	Thu Aug 17 18:11:50 2000
@@ -117,14 +117,15 @@
 #define r_str(x)        (unsigned char)inb((x)+1)
 #define r_ctr(x)        (unsigned char)inb((x)+2)
 #define r_epp(x)        (unsigned char)inb((x)+4)
-#define r_fifo(x)       (unsigned char)inb((x)+0x400)
-#define r_ecr(x)        (unsigned char)inb((x)+0x402)
+#define r_fifo(x)       (unsigned char)inb((x)) /* x must be base_hi */
+					/* On PCI is base+0x400 != base_hi */
+#define r_ecr(x)        (unsigned char)inb((x)+0x2) /* x must be base_hi */
 
 #define w_dtr(x,y)      outb(y, (x))
 #define w_str(x,y)      outb(y, (x)+1)
 #define w_epp(x,y)      outb(y, (x)+4)
-#define w_fifo(x,y)     outb(y, (x)+0x400)
-#define w_ecr(x,y)      outb(y, (x)+0x402)
+#define w_fifo(x,y)     outb(y, (x))	/* x must be base_hi */
+#define w_ecr(x,y)      outb(y, (x)+0x2)/* x must be base_hi */
 
 #ifdef CONFIG_SCSI_IZIP_SLOW_CTR
 #define w_ctr(x,y)      outb_p(y, (x)+2)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/qlogicfc.c linux.17p18/drivers/scsi/qlogicfc.c
--- linux.vanilla/drivers/scsi/qlogicfc.c	Fri Apr 21 12:46:31 2000
+++ linux.17p18/drivers/scsi/qlogicfc.c	Mon Aug 14 20:16:17 2000
@@ -867,7 +867,7 @@
 
 	short param[8];
 	int i, j;
-	struct id_name_map temp[QLOGICFC_MAX_ID + 1];
+	static struct id_name_map temp[QLOGICFC_MAX_ID + 1];
 	struct isp2x00_hostdata *hostdata;
 
 	isp2x00_disable_irqs(host);
@@ -1904,9 +1904,9 @@
 #endif
 
 	hostdata->wwn = (u64) (hostdata->control_block.node_name[0]) << 56;
-	hostdata->wwn |= (u64) (hostdata->control_block.node_name[0] & 0xff00) << 48;
+	hostdata->wwn |= (u64) (hostdata->control_block.node_name[0] & 0xff00) << 40;
+	hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0x00ff) << 40;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0xff00) << 24;
-	hostdata->wwn |= (u64) (hostdata->control_block.node_name[1] & 0x00ff) << 48;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0x00ff) << 24;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[2] & 0xff00) << 8;
 	hostdata->wwn |= (u64) (hostdata->control_block.node_name[3] & 0x00ff) << 8;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/scsi.c linux.17p18/drivers/scsi/scsi.c
--- linux.vanilla/drivers/scsi/scsi.c	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/scsi/scsi.c	Tue Aug  1 07:59:56 2000
@@ -307,7 +307,11 @@
 {"MATSHITA","PD-1","*", BLIST_FORCELUN | BLIST_SINGLELUN},
 {"iomega","jaz 1GB","J.86", BLIST_NOTQ | BLIST_NOLUN},
 {"TOSHIBA","CDROM","*", BLIST_ISROM},
-{"MegaRAID", "LD", "*", BLIST_FORCELUN},
+{"MegaRAID", "LD", "*", BLIST_FORCELUN},     /* Multiple luns always safe (logical raid vols) */
+{"DGC",  "RAID",      "*", BLIST_SPARSELUN}, /* Dell PV 650F (tgt @ LUN 0) */
+{"DGC",  "DISK",      "*", BLIST_SPARSELUN}, /* Dell PV 650F (no tgt @ LUN 0) */
+{"DELL", "PV530F",    "*", BLIST_SPARSELUN}, /* Dell PV 530F */
+{"SONY", "TSL",       "*", BLIST_FORCELUN},  /* DDS3 & DDS4 autoloaders */
 /*
  * Must be at end of list...
  */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/scsi_error.c linux.17p18/drivers/scsi/scsi_error.c
--- linux.vanilla/drivers/scsi/scsi_error.c	Fri Apr 21 12:46:31 2000
+++ linux.17p18/drivers/scsi/scsi_error.c	Tue Aug  1 07:59:56 2000
@@ -1941,7 +1941,11 @@
 	current->pgrp = 1;
 	
 	/* Become as one with the init task */
-	
+
+ 	exit_files(current);
+	current->files = init_task.files;
+	atomic_inc(&current->files->count);
+ 		
 	exit_fs(current);	/* current->fs->count--; */
 	fs = init_task.fs;
 	current->fs = fs;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/scsi_ioctl.c linux.17p18/drivers/scsi/scsi_ioctl.c
--- linux.vanilla/drivers/scsi/scsi_ioctl.c	Fri Apr 21 12:46:31 2000
+++ linux.17p18/drivers/scsi/scsi_ioctl.c	Tue Aug  1 07:59:56 2000
@@ -403,6 +403,7 @@
 	return ioctl_probe(dev->host, arg);
     case SCSI_IOCTL_SEND_COMMAND:
 	if(!capable(CAP_SYS_ADMIN))  return -EACCES;
+	if(!capable(CAP_SYS_RAWIO))  return -EACCES;
 	return scsi_ioctl_send_command((Scsi_Device *) dev,
 				       (Scsi_Ioctl_Command *) arg);
     case SCSI_IOCTL_DOORLOCK:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/sg.c linux.17p18/drivers/scsi/sg.c
--- linux.vanilla/drivers/scsi/sg.c	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/scsi/sg.c	Tue Aug  1 07:59:56 2000
@@ -16,8 +16,8 @@
  *
  *  Borrows code from st driver. Thanks to Alessandro Rubini's "dd" book.
  */
- static char * sg_version_str = "Version: 2.1.38 (20000527)";
- static int sg_version_num = 20138; /* 2 digits for each component */
+ static char * sg_version_str = "Version: 2.1.39 (20000626)";
+ static int sg_version_num = 20139; /* 2 digits for each component */
 /*
  *  D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au), notes:
  *      - scsi logging is available via SCSI_LOG_TIMEOUT macros. First
@@ -1376,9 +1376,9 @@
     Sg_scatter_hold * req_schp = &srp->data;
     Sg_scatter_hold * rsv_schp = &sfp->reserve;
 
+    srp->res_used = 1;
     SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size)); 
-    /* round request up to next highest SG_SECTOR_SZ byte boundary */
-    size = (size + SG_SECTOR_MSK) & (~SG_SECTOR_MSK);
+    size = (size + 1) & (~1);   /* round to even for aha1542 */
     if (rsv_schp->use_sg > 0) {
         int k, num;
         int rem = size;
@@ -1387,22 +1387,26 @@
         for (k = 0; k < rsv_schp->use_sg; ++k, ++sclp) {
             num = (int)sclp->length;
             if (rem <= num) {
-                sfp->save_scat_len = num;
-                sclp->length = (unsigned)rem;
+                if (0 == k) {
+                    req_schp->use_sg = 0;
+                    req_schp->buffer = sclp->address;
+                }
+                else {
+                    sfp->save_scat_len = num;
+                    sclp->length = (unsigned)rem;
+                    req_schp->use_sg = k + 1;
+                    req_schp->sglist_len = rsv_schp->sglist_len;
+                    req_schp->buffer = rsv_schp->buffer;
+                }
+                req_schp->bufflen = size;
+                req_schp->mem_src = rsv_schp->mem_src;
+                req_schp->b_malloc_len = rsv_schp->b_malloc_len;
                 break;
             }
             else
                 rem -= num;
         }
-        if (k < rsv_schp->use_sg) {
-            req_schp->use_sg = k + 1;   /* adjust scatter list length */
-            req_schp->bufflen = size;
-            req_schp->sglist_len = rsv_schp->sglist_len;
-            req_schp->buffer = rsv_schp->buffer;
-            req_schp->mem_src = rsv_schp->mem_src;
-            req_schp->b_malloc_len = rsv_schp->b_malloc_len;
-        }
-        else
+        if (k >= rsv_schp->use_sg)
             SCSI_LOG_TIMEOUT(1, printk("sg_link_reserve: BAD size\n")); 
     }
     else {
@@ -1410,10 +1414,8 @@
         req_schp->bufflen = size;
         req_schp->buffer = rsv_schp->buffer;
         req_schp->mem_src = rsv_schp->mem_src;
-        req_schp->use_sg = rsv_schp->use_sg;
         req_schp->b_malloc_len = rsv_schp->b_malloc_len;
     }
-    srp->res_used = 1;
 }
 
 static void sg_unlink_reserve(Sg_fd * sfp, Sg_request * srp)
@@ -1423,7 +1425,7 @@
 
     SCSI_LOG_TIMEOUT(4, printk("sg_unlink_reserve: req->use_sg=%d\n",
                                (int)req_schp->use_sg)); 
-    if (rsv_schp->use_sg > 0) {
+    if ((rsv_schp->use_sg > 0) && (req_schp->use_sg > 0)) {
         struct scatterlist * sclp = (struct scatterlist *)rsv_schp->buffer;
 
         if (sfp->save_scat_len > 0) 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/sr_ioctl.c linux.17p18/drivers/scsi/sr_ioctl.c
--- linux.vanilla/drivers/scsi/sr_ioctl.c	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/scsi/sr_ioctl.c	Tue Aug  1 07:59:56 2000
@@ -365,6 +365,98 @@
 	
         break;
     }
+	case CDROMVOLCTRL: {
+		char * buffer, * mask;
+		struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+	
+	/* First we get the current params so we can just twiddle the volume */
+		sr_cmd[0] = MODE_SENSE;
+		sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
+		sr_cmd[2] = 0xe;    /* Want mode page 0xe, CDROM audio params */
+		sr_cmd[3] = 0;
+		sr_cmd[4] = 28;
+		sr_cmd[5] = 0;
+	
+		if ((buffer = (unsigned char *) scsi_malloc(512)) == NULL)
+			return -ENOMEM;
+	
+		if ((result = sr_do_ioctl(target, sr_cmd, buffer, 28, 0))) {
+			printk ("Hosed while obtaining audio mode page\n");
+			scsi_free(buffer, 512);
+			break;
+		}
+	
+		sr_cmd[0] = MODE_SENSE;
+		sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
+		sr_cmd[2] = 0x4e;   /* Want the mask for mode page 0xe */
+		sr_cmd[3] = 0;
+		sr_cmd[4] = 28;
+		sr_cmd[5] = 0;
+	
+		mask = (unsigned char *) scsi_malloc(512);
+		if(!mask) {
+			scsi_free(buffer, 512);
+			result = -ENOMEM;
+			break;
+		}
+
+		if ((result = sr_do_ioctl (target, sr_cmd, mask, 28, 0))) {
+			printk("Hosed obtaining mask for audio mode page\n");
+			scsi_free(buffer, 512);
+			scsi_free(mask, 512);
+			break;
+		}
+	
+		/* Now mask and substitute our own volume and reuse the rest */
+		buffer[0] = 0;  /* Clear reserved field */
+	
+		buffer[21] = volctrl->channel0 & mask[21];
+		buffer[23] = volctrl->channel1 & mask[23];
+		buffer[25] = volctrl->channel2 & mask[25];
+		buffer[27] = volctrl->channel3 & mask[27];
+	
+		sr_cmd[0] = MODE_SELECT;
+		sr_cmd[1] = ((scsi_CDs[target].device -> lun) << 5) | 0x10;    /* Params are SCSI-2 */
+		sr_cmd[2] = sr_cmd[3] = 0;
+		sr_cmd[4] = 28;
+		sr_cmd[5] = 0;
+	
+		result = sr_do_ioctl (target, sr_cmd, buffer, 28, 0);
+		scsi_free(buffer, 512);
+		scsi_free(mask, 512);
+		break;
+	}
+	
+	case CDROMVOLREAD: {
+		char * buffer;
+		struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg;
+	
+		/* Get the current params */
+	
+		sr_cmd[0] = MODE_SENSE;
+		sr_cmd[1] = (scsi_CDs[target].device -> lun) << 5;
+		sr_cmd[2] = 0xe;    /* Want mode page 0xe, CDROM audio params */
+		sr_cmd[3] = 0;
+		sr_cmd[4] = 28;
+		sr_cmd[5] = 0;
+	
+		if ((buffer = (unsigned char *) scsi_malloc(512)) == NULL)
+			return -ENOMEM;
+	
+		if ((result = sr_do_ioctl (target, sr_cmd, buffer, 28, 0))) {
+			printk("(CDROMVOLREAD) Hosed while obtaining audio mode page\n");
+			scsi_free(buffer, 512);
+			break;
+		}
+
+		volctrl->channel0 = buffer[21];
+		volctrl->channel1 = buffer[23];
+		volctrl->channel2 = buffer[25];
+		volctrl->channel3 = buffer[27];
+
+		scsi_free(buffer, 512);
+		break;
+	}
 
     default:
         return -EINVAL;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/st.c linux.17p18/drivers/scsi/st.c
--- linux.vanilla/drivers/scsi/st.c	Fri Apr 21 12:46:32 2000
+++ linux.17p18/drivers/scsi/st.c	Tue Aug  1 07:59:56 2000
@@ -11,7 +11,7 @@
   Copyright 1992 - 2000 Kai Makisara
 		 email Kai.Makisara@metla.fi
 
-  Last modified: Wed Feb  2 22:04:05 2000 by makisara@kai.makisara.local
+  Last modified: Sat Jun 17 17:29:35 2000 by makisara@kai.makisara.local
   Some small formal changes - aeb, 950809
 */
 
@@ -896,7 +896,7 @@
 scsi_tape_flush(struct file * filp)
 {
     int result = 0, result2;
-    static unsigned char cmd[10];
+    unsigned char cmd[10];
     Scsi_Cmnd * SCpnt;
     Scsi_Tape * STp;
     ST_mode * STm;
@@ -1060,7 +1060,7 @@
     ssize_t i, do_count, blks, retval, transfer;
     int write_threshold;
     int doing_write = 0;
-    static unsigned char cmd[10];
+    unsigned char cmd[10];
     const char *b_point;
     Scsi_Cmnd * SCpnt = NULL;
     Scsi_Tape * STp;
@@ -1380,7 +1380,7 @@
 read_tape(struct inode *inode, long count, Scsi_Cmnd **aSCpnt)
 {
     int transfer, blks, bytes;
-    static unsigned char cmd[10];
+    unsigned char cmd[10];
     Scsi_Cmnd *SCpnt;
     Scsi_Tape *STp;
     ST_mode * STm;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/sym53c8xx.c linux.17p18/drivers/scsi/sym53c8xx.c
--- linux.vanilla/drivers/scsi/sym53c8xx.c	Fri Apr 21 12:46:33 2000
+++ linux.17p18/drivers/scsi/sym53c8xx.c	Tue Aug  1 07:59:56 2000
@@ -4180,7 +4180,7 @@
 	**	64 bit (53C896) ?
 	*/
 	if (np->features & FE_64BIT)
-#if BITS_PER_LONG > 32
+#ifdef SCSI_NCR_USE_64BIT_DAC
 		np->rv_ccntl1	|= (XTIMOD | EXTIBMV);
 #else
 		np->rv_ccntl1	|= (DDAC);
@@ -9021,7 +9021,7 @@
 **	code will get more complex later).
 */
 
-#if BITS_PER_LONG > 32
+#ifdef SCSI_NCR_USE_64BIT_DAC
 #define SCATTER_ONE(data, badd, len)					\
 	(data)->addr = cpu_to_scr(badd);				\
 	(data)->size = cpu_to_scr((((badd) >> 8) & 0xff000000) + len);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/scsi/tmscsim.c linux.17p18/drivers/scsi/tmscsim.c
--- linux.vanilla/drivers/scsi/tmscsim.c	Fri Apr 21 12:46:33 2000
+++ linux.17p18/drivers/scsi/tmscsim.c	Tue Aug  1 07:59:56 2000
@@ -165,6 +165,7 @@
 #include "constants.h"
 #include "sd.h"
 #include <linux/stat.h>
+#include <scsi/scsicam.h>
 
 #include "dc390.h"
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/Config.in linux.17p18/drivers/sound/Config.in
--- linux.vanilla/drivers/sound/Config.in	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/sound/Config.in	Mon Aug 14 18:50:09 2000
@@ -17,6 +17,9 @@
   fi
 fi
 
+dep_tristate 'Crystal CS4281' CONFIG_SOUND_CS4281 $CONFIG_SOUND
+dep_tristate 'Crystal SoundFusion (CS461x)' CONFIG_SOUND_FUSION $CONFIG_SOUND
+dep_tristate 'Creative SBLive! (EMU10K1)' CONFIG_SOUND_EMU10K1 $CONFIG_SOUND
 dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
 if [ "$CONFIG_SOUND_ES1370" = "y" ]; then
    bool 'Joystick support at boot time' CONFIG_SOUND_ES1370_JOYPORT_BOOT
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/Hwmcode.h linux.17p18/drivers/sound/Hwmcode.h
--- linux.vanilla/drivers/sound/Hwmcode.h	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/sound/Hwmcode.h	Thu Jan  1 01:00:00 1970
@@ -1,804 +0,0 @@
-//=============================================================================
-// Copyright (c) 1997	Yamaha Corporation.	All Rights Reserved.
-//
-//	Title:
-//		hwmcode.c
-//	Desc:
-//		micro-code for CTRL & DSP
-//	HISTORY:
-//		April 03, 1997:		1st try by M. Mukojima
-//=============================================================================
-#define	YDSXG_DSPLENGTH				0x0080
-#define	YDSXG_CTRLLENGTH			0x3000
-
-
-static unsigned long int	gdwDSPCode[YDSXG_DSPLENGTH >> 2] = {
-	0x00000081, 0x000001a4, 0x0000000a, 0x0000002f,
-	0x00080253, 0x01800317, 0x0000407b, 0x0000843f,
-	0x0001483c, 0x0001943c, 0x0005d83c, 0x00001c3c,
-	0x0000c07b, 0x00050c3f, 0x0121503c, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x00000000
-};
-
-
-// --------------------------------------------
-//  DS-1E Controller InstructionRAM Code
-//	1999/06/21
-//	Buf441 slot is Enabled.
-// --------------------------------------------
-// 04/09�@creat
-// 04/12  stop nise fix
-// 06/21�@WorkingOff timming
-static unsigned long	gdwCtrl1eCode[YDSXG_CTRLLENGTH >> 2] = {
-	0x000007, 0x240007, 0x0C0007, 0x1C0007,
-	0x060007, 0x700002, 0x000020, 0x030040,
-	0x007104, 0x004286, 0x030040, 0x000F0D,
-	0x000810, 0x20043A, 0x000282, 0x00020D,
-	0x000810, 0x20043A, 0x001282, 0x200E82,
-	0x00800D, 0x000810, 0x20043A, 0x001A82,
-	0x03460D, 0x000810, 0x10043A, 0x02EC0D,
-	0x000810, 0x18043A, 0x00010D, 0x020015,
-	0x0000FD, 0x000020, 0x038860, 0x039060,
-	0x038060, 0x038040, 0x038040, 0x038040,
-	0x018040, 0x000A7D, 0x038040, 0x038040,
-	0x018040, 0x200402, 0x000882, 0x08001A,
-	0x000904, 0x017186, 0x000007, 0x260007,
-	0x400007, 0x000007, 0x03258D, 0x000810,
-	0x18043A, 0x260007, 0x284402, 0x00087D,
-	0x018042, 0x00160A, 0x05A206, 0x000007,
-	0x440007, 0x00230D, 0x000810, 0x08043A,
-	0x22FA06, 0x000007, 0x0007FD, 0x018042,
-	0x08000A, 0x000904, 0x02AB86, 0x000195,
-	0x090D04, 0x000007, 0x000820, 0x0000F5,
-	0x000B7D, 0x01F060, 0x0000FD, 0x033A06,
-	0x018040, 0x000A7D, 0x038042, 0x13804A,
-	0x18000A, 0x001820, 0x059060, 0x058860,
-	0x018040, 0x0000FD, 0x018042, 0x70000A,
-	0x000115, 0x071144, 0x033B86, 0x030000,
-	0x007020, 0x036206, 0x018040, 0x00360D,
-	0x000810, 0x08043A, 0x232206, 0x000007,
-	0x02EC0D, 0x000810, 0x18043A, 0x019A06,
-	0x000007, 0x240007, 0x000F8D, 0x000810,
-	0x00163A, 0x002402, 0x005C02, 0x0028FD,
-	0x000020, 0x018040, 0x08000D, 0x000815,
-	0x510984, 0x000007, 0x00004D, 0x000E5D,
-	0x000E02, 0x00430D, 0x000810, 0x08043A,
-	0x2E1206, 0x000007, 0x00008D, 0x000924,
-	0x000F02, 0x00470D, 0x000810, 0x08043A,
-	0x2E1206, 0x000007, 0x480480, 0x001210,
-	0x28043A, 0x00778D, 0x000810, 0x280C3A,
-	0x00068D, 0x000810, 0x28143A, 0x284402,
-	0x03258D, 0x000810, 0x18043A, 0x07FF8D,
-	0x000820, 0x0002FD, 0x018040, 0x260007,
-	0x200007, 0x0002FD, 0x018042, 0x08000A,
-	0x000904, 0x051286, 0x000007, 0x240007,
-	0x02EC0D, 0x000810, 0x18043A, 0x00387D,
-	0x018042, 0x08000A, 0x001015, 0x010984,
-	0x019B86, 0x000007, 0x01B206, 0x000007,
-	0x0008FD, 0x018042, 0x18000A, 0x001904,
-	0x22B886, 0x280007, 0x001810, 0x28043A,
-	0x280C02, 0x00000D, 0x000810, 0x28143A,
-	0x08808D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00020D, 0x189904, 0x000007,
-	0x00402D, 0x0000BD, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x065A86, 0x000007,
-	0x000100, 0x000A20, 0x00047D, 0x018040,
-	0x018042, 0x20000A, 0x003015, 0x012144,
-	0x036186, 0x000007, 0x002104, 0x036186,
-	0x000007, 0x000F8D, 0x000810, 0x280C3A,
-	0x023944, 0x07C986, 0x000007, 0x001810,
-	0x28043A, 0x08810D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x002810, 0x78003A,
-	0x00788D, 0x000810, 0x08043A, 0x2A1206,
-	0x000007, 0x00400D, 0x001015, 0x189904,
-	0x292904, 0x393904, 0x000007, 0x070206,
-	0x000007, 0x0004F5, 0x00007D, 0x000020,
-	0x00008D, 0x010860, 0x018040, 0x00047D,
-	0x038042, 0x21804A, 0x18000A, 0x021944,
-	0x229086, 0x000007, 0x004075, 0x71F104,
-	0x000007, 0x010042, 0x28000A, 0x002904,
-	0x225886, 0x000007, 0x003C0D, 0x30A904,
-	0x000007, 0x00077D, 0x018042, 0x08000A,
-	0x000904, 0x08DA86, 0x00057D, 0x002820,
-	0x03B060, 0x08F206, 0x018040, 0x003020,
-	0x03A860, 0x018040, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x08FA86, 0x000007,
-	0x00057D, 0x018042, 0x28040A, 0x000E8D,
-	0x000810, 0x280C3A, 0x00000D, 0x000810,
-	0x28143A, 0x09000D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x003DFD, 0x000020,
-	0x018040, 0x00107D, 0x009D8D, 0x000810,
-	0x08043A, 0x2A1206, 0x000007, 0x000815,
-	0x08001A, 0x010984, 0x0A5186, 0x00137D,
-	0x200500, 0x280F20, 0x338F60, 0x3B8F60,
-	0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-	0x038A60, 0x018040, 0x00107D, 0x018042,
-	0x08000A, 0x000215, 0x010984, 0x3A8186,
-	0x000007, 0x007FBD, 0x383DC4, 0x000007,
-	0x001A7D, 0x001375, 0x018042, 0x09004A,
-	0x10000A, 0x0B8D04, 0x139504, 0x000007,
-	0x000820, 0x019060, 0x001104, 0x225886,
-	0x010040, 0x0017FD, 0x018042, 0x08000A,
-	0x000904, 0x225A86, 0x000007, 0x00197D,
-	0x038042, 0x09804A, 0x10000A, 0x000924,
-	0x001664, 0x0011FD, 0x038042, 0x2B804A,
-	0x19804A, 0x00008D, 0x218944, 0x000007,
-	0x002244, 0x0C1986, 0x000007, 0x001A64,
-	0x002A24, 0x00197D, 0x080102, 0x100122,
-	0x000820, 0x039060, 0x018040, 0x003DFD,
-	0x00008D, 0x000820, 0x018040, 0x001375,
-	0x001A7D, 0x010042, 0x09804A, 0x10000A,
-	0x00021D, 0x0189E4, 0x2992E4, 0x309144,
-	0x000007, 0x00060D, 0x000A15, 0x000C1D,
-	0x001025, 0x00A9E4, 0x012BE4, 0x000464,
-	0x01B3E4, 0x0232E4, 0x000464, 0x000464,
-	0x000464, 0x000464, 0x00040D, 0x08B1C4,
-	0x000007, 0x000820, 0x000BF5, 0x030040,
-	0x00197D, 0x038042, 0x09804A, 0x000A24,
-	0x08000A, 0x080E64, 0x000007, 0x100122,
-	0x000820, 0x031060, 0x010040, 0x0064AC,
-	0x00027D, 0x000020, 0x018040, 0x00107D,
-	0x018042, 0x0011FD, 0x3B804A, 0x09804A,
-	0x20000A, 0x000095, 0x1A1144, 0x00A144,
-	0x0E5886, 0x00040D, 0x00B984, 0x0E5986,
-	0x0018FD, 0x018042, 0x0010FD, 0x09804A,
-	0x28000A, 0x000095, 0x010924, 0x002A64,
-	0x0E4986, 0x000007, 0x002904, 0x0E5A86,
-	0x000007, 0x0E6206, 0x080002, 0x00008D,
-	0x00387D, 0x000820, 0x018040, 0x00127D,
-	0x018042, 0x10000A, 0x003904, 0x0F0986,
-	0x00080D, 0x7FFFB5, 0x00B984, 0x0ED986,
-	0x000025, 0x0FB206, 0x00002D, 0x000015,
-	0x00082D, 0x02E00D, 0x000820, 0x0FFA06,
-	0x00000D, 0x7F8035, 0x00B984, 0x0FA986,
-	0x400025, 0x00008D, 0x110944, 0x000007,
-	0x00018D, 0x109504, 0x000007, 0x009164,
-	0x000424, 0x000424, 0x000424, 0x100102,
-	0x280002, 0x02DF0D, 0x000820, 0x0FFA06,
-	0x00018D, 0x00042D, 0x00008D, 0x109504,
-	0x000007, 0x00020D, 0x109184, 0x000007,
-	0x02DF8D, 0x000820, 0x00008D, 0x0038FD,
-	0x018040, 0x003BFD, 0x001020, 0x03A860,
-	0x000815, 0x313184, 0x212184, 0x000007,
-	0x03B060, 0x03A060, 0x018040, 0x0022FD,
-	0x000095, 0x010924, 0x000424, 0x000424,
-	0x001264, 0x100102, 0x000820, 0x039060,
-	0x018040, 0x001924, 0x010F0D, 0x00397D,
-	0x000820, 0x058040, 0x038042, 0x09844A,
-	0x000606, 0x08040A, 0x000424, 0x000424,
-	0x00117D, 0x018042, 0x08000A, 0x000A24,
-	0x280502, 0x280C02, 0x09800D, 0x000820,
-	0x0002FD, 0x018040, 0x200007, 0x0022FD,
-	0x018042, 0x08000A, 0x000095, 0x280DC4,
-	0x011924, 0x00197D, 0x018042, 0x0011FD,
-	0x09804A, 0x10000A, 0x0000B5, 0x113144,
-	0x0A8D04, 0x000007, 0x080A44, 0x129504,
-	0x000007, 0x0023FD, 0x001020, 0x038040,
-	0x101244, 0x000007, 0x000820, 0x039060,
-	0x018040, 0x0002FD, 0x018042, 0x08000A,
-	0x000904, 0x123286, 0x000007, 0x003BFD,
-	0x000100, 0x000A10, 0x0B807A, 0x13804A,
-	0x090984, 0x000007, 0x000095, 0x013D04,
-	0x12B886, 0x10000A, 0x100002, 0x090984,
-	0x000007, 0x038042, 0x11804A, 0x090D04,
-	0x000007, 0x10000A, 0x090D84, 0x000007,
-	0x00257D, 0x000820, 0x018040, 0x00010D,
-	0x000810, 0x28143A, 0x00127D, 0x018042,
-	0x20000A, 0x00197D, 0x018042, 0x00117D,
-	0x31804A, 0x10000A, 0x003124, 0x013B8D,
-	0x00397D, 0x000820, 0x058040, 0x038042,
-	0x09844A, 0x000606, 0x08040A, 0x300102,
-	0x003124, 0x000424, 0x000424, 0x001224,
-	0x280502, 0x001A4C, 0x143986, 0x700002,
-	0x00002D, 0x030000, 0x00387D, 0x018042,
-	0x10000A, 0x146206, 0x002124, 0x0000AD,
-	0x100002, 0x00010D, 0x000924, 0x006B24,
-	0x014A0D, 0x00397D, 0x000820, 0x058040,
-	0x038042, 0x09844A, 0x000606, 0x08040A,
-	0x003264, 0x00008D, 0x000A24, 0x001020,
-	0x00227D, 0x018040, 0x014F8D, 0x000810,
-	0x08043A, 0x2B5A06, 0x000007, 0x002820,
-	0x00207D, 0x018040, 0x00117D, 0x038042,
-	0x13804A, 0x33800A, 0x00387D, 0x018042,
-	0x08000A, 0x000904, 0x177286, 0x000007,
-	0x00008D, 0x030964, 0x015B0D, 0x00397D,
-	0x000820, 0x058040, 0x038042, 0x09844A,
-	0x000606, 0x08040A, 0x380102, 0x000424,
-	0x000424, 0x001224, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x15DA86, 0x000007,
-	0x280502, 0x001A4C, 0x177186, 0x000007,
-	0x032164, 0x00632C, 0x003DFD, 0x018042,
-	0x08000A, 0x000095, 0x090904, 0x000007,
-	0x000820, 0x001A4C, 0x169986, 0x018040,
-	0x030000, 0x16B206, 0x002124, 0x00010D,
-	0x000924, 0x006B24, 0x016F0D, 0x00397D,
-	0x000820, 0x058040, 0x038042, 0x09844A,
-	0x000606, 0x08040A, 0x003A64, 0x000095,
-	0x001224, 0x0002FD, 0x018042, 0x08000A,
-	0x000904, 0x171286, 0x000007, 0x01760D,
-	0x000810, 0x08043A, 0x2B5A06, 0x000007,
-	0x160A06, 0x000007, 0x007020, 0x08010A,
-	0x10012A, 0x0020FD, 0x038860, 0x039060,
-	0x018040, 0x00227D, 0x018042, 0x003DFD,
-	0x08000A, 0x31844A, 0x000904, 0x181086,
-	0x18008B, 0x00008D, 0x189904, 0x00312C,
-	0x18E206, 0x000007, 0x00324C, 0x186B86,
-	0x000007, 0x001904, 0x186886, 0x000007,
-	0x000095, 0x199144, 0x00222C, 0x003124,
-	0x00636C, 0x000E3D, 0x001375, 0x000BFD,
-	0x010042, 0x09804A, 0x10000A, 0x038AEC,
-	0x0393EC, 0x00224C, 0x18E186, 0x000007,
-	0x00008D, 0x189904, 0x00226C, 0x00322C,
-	0x30050A, 0x301DAB, 0x002083, 0x0018FD,
-	0x018042, 0x08000A, 0x018924, 0x300502,
-	0x001083, 0x001875, 0x010042, 0x10000A,
-	0x00008D, 0x010924, 0x001375, 0x330542,
-	0x330CCB, 0x332CCB, 0x3334CB, 0x333CCB,
-	0x3344CB, 0x334CCB, 0x3354CB, 0x305C8B,
-	0x006083, 0x0002F5, 0x010042, 0x08000A,
-	0x000904, 0x19B286, 0x000007, 0x001E2D,
-	0x0005FD, 0x018042, 0x08000A, 0x028924,
-	0x280502, 0x00060D, 0x000810, 0x280C3A,
-	0x00008D, 0x000810, 0x28143A, 0x0A808D,
-	0x000820, 0x0002F5, 0x010040, 0x220007,
-	0x001275, 0x030042, 0x21004A, 0x00008D,
-	0x1A0944, 0x000007, 0x01AB8D, 0x000810,
-	0x08043A, 0x2CAA06, 0x000007, 0x0001F5,
-	0x030042, 0x0D004A, 0x10000A, 0x089144,
-	0x000007, 0x000820, 0x010040, 0x0025F5,
-	0x0A3144, 0x000007, 0x000820, 0x032860,
-	0x030040, 0x00217D, 0x038042, 0x0B804A,
-	0x10000A, 0x000820, 0x031060, 0x030040,
-	0x00008D, 0x000124, 0x00012C, 0x000E64,
-	0x001A64, 0x00636C, 0x08010A, 0x10012A,
-	0x000820, 0x031060, 0x030040, 0x0020FD,
-	0x018042, 0x08000A, 0x00227D, 0x018042,
-	0x10000A, 0x000820, 0x031060, 0x030040,
-	0x00197D, 0x018042, 0x08000A, 0x0022FD,
-	0x038042, 0x10000A, 0x000820, 0x031060,
-	0x030040, 0x090D04, 0x000007, 0x000820,
-	0x030040, 0x038042, 0x0B804A, 0x10000A,
-	0x000820, 0x031060, 0x030040, 0x038042,
-	0x13804A, 0x19804A, 0x110D04, 0x198D04,
-	0x000007, 0x08000A, 0x001020, 0x031860,
-	0x030860, 0x030040, 0x00008D, 0x0B0944,
-	0x000007, 0x000820, 0x010040, 0x0005F5,
-	0x030042, 0x08000A, 0x000820, 0x010040,
-	0x0000F5, 0x010042, 0x08000A, 0x000904,
-	0x1D9886, 0x001E75, 0x030042, 0x01044A,
-	0x000C0A, 0x1DAA06, 0x000007, 0x000402,
-	0x000C02, 0x00177D, 0x001AF5, 0x018042,
-	0x03144A, 0x031C4A, 0x03244A, 0x032C4A,
-	0x03344A, 0x033C4A, 0x03444A, 0x004C0A,
-	0x00043D, 0x0013F5, 0x001AFD, 0x030042,
-	0x0B004A, 0x1B804A, 0x13804A, 0x20000A,
-	0x089144, 0x19A144, 0x0389E4, 0x0399EC,
-	0x005502, 0x005D0A, 0x030042, 0x0B004A,
-	0x1B804A, 0x13804A, 0x20000A, 0x089144,
-	0x19A144, 0x0389E4, 0x0399EC, 0x006502,
-	0x006D0A, 0x030042, 0x0B004A, 0x19004A,
-	0x2B804A, 0x13804A, 0x21804A, 0x30000A,
-	0x089144, 0x19A144, 0x2AB144, 0x0389E4,
-	0x0399EC, 0x007502, 0x007D0A, 0x03A9E4,
-	0x000702, 0x00107D, 0x000415, 0x018042,
-	0x08000A, 0x0109E4, 0x000F02, 0x002AF5,
-	0x0019FD, 0x010042, 0x09804A, 0x10000A,
-	0x000934, 0x001674, 0x0029F5, 0x010042,
-	0x10000A, 0x00917C, 0x002075, 0x010042,
-	0x08000A, 0x000904, 0x200A86, 0x0026F5,
-	0x0027F5, 0x030042, 0x09004A, 0x10000A,
-	0x000A3C, 0x00167C, 0x001A75, 0x000BFD,
-	0x010042, 0x51804A, 0x48000A, 0x160007,
-	0x001075, 0x010042, 0x282C0A, 0x281D12,
-	0x282512, 0x001F32, 0x1E0007, 0x0E0007,
-	0x001975, 0x010042, 0x002DF5, 0x0D004A,
-	0x10000A, 0x009144, 0x20EA86, 0x010042,
-	0x28340A, 0x000E5D, 0x00008D, 0x000375,
-	0x000820, 0x010040, 0x05D2F4, 0x54D104,
-	0x00735C, 0x218B86, 0x000007, 0x0C0007,
-	0x080007, 0x0A0007, 0x02178D, 0x000810,
-	0x08043A, 0x34B206, 0x000007, 0x219206,
-	0x000007, 0x080007, 0x002275, 0x010042,
-	0x20000A, 0x002104, 0x225886, 0x001E2D,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x21CA86, 0x000007, 0x002010, 0x30043A,
-	0x00057D, 0x0180C3, 0x08000A, 0x028924,
-	0x280502, 0x280C02, 0x0A810D, 0x000820,
-	0x0002F5, 0x010040, 0x220007, 0x0004FD,
-	0x018042, 0x70000A, 0x030000, 0x007020,
-	0x07FA06, 0x018040, 0x022B8D, 0x000810,
-	0x08043A, 0x2CAA06, 0x000007, 0x0002FD,
-	0x018042, 0x08000A, 0x000904, 0x22C286,
-	0x000007, 0x020206, 0x000007, 0x000875,
-	0x0009FD, 0x00010D, 0x234206, 0x000295,
-	0x000B75, 0x00097D, 0x00000D, 0x000515,
-	0x010042, 0x18000A, 0x001904, 0x2A0086,
-	0x0006F5, 0x001020, 0x010040, 0x0004F5,
-	0x000820, 0x010040, 0x000775, 0x010042,
-	0x09804A, 0x10000A, 0x001124, 0x000904,
-	0x23F286, 0x000815, 0x080102, 0x101204,
-	0x241206, 0x000575, 0x081204, 0x000007,
-	0x100102, 0x000575, 0x000425, 0x021124,
-	0x100102, 0x000820, 0x031060, 0x010040,
-	0x001924, 0x2A0086, 0x00008D, 0x000464,
-	0x009D04, 0x291086, 0x180102, 0x000575,
-	0x010042, 0x28040A, 0x00018D, 0x000924,
-	0x280D02, 0x00000D, 0x000924, 0x281502,
-	0x10000D, 0x000820, 0x0002F5, 0x010040,
-	0x200007, 0x001175, 0x0002FD, 0x018042,
-	0x08000A, 0x000904, 0x24FA86, 0x000007,
-	0x000100, 0x080B20, 0x130B60, 0x1B0B60,
-	0x030A60, 0x010040, 0x050042, 0x3D004A,
-	0x35004A, 0x2D004A, 0x20000A, 0x0006F5,
-	0x010042, 0x28140A, 0x0004F5, 0x010042,
-	0x08000A, 0x000315, 0x010D04, 0x260286,
-	0x004015, 0x000095, 0x010D04, 0x25F086,
-	0x100022, 0x10002A, 0x261A06, 0x000007,
-	0x333104, 0x2AA904, 0x000007, 0x032124,
-	0x280502, 0x284402, 0x001124, 0x400102,
-	0x000424, 0x000424, 0x003224, 0x00292C,
-	0x00636C, 0x277386, 0x000007, 0x02B164,
-	0x000464, 0x000464, 0x00008D, 0x000A64,
-	0x280D02, 0x10008D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x00008D, 0x38B904,
-	0x000007, 0x03296C, 0x30010A, 0x0002F5,
-	0x010042, 0x08000A, 0x000904, 0x270286,
-	0x000007, 0x00212C, 0x28050A, 0x00316C,
-	0x00046C, 0x00046C, 0x28450A, 0x001124,
-	0x006B64, 0x100102, 0x00008D, 0x01096C,
-	0x280D0A, 0x10010D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x004124, 0x000424,
-	0x000424, 0x003224, 0x300102, 0x032944,
-	0x27FA86, 0x000007, 0x300002, 0x0004F5,
-	0x010042, 0x08000A, 0x000315, 0x010D04,
-	0x284086, 0x003124, 0x000464, 0x300102,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x284A86, 0x000007, 0x284402, 0x003124,
-	0x300502, 0x003924, 0x300583, 0x000883,
-	0x0005F5, 0x010042, 0x28040A, 0x00008D,
-	0x008124, 0x280D02, 0x00008D, 0x008124,
-	0x281502, 0x10018D, 0x000820, 0x0002F5,
-	0x010040, 0x220007, 0x001025, 0x000575,
-	0x030042, 0x09004A, 0x10000A, 0x0A0904,
-	0x121104, 0x000007, 0x001020, 0x050860,
-	0x050040, 0x0006FD, 0x018042, 0x09004A,
-	0x10000A, 0x0000A5, 0x0A0904, 0x121104,
-	0x000007, 0x000820, 0x019060, 0x010040,
-	0x0002F5, 0x010042, 0x08000A, 0x000904,
-	0x29CA86, 0x000007, 0x244206, 0x000007,
-	0x000606, 0x000007, 0x0002F5, 0x010042,
-	0x08000A, 0x000904, 0x2A1A86, 0x000007,
-	0x000100, 0x080B20, 0x138B60, 0x1B8B60,
-	0x238B60, 0x2B8B60, 0x338B60, 0x3B8B60,
-	0x438B60, 0x4B8B60, 0x538B60, 0x5B8B60,
-	0x638B60, 0x6B8B60, 0x738B60, 0x7B8B60,
-	0x038F60, 0x0B8F60, 0x138F60, 0x1B8F60,
-	0x238F60, 0x2B8F60, 0x338F60, 0x3B8F60,
-	0x438F60, 0x4B8F60, 0x538F60, 0x5B8F60,
-	0x638F60, 0x6B8F60, 0x738F60, 0x7B8F60,
-	0x038A60, 0x000606, 0x018040, 0x00008D,
-	0x000A64, 0x280D02, 0x000A24, 0x00027D,
-	0x018042, 0x10000A, 0x001224, 0x0003FD,
-	0x018042, 0x08000A, 0x000904, 0x2C0A86,
-	0x000007, 0x00018D, 0x000A24, 0x000464,
-	0x000464, 0x080102, 0x000924, 0x000424,
-	0x000424, 0x100102, 0x02000D, 0x009144,
-	0x2C6186, 0x000007, 0x0001FD, 0x018042,
-	0x08000A, 0x000A44, 0x2C4386, 0x018042,
-	0x0A000D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00027D, 0x001020, 0x000606,
-	0x018040, 0x0002F5, 0x010042, 0x08000A,
-	0x000904, 0x2CB286, 0x000007, 0x00037D,
-	0x018042, 0x08000A, 0x000904, 0x2CE286,
-	0x000007, 0x000075, 0x002E7D, 0x010042,
-	0x0B804A, 0x000020, 0x000904, 0x000686,
-	0x010040, 0x31844A, 0x30048B, 0x000883,
-	0x00008D, 0x000810, 0x28143A, 0x00008D,
-	0x000810, 0x280C3A, 0x000675, 0x010042,
-	0x08000A, 0x003815, 0x010924, 0x280502,
-	0x0B000D, 0x000820, 0x0002F5, 0x010040,
-	0x000606, 0x220007, 0x000464, 0x000464,
-	0x000606, 0x000007, 0x000134, 0x007F8D,
-	0x00093C, 0x281D12, 0x282512, 0x001F32,
-	0x0E0007, 0x00010D, 0x00037D, 0x000820,
-	0x018040, 0x05D2F4, 0x000007, 0x080007,
-	0x00037D, 0x018042, 0x08000A, 0x000904,
-	0x2E8A86, 0x000007, 0x000606, 0x000007,
-	0x000007, 0x000012, 0x100007, 0x320007,
-	0x600007, 0x460007, 0x100080, 0x48001A,
-	0x004904, 0x2EF186, 0x000007, 0x001210,
-	0x58003A, 0x000145, 0x5C5D04, 0x000007,
-	0x000080, 0x48001A, 0x004904, 0x2F4186,
-	0x000007, 0x001210, 0x50003A, 0x005904,
-	0x2F9886, 0x000045, 0x0000C5, 0x7FFFF5,
-	0x7FFF7D, 0x07D524, 0x004224, 0x500102,
-	0x200502, 0x000082, 0x40001A, 0x004104,
-	0x2FC986, 0x000007, 0x003865, 0x40001A,
-	0x004020, 0x00104D, 0x04C184, 0x31AB86,
-	0x000040, 0x040007, 0x000165, 0x000145,
-	0x004020, 0x000040, 0x000765, 0x080080,
-	0x40001A, 0x004104, 0x305986, 0x000007,
-	0x001210, 0x40003A, 0x004104, 0x30B286,
-	0x00004D, 0x0000CD, 0x004810, 0x20043A,
-	0x000882, 0x40001A, 0x004104, 0x30C186,
-	0x000007, 0x004820, 0x005904, 0x319886,
-	0x000040, 0x0007E5, 0x200480, 0x2816A0,
-	0x3216E0, 0x3A16E0, 0x4216E0, 0x021260,
-	0x000040, 0x000032, 0x400075, 0x00007D,
-	0x07D574, 0x200512, 0x000082, 0x40001A,
-	0x004104, 0x317186, 0x000007, 0x038A06,
-	0x640007, 0x0000E5, 0x000020, 0x000040,
-	0x000A65, 0x000020, 0x020040, 0x020040,
-	0x000040, 0x000165, 0x000042, 0x70000A,
-	0x007104, 0x323286, 0x000007, 0x060007,
-	0x019A06, 0x640007, 0x050000, 0x007020,
-	0x000040, 0x038A06, 0x640007, 0x000007,
-	0x00306D, 0x028860, 0x029060, 0x08000A,
-	0x028860, 0x008040, 0x100012, 0x00100D,
-	0x009184, 0x32D186, 0x000E0D, 0x009184,
-	0x33E186, 0x000007, 0x300007, 0x001020,
-	0x003B6D, 0x008040, 0x000080, 0x08001A,
-	0x000904, 0x32F186, 0x000007, 0x001220,
-	0x000DED, 0x008040, 0x008042, 0x10000A,
-	0x40000D, 0x109544, 0x000007, 0x001020,
-	0x000DED, 0x008040, 0x008042, 0x20040A,
-	0x000082, 0x08001A, 0x000904, 0x338186,
-	0x000007, 0x003B6D, 0x008042, 0x08000A,
-	0x000E15, 0x010984, 0x342B86, 0x600007,
-	0x08001A, 0x000C15, 0x010984, 0x341386,
-	0x000020, 0x1A0007, 0x0002ED, 0x008040,
-	0x620007, 0x00306D, 0x028042, 0x0A804A,
-	0x000820, 0x0A804A, 0x000606, 0x10804A,
-	0x000007, 0x282512, 0x001F32, 0x05D2F4,
-	0x54D104, 0x00735C, 0x000786, 0x000007,
-	0x0C0007, 0x0A0007, 0x1C0007, 0x003465,
-	0x020040, 0x004820, 0x025060, 0x40000A,
-	0x024060, 0x000040, 0x454944, 0x000007,
-	0x004020, 0x003AE5, 0x000040, 0x0028E5,
-	0x000042, 0x48000A, 0x004904, 0x39F886,
-	0x002C65, 0x000042, 0x40000A, 0x0000D5,
-	0x454104, 0x000007, 0x000655, 0x054504,
-	0x368286, 0x0001D5, 0x054504, 0x368086,
-	0x002B65, 0x000042, 0x003AE5, 0x50004A,
-	0x40000A, 0x45C3D4, 0x000007, 0x454504,
-	0x000007, 0x0000CD, 0x444944, 0x000007,
-	0x454504, 0x000007, 0x00014D, 0x554944,
-	0x000007, 0x045144, 0x367986, 0x002C65,
-	0x000042, 0x48000A, 0x4CD104, 0x000007,
-	0x04C144, 0x368386, 0x000007, 0x160007,
-	0x002CE5, 0x040042, 0x40000A, 0x004020,
-	0x000040, 0x002965, 0x000042, 0x40000A,
-	0x004104, 0x36F086, 0x000007, 0x002402,
-	0x383206, 0x005C02, 0x0025E5, 0x000042,
-	0x40000A, 0x004274, 0x002AE5, 0x000042,
-	0x40000A, 0x004274, 0x500112, 0x0029E5,
-	0x000042, 0x40000A, 0x004234, 0x454104,
-	0x000007, 0x004020, 0x000040, 0x003EE5,
-	0x000020, 0x000040, 0x002DE5, 0x400152,
-	0x50000A, 0x045144, 0x37DA86, 0x0000C5,
-	0x003EE5, 0x004020, 0x000040, 0x002BE5,
-	0x000042, 0x40000A, 0x404254, 0x000007,
-	0x002AE5, 0x004020, 0x000040, 0x500132,
-	0x040134, 0x005674, 0x0029E5, 0x020042,
-	0x42000A, 0x000042, 0x50000A, 0x05417C,
-	0x0028E5, 0x000042, 0x48000A, 0x0000C5,
-	0x4CC144, 0x38A086, 0x0026E5, 0x0027E5,
-	0x020042, 0x40004A, 0x50000A, 0x00423C,
-	0x00567C, 0x0028E5, 0x004820, 0x000040,
-	0x281D12, 0x282512, 0x001F72, 0x002965,
-	0x000042, 0x40000A, 0x004104, 0x393A86,
-	0x0E0007, 0x160007, 0x1E0007, 0x003EE5,
-	0x000042, 0x40000A, 0x004104, 0x397886,
-	0x002D65, 0x000042, 0x28340A, 0x003465,
-	0x020042, 0x42004A, 0x004020, 0x4A004A,
-	0x50004A, 0x05D2F4, 0x54D104, 0x00735C,
-	0x39E186, 0x000007, 0x000606, 0x080007,
-	0x0C0007, 0x080007, 0x0A0007, 0x0001E5,
-	0x020045, 0x004020, 0x000060, 0x000365,
-	0x000040, 0x002E65, 0x001A20, 0x0A1A60,
-	0x000040, 0x003465, 0x020042, 0x42004A,
-	0x004020, 0x4A004A, 0x000606, 0x50004A,
-	0x0017FD, 0x018042, 0x08000A, 0x000904,
-	0x225A86, 0x000007, 0x00107D, 0x018042,
-	0x0011FD, 0x33804A, 0x19804A, 0x20000A,
-	0x000095, 0x2A1144, 0x01A144, 0x3B9086,
-	0x00040D, 0x00B184, 0x3B9186, 0x0018FD,
-	0x018042, 0x0010FD, 0x09804A, 0x38000A,
-	0x000095, 0x010924, 0x003A64, 0x3B8186,
-	0x000007, 0x003904, 0x3B9286, 0x000007,
-	0x3B9A06, 0x00000D, 0x00008D, 0x000820,
-	0x00387D, 0x018040, 0x700002, 0x00117D,
-	0x018042, 0x00197D, 0x29804A, 0x30000A,
-	0x380002, 0x003124, 0x000424, 0x000424,
-	0x002A24, 0x280502, 0x00068D, 0x000810,
-	0x28143A, 0x00750D, 0x00B124, 0x002264,
-	0x3D0386, 0x284402, 0x000810, 0x280C3A,
-	0x0B800D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00758D, 0x00B124, 0x100102,
-	0x012144, 0x3E4986, 0x001810, 0x10003A,
-	0x00387D, 0x018042, 0x08000A, 0x000904,
-	0x3E4886, 0x030000, 0x3E4A06, 0x0000BD,
-	0x00008D, 0x023164, 0x000A64, 0x280D02,
-	0x0B808D, 0x000820, 0x0002FD, 0x018040,
-	0x200007, 0x00387D, 0x018042, 0x08000A,
-	0x000904, 0x3E3286, 0x030000, 0x0002FD,
-	0x018042, 0x08000A, 0x000904, 0x3D8286,
-	0x000007, 0x002810, 0x28043A, 0x00750D,
-	0x030924, 0x002264, 0x280D02, 0x02316C,
-	0x28450A, 0x0B810D, 0x000820, 0x0002FD,
-	0x018040, 0x200007, 0x00008D, 0x000A24,
-	0x3E4A06, 0x100102, 0x001810, 0x10003A,
-	0x0000BD, 0x003810, 0x30043A, 0x00187D,
-	0x018042, 0x0018FD, 0x09804A, 0x20000A,
-	0x0000AD, 0x028924, 0x07212C, 0x001010,
-	0x300583, 0x300D8B, 0x3014BB, 0x301C83,
-	0x002083, 0x00137D, 0x038042, 0x33844A,
-	0x33ACCB, 0x33B4CB, 0x33BCCB, 0x33C4CB,
-	0x33CCCB, 0x33D4CB, 0x305C8B, 0x006083,
-	0x001E0D, 0x0005FD, 0x018042, 0x20000A,
-	0x020924, 0x00068D, 0x00A96C, 0x00009D,
-	0x0002FD, 0x018042, 0x08000A, 0x000904,
-	0x3F6A86, 0x000007, 0x280502, 0x280D0A,
-	0x284402, 0x001810, 0x28143A, 0x0C008D,
-	0x000820, 0x0002FD, 0x018040, 0x220007,
-	0x003904, 0x225886, 0x001E0D, 0x00057D,
-	0x018042, 0x20000A, 0x020924, 0x0000A5,
-	0x0002FD, 0x018042, 0x08000A, 0x000904,
-	0x402A86, 0x000007, 0x280502, 0x280C02,
-	0x002010, 0x28143A, 0x0C010D, 0x000820,
-	0x0002FD, 0x018040, 0x225A06, 0x220007,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000,
-	0x000000, 0x000000, 0x000000, 0x000000
-};
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/Makefile linux.17p18/drivers/sound/Makefile
--- linux.vanilla/drivers/sound/Makefile	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/sound/Makefile	Mon Aug 14 18:49:12 2000
@@ -10,13 +10,20 @@
 SUB_DIRS	:= 
 MOD_SUB_DIRS	:=
 MOD_IN_SUB_DIRS	:=
-ALL_SUB_DIRS	:= $(SUB_DIRS) lowlevel
+ALL_SUB_DIRS	:= $(SUB_DIRS) lowlevel emu10k1
 
 ifeq ($(CONFIG_LOWLEVEL_SOUND),y)
     SUB_DIRS		+= lowlevel
     MOD_IN_SUB_DIRS	+= lowlevel
 endif
 
+ifeq ($(CONFIG_SOUND_EMU10K1),y)
+    SUB_DIRS		+= emu10k1 
+else
+  ifeq ($(CONFIG_SOUND_EMU10K1),m)
+    MOD_IN_SUB_DIRS	+= emu10k1
+  endif
+endif
 
 
 # All of the (potential) objects that export symbols.
@@ -54,7 +61,7 @@
 obj-$(CONFIG_SOUND_GUS)		+= gus.o ad1848.o
 obj-$(CONFIG_SOUND_MAD16)	+= mad16.o ad1848.o sb.o uart401.o
 obj-$(CONFIG_SOUND_VIA82CXXX)	+= via82cxxx.o sb.o uart401.o 
-obj-$(CONFIG_SOUND_YMPCI)	+= ymf_sb.o sb.o uart401.o ac97_codec.o
+obj-$(CONFIG_SOUND_YMPCI)	+= ymfsb.o sb.o uart401.o ac97.o
 obj-$(CONFIG_SOUND_MAUI)	+= maui.o mpu401.o
 obj-$(CONFIG_SOUND_MPU401)	+= mpu401.o
 obj-$(CONFIG_SOUND_MSNDCLAS)	+= msnd.o msnd_classic.o
@@ -81,18 +88,25 @@
 
 #jnx
 obj-$(CONFIG_SOUND_CMPCI)	+= cmpci.o
+obj-$(CONFIG_SOUND_CS4281)	+= cs4281.o
 obj-$(CONFIG_SOUND_ES1370)	+= es1370.o
 obj-$(CONFIG_SOUND_ES1371)	+= es1371.o
 obj-$(CONFIG_SOUND_ESSSOLO1)	+= esssolo1.o
+obj-$(CONFIG_SOUND_FUSION)	+= cs46xx.o ac97_codec.o
 obj-$(CONFIG_SOUND_ICH)		+= i810_audio.o ac97_codec.o
 obj-$(CONFIG_SOUND_MAESTRO)	+= maestro.o
 obj-$(CONFIG_SOUND_SONICVIBES)	+= sonicvibes.o
 obj-$(CONFIG_SOUND_TRIDENT)     += trident.o ac97_codec.o
 
+ifeq ($(CONFIG_SOUND_EMU10K1),y)
+  obj-y				+= emu10k1/emu10k1.o
+endif
+
+
 # Declare multi-part drivers.
 
 list-multi	:= sound.o gus.o pas2.o sb.o softoss2.o vidc_mod.o \
-    soundcore.o wavefront.o nm256.o via82cxxx.o \
+    soundcore.o wavefront.o nm256.o ymfsb.o via82cxxx.o \
 
 sound-objs	:= 							\
     dev_table.o soundcard.o sound_syms.o		\
@@ -110,7 +124,8 @@
 vidc_mod-objs	:= vidc.o vidc_audio.o vidc_fill.o vidc_mixer.o vidc_synth.o
 wavefront-objs  := wavfront.o wf_midi.o yss225.o
 nm256-objs	:= nm256_audio.o ac97.o
-via82cxxx-objs := via82cxxx_audio.o ac97.o
+via82cxxx-objs  := via82cxxx_audio.o ac97.o
+ymfsb-objs	:= ymf_sb.o ac97.o
 
 
 # Extract lists of the multi-part drivers.
@@ -201,6 +216,9 @@
 
 via82cxxx.o: $(via82cxxx-objs)
 	$(LD) -r -o $@ $(via82cxxx-objs)
+
+ymfsb.o: $(ymfsb-objs)
+	$(LD) -r -o $@ $(ymfsb-objs)
 
 # Firmware files that need translation
 #
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/ac97_codec.c linux.17p18/drivers/sound/ac97_codec.c
--- linux.vanilla/drivers/sound/ac97_codec.c	Sun Jun 11 21:44:17 2000
+++ linux.17p18/drivers/sound/ac97_codec.c	Thu Aug 17 18:44:41 2000
@@ -62,6 +62,7 @@
 	{0x43525903, "Cirrus Logic CS4297"  ,	NULL},
 	{0x43525913, "Cirrus Logic CS4297A"   , NULL},
 	{0x43525923, "Cirrus Logic CS4298"    , NULL},
+	{0x4352592B, "Cirrus Logic CS4294"    , NULL},
 	{0x43525931, "Cirrus Logic CS4299"    , NULL},
 	{0x4e534331, "National Semiconductor LM4549" ,	NULL},
 	{0x53494c22, "Silicon Laboratory Si3036"     ,	NULL},
@@ -530,6 +531,12 @@
 	/* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should 
 	   be read zero. Probing of AC97 in this way is not reliable, it is not even SAFE !! */
 	codec->codec_write(codec, AC97_RESET, 0L);
+	
+	/* We need a codec->codec_reset() function here but the delay is a
+	   reasonable hack for the moment */
+	   
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout((5*HZ)/100);
 	if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) {
 		printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n",
 		       codec->id ? "Secondary" : "Primary");
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/cs4281.c linux.17p18/drivers/sound/cs4281.c
--- linux.vanilla/drivers/sound/cs4281.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/cs4281.c	Mon Aug 14 19:08:35 2000
@@ -0,0 +1,2450 @@
+//*****************************************************************************
+//
+//      "cs4281.c" --  Cirrus Logic-Crystal CS4281 linux audio driver.
+//
+//      Copyright (C) 2000  Cirrus Logic Corp.  
+//            -- adapted from drivers by Thomas Sailer, 
+//            -- but don't bug him; Problems should go to:
+//            -- gw boynton (wesb@crystal.cirrus.com) or
+//            -- tom woller (twoller@crystal.cirrus.com).
+//
+//      This program is free software; you can redistribute it and/or modify
+//      it under the terms of the GNU General Public License as published by
+//      the Free Software Foundation; either version 2 of the License, or
+//      (at your option) any later version.
+//
+//      This program is distributed in the hope that it will be useful,
+//      but WITHOUT ANY WARRANTY; without even the implied warranty of
+//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//      GNU General Public License for more details.
+//
+//      You should have received a copy of the GNU General Public License
+//      along with this program; if not, write to the Free Software
+//      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// Module command line parameters:
+//   none
+//
+//  Supported devices:
+//  /dev/dsp    standard /dev/dsp device, (mostly) OSS compatible
+//  /dev/mixer  standard /dev/mixer device, (mostly) OSS compatible
+//  /dev/midi   simple MIDI UART interface, no ioctl
+//
+//
+//
+
+// *****************************************************************************
+
+#include <linux/config.h>
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <linux/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <asm/spinlock.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+#include <linux/vmalloc.h>
+#include "dm.h"
+#include "cs4281_hwdefs.h"
+
+EXPORT_NO_SYMBOLS;
+
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+// --------------------------------------------------------------------- 
+
+#ifndef PCI_VENDOR_ID_CIRRUS
+#define PCI_VENDOR_ID_CIRRUS          0x1013
+#endif
+#ifndef PCI_DEVICE_ID_CRYSTAL_CS4281
+#define PCI_DEVICE_ID_CRYSTAL_CS4281  0x6005
+#endif
+
+#define CS4281_MAGIC  ((PCI_DEVICE_ID_CRYSTAL_CS4281<<16) | PCI_VENDOR_ID_CIRRUS)
+
+#include <linux/version.h>
+
+#if LINUX_VERSION_CODE < 0x02030d
+#ifdef MODULE
+#define __exit
+#define module_exit(x) void cleanup_module(void) { x(); }
+#define module_init(x) int init_module(void) { return x(); }
+#else
+#define __exit __attribute__ ((unused, __section__ (".text.init")))
+#define module_exit(x) // nothing 
+#define module_init(x) // nothing 
+#endif
+
+#define DECLARE_WAIT_QUEUE_HEAD(w) struct wait_queue *w = NULL
+#define DECLARE_WAITQUEUE(w,c) struct wait_queue w = {(c), NULL}
+#define wait_queue_head_t struct wait_queue *
+#define init_waitqueue_head(w) *(w) = 0
+#define init_MUTEX(m) *(m) = MUTEX
+#endif
+
+// MIDI buffer sizes 
+#define MIDIINBUF  500
+#define MIDIOUTBUF 500
+
+#define FMODE_MIDI_SHIFT 3
+#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
+#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
+
+
+struct cs4281_state {
+        // magic 
+        unsigned int magic;
+
+        // we keep the cards in a linked list 
+        struct cs4281_state *next;
+
+        // pcidev is needed to turn off the DDMA controller at driver shutdown 
+        struct pci_dev *pcidev;
+
+        // soundcore stuff 
+        int dev_audio;
+        int dev_mixer;
+        int dev_midi;
+// *wb*    int dev_dmfm;
+
+        // hardware resources 
+// *wb*    unsigned long iobase, sbbase, vcbase, ddmabase, mpubase, gpbase; // long for SPARC   
+        unsigned int pBA0phys, pBA1phys;
+        char *pBA0, *pBA1; 
+        unsigned int irq;
+	int endofbuffer;
+
+        // mixer registers 
+        struct {
+                unsigned short vol[10];
+                unsigned int recsrc;
+                unsigned int modcnt;
+                unsigned short micpreamp;
+        } mix;
+
+        // wave stuff   // Note that play & record formats must be the same *wb.
+        unsigned fmt;
+        unsigned channels;
+        unsigned rate;
+        unsigned char clkdiv;
+        unsigned ena;
+
+        spinlock_t lock;
+        struct semaphore open_sem;
+        mode_t open_mode;
+        wait_queue_head_t open_wait;
+
+        struct dmabuf {
+                void *rawbuf;            // Physical address of  
+                unsigned buforder;       // Log base 2 of 'rawbuf' size in bytes..
+                unsigned numfrag;        // # of 'fragments' in the buffer.
+                unsigned fragshift;      // Log base 2 of fragment size.
+                unsigned hwptr, swptr;
+                unsigned total_bytes;    // # bytes process since open.
+                int count;
+                unsigned error; // over/underrun 
+                wait_queue_head_t wait;
+                // redundant, but makes calculations easier 
+                unsigned fragsize;       // 2**fragshift..
+                unsigned dmasize;        // 2**buforder.
+                unsigned fragsamples;
+                // OSS stuff 
+                unsigned mapped:1;       // Buffer mapped in cs4281_mmap()?
+                unsigned ready:1;        // prog_dmabuf_dac()/adc() successful?
+                unsigned endcleared:1;
+                unsigned ossfragshift;
+                int ossmaxfrags;
+                unsigned subdivision;
+        } dma_dac, dma_adc;
+
+        // midi stuff 
+        struct {
+                unsigned ird, iwr, icnt;
+                unsigned ord, owr, ocnt;
+                wait_queue_head_t iwait;
+                wait_queue_head_t owait;
+                struct timer_list timer;
+                unsigned char ibuf[MIDIINBUF];
+                unsigned char obuf[MIDIOUTBUF];
+        } midi;
+
+};
+
+
+struct cs4281_state *devs = NULL;
+// --------------------------------------------------------------------- 
+//
+//		Hardware Interfaces For the CS4281
+//
+
+
+//******************************************************************************
+// "delayus()-- Delay for the specified # of microseconds.
+//******************************************************************************
+static void delayus(u32 delay)
+{
+	u32 j;   
+	if(delay > 9999)
+	{
+		j = (delay * HZ)/1000000;   /* calculate delay in jiffies  */
+		if(j<1) 
+			j=1;               /* minimum one jiffy. */
+		current->state = TASK_UNINTERRUPTIBLE;  
+		schedule_timeout(j);       
+	}
+	else
+		udelay(delay);
+	return;                      
+}
+
+
+//******************************************************************************
+// "cs4281_read_ac97" -- Reads a word from the specified location in the
+//               CS4281's address space(based on the BA0 register).
+//
+// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 register,
+//                                            0h for reads.
+// 3. Write ACCTL = Control Register = 460h for initiating the write
+// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
+// 5. if DCV not cleared, break and return error
+// 6. Read ACSTS = Status Register = 464h, check VSTS bit
+//****************************************************************************
+static int cs4281_read_ac97(struct cs4281_state *card, u32 offset, u32 *value)
+{
+	u32 count, status;
+
+        // Make sure that there is not data sitting
+        // around from a previous uncompleted access.
+        // ACSDA = Status Data Register = 47Ch
+	status = readl(card->pBA0+BA0_ACSDA);
+
+        // Setup the AC97 control registers on the CS4281 to send the
+        // appropriate command to the AC97 to perform the read.
+        // ACCAD = Command Address Register = 46Ch
+        // ACCDA = Command Data Register = 470h
+        // ACCTL = Control Register = 460h
+        // bit DCV - will clear when process completed
+        // bit CRW - Read command
+        // bit VFRM - valid frame enabled
+        // bit ESYN - ASYNC generation enabled
+
+        // Get the actual AC97 register from the offset
+	writel(offset - BA0_AC97_RESET, card->pBA0+BA0_ACCAD);
+	writel(0, card->pBA0+BA0_ACCDA);
+	writel(ACCTL_DCV | ACCTL_CRW | ACCTL_VFRM | ACCTL_ESYN, card->pBA0+BA0_ACCTL);
+
+         // Wait for the read to occur.
+	for(count = 0; count < 10; count++)
+	{
+		// First, we want to wait for a short time.
+		udelay(25);
+
+		// Now, check to see if the read has completed.
+        	// ACCTL = 460h, DCV should be reset by now and 460h = 17h
+        	if( !(readl(card->pBA0+BA0_ACCTL) & ACCTL_DCV))
+			break;
+	}
+
+         // Make sure the read completed.
+	if(readl(card->pBA0+BA0_ACCTL) & ACCTL_DCV)
+ 	       return 1;
+
+         // Wait for the valid status bit to go active.
+	for(count = 0; count < 10; count++)
+	{
+        	// Read the AC97 status register.
+        	// ACSTS = Status Register = 464h
+        	status = readl(card->pBA0+BA0_ACSTS);
+
+		// See if we have valid status.
+        	// VSTS - Valid Status
+        	if(status & ACSTS_VSTS)
+        		break;
+		// Wait for a short while.
+        	udelay(25);
+	}
+
+         // Make sure we got valid status.
+	if(!(status & ACSTS_VSTS))
+        	return 1;
+
+	// Read the data returned from the AC97 register.
+	// ACSDA = Status Data Register = 474h
+	*value = readl(card->pBA0+BA0_ACSDA);
+
+	// Success.
+	return(0);
+}
+
+
+//****************************************************************************
+//
+// "cs4281_write_ac97()"-- writes a word to the specified location in the
+// CS461x's address space (based on the part's base address zero register).
+//
+// 1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+// 2. Write ACCDA = Command Data Register = 470h for data to write to AC97 reg.
+// 3. Write ACCTL = Control Register = 460h for initiating the write
+// 4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
+// 5. if DCV not cleared, break and return error
+//
+//****************************************************************************
+static int cs4281_write_ac97(struct cs4281_state *card, u32 offset, u32 value)
+{
+	u32 count, status;
+
+         // Setup the AC97 control registers on the CS4281 to send the
+         // appropriate command to the AC97 to perform the read.
+         // ACCAD = Command Address Register = 46Ch
+         // ACCDA = Command Data Register = 470h
+         // ACCTL = Control Register = 460h
+         // set DCV - will clear when process completed
+         // reset CRW - Write command
+         // set VFRM - valid frame enabled
+         // set ESYN - ASYNC generation enabled
+         // set RSTN - ARST# inactive, AC97 codec not reset
+
+         // Get the actual AC97 register from the offset
+
+	writel(offset - BA0_AC97_RESET, card->pBA0+BA0_ACCAD);
+	writel(value, card->pBA0+BA0_ACCDA);
+	writel(ACCTL_DCV | ACCTL_VFRM | ACCTL_ESYN, card->pBA0+BA0_ACCTL);
+
+         // Wait for the write to occur.
+	for(count = 0; count < 10; count++)
+	{
+		// First, we want to wait for a short time.
+        	udelay(25);
+		// Now, check to see if the write has completed.
+		// ACCTL = 460h, DCV should be reset by now and 460h = 07h
+		status = readl(card->pBA0+BA0_ACCTL);
+		if(!(status & ACCTL_DCV))
+			break;
+	}
+
+        // Make sure the write completed.
+	if(status & ACCTL_DCV)
+	        return 1;
+	// Success.
+	return 0;
+}
+
+
+//******************************************************************************
+// "Init4281()" -- Bring up the part.
+//******************************************************************************
+static int cs4281_hw_init(struct cs4281_state *card)
+{
+	u32 ac97_slotid;
+	u32 temp1, temp2;
+
+	//***************************************
+	//  Set up the Sound System Configuration
+	//***************************************
+
+         // Set the 'Configuration Write Protect' register
+         // to 4281h.  Allows vendor-defined configuration
+         // space between 0e4h and 0ffh to be written.
+
+	writel(0x4281, card->pBA0+BA0_CWPR);                       // (3e0h)
+
+         // (0), Blast the clock control register to zero so that the
+         // PLL starts out in a known state, and blast the master serial
+         // port control register to zero so that the serial ports also
+         // start out in a known state.
+
+	writel(0, card->pBA0+BA0_CLKCR1);                          // (400h)
+	writel(0, card->pBA0+BA0_SERMC);                           // (420h)
+
+
+         // (1), Make ESYN go to zero to turn off
+         // the Sync pulse on the AC97 link.
+
+	writel(0, card->pBA0+BA0_ACCTL);
+	udelay(50);
+
+
+         // (2) Drive the ARST# pin low for a minimum of 1uS (as defined in
+         // the AC97 spec) and then drive it high.  This is done for non
+         // AC97 modes since there might be logic external to the CS461x
+         // that uses the ARST# line for a reset.
+
+	writel(0, card->pBA0+BA0_SPMC);                            // (3ech)
+	udelay(100);
+	writel(SPMC_RSTN, card->pBA0+BA0_SPMC);
+	delayus(50000);     // Wait 50 ms for ABITCLK to become stable.
+
+        // (3) Turn on the Sound System Clocks.
+	writel(CLKCR1_PLLP, card->pBA0+BA0_CLKCR1);                // (400h)
+	delayus(50000);     // Wait for the PLL to stabilize.
+	// Turn on clocking of the core (CLKCR1(400h) = 0x00000030)
+	writel(CLKCR1_PLLP | CLKCR1_SWCE, card->pBA0+BA0_CLKCR1);
+
+        // (4) Power on everything for now..
+	writel(0x7E, card->pBA0 + BA0_SSPM);                       // (740h)
+
+        // (5) Wait for clock stabilization.
+	for(temp1=0; temp1<1000;  temp1++)
+	{
+		udelay(1000);
+		if(readl(card->pBA0+BA0_CLKCR1) & CLKCR1_DLLRDY)
+			break;
+	}
+	if(!(readl(card->pBA0+BA0_CLKCR1) & CLKCR1_DLLRDY))
+	{
+		printk(KERN_ERR "cs4281: DLLRDY failed!\n");
+		return -EIO;
+	}
+
+	// (6) Enable ASYNC generation.
+	writel(ACCTL_ESYN, card->pBA0+BA0_ACCTL);                  // (460h)
+
+	// Now wait 'for a short while' to allow the  AC97
+	// part to start generating bit clock. (so we don't
+	// Try to start the PLL without an input clock.)
+	delayus(50000);
+
+        // Set the serial port timing configuration, so that the
+        // clock control circuit gets its clock from the right place.
+	writel(SERMC_PTC_AC97, card->pBA0+BA0_SERMC);              // (420h)=2.
+
+        // (7) Wait for the codec ready signal from the AC97 codec.
+
+	for(temp1=0; temp1<1000; temp1++)
+	{
+		// Delay a mil to let things settle out and
+		// to prevent retrying the read too quickly.
+		udelay(1000);
+		if( readl(card->pBA0+BA0_ACSTS) & ACSTS_CRDY )	// If ready,  (464h)
+			break;                                  //   exit the 'for' loop.
+	}
+	if( !(readl(card->pBA0+BA0_ACSTS) & ACSTS_CRDY) )       // If never came ready,
+	{
+        	printk(KERN_ERR "cs4281: ACSTS never came ready!\n");
+        	return -EIO;                                //   exit initialization.
+	}
+
+         // (8) Assert the 'valid frame' signal so we can
+         // begin sending commands to the AC97 codec.
+	writel(ACCTL_VFRM | ACCTL_ESYN, card->pBA0+BA0_ACCTL);   // (460h)
+
+         // (9), Wait until CODEC calibration is finished.
+         // Print an error message if it doesn't.
+	for(temp1 = 0; temp1 < 1000; temp1++)
+	{
+		delayus(10000);
+		// Read the AC97 Powerdown Control/Status Register.
+		cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp2);
+		if( (temp2 & 0x0000000F) == 0x0000000F )
+			break;
+	}
+	if ( (temp2 & 0x0000000F) != 0x0000000F )
+	{
+		printk(KERN_ERR "cs4281: Codec failed to calibrate.  Status = %.8x.\n", temp2);
+		return -EIO;
+	}
+
+         // (10), Set the serial port timing configuration, so that the
+         // clock control circuit gets its clock from the right place.
+	writel(SERMC_PTC_AC97, card->pBA0+BA0_SERMC);              // (420h)=2.
+
+
+         // (11) Wait until we've sampled input slots 3 & 4 as valid, meaning
+         // that the codec is pumping ADC data across the AC link.
+	for(temp1=0; temp1<1000; temp1++)
+	{
+        	// Delay a mil to let things settle out and
+        	// to prevent retrying the read too quickly.
+        	delayus(1000);    //(test)
+
+        	// Read the input slot valid register;  See
+        	// if input slots 3 and 4 are valid yet.
+        	if( (readl(card->pBA0+BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4) ) ==  (ACISV_ISV3 | ACISV_ISV4))
+			break;    // Exit the 'for' if slots are valid.
+	}
+       	// If we never got valid data, exit initialization.
+	if( (readl(card->pBA0+BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4) ) != (ACISV_ISV3 | ACISV_ISV4))
+	{
+       		printk(KERN_ERR "cs4281: Never got valid data!\n");
+       		return -EIO;     // If no valid data, exit initialization.
+	}
+
+	// (12), Start digital data transfer of audio data to the codec.
+	writel(ACOSV_SLV3 | ACOSV_SLV4, card->pBA0+BA0_ACOSV);             // (468h)
+
+
+        //**************************************
+        // Unmute the Master and Alternate
+        // (headphone) volumes.  Set to max.
+        //**************************************
+	cs4281_write_ac97(card,BA0_AC97_HEADPHONE_VOLUME, 0);
+	cs4281_write_ac97(card,BA0_AC97_MASTER_VOLUME, 0);
+
+        //******************************************
+        // Power on the DAC(AddDACUser()from main())
+        //******************************************
+	cs4281_read_ac97(card,BA0_AC97_POWERDOWN, &temp1);
+	cs4281_write_ac97(card,BA0_AC97_POWERDOWN, temp1 &= 0xfdff);
+
+        // Wait until we sample a DAC ready state.
+	for(temp2=0; temp2<32; temp2++)
+	{
+		// Let's wait a mil to let things settle.
+		delayus(1000);
+		// Read the current state of the power control reg.
+        	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+		// If the DAC ready state bit is set, stop waiting.
+		if(temp1 & 0x2)
+        		break;
+	}
+
+        //******************************************
+        // Power on the ADC(AddADCUser()from main())
+        //******************************************
+	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+	cs4281_write_ac97(card, BA0_AC97_POWERDOWN, temp1 &= 0xfeff);
+
+        // Wait until we sample ADC ready state.
+	for(temp2=0; temp2<32; temp2++)
+	{
+		// Let's wait a mil to let things settle.
+		delayus(1000);
+        	// Read the current state of the power control reg.
+        	cs4281_read_ac97(card, BA0_AC97_POWERDOWN, &temp1);
+		// If the ADC ready state bit is set, stop waiting.
+		if(temp1 & 0x1)
+        		break;
+	}
+	// Set up 4281 Register contents that
+	// don't change for boot duration.
+
+	// For playback, we map AC97 slot 3 and 4(Left
+	// & Right PCM playback) to DMA Channel 0.
+	// Set the fifo to be 15 bytes at offset zero.
+
+	ac97_slotid = 0x01000f00;	// FCR0.RS[4:0]=1(=>slot4, right PCM playback).
+        				// FCR0.LS[4:0]=0(=>slot3, left PCM playback).
+                                 	// FCR0.SZ[6-0]=15; FCR0.OF[6-0]=0.
+	writel(ac97_slotid, card->pBA0 + BA0_FCR0);                 // (180h)
+	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR0);      // Turn on FIFO Enable.
+
+        // For capture, we map AC97 slot 10 and 11(Left
+        // and Right PCM Record) to DMA Channel 1.
+        // Set the fifo to be 15 bytes at offset sixteen.
+	ac97_slotid = 0x0B0A0f10;	// FCR1.RS[4:0]=11(=>slot11, right PCM record).
+               				// FCR1.LS[4:0]=10(=>slot10, left PCM record).
+					// FCR1.SZ[6-0]=15; FCR1.OF[6-0]=16.
+	writel(ac97_slotid | FCRn_PSH, card->pBA0 + BA0_FCR1);      // (184h)
+	writel(ac97_slotid | FCRn_FEN, card->pBA0 + BA0_FCR1);      // Turn on FIFO Enable.
+
+        // Map the Playback SRC to the same AC97 slots(3 & 4--
+        // --Playback left & right)as DMA channel 0.
+        // Map the record SRC to the same AC97 slots(10 & 11--
+        // -- Record left & right) as DMA channel 1.
+
+	ac97_slotid = 0x0b0a0100;	// SCRSA.PRSS[4:0]=1(=>slot4, right PCM playback).
+					// SCRSA.PLSS[4:0]=0(=>slot3, left PCM playback).
+					// SCRSA.CRSS[4:0]=11(=>slot11, right PCM record)
+					// SCRSA.CLSS[4:0]=10(=>slot10, left PCM record).
+	writel(ac97_slotid, card->pBA0 + BA0_SRCSA);                // (75ch)
+
+        // Set 'Half Terminal Count Interrupt Enable' and 'Terminal
+        // Count Interrupt Enable' in DMA Control Registers 0 & 1.
+        // Set 'MSK' flag to 1 to keep the DMA engines paused.
+	temp1 = (DCRn_HTCIE | DCRn_TCIE | DCRn_MSK);	 // (00030001h)
+	writel(temp1, card->pBA0 + BA0_DCR0);            // (154h
+	writel(temp1, card->pBA0 + BA0_DCR1);            // (15ch)
+
+        // Set 'Auto-Initialize Control' to 'enabled'; For playback,
+        // set 'Transfer Type Control'(TR[1:0]) to 'read transfer',
+        // for record, set Transfer Type Control to 'write transfer'.
+        // All other bits set to zero;  Some will be changed @ transfer start.
+	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_READ);   // (20000018h)
+	writel(temp1, card->pBA0 + BA0_DMR0);            // (150h)
+	temp1 = (DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE);  // (20000014h)
+	writel(temp1, card->pBA0 + BA0_DMR1);            // (158h)
+
+        // Enable DMA interrupts generally, and
+        // DMA0 & DMA1 interrupts specifically.
+	temp1 = readl(card->pBA0 + BA0_HIMR) &  0xfffbfcff;
+	writel(temp1, card->pBA0+BA0_HIMR);
+	return 0;
+}
+
+
+//******************************************************************************
+// "cs4281_play_rate()" --
+//******************************************************************************
+static void cs4281_play_rate(struct cs4281_state *card, u32 playrate)
+{
+	u32 DACSRvalue = 1;
+
+         // Based on the sample rate, program the DACSR register.
+	if(playrate == 8000)
+        	DACSRvalue = 5;
+	if(playrate == 11025)
+		DACSRvalue = 4;
+	else if(playrate == 22050)
+        	DACSRvalue = 2;
+	else if(playrate == 44100)
+	        DACSRvalue = 1;
+	else if((playrate <= 48000) && (playrate >= 6023))
+        	DACSRvalue = 24576000/(playrate*16);
+	else if(playrate < 6023)
+		// Not allowed by open.
+		return;
+	else if(playrate > 48000)
+		// Not allowed by open.
+		return;
+         //  Write the 'sample rate select code'
+         //  to the 'DAC Sample Rate' register.
+	writel(DACSRvalue, card->pBA0 + BA0_DACSR);           // (744h)
+}
+
+//******************************************************************************
+// "cs481_record_rate()" -- Initialize the record sample rate converter.
+//******************************************************************************
+static void cs481_record_rate(struct cs4281_state *card, u32 outrate)
+{
+	u32 ADCSRvalue = 1;
+
+         //
+         // Based on the sample rate, program the ADCSR register
+         //
+	if(outrate == 8000)
+        	ADCSRvalue = 5;
+	if(outrate == 11025)
+	        ADCSRvalue = 4;
+	else if(outrate == 22050)
+		ADCSRvalue = 2;
+	else if(outrate == 44100)
+		ADCSRvalue = 1;
+	else if((outrate <= 48000) && (outrate >= 6023))
+		ADCSRvalue = 24576000/(outrate*16);
+	else if(outrate < 6023)
+	{
+		// Not allowed by open.
+		return;
+	}
+	else if(outrate > 48000)
+	{
+	        // Not allowed by open.
+	        return;
+	}
+        //  Write the 'sample rate select code
+	//  to the 'ADC Sample Rate' register.
+	writel(ADCSRvalue, card->pBA0 + BA0_ADCSR);           // (748h)
+}
+
+
+
+static void stop_dac(struct cs4281_state *s)
+{
+        unsigned long flags;
+        unsigned temp1;
+
+        spin_lock_irqsave(&s->lock, flags);
+        s->ena &= ~FMODE_WRITE;
+        temp1 = readl(s->pBA0+ BA0_DCR0) | DCRn_MSK;     
+        writel(temp1, s->pBA0+BA0_DCR0);         
+
+        spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void start_dac(struct cs4281_state *s)
+{
+        unsigned long flags;
+        unsigned temp1;
+
+        spin_lock_irqsave(&s->lock, flags);
+        if (!(s->ena & FMODE_WRITE) && (s->dma_dac.mapped ||
+              s->dma_dac.count > 0) && s->dma_dac.ready)      {
+                s->ena |= FMODE_WRITE;
+                temp1 = readl(s->pBA0+BA0_DCR0) & ~DCRn_MSK;     // Clear DMA0 channel mask.
+                writel(temp1, s->pBA0+BA0_DCR0);                 // Start DMA'ing.
+                writel(HICR_IEV | HICR_CHGM, s->pBA0+BA0_HICR);     // Enable interrupts.              
+        
+                writel(7, s->pBA0+BA0_PPRVC);
+                writel(7, s->pBA0+BA0_PPLVC);
+        
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void stop_adc(struct cs4281_state *s)
+{
+        unsigned long flags;
+        unsigned temp1;
+
+        spin_lock_irqsave(&s->lock, flags);
+        s->ena &= ~FMODE_READ;
+        temp1 = readl(s->pBA0+ BA0_DCR1) | DCRn_MSK;     
+        writel(temp1, s->pBA0+BA0_DCR1);
+        spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+static void start_adc(struct cs4281_state *s)
+{
+        unsigned long flags;
+        unsigned temp1;
+
+        spin_lock_irqsave(&s->lock, flags);
+        if (!(s->ena & FMODE_READ) && (s->dma_adc.mapped
+              || s->dma_adc.count <= 
+                 (signed)(s->dma_adc.dmasize - 2*s->dma_adc.fragsize))
+              && s->dma_adc.ready)
+        {
+                s->ena |= FMODE_READ;
+                temp1 = readl(s->pBA0+BA0_DCR1) & ~ DCRn_MSK;         // Clear DMA1 channel mask bit.
+                writel(temp1, s->pBA0+BA0_DCR1);                      // Start recording
+                writel(HICR_IEV | HICR_CHGM, s->pBA0+BA0_HICR);       // Enable interrupts.
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+
+}
+
+
+// --------------------------------------------------------------------- 
+#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)     // == 3(for PC), = log base 2( buff sz = 32k).
+#define DMABUF_MINORDER 1                       // ==> min buffer size = 8K.
+
+
+static void dealloc_dmabuf(struct dmabuf *db)
+{
+        unsigned long map, mapend;
+
+        if (db->rawbuf) {
+                // Undo prog_dmabuf()'s marking the pages as reserved 
+                mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+                for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
+                        clear_bit(PG_reserved, &mem_map[map].flags);
+                free_pages((unsigned long)db->rawbuf, db->buforder);
+        }
+        db->rawbuf = NULL;
+        db->mapped = db->ready = 0;
+}
+
+
+static int prog_dmabuf(struct cs4281_state *s, struct dmabuf *db, int gfp_mask)
+{
+        int order;
+        unsigned bytespersec, temp1;
+        unsigned bufs, sample_shift = 0;
+        unsigned long map, mapend;
+
+        db->hwptr = db->swptr = db->total_bytes = db->count = db->error = db->endcleared = 0;
+        if (!db->rawbuf) {
+                db->ready = db->mapped = 0;
+                for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+                        if ((db->rawbuf = (void *)__get_free_pages(gfp_mask, order)))
+                                break;
+                if (!db->rawbuf)
+                        return -ENOMEM;
+                db->buforder = order;
+                // Now mark the pages as reserved; otherwise the 
+                // remap_page_range() in cs4281_mmap doesn't work.
+                // 1. get index to last page in mem_map array for rawbuf.
+                mapend = MAP_NR(db->rawbuf + (PAGE_SIZE << db->buforder) - 1);
+                
+                     // 2. mark each physical page in range as 'reserved'.
+                for (map = MAP_NR(db->rawbuf); map <= mapend; map++)
+                        set_bit(PG_reserved, &mem_map[map].flags);
+        }
+        if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
+                sample_shift++;
+        if (s->channels > 1)
+                sample_shift++;
+        bytespersec = s->rate << sample_shift;
+        bufs = PAGE_SIZE << db->buforder;
+
+
+#define INTERRUPT_RATE_MS       100                      // Interrupt rate in milliseconds.
+        db->numfrag = 2;
+        temp1 = bytespersec/(1000/INTERRUPT_RATE_MS);    // Nominal frag size(bytes/interrupt)
+        db->fragshift = 8;                               // Min 256 bytes.
+        while( 1 << db->fragshift  < temp1)              // Calc power of 2 frag size.
+                db->fragshift +=1;
+        db->fragsize = 1 << db->fragshift;               
+        db->dmasize = db->fragsize * 2;
+ 
+                // If the calculated size is larger than the allocated
+                //  buffer, divide the allocated buffer into 2 fragments.
+        if(db->dmasize > bufs) {
+                db->numfrag = 2;                                 // Two fragments.
+                db->fragsize = bufs >> 1;                        // Each 1/2 the alloc'ed buffer.
+                db->fragsamples = db->fragsize >> sample_shift;  // # samples/fragment.
+                db->dmasize =  bufs;                             // Use all the alloc'ed buffer.
+                
+                db->fragshift = 0;                               // Calculate 'fragshift'.
+                temp1 = db->fragsize;                            // update_ptr() uses it 
+                while( (temp1 >>=1) > 1)                         // to calc 'total-bytes'
+                     db->fragshift +=1;                          // returned in DSP_GETI/OPTR. 
+        }
+        return 0;
+}    
+
+
+static int prog_dmabuf_adc(struct cs4281_state *s)
+{
+        unsigned long va;
+        unsigned count;      
+        int c;
+        stop_adc(s);
+        if ((c = prog_dmabuf(s, &s->dma_adc, GFP_KERNEL | GFP_DMA)))
+                return c;
+             
+        va = virt_to_bus(s->dma_adc.rawbuf);
+        
+        count = s->dma_adc.dmasize;       
+       
+        if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
+                count /= 2;                      // 16-bit.
+                        
+        if(s->channels > 1)
+                count /= 2;                      // Assume stereo.
+          
+        writel(va, s->pBA0+BA0_DBA1);            // Set buffer start address.
+        writel(count-1, s->pBA0+BA0_DBC1);       // Set count. 
+        s->dma_adc.ready = 1;
+        return 0;
+}
+
+
+static int prog_dmabuf_dac(struct cs4281_state *s)
+{
+        unsigned long va;
+        unsigned count;
+        int c;
+        stop_dac(s);
+        if ((c = prog_dmabuf(s, &s->dma_dac, GFP_KERNEL)))
+                return c;
+        memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE))
+                                   ? 0x80 : 0, s->dma_dac.dmasize);      
+
+        va = virt_to_bus(s->dma_dac.rawbuf);
+
+        count = s->dma_dac.dmasize;       
+        if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE))
+                count /= 2;                      // 16-bit.
+      
+        if(s->channels > 1)
+                count /= 2;                      // Assume stereo.
+           
+        writel(va, s->pBA0+BA0_DBA0);               // Set buffer start address.
+        writel(count-1, s->pBA0+BA0_DBC0);       // Set count.             
+
+        s->dma_dac.ready = 1;
+        return 0;
+}
+
+
+static void clear_advance(void *buf, unsigned bsize, unsigned bptr, unsigned len, unsigned char c)
+{
+        if (bptr + len > bsize) {
+                unsigned x = bsize - bptr;
+                memset(((char *)buf) + bptr, c, x);
+                bptr = 0;
+                len -= x;
+        }
+        memset(((char *)buf) + bptr, c, len);
+}
+
+
+
+// call with spinlock held! 
+static void cs4281_update_ptr(struct cs4281_state *s)
+{
+        int diff;
+        unsigned hwptr, va, temp1;
+
+        // update ADC pointer 
+        if (s->ena & FMODE_READ) {
+                hwptr = readl(s->pBA0+BA0_DCA1);          // Read capture DMA address.
+                va = virt_to_bus(s->dma_adc.rawbuf);
+                //trw added fix  hwptr -= (unsigned)s->dma_adc.rawbuf;
+                hwptr -= (unsigned)va;                 
+                diff = (s->dma_adc.dmasize + hwptr - s->dma_adc.hwptr) % s->dma_adc.dmasize;
+                s->dma_adc.hwptr = hwptr;
+                s->dma_adc.total_bytes += diff;
+                s->dma_adc.count += diff;
+                if (s->dma_adc.mapped) {
+                        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+                                wake_up(&s->dma_adc.wait);
+                } else {
+                        if (s->dma_adc.count > 0)
+                                wake_up(&s->dma_adc.wait);
+                }
+        }
+        // update DAC pointer 
+	//
+	// check for end of buffer, means that we are going to wait for another interrupt
+	// to allow silence to fill the fifos on the part, to keep pops down to a minimum.
+	//
+        if ( (s->ena & FMODE_WRITE) && (!s->endofbuffer) )
+	{
+                hwptr = readl(s->pBA0+BA0_DCA0);          // Read play DMA address.
+                va = virt_to_bus(s->dma_dac.rawbuf);
+                hwptr -= (unsigned)va;
+                diff = (s->dma_dac.dmasize + hwptr - s->dma_dac.hwptr) % s->dma_dac.dmasize;
+                s->dma_dac.hwptr = hwptr;
+                s->dma_dac.total_bytes += diff;
+                if (s->dma_dac.mapped) {
+                        s->dma_dac.count += diff;
+                        if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
+                                wake_up(&s->dma_dac.wait);
+                } else {
+                        s->dma_dac.count -= diff;
+                        if (s->dma_dac.count <= 0) {
+                                s->ena &= ~FMODE_WRITE;
+                                temp1 = readl(s->pBA0+BA0_DCR0);
+			//
+			// fill with silence, and wait on turning off the DAC until interrupt routine.
+			// wait on "Poke(pBA0+BA0_DCR0, temp1 | DCRn_MSK);    // Stop Play DMA"
+			//
+				memset(s->dma_dac.rawbuf, (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0, 
+					s->dma_dac.dmasize); 
+				s->endofbuffer = 1;
+                        } else if (s->dma_dac.count <= (signed)s->dma_dac.fragsize
+                                                         && !s->dma_dac.endcleared) {
+                                clear_advance(s->dma_dac.rawbuf, 
+                                              s->dma_dac.dmasize, s->dma_dac.swptr,
+                                              s->dma_dac.fragsize,
+                                              (s->fmt & (AFMT_U8 | AFMT_U16_LE)) ? 0x80 : 0);
+                                s->dma_dac.endcleared = 1;
+                        }
+                        if (s->dma_dac.count < (signed)s->dma_dac.dmasize)
+                                wake_up(&s->dma_dac.wait);
+                }
+        }
+}
+
+
+// --------------------------------------------------------------------- 
+
+static void prog_codec(struct cs4281_state *s)
+{
+        unsigned long flags;
+        unsigned temp1, format;
+
+        spin_lock_irqsave(&s->lock, flags);
+        temp1 = readl(s->pBA0+BA0_DCR0);
+        writel(temp1 | DCRn_MSK, s->pBA0+BA0_DCR0);   // Stop play DMA, if active.
+        temp1 = readl(s->pBA0+BA0_DCR1);
+        writel(temp1 | DCRn_MSK, s->pBA0+BA0_DCR1);   // Stop capture DMA, if active.
+ 
+        // program sampling rates  
+        // Note, for CS4281, capture & play rates can be set independently.
+        cs481_record_rate(s, s->rate); 
+               
+        // program ADC parameters 
+        format = DMRn_DMA | DMRn_AUTO | DMRn_TR_WRITE;
+        if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) { // 16-bit
+        if(s->fmt & (AFMT_S16_BE | AFMT_U16_BE))  // Big-endian?
+                format |= DMRn_BEND;  
+                if(s->fmt & (AFMT_U16_LE  | AFMT_U16_BE)) 
+                        format |= DMRn_USIGN;         // Unsigned.      
+        }          
+        else
+                format |= DMRn_SIZE8 | DMRn_USIGN;    // 8-bit, unsigned
+        if(s->channels < 2)
+                format |= DMRn_MONO;
+
+        writel(format, s->pBA0+BA0_DMR1);       
+       
+  
+        // program DAC parameters 
+        format = DMRn_DMA | DMRn_AUTO | DMRn_TR_READ;
+        if(s->fmt & (AFMT_S16_LE | AFMT_U16_LE | AFMT_S16_BE | AFMT_U16_BE)) { // 16-bit
+                if(s->fmt & (AFMT_S16_BE | AFMT_U16_BE))  
+                        format |= DMRn_BEND;          // Big Endian.
+                if(s->fmt & (AFMT_U16_LE  | AFMT_U16_BE)) 
+                        format |= DMRn_USIGN;         // Unsigned.      
+        }          
+        else
+                format |= DMRn_SIZE8 | DMRn_USIGN;    // 8-bit, unsigned
+        
+        if(s->channels < 2)
+                format |= DMRn_MONO;
+
+        writel(format, s->pBA0+BA0_DMR0);       
+        cs4281_play_rate(s, s->rate);
+
+        s->ena = 0;     // Neither writing or reading.
+        spin_unlock_irqrestore(&s->lock, flags);
+}
+
+
+// --------------------------------------------------------------------- 
+
+static const char invalid_magic[] = KERN_CRIT "cs4281: invalid magic value\n";
+
+#define VALIDATE_STATE(s)                         \
+({                                                \
+        if (!(s) || (s)->magic != CS4281_MAGIC) { \
+                printk(invalid_magic);            \
+                return -ENXIO;                    \
+        }                                         \
+})
+
+// --------------------------------------------------------------------- 
+
+
+static int mixer_ioctl(struct cs4281_state *s, unsigned int cmd, unsigned long arg)
+{
+	// Index to mixer_src[] is value of AC97 Input Mux Select Reg.
+	// Value of array member is recording source Device ID Mask.
+        static const unsigned int mixer_src[8] = {
+                SOUND_MASK_MIC, SOUND_MASK_CD, 0, SOUND_MASK_LINE1,
+                SOUND_MASK_LINE, SOUND_MASK_VOLUME, 0, 0
+        };
+             
+        // Index of mixtable1[] member is Device ID 
+        // and must be <= SOUND_MIXER_NRDEVICES.
+        // Value of array member is index into s->mix.vol[]
+        static const unsigned char mixtable1[SOUND_MIXER_NRDEVICES] = {
+                [SOUND_MIXER_PCM]     = 1,   // voice 
+                [SOUND_MIXER_LINE1]   = 2,   // AUX
+                [SOUND_MIXER_CD]      = 3,   // CD 
+                [SOUND_MIXER_LINE]    = 4,   // Line 
+                [SOUND_MIXER_SYNTH]   = 5,   // FM
+                [SOUND_MIXER_MIC]     = 6,   // Mic 
+                [SOUND_MIXER_SPEAKER] = 7,   // Speaker 
+                [SOUND_MIXER_RECLEV]  = 8,   // Recording level 
+                [SOUND_MIXER_VOLUME]  = 9    // Master Volume 
+        };
+        
+        
+        static const unsigned mixreg[] = {
+                BA0_AC97_PCM_OUT_VOLUME,
+                BA0_AC97_AUX_VOLUME, 
+                BA0_AC97_CD_VOLUME, 
+                BA0_AC97_LINE_IN_VOLUME
+        };
+        unsigned char l, r, rl, rr, vidx;
+        unsigned char attentbl[11] = {63,42,26,17,14,11,8,6,4,2,0};
+        unsigned temp1;
+        int i, val;
+
+        VALIDATE_STATE(s);
+ 
+        if (cmd == SOUND_MIXER_PRIVATE1) {
+                // enable/disable/query mixer preamp 
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (val != -1) {
+                        cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+                        temp1 = val ? (temp1 | 0x40) : (temp1 & 0xffbf);
+                        cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
+                }
+                cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+                val = (temp1 & 0x40) ? 1 : 0;
+                return put_user(val, (int *)arg);
+        }
+        if (cmd == SOUND_MIXER_PRIVATE2) {
+                // enable/disable/query spatializer 
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (val != -1) {
+                        temp1 = (val & 0x3f) >> 2;
+                        cs4281_write_ac97(s, BA0_AC97_3D_CONTROL, temp1);
+                        cs4281_read_ac97(s, BA0_AC97_GENERAL_PURPOSE, &temp1);
+                        cs4281_write_ac97(s, BA0_AC97_GENERAL_PURPOSE,temp1 | 0x2000);
+                }
+                cs4281_read_ac97(s, BA0_AC97_3D_CONTROL, &temp1);
+                return put_user((temp1 << 2) | 3, (int *)arg);
+        }
+        if (cmd == SOUND_MIXER_INFO) {
+                mixer_info info;
+                strncpy(info.id, "CS4281", sizeof(info.id));
+                strncpy(info.name, "Crystal CS4281", sizeof(info.name));
+                info.modify_counter = s->mix.modcnt;
+                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                        return -EFAULT;
+                return 0;
+        }
+        if (cmd == SOUND_OLD_MIXER_INFO) {
+                _old_mixer_info info;
+                strncpy(info.id, "CS4281", sizeof(info.id));
+                strncpy(info.name, "Crystal CS4281", sizeof(info.name));
+                if (copy_to_user((void *)arg, &info, sizeof(info)))
+                        return -EFAULT;
+                return 0;
+        }
+        if (cmd == OSS_GETVERSION)
+                return put_user(SOUND_VERSION, (int *)arg);
+        
+        if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
+                return -EINVAL;
+        
+             // If ioctl has only the IOC_READ bit(bit 31)
+             // on, process the only-read commands. 
+        if (_IOC_DIR(cmd) == _IOC_READ) {
+                switch (_IOC_NR(cmd)) {
+                case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source 
+                    cs4281_read_ac97(s, BA0_AC97_RECORD_SELECT, &temp1);
+                    return put_user(mixer_src[temp1 & 7], (int *)arg);
+
+                case SOUND_MIXER_DEVMASK: // Arg contains a bit for each supported device 
+                        return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
+                                        SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
+                                        SOUND_MASK_VOLUME | SOUND_MASK_RECLEV |
+                                        SOUND_MASK_SPEAKER, (int *)arg);
+
+                case SOUND_MIXER_RECMASK: // Arg contains a bit for each supported recording source 
+                        return put_user(SOUND_MASK_LINE | SOUND_MASK_MIC | SOUND_MASK_CD 
+                                      | SOUND_MASK_VOLUME | SOUND_MASK_LINE1, (int *)arg);
+
+                case SOUND_MIXER_STEREODEVS: // Mixer channels supporting stereo 
+                        return put_user(SOUND_MASK_PCM | SOUND_MASK_SYNTH | SOUND_MASK_CD |
+                                        SOUND_MASK_LINE | SOUND_MASK_LINE1 | SOUND_MASK_MIC |
+                                        SOUND_MASK_VOLUME | SOUND_MASK_RECLEV, (int *)arg);
+
+                case SOUND_MIXER_CAPS:
+                        return put_user(SOUND_CAP_EXCL_INPUT, (int *)arg);
+
+                default:
+                        i = _IOC_NR(cmd);
+                        if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
+                                return -EINVAL;
+                        return put_user(s->mix.vol[vidx-1], (int *)arg);
+                }
+        }
+        
+             // If ioctl doesn't have both the IOC_READ and 
+             // the IOC_WRITE bit set, return invalid.
+        if (_IOC_DIR(cmd) != (_IOC_READ|_IOC_WRITE))
+                return -EINVAL;
+        
+             // Increment the count of volume writes.
+        s->mix.modcnt++;
+             
+             // Isolate the command; it must be a write.
+        switch (_IOC_NR(cmd)) {
+        
+        case SOUND_MIXER_RECSRC: // Arg contains a bit for each recording source 
+                get_user_ret(val, (int *)arg, -EFAULT);
+                i = hweight32(val);                 // i = # bits on in val.
+                if (i != 1)                         // One & only 1 bit must be on.
+                        return 0;
+                for(i=0; i<sizeof(mixer_src)/sizeof(int); i++) {
+                        if(val == mixer_src[i]) {
+                                temp1 = (i << 8) | i;  
+                                cs4281_write_ac97(s, BA0_AC97_RECORD_SELECT, temp1);
+                                return 0;
+                        }
+                }
+                return 0;
+
+        case SOUND_MIXER_VOLUME:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                l = val & 0xff;
+                if(l > 100)
+                        l = 100;                    // Max soundcard.h vol is 100.
+                if(l < 6) {
+                        rl = 63;
+                        l  = 0;
+                }
+                else 
+                        rl = attentbl[(10*l)/100];  // Convert 0-100 vol to 63-0 atten.
+                        
+                        r = (val >> 8) & 0xff;
+                        if (r > 100)
+                                r = 100;            // Max right volume is 100, too
+                        if(r < 6) {
+                                rr = 63;
+                                r  = 0;
+                        }
+                        else 
+                               rr = attentbl[(10*r)/100];   // Convert volume to attenuation.
+                
+                if ((rl > 60 ) && (rr > 60))        // If both l & r are 'low',          
+                        temp1 = 0x8000;             //  turn on the mute bit.
+                else
+                        temp1 = 0;
+                
+                temp1 |= (rl << 8) | rr;
+                
+                cs4281_write_ac97(s, BA0_AC97_MASTER_VOLUME, temp1);
+                cs4281_write_ac97(s, BA0_AC97_HEADPHONE_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+                s->mix.vol[8] = ((unsigned int)r << 8) | l;
+#else
+                s->mix.vol[8] = val;
+#endif
+                return put_user(s->mix.vol[8], (int *)arg);
+
+        case SOUND_MIXER_SPEAKER:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                l = val & 0xff;
+                if (l > 100)
+                        l = 100;
+                if(l < 3 ) {
+                        rl = 0;
+                        l = 0;
+                }
+                else {
+                        rl = (l*2 - 5)/13;          // Convert 0-100 range to 0-15.
+                        l = (rl*13 +5)/2;
+                }
+
+                if (rl < 3){
+                       temp1 = 0x8000;
+                       rl     = 0;
+                }
+                else
+                       temp1 = 0;
+                rl = 15 - rl;                       // Convert volume to attenuation.
+                temp1 |= rl << 1;
+                cs4281_write_ac97(s, BA0_AC97_PC_BEEP_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+                s->mix.vol[6] = l << 8;
+#else
+                s->mix.vol[6] = val;
+#endif
+                return put_user(s->mix.vol[6], (int *)arg);
+
+        case SOUND_MIXER_RECLEV:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                l = val & 0xff;
+                if (l > 100)
+                        l = 100;
+                r = (val >> 8) & 0xff;
+                if (r > 100)
+                        r = 100;
+                rl = (l*2 - 5) / 13;                // Convert 0-100 scale to 0-15.
+                rr = (r*2 - 5) / 13;
+                if (rl <3 && rr <3)
+                        temp1 = 0x8000;
+                else
+                        temp1 = 0;
+
+                temp1 = temp1 | (rl << 8) | rr;
+                cs4281_write_ac97(s, BA0_AC97_RECORD_GAIN, temp1); 
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+                s->mix.vol[7] = ((unsigned int)r << 8) | l;
+#else
+                s->mix.vol[7] = val;
+#endif
+                return put_user(s->mix.vol[7], (int *)arg);
+
+        case SOUND_MIXER_MIC:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                l = val & 0xff;
+                if (l > 100)
+                        l = 100;
+                if (l < 1) {
+                        l = 0;
+                        rl = 0;
+                }
+                else {
+                        rl = ((unsigned)l*5 - 4)/16; // Convert 0-100 range to 0-31.
+                        l  = (rl*16 +4)/5;
+                }
+                cs4281_read_ac97(s, BA0_AC97_MIC_VOLUME, &temp1);
+                temp1 &= 0x40;                      // Isolate 20db gain bit.
+                if (rl < 3){
+                       temp1 |= 0x8000;
+                       rl     = 0;
+                }
+                rl = 31 - rl;                       // Convert volume to attenuation.
+                temp1 |= rl; 
+                cs4281_write_ac97(s, BA0_AC97_MIC_VOLUME, temp1);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+                s->mix.vol[5] = val << 8;
+#else
+                s->mix.vol[5] = val;
+#endif
+                return put_user(s->mix.vol[5], (int *)arg);
+        
+        
+        case SOUND_MIXER_SYNTH:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                l = val & 0xff;
+                if (l > 100)
+                        l = 100;
+                get_user_ret(val, (int *)arg, -EFAULT);
+                r = (val >> 8) & 0xff;
+                if (r > 100)
+                        r = 100;
+                rl = (l * 2 - 11)/3;        // Convert 0-100 range to 0-63.
+                rr = (r * 2 - 11)/3;
+                if (rl < 3)                 // If l is low, turn on
+                        temp1 = 0x0080;     //  the mute bit.
+                else
+                        temp1 = 0;
+
+                rl = 63 - rl;               // Convert vol to attenuation.
+                writel(temp1|rl, s->pBA0+BA0_FMLVC);
+                if (rr < 3)                 //  If rr is low, turn on
+                        temp1 = 0x0080;     //   the mute bit.
+                else
+                        temp1 = 0;
+                rr = 63 - rr;               // Convert vol to attenuation.
+                writel(temp1 | rr, s->pBA0+BA0_FMRVC);
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+                s->mix.vol[4] = (r << 8) | l;
+#else
+                s->mix.vol[4] = val;
+#endif
+                return put_user(s->mix.vol[4], (int *)arg);
+
+                
+        default:
+                i = _IOC_NR(cmd);
+                if (i >= SOUND_MIXER_NRDEVICES || !(vidx = mixtable1[i]))
+                        return -EINVAL;
+                get_user_ret(val, (int *)arg, -EFAULT);
+                l = val & 0xff;
+                if (l > 100)
+                        l = 100;
+                if (l < 1) {
+                        l = 0;
+                        rl = 31;
+                }
+                else 
+                        rl = (attentbl[(l*10)/100])>>1;
+                
+                r = (val >> 8) & 0xff;
+                if (r > 100)
+                        r = 100;
+                if (r < 1) {
+                        r = 0;
+                        rr = 31;
+                }
+                else 
+                        rr = (attentbl[(r*10)/100])>>1;                        
+                if ((rl > 30) && (rr > 30))
+                        temp1 = 0x8000;
+                else
+                        temp1 = 0;
+                temp1 = temp1 | (rl << 8) | rr;              
+                cs4281_write_ac97(s, mixreg[vidx-1], temp1);
+                
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+                s->mix.vol[vidx-1] = ((unsigned int)r << 8) | l;
+#else
+                s->mix.vol[vidx-1] = val;
+#endif
+                return put_user(s->mix.vol[vidx-1], (int *)arg);
+        }
+}
+
+
+// --------------------------------------------------------------------- 
+
+static loff_t cs4281_llseek(struct file *file, loff_t offset, int origin)
+{
+        return -ESPIPE;
+}
+
+
+// --------------------------------------------------------------------- 
+
+static int cs4281_open_mixdev(struct inode *inode, struct file *file)
+{
+        int minor = MINOR(inode->i_rdev);
+        struct cs4281_state *s = devs;
+
+        while (s && s->dev_mixer != minor)
+                s = s->next;
+        if (!s)
+                return -ENODEV;
+        VALIDATE_STATE(s);
+        file->private_data = s;
+        MOD_INC_USE_COUNT;
+        return 0;
+}
+
+
+static int cs4281_release_mixdev(struct inode *inode, struct file *file)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+
+        VALIDATE_STATE(s);
+        MOD_DEC_USE_COUNT;
+        return 0;
+}
+
+
+static int cs4281_ioctl_mixdev(struct inode *inode, struct file *file,
+                               unsigned int cmd, unsigned long arg)
+{
+        return mixer_ioctl((struct cs4281_state *)file->private_data, cmd, arg);
+}
+
+
+// ******************************************************************************************
+//   Mixer file operations struct.
+// ******************************************************************************************
+static /*const*/ struct file_operations cs4281_mixer_fops = {
+        &cs4281_llseek,
+        NULL,  // read 
+        NULL,  // write 
+        NULL,  // readdir 
+        NULL,  // poll 
+        &cs4281_ioctl_mixdev,
+        NULL,  // mmap 
+        &cs4281_open_mixdev,
+        NULL,  // flush 
+        &cs4281_release_mixdev,
+        NULL,  // fsync 
+        NULL,  // fasync 
+        NULL,  // check_media_change 
+        NULL,  // revalidate 
+        NULL,  // lock 
+};
+
+
+// --------------------------------------------------------------------- 
+
+static int drain_dac(struct cs4281_state *s, int nonblock)
+{
+        DECLARE_WAITQUEUE(wait, current);
+        unsigned long flags;
+        int count;
+        unsigned tmo;
+
+        if (s->dma_dac.mapped)
+                return 0;
+        current->state = TASK_INTERRUPTIBLE;
+        add_wait_queue(&s->dma_dac.wait, &wait);
+        for (;;) {
+                spin_lock_irqsave(&s->lock, flags);
+                count = s->dma_dac.count;
+                spin_unlock_irqrestore(&s->lock, flags);
+                if (count <= 0)
+                        break;
+                if (signal_pending(current))
+                        break;
+                if (nonblock) {
+                        remove_wait_queue(&s->dma_dac.wait, &wait);
+                        current->state = TASK_RUNNING;
+                        return -EBUSY;
+                }
+                tmo = 3 * HZ * (count + s->dma_dac.fragsize) / 2 / s->rate;
+                if (s->fmt & (AFMT_S16_LE | AFMT_U16_LE))
+                        tmo >>= 1;
+                if (s->channels > 1)
+                        tmo >>= 1;
+                if (!schedule_timeout(tmo + 1))
+                        printk(KERN_DEBUG "cs4281: dma timed out??\n");
+        }
+        remove_wait_queue(&s->dma_dac.wait, &wait);
+        current->state = TASK_RUNNING;
+        if (signal_pending(current))
+                return -ERESTARTSYS;
+        return 0;
+}
+
+
+// --------------------------------------------------------------------- 
+
+static ssize_t cs4281_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        ssize_t ret;
+        unsigned long flags;
+        unsigned swptr;
+        int cnt;
+
+        VALIDATE_STATE(s);
+        if (ppos != &file->f_pos)
+                return -ESPIPE;
+        if (s->dma_adc.mapped)
+                return -ENXIO;
+        if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+                return ret;
+        if (!access_ok(VERIFY_WRITE, buffer, count))
+                return -EFAULT;
+        ret = 0;
+        while (count > 0) {
+                spin_lock_irqsave(&s->lock, flags);
+                swptr = s->dma_adc.swptr;
+                cnt = s->dma_adc.dmasize-swptr;
+                if (s->dma_adc.count < cnt)
+                        cnt = s->dma_adc.count;
+                spin_unlock_irqrestore(&s->lock, flags);
+                if (cnt > count)
+                        cnt = count;
+                if (cnt <= 0) {
+                        start_adc(s);
+                         if (file->f_flags & O_NONBLOCK)
+                                return ret ? ret : -EAGAIN;
+                        interruptible_sleep_on(&s->dma_adc.wait);
+                        if (signal_pending(current))
+                                return ret ? ret : -ERESTARTSYS;
+                        continue;
+                }
+                if (copy_to_user(buffer, s->dma_adc.rawbuf + swptr, cnt))
+                        return ret ? ret : -EFAULT;
+                swptr = (swptr + cnt) % s->dma_adc.dmasize;
+                spin_lock_irqsave(&s->lock, flags);
+                s->dma_adc.swptr = swptr;
+                s->dma_adc.count -= cnt;
+                spin_unlock_irqrestore(&s->lock, flags);
+                count -= cnt;
+                buffer += cnt;
+                ret += cnt;
+                start_adc(s);
+        }
+        return ret;
+}
+
+
+static ssize_t cs4281_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        ssize_t ret;
+        unsigned long flags;
+        unsigned swptr;
+        int cnt;
+
+        VALIDATE_STATE(s);
+
+        if (ppos != &file->f_pos)
+                return -ESPIPE;
+        if (s->dma_dac.mapped)
+                return -ENXIO;
+        if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+                return ret;
+        if (!access_ok(VERIFY_READ, buffer, count))
+                return -EFAULT;
+        ret = 0;
+        while (count > 0) {
+                spin_lock_irqsave(&s->lock, flags);
+                if (s->dma_dac.count < 0) {
+                        s->dma_dac.count = 0;
+                        s->dma_dac.swptr = s->dma_dac.hwptr;
+                }
+                swptr = s->dma_dac.swptr;
+                cnt = s->dma_dac.dmasize-swptr;
+                if (s->dma_dac.count + cnt > s->dma_dac.dmasize)
+                        cnt = s->dma_dac.dmasize - s->dma_dac.count;
+                spin_unlock_irqrestore(&s->lock, flags);
+                if (cnt > count)
+                        cnt = count;
+                if (cnt <= 0) {
+                        start_dac(s);
+                        if (file->f_flags & O_NONBLOCK)
+                                return ret ? ret : -EAGAIN;
+                        interruptible_sleep_on(&s->dma_dac.wait);
+                        if (signal_pending(current))
+                                return ret ? ret : -ERESTARTSYS;
+                        continue;
+                }
+                if (copy_from_user(s->dma_dac.rawbuf + swptr, buffer, cnt))
+                        return ret ? ret : -EFAULT;
+                swptr = (swptr + cnt) % s->dma_dac.dmasize;
+                spin_lock_irqsave(&s->lock, flags);
+                s->dma_dac.swptr = swptr;
+                s->dma_dac.count += cnt;
+                s->dma_dac.endcleared = 0;
+                spin_unlock_irqrestore(&s->lock, flags);
+                count -= cnt;
+                buffer += cnt;
+                ret += cnt;
+                start_dac(s);
+        }
+        return ret;
+}
+
+
+static unsigned int cs4281_poll(struct file *file, struct poll_table_struct *wait)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        unsigned long flags;
+        unsigned int mask = 0;
+
+        VALIDATE_STATE(s);
+        if (file->f_mode & FMODE_WRITE)
+                poll_wait(file, &s->dma_dac.wait, wait);
+        if (file->f_mode & FMODE_READ)
+                poll_wait(file, &s->dma_adc.wait, wait);
+        spin_lock_irqsave(&s->lock, flags);
+        cs4281_update_ptr(s);
+        if (file->f_mode & FMODE_READ) {
+                if (s->dma_adc.mapped) {
+                        if (s->dma_adc.count >= (signed)s->dma_adc.fragsize)
+                                mask |= POLLIN | POLLRDNORM;
+                } else {
+                        if (s->dma_adc.count > 0)
+                                mask |= POLLIN | POLLRDNORM;
+                }
+        }
+        if (file->f_mode & FMODE_WRITE) {
+                if (s->dma_dac.mapped) {
+                        if (s->dma_dac.count >= (signed)s->dma_dac.fragsize)
+                                mask |= POLLOUT | POLLWRNORM;
+                } else {
+                        if ((signed)s->dma_dac.dmasize > s->dma_dac.count)
+                                mask |= POLLOUT | POLLWRNORM;
+                }
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return mask;
+}
+
+
+static int cs4281_mmap(struct file *file, struct vm_area_struct *vma)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        struct dmabuf *db;
+        int ret;
+        unsigned long size;
+
+        VALIDATE_STATE(s);
+        if (vma->vm_flags & VM_WRITE) {
+                if ((ret = prog_dmabuf_dac(s)) != 0)
+                        return ret;
+                db = &s->dma_dac;
+        } else if (vma->vm_flags & VM_READ) {
+                if ((ret = prog_dmabuf_adc(s)) != 0)
+                        return ret;
+                db = &s->dma_adc;
+        } else
+                return -EINVAL;
+        if (vma->vm_offset != 0)
+                return -EINVAL;
+        size = vma->vm_end - vma->vm_start;
+        if (size > (PAGE_SIZE << db->buforder))
+                return -EINVAL;
+        if (remap_page_range(vma->vm_start, virt_to_phys(db->rawbuf), size, vma->vm_page_prot))
+                return -EAGAIN;
+        db->mapped = 1;
+        return 0;
+}
+
+
+static int cs4281_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        unsigned long flags;
+        audio_buf_info abinfo;
+        count_info cinfo;
+        int val, mapped, ret;
+  
+        VALIDATE_STATE(s);
+        mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) ||
+                ((file->f_mode & FMODE_READ) && s->dma_adc.mapped);
+        switch (cmd) {
+        case OSS_GETVERSION:
+                return put_user(SOUND_VERSION, (int *)arg);
+
+        case SNDCTL_DSP_SYNC:
+                if (file->f_mode & FMODE_WRITE)
+                        return drain_dac(s, 0/*file->f_flags & O_NONBLOCK*/);
+                return 0;
+
+        case SNDCTL_DSP_SETDUPLEX:
+                return 0;
+
+        case SNDCTL_DSP_GETCAPS:
+                return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg);
+
+        case SNDCTL_DSP_RESET:
+                if (file->f_mode & FMODE_WRITE) {
+                        stop_dac(s);
+                        synchronize_irq();
+                        s->dma_dac.swptr = s->dma_dac.hwptr = s->dma_dac.count = s->dma_dac.total_bytes = 0;
+                }
+                if (file->f_mode & FMODE_READ) {
+                        stop_adc(s);
+                        synchronize_irq();
+                        s->dma_adc.swptr = s->dma_adc.hwptr = s->dma_adc.count = s->dma_adc.total_bytes = 0;
+                }
+                prog_codec(s);
+                return 0;
+
+        case SNDCTL_DSP_SPEED:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (val >= 0) {
+                        stop_adc(s);
+                        stop_dac(s);
+                        s->dma_adc.ready = s->dma_dac.ready = 0;
+                        // program sampling rates 
+                        if (val > 48000)
+                                val = 48000;
+                        if (val < 6300)
+                                val = 6300;
+                        s->rate = val;
+                        prog_codec(s);
+                }
+                return put_user(s->rate, (int *)arg);
+
+        case SNDCTL_DSP_STEREO:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                stop_adc(s);
+                stop_dac(s);
+                s->dma_adc.ready = s->dma_dac.ready = 0;
+                // program channels 
+                s->channels = val ? 2 : 1;
+                prog_codec(s);
+                return 0;
+
+        case SNDCTL_DSP_CHANNELS:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (val != 0) {
+                        stop_adc(s);
+                        stop_dac(s);
+                        s->dma_adc.ready = s->dma_dac.ready = 0;
+                        // program channels 
+                        s->channels = val ? 2 : 1;
+                        prog_codec(s);
+                }
+                return put_user(s->channels, (int *)arg);
+
+        case SNDCTL_DSP_GETFMTS: // Returns a mask 
+                return put_user(AFMT_S16_LE|AFMT_U16_LE|AFMT_S8|AFMT_U8, (int *)arg);
+
+        case SNDCTL_DSP_SETFMT: // Selects ONE fmt
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (val != AFMT_QUERY) {
+                        stop_adc(s);
+                        stop_dac(s);
+                        s->dma_adc.ready = s->dma_dac.ready = 0;
+                        // program format 
+                        if (val != AFMT_S16_LE && val != AFMT_U16_LE &&
+                            val != AFMT_S8 && val != AFMT_U8)
+                                val = AFMT_U8;
+                        s->fmt = val;
+                        prog_codec(s);
+                }
+                return put_user(s->fmt, (int *)arg);
+
+        case SNDCTL_DSP_POST:
+                return 0;
+
+        case SNDCTL_DSP_GETTRIGGER:
+                val = 0;
+                if (file->f_mode & s->ena & FMODE_READ)
+                        val |= PCM_ENABLE_INPUT;
+                if (file->f_mode & s->ena & FMODE_WRITE)
+                        val |= PCM_ENABLE_OUTPUT;
+                return put_user(val, (int *)arg);
+
+        case SNDCTL_DSP_SETTRIGGER:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (file->f_mode & FMODE_READ) {
+                        if (val & PCM_ENABLE_INPUT) {
+                                if (!s->dma_adc.ready && (ret = prog_dmabuf_adc(s)))
+                                        return ret;
+                                start_adc(s);
+                        } else
+                                stop_adc(s);
+                }
+                if (file->f_mode & FMODE_WRITE) {
+                        if (val & PCM_ENABLE_OUTPUT) {
+                                if (!s->dma_dac.ready && (ret = prog_dmabuf_dac(s)))
+                                        return ret;
+                                start_dac(s);
+                        } else
+                                stop_dac(s);
+                }
+                return 0;
+
+        case SNDCTL_DSP_GETOSPACE:
+                if (!(file->f_mode & FMODE_WRITE))
+                        return -EINVAL;
+                if (!(s->ena & FMODE_WRITE) && (val = prog_dmabuf_dac(s)) != 0)
+                        return val;
+                spin_lock_irqsave(&s->lock, flags);
+                cs4281_update_ptr(s);
+                abinfo.fragsize = s->dma_dac.fragsize;
+                abinfo.bytes = s->dma_dac.dmasize - s->dma_dac.count;
+                abinfo.fragstotal = s->dma_dac.numfrag;
+                abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift;  
+                spin_unlock_irqrestore(&s->lock, flags);
+                return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+        case SNDCTL_DSP_GETISPACE:
+                if (!(file->f_mode & FMODE_READ))
+                        return -EINVAL;
+                if (!(s->ena & FMODE_READ) && (val = prog_dmabuf_adc(s)) != 0)
+                        return val;
+                spin_lock_irqsave(&s->lock, flags);
+                cs4281_update_ptr(s);
+                abinfo.fragsize = s->dma_adc.fragsize;
+                abinfo.bytes = s->dma_adc.count;
+                abinfo.fragstotal = s->dma_adc.numfrag;
+                abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift;
+                spin_unlock_irqrestore(&s->lock, flags);
+                return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+        case SNDCTL_DSP_NONBLOCK:
+                file->f_flags |= O_NONBLOCK;
+                return 0;
+
+        case SNDCTL_DSP_GETODELAY:
+                if (!(file->f_mode & FMODE_WRITE))
+                        return -EINVAL;
+                spin_lock_irqsave(&s->lock, flags);
+                cs4281_update_ptr(s);
+                val = s->dma_dac.count;
+                spin_unlock_irqrestore(&s->lock, flags);
+                return put_user(val, (int *)arg);
+
+        case SNDCTL_DSP_GETIPTR:
+                if (!(file->f_mode & FMODE_READ))
+                        return -EINVAL;
+                spin_lock_irqsave(&s->lock, flags);
+                cs4281_update_ptr(s);
+                cinfo.bytes = s->dma_adc.total_bytes;
+                cinfo.blocks = s->dma_adc.count >> s->dma_adc.fragshift;
+                cinfo.ptr = s->dma_adc.hwptr;
+                if (s->dma_adc.mapped)
+                        s->dma_adc.count &= s->dma_adc.fragsize-1;
+                spin_unlock_irqrestore(&s->lock, flags);
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+        case SNDCTL_DSP_GETOPTR:
+                if (!(file->f_mode & FMODE_WRITE))
+                        return -EINVAL;
+                spin_lock_irqsave(&s->lock, flags);
+                cs4281_update_ptr(s);
+                cinfo.bytes = s->dma_dac.total_bytes;
+                cinfo.blocks = s->dma_dac.count >> s->dma_dac.fragshift;
+                cinfo.ptr = s->dma_dac.hwptr;
+                if (s->dma_dac.mapped)
+                        s->dma_dac.count &= s->dma_dac.fragsize-1;
+                spin_unlock_irqrestore(&s->lock, flags);
+                return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+        case SNDCTL_DSP_GETBLKSIZE:
+                if (file->f_mode & FMODE_WRITE) {
+                        if ((val = prog_dmabuf_dac(s)))
+                                return val;
+                        return put_user(s->dma_dac.fragsize, (int *)arg);
+                }
+                if ((val = prog_dmabuf_adc(s)))
+                        return val;
+                return put_user(s->dma_adc.fragsize, (int *)arg);
+
+        case SNDCTL_DSP_SETFRAGMENT:
+                get_user_ret(val, (int *)arg, -EFAULT);
+                return 0;              // Say OK, but do nothing.
+
+        case SNDCTL_DSP_SUBDIVIDE:
+                if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) ||
+                    (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision))
+                        return -EINVAL;
+                get_user_ret(val, (int *)arg, -EFAULT);
+                if (val != 1 && val != 2 && val != 4)
+                        return -EINVAL;
+                if (file->f_mode & FMODE_READ)
+                        s->dma_adc.subdivision = val;
+                if (file->f_mode & FMODE_WRITE)
+                        s->dma_dac.subdivision = val;
+                return 0;
+
+        case SOUND_PCM_READ_RATE:
+                return put_user(s->rate, (int *)arg);
+
+        case SOUND_PCM_READ_CHANNELS:
+                return put_user(s->channels, (int *)arg);
+
+        case SOUND_PCM_READ_BITS:
+                return put_user((s->fmt & (AFMT_S8|AFMT_U8)) ? 8 : 16, (int *)arg);
+
+        case SOUND_PCM_WRITE_FILTER:
+        case SNDCTL_DSP_SETSYNCRO:
+        case SOUND_PCM_READ_FILTER:
+                return -EINVAL;
+
+        }
+        return mixer_ioctl(s, cmd, arg);
+}
+
+
+static int cs4281_release(struct inode *inode, struct file *file)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+
+        VALIDATE_STATE(s);
+
+        if (file->f_mode & FMODE_WRITE)
+                drain_dac(s, file->f_flags & O_NONBLOCK);
+        down(&s->open_sem);
+        if (file->f_mode & FMODE_WRITE) {
+                stop_dac(s);
+                dealloc_dmabuf(&s->dma_dac);
+        }
+        if (file->f_mode & FMODE_READ) {
+                stop_adc(s);
+                dealloc_dmabuf(&s->dma_adc);
+        }
+        s->open_mode &= ~(FMODE_READ | FMODE_WRITE);
+        up(&s->open_sem);
+        wake_up(&s->open_wait);
+        MOD_DEC_USE_COUNT;
+        return 0;
+}
+
+static int cs4281_open(struct inode *inode, struct file *file)
+{
+        int minor = MINOR(inode->i_rdev);
+        struct cs4281_state *s = devs;
+
+        while (s && ((s->dev_audio ^ minor) & ~0xf))
+                s = s->next;
+        if (!s)
+                return -ENODEV;
+        VALIDATE_STATE(s);
+        file->private_data = s;
+        
+                // wait for device to become free 
+        down(&s->open_sem);
+        while (s->open_mode & (FMODE_READ | FMODE_WRITE)) {
+                if (file->f_flags & O_NONBLOCK) {
+                        up(&s->open_sem);
+                        return -EBUSY;
+                }
+                up(&s->open_sem);
+                interruptible_sleep_on(&s->open_wait);
+                if (signal_pending(current))
+                        return -ERESTARTSYS;
+                down(&s->open_sem);
+        }
+        s->fmt = AFMT_U8;
+        s->channels = 1;
+        s->rate = 8000;
+        s->clkdiv = 96 | 0x80;
+        s->ena = 0;
+	s->endofbuffer = 0;
+        s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = s->dma_adc.subdivision = 0;
+        s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = s->dma_dac.subdivision = 0;
+        s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+        up(&s->open_sem);
+        MOD_INC_USE_COUNT;
+
+        if (prog_dmabuf_dac(s) || prog_dmabuf_adc(s)) {
+                
+             printk(KERN_ERR "cs4281: Program dmabufs failed.\n");
+             cs4281_release(inode, file);
+                
+             return -ENOMEM;
+        }
+        prog_codec(s);
+        return 0;
+}
+
+
+// ******************************************************************************************
+//   Wave (audio) file operations struct.
+// ******************************************************************************************
+static /*const*/ struct file_operations cs4281_audio_fops = {
+        &cs4281_llseek,
+        &cs4281_read,
+        &cs4281_write,
+        NULL,  // readdir 
+        &cs4281_poll,
+        &cs4281_ioctl,
+        &cs4281_mmap,
+        &cs4281_open,
+        NULL,  // flush 
+        &cs4281_release,
+        NULL,  // fsync 
+        NULL,  // fasync 
+        NULL,  // check_media_change 
+        NULL,  // revalidate 
+        NULL,  // lock 
+};
+
+// --------------------------------------------------------------------- 
+
+// hold spinlock for the following! 
+static void cs4281_handle_midi(struct cs4281_state *s)
+{
+        unsigned char ch;
+        int wake;
+        unsigned temp1;
+
+        wake = 0;
+        while (!(readl(s->pBA0+ BA0_MIDSR) & 0x80)) {
+                ch = readl(s->pBA0+BA0_MIDRP);
+                if (s->midi.icnt < MIDIINBUF) {
+                        s->midi.ibuf[s->midi.iwr] = ch;
+                        s->midi.iwr = (s->midi.iwr + 1) % MIDIINBUF;
+                        s->midi.icnt++;
+                }
+                wake = 1;
+        }
+        if (wake)
+                wake_up(&s->midi.iwait);
+        wake = 0;
+        while (!(readl(s->pBA0+ BA0_MIDSR) & 0x40) && s->midi.ocnt > 0) {
+                temp1 = ( s->midi.obuf[s->midi.ord] ) & 0x000000ff;
+                writel(temp1, s->pBA0+BA0_MIDWP);
+                s->midi.ord = (s->midi.ord + 1) % MIDIOUTBUF;
+                s->midi.ocnt--;
+                if (s->midi.ocnt < MIDIOUTBUF-16)
+                        wake = 1;
+        }
+        if (wake)
+                wake_up(&s->midi.owait);
+}
+
+
+
+static void cs4281_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+        struct cs4281_state *s = (struct cs4281_state *)dev_id;
+        unsigned int temp1;
+
+        // fastpath out, to ease interrupt sharing 
+        temp1 = readl(s->pBA0+BA0_HISR);                          // Get Int Status reg.
+        if (!(temp1 & (HISR_DMA0 | HISR_DMA1 | HISR_MIDI))) {     // If not DMA or MIDI int,
+                writel(HICR_IEV| HICR_CHGM, s->pBA0+BA0_HICR);    //  reenable interrupts
+                return;                                           //   and return.
+        }
+        
+        if(temp1 & HISR_DMA0)                      // If play interrupt,
+                readl(s->pBA0+BA0_HDSR0);              //   clear the source.
+
+        if(temp1 & HISR_DMA1)                      // Same for play.
+                readl(s->pBA0+BA0_HDSR1);        
+        writel(HICR_IEV| HICR_CHGM, s->pBA0+BA0_HICR);  // Local EOI
+        
+        spin_lock(&s->lock);
+	//
+	// ok, at this point we assume that the fifos have been filled
+	// with silence and so we now turn off the DMA engine.
+	// if FMODE_WRITE is set that means that some thread
+	// attempted to start_dac, which probably means that an open
+	// occurred, so do not stop the dac in this case.
+	//
+	if(s->endofbuffer && !(s->ena & FMODE_WRITE))
+	{
+		writel(temp1|DCRn_MSK, s->pBA0+BA0_DCR0);    // Stop Play DMA
+		s->endofbuffer = 0;
+	}
+	else
+	{
+        	cs4281_update_ptr(s);
+	}
+        cs4281_handle_midi(s);
+        spin_unlock(&s->lock);
+}
+
+// **************************************************************************
+
+static void cs4281_midi_timer(unsigned long data)
+{
+        struct cs4281_state *s = (struct cs4281_state *)data;
+        unsigned long flags;
+
+        spin_lock_irqsave(&s->lock, flags);
+        cs4281_handle_midi(s);
+        spin_unlock_irqrestore(&s->lock, flags);
+        s->midi.timer.expires = jiffies+1;
+        add_timer(&s->midi.timer);
+}
+
+
+// --------------------------------------------------------------------- 
+
+static ssize_t cs4281_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        ssize_t ret;
+        unsigned long flags;
+        unsigned ptr;
+        int cnt;
+
+        VALIDATE_STATE(s);
+        if (ppos != &file->f_pos)
+                return -ESPIPE;
+        if (!access_ok(VERIFY_WRITE, buffer, count))
+                return -EFAULT;
+        ret = 0;
+        while (count > 0) {
+                spin_lock_irqsave(&s->lock, flags);
+                ptr = s->midi.ird;
+                cnt = MIDIINBUF - ptr;
+                if (s->midi.icnt < cnt)
+                        cnt = s->midi.icnt;
+                spin_unlock_irqrestore(&s->lock, flags);
+                if (cnt > count)
+                        cnt = count;
+                if (cnt <= 0) {
+                        if (file->f_flags & O_NONBLOCK)
+                                return ret ? ret : -EAGAIN;
+                        interruptible_sleep_on(&s->midi.iwait);
+                        if (signal_pending(current))
+                                return ret ? ret : -ERESTARTSYS;
+                        continue;
+                }
+                if (copy_to_user(buffer, s->midi.ibuf + ptr, cnt))
+                        return ret ? ret : -EFAULT;
+                ptr = (ptr + cnt) % MIDIINBUF;
+                spin_lock_irqsave(&s->lock, flags);
+                s->midi.ird = ptr;
+                s->midi.icnt -= cnt;
+                spin_unlock_irqrestore(&s->lock, flags);
+                count -= cnt;
+                buffer += cnt;
+                ret += cnt;
+        }
+        return ret;
+}
+
+
+static ssize_t cs4281_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        ssize_t ret;
+        unsigned long flags;
+        unsigned ptr;
+        int cnt;
+
+        VALIDATE_STATE(s);
+        if (ppos != &file->f_pos)
+                return -ESPIPE;
+        if (!access_ok(VERIFY_READ, buffer, count))
+                return -EFAULT;
+        ret = 0;
+        while (count > 0) {
+                spin_lock_irqsave(&s->lock, flags);
+                ptr = s->midi.owr;
+                cnt = MIDIOUTBUF - ptr;
+                if (s->midi.ocnt + cnt > MIDIOUTBUF)
+                        cnt = MIDIOUTBUF - s->midi.ocnt;
+                if (cnt <= 0)
+                        cs4281_handle_midi(s);
+                spin_unlock_irqrestore(&s->lock, flags);
+                if (cnt > count)
+                        cnt = count;
+                if (cnt <= 0) {
+                        if (file->f_flags & O_NONBLOCK)
+                                return ret ? ret : -EAGAIN;
+                        interruptible_sleep_on(&s->midi.owait);
+                        if (signal_pending(current))
+                                return ret ? ret : -ERESTARTSYS;
+                        continue;
+                }
+                if (copy_from_user(s->midi.obuf + ptr, buffer, cnt))
+                        return ret ? ret : -EFAULT;
+                ptr = (ptr + cnt) % MIDIOUTBUF;
+                spin_lock_irqsave(&s->lock, flags);
+                s->midi.owr = ptr;
+                s->midi.ocnt += cnt;
+                spin_unlock_irqrestore(&s->lock, flags);
+                count -= cnt;
+                buffer += cnt;
+                ret += cnt;
+                spin_lock_irqsave(&s->lock, flags);
+                cs4281_handle_midi(s);
+                spin_unlock_irqrestore(&s->lock, flags);
+        }
+        return ret;
+}
+
+
+static unsigned int cs4281_midi_poll(struct file *file, struct poll_table_struct *wait)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        unsigned long flags;
+        unsigned int mask = 0;
+
+        VALIDATE_STATE(s);
+        if (file->f_flags & FMODE_WRITE)
+                poll_wait(file, &s->midi.owait, wait);
+        if (file->f_flags & FMODE_READ)
+                poll_wait(file, &s->midi.iwait, wait);
+        spin_lock_irqsave(&s->lock, flags);
+        if (file->f_flags & FMODE_READ) {
+                if (s->midi.icnt > 0)
+                        mask |= POLLIN | POLLRDNORM;
+        }
+        if (file->f_flags & FMODE_WRITE) {
+                if (s->midi.ocnt < MIDIOUTBUF)
+                        mask |= POLLOUT | POLLWRNORM;
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        return mask;
+}
+
+
+static int cs4281_midi_open(struct inode *inode, struct file *file)
+{
+        int minor = MINOR(inode->i_rdev);
+        struct cs4281_state *s = devs;
+        unsigned long flags,temp1;
+        while (s && s->dev_midi != minor)
+                s = s->next;
+        if (!s)
+                return -ENODEV;
+        VALIDATE_STATE(s);
+        file->private_data = s;
+        // wait for device to become free 
+        down(&s->open_sem);
+        while (s->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
+                if (file->f_flags & O_NONBLOCK) {
+                        up(&s->open_sem);
+                        return -EBUSY;
+                }
+                up(&s->open_sem);
+                interruptible_sleep_on(&s->open_wait);
+                if (signal_pending(current))
+                        return -ERESTARTSYS;
+                down(&s->open_sem);
+        }
+        spin_lock_irqsave(&s->lock, flags);
+        if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
+                s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+                s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
+                writel(1, s->pBA0+BA0_MIDCR);   // Reset the interface.
+                writel(0, s->pBA0+BA0_MIDCR);   // Return to normal mode.
+                s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+                writel(0x0000000f, s->pBA0+BA0_MIDCR);                // Enable transmit, record, ints.
+                temp1 = readl(s->pBA0+BA0_HIMR);
+                writel(temp1 & 0xffbfffff, s->pBA0+BA0_HIMR);         // Enable midi int. recognition.
+                writel(HICR_IEV | HICR_CHGM, s->pBA0+BA0_HICR);       // Enable interrupts
+                init_timer(&s->midi.timer);
+                s->midi.timer.expires = jiffies+1;
+                s->midi.timer.data = (unsigned long)s;
+                s->midi.timer.function = cs4281_midi_timer;
+                add_timer(&s->midi.timer);
+        }
+        if (file->f_mode & FMODE_READ) {
+                s->midi.ird = s->midi.iwr = s->midi.icnt = 0;
+        }
+        if (file->f_mode & FMODE_WRITE) {
+                s->midi.ord = s->midi.owr = s->midi.ocnt = 0;
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        s->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
+        up(&s->open_sem);
+        MOD_INC_USE_COUNT;
+        return 0;
+}
+
+
+static int cs4281_midi_release(struct inode *inode, struct file *file)
+{
+        struct cs4281_state *s = (struct cs4281_state *)file->private_data;
+        DECLARE_WAITQUEUE(wait, current);
+        unsigned long flags;
+        unsigned count, tmo;
+
+        VALIDATE_STATE(s);
+
+        if (file->f_mode & FMODE_WRITE) {
+                current->state = TASK_INTERRUPTIBLE;
+                add_wait_queue(&s->midi.owait, &wait);
+                for (;;) {
+                        spin_lock_irqsave(&s->lock, flags);
+                        count = s->midi.ocnt;
+                        spin_unlock_irqrestore(&s->lock, flags);
+                        if (count <= 0)
+                                break;
+                        if (signal_pending(current))
+                                break;
+                        if (file->f_flags & O_NONBLOCK) {
+                                remove_wait_queue(&s->midi.owait, &wait);
+                                current->state = TASK_RUNNING;
+                                return -EBUSY;
+                        }
+                        tmo = (count * HZ) / 3100;
+                        if (!schedule_timeout(tmo ? : 1) && tmo)
+                                printk(KERN_DEBUG "cs4281: midi timed out??\n");
+                }
+                remove_wait_queue(&s->midi.owait, &wait);
+                current->state = TASK_RUNNING;
+        }
+        down(&s->open_sem);
+        s->open_mode &= (~(file->f_mode << FMODE_MIDI_SHIFT)) & (FMODE_MIDI_READ|FMODE_MIDI_WRITE);
+        spin_lock_irqsave(&s->lock, flags);
+        if (!(s->open_mode & (FMODE_MIDI_READ | FMODE_MIDI_WRITE))) {
+                writel(0, s->pBA0+BA0_MIDCR);    // Disable Midi interrupts.  
+                del_timer(&s->midi.timer);
+        }
+        spin_unlock_irqrestore(&s->lock, flags);
+        up(&s->open_sem);
+        wake_up(&s->open_wait);
+        MOD_DEC_USE_COUNT;
+        return 0;
+}
+
+// ******************************************************************************************
+//   Midi file operations struct.
+// ******************************************************************************************
+static /*const*/ struct file_operations cs4281_midi_fops = {
+        &cs4281_llseek,
+        &cs4281_midi_read,
+        &cs4281_midi_write,
+        NULL,  // readdir 
+        &cs4281_midi_poll,
+        NULL,  // ioctl 
+        NULL,  // mmap 
+        &cs4281_midi_open,
+        NULL,  // flush 
+        &cs4281_midi_release,
+        NULL,  // fsync 
+        NULL,  // fasync 
+        NULL,  // check_media_change 
+        NULL,  // revalidate 
+        NULL,  // lock 
+};
+
+
+// --------------------------------------------------------------------- 
+
+// maximum number of devices 
+#define NR_DEVICE 8          // Only eight devices supported currently.
+
+// --------------------------------------------------------------------- 
+
+static struct initvol {
+        int mixch;
+        int vol;
+} initvol[] __initdata = {
+        { SOUND_MIXER_WRITE_VOLUME, 0x4040 },
+        { SOUND_MIXER_WRITE_PCM, 0x4040 },
+        { SOUND_MIXER_WRITE_SYNTH, 0x4040 },
+        { SOUND_MIXER_WRITE_CD, 0x4040 },
+        { SOUND_MIXER_WRITE_LINE, 0x4040 },
+        { SOUND_MIXER_WRITE_LINE1, 0x4040 },
+        { SOUND_MIXER_WRITE_RECLEV, 0x0000 },
+        { SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
+        { SOUND_MIXER_WRITE_MIC, 0x0000 }
+};
+
+
+int __init cs4281_probe(void)
+{
+        struct cs4281_state *s;
+        struct pci_dev *pcidev = NULL;
+        mm_segment_t fs;
+        int i, val, index = 0;
+        unsigned int temp1, temp2;
+ 
+        if (!pci_present())   // No PCI bus in this machine! 
+                return -ENODEV;
+        printk(KERN_INFO "cs4281: version 0.9 time " __TIME__ " " __DATE__ "\n");
+        while (index < NR_DEVICE && 
+        	(pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, PCI_DEVICE_ID_CRYSTAL_CS4281, pcidev)))
+        {   
+                if (!(s = kmalloc(sizeof(struct cs4281_state), GFP_KERNEL))) {
+                        printk(KERN_ERR "cs4281: no memory for state struct.\n");
+                        continue;
+                }
+
+                memset(s, 0, sizeof(struct cs4281_state));
+                init_waitqueue_head(&s->dma_adc.wait);
+                init_waitqueue_head(&s->dma_dac.wait);
+                init_waitqueue_head(&s->open_wait);
+                init_waitqueue_head(&s->midi.iwait);
+                init_waitqueue_head(&s->midi.owait);
+                init_MUTEX(&s->open_sem);
+                s->pBA0phys = pcidev->base_address[0]&PCI_BASE_ADDRESS_MEM_MASK;                  // Get physical addresses
+                s->pBA1phys = pcidev->base_address[1]&PCI_BASE_ADDRESS_MEM_MASK;                  //  of part.
+		s->pBA0 = ioremap_nocache(s->pBA0phys, 4096);		// Convert phys 
+		s->pBA1 = ioremap_nocache(s->pBA1phys, 65536);  	//  to linear. 
+                temp1 = readl(s->pBA0+ BA0_PCICFG00);
+                temp2 = readl(s->pBA0+ BA0_PCICFG04);
+                temp1 = cs4281_hw_init(s);
+                if(!temp1){
+                        printk(KERN_INFO "cs4281: Init4281() failed. Skipping part.\n");
+                        continue;
+                }	
+                s->magic = CS4281_MAGIC;
+		s->pcidev = pcidev;
+                s->irq = pcidev->irq;
+                if(request_irq(s->irq, cs4281_interrupt, SA_SHIRQ, "Crystal CS4281", s)){
+                        printk(KERN_ERR "cs4281: irq %u in use\n", s->irq);
+                        goto err_irq;
+                }
+                if ((s->dev_audio = register_sound_dsp(&cs4281_audio_fops, -1)) < 0)
+                        goto err_dev1;
+                if ((s->dev_mixer = register_sound_mixer(&cs4281_mixer_fops, -1)) < 0)
+                        goto err_dev2;
+                if ((s->dev_midi = register_sound_midi(&cs4281_midi_fops, -1)) < 0)
+                        goto err_dev3;
+                                    
+                pci_set_master(pcidev);           // enable bus mastering 
+
+                fs = get_fs();
+                set_fs(KERNEL_DS);
+                val = SOUND_MASK_LINE;
+                mixer_ioctl(s, SOUND_MIXER_WRITE_RECSRC, (unsigned long)&val);
+                for (i = 0; i < sizeof(initvol)/sizeof(initvol[0]); i++) {
+                        val = initvol[i].vol;
+                        mixer_ioctl(s, initvol[i].mixch, (unsigned long)&val);
+                }
+                val = 1; // enable mic preamp 
+                mixer_ioctl(s, SOUND_MIXER_PRIVATE1, (unsigned long)&val);
+                set_fs(fs);
+                
+                // queue it for later freeing 
+                s->next = devs;
+                devs = s;
+                index++;
+                continue;
+
+        err_dev3:
+                unregister_sound_mixer(s->dev_mixer);
+        err_dev2:
+                unregister_sound_dsp(s->dev_audio);
+        err_dev1:
+                printk(KERN_ERR "cs4281: cannot register dsp device\n");
+                free_irq(s->irq, s);
+        err_irq:
+                kfree_s(s, sizeof(struct cs4281_state));
+        } // endwhile
+        if (!devs)
+                return -ENODEV;
+        return 0;
+} // init_cs4281
+
+
+// --------------------------------------------------------------------- 
+
+
+#ifdef MODULE
+
+MODULE_AUTHOR("gw boynton, wesb@crystal.cirrus.com");
+MODULE_DESCRIPTION("Cirrus Logic CS4281 Driver");
+
+int init_module(void)
+{
+	return cs4281_probe();
+}
+
+void cleanup_module(void)
+{
+        struct cs4281_state *s;
+        while ((s = devs)) {
+                devs = devs->next;
+                // stop DMA controller 
+                synchronize_irq();
+                free_irq(s->irq, s);              
+                unregister_sound_dsp(s->dev_audio);
+                unregister_sound_mixer(s->dev_mixer);
+                unregister_sound_midi(s->dev_midi);
+                iounmap(s->pBA0);
+                iounmap(s->pBA1);
+                kfree_s(s, sizeof(struct cs4281_state));
+        }
+}
+
+// --------------------------------------------------------------------- 
+
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/cs4281_hwdefs.h linux.17p18/drivers/sound/cs4281_hwdefs.h
--- linux.vanilla/drivers/sound/cs4281_hwdefs.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/cs4281_hwdefs.h	Mon Aug 14 18:48:36 2000
@@ -0,0 +1,1234 @@
+//****************************************************************************
+//
+// HWDEFS.H - Definitions of the registers and data structures used by the
+//            CS4281
+//
+// Copyright (c) 1999 Crystal Semiconductor Corp.
+//
+//****************************************************************************
+
+#ifndef _H_HWDEFS
+#define _H_HWDEFS
+
+//****************************************************************************
+//
+// The following define the offsets of the registers located in the PCI
+// configuration space of the CS4281 part.
+//
+//****************************************************************************
+#define PCICONFIG_DEVID_VENID                   0x00000000L
+#define PCICONFIG_STATUS_COMMAND                0x00000004L
+#define PCICONFIG_CLASS_REVISION                0x00000008L
+#define PCICONFIG_LATENCY_TIMER                 0x0000000CL
+#define PCICONFIG_BA0                           0x00000010L
+#define PCICONFIG_BA1                           0x00000014L
+#define PCICONFIG_SUBSYSID_SUBSYSVENID          0x0000002CL
+#define PCICONFIG_INTERRUPT                     0x0000003CL
+
+//****************************************************************************
+//
+// The following define the offsets of the registers accessed via base address
+// register zero on the CS4281 part.
+//
+//****************************************************************************
+#define BA0_HISR                                0x00000000L
+#define BA0_HICR                                0x00000008L
+#define BA0_HIMR                                0x0000000CL
+#define BA0_IIER                                0x00000010L
+#define BA0_HDSR0                               0x000000F0L
+#define BA0_HDSR1                               0x000000F4L
+#define BA0_HDSR2                               0x000000F8L
+#define BA0_HDSR3                               0x000000FCL
+#define BA0_DCA0                                0x00000110L
+#define BA0_DCC0                                0x00000114L
+#define BA0_DBA0                                0x00000118L
+#define BA0_DBC0                                0x0000011CL
+#define BA0_DCA1                                0x00000120L
+#define BA0_DCC1                                0x00000124L
+#define BA0_DBA1                                0x00000128L
+#define BA0_DBC1                                0x0000012CL
+#define BA0_DCA2                                0x00000130L
+#define BA0_DCC2                                0x00000134L
+#define BA0_DBA2                                0x00000138L
+#define BA0_DBC2                                0x0000013CL
+#define BA0_DCA3                                0x00000140L
+#define BA0_DCC3                                0x00000144L
+#define BA0_DBA3                                0x00000148L
+#define BA0_DBC3                                0x0000014CL
+#define BA0_DMR0                                0x00000150L
+#define BA0_DCR0                                0x00000154L
+#define BA0_DMR1                                0x00000158L
+#define BA0_DCR1                                0x0000015CL
+#define BA0_DMR2                                0x00000160L
+#define BA0_DCR2                                0x00000164L
+#define BA0_DMR3                                0x00000168L
+#define BA0_DCR3                                0x0000016CL
+#define BA0_DLMR                                0x00000170L
+#define BA0_DLSR                                0x00000174L
+#define BA0_FCR0                                0x00000180L
+#define BA0_FCR1                                0x00000184L
+#define BA0_FCR2                                0x00000188L
+#define BA0_FCR3                                0x0000018CL
+#define BA0_FPDR0                               0x00000190L
+#define BA0_FPDR1                               0x00000194L
+#define BA0_FPDR2                               0x00000198L
+#define BA0_FPDR3                               0x0000019CL
+#define BA0_FCHS                                0x0000020CL
+#define BA0_FSIC0                               0x00000210L
+#define BA0_FSIC1                               0x00000214L
+#define BA0_FSIC2                               0x00000218L
+#define BA0_FSIC3                               0x0000021CL
+#define BA0_PCICFG00                            0x00000300L
+#define BA0_PCICFG04                            0x00000304L
+#define BA0_PCICFG08                            0x00000308L
+#define BA0_PCICFG0C                            0x0000030CL
+#define BA0_PCICFG10                            0x00000310L
+#define BA0_PCICFG14                            0x00000314L
+#define BA0_PCICFG18                            0x00000318L
+#define BA0_PCICFG1C                            0x0000031CL
+#define BA0_PCICFG20                            0x00000320L
+#define BA0_PCICFG24                            0x00000324L
+#define BA0_PCICFG28                            0x00000328L
+#define BA0_PCICFG2C                            0x0000032CL
+#define BA0_PCICFG30                            0x00000330L
+#define BA0_PCICFG34                            0x00000334L
+#define BA0_PCICFG38                            0x00000338L
+#define BA0_PCICFG3C                            0x0000033CL
+#define BA0_PCICFG40                            0x00000340L
+#define BA0_PMCS                                0x00000344L
+#define BA0_CWPR                                0x000003E0L
+#define BA0_EPPMC                               0x000003E4L
+#define BA0_GPIOR                               0x000003E8L
+#define BA0_SPMC                                0x000003ECL
+#define BA0_CFLR                                0x000003F0L
+#define BA0_IISR                                0x000003F4L
+#define BA0_TMS                                 0x000003F8L
+#define BA0_SSVID                               0x000003FCL
+#define BA0_CLKCR1                              0x00000400L
+#define BA0_FRR                                 0x00000410L
+#define BA0_SLT12O                              0x0000041CL
+#define BA0_SERMC                               0x00000420L
+#define BA0_SERC1                               0x00000428L
+#define BA0_SERC2                               0x0000042CL
+#define BA0_SLT12M                              0x0000045CL
+#define BA0_ACCTL                               0x00000460L
+#define BA0_ACSTS                               0x00000464L
+#define BA0_ACOSV                               0x00000468L
+#define BA0_ACCAD                               0x0000046CL
+#define BA0_ACCDA                               0x00000470L
+#define BA0_ACISV                               0x00000474L
+#define BA0_ACSAD                               0x00000478L
+#define BA0_ACSDA                               0x0000047CL
+#define BA0_JSPT                                0x00000480L
+#define BA0_JSCTL                               0x00000484L
+#define BA0_MIDCR                               0x00000490L
+#define BA0_MIDCMD                              0x00000494L
+#define BA0_MIDSR                               0x00000494L
+#define BA0_MIDWP                               0x00000498L
+#define BA0_MIDRP                               0x0000049CL
+#define BA0_AODSD1                              0x000004A8L
+#define BA0_AODSD2                              0x000004ACL
+#define BA0_CFGI                                0x000004B0L
+#define BA0_SLT12M2                             0x000004DCL
+#define BA0_ACSTS2                              0x000004E4L
+#define BA0_ACISV2                              0x000004F4L
+#define BA0_ACSAD2                              0x000004F8L
+#define BA0_ACSDA2                              0x000004FCL
+#define BA0_IOTGP                               0x00000500L
+#define BA0_IOTSB                               0x00000504L
+#define BA0_IOTFM                               0x00000508L
+#define BA0_IOTDMA                              0x0000050CL
+#define BA0_IOTAC0                              0x00000500L
+#define BA0_IOTAC1                              0x00000504L
+#define BA0_IOTAC2                              0x00000508L
+#define BA0_IOTAC3                              0x0000050CL
+#define BA0_IOTPCP                              0x0000052CL
+#define BA0_IOTCC                               0x00000530L
+#define BA0_IOTCR                               0x0000058CL
+#define BA0_PCPRR                               0x00000600L
+#define BA0_PCPGR                               0x00000604L
+#define BA0_PCPCR                               0x00000608L
+#define BA0_PCPCIEN                             0x00000608L
+#define BA0_SBMAR                               0x00000700L
+#define BA0_SBMDR                               0x00000704L
+#define BA0_SBRR                                0x00000708L
+#define BA0_SBRDP                               0x0000070CL
+#define BA0_SBWDP                               0x00000710L
+#define BA0_SBWBS                               0x00000710L
+#define BA0_SBRBS                               0x00000714L
+#define BA0_FMSR                                0x00000730L
+#define BA0_B0AP                                0x00000730L
+#define BA0_FMDP                                0x00000734L
+#define BA0_B1AP                                0x00000738L
+#define BA0_B1DP                                0x0000073CL
+#define BA0_SSPM                                0x00000740L
+#define BA0_DACSR                               0x00000744L
+#define BA0_ADCSR                               0x00000748L
+#define BA0_SSCR                                0x0000074CL
+#define BA0_FMLVC                               0x00000754L
+#define BA0_FMRVC                               0x00000758L
+#define BA0_SRCSA                               0x0000075CL
+#define BA0_PPLVC                               0x00000760L
+#define BA0_PPRVC                               0x00000764L
+#define BA0_PASR                                0x00000768L
+#define BA0_CASR                                0x0000076CL
+
+//****************************************************************************
+//
+// The following define the offsets of the AC97 shadow registers, which appear
+// as a virtual extension to the base address register zero memory range.
+//
+//****************************************************************************
+#define AC97_REG_OFFSET_MASK                    0x0000007EL
+#define AC97_CODEC_NUMBER_MASK                  0x00003000L
+
+#define BA0_AC97_RESET                          0x00001000L
+#define BA0_AC97_MASTER_VOLUME                  0x00001002L
+#define BA0_AC97_HEADPHONE_VOLUME               0x00001004L
+#define BA0_AC97_MASTER_VOLUME_MONO             0x00001006L
+#define BA0_AC97_MASTER_TONE                    0x00001008L
+#define BA0_AC97_PC_BEEP_VOLUME                 0x0000100AL
+#define BA0_AC97_PHONE_VOLUME                   0x0000100CL
+#define BA0_AC97_MIC_VOLUME                     0x0000100EL
+#define BA0_AC97_LINE_IN_VOLUME                 0x00001010L
+#define BA0_AC97_CD_VOLUME                      0x00001012L
+#define BA0_AC97_VIDEO_VOLUME                   0x00001014L
+#define BA0_AC97_AUX_VOLUME                     0x00001016L
+#define BA0_AC97_PCM_OUT_VOLUME                 0x00001018L
+#define BA0_AC97_RECORD_SELECT                  0x0000101AL
+#define BA0_AC97_RECORD_GAIN                    0x0000101CL
+#define BA0_AC97_RECORD_GAIN_MIC                0x0000101EL
+#define BA0_AC97_GENERAL_PURPOSE                0x00001020L
+#define BA0_AC97_3D_CONTROL                     0x00001022L
+#define BA0_AC97_MODEM_RATE                     0x00001024L
+#define BA0_AC97_POWERDOWN                      0x00001026L
+#define BA0_AC97_EXT_AUDIO_ID                   0x00001028L
+#define BA0_AC97_EXT_AUDIO_POWER                0x0000102AL
+#define BA0_AC97_PCM_FRONT_DAC_RATE             0x0000102CL
+#define BA0_AC97_PCM_SURR_DAC_RATE              0x0000102EL
+#define BA0_AC97_PCM_LFE_DAC_RATE               0x00001030L
+#define BA0_AC97_PCM_LR_ADC_RATE                0x00001032L
+#define BA0_AC97_MIC_ADC_RATE                   0x00001034L
+#define BA0_AC97_6CH_VOL_C_LFE                  0x00001036L
+#define BA0_AC97_6CH_VOL_SURROUND               0x00001038L
+#define BA0_AC97_RESERVED_3A                    0x0000103AL
+#define BA0_AC97_EXT_MODEM_ID                   0x0000103CL
+#define BA0_AC97_EXT_MODEM_POWER                0x0000103EL
+#define BA0_AC97_LINE1_CODEC_RATE               0x00001040L
+#define BA0_AC97_LINE2_CODEC_RATE               0x00001042L
+#define BA0_AC97_HANDSET_CODEC_RATE             0x00001044L
+#define BA0_AC97_LINE1_CODEC_LEVEL              0x00001046L
+#define BA0_AC97_LINE2_CODEC_LEVEL              0x00001048L
+#define BA0_AC97_HANDSET_CODEC_LEVEL            0x0000104AL
+#define BA0_AC97_GPIO_PIN_CONFIG                0x0000104CL
+#define BA0_AC97_GPIO_PIN_TYPE                  0x0000104EL
+#define BA0_AC97_GPIO_PIN_STICKY                0x00001050L
+#define BA0_AC97_GPIO_PIN_WAKEUP                0x00001052L
+#define BA0_AC97_GPIO_PIN_STATUS                0x00001054L
+#define BA0_AC97_MISC_MODEM_AFE_STAT            0x00001056L
+#define BA0_AC97_RESERVED_58                    0x00001058L
+#define BA0_AC97_CRYSTAL_REV_N_FAB_ID           0x0000105AL
+#define BA0_AC97_TEST_AND_MISC_CTRL             0x0000105CL
+#define BA0_AC97_AC_MODE                        0x0000105EL
+#define BA0_AC97_MISC_CRYSTAL_CONTROL           0x00001060L
+#define BA0_AC97_LINE1_HYPRID_CTRL              0x00001062L
+#define BA0_AC97_VENDOR_RESERVED_64             0x00001064L
+#define BA0_AC97_VENDOR_RESERVED_66             0x00001066L
+#define BA0_AC97_SPDIF_CONTROL                  0x00001068L
+#define BA0_AC97_VENDOR_RESERVED_6A             0x0000106AL
+#define BA0_AC97_VENDOR_RESERVED_6C             0x0000106CL
+#define BA0_AC97_VENDOR_RESERVED_6E             0x0000106EL
+#define BA0_AC97_VENDOR_RESERVED_70             0x00001070L
+#define BA0_AC97_VENDOR_RESERVED_72             0x00001072L
+#define BA0_AC97_VENDOR_RESERVED_74             0x00001074L
+#define BA0_AC97_CAL_ADDRESS                    0x00001076L
+#define BA0_AC97_CAL_DATA                       0x00001078L
+#define BA0_AC97_VENDOR_RESERVED_7A             0x0000107AL
+#define BA0_AC97_VENDOR_ID1                     0x0000107CL
+#define BA0_AC97_VENDOR_ID2                     0x0000107EL
+
+//****************************************************************************
+//
+// The following define the offsets of the registers and memories accessed via
+// base address register one on the CS4281 part.
+//
+//****************************************************************************
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI device ID/vendor ID
+// register.
+//
+//****************************************************************************
+#define PDV_VENID_MASK                          0x0000FFFFL
+#define PDV_DEVID_MASK                          0xFFFF0000L
+#define PDV_VENID_SHIFT                         0L
+#define PDV_DEVID_SHIFT                         16L
+#define VENID_CIRRUS_LOGIC                      0x1013L
+#define DEVID_CS4281                            0x6005L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI status and command
+// register.
+//
+//****************************************************************************
+#define PSC_IO_SPACE_ENABLE                     0x00000001L
+#define PSC_MEMORY_SPACE_ENABLE                 0x00000002L
+#define PSC_BUS_MASTER_ENABLE                   0x00000004L
+#define PSC_SPECIAL_CYCLES                      0x00000008L
+#define PSC_MWI_ENABLE                          0x00000010L
+#define PSC_VGA_PALETTE_SNOOP                   0x00000020L
+#define PSC_PARITY_RESPONSE                     0x00000040L
+#define PSC_WAIT_CONTROL                        0x00000080L
+#define PSC_SERR_ENABLE                         0x00000100L
+#define PSC_FAST_B2B_ENABLE                     0x00000200L
+#define PSC_UDF_MASK                            0x007F0000L
+#define PSC_FAST_B2B_CAPABLE                    0x00800000L
+#define PSC_PARITY_ERROR_DETECTED               0x01000000L
+#define PSC_DEVSEL_TIMING_MASK                  0x06000000L
+#define PSC_TARGET_ABORT_SIGNALLED              0x08000000L
+#define PSC_RECEIVED_TARGET_ABORT               0x10000000L
+#define PSC_RECEIVED_MASTER_ABORT               0x20000000L
+#define PSC_SIGNALLED_SERR                      0x40000000L
+#define PSC_DETECTED_PARITY_ERROR               0x80000000L
+#define PSC_UDF_SHIFT                           16L
+#define PSC_DEVSEL_TIMING_SHIFT                 25L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI class/revision ID
+// register.
+//
+//****************************************************************************
+#define PCR_REVID_MASK                          0x000000FFL
+#define PCR_INTERFACE_MASK                      0x0000FF00L
+#define PCR_SUBCLASS_MASK                       0x00FF0000L
+#define PCR_CLASS_MASK                          0xFF000000L
+#define PCR_REVID_SHIFT                         0L
+#define PCR_INTERFACE_SHIFT                     8L
+#define PCR_SUBCLASS_SHIFT                      16L
+#define PCR_CLASS_SHIFT                         24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI latency timer register.
+//
+//****************************************************************************
+#define PLT_CACHE_LINE_SIZE_MASK                0x000000FFL
+#define PLT_LATENCY_TIMER_MASK                  0x0000FF00L
+#define PLT_HEADER_TYPE_MASK                    0x00FF0000L
+#define PLT_BIST_MASK                           0xFF000000L
+#define PLT_CACHE_LINE_SIZE_SHIFT               0L
+#define PLT_LATENCY_TIMER_SHIFT                 8L
+#define PLT_HEADER_TYPE_SHIFT                   16L
+#define PLT_BIST_SHIFT                          24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI base address registers.
+//
+//****************************************************************************
+#define PBAR_MEMORY_SPACE_INDICATOR             0x00000001L
+#define PBAR_LOCATION_TYPE_MASK                 0x00000006L
+#define PBAR_NOT_PREFETCHABLE                   0x00000008L
+#define PBAR_ADDRESS_MASK                       0xFFFFFFF0L
+#define PBAR_LOCATION_TYPE_SHIFT                1L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI subsystem ID/subsystem
+// vendor ID register.
+//
+//****************************************************************************
+#define PSS_SUBSYSTEM_VENDOR_ID_MASK            0x0000FFFFL
+#define PSS_SUBSYSTEM_ID_MASK                   0xFFFF0000L
+#define PSS_SUBSYSTEM_VENDOR_ID_SHIFT           0L
+#define PSS_SUBSYSTEM_ID_SHIFT                  16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PCI interrupt register.
+//
+//****************************************************************************
+#define PI_LINE_MASK                            0x000000FFL
+#define PI_PIN_MASK                             0x0000FF00L
+#define PI_MIN_GRANT_MASK                       0x00FF0000L
+#define PI_MAX_LATENCY_MASK                     0xFF000000L
+#define PI_LINE_SHIFT                           0L
+#define PI_PIN_SHIFT                            8L
+#define PI_MIN_GRANT_SHIFT                      16L
+#define PI_MAX_LATENCY_SHIFT                    24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the host interrupt status
+// register.
+//
+//****************************************************************************
+#define HISR_HVOLMASK                            0x00000003L
+#define HISR_VDNI                                0x00000001L
+#define HISR_VUPI                                0x00000002L
+#define HISR_GP1I                                0x00000004L
+#define HISR_GP3I                                0x00000008L
+#define HISR_GPSI                                0x00000010L
+#define HISR_GPPI                                0x00000020L
+#define HISR_DMAI                                0x00040000L
+#define HISR_FIFOI                               0x00100000L
+#define HISR_HVOL                                0x00200000L
+#define HISR_MIDI                                0x00400000L
+#define HISR_SBINT                               0x00800000L
+#define HISR_INTENA                              0x80000000L
+#define HISR_DMA_MASK                            0x00000F00L
+#define HISR_FIFO_MASK                           0x0000F000L
+#define HISR_DMA_SHIFT                           8L
+#define HISR_FIFO_SHIFT                          12L
+#define HISR_FIFO0                               0x00001000L
+#define HISR_FIFO1                               0x00002000L
+#define HISR_FIFO2                               0x00004000L
+#define HISR_FIFO3                               0x00008000L
+#define HISR_DMA0                                0x00000100L
+#define HISR_DMA1                                0x00000200L
+#define HISR_DMA2                                0x00000400L
+#define HISR_DMA3                                0x00000800L
+#define HISR_RESERVED                            0x40000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the host interrupt control
+// register.
+//
+//****************************************************************************
+#define HICR_IEV                                 0x00000001L
+#define HICR_CHGM                                0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the DMA Mode Register n
+// (DMRn)
+//
+//****************************************************************************
+#define DMRn_TR_MASK                             0x0000000CL
+#define DMRn_TR_SHIFT                            2L
+#define DMRn_AUTO                                0x00000010L
+#define DMRn_TR_READ                             0x00000008L
+#define DMRn_TR_WRITE                            0x00000004L
+#define DMRn_TYPE_MASK                           0x000000C0L
+#define DMRn_TYPE_SHIFT                          6L
+#define DMRn_SIZE8                               0x00010000L
+#define DMRn_MONO                                0x00020000L
+#define DMRn_BEND                                0x00040000L
+#define DMRn_USIGN                               0x00080000L
+#define DMRn_SIZE20                              0x00100000L
+#define DMRn_SWAPC                               0x00400000L
+#define DMRn_CBC                                 0x01000000L
+#define DMRn_TBC                                 0x02000000L
+#define DMRn_POLL                                0x10000000L
+#define DMRn_DMA                                 0x20000000L
+#define DMRn_FSEL_MASK                           0xC0000000L
+#define DMRn_FSEL_SHIFT                          30L
+#define DMRn_FSEL0                               0x00000000L
+#define DMRn_FSEL1                               0x40000000L
+#define DMRn_FSEL2                               0x80000000L
+#define DMRn_FSEL3                               0xC0000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the DMA Command Register n
+// (DCRn)
+//
+//****************************************************************************
+#define DCRn_HTCIE                               0x00020000L
+#define DCRn_TCIE                                0x00010000L
+#define DCRn_MSK                                 0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the FIFO Control 
+// register n.(FCRn)
+//
+//****************************************************************************
+#define FCRn_OF_MASK                            0x0000007FL
+#define FCRn_OF_SHIFT                           0L
+#define FCRn_SZ_MASK                            0x00007F00L
+#define FCRn_SZ_SHIFT                           8L
+#define FCRn_LS_MASK                            0x001F0000L
+#define FCRn_LS_SHIFT                           16L
+#define FCRn_RS_MASK                            0x1F000000L
+#define FCRn_RS_SHIFT                           24L
+#define FCRn_FEN                                0x80000000L
+#define FCRn_PSH                                0x20000000L
+#define FCRn_DACZ                               0x40000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port Power Management
+// control register.(SPMC)
+//
+//****************************************************************************
+#define SPMC_RSTN                               0x00000001L
+#define SPMC_ASYN                               0x00000002L
+#define SPMC_WUP1                               0x00000004L
+#define SPMC_WUP2                               0x00000008L
+#define SPMC_ASDI2E                             0x00000100L
+#define SPMC_ESSPD                              0x00000200L
+#define SPMC_GISPEN                             0x00004000L
+#define SPMC_GIPPEN                             0x00008000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Configuration Load register.
+// (CFLR)
+//
+//****************************************************************************
+#define CFLR_CLOCK_SOURCE_MASK                  0x00000003L
+#define CFLR_CLOCK_SOURCE_AC97                  0x00000001L
+
+#define CFLR_CB0_MASK                            0x000000FFL
+#define CFLR_CB1_MASK                            0x0000FF00L
+#define CFLR_CB2_MASK                            0x00FF0000L
+#define CFLR_CB3_MASK                            0xFF000000L
+#define CFLR_CB0_SHIFT                           0L
+#define CFLR_CB1_SHIFT                           8L
+#define CFLR_CB2_SHIFT                           16L
+#define CFLR_CB3_SHIFT                           24L
+
+#define IOTCR_DMA0                              0x00000000L
+#define IOTCR_DMA1                              0x00000400L
+#define IOTCR_DMA2                              0x00000800L
+#define IOTCR_DMA3                              0x00000C00L
+#define IOTCR_CCLS                              0x00000100L
+#define IOTCR_PCPCI                             0x00000200L
+#define IOTCR_DDMA                              0x00000300L
+
+#define SBWBS_WBB                               0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the SRC Slot Assignment Register
+// (SRCSA)
+//
+//****************************************************************************
+#define SRCSA_PLSS_MASK                         0x0000001FL
+#define SRCSA_PLSS_SHIFT                        0L
+#define SRCSA_PRSS_MASK                         0x00001F00L
+#define SRCSA_PRSS_SHIFT                        8L
+#define SRCSA_CLSS_MASK                         0x001F0000L
+#define SRCSA_CLSS_SHIFT                        16L
+#define SRCSA_CRSS_MASK                         0x1F000000L
+#define SRCSA_CRSS_SHIFT                        24L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound System Power Management
+// register.(SSPM)
+//
+//****************************************************************************
+#define SSPM_FPDN                               0x00000080L
+#define SSPM_MIXEN                              0x00000040L
+#define SSPM_CSRCEN                             0x00000020L
+#define SSPM_PSRCEN                             0x00000010L
+#define SSPM_JSEN                               0x00000008L
+#define SSPM_ACLEN                              0x00000004L
+#define SSPM_FMEN                               0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound System Control
+// Register. (SSCR)
+//
+//****************************************************************************
+#define SSCR_SB                                 0x00000004L
+#define SSCR_HVC                                0x00000008L
+#define SSCR_LPFIFO                             0x00000040L
+#define SSCR_LPSRC                              0x00000080L
+#define SSCR_XLPSRC                             0x00000100L
+#define SSCR_MVMD                               0x00010000L
+#define SSCR_MVAD                               0x00020000L
+#define SSCR_MVLD                               0x00040000L
+#define SSCR_MVCS                               0x00080000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Clock Control Register 1. 
+// (CLKCR1)
+//
+//****************************************************************************
+#define CLKCR1_DLLSS_MASK                       0x0000000CL
+#define CLKCR1_DLLSS_SHIFT                      2L
+#define CLKCR1_DLLP                             0x00000010L
+#define CLKCR1_SWCE                             0x00000020L
+#define CLKCR1_DLLOS                            0x00000040L
+#define CLKCR1_CKRA                             0x00010000L
+#define CLKCR1_CKRN                             0x00020000L
+#define CLKCR1_DLLRDY                           0x01000000L
+#define CLKCR1_CLKON                            0x02000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the Sound Blaster Read Buffer
+// Status.(SBRBS)
+//
+//****************************************************************************
+#define SBRBS_RD_MASK                           0x0000007FL
+#define SBRBS_RD_SHIFT                          0L
+#define SBRBS_RBF                               0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port master control
+// register.(SERMC)
+//
+//****************************************************************************
+#define SERMC_MSPE                              0x00000001L
+#define SERMC_PTC_MASK                          0x0000000EL
+#define SERMC_PTC_SHIFT                         1L
+#define SERMC_PTC_AC97                          0x00000002L
+#define SERMC_PLB                               0x00000010L
+#define SERMC_PXLB                              0x00000020L
+#define SERMC_LOFV                              0x00080000L
+#define SERMC_SLB                               0x00100000L
+#define SERMC_SXLB                              0x00200000L
+#define SERMC_ODSEN1                            0x01000000L
+#define SERMC_ODSEN2                            0x02000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the General Purpose I/O Register. 
+// (GPIOR)
+//
+//****************************************************************************
+#define GPIOR_VDNS                              0x00000001L
+#define GPIOR_VUPS                              0x00000002L
+#define GPIOR_GP1S                              0x00000004L
+#define GPIOR_GP3S                              0x00000008L
+#define GPIOR_GPSS                              0x00000010L
+#define GPIOR_GPPS                              0x00000020L
+#define GPIOR_GP1D                              0x00000400L
+#define GPIOR_GP3D                              0x00000800L
+#define GPIOR_VDNLT                             0x00010000L
+#define GPIOR_VDNPO                             0x00020000L
+#define GPIOR_VDNST                             0x00040000L
+#define GPIOR_VDNW                              0x00080000L
+#define GPIOR_VUPLT                             0x00100000L
+#define GPIOR_VUPPO                             0x00200000L
+#define GPIOR_VUPST                             0x00400000L
+#define GPIOR_VUPW                              0x00800000L
+#define GPIOR_GP1OE                             0x01000000L
+#define GPIOR_GP1PT                             0x02000000L
+#define GPIOR_GP1ST                             0x04000000L
+#define GPIOR_GP1W                              0x08000000L
+#define GPIOR_GP3OE                             0x10000000L
+#define GPIOR_GP3PT                             0x20000000L
+#define GPIOR_GP3ST                             0x40000000L
+#define GPIOR_GP3W                              0x80000000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the clock control register 1.
+//
+//****************************************************************************
+#define CLKCR1_PLLSS_MASK                       0x0000000CL
+#define CLKCR1_PLLSS_SERIAL                     0x00000000L
+#define CLKCR1_PLLSS_CRYSTAL                    0x00000004L
+#define CLKCR1_PLLSS_PCI                        0x00000008L
+#define CLKCR1_PLLSS_RESERVED                   0x0000000CL
+#define CLKCR1_PLLP                             0x00000010L
+#define CLKCR1_SWCE                             0x00000020L
+#define CLKCR1_PLLOS                            0x00000040L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the feature reporting register.
+//
+//****************************************************************************
+#define FRR_FAB_MASK                            0x00000003L
+#define FRR_MASK_MASK                           0x0000001CL
+#define FRR_ID_MASK                             0x00003000L
+#define FRR_FAB_SHIFT                           0L
+#define FRR_MASK_SHIFT                          2L
+#define FRR_ID_SHIFT                            12L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port 1 configuration
+// register.
+//
+//****************************************************************************
+#define SERC1_VALUE                             0x00000003L
+#define SERC1_SO1EN                             0x00000001L
+#define SERC1_SO1F_MASK                         0x0000000EL
+#define SERC1_SO1F_CS423X                       0x00000000L
+#define SERC1_SO1F_AC97                         0x00000002L
+#define SERC1_SO1F_DAC                          0x00000004L
+#define SERC1_SO1F_SPDIF                        0x00000006L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the serial port 2 configuration
+// register.
+//
+//****************************************************************************
+#define SERC2_VALUE                             0x00000003L
+#define SERC2_SI1EN                             0x00000001L
+#define SERC2_SI1F_MASK                         0x0000000EL
+#define SERC2_SI1F_CS423X                       0x00000000L
+#define SERC2_SI1F_AC97                         0x00000002L
+#define SERC2_SI1F_ADC                          0x00000004L
+#define SERC2_SI1F_SPDIF                        0x00000006L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 control register.
+//
+//****************************************************************************
+#define ACCTL_ESYN                              0x00000002L
+#define ACCTL_VFRM                              0x00000004L
+#define ACCTL_DCV                               0x00000008L
+#define ACCTL_CRW                               0x00000010L
+#define ACCTL_TC                                0x00000040L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status register.
+//
+//****************************************************************************
+#define ACSTS_CRDY                              0x00000001L
+#define ACSTS_VSTS                              0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 output slot valid
+// register.
+//
+//****************************************************************************
+#define ACOSV_SLV3                              0x00000001L
+#define ACOSV_SLV4                              0x00000002L
+#define ACOSV_SLV5                              0x00000004L
+#define ACOSV_SLV6                              0x00000008L
+#define ACOSV_SLV7                              0x00000010L
+#define ACOSV_SLV8                              0x00000020L
+#define ACOSV_SLV9                              0x00000040L
+#define ACOSV_SLV10                             0x00000080L
+#define ACOSV_SLV11                             0x00000100L
+#define ACOSV_SLV12                             0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 command address
+// register.
+//
+//****************************************************************************
+#define ACCAD_CI_MASK                           0x0000007FL
+#define ACCAD_CI_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 command data register.
+//
+//****************************************************************************
+#define ACCDA_CD_MASK                           0x0000FFFFL
+#define ACCDA_CD_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 input slot valid
+// register.
+//
+//****************************************************************************
+#define ACISV_ISV3                              0x00000001L
+#define ACISV_ISV4                              0x00000002L
+#define ACISV_ISV5                              0x00000004L
+#define ACISV_ISV6                              0x00000008L
+#define ACISV_ISV7                              0x00000010L
+#define ACISV_ISV8                              0x00000020L
+#define ACISV_ISV9                              0x00000040L
+#define ACISV_ISV10                             0x00000080L
+#define ACISV_ISV11                             0x00000100L
+#define ACISV_ISV12                             0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status address
+// register.
+//
+//****************************************************************************
+#define ACSAD_SI_MASK                           0x0000007FL
+#define ACSAD_SI_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status data register.
+//
+//****************************************************************************
+#define ACSDA_SD_MASK                           0x0000FFFFL
+#define ACSDA_SD_SHIFT                          0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers (all 12).
+//
+//****************************************************************************
+#define IOTAC_SA_MASK                           0x0000FFFFL
+#define IOTAC_MSK_MASK                          0x000F0000L
+#define IOTAC_IODC_MASK                         0x06000000L
+#define IOTAC_IODC_16_BIT                       0x00000000L
+#define IOTAC_IODC_10_BIT                       0x02000000L
+#define IOTAC_IODC_12_BIT                       0x04000000L
+#define IOTAC_WSPI                              0x08000000L
+#define IOTAC_RSPI                              0x10000000L
+#define IOTAC_WSE                               0x20000000L
+#define IOTAC_WE                                0x40000000L
+#define IOTAC_RE                                0x80000000L
+#define IOTAC_SA_SHIFT                          0L
+#define IOTAC_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI master enable
+// register.
+//
+//****************************************************************************
+#define PCPCIEN_EN                              0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the joystick poll/trigger
+// register.
+//
+//****************************************************************************
+#define JSPT_CAX                                0x00000001L
+#define JSPT_CAY                                0x00000002L
+#define JSPT_CBX                                0x00000004L
+#define JSPT_CBY                                0x00000008L
+#define JSPT_BA1                                0x00000010L
+#define JSPT_BA2                                0x00000020L
+#define JSPT_BB1                                0x00000040L
+#define JSPT_BB2                                0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the joystick control register.
+// The TBF bit has been moved from MIDSR register to JSCTL register bit 8.
+//
+//****************************************************************************
+#define JSCTL_SP_MASK                           0x00000003L
+#define JSCTL_SP_SLOW                           0x00000000L
+#define JSCTL_SP_MEDIUM_SLOW                    0x00000001L
+#define JSCTL_SP_MEDIUM_FAST                    0x00000002L
+#define JSCTL_SP_FAST                           0x00000003L
+#define JSCTL_ARE                               0x00000004L
+#define JSCTL_TBF                               0x00000100L
+
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI control register.
+//
+//****************************************************************************
+#define MIDCR_TXE                               0x00000001L
+#define MIDCR_RXE                               0x00000002L
+#define MIDCR_RIE                               0x00000004L
+#define MIDCR_TIE                               0x00000008L
+#define MIDCR_MLB                               0x00000010L
+#define MIDCR_MRST                              0x00000020L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI status register.
+//
+//****************************************************************************
+#define MIDSR_RBE                               0x00000080L
+#define MIDSR_RDA                               0x00008000L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI write port register.
+//
+//****************************************************************************
+#define MIDWP_MWD_MASK                          0x000000FFL
+#define MIDWP_MWD_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the MIDI read port register.
+//
+//****************************************************************************
+#define MIDRP_MRD_MASK                          0x000000FFL
+#define MIDRP_MRD_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the configuration interface
+// register.
+//
+//****************************************************************************
+#define CFGI_CLK                                0x00000001L
+#define CFGI_DOUT                               0x00000002L
+#define CFGI_DIN_EEN                            0x00000004L
+#define CFGI_EELD                               0x00000008L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the subsystem ID and vendor ID
+// register.
+//
+//****************************************************************************
+#define SSVID_VID_MASK                          0x0000FFFFL
+#define SSVID_SID_MASK                          0xFFFF0000L
+#define SSVID_VID_SHIFT                         0L
+#define SSVID_SID_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the GPIO pin interface register.
+//
+//****************************************************************************
+#define GPIOR_VOLDN                             0x00000001L
+#define GPIOR_VOLUP                             0x00000002L
+#define GPIOR_SI2D                              0x00000004L
+#define GPIOR_SI2OE                             0x00000008L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status register 2.
+//
+//****************************************************************************
+#define ACSTS2_CRDY                             0x00000001L
+#define ACSTS2_VSTS                             0x00000002L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 input slot valid
+// register 2.
+//
+//****************************************************************************
+#define ACISV2_ISV3                             0x00000001L
+#define ACISV2_ISV4                             0x00000002L
+#define ACISV2_ISV5                             0x00000004L
+#define ACISV2_ISV6                             0x00000008L
+#define ACISV2_ISV7                             0x00000010L
+#define ACISV2_ISV8                             0x00000020L
+#define ACISV2_ISV9                             0x00000040L
+#define ACISV2_ISV10                            0x00000080L
+#define ACISV2_ISV11                            0x00000100L
+#define ACISV2_ISV12                            0x00000200L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status address
+// register 2.
+//
+//****************************************************************************
+#define ACSAD2_SI_MASK                          0x0000007FL
+#define ACSAD2_SI_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 status data register 2.
+//
+//****************************************************************************
+#define ACSDA2_SD_MASK                          0x0000FFFFL
+#define ACSDA2_SD_SHIFT                         0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap control register.
+//
+//****************************************************************************
+#define IOTCR_ITD                               0x00000001L
+#define IOTCR_HRV                               0x00000002L
+#define IOTCR_SRV                               0x00000004L
+#define IOTCR_DTI                               0x00000008L
+#define IOTCR_DFI                               0x00000010L
+#define IOTCR_DDP                               0x00000020L
+#define IOTCR_JTE                               0x00000040L
+#define IOTCR_PPE                               0x00000080L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for Hardware Master Volume.  
+//
+//****************************************************************************
+#define IOTGP_SA_MASK                           0x0000FFFFL
+#define IOTGP_MSK_MASK                          0x000F0000L
+#define IOTGP_IODC_MASK                         0x06000000L
+#define IOTGP_IODC_16_BIT                       0x00000000L
+#define IOTGP_IODC_10_BIT                       0x02000000L
+#define IOTGP_IODC_12_BIT                       0x04000000L
+#define IOTGP_WSPI                              0x08000000L
+#define IOTGP_RSPI                              0x10000000L
+#define IOTGP_WSE                               0x20000000L
+#define IOTGP_WE                                0x40000000L
+#define IOTGP_RE                                0x80000000L
+#define IOTGP_SA_SHIFT                          0L
+#define IOTGP_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for Sound Blaster
+//
+//****************************************************************************
+#define IOTSB_SA_MASK                           0x0000FFFFL
+#define IOTSB_MSK_MASK                          0x000F0000L
+#define IOTSB_IODC_MASK                         0x06000000L
+#define IOTSB_IODC_16_BIT                       0x00000000L
+#define IOTSB_IODC_10_BIT                       0x02000000L
+#define IOTSB_IODC_12_BIT                       0x04000000L
+#define IOTSB_WSPI                              0x08000000L
+#define IOTSB_RSPI                              0x10000000L
+#define IOTSB_WSE                               0x20000000L
+#define IOTSB_WE                                0x40000000L
+#define IOTSB_RE                                0x80000000L
+#define IOTSB_SA_SHIFT                          0L
+#define IOTSB_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the I/O trap address and control
+// registers for FM.
+//
+//****************************************************************************
+#define IOTFM_SA_MASK                           0x0000FFFFL
+#define IOTFM_MSK_MASK                          0x000F0000L
+#define IOTFM_IODC_MASK                         0x06000000L
+#define IOTFM_IODC_16_BIT                       0x00000000L
+#define IOTFM_IODC_10_BIT                       0x02000000L
+#define IOTFM_IODC_12_BIT                       0x04000000L
+#define IOTFM_WSPI                              0x08000000L
+#define IOTFM_RSPI                              0x10000000L
+#define IOTFM_WSE                               0x20000000L
+#define IOTFM_WE                                0x40000000L
+#define IOTFM_RE                                0x80000000L
+#define IOTFM_SA_SHIFT                          0L
+#define IOTFM_MSK_SHIFT                         16L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI request register.
+//
+//****************************************************************************
+#define PCPRR_RDC_MASK                         0x00000007L
+#define PCPRR_REQ                              0x00008000L
+#define PCPRR_RDC_SHIFT                        0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI grant register.
+//
+//****************************************************************************
+#define PCPGR_GDC_MASK                         0x00000007L
+#define PCPGR_VL                               0x00008000L
+#define PCPGR_GDC_SHIFT                        0L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the PC/PCI Control Register.
+//
+//****************************************************************************
+#define PCPCR_EN                               0x00000001L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the debug index register.
+//
+//****************************************************************************
+#define DREG_REGID_MASK                         0x0000007FL
+#define DREG_DEBUG                              0x00000080L
+#define DREG_RGBK_MASK                          0x00000700L
+#define DREG_TRAP                               0x00000800L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX                              0x00001000L
+#endif
+#endif
+#define DREG_REGID_SHIFT                        0L
+#define DREG_RGBK_SHIFT                         8L
+#define DREG_RGBK_REGID_MASK                    0x0000077FL
+#define DREG_REGID_R0                           0x00000010L
+#define DREG_REGID_R1                           0x00000011L
+#define DREG_REGID_R2                           0x00000012L
+#define DREG_REGID_R3                           0x00000013L
+#define DREG_REGID_R4                           0x00000014L
+#define DREG_REGID_R5                           0x00000015L
+#define DREG_REGID_R6                           0x00000016L
+#define DREG_REGID_R7                           0x00000017L
+#define DREG_REGID_R8                           0x00000018L
+#define DREG_REGID_R9                           0x00000019L
+#define DREG_REGID_RA                           0x0000001AL
+#define DREG_REGID_RB                           0x0000001BL
+#define DREG_REGID_RC                           0x0000001CL
+#define DREG_REGID_RD                           0x0000001DL
+#define DREG_REGID_RE                           0x0000001EL
+#define DREG_REGID_RF                           0x0000001FL
+#define DREG_REGID_RA_BUS_LOW                   0x00000020L
+#define DREG_REGID_RA_BUS_HIGH                  0x00000038L
+#define DREG_REGID_YBUS_LOW                     0x00000050L
+#define DREG_REGID_YBUS_HIGH                    0x00000058L
+#define DREG_REGID_TRAP_0                       0x00000100L
+#define DREG_REGID_TRAP_1                       0x00000101L
+#define DREG_REGID_TRAP_2                       0x00000102L
+#define DREG_REGID_TRAP_3                       0x00000103L
+#define DREG_REGID_TRAP_4                       0x00000104L
+#define DREG_REGID_TRAP_5                       0x00000105L
+#define DREG_REGID_TRAP_6                       0x00000106L
+#define DREG_REGID_TRAP_7                       0x00000107L
+#define DREG_REGID_INDIRECT_ADDRESS             0x0000010EL
+#define DREG_REGID_TOP_OF_STACK                 0x0000010FL
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8                       0x00000110L
+#define DREG_REGID_TRAP_9                       0x00000111L
+#define DREG_REGID_TRAP_10                      0x00000112L
+#define DREG_REGID_TRAP_11                      0x00000113L
+#define DREG_REGID_TRAP_12                      0x00000114L
+#define DREG_REGID_TRAP_13                      0x00000115L
+#define DREG_REGID_TRAP_14                      0x00000116L
+#define DREG_REGID_TRAP_15                      0x00000117L
+#define DREG_REGID_TRAP_16                      0x00000118L
+#define DREG_REGID_TRAP_17                      0x00000119L
+#define DREG_REGID_TRAP_18                      0x0000011AL
+#define DREG_REGID_TRAP_19                      0x0000011BL
+#define DREG_REGID_TRAP_20                      0x0000011CL
+#define DREG_REGID_TRAP_21                      0x0000011DL
+#define DREG_REGID_TRAP_22                      0x0000011EL
+#define DREG_REGID_TRAP_23                      0x0000011FL
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW                     0x00000200L
+#define DREG_REGID_RSA0_HIGH                    0x00000201L
+#define DREG_REGID_RSA1_LOW                     0x00000202L
+#define DREG_REGID_RSA1_HIGH                    0x00000203L
+#define DREG_REGID_RSA2                         0x00000204L
+#define DREG_REGID_RSA3                         0x00000205L
+#define DREG_REGID_RSI0_LOW                     0x00000206L
+#define DREG_REGID_RSI0_HIGH                    0x00000207L
+#define DREG_REGID_RSI1                         0x00000208L
+#define DREG_REGID_RSI2                         0x00000209L
+#define DREG_REGID_SAGUSTATUS                   0x0000020AL
+#define DREG_REGID_RSCONFIG01_LOW               0x0000020BL
+#define DREG_REGID_RSCONFIG01_HIGH              0x0000020CL
+#define DREG_REGID_RSCONFIG23_LOW               0x0000020DL
+#define DREG_REGID_RSCONFIG23_HIGH              0x0000020EL
+#define DREG_REGID_RSDMA01E                     0x0000020FL
+#define DREG_REGID_RSDMA23E                     0x00000210L
+#define DREG_REGID_RSD0_LOW                     0x00000211L
+#define DREG_REGID_RSD0_HIGH                    0x00000212L
+#define DREG_REGID_RSD1_LOW                     0x00000213L
+#define DREG_REGID_RSD1_HIGH                    0x00000214L
+#define DREG_REGID_RSD2_LOW                     0x00000215L
+#define DREG_REGID_RSD2_HIGH                    0x00000216L
+#define DREG_REGID_RSD3_LOW                     0x00000217L
+#define DREG_REGID_RSD3_HIGH                    0x00000218L
+#define DREG_REGID_SRAR_HIGH                    0x0000021AL
+#define DREG_REGID_SRAR_LOW                     0x0000021BL
+#define DREG_REGID_DMA_STATE                    0x0000021CL
+#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021DL
+#define DREG_REGID_NEXT_DMA_STREAM              0x0000021EL
+#define DREG_REGID_CPU_STATUS                   0x00000300L
+#define DREG_REGID_MAC_MODE                     0x00000301L
+#define DREG_REGID_STACK_AND_REPEAT             0x00000302L
+#define DREG_REGID_INDEX0                       0x00000304L
+#define DREG_REGID_INDEX1                       0x00000305L
+#define DREG_REGID_DMA_STATE_0_3                0x00000400L
+#define DREG_REGID_DMA_STATE_4_7                0x00000404L
+#define DREG_REGID_DMA_STATE_8_11               0x00000408L
+#define DREG_REGID_DMA_STATE_12_15              0x0000040CL
+#define DREG_REGID_DMA_STATE_16_19              0x00000410L
+#define DREG_REGID_DMA_STATE_20_23              0x00000414L
+#define DREG_REGID_DMA_STATE_24_27              0x00000418L
+#define DREG_REGID_DMA_STATE_28_31              0x0000041CL
+#define DREG_REGID_DMA_STATE_32_35              0x00000420L
+#define DREG_REGID_DMA_STATE_36_39              0x00000424L
+#define DREG_REGID_DMA_STATE_40_43              0x00000428L
+#define DREG_REGID_DMA_STATE_44_47              0x0000042CL
+#define DREG_REGID_DMA_STATE_48_51              0x00000430L
+#define DREG_REGID_DMA_STATE_52_55              0x00000434L
+#define DREG_REGID_DMA_STATE_56_59              0x00000438L
+#define DREG_REGID_DMA_STATE_60_63              0x0000043CL
+#define DREG_REGID_DMA_STATE_64_67              0x00000440L
+#define DREG_REGID_DMA_STATE_68_71              0x00000444L
+#define DREG_REGID_DMA_STATE_72_75              0x00000448L
+#define DREG_REGID_DMA_STATE_76_79              0x0000044CL
+#define DREG_REGID_DMA_STATE_80_83              0x00000450L
+#define DREG_REGID_DMA_STATE_84_87              0x00000454L
+#define DREG_REGID_DMA_STATE_88_91              0x00000458L
+#define DREG_REGID_DMA_STATE_92_95              0x0000045CL
+#define DREG_REGID_TRAP_SELECT                  0x00000500L
+#define DREG_REGID_TRAP_WRITE_0                 0x00000500L
+#define DREG_REGID_TRAP_WRITE_1                 0x00000501L
+#define DREG_REGID_TRAP_WRITE_2                 0x00000502L
+#define DREG_REGID_TRAP_WRITE_3                 0x00000503L
+#define DREG_REGID_TRAP_WRITE_4                 0x00000504L
+#define DREG_REGID_TRAP_WRITE_5                 0x00000505L
+#define DREG_REGID_TRAP_WRITE_6                 0x00000506L
+#define DREG_REGID_TRAP_WRITE_7                 0x00000507L
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8                 0x00000510L
+#define DREG_REGID_TRAP_WRITE_9                 0x00000511L
+#define DREG_REGID_TRAP_WRITE_10                0x00000512L
+#define DREG_REGID_TRAP_WRITE_11                0x00000513L
+#define DREG_REGID_TRAP_WRITE_12                0x00000514L
+#define DREG_REGID_TRAP_WRITE_13                0x00000515L
+#define DREG_REGID_TRAP_WRITE_14                0x00000516L
+#define DREG_REGID_TRAP_WRITE_15                0x00000517L
+#define DREG_REGID_TRAP_WRITE_16                0x00000518L
+#define DREG_REGID_TRAP_WRITE_17                0x00000519L
+#define DREG_REGID_TRAP_WRITE_18                0x0000051AL
+#define DREG_REGID_TRAP_WRITE_19                0x0000051BL
+#define DREG_REGID_TRAP_WRITE_20                0x0000051CL
+#define DREG_REGID_TRAP_WRITE_21                0x0000051DL
+#define DREG_REGID_TRAP_WRITE_22                0x0000051EL
+#define DREG_REGID_TRAP_WRITE_23                0x0000051FL
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW                0x00000600L
+#define DREG_REGID_MAC0_ACC1_LOW                0x00000601L
+#define DREG_REGID_MAC0_ACC2_LOW                0x00000602L
+#define DREG_REGID_MAC0_ACC3_LOW                0x00000603L
+#define DREG_REGID_MAC1_ACC0_LOW                0x00000604L
+#define DREG_REGID_MAC1_ACC1_LOW                0x00000605L
+#define DREG_REGID_MAC1_ACC2_LOW                0x00000606L
+#define DREG_REGID_MAC1_ACC3_LOW                0x00000607L
+#define DREG_REGID_MAC0_ACC0_MID                0x00000608L
+#define DREG_REGID_MAC0_ACC1_MID                0x00000609L
+#define DREG_REGID_MAC0_ACC2_MID                0x0000060AL
+#define DREG_REGID_MAC0_ACC3_MID                0x0000060BL
+#define DREG_REGID_MAC1_ACC0_MID                0x0000060CL
+#define DREG_REGID_MAC1_ACC1_MID                0x0000060DL
+#define DREG_REGID_MAC1_ACC2_MID                0x0000060EL
+#define DREG_REGID_MAC1_ACC3_MID                0x0000060FL
+#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610L
+#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611L
+#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612L
+#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613L
+#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614L
+#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615L
+#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616L
+#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617L
+#define DREG_REGID_RSHOUT_LOW                   0x00000620L
+#define DREG_REGID_RSHOUT_MID                   0x00000628L
+#define DREG_REGID_RSHOUT_HIGH                  0x00000630L
+
+//****************************************************************************
+//
+// The following defines are for the flags in the AC97 S/PDIF Control register.
+//
+//****************************************************************************
+#define SPDIF_CONTROL_SPDIF_EN                 0x00008000L
+#define SPDIF_CONTROL_VAL                      0x00004000L
+#define SPDIF_CONTROL_COPY                     0x00000004L
+#define SPDIF_CONTROL_CC0                      0x00000010L
+#define SPDIF_CONTROL_CC1                      0x00000020L
+#define SPDIF_CONTROL_CC2                      0x00000040L
+#define SPDIF_CONTROL_CC3                      0x00000080L
+#define SPDIF_CONTROL_CC4                      0x00000100L
+#define SPDIF_CONTROL_CC5                      0x00000200L
+#define SPDIF_CONTROL_CC6                      0x00000400L
+#define SPDIF_CONTROL_L                        0x00000800L
+
+#endif // _H_HWDEFS
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/cs461x.h linux.17p18/drivers/sound/cs461x.h
--- linux.vanilla/drivers/sound/cs461x.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/cs461x.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,1617 @@
+#ifndef __CS461X_H
+#define __CS461X_H
+
+/*
+ *  Copyright (c) by Jaroslav Kysela <perex@suse.cz>
+ *  Definitions for Cirrus Logic CS461x chips
+ *
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#ifndef PCI_VENDOR_ID_CIRRUS
+#define PCI_VENDOR_ID_CIRRUS            0x1013
+#endif
+#ifndef PCI_DEVICE_ID_CIRRUS_4610
+#define PCI_DEVICE_ID_CIRRUS_4610       0x6001
+#endif
+#ifndef PCI_DEVICE_ID_CIRRUS_4612
+#define PCI_DEVICE_ID_CIRRUS_4612       0x6003
+#endif
+#ifndef PCI_DEVICE_ID_CIRRUS_4615
+#define PCI_DEVICE_ID_CIRRUS_4615       0x6004
+#endif
+
+/*
+ *  Direct registers
+ */
+
+/*
+ *  The following define the offsets of the registers accessed via base address
+ *  register zero on the CS461x part.
+ */
+#define BA0_HISR				0x00000000
+#define BA0_HSR0                                0x00000004
+#define BA0_HICR                                0x00000008
+#define BA0_DMSR                                0x00000100
+#define BA0_HSAR                                0x00000110
+#define BA0_HDAR                                0x00000114
+#define BA0_HDMR                                0x00000118
+#define BA0_HDCR                                0x0000011C
+#define BA0_PFMC                                0x00000200
+#define BA0_PFCV1                               0x00000204
+#define BA0_PFCV2                               0x00000208
+#define BA0_PCICFG00                            0x00000300
+#define BA0_PCICFG04                            0x00000304
+#define BA0_PCICFG08                            0x00000308
+#define BA0_PCICFG0C                            0x0000030C
+#define BA0_PCICFG10                            0x00000310
+#define BA0_PCICFG14                            0x00000314
+#define BA0_PCICFG18                            0x00000318
+#define BA0_PCICFG1C                            0x0000031C
+#define BA0_PCICFG20                            0x00000320
+#define BA0_PCICFG24                            0x00000324
+#define BA0_PCICFG28                            0x00000328
+#define BA0_PCICFG2C                            0x0000032C
+#define BA0_PCICFG30                            0x00000330
+#define BA0_PCICFG34                            0x00000334
+#define BA0_PCICFG38                            0x00000338
+#define BA0_PCICFG3C                            0x0000033C
+#define BA0_CLKCR1                              0x00000400
+#define BA0_CLKCR2                              0x00000404
+#define BA0_PLLM                                0x00000408
+#define BA0_PLLCC                               0x0000040C
+#define BA0_FRR                                 0x00000410 
+#define BA0_CFL1                                0x00000414
+#define BA0_CFL2                                0x00000418
+#define BA0_SERMC1                              0x00000420
+#define BA0_SERMC2                              0x00000424
+#define BA0_SERC1                               0x00000428
+#define BA0_SERC2                               0x0000042C
+#define BA0_SERC3                               0x00000430
+#define BA0_SERC4                               0x00000434
+#define BA0_SERC5                               0x00000438
+#define BA0_SERBSP                              0x0000043C
+#define BA0_SERBST                              0x00000440
+#define BA0_SERBCM                              0x00000444
+#define BA0_SERBAD                              0x00000448
+#define BA0_SERBCF                              0x0000044C
+#define BA0_SERBWP                              0x00000450
+#define BA0_SERBRP                              0x00000454
+#ifndef NO_CS4612
+#define BA0_ASER_FADDR                          0x00000458
+#endif
+#define BA0_ACCTL                               0x00000460
+#define BA0_ACSTS                               0x00000464
+#define BA0_ACOSV                               0x00000468
+#define BA0_ACCAD                               0x0000046C
+#define BA0_ACCDA                               0x00000470
+#define BA0_ACISV                               0x00000474
+#define BA0_ACSAD                               0x00000478
+#define BA0_ACSDA                               0x0000047C
+#define BA0_JSPT                                0x00000480
+#define BA0_JSCTL                               0x00000484
+#define BA0_JSC1                                0x00000488
+#define BA0_JSC2                                0x0000048C
+#define BA0_MIDCR                               0x00000490
+#define BA0_MIDSR                               0x00000494
+#define BA0_MIDWP                               0x00000498
+#define BA0_MIDRP                               0x0000049C
+#define BA0_JSIO                                0x000004A0
+#ifndef NO_CS4612
+#define BA0_ASER_MASTER                         0x000004A4
+#endif
+#define BA0_CFGI                                0x000004B0
+#define BA0_SSVID                               0x000004B4
+#define BA0_GPIOR                               0x000004B8
+#ifndef NO_CS4612
+#define BA0_EGPIODR                             0x000004BC
+#define BA0_EGPIOPTR                            0x000004C0
+#define BA0_EGPIOTR                             0x000004C4
+#define BA0_EGPIOWR                             0x000004C8
+#define BA0_EGPIOSR                             0x000004CC
+#define BA0_SERC6                               0x000004D0
+#define BA0_SERC7                               0x000004D4
+#define BA0_SERACC                              0x000004D8
+#define BA0_ACCTL2                              0x000004E0
+#define BA0_ACSTS2                              0x000004E4
+#define BA0_ACOSV2                              0x000004E8
+#define BA0_ACCAD2                              0x000004EC
+#define BA0_ACCDA2                              0x000004F0
+#define BA0_ACISV2                              0x000004F4
+#define BA0_ACSAD2                              0x000004F8
+#define BA0_ACSDA2                              0x000004FC
+#define BA0_IOTAC0                              0x00000500
+#define BA0_IOTAC1                              0x00000504
+#define BA0_IOTAC2                              0x00000508
+#define BA0_IOTAC3                              0x0000050C
+#define BA0_IOTAC4                              0x00000510
+#define BA0_IOTAC5                              0x00000514
+#define BA0_IOTAC6                              0x00000518
+#define BA0_IOTAC7                              0x0000051C
+#define BA0_IOTAC8                              0x00000520
+#define BA0_IOTAC9                              0x00000524
+#define BA0_IOTAC10                             0x00000528
+#define BA0_IOTAC11                             0x0000052C
+#define BA0_IOTFR0                              0x00000540
+#define BA0_IOTFR1                              0x00000544
+#define BA0_IOTFR2                              0x00000548
+#define BA0_IOTFR3                              0x0000054C
+#define BA0_IOTFR4                              0x00000550
+#define BA0_IOTFR5                              0x00000554
+#define BA0_IOTFR6                              0x00000558
+#define BA0_IOTFR7                              0x0000055C
+#define BA0_IOTFIFO                             0x00000580
+#define BA0_IOTRRD                              0x00000584
+#define BA0_IOTFP                               0x00000588
+#define BA0_IOTCR                               0x0000058C
+#define BA0_DPCID                               0x00000590
+#define BA0_DPCIA                               0x00000594
+#define BA0_DPCIC                               0x00000598
+#define BA0_PCPCIR                              0x00000600
+#define BA0_PCPCIG                              0x00000604
+#define BA0_PCPCIEN                             0x00000608
+#define BA0_EPCIPMC                             0x00000610
+#endif
+
+/*
+ *  The following define the offsets of the registers and memories accessed via
+ *  base address register one on the CS461x part.
+ */
+#define BA1_SP_DMEM0                            0x00000000
+#define BA1_SP_DMEM1                            0x00010000
+#define BA1_SP_PMEM                             0x00020000
+#define BA1_SP_REG				0x00030000
+#define BA1_SPCR                                0x00030000
+#define BA1_DREG                                0x00030004
+#define BA1_DSRWP                               0x00030008
+#define BA1_TWPR                                0x0003000C
+#define BA1_SPWR                                0x00030010
+#define BA1_SPIR                                0x00030014
+#define BA1_FGR1                                0x00030020
+#define BA1_SPCS                                0x00030028
+#define BA1_SDSR                                0x0003002C
+#define BA1_FRMT                                0x00030030
+#define BA1_FRCC                                0x00030034
+#define BA1_FRSC                                0x00030038
+#define BA1_OMNI_MEM                            0x000E0000
+
+/*
+ *  The following defines are for the flags in the host interrupt status
+ *  register.
+ */
+#define HISR_VC_MASK                            0x0000FFFF
+#define HISR_VC0                                0x00000001
+#define HISR_VC1                                0x00000002
+#define HISR_VC2                                0x00000004
+#define HISR_VC3                                0x00000008
+#define HISR_VC4                                0x00000010
+#define HISR_VC5                                0x00000020
+#define HISR_VC6                                0x00000040
+#define HISR_VC7                                0x00000080
+#define HISR_VC8                                0x00000100
+#define HISR_VC9                                0x00000200
+#define HISR_VC10                               0x00000400
+#define HISR_VC11                               0x00000800
+#define HISR_VC12                               0x00001000
+#define HISR_VC13                               0x00002000
+#define HISR_VC14                               0x00004000
+#define HISR_VC15                               0x00008000
+#define HISR_INT0                               0x00010000
+#define HISR_INT1                               0x00020000
+#define HISR_DMAI                               0x00040000
+#define HISR_FROVR                              0x00080000
+#define HISR_MIDI                               0x00100000
+#ifdef NO_CS4612
+#define HISR_RESERVED                           0x0FE00000
+#else
+#define HISR_SBINT                              0x00200000
+#define HISR_RESERVED                           0x0FC00000
+#endif
+#define HISR_H0P                                0x40000000
+#define HISR_INTENA                             0x80000000
+
+/*
+ *  The following defines are for the flags in the host signal register 0.
+ */
+#define HSR0_VC_MASK                            0xFFFFFFFF
+#define HSR0_VC16                               0x00000001
+#define HSR0_VC17                               0x00000002
+#define HSR0_VC18                               0x00000004
+#define HSR0_VC19                               0x00000008
+#define HSR0_VC20                               0x00000010
+#define HSR0_VC21                               0x00000020
+#define HSR0_VC22                               0x00000040
+#define HSR0_VC23                               0x00000080
+#define HSR0_VC24                               0x00000100
+#define HSR0_VC25                               0x00000200
+#define HSR0_VC26                               0x00000400
+#define HSR0_VC27                               0x00000800
+#define HSR0_VC28                               0x00001000
+#define HSR0_VC29                               0x00002000
+#define HSR0_VC30                               0x00004000
+#define HSR0_VC31                               0x00008000
+#define HSR0_VC32                               0x00010000
+#define HSR0_VC33                               0x00020000
+#define HSR0_VC34                               0x00040000
+#define HSR0_VC35                               0x00080000
+#define HSR0_VC36                               0x00100000
+#define HSR0_VC37                               0x00200000
+#define HSR0_VC38                               0x00400000
+#define HSR0_VC39                               0x00800000
+#define HSR0_VC40                               0x01000000
+#define HSR0_VC41                               0x02000000
+#define HSR0_VC42                               0x04000000
+#define HSR0_VC43                               0x08000000
+#define HSR0_VC44                               0x10000000
+#define HSR0_VC45                               0x20000000
+#define HSR0_VC46                               0x40000000
+#define HSR0_VC47                               0x80000000
+
+/*
+ *  The following defines are for the flags in the host interrupt control
+ *  register.
+ */
+#define HICR_IEV                                0x00000001
+#define HICR_CHGM                               0x00000002
+
+/*
+ *  The following defines are for the flags in the DMA status register.
+ */
+#define DMSR_HP                                 0x00000001
+#define DMSR_HR                                 0x00000002
+#define DMSR_SP                                 0x00000004
+#define DMSR_SR                                 0x00000008
+
+/*
+ *  The following defines are for the flags in the host DMA source address
+ *  register.
+ */
+#define HSAR_HOST_ADDR_MASK                     0xFFFFFFFF
+#define HSAR_DSP_ADDR_MASK                      0x0000FFFF
+#define HSAR_MEMID_MASK                         0x000F0000
+#define HSAR_MEMID_SP_DMEM0                     0x00000000
+#define HSAR_MEMID_SP_DMEM1                     0x00010000
+#define HSAR_MEMID_SP_PMEM                      0x00020000
+#define HSAR_MEMID_SP_DEBUG                     0x00030000
+#define HSAR_MEMID_OMNI_MEM                     0x000E0000
+#define HSAR_END                                0x40000000
+#define HSAR_ERR                                0x80000000
+
+/*
+ *  The following defines are for the flags in the host DMA destination address
+ *  register.
+ */
+#define HDAR_HOST_ADDR_MASK                     0xFFFFFFFF
+#define HDAR_DSP_ADDR_MASK                      0x0000FFFF
+#define HDAR_MEMID_MASK                         0x000F0000
+#define HDAR_MEMID_SP_DMEM0                     0x00000000
+#define HDAR_MEMID_SP_DMEM1                     0x00010000
+#define HDAR_MEMID_SP_PMEM                      0x00020000
+#define HDAR_MEMID_SP_DEBUG                     0x00030000
+#define HDAR_MEMID_OMNI_MEM                     0x000E0000
+#define HDAR_END                                0x40000000
+#define HDAR_ERR                                0x80000000
+
+/*
+ *  The following defines are for the flags in the host DMA control register.
+ */
+#define HDMR_AC_MASK                            0x0000F000
+#define HDMR_AC_8_16                            0x00001000
+#define HDMR_AC_M_S                             0x00002000
+#define HDMR_AC_B_L                             0x00004000
+#define HDMR_AC_S_U                             0x00008000
+
+/*
+ *  The following defines are for the flags in the host DMA control register.
+ */
+#define HDCR_COUNT_MASK                         0x000003FF
+#define HDCR_DONE                               0x00004000
+#define HDCR_OPT                                0x00008000
+#define HDCR_WBD                                0x00400000
+#define HDCR_WBS                                0x00800000
+#define HDCR_DMS_MASK                           0x07000000
+#define HDCR_DMS_LINEAR                         0x00000000
+#define HDCR_DMS_16_DWORDS                      0x01000000
+#define HDCR_DMS_32_DWORDS                      0x02000000
+#define HDCR_DMS_64_DWORDS                      0x03000000
+#define HDCR_DMS_128_DWORDS                     0x04000000
+#define HDCR_DMS_256_DWORDS                     0x05000000
+#define HDCR_DMS_512_DWORDS                     0x06000000
+#define HDCR_DMS_1024_DWORDS                    0x07000000
+#define HDCR_DH                                 0x08000000
+#define HDCR_SMS_MASK                           0x70000000
+#define HDCR_SMS_LINEAR                         0x00000000
+#define HDCR_SMS_16_DWORDS                      0x10000000
+#define HDCR_SMS_32_DWORDS                      0x20000000
+#define HDCR_SMS_64_DWORDS                      0x30000000
+#define HDCR_SMS_128_DWORDS                     0x40000000
+#define HDCR_SMS_256_DWORDS                     0x50000000
+#define HDCR_SMS_512_DWORDS                     0x60000000
+#define HDCR_SMS_1024_DWORDS                    0x70000000
+#define HDCR_SH                                 0x80000000
+#define HDCR_COUNT_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the performance monitor control
+ *  register.
+ */
+#define PFMC_C1SS_MASK                          0x0000001F
+#define PFMC_C1EV                               0x00000020
+#define PFMC_C1RS                               0x00008000
+#define PFMC_C2SS_MASK                          0x001F0000
+#define PFMC_C2EV                               0x00200000
+#define PFMC_C2RS                               0x80000000
+#define PFMC_C1SS_SHIFT                         0
+#define PFMC_C2SS_SHIFT                         16
+#define PFMC_BUS_GRANT                          0
+#define PFMC_GRANT_AFTER_REQ                    1
+#define PFMC_TRANSACTION                        2
+#define PFMC_DWORD_TRANSFER                     3
+#define PFMC_SLAVE_READ                         4
+#define PFMC_SLAVE_WRITE                        5
+#define PFMC_PREEMPTION                         6
+#define PFMC_DISCONNECT_RETRY                   7
+#define PFMC_INTERRUPT                          8
+#define PFMC_BUS_OWNERSHIP                      9
+#define PFMC_TRANSACTION_LAG                    10
+#define PFMC_PCI_CLOCK                          11
+#define PFMC_SERIAL_CLOCK                       12
+#define PFMC_SP_CLOCK                           13
+
+/*
+ *  The following defines are for the flags in the performance counter value 1
+ *  register.
+ */
+#define PFCV1_PC1V_MASK                         0xFFFFFFFF
+#define PFCV1_PC1V_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the performance counter value 2
+ *  register.
+ */
+#define PFCV2_PC2V_MASK                         0xFFFFFFFF
+#define PFCV2_PC2V_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the clock control register 1.
+ */
+#define CLKCR1_OSCS                             0x00000001
+#define CLKCR1_OSCP                             0x00000002
+#define CLKCR1_PLLSS_MASK                       0x0000000C
+#define CLKCR1_PLLSS_SERIAL                     0x00000000
+#define CLKCR1_PLLSS_CRYSTAL                    0x00000004
+#define CLKCR1_PLLSS_PCI                        0x00000008
+#define CLKCR1_PLLSS_RESERVED                   0x0000000C
+#define CLKCR1_PLLP                             0x00000010
+#define CLKCR1_SWCE                             0x00000020
+#define CLKCR1_PLLOS                            0x00000040
+
+/*
+ *  The following defines are for the flags in the clock control register 2.
+ */
+#define CLKCR2_PDIVS_MASK                       0x0000000F
+#define CLKCR2_PDIVS_1                          0x00000001
+#define CLKCR2_PDIVS_2                          0x00000002
+#define CLKCR2_PDIVS_4                          0x00000004
+#define CLKCR2_PDIVS_7                          0x00000007
+#define CLKCR2_PDIVS_8                          0x00000008
+#define CLKCR2_PDIVS_16                         0x00000000
+
+/*
+ *  The following defines are for the flags in the PLL multiplier register.
+ */
+#define PLLM_MASK                               0x000000FF
+#define PLLM_SHIFT                              0
+
+/*
+ *  The following defines are for the flags in the PLL capacitor coefficient
+ *  register.
+ */
+#define PLLCC_CDR_MASK                          0x00000007
+#ifndef NO_CS4610
+#define PLLCC_CDR_240_350_MHZ                   0x00000000
+#define PLLCC_CDR_184_265_MHZ                   0x00000001
+#define PLLCC_CDR_144_205_MHZ                   0x00000002
+#define PLLCC_CDR_111_160_MHZ                   0x00000003
+#define PLLCC_CDR_87_123_MHZ                    0x00000004
+#define PLLCC_CDR_67_96_MHZ                     0x00000005
+#define PLLCC_CDR_52_74_MHZ                     0x00000006
+#define PLLCC_CDR_45_58_MHZ                     0x00000007
+#endif
+#ifndef NO_CS4612
+#define PLLCC_CDR_271_398_MHZ                   0x00000000
+#define PLLCC_CDR_227_330_MHZ                   0x00000001
+#define PLLCC_CDR_167_239_MHZ                   0x00000002
+#define PLLCC_CDR_150_215_MHZ                   0x00000003
+#define PLLCC_CDR_107_154_MHZ                   0x00000004
+#define PLLCC_CDR_98_140_MHZ                    0x00000005
+#define PLLCC_CDR_73_104_MHZ                    0x00000006
+#define PLLCC_CDR_63_90_MHZ                     0x00000007
+#endif
+#define PLLCC_LPF_MASK                          0x000000F8
+#ifndef NO_CS4610
+#define PLLCC_LPF_23850_60000_KHZ               0x00000000
+#define PLLCC_LPF_7960_26290_KHZ                0x00000008
+#define PLLCC_LPF_4160_10980_KHZ                0x00000018
+#define PLLCC_LPF_1740_4580_KHZ                 0x00000038
+#define PLLCC_LPF_724_1910_KHZ                  0x00000078
+#define PLLCC_LPF_317_798_KHZ                   0x000000F8
+#endif
+#ifndef NO_CS4612
+#define PLLCC_LPF_25580_64530_KHZ               0x00000000
+#define PLLCC_LPF_14360_37270_KHZ               0x00000008
+#define PLLCC_LPF_6100_16020_KHZ                0x00000018
+#define PLLCC_LPF_2540_6690_KHZ                 0x00000038
+#define PLLCC_LPF_1050_2780_KHZ                 0x00000078
+#define PLLCC_LPF_450_1160_KHZ                  0x000000F8
+#endif
+
+/*
+ *  The following defines are for the flags in the feature reporting register.
+ */
+#define FRR_FAB_MASK                            0x00000003
+#define FRR_MASK_MASK                           0x0000001C
+#ifdef NO_CS4612
+#define FRR_CFOP_MASK                           0x000000E0
+#else
+#define FRR_CFOP_MASK                           0x00000FE0
+#endif
+#define FRR_CFOP_NOT_DVD                        0x00000020
+#define FRR_CFOP_A3D                            0x00000040
+#define FRR_CFOP_128_PIN                        0x00000080
+#ifndef NO_CS4612
+#define FRR_CFOP_CS4280                         0x00000800
+#endif
+#define FRR_FAB_SHIFT                           0
+#define FRR_MASK_SHIFT                          2
+#define FRR_CFOP_SHIFT                          5
+
+/*
+ *  The following defines are for the flags in the configuration load 1
+ *  register.
+ */
+#define CFL1_CLOCK_SOURCE_MASK                  0x00000003
+#define CFL1_CLOCK_SOURCE_CS423X                0x00000000
+#define CFL1_CLOCK_SOURCE_AC97                  0x00000001
+#define CFL1_CLOCK_SOURCE_CRYSTAL               0x00000002
+#define CFL1_CLOCK_SOURCE_DUAL_AC97             0x00000003
+#define CFL1_VALID_DATA_MASK                    0x000000FF
+
+/*
+ *  The following defines are for the flags in the configuration load 2
+ *  register.
+ */
+#define CFL2_VALID_DATA_MASK                    0x000000FF
+
+/*
+ *  The following defines are for the flags in the serial port master control
+ *  register 1.
+ */
+#define SERMC1_MSPE                             0x00000001
+#define SERMC1_PTC_MASK                         0x0000000E
+#define SERMC1_PTC_CS423X                       0x00000000
+#define SERMC1_PTC_AC97                         0x00000002
+#define SERMC1_PTC_DAC                          0x00000004
+#define SERMC1_PLB                              0x00000010
+#define SERMC1_XLB                              0x00000020
+
+/*
+ *  The following defines are for the flags in the serial port master control
+ *  register 2.
+ */
+#define SERMC2_LROE                             0x00000001
+#define SERMC2_MCOE                             0x00000002
+#define SERMC2_MCDIV                            0x00000004
+
+/*
+ *  The following defines are for the flags in the serial port 1 configuration
+ *  register.
+ */
+#define SERC1_SO1EN                             0x00000001
+#define SERC1_SO1F_MASK                         0x0000000E
+#define SERC1_SO1F_CS423X                       0x00000000
+#define SERC1_SO1F_AC97                         0x00000002
+#define SERC1_SO1F_DAC                          0x00000004
+#define SERC1_SO1F_SPDIF                        0x00000006
+
+/*
+ *  The following defines are for the flags in the serial port 2 configuration
+ *  register.
+ */
+#define SERC2_SI1EN                             0x00000001
+#define SERC2_SI1F_MASK                         0x0000000E
+#define SERC2_SI1F_CS423X                       0x00000000
+#define SERC2_SI1F_AC97                         0x00000002
+#define SERC2_SI1F_ADC                          0x00000004
+#define SERC2_SI1F_SPDIF                        0x00000006
+
+/*
+ *  The following defines are for the flags in the serial port 3 configuration
+ *  register.
+ */
+#define SERC3_SO2EN                             0x00000001
+#define SERC3_SO2F_MASK                         0x00000006
+#define SERC3_SO2F_DAC                          0x00000000
+#define SERC3_SO2F_SPDIF                        0x00000002
+
+/*
+ *  The following defines are for the flags in the serial port 4 configuration
+ *  register.
+ */
+#define SERC4_SO3EN                             0x00000001
+#define SERC4_SO3F_MASK                         0x00000006
+#define SERC4_SO3F_DAC                          0x00000000
+#define SERC4_SO3F_SPDIF                        0x00000002
+
+/*
+ *  The following defines are for the flags in the serial port 5 configuration
+ *  register.
+ */
+#define SERC5_SI2EN                             0x00000001
+#define SERC5_SI2F_MASK                         0x00000006
+#define SERC5_SI2F_ADC                          0x00000000
+#define SERC5_SI2F_SPDIF                        0x00000002
+
+/*
+ *  The following defines are for the flags in the serial port backdoor sample
+ *  pointer register.
+ */
+#define SERBSP_FSP_MASK                         0x0000000F
+#define SERBSP_FSP_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the serial port backdoor status
+ *  register.
+ */
+#define SERBST_RRDY                             0x00000001
+#define SERBST_WBSY                             0x00000002
+
+/*
+ *  The following defines are for the flags in the serial port backdoor command
+ *  register.
+ */
+#define SERBCM_RDC                              0x00000001
+#define SERBCM_WRC                              0x00000002
+
+/*
+ *  The following defines are for the flags in the serial port backdoor address
+ *  register.
+ */
+#ifdef NO_CS4612
+#define SERBAD_FAD_MASK                         0x000000FF
+#else
+#define SERBAD_FAD_MASK                         0x000001FF
+#endif
+#define SERBAD_FAD_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the serial port backdoor
+ *  configuration register.
+ */
+#define SERBCF_HBP                              0x00000001
+
+/*
+ *  The following defines are for the flags in the serial port backdoor write
+ *  port register.
+ */
+#define SERBWP_FWD_MASK                         0x000FFFFF
+#define SERBWP_FWD_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the serial port backdoor read
+ *  port register.
+ */
+#define SERBRP_FRD_MASK                         0x000FFFFF
+#define SERBRP_FRD_SHIFT                        0
+
+/*
+ *  The following defines are for the flags in the async FIFO address register.
+ */
+#ifndef NO_CS4612
+#define ASER_FADDR_A1_MASK                      0x000001FF
+#define ASER_FADDR_EN1                          0x00008000
+#define ASER_FADDR_A2_MASK                      0x01FF0000
+#define ASER_FADDR_EN2                          0x80000000
+#define ASER_FADDR_A1_SHIFT                     0
+#define ASER_FADDR_A2_SHIFT                     16
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 control register.
+ */
+#define ACCTL_RSTN                              0x00000001
+#define ACCTL_ESYN                              0x00000002
+#define ACCTL_VFRM                              0x00000004
+#define ACCTL_DCV                               0x00000008
+#define ACCTL_CRW                               0x00000010
+#define ACCTL_ASYN                              0x00000020
+#ifndef NO_CS4612
+#define ACCTL_TC                                0x00000040
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 status register.
+ */
+#define ACSTS_CRDY                              0x00000001
+#define ACSTS_VSTS                              0x00000002
+#ifndef NO_CS4612
+#define ACSTS_WKUP                              0x00000004
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 output slot valid
+ *  register.
+ */
+#define ACOSV_SLV3                              0x00000001
+#define ACOSV_SLV4                              0x00000002
+#define ACOSV_SLV5                              0x00000004
+#define ACOSV_SLV6                              0x00000008
+#define ACOSV_SLV7                              0x00000010
+#define ACOSV_SLV8                              0x00000020
+#define ACOSV_SLV9                              0x00000040
+#define ACOSV_SLV10                             0x00000080
+#define ACOSV_SLV11                             0x00000100
+#define ACOSV_SLV12                             0x00000200
+
+/*
+ *  The following defines are for the flags in the AC97 command address
+ *  register.
+ */
+#define ACCAD_CI_MASK                           0x0000007F
+#define ACCAD_CI_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the AC97 command data register.
+ */
+#define ACCDA_CD_MASK                           0x0000FFFF
+#define ACCDA_CD_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the AC97 input slot valid
+ *  register.
+ */
+#define ACISV_ISV3                              0x00000001
+#define ACISV_ISV4                              0x00000002
+#define ACISV_ISV5                              0x00000004
+#define ACISV_ISV6                              0x00000008
+#define ACISV_ISV7                              0x00000010
+#define ACISV_ISV8                              0x00000020
+#define ACISV_ISV9                              0x00000040
+#define ACISV_ISV10                             0x00000080
+#define ACISV_ISV11                             0x00000100
+#define ACISV_ISV12                             0x00000200
+
+/*
+ *  The following defines are for the flags in the AC97 status address
+ *  register.
+ */
+#define ACSAD_SI_MASK                           0x0000007F
+#define ACSAD_SI_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the AC97 status data register.
+ */
+#define ACSDA_SD_MASK                           0x0000FFFF
+#define ACSDA_SD_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the joystick poll/trigger
+ *  register.
+ */
+#define JSPT_CAX                                0x00000001
+#define JSPT_CAY                                0x00000002
+#define JSPT_CBX                                0x00000004
+#define JSPT_CBY                                0x00000008
+#define JSPT_BA1                                0x00000010
+#define JSPT_BA2                                0x00000020
+#define JSPT_BB1                                0x00000040
+#define JSPT_BB2                                0x00000080
+
+/*
+ *  The following defines are for the flags in the joystick control register.
+ */
+#define JSCTL_SP_MASK                           0x00000003
+#define JSCTL_SP_SLOW                           0x00000000
+#define JSCTL_SP_MEDIUM_SLOW                    0x00000001
+#define JSCTL_SP_MEDIUM_FAST                    0x00000002
+#define JSCTL_SP_FAST                           0x00000003
+#define JSCTL_ARE                               0x00000004
+
+/*
+ *  The following defines are for the flags in the joystick coordinate pair 1
+ *  readback register.
+ */
+#define JSC1_Y1V_MASK                           0x0000FFFF
+#define JSC1_X1V_MASK                           0xFFFF0000
+#define JSC1_Y1V_SHIFT                          0
+#define JSC1_X1V_SHIFT                          16
+
+/*
+ *  The following defines are for the flags in the joystick coordinate pair 2
+ *  readback register.
+ */
+#define JSC2_Y2V_MASK                           0x0000FFFF
+#define JSC2_X2V_MASK                           0xFFFF0000
+#define JSC2_Y2V_SHIFT                          0
+#define JSC2_X2V_SHIFT                          16
+
+/*
+ *  The following defines are for the flags in the MIDI control register.
+ */
+#define MIDCR_TXE                               0x00000001	/* Enable transmitting. */
+#define MIDCR_RXE                               0x00000002	/* Enable receiving. */
+#define MIDCR_RIE                               0x00000004	/* Interrupt upon tx ready. */
+#define MIDCR_TIE                               0x00000008	/* Interrupt upon rx ready. */
+#define MIDCR_MLB                               0x00000010	/* Enable midi loopback. */
+#define MIDCR_MRST                              0x00000020	/* Reset interface. */
+
+/*
+ *  The following defines are for the flags in the MIDI status register.
+ */
+#define MIDSR_TBF                               0x00000001	/* Tx FIFO is full. */
+#define MIDSR_RBE                               0x00000002	/* Rx FIFO is empty. */
+
+/*
+ *  The following defines are for the flags in the MIDI write port register.
+ */
+#define MIDWP_MWD_MASK                          0x000000FF
+#define MIDWP_MWD_SHIFT                         0
+
+/*
+ *  The following defines are for the flags in the MIDI read port register.
+ */
+#define MIDRP_MRD_MASK                          0x000000FF
+#define MIDRP_MRD_SHIFT                         0
+
+/*
+ *  The following defines are for the flags in the joystick GPIO register.
+ */
+#define JSIO_DAX                                0x00000001
+#define JSIO_DAY                                0x00000002
+#define JSIO_DBX                                0x00000004
+#define JSIO_DBY                                0x00000008
+#define JSIO_AXOE                               0x00000010
+#define JSIO_AYOE                               0x00000020
+#define JSIO_BXOE                               0x00000040
+#define JSIO_BYOE                               0x00000080
+
+/*
+ *  The following defines are for the flags in the master async/sync serial
+ *  port enable register.
+ */
+#ifndef NO_CS4612
+#define ASER_MASTER_ME                          0x00000001
+#endif
+
+/*
+ *  The following defines are for the flags in the configuration interface
+ *  register.
+ */
+#define CFGI_CLK                                0x00000001
+#define CFGI_DOUT                               0x00000002
+#define CFGI_DIN_EEN                            0x00000004
+#define CFGI_EELD                               0x00000008
+
+/*
+ *  The following defines are for the flags in the subsystem ID and vendor ID
+ *  register.
+ */
+#define SSVID_VID_MASK                          0x0000FFFF
+#define SSVID_SID_MASK                          0xFFFF0000
+#define SSVID_VID_SHIFT                         0
+#define SSVID_SID_SHIFT                         16
+
+/*
+ *  The following defines are for the flags in the GPIO pin interface register.
+ */
+#define GPIOR_VOLDN                             0x00000001
+#define GPIOR_VOLUP                             0x00000002
+#define GPIOR_SI2D                              0x00000004
+#define GPIOR_SI2OE                             0x00000008
+
+/*
+ *  The following defines are for the flags in the extended GPIO pin direction
+ *  register.
+ */
+#ifndef NO_CS4612
+#define EGPIODR_GPOE0                           0x00000001
+#define EGPIODR_GPOE1                           0x00000002
+#define EGPIODR_GPOE2                           0x00000004
+#define EGPIODR_GPOE3                           0x00000008
+#define EGPIODR_GPOE4                           0x00000010
+#define EGPIODR_GPOE5                           0x00000020
+#define EGPIODR_GPOE6                           0x00000040
+#define EGPIODR_GPOE7                           0x00000080
+#define EGPIODR_GPOE8                           0x00000100
+#endif
+
+/*
+ *  The following defines are for the flags in the extended GPIO pin polarity/
+ *  type register.
+ */
+#ifndef NO_CS4612
+#define EGPIOPTR_GPPT0                          0x00000001
+#define EGPIOPTR_GPPT1                          0x00000002
+#define EGPIOPTR_GPPT2                          0x00000004
+#define EGPIOPTR_GPPT3                          0x00000008
+#define EGPIOPTR_GPPT4                          0x00000010
+#define EGPIOPTR_GPPT5                          0x00000020
+#define EGPIOPTR_GPPT6                          0x00000040
+#define EGPIOPTR_GPPT7                          0x00000080
+#define EGPIOPTR_GPPT8                          0x00000100
+#endif
+
+/*
+ *  The following defines are for the flags in the extended GPIO pin sticky
+ *  register.
+ */
+#ifndef NO_CS4612
+#define EGPIOTR_GPS0                            0x00000001
+#define EGPIOTR_GPS1                            0x00000002
+#define EGPIOTR_GPS2                            0x00000004
+#define EGPIOTR_GPS3                            0x00000008
+#define EGPIOTR_GPS4                            0x00000010
+#define EGPIOTR_GPS5                            0x00000020
+#define EGPIOTR_GPS6                            0x00000040
+#define EGPIOTR_GPS7                            0x00000080
+#define EGPIOTR_GPS8                            0x00000100
+#endif
+
+/*
+ *  The following defines are for the flags in the extended GPIO ping wakeup
+ *  register.
+ */
+#ifndef NO_CS4612
+#define EGPIOWR_GPW0                            0x00000001
+#define EGPIOWR_GPW1                            0x00000002
+#define EGPIOWR_GPW2                            0x00000004
+#define EGPIOWR_GPW3                            0x00000008
+#define EGPIOWR_GPW4                            0x00000010
+#define EGPIOWR_GPW5                            0x00000020
+#define EGPIOWR_GPW6                            0x00000040
+#define EGPIOWR_GPW7                            0x00000080
+#define EGPIOWR_GPW8                            0x00000100
+#endif
+
+/*
+ *  The following defines are for the flags in the extended GPIO pin status
+ *  register.
+ */
+#ifndef NO_CS4612
+#define EGPIOSR_GPS0                            0x00000001
+#define EGPIOSR_GPS1                            0x00000002
+#define EGPIOSR_GPS2                            0x00000004
+#define EGPIOSR_GPS3                            0x00000008
+#define EGPIOSR_GPS4                            0x00000010
+#define EGPIOSR_GPS5                            0x00000020
+#define EGPIOSR_GPS6                            0x00000040
+#define EGPIOSR_GPS7                            0x00000080
+#define EGPIOSR_GPS8                            0x00000100
+#endif
+
+/*
+ *  The following defines are for the flags in the serial port 6 configuration
+ *  register.
+ */
+#ifndef NO_CS4612
+#define SERC6_ASDO2EN                           0x00000001
+#endif
+
+/*
+ *  The following defines are for the flags in the serial port 7 configuration
+ *  register.
+ */
+#ifndef NO_CS4612
+#define SERC7_ASDI2EN                           0x00000001
+#define SERC7_POSILB                            0x00000002
+#define SERC7_SIPOLB                            0x00000004
+#define SERC7_SOSILB                            0x00000008
+#define SERC7_SISOLB                            0x00000010
+#endif
+
+/*
+ *  The following defines are for the flags in the serial port AC link
+ *  configuration register.
+ */
+#ifndef NO_CS4612
+#define SERACC_CODEC_TYPE_MASK                  0x00000001
+#define SERACC_CODEC_TYPE_1_03                  0x00000000
+#define SERACC_CODEC_TYPE_2_0                   0x00000001
+#define SERACC_TWO_CODECS                       0x00000002
+#define SERACC_MDM                              0x00000004
+#define SERACC_HSP                              0x00000008
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 control register 2.
+ */
+#ifndef NO_CS4612
+#define ACCTL2_RSTN                             0x00000001
+#define ACCTL2_ESYN                             0x00000002
+#define ACCTL2_VFRM                             0x00000004
+#define ACCTL2_DCV                              0x00000008
+#define ACCTL2_CRW                              0x00000010
+#define ACCTL2_ASYN                             0x00000020
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 status register 2.
+ */
+#ifndef NO_CS4612
+#define ACSTS2_CRDY                             0x00000001
+#define ACSTS2_VSTS                             0x00000002
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 output slot valid
+ *  register 2.
+ */
+#ifndef NO_CS4612
+#define ACOSV2_SLV3                             0x00000001
+#define ACOSV2_SLV4                             0x00000002
+#define ACOSV2_SLV5                             0x00000004
+#define ACOSV2_SLV6                             0x00000008
+#define ACOSV2_SLV7                             0x00000010
+#define ACOSV2_SLV8                             0x00000020
+#define ACOSV2_SLV9                             0x00000040
+#define ACOSV2_SLV10                            0x00000080
+#define ACOSV2_SLV11                            0x00000100
+#define ACOSV2_SLV12                            0x00000200
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 command address
+ *  register 2.
+ */
+#ifndef NO_CS4612
+#define ACCAD2_CI_MASK                          0x0000007F
+#define ACCAD2_CI_SHIFT                         0
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 command data register
+ *  2.
+ */
+#ifndef NO_CS4612
+#define ACCDA2_CD_MASK                          0x0000FFFF
+#define ACCDA2_CD_SHIFT                         0  
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 input slot valid
+ *  register 2.
+ */
+#ifndef NO_CS4612
+#define ACISV2_ISV3                             0x00000001
+#define ACISV2_ISV4                             0x00000002
+#define ACISV2_ISV5                             0x00000004
+#define ACISV2_ISV6                             0x00000008
+#define ACISV2_ISV7                             0x00000010
+#define ACISV2_ISV8                             0x00000020
+#define ACISV2_ISV9                             0x00000040
+#define ACISV2_ISV10                            0x00000080
+#define ACISV2_ISV11                            0x00000100
+#define ACISV2_ISV12                            0x00000200
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 status address
+ *  register 2.
+ */
+#ifndef NO_CS4612
+#define ACSAD2_SI_MASK                          0x0000007F
+#define ACSAD2_SI_SHIFT                         0
+#endif
+
+/*
+ *  The following defines are for the flags in the AC97 status data register 2.
+ */
+#ifndef NO_CS4612
+#define ACSDA2_SD_MASK                          0x0000FFFF
+#define ACSDA2_SD_SHIFT                         0
+#endif
+
+/*
+ *  The following defines are for the flags in the I/O trap address and control
+ *  registers (all 12).
+ */
+#ifndef NO_CS4612
+#define IOTAC_SA_MASK                           0x0000FFFF
+#define IOTAC_MSK_MASK                          0x000F0000
+#define IOTAC_IODC_MASK                         0x06000000
+#define IOTAC_IODC_16_BIT                       0x00000000
+#define IOTAC_IODC_10_BIT                       0x02000000
+#define IOTAC_IODC_12_BIT                       0x04000000
+#define IOTAC_WSPI                              0x08000000
+#define IOTAC_RSPI                              0x10000000
+#define IOTAC_WSE                               0x20000000
+#define IOTAC_WE                                0x40000000
+#define IOTAC_RE                                0x80000000
+#define IOTAC_SA_SHIFT                          0
+#define IOTAC_MSK_SHIFT                         16
+#endif
+
+/*
+ *  The following defines are for the flags in the I/O trap fast read registers
+ *  (all 8).
+ */
+#ifndef NO_CS4612
+#define IOTFR_D_MASK                            0x0000FFFF
+#define IOTFR_A_MASK                            0x000F0000
+#define IOTFR_R_MASK                            0x0F000000
+#define IOTFR_ALL                               0x40000000
+#define IOTFR_VL                                0x80000000
+#define IOTFR_D_SHIFT                           0
+#define IOTFR_A_SHIFT                           16
+#define IOTFR_R_SHIFT                           24
+#endif
+
+/*
+ *  The following defines are for the flags in the I/O trap FIFO register.
+ */
+#ifndef NO_CS4612
+#define IOTFIFO_BA_MASK                         0x00003FFF
+#define IOTFIFO_S_MASK                          0x00FF0000
+#define IOTFIFO_OF                              0x40000000
+#define IOTFIFO_SPIOF                           0x80000000
+#define IOTFIFO_BA_SHIFT                        0
+#define IOTFIFO_S_SHIFT                         16
+#endif
+
+/*
+ *  The following defines are for the flags in the I/O trap retry read data
+ *  register.
+ */
+#ifndef NO_CS4612
+#define IOTRRD_D_MASK                           0x0000FFFF
+#define IOTRRD_RDV                              0x80000000
+#define IOTRRD_D_SHIFT                          0
+#endif
+
+/*
+ *  The following defines are for the flags in the I/O trap FIFO pointer
+ *  register.
+ */
+#ifndef NO_CS4612
+#define IOTFP_CA_MASK                           0x00003FFF
+#define IOTFP_PA_MASK                           0x3FFF0000
+#define IOTFP_CA_SHIFT                          0
+#define IOTFP_PA_SHIFT                          16
+#endif
+
+/*
+ *  The following defines are for the flags in the I/O trap control register.
+ */
+#ifndef NO_CS4612
+#define IOTCR_ITD                               0x00000001
+#define IOTCR_HRV                               0x00000002
+#define IOTCR_SRV                               0x00000004
+#define IOTCR_DTI                               0x00000008
+#define IOTCR_DFI                               0x00000010
+#define IOTCR_DDP                               0x00000020
+#define IOTCR_JTE                               0x00000040
+#define IOTCR_PPE                               0x00000080
+#endif
+
+/*
+ *  The following defines are for the flags in the direct PCI data register.
+ */
+#ifndef NO_CS4612
+#define DPCID_D_MASK                            0xFFFFFFFF
+#define DPCID_D_SHIFT                           0
+#endif
+
+/*
+ *  The following defines are for the flags in the direct PCI address register.
+ */
+#ifndef NO_CS4612
+#define DPCIA_A_MASK                            0xFFFFFFFF
+#define DPCIA_A_SHIFT                           0
+#endif
+
+/*
+ *  The following defines are for the flags in the direct PCI command register.
+ */
+#ifndef NO_CS4612
+#define DPCIC_C_MASK                            0x0000000F
+#define DPCIC_C_IOREAD                          0x00000002
+#define DPCIC_C_IOWRITE                         0x00000003
+#define DPCIC_BE_MASK                           0x000000F0
+#endif
+
+/*
+ *  The following defines are for the flags in the PC/PCI request register.
+ */
+#ifndef NO_CS4612
+#define PCPCIR_RDC_MASK                         0x00000007
+#define PCPCIR_C_MASK                           0x00007000
+#define PCPCIR_REQ                              0x00008000
+#define PCPCIR_RDC_SHIFT                        0
+#define PCPCIR_C_SHIFT                          12
+#endif
+
+/*
+ *  The following defines are for the flags in the PC/PCI grant register.
+ */ 
+#ifndef NO_CS4612
+#define PCPCIG_GDC_MASK                         0x00000007
+#define PCPCIG_VL                               0x00008000
+#define PCPCIG_GDC_SHIFT                        0
+#endif
+
+/*
+ *  The following defines are for the flags in the PC/PCI master enable
+ *  register.
+ */
+#ifndef NO_CS4612
+#define PCPCIEN_EN                              0x00000001
+#endif
+
+/*
+ *  The following defines are for the flags in the extended PCI power
+ *  management control register.
+ */
+#ifndef NO_CS4612
+#define EPCIPMC_GWU                             0x00000001
+#define EPCIPMC_FSPC                            0x00000002
+#endif 
+
+/*
+ *  The following defines are for the flags in the SP control register.
+ */
+#define SPCR_RUN                                0x00000001
+#define SPCR_STPFR                              0x00000002
+#define SPCR_RUNFR                              0x00000004
+#define SPCR_TICK                               0x00000008
+#define SPCR_DRQEN                              0x00000020
+#define SPCR_RSTSP                              0x00000040
+#define SPCR_OREN                               0x00000080
+#ifndef NO_CS4612
+#define SPCR_PCIINT                             0x00000100
+#define SPCR_OINTD                              0x00000200
+#define SPCR_CRE                                0x00008000
+#endif
+
+/*
+ *  The following defines are for the flags in the debug index register.
+ */
+#define DREG_REGID_MASK                         0x0000007F
+#define DREG_DEBUG                              0x00000080
+#define DREG_RGBK_MASK                          0x00000700
+#define DREG_TRAP                               0x00000800
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_TRAPX                              0x00001000
+#endif
+#endif
+#define DREG_REGID_SHIFT                        0
+#define DREG_RGBK_SHIFT                         8
+#define DREG_RGBK_REGID_MASK                    0x0000077F
+#define DREG_REGID_R0                           0x00000010
+#define DREG_REGID_R1                           0x00000011
+#define DREG_REGID_R2                           0x00000012
+#define DREG_REGID_R3                           0x00000013
+#define DREG_REGID_R4                           0x00000014
+#define DREG_REGID_R5                           0x00000015
+#define DREG_REGID_R6                           0x00000016
+#define DREG_REGID_R7                           0x00000017
+#define DREG_REGID_R8                           0x00000018
+#define DREG_REGID_R9                           0x00000019
+#define DREG_REGID_RA                           0x0000001A
+#define DREG_REGID_RB                           0x0000001B
+#define DREG_REGID_RC                           0x0000001C
+#define DREG_REGID_RD                           0x0000001D
+#define DREG_REGID_RE                           0x0000001E
+#define DREG_REGID_RF                           0x0000001F
+#define DREG_REGID_RA_BUS_LOW                   0x00000020
+#define DREG_REGID_RA_BUS_HIGH                  0x00000038
+#define DREG_REGID_YBUS_LOW                     0x00000050
+#define DREG_REGID_YBUS_HIGH                    0x00000058
+#define DREG_REGID_TRAP_0                       0x00000100
+#define DREG_REGID_TRAP_1                       0x00000101
+#define DREG_REGID_TRAP_2                       0x00000102
+#define DREG_REGID_TRAP_3                       0x00000103
+#define DREG_REGID_TRAP_4                       0x00000104
+#define DREG_REGID_TRAP_5                       0x00000105
+#define DREG_REGID_TRAP_6                       0x00000106
+#define DREG_REGID_TRAP_7                       0x00000107
+#define DREG_REGID_INDIRECT_ADDRESS             0x0000010E
+#define DREG_REGID_TOP_OF_STACK                 0x0000010F
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_8                       0x00000110
+#define DREG_REGID_TRAP_9                       0x00000111
+#define DREG_REGID_TRAP_10                      0x00000112
+#define DREG_REGID_TRAP_11                      0x00000113
+#define DREG_REGID_TRAP_12                      0x00000114
+#define DREG_REGID_TRAP_13                      0x00000115
+#define DREG_REGID_TRAP_14                      0x00000116
+#define DREG_REGID_TRAP_15                      0x00000117
+#define DREG_REGID_TRAP_16                      0x00000118
+#define DREG_REGID_TRAP_17                      0x00000119
+#define DREG_REGID_TRAP_18                      0x0000011A
+#define DREG_REGID_TRAP_19                      0x0000011B
+#define DREG_REGID_TRAP_20                      0x0000011C
+#define DREG_REGID_TRAP_21                      0x0000011D
+#define DREG_REGID_TRAP_22                      0x0000011E
+#define DREG_REGID_TRAP_23                      0x0000011F
+#endif
+#endif
+#define DREG_REGID_RSA0_LOW                     0x00000200
+#define DREG_REGID_RSA0_HIGH                    0x00000201
+#define DREG_REGID_RSA1_LOW                     0x00000202
+#define DREG_REGID_RSA1_HIGH                    0x00000203
+#define DREG_REGID_RSA2                         0x00000204
+#define DREG_REGID_RSA3                         0x00000205
+#define DREG_REGID_RSI0_LOW                     0x00000206
+#define DREG_REGID_RSI0_HIGH                    0x00000207
+#define DREG_REGID_RSI1                         0x00000208
+#define DREG_REGID_RSI2                         0x00000209
+#define DREG_REGID_SAGUSTATUS                   0x0000020A
+#define DREG_REGID_RSCONFIG01_LOW               0x0000020B
+#define DREG_REGID_RSCONFIG01_HIGH              0x0000020C
+#define DREG_REGID_RSCONFIG23_LOW               0x0000020D
+#define DREG_REGID_RSCONFIG23_HIGH              0x0000020E
+#define DREG_REGID_RSDMA01E                     0x0000020F
+#define DREG_REGID_RSDMA23E                     0x00000210
+#define DREG_REGID_RSD0_LOW                     0x00000211
+#define DREG_REGID_RSD0_HIGH                    0x00000212
+#define DREG_REGID_RSD1_LOW                     0x00000213
+#define DREG_REGID_RSD1_HIGH                    0x00000214
+#define DREG_REGID_RSD2_LOW                     0x00000215
+#define DREG_REGID_RSD2_HIGH                    0x00000216
+#define DREG_REGID_RSD3_LOW                     0x00000217
+#define DREG_REGID_RSD3_HIGH                    0x00000218
+#define DREG_REGID_SRAR_HIGH                    0x0000021A
+#define DREG_REGID_SRAR_LOW                     0x0000021B
+#define DREG_REGID_DMA_STATE                    0x0000021C
+#define DREG_REGID_CURRENT_DMA_STREAM           0x0000021D
+#define DREG_REGID_NEXT_DMA_STREAM              0x0000021E
+#define DREG_REGID_CPU_STATUS                   0x00000300
+#define DREG_REGID_MAC_MODE                     0x00000301
+#define DREG_REGID_STACK_AND_REPEAT             0x00000302
+#define DREG_REGID_INDEX0                       0x00000304
+#define DREG_REGID_INDEX1                       0x00000305
+#define DREG_REGID_DMA_STATE_0_3                0x00000400
+#define DREG_REGID_DMA_STATE_4_7                0x00000404
+#define DREG_REGID_DMA_STATE_8_11               0x00000408
+#define DREG_REGID_DMA_STATE_12_15              0x0000040C
+#define DREG_REGID_DMA_STATE_16_19              0x00000410
+#define DREG_REGID_DMA_STATE_20_23              0x00000414
+#define DREG_REGID_DMA_STATE_24_27              0x00000418
+#define DREG_REGID_DMA_STATE_28_31              0x0000041C
+#define DREG_REGID_DMA_STATE_32_35              0x00000420
+#define DREG_REGID_DMA_STATE_36_39              0x00000424
+#define DREG_REGID_DMA_STATE_40_43              0x00000428
+#define DREG_REGID_DMA_STATE_44_47              0x0000042C
+#define DREG_REGID_DMA_STATE_48_51              0x00000430
+#define DREG_REGID_DMA_STATE_52_55              0x00000434
+#define DREG_REGID_DMA_STATE_56_59              0x00000438
+#define DREG_REGID_DMA_STATE_60_63              0x0000043C
+#define DREG_REGID_DMA_STATE_64_67              0x00000440
+#define DREG_REGID_DMA_STATE_68_71              0x00000444
+#define DREG_REGID_DMA_STATE_72_75              0x00000448
+#define DREG_REGID_DMA_STATE_76_79              0x0000044C
+#define DREG_REGID_DMA_STATE_80_83              0x00000450
+#define DREG_REGID_DMA_STATE_84_87              0x00000454
+#define DREG_REGID_DMA_STATE_88_91              0x00000458
+#define DREG_REGID_DMA_STATE_92_95              0x0000045C
+#define DREG_REGID_TRAP_SELECT                  0x00000500
+#define DREG_REGID_TRAP_WRITE_0                 0x00000500
+#define DREG_REGID_TRAP_WRITE_1                 0x00000501
+#define DREG_REGID_TRAP_WRITE_2                 0x00000502
+#define DREG_REGID_TRAP_WRITE_3                 0x00000503
+#define DREG_REGID_TRAP_WRITE_4                 0x00000504
+#define DREG_REGID_TRAP_WRITE_5                 0x00000505
+#define DREG_REGID_TRAP_WRITE_6                 0x00000506
+#define DREG_REGID_TRAP_WRITE_7                 0x00000507
+#if !defined(NO_CS4612)
+#if !defined(NO_CS4615)
+#define DREG_REGID_TRAP_WRITE_8                 0x00000510
+#define DREG_REGID_TRAP_WRITE_9                 0x00000511
+#define DREG_REGID_TRAP_WRITE_10                0x00000512
+#define DREG_REGID_TRAP_WRITE_11                0x00000513
+#define DREG_REGID_TRAP_WRITE_12                0x00000514
+#define DREG_REGID_TRAP_WRITE_13                0x00000515
+#define DREG_REGID_TRAP_WRITE_14                0x00000516
+#define DREG_REGID_TRAP_WRITE_15                0x00000517
+#define DREG_REGID_TRAP_WRITE_16                0x00000518
+#define DREG_REGID_TRAP_WRITE_17                0x00000519
+#define DREG_REGID_TRAP_WRITE_18                0x0000051A
+#define DREG_REGID_TRAP_WRITE_19                0x0000051B
+#define DREG_REGID_TRAP_WRITE_20                0x0000051C
+#define DREG_REGID_TRAP_WRITE_21                0x0000051D
+#define DREG_REGID_TRAP_WRITE_22                0x0000051E
+#define DREG_REGID_TRAP_WRITE_23                0x0000051F
+#endif
+#endif
+#define DREG_REGID_MAC0_ACC0_LOW                0x00000600
+#define DREG_REGID_MAC0_ACC1_LOW                0x00000601
+#define DREG_REGID_MAC0_ACC2_LOW                0x00000602
+#define DREG_REGID_MAC0_ACC3_LOW                0x00000603
+#define DREG_REGID_MAC1_ACC0_LOW                0x00000604
+#define DREG_REGID_MAC1_ACC1_LOW                0x00000605
+#define DREG_REGID_MAC1_ACC2_LOW                0x00000606
+#define DREG_REGID_MAC1_ACC3_LOW                0x00000607
+#define DREG_REGID_MAC0_ACC0_MID                0x00000608
+#define DREG_REGID_MAC0_ACC1_MID                0x00000609
+#define DREG_REGID_MAC0_ACC2_MID                0x0000060A
+#define DREG_REGID_MAC0_ACC3_MID                0x0000060B
+#define DREG_REGID_MAC1_ACC0_MID                0x0000060C
+#define DREG_REGID_MAC1_ACC1_MID                0x0000060D
+#define DREG_REGID_MAC1_ACC2_MID                0x0000060E
+#define DREG_REGID_MAC1_ACC3_MID                0x0000060F
+#define DREG_REGID_MAC0_ACC0_HIGH               0x00000610
+#define DREG_REGID_MAC0_ACC1_HIGH               0x00000611
+#define DREG_REGID_MAC0_ACC2_HIGH               0x00000612
+#define DREG_REGID_MAC0_ACC3_HIGH               0x00000613
+#define DREG_REGID_MAC1_ACC0_HIGH               0x00000614
+#define DREG_REGID_MAC1_ACC1_HIGH               0x00000615
+#define DREG_REGID_MAC1_ACC2_HIGH               0x00000616
+#define DREG_REGID_MAC1_ACC3_HIGH               0x00000617
+#define DREG_REGID_RSHOUT_LOW                   0x00000620
+#define DREG_REGID_RSHOUT_MID                   0x00000628
+#define DREG_REGID_RSHOUT_HIGH                  0x00000630
+
+/*
+ *  The following defines are for the flags in the DMA stream requestor write
+ */
+#define DSRWP_DSR_MASK                          0x0000000F
+#define DSRWP_DSR_BG_RQ                         0x00000001
+#define DSRWP_DSR_PRIORITY_MASK                 0x00000006
+#define DSRWP_DSR_PRIORITY_0                    0x00000000
+#define DSRWP_DSR_PRIORITY_1                    0x00000002
+#define DSRWP_DSR_PRIORITY_2                    0x00000004
+#define DSRWP_DSR_PRIORITY_3                    0x00000006
+#define DSRWP_DSR_RQ_PENDING                    0x00000008
+
+/*
+ *  The following defines are for the flags in the trap write port register.
+ */
+#define TWPR_TW_MASK                            0x0000FFFF
+#define TWPR_TW_SHIFT                           0
+
+/*
+ *  The following defines are for the flags in the stack pointer write
+ *  register.
+ */
+#define SPWR_STKP_MASK                          0x0000000F
+#define SPWR_STKP_SHIFT                         0
+
+/*
+ *  The following defines are for the flags in the SP interrupt register.
+ */
+#define SPIR_FRI                                0x00000001
+#define SPIR_DOI                                0x00000002
+#define SPIR_GPI2                               0x00000004
+#define SPIR_GPI3                               0x00000008
+#define SPIR_IP0                                0x00000010
+#define SPIR_IP1                                0x00000020
+#define SPIR_IP2                                0x00000040
+#define SPIR_IP3                                0x00000080
+
+/*
+ *  The following defines are for the flags in the functional group 1 register.
+ */
+#define FGR1_F1S_MASK                           0x0000FFFF
+#define FGR1_F1S_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the SP clock status register.
+ */
+#define SPCS_FRI                                0x00000001
+#define SPCS_DOI                                0x00000002
+#define SPCS_GPI2                               0x00000004
+#define SPCS_GPI3                               0x00000008
+#define SPCS_IP0                                0x00000010
+#define SPCS_IP1                                0x00000020
+#define SPCS_IP2                                0x00000040
+#define SPCS_IP3                                0x00000080
+#define SPCS_SPRUN                              0x00000100
+#define SPCS_SLEEP                              0x00000200
+#define SPCS_FG                                 0x00000400
+#define SPCS_ORUN                               0x00000800
+#define SPCS_IRQ                                0x00001000
+#define SPCS_FGN_MASK                           0x0000E000
+#define SPCS_FGN_SHIFT                          13
+
+/*
+ *  The following defines are for the flags in the SP DMA requestor status
+ *  register.
+ */
+#define SDSR_DCS_MASK                           0x000000FF
+#define SDSR_DCS_SHIFT                          0
+#define SDSR_DCS_NONE                           0x00000007
+
+/*
+ *  The following defines are for the flags in the frame timer register.
+ */
+#define FRMT_FTV_MASK                           0x0000FFFF
+#define FRMT_FTV_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the frame timer current count
+ *  register.
+ */
+#define FRCC_FCC_MASK                           0x0000FFFF
+#define FRCC_FCC_SHIFT                          0
+
+/*
+ *  The following defines are for the flags in the frame timer save count
+ *  register.
+ */
+#define FRSC_FCS_MASK                           0x0000FFFF
+#define FRSC_FCS_SHIFT                          0
+
+/*
+ *  The following define the various flags stored in the scatter/gather
+ *  descriptors.
+ */
+#define DMA_SG_NEXT_ENTRY_MASK                  0x00000FF8
+#define DMA_SG_SAMPLE_END_MASK                  0x0FFF0000
+#define DMA_SG_SAMPLE_END_FLAG                  0x10000000
+#define DMA_SG_LOOP_END_FLAG                    0x20000000
+#define DMA_SG_SIGNAL_END_FLAG                  0x40000000
+#define DMA_SG_SIGNAL_PAGE_FLAG                 0x80000000
+#define DMA_SG_NEXT_ENTRY_SHIFT                 3
+#define DMA_SG_SAMPLE_END_SHIFT                 16
+
+/*
+ *  The following define the offsets of the fields within the on-chip generic
+ *  DMA requestor.
+ */
+#define DMA_RQ_CONTROL1                         0x00000000
+#define DMA_RQ_CONTROL2                         0x00000004
+#define DMA_RQ_SOURCE_ADDR                      0x00000008
+#define DMA_RQ_DESTINATION_ADDR                 0x0000000C
+#define DMA_RQ_NEXT_PAGE_ADDR                   0x00000010
+#define DMA_RQ_NEXT_PAGE_SGDESC                 0x00000014
+#define DMA_RQ_LOOP_START_ADDR                  0x00000018
+#define DMA_RQ_POST_LOOP_ADDR                   0x0000001C
+#define DMA_RQ_PAGE_MAP_ADDR                    0x00000020
+
+/*
+ *  The following defines are for the flags in the first control word of the
+ *  on-chip generic DMA requestor.
+ */
+#define DMA_RQ_C1_COUNT_MASK                    0x000003FF
+#define DMA_RQ_C1_DESTINATION_SCATTER           0x00001000
+#define DMA_RQ_C1_SOURCE_GATHER                 0x00002000
+#define DMA_RQ_C1_DONE_FLAG                     0x00004000
+#define DMA_RQ_C1_OPTIMIZE_STATE                0x00008000
+#define DMA_RQ_C1_SAMPLE_END_STATE_MASK         0x00030000
+#define DMA_RQ_C1_FULL_PAGE                     0x00000000
+#define DMA_RQ_C1_BEFORE_SAMPLE_END             0x00010000
+#define DMA_RQ_C1_PAGE_MAP_ERROR                0x00020000
+#define DMA_RQ_C1_AT_SAMPLE_END                 0x00030000
+#define DMA_RQ_C1_LOOP_END_STATE_MASK           0x000C0000
+#define DMA_RQ_C1_NOT_LOOP_END                  0x00000000
+#define DMA_RQ_C1_BEFORE_LOOP_END               0x00040000
+#define DMA_RQ_C1_2PAGE_LOOP_BEGIN              0x00080000
+#define DMA_RQ_C1_LOOP_BEGIN                    0x000C0000
+#define DMA_RQ_C1_PAGE_MAP_MASK                 0x00300000
+#define DMA_RQ_C1_PM_NONE_PENDING               0x00000000
+#define DMA_RQ_C1_PM_NEXT_PENDING               0x00100000
+#define DMA_RQ_C1_PM_RESERVED                   0x00200000
+#define DMA_RQ_C1_PM_LOOP_NEXT_PENDING          0x00300000
+#define DMA_RQ_C1_WRITEBACK_DEST_FLAG           0x00400000
+#define DMA_RQ_C1_WRITEBACK_SRC_FLAG            0x00800000
+#define DMA_RQ_C1_DEST_SIZE_MASK                0x07000000
+#define DMA_RQ_C1_DEST_LINEAR                   0x00000000
+#define DMA_RQ_C1_DEST_MOD16                    0x01000000
+#define DMA_RQ_C1_DEST_MOD32                    0x02000000
+#define DMA_RQ_C1_DEST_MOD64                    0x03000000
+#define DMA_RQ_C1_DEST_MOD128                   0x04000000
+#define DMA_RQ_C1_DEST_MOD256                   0x05000000
+#define DMA_RQ_C1_DEST_MOD512                   0x06000000
+#define DMA_RQ_C1_DEST_MOD1024                  0x07000000
+#define DMA_RQ_C1_DEST_ON_HOST                  0x08000000
+#define DMA_RQ_C1_SOURCE_SIZE_MASK              0x70000000
+#define DMA_RQ_C1_SOURCE_LINEAR                 0x00000000
+#define DMA_RQ_C1_SOURCE_MOD16                  0x10000000
+#define DMA_RQ_C1_SOURCE_MOD32                  0x20000000
+#define DMA_RQ_C1_SOURCE_MOD64                  0x30000000
+#define DMA_RQ_C1_SOURCE_MOD128                 0x40000000
+#define DMA_RQ_C1_SOURCE_MOD256                 0x50000000
+#define DMA_RQ_C1_SOURCE_MOD512                 0x60000000
+#define DMA_RQ_C1_SOURCE_MOD1024                0x70000000
+#define DMA_RQ_C1_SOURCE_ON_HOST                0x80000000
+#define DMA_RQ_C1_COUNT_SHIFT                   0
+
+/*
+ *  The following defines are for the flags in the second control word of the
+ *  on-chip generic DMA requestor.
+ */
+#define DMA_RQ_C2_VIRTUAL_CHANNEL_MASK          0x0000003F
+#define DMA_RQ_C2_VIRTUAL_SIGNAL_MASK           0x00000300
+#define DMA_RQ_C2_NO_VIRTUAL_SIGNAL             0x00000000
+#define DMA_RQ_C2_SIGNAL_EVERY_DMA              0x00000100
+#define DMA_RQ_C2_SIGNAL_SOURCE_PINGPONG        0x00000200
+#define DMA_RQ_C2_SIGNAL_DEST_PINGPONG          0x00000300
+#define DMA_RQ_C2_AUDIO_CONVERT_MASK            0x0000F000
+#define DMA_RQ_C2_AC_NONE                       0x00000000
+#define DMA_RQ_C2_AC_8_TO_16_BIT                0x00001000
+#define DMA_RQ_C2_AC_MONO_TO_STEREO             0x00002000
+#define DMA_RQ_C2_AC_ENDIAN_CONVERT             0x00004000
+#define DMA_RQ_C2_AC_SIGNED_CONVERT             0x00008000
+#define DMA_RQ_C2_LOOP_END_MASK                 0x0FFF0000
+#define DMA_RQ_C2_LOOP_MASK                     0x30000000
+#define DMA_RQ_C2_NO_LOOP                       0x00000000
+#define DMA_RQ_C2_ONE_PAGE_LOOP                 0x10000000
+#define DMA_RQ_C2_TWO_PAGE_LOOP                 0x20000000
+#define DMA_RQ_C2_MULTI_PAGE_LOOP               0x30000000
+#define DMA_RQ_C2_SIGNAL_LOOP_BACK              0x40000000
+#define DMA_RQ_C2_SIGNAL_POST_BEGIN_PAGE        0x80000000
+#define DMA_RQ_C2_VIRTUAL_CHANNEL_SHIFT         0
+#define DMA_RQ_C2_LOOP_END_SHIFT                16
+
+/*
+ *  The following defines are for the flags in the source and destination words
+ *  of the on-chip generic DMA requestor.
+ */
+#define DMA_RQ_SD_ADDRESS_MASK                  0x0000FFFF
+#define DMA_RQ_SD_MEMORY_ID_MASK                0x000F0000
+#define DMA_RQ_SD_SP_PARAM_ADDR                 0x00000000
+#define DMA_RQ_SD_SP_SAMPLE_ADDR                0x00010000
+#define DMA_RQ_SD_SP_PROGRAM_ADDR               0x00020000
+#define DMA_RQ_SD_SP_DEBUG_ADDR                 0x00030000
+#define DMA_RQ_SD_OMNIMEM_ADDR                  0x000E0000
+#define DMA_RQ_SD_END_FLAG                      0x40000000
+#define DMA_RQ_SD_ERROR_FLAG                    0x80000000
+#define DMA_RQ_SD_ADDRESS_SHIFT                 0
+
+/*
+ *  The following defines are for the flags in the page map address word of the
+ *  on-chip generic DMA requestor.
+ */
+#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_MASK   0x00000FF8
+#define DMA_RQ_PMA_PAGE_TABLE_MASK              0xFFFFF000
+#define DMA_RQ_PMA_LOOP_THIRD_PAGE_ENTRY_SHIFT  3
+#define DMA_RQ_PMA_PAGE_TABLE_SHIFT             12
+
+#define BA1_VARIDEC_BUF_1       0x000
+
+#define BA1_PDTC                0x0c0    /* BA1_PLAY_DMA_TRANSACTION_COUNT_REG */
+#define BA1_PFIE                0x0c4    /* BA1_PLAY_FORMAT_&_INTERRUPT_ENABLE_REG */
+#define BA1_PBA                 0x0c8    /* BA1_PLAY_BUFFER_ADDRESS */
+#define BA1_PVOL                0x0f8    /* BA1_PLAY_VOLUME_REG */
+#define BA1_PSRC                0x288    /* BA1_PLAY_SAMPLE_RATE_CORRECTION_REG */
+#define BA1_PCTL                0x2a4    /* BA1_PLAY_CONTROL_REG */
+#define BA1_PPI                 0x2b4    /* BA1_PLAY_PHASE_INCREMENT_REG */
+
+#define BA1_CCTL                0x064    /* BA1_CAPTURE_CONTROL_REG */
+#define BA1_CIE                 0x104    /* BA1_CAPTURE_INTERRUPT_ENABLE_REG */
+#define BA1_CBA                 0x10c    /* BA1_CAPTURE_BUFFER_ADDRESS */
+#define BA1_CSRC                0x2c8    /* BA1_CAPTURE_SAMPLE_RATE_CORRECTION_REG */
+#define BA1_CCI                 0x2d8    /* BA1_CAPTURE_COEFFICIENT_INCREMENT_REG */
+#define BA1_CD                  0x2e0    /* BA1_CAPTURE_DELAY_REG */
+#define BA1_CPI                 0x2f4    /* BA1_CAPTURE_PHASE_INCREMENT_REG */
+#define BA1_CVOL                0x2f8    /* BA1_CAPTURE_VOLUME_REG */
+
+#define BA1_CFG1                0x134    /* BA1_CAPTURE_FRAME_GROUP_1_REG */
+#define BA1_CFG2                0x138    /* BA1_CAPTURE_FRAME_GROUP_2_REG */
+#define BA1_CCST                0x13c    /* BA1_CAPTURE_CONSTANT_REG */
+#define BA1_CSPB                0x340    /* BA1_CAPTURE_SPB_ADDRESS */
+
+/*
+ *
+ */
+
+#define CS461X_MODE_OUTPUT	(1<<0)	 /* MIDI UART - output */ 
+#define CS461X_MODE_INPUT	(1<<1)	 /* MIDI UART - input */
+
+#endif				/* __CS461X_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/cs461x_image.h linux.17p18/drivers/sound/cs461x_image.h
--- linux.vanilla/drivers/sound/cs461x_image.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/cs461x_image.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,3459 @@
+struct BA1struct BA1Struct = {
+{{ 0x00000000, 0x00003000 },{ 0x00010000, 0x00003800 },{ 0x00020000, 0x00007000 }},
+{0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000163,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00200040,0x00008010,0x00000000,
+0x00000000,0x80000001,0x00000001,0x00060000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00900080,0x00000173,0x00000000,
+0x00000000,0x00000010,0x00800000,0x00900000,
+0xf2c0000f,0x00000200,0x00000000,0x00010600,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000163,0x330300c2,
+0x06000000,0x00000000,0x80008000,0x80008000,
+0x3fc0000f,0x00000301,0x00010400,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00b00000,0x00d0806d,0x330480c3,
+0x04800000,0x00000001,0x00800001,0x0000ffff,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x066a0600,0x06350070,0x0000929d,0x929d929d,
+0x00000000,0x0000735a,0x00000600,0x00000000,
+0x929d735a,0x8734abfe,0x00010000,0x735a735a,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000804f,0x000000c3,
+0x05000000,0x00a00010,0x00000000,0x80008000,
+0x00000000,0x00000000,0x00000700,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000080,0x00a00000,0x0000809a,0x000000c2,
+0x07400000,0x00000000,0x80008000,0xffffffff,
+0x00c80028,0x00005555,0x00000000,0x000107a0,
+0x00c80028,0x000000c2,0x06800000,0x00000000,
+0x06e00080,0x00300000,0x000080bb,0x000000c9,
+0x07a00000,0x04000000,0x80008000,0xffffffff,
+0x00c80028,0x00005555,0x00000000,0x00000780,
+0x00c80028,0x000000c5,0xff800000,0x00000000,
+0x00640080,0x00c00000,0x00008197,0x000000c9,
+0x07800000,0x04000000,0x80008000,0xffffffff,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000805e,0x000000c1,
+0x00000000,0x00800000,0x80008000,0x80008000,
+0x00020000,0x0000ffff,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x929d0600,0x929d929d,0x929d929d,0x929d0000,
+0x929d929d,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0x00100635,0x060b013f,0x00000004,
+0x00000001,0x007a0002,0x00000000,0x066e0610,
+0x0105929d,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0xa431ac75,0x0001735a,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0x735a0051,
+0x00000000,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0x929d929d,0x929d929d,0x929d929d,
+0x929d929d,0x929d929d,0x00000000,0x06400136,
+0x0000270f,0x00010000,0x007a0000,0x00000000,
+0x068e0645,0x0105929d,0x929d929d,0x929d929d,
+0x929d929d,0x929d929d,0xa431ac75,0x0001735a,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0xa431ac75,0xa431ac75,0xa431ac75,0xa431ac75,
+0x735a0100,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00010004,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00001705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00009705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00011705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00019705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00021705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00029705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00031705,0x00001400,0x000a411e,0x00001003,
+0x00040730,0x00001002,0x000f619e,0x00001003,
+0x00039705,0x00001400,0x000a411e,0x00001003,
+0x000fe19e,0x00001003,0x0009c730,0x00001003,
+0x0008e19c,0x00001003,0x000083c1,0x00093040,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00009705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00011705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00019705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00021705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00029705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00031705,0x00001400,0x000a211e,0x00001003,
+0x00098730,0x00001002,0x000ee19e,0x00001003,
+0x00039705,0x00001400,0x000a211e,0x00001003,
+0x0000a730,0x00001008,0x000e2730,0x00001002,
+0x0000a731,0x00001002,0x0000a731,0x00001002,
+0x0000a731,0x00001002,0x0000a731,0x00001002,
+0x0000a731,0x00001002,0x0000a731,0x00001002,
+0x00000000,0x00000000,0x000f619c,0x00001003,
+0x0007f801,0x000c0000,0x00000037,0x00001000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x000c0000,0x00000000,0x00000000,
+0x0000373c,0x00001000,0x00000000,0x00000000,
+0x000ee19c,0x00001003,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000273c,0x00001000,
+0x00000033,0x00001000,0x000e679e,0x00001003,
+0x00007705,0x00001400,0x000ac71e,0x00001003,
+0x00087fc1,0x000c3be0,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0000a730,0x00001003,
+0x00000033,0x00001000,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x000c0000,
+0x00000032,0x00001000,0x0000273d,0x00001000,
+0x0004a730,0x00001003,0x00000f41,0x00097140,
+0x0000a841,0x0009b240,0x0000a0c1,0x0009f040,
+0x0001c641,0x00093540,0x0001cec1,0x0009b5c0,
+0x00000000,0x00000000,0x0001bf05,0x0003fc40,
+0x00002725,0x000aa400,0x00013705,0x00093a00,
+0x0000002e,0x0009d6c0,0x00038630,0x00001004,
+0x0004ef0a,0x000eb785,0x0003fc8a,0x00000000,
+0x00000000,0x000c70e0,0x0007d182,0x0002c640,
+0x00000630,0x00001004,0x000799b8,0x0002c6c0,
+0x00031705,0x00092240,0x00039f05,0x000932c0,
+0x0003520a,0x00000000,0x00040731,0x0000100b,
+0x00010705,0x000b20c0,0x00000000,0x000eba44,
+0x00032108,0x000c60c4,0x00065208,0x000c2917,
+0x000406b0,0x00001007,0x00012f05,0x00036880,
+0x0002818e,0x000c0000,0x0004410a,0x00000000,
+0x00040630,0x00001007,0x00029705,0x000c0000,
+0x00000000,0x00000000,0x00003fc1,0x0003fc40,
+0x000037c1,0x00091b40,0x00003fc1,0x000911c0,
+0x000037c1,0x000957c0,0x00003fc1,0x000951c0,
+0x000037c1,0x00000000,0x00003fc1,0x000991c0,
+0x000037c1,0x00000000,0x00003fc1,0x0009d1c0,
+0x000037c1,0x00000000,0x0001ccc1,0x000915c0,
+0x0001c441,0x0009d800,0x0009cdc1,0x00091240,
+0x0001c541,0x00091d00,0x0009cfc1,0x00095240,
+0x0001c741,0x00095c80,0x000e8ca9,0x00099240,
+0x000e85ad,0x00095640,0x00069ca9,0x00099d80,
+0x000e952d,0x00099640,0x000eaca9,0x0009d6c0,
+0x000ea5ad,0x00091a40,0x0006bca9,0x0009de80,
+0x000eb52d,0x00095a40,0x000ecca9,0x00099ac0,
+0x000ec5ad,0x0009da40,0x000edca9,0x0009d300,
+0x000a6e0a,0x00001000,0x000ed52d,0x00091e40,
+0x000eeca9,0x00095ec0,0x000ee5ad,0x00099e40,
+0x0006fca9,0x00002500,0x000fb208,0x000c59a0,
+0x000ef52d,0x0009de40,0x00068ca9,0x000912c1,
+0x000683ad,0x00095241,0x00020f05,0x000991c1,
+0x00000000,0x00000000,0x00086f88,0x00001000,
+0x0009cf81,0x000b5340,0x0009c701,0x000b92c0,
+0x0009de81,0x000bd300,0x0009d601,0x000b1700,
+0x0001fd81,0x000b9d80,0x0009f501,0x000b57c0,
+0x000a0f81,0x000bd740,0x00020701,0x000b5c80,
+0x000a1681,0x000b97c0,0x00021601,0x00002500,
+0x000a0701,0x000b9b40,0x000a0f81,0x000b1bc0,
+0x00021681,0x00002d00,0x00020f81,0x000bd800,
+0x000a0701,0x000b5bc0,0x00021601,0x00003500,
+0x000a0f81,0x000b5f40,0x000a0701,0x000bdbc0,
+0x00021681,0x00003d00,0x00020f81,0x000b1d00,
+0x000a0701,0x000b1fc0,0x00021601,0x00020500,
+0x00020f81,0x000b1341,0x000a0701,0x000b9fc0,
+0x00021681,0x00020d00,0x00020f81,0x000bde80,
+0x000a0701,0x000bdfc0,0x00021601,0x00021500,
+0x00020f81,0x000b9341,0x00020701,0x000b53c1,
+0x00021681,0x00021d00,0x000a0f81,0x000d0380,
+0x0000b601,0x000b15c0,0x00007b01,0x00000000,
+0x00007b81,0x000bd1c0,0x00007b01,0x00000000,
+0x00007b81,0x000b91c0,0x00007b01,0x000b57c0,
+0x00007b81,0x000b51c0,0x00007b01,0x000b1b40,
+0x00007b81,0x000b11c0,0x00087b01,0x000c3dc0,
+0x0007e488,0x000d7e45,0x00000000,0x000d7a44,
+0x0007e48a,0x00000000,0x00011f05,0x00084080,
+0x00000000,0x00000000,0x00001705,0x000b3540,
+0x00008a01,0x000bf040,0x00007081,0x000bb5c0,
+0x00055488,0x00000000,0x0000d482,0x0003fc40,
+0x0003fc88,0x00000000,0x0001e401,0x000b3a00,
+0x0001ec81,0x000bd6c0,0x0004ef08,0x000eb784,
+0x000c86b0,0x00001007,0x00008281,0x000bb240,
+0x0000b801,0x000b7140,0x00007888,0x00000000,
+0x0000073c,0x00001000,0x0007f188,0x000c0000,
+0x00000000,0x00000000,0x00055288,0x000c555c,
+0x0005528a,0x000c0000,0x0009fa88,0x000c5d00,
+0x0000fa88,0x00000000,0x00000032,0x00001000,
+0x0000073d,0x00001000,0x0007f188,0x000c0000,
+0x00000000,0x00000000,0x0008c01c,0x00001003,
+0x00002705,0x00001008,0x0008b201,0x000c1392,
+0x0000ba01,0x00000000,0x00008731,0x00001400,
+0x0004c108,0x000fe0c4,0x00057488,0x00000000,
+0x000a6388,0x00001001,0x0008b334,0x000bc141,
+0x0003020e,0x00000000,0x000886b0,0x00001008,
+0x00003625,0x000c5dfa,0x000a638a,0x00001001,
+0x0008020e,0x00001002,0x0008a6b0,0x00001008,
+0x0007f301,0x00000000,0x00000000,0x00000000,
+0x00002725,0x000a8c40,0x000000ae,0x00000000,
+0x000d8630,0x00001008,0x00000000,0x000c74e0,
+0x0007d182,0x0002d640,0x000a8630,0x00001008,
+0x000799b8,0x0002d6c0,0x0000748a,0x000c3ec5,
+0x0007420a,0x000c0000,0x00062208,0x000c4117,
+0x00070630,0x00001009,0x00000000,0x000c0000,
+0x0001022e,0x00000000,0x0003a630,0x00001009,
+0x00000000,0x000c0000,0x00000036,0x00001000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x0002a730,0x00001008,0x0007f801,0x000c0000,
+0x00000037,0x00001000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x0002a730,0x00001008,
+0x00000033,0x00001000,0x0002a705,0x00001008,
+0x00007a01,0x000c0000,0x000e6288,0x000d550a,
+0x0006428a,0x00000000,0x00060730,0x0000100a,
+0x00000000,0x000c0000,0x00000000,0x00000000,
+0x0007aab0,0x00034880,0x00078fb0,0x0000100b,
+0x00057488,0x00000000,0x00033b94,0x00081140,
+0x000183ae,0x00000000,0x000786b0,0x0000100b,
+0x00022f05,0x000c3545,0x0000eb8a,0x00000000,
+0x00042731,0x00001003,0x0007aab0,0x00034880,
+0x00048fb0,0x0000100a,0x00057488,0x00000000,
+0x00033b94,0x00081140,0x000183ae,0x00000000,
+0x000806b0,0x0000100b,0x00022f05,0x00000000,
+0x00007401,0x00091140,0x00048f05,0x000951c0,
+0x00042731,0x00001003,0x0000473d,0x00001000,
+0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
+0x000fe19e,0x00001003,0x00000000,0x00000000,
+0x0008e19c,0x00001003,0x000083c1,0x00093040,
+0x00000f41,0x00097140,0x0000a841,0x0009b240,
+0x0000a0c1,0x0009f040,0x0001c641,0x00093540,
+0x0001cec1,0x0009b5c0,0x00000000,0x000fdc44,
+0x00055208,0x00000000,0x00010705,0x000a2880,
+0x0000a23a,0x00093a00,0x0003fc8a,0x000df6c5,
+0x0004ef0a,0x000c0000,0x00012f05,0x00036880,
+0x00065308,0x000c2997,0x000d86b0,0x0000100a,
+0x0004410a,0x000d40c7,0x00000000,0x00000000,
+0x00080730,0x00001004,0x00056f0a,0x000ea105,
+0x00000000,0x00000000,0x0000473d,0x00001000,
+0x000f19b0,0x000bbc47,0x00080000,0x000bffc7,
+0x0000273d,0x00001000,0x00000000,0x000eba44,
+0x00048f05,0x0000f440,0x00007401,0x0000f7c0,
+0x00000734,0x00001000,0x00010705,0x000a6880,
+0x00006a88,0x000c75c4,0x00000000,0x000e5084,
+0x00000000,0x000eba44,0x00087401,0x000e4782,
+0x00000734,0x00001000,0x00010705,0x000a6880,
+0x00006a88,0x000c75c4,0x0007c108,0x000c0000,
+0x0007e721,0x000bed40,0x00005f25,0x000badc0,
+0x0003ba97,0x000beb80,0x00065590,0x000b2e00,
+0x00033217,0x00003ec0,0x00065590,0x000b8e40,
+0x0003ed80,0x000491c0,0x00073fb0,0x00074c80,
+0x000283a0,0x0000100c,0x000ee388,0x00042970,
+0x00008301,0x00021ef2,0x000b8f14,0x0000000f,
+0x000c4d8d,0x0000001b,0x000d6dc2,0x000e06c6,
+0x000032ac,0x000c3916,0x0004edc2,0x00074c80,
+0x00078898,0x00001000,0x00038894,0x00000032,
+0x000c4d8d,0x00092e1b,0x000d6dc2,0x000e06c6,
+0x0004edc2,0x000c1956,0x0000722c,0x00034a00,
+0x00041705,0x0009ed40,0x00058730,0x00001400,
+0x000d7488,0x000c3a00,0x00048f05,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000,
+0x00000000,0x00000000,0x00000000,0x00000000}
+ };
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/cs46xx.c linux.17p18/drivers/sound/cs46xx.c
--- linux.vanilla/drivers/sound/cs46xx.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/cs46xx.c	Thu Aug 17 19:35:54 2000
@@ -0,0 +1,2801 @@
+/*
+ *	Crystal SoundFusion CS46xx driver
+ *
+ *	Copyright 1999-2000 Jaroslav Kysela <perex@suse.cz>
+ *	Copyright 2000 Alan Cox <alan@redhat.com>
+ *
+ *	The core of this code is taken from the ALSA project driver by 
+ *	Jaroslav. Please send Jaroslav the credit for the driver and 
+ *	report bugs in this port to <alan@redhat.com>
+ *
+ *	This program is free software; you can redistribute it and/or modify
+ *	it under the terms of the GNU General Public License as published by
+ *	the Free Software Foundation; either version 2 of the License, or
+ *	(at your option) any later version.
+ *
+ *	This program is distributed in the hope that it will be useful,
+ *	but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *	GNU General Public License for more details.
+ *
+ *	You should have received a copy of the GNU General Public License
+ *	along with this program; if not, write to the Free Software
+ *	Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+ 
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/string.h>
+#include <linux/ctype.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/sound.h>
+#include <linux/malloc.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/init.h>
+#include <linux/poll.h>
+#include <asm/spinlock.h>
+#include <linux/ac97_codec.h>
+#include <asm/uaccess.h>
+#include <asm/hardirq.h>
+
+#include "cs461x.h"
+
+#define ADC_RUNNING	1
+#define DAC_RUNNING	2
+
+#define CS_FMT_16BIT	1		/* These are fixed in fact */
+#define CS_FMT_STEREO	2
+#define CS_FMT_MASK	3
+
+/*
+ *	CS461x definitions
+ */
+ 
+#define CS461X_BA0_SIZE		0x2000
+#define CS461X_BA1_DATA0_SIZE	0x3000
+#define CS461X_BA1_DATA1_SIZE	0x3800
+#define CS461X_BA1_PRG_SIZE	0x7000
+#define CS461X_BA1_REG_SIZE	0x0100
+
+#define GOF_PER_SEC	200
+
+static int external_amp = 0;
+static int thinkpad = 0;
+
+
+/* An instance of the 4610 channel */
+
+struct cs_channel 
+{
+	int used;
+	int num;
+	void *state;
+};
+
+#define DRIVER_VERSION "0.09"
+
+/* magic numbers to protect our data structures */
+#define CS_CARD_MAGIC		0x46524F4D /* "FROM" */
+#define CS_STATE_MAGIC		0x414c5341 /* "ALSA" */
+#define NR_HW_CH		3
+
+/* maxinum number of AC97 codecs connected, AC97 2.0 defined 4 */
+#define NR_AC97		2
+
+/* minor number of /dev/dspW */
+#define SND_DEV_DSP8	1
+
+/* minor number of /dev/dspW */
+#define SND_DEV_DSP16	1 
+
+static const unsigned sample_size[] = { 1, 2, 2, 4 };
+static const unsigned sample_shift[] = { 0, 1, 1, 2 };
+
+/* "software" or virtual channel, an instance of opened /dev/dsp */
+struct cs_state {
+	unsigned int magic;
+	struct cs_card *card;	/* Card info */
+
+	/* single open lock mechanism, only used for recording */
+	struct semaphore open_sem;
+	struct wait_queue *open_wait;
+
+	/* file mode */
+	mode_t open_mode;
+
+	/* virtual channel number */
+	int virt;
+	
+	struct dmabuf {
+		/* wave sample stuff */
+		unsigned int rate;
+		unsigned char fmt, enable;
+
+		/* hardware channel */
+		struct cs_channel *channel;
+		int pringbuf;		/* Software ring slot */
+		int ppingbuf;		/* Hardware ring slot */
+		void *pbuf;		/* 4K hardware DMA buffer */
+
+		/* OSS buffer management stuff */
+		void *rawbuf;
+		unsigned buforder;
+		unsigned numfrag;
+		unsigned fragshift;
+
+		/* our buffer acts like a circular ring */
+		unsigned hwptr;		/* where dma last started, updated by update_ptr */
+		unsigned swptr;		/* where driver last clear/filled, updated by read/write */
+		int count;		/* bytes to be comsumed or been generated by dma machine */
+		unsigned total_bytes;	/* total bytes dmaed by hardware */
+
+		unsigned error;		/* number of over/underruns */
+		struct wait_queue *wait;	/* put process on wait queue when no more space in buffer */
+
+		/* redundant, but makes calculations easier */
+		unsigned fragsize;
+		unsigned dmasize;
+		unsigned fragsamples;
+
+		/* OSS stuff */
+		unsigned mapped:1;
+		unsigned ready:1;
+		unsigned endcleared:1;
+		unsigned update_flag;
+		unsigned ossfragshift;
+		int ossmaxfrags;
+		unsigned subdivision;
+	} dmabuf;
+};
+
+
+struct cs_card {
+	struct cs_channel channel[2];
+	unsigned int magic;
+
+	/* We keep cs461x cards in a linked list */
+	struct cs_card *next;
+
+	/* The cs461x has a certain amount of cross channel interaction
+	   so we use a single per card lock */
+	spinlock_t lock;
+
+	/* PCI device stuff */
+	struct pci_dev * pci_dev;
+
+	unsigned int pctl, cctl;	/* Hardware DMA flag sets */
+
+	/* soundcore stuff */
+	int dev_audio;
+
+	/* structures for abstraction of hardware facilities, codecs, banks and channels*/
+	struct ac97_codec *ac97_codec[NR_AC97];
+	struct cs_state *states[NR_HW_CH];
+
+	u16 ac97_features;
+	
+	int amplifier;			/* Amplifier control */
+	void (*amplifier_ctrl)(struct cs_card *, int);
+	
+	int active;			/* Active clocking */
+	void (*active_ctrl)(struct cs_card *, int);
+	
+	/* hardware resources */
+	unsigned long ba0_addr;
+	unsigned long ba1_addr;
+	u32 irq;
+	
+	/* mappings */
+	void *ba0;
+	union
+	{
+		struct
+		{
+			u8 *data0;
+			u8 *data1;
+			u8 *pmem;
+			u8 *reg;
+		} name;
+		u8 *idx[4];
+	} ba1;
+	
+	/* Function support */
+	struct cs_channel *(*alloc_pcm_channel)(struct cs_card *);
+	struct cs_channel *(*alloc_rec_pcm_channel)(struct cs_card *);
+	void (*free_pcm_channel)(struct cs_card *, int chan);
+};
+
+static struct cs_card *devs = NULL;
+
+static int cs_open_mixdev(struct inode *inode, struct file *file);
+static int cs_release_mixdev(struct inode *inode, struct file *file);
+static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
+				unsigned long arg);
+static loff_t cs_llseek(struct file *file, loff_t offset, int origin);
+
+extern __inline__ unsigned ld2(unsigned int x)
+{
+	unsigned r = 0;
+	
+	if (x >= 0x10000) {
+		x >>= 16;
+		r += 16;
+	}
+	if (x >= 0x100) {
+		x >>= 8;
+		r += 8;
+	}
+	if (x >= 0x10) {
+		x >>= 4;
+		r += 4;
+	}
+	if (x >= 4) {
+		x >>= 2;
+		r += 2;
+	}
+	if (x >= 2)
+		r++;
+	return r;
+}
+
+
+/*
+ *  common I/O routines
+ */
+
+static void cs461x_poke(struct cs_card *codec, unsigned long reg, unsigned int val)
+{
+	writel(val, codec->ba1.idx[(reg >> 16) & 3]+(reg&0xffff));
+}
+
+static unsigned int cs461x_peek(struct cs_card *codec, unsigned long reg)
+{
+	return readl(codec->ba1.idx[(reg >> 16) & 3]+(reg&0xffff));
+}
+
+static void cs461x_pokeBA0(struct cs_card *codec, unsigned long reg, unsigned int val)
+{
+	writel(val, codec->ba0+reg);
+}
+
+static unsigned int cs461x_peekBA0(struct cs_card *codec, unsigned long reg)
+{
+	return readl(codec->ba0+reg);
+}
+
+
+static u16 cs_ac97_get(struct ac97_codec *dev, u8 reg);
+static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 data);
+
+static struct cs_channel *cs_alloc_pcm_channel(struct cs_card *card)
+{
+	if(card->channel[1].used==1)
+		return NULL;
+	card->channel[1].used=1;
+	card->channel[1].num=1;
+	return &card->channel[1];
+}
+
+static struct cs_channel *cs_alloc_rec_pcm_channel(struct cs_card *card)
+{
+	if(card->channel[0].used==1)
+		return NULL;
+	card->channel[0].used=1;
+	card->channel[0].num=0;
+	return &card->channel[0];
+}
+
+static void cs_free_pcm_channel(struct cs_card *card, int channel)
+{
+	card->channel[channel].state = NULL;
+	card->channel[channel].used=0;
+}
+
+/* set playback sample rate */
+static unsigned int cs_set_dac_rate(struct cs_state * state, unsigned int rate)
+{	
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned int tmp1, tmp2;
+	unsigned int phiIncr;
+	unsigned int correctionPerGOF, correctionPerSec;
+
+	/*
+	 *  Compute the values used to drive the actual sample rate conversion.
+	 *  The following formulas are being computed, using inline assembly
+	 *  since we need to use 64 bit arithmetic to compute the values:
+	 *
+	 *  phiIncr = floor((Fs,in * 2^26) / Fs,out)
+	 *  correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
+         *                                   GOF_PER_SEC)
+         *  ulCorrectionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -M
+         *                       GOF_PER_SEC * correctionPerGOF
+	 *
+	 *  i.e.
+	 *
+	 *  phiIncr:other = dividend:remainder((Fs,in * 2^26) / Fs,out)
+	 *  correctionPerGOF:correctionPerSec =
+	 *      dividend:remainder(ulOther / GOF_PER_SEC)
+	 */
+	tmp1 = rate << 16;
+	phiIncr = tmp1 / 48000;
+	tmp1 -= phiIncr * 48000;
+	tmp1 <<= 10;
+	phiIncr <<= 10;
+	tmp2 = tmp1 / 48000;
+	phiIncr += tmp2;
+	tmp1 -= tmp2 * 48000;
+	correctionPerGOF = tmp1 / GOF_PER_SEC;
+	tmp1 -= correctionPerGOF * GOF_PER_SEC;
+	correctionPerSec = tmp1;
+
+	/*
+	 *  Fill in the SampleRateConverter control block.
+	 */
+	 
+	spin_lock_irq(&state->card->lock);
+	cs461x_poke(state->card, BA1_PSRC,
+	  ((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
+	cs461x_poke(state->card, BA1_PPI, phiIncr);
+	spin_unlock_irq(&state->card->lock);
+	dmabuf->rate = rate;
+	
+	return rate;
+}
+
+/* set recording sample rate */
+static unsigned int cs_set_adc_rate(struct cs_state * state, unsigned int rate)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	struct cs_card *card = state->card;
+	unsigned int phiIncr, coeffIncr, tmp1, tmp2;
+	unsigned int correctionPerGOF, correctionPerSec, initialDelay;
+	unsigned int frameGroupLength, cnt;
+
+	/*
+	 *  We can only decimate by up to a factor of 1/9th the hardware rate.
+	 *  Correct the value if an attempt is made to stray outside that limit.
+	 */
+	if ((rate * 9) < 48000)
+		rate = 48000 / 9;
+
+	/*
+	 *  We can not capture at at rate greater than the Input Rate (48000).
+	 *  Return an error if an attempt is made to stray outside that limit.
+	 */
+	if (rate > 48000)
+		rate = 48000;
+
+	/*
+	 *  Compute the values used to drive the actual sample rate conversion.
+	 *  The following formulas are being computed, using inline assembly
+	 *  since we need to use 64 bit arithmetic to compute the values:
+	 *
+	 *     coeffIncr = -floor((Fs,out * 2^23) / Fs,in)
+	 *     phiIncr = floor((Fs,in * 2^26) / Fs,out)
+	 *     correctionPerGOF = floor((Fs,in * 2^26 - Fs,out * phiIncr) /
+	 *                                GOF_PER_SEC)
+	 *     correctionPerSec = Fs,in * 2^26 - Fs,out * phiIncr -
+	 *                          GOF_PER_SEC * correctionPerGOF
+	 *     initialDelay = ceil((24 * Fs,in) / Fs,out)
+	 *
+	 * i.e.
+	 *
+	 *     coeffIncr = neg(dividend((Fs,out * 2^23) / Fs,in))
+	 *     phiIncr:ulOther = dividend:remainder((Fs,in * 2^26) / Fs,out)
+	 *     correctionPerGOF:correctionPerSec =
+	 * 	    dividend:remainder(ulOther / GOF_PER_SEC)
+	 *     initialDelay = dividend(((24 * Fs,in) + Fs,out - 1) / Fs,out)
+	 */
+
+	tmp1 = rate << 16;
+	coeffIncr = tmp1 / 48000;
+	tmp1 -= coeffIncr * 48000;
+	tmp1 <<= 7;
+	coeffIncr <<= 7;
+	coeffIncr += tmp1 / 48000;
+	coeffIncr ^= 0xFFFFFFFF;
+	coeffIncr++;
+	tmp1 = 48000 << 16;
+	phiIncr = tmp1 / rate;
+	tmp1 -= phiIncr * rate;
+	tmp1 <<= 10;
+	phiIncr <<= 10;
+	tmp2 = tmp1 / rate;
+	phiIncr += tmp2;
+	tmp1 -= tmp2 * rate;
+	correctionPerGOF = tmp1 / GOF_PER_SEC;
+	tmp1 -= correctionPerGOF * GOF_PER_SEC;
+	correctionPerSec = tmp1;
+	initialDelay = ((48000 * 24) + rate - 1) / rate;
+
+	/*
+	 *  Fill in the VariDecimate control block.
+	 */
+	spin_lock_irq(&card->lock);
+	cs461x_poke(card, BA1_CSRC,
+		((correctionPerSec << 16) & 0xFFFF0000) | (correctionPerGOF & 0xFFFF));
+	cs461x_poke(card, BA1_CCI, coeffIncr);
+	cs461x_poke(card, BA1_CD,
+		(((BA1_VARIDEC_BUF_1 + (initialDelay << 2)) << 16) & 0xFFFF0000) | 0x80);
+	cs461x_poke(card, BA1_CPI, phiIncr);
+	spin_unlock_irq(&card->lock);
+
+	/*
+	 *  Figure out the frame group length for the write back task.  Basically,
+	 *  this is just the factors of 24000 (2^6*3*5^3) that are not present in
+	 *  the output sample rate.
+	 */
+	frameGroupLength = 1;
+	for (cnt = 2; cnt <= 64; cnt *= 2) {
+		if (((rate / cnt) * cnt) != rate)
+			frameGroupLength *= 2;
+	}
+	if (((rate / 3) * 3) != rate) {
+		frameGroupLength *= 3;
+	}
+	for (cnt = 5; cnt <= 125; cnt *= 5) {
+		if (((rate / cnt) * cnt) != rate) 
+			frameGroupLength *= 5;
+        }
+
+	/*
+	 * Fill in the WriteBack control block.
+	 */
+	spin_lock_irq(&card->lock);
+	cs461x_poke(card, BA1_CFG1, frameGroupLength);
+	cs461x_poke(card, BA1_CFG2, (0x00800000 | frameGroupLength));
+	cs461x_poke(card, BA1_CCST, 0x0000FFFF);
+	cs461x_poke(card, BA1_CSPB, ((65536 * rate) / 24000));
+	cs461x_poke(card, (BA1_CSPB + 4), 0x0000FFFF);
+	spin_unlock_irq(&card->lock);
+	dmabuf->rate = rate;
+	return rate;
+}
+
+/* prepare channel attributes for playback */ 
+static void cs_play_setup(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	struct cs_card *card = state->card;
+	unsigned int tmp, tmp1;
+
+	tmp1=16;
+	if (!(dmabuf->fmt & CS_FMT_STEREO))
+		tmp1>>=1;
+	cs461x_poke(card, BA1_PVOL, 0x80008000);
+	cs461x_poke(card, BA1_PBA, virt_to_bus(dmabuf->pbuf));
+	
+	tmp=cs461x_peek(card, BA1_PDTC);
+	tmp&=~0x000003FF;
+	tmp|=tmp1-1;
+	cs461x_poke(card, BA1_PDTC, tmp);
+	
+	tmp=cs461x_peek(card, BA1_PFIE);
+	tmp&=~0x0000F03F;
+	if(!(dmabuf->fmt & CS_FMT_STEREO))
+	{
+		tmp|=0x00002000;
+	}
+	cs461x_poke(card, BA1_PFIE, tmp);
+
+}
+
+/* prepare channel attributes for recording */
+static void cs_rec_setup(struct cs_state *state)
+{
+	struct cs_card *card = state->card;
+	struct dmabuf *dmabuf = &state->dmabuf;
+	/* set the attenuation to 0dB */
+	cs461x_poke(card, BA1_CVOL, 0x80008000);
+	cs461x_poke(card, BA1_CBA, virt_to_bus(dmabuf->pbuf));
+}
+
+
+/* get current playback/recording dma buffer pointer (byte offset from LBA),
+   called with spinlock held! */
+   
+extern __inline__ unsigned cs_get_dma_addr(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	u32 offset;
+	
+	if (!dmabuf->enable)
+		return 0;
+		
+	offset = dmabuf->pringbuf * 2048;
+	return offset;
+}
+
+static void resync_dma_ptrs(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	int offset;
+	
+	offset = 0;
+	dmabuf->hwptr=dmabuf->swptr = 0;
+	dmabuf->ppingbuf = dmabuf->pringbuf = 0;
+	dmabuf->ppingbuf = 1;
+	if(dmabuf->fmt&CS_FMT_16BIT)
+		memset(dmabuf->pbuf, 0, PAGE_SIZE);
+	else
+		memset(dmabuf->pbuf, 0x80, PAGE_SIZE);
+}
+	
+/* Stop recording (lock held) */
+extern __inline__ void __stop_adc(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	struct cs_card *card = state->card;
+	unsigned int tmp;
+	
+	dmabuf->enable &= ~ADC_RUNNING;
+	
+	tmp=cs461x_peek(card, BA1_CCTL);
+	tmp&=0xFFFF;
+	cs461x_poke(card, BA1_CCTL, tmp);
+	
+}
+
+static void stop_adc(struct cs_state *state)
+{
+	struct cs_card *card = state->card;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+	__stop_adc(state);
+	spin_unlock_irqrestore(&card->lock, flags);
+}
+
+static void start_adc(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	struct cs_card *card = state->card;
+	unsigned long flags;
+	unsigned int tmp;
+
+	spin_lock_irqsave(&card->lock, flags);
+	if ((dmabuf->mapped || dmabuf->count < (signed)dmabuf->dmasize) && dmabuf->ready) {
+		dmabuf->enable |= ADC_RUNNING;
+		tmp=cs461x_peek(card, BA1_CCTL);
+		tmp&=0xFFFF;
+		tmp|=card->cctl;
+		cs461x_poke(card, BA1_CCTL, tmp);
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+}
+
+/* stop playback (lock held) */
+extern __inline__ void __stop_dac(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	struct cs_card *card = state->card;
+	unsigned int tmp;
+
+	dmabuf->enable &= ~DAC_RUNNING;
+	
+	tmp=cs461x_peek(card, BA1_PCTL);
+	tmp&=0xFFFF;
+	cs461x_poke(card, BA1_PCTL, tmp);
+}
+
+static void stop_dac(struct cs_state *state)
+{
+	struct cs_card *card = state->card;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+	__stop_dac(state);
+	spin_unlock_irqrestore(&card->lock, flags);
+}	
+
+static void start_dac(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	struct cs_card *card = state->card;
+	unsigned long flags;
+	int tmp;
+
+	spin_lock_irqsave(&card->lock, flags);
+	if ((dmabuf->mapped || dmabuf->count > 0) && dmabuf->ready) {
+		if(!(dmabuf->enable&DAC_RUNNING))
+		{
+			dmabuf->enable |= DAC_RUNNING;
+			tmp = cs461x_peek(card, BA1_PCTL);
+			tmp &= 0xFFFF;
+			tmp |= card->pctl;
+			cs461x_poke(card, BA1_PCTL, tmp);
+		}
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+}
+
+#define DMABUF_DEFAULTORDER (15-PAGE_SHIFT)
+#define DMABUF_MINORDER 1
+
+/* allocate DMA buffer, playback and recording buffer should be allocated seperately */
+static int alloc_dmabuf(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	void *rawbuf = NULL;
+	int order;
+	unsigned long map, mapend;
+
+	/* alloc as big a chunk as we can */
+	for (order = DMABUF_DEFAULTORDER; order >= DMABUF_MINORDER; order--)
+		if((rawbuf = (void *)__get_free_pages(GFP_KERNEL|GFP_DMA, order)))
+			break;
+
+	if (!rawbuf)
+		return -ENOMEM;
+
+#ifdef DEBUG
+	printk("cs461x: allocated %ld (order = %d) bytes at %p\n",
+	       PAGE_SIZE << order, order, rawbuf);
+#endif
+
+	dmabuf->ready  = dmabuf->mapped = 0;
+	dmabuf->rawbuf = rawbuf;
+	dmabuf->buforder = order;
+	
+	/* now mark the pages as reserved; otherwise remap_page_range doesn't do what we want */
+	mapend = MAP_NR(rawbuf + (PAGE_SIZE << order) - 1);
+	for (map = MAP_NR(rawbuf); map <= mapend; map++)
+		set_bit(PG_reserved, &mem_map[map].flags);
+
+	return 0;
+}
+
+/* free DMA buffer */
+static void dealloc_dmabuf(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned long map, mapend;
+
+	if (dmabuf->rawbuf) {
+		/* undo marking the pages as reserved */
+		mapend = MAP_NR(dmabuf->rawbuf + (PAGE_SIZE << dmabuf->buforder) - 1);
+		for (map = MAP_NR(dmabuf->rawbuf); map <= mapend; map++)
+			clear_bit(PG_reserved, &mem_map[map].flags);
+		free_pages((unsigned long)dmabuf->rawbuf,dmabuf->buforder);
+	}
+	dmabuf->rawbuf = NULL;
+	dmabuf->mapped = dmabuf->ready = 0;
+}
+
+static int prog_dmabuf(struct cs_state *state, unsigned rec)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned bytepersec;
+	unsigned bufsize;
+	unsigned long flags;
+	int ret;
+	
+	spin_lock_irqsave(&state->card->lock, flags);
+	resync_dma_ptrs(state);
+	dmabuf->total_bytes = 0;
+	dmabuf->count = dmabuf->error = 0;
+	spin_unlock_irqrestore(&state->card->lock, flags);
+
+	/* allocate DMA buffer if not allocated yet */
+	if (!dmabuf->rawbuf)
+		if ((ret = alloc_dmabuf(state)))
+			return ret;
+
+	/* FIXME: figure out all this OSS fragment stuff */
+	bytepersec = dmabuf->rate << sample_shift[dmabuf->fmt];
+	bufsize = PAGE_SIZE << dmabuf->buforder;
+	if (dmabuf->ossfragshift) {
+		if ((1000 << dmabuf->ossfragshift) < bytepersec)
+			dmabuf->fragshift = ld2(bytepersec/1000);
+		else
+			dmabuf->fragshift = dmabuf->ossfragshift;
+	} else {
+		/* lets hand out reasonable big ass buffers by default */
+		dmabuf->fragshift = (dmabuf->buforder + PAGE_SHIFT -2);
+	}
+	dmabuf->numfrag = bufsize >> dmabuf->fragshift;
+	while (dmabuf->numfrag < 4 && dmabuf->fragshift > 3) {
+		dmabuf->fragshift--;
+		dmabuf->numfrag = bufsize >> dmabuf->fragshift;
+	}
+	dmabuf->fragsize = 1 << dmabuf->fragshift;
+	if (dmabuf->ossmaxfrags >= 4 && dmabuf->ossmaxfrags < dmabuf->numfrag)
+		dmabuf->numfrag = dmabuf->ossmaxfrags;
+	dmabuf->fragsamples = dmabuf->fragsize >> sample_shift[dmabuf->fmt];
+	dmabuf->dmasize = dmabuf->numfrag << dmabuf->fragshift;
+
+	memset(dmabuf->rawbuf, (dmabuf->fmt & CS_FMT_16BIT) ? 0 : 0x80,
+	       dmabuf->dmasize);
+
+	/*
+	 *	Now set up the ring 
+	 */
+
+	spin_lock_irqsave(&state->card->lock, flags);
+	if (rec) {
+		cs_rec_setup(state);
+	} else {
+		cs_play_setup(state);
+	}
+	spin_unlock_irqrestore(&state->card->lock, flags);
+
+	/* set the ready flag for the dma buffer */
+	dmabuf->ready = 1;
+
+#ifdef DEBUG
+	printk("cs461x: prog_dmabuf, sample rate = %d, format = %d, numfrag = %d, "
+	       "fragsize = %d dmasize = %d\n",
+	       dmabuf->rate, dmabuf->fmt, dmabuf->numfrag,
+	       dmabuf->fragsize, dmabuf->dmasize);
+#endif
+
+	return 0;
+}
+
+static void cs_clear_tail(struct cs_state *state)
+{
+}
+
+static int drain_dac(struct cs_state *state, int nonblock)
+{
+	struct wait_queue wait = {current, NULL};
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned long flags;
+	unsigned long tmo;
+	int count;
+
+	if (dmabuf->mapped || !dmabuf->ready)
+		return 0;
+
+	add_wait_queue(&dmabuf->wait, &wait);
+	for (;;) {
+		/* It seems that we have to set the current state to TASK_INTERRUPTIBLE
+		   every time to make the process really go to sleep */
+		current->state = TASK_INTERRUPTIBLE;
+
+		spin_lock_irqsave(&state->card->lock, flags);
+		count = dmabuf->count;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+
+		if (count <= 0)
+			break;
+
+		if (signal_pending(current))
+			break;
+
+		if (nonblock) {
+			remove_wait_queue(&dmabuf->wait, &wait);
+			current->state = TASK_RUNNING;
+			return -EBUSY;
+		}
+
+		tmo = (dmabuf->dmasize * HZ) / dmabuf->rate;
+		tmo >>= sample_shift[dmabuf->fmt];
+		tmo += (4096*HZ)/dmabuf->rate;
+		
+		if (!schedule_timeout(tmo ? tmo : 1) && tmo){
+			printk(KERN_ERR "cs461x: drain_dac, dma timeout? %d\n", count);
+			break;
+		}
+	}
+	remove_wait_queue(&dmabuf->wait, &wait);
+	current->state = TASK_RUNNING;
+	if (signal_pending(current))
+		return -ERESTARTSYS;
+
+	return 0;
+}
+
+/* update buffer manangement pointers, especially, dmabuf->count and dmabuf->hwptr */
+static void cs_update_ptr(struct cs_state *state)
+{
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned hwptr, swptr;
+	int clear_cnt = 0;
+	int diff;
+	unsigned char silence;
+
+	/* update hardware pointer */
+	hwptr = cs_get_dma_addr(state);
+	diff = (dmabuf->dmasize + hwptr - dmabuf->hwptr) % dmabuf->dmasize;
+	dmabuf->hwptr = hwptr;
+	dmabuf->total_bytes += diff;
+
+	/* error handling and process wake up for DAC */
+	if (dmabuf->enable == ADC_RUNNING) {
+		if (dmabuf->mapped) {
+			dmabuf->count -= diff;
+			if (dmabuf->count >= (signed)dmabuf->fragsize)
+				wake_up(&dmabuf->wait);
+		} else {
+			dmabuf->count += diff;
+
+			if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
+				/* buffer underrun or buffer overrun, we have no way to recover
+				   it here, just stop the machine and let the process force hwptr
+				   and swptr to sync */
+				__stop_adc(state);
+				dmabuf->error++;
+			}
+			else if (!dmabuf->endcleared) {
+				swptr = dmabuf->swptr;
+				silence = (dmabuf->fmt & CS_FMT_16BIT ? 0 : 0x80);
+				if (dmabuf->count < (signed) dmabuf->fragsize) 
+				{
+					clear_cnt = dmabuf->fragsize;
+					if ((swptr + clear_cnt) > dmabuf->dmasize)
+						clear_cnt = dmabuf->dmasize - swptr;
+					memset (dmabuf->rawbuf + swptr, silence, clear_cnt);
+					dmabuf->endcleared = 1;
+				}
+			}			
+			wake_up(&dmabuf->wait);
+		}
+	}
+	/* error handling and process wake up for DAC */
+	if (dmabuf->enable == DAC_RUNNING) {
+		if (dmabuf->mapped) {
+			dmabuf->count += diff;
+			if (dmabuf->count >= (signed)dmabuf->fragsize)
+				wake_up(&dmabuf->wait);
+		} else {
+			dmabuf->count -= diff;
+
+			if (dmabuf->count < 0 || dmabuf->count > dmabuf->dmasize) {
+				/* buffer underrun or buffer overrun, we have no way to recover
+				   it here, just stop the machine and let the process force hwptr
+				   and swptr to sync */
+				__stop_dac(state);
+				dmabuf->error++;
+			}
+			wake_up(&dmabuf->wait);
+		}
+	}
+}
+
+static void cs_record_interrupt(struct cs_state *state)
+{
+	memcpy(state->dmabuf.rawbuf + (2048*state->dmabuf.pringbuf++),
+		state->dmabuf.pbuf+2048*state->dmabuf.ppingbuf++, 2048);
+	state->dmabuf.ppingbuf&=1;
+	if(state->dmabuf.pringbuf >= (PAGE_SIZE<<state->dmabuf.buforder)/2048)
+		state->dmabuf.pringbuf=0;
+	cs_update_ptr(state);
+}
+
+static void cs_play_interrupt(struct cs_state *state)
+{
+	memcpy(state->dmabuf.pbuf+2048*state->dmabuf.ppingbuf++,
+		state->dmabuf.rawbuf + (2048*state->dmabuf.pringbuf++), 2048);
+	state->dmabuf.ppingbuf&=1;
+	if(state->dmabuf.pringbuf >= (PAGE_SIZE<<state->dmabuf.buforder)/2048)
+		state->dmabuf.pringbuf=0;
+	cs_update_ptr(state);
+}
+
+static void cs_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct cs_card *card = (struct cs_card *)dev_id;
+	/* Single channel card */
+	struct cs_state *recstate = card->channel[0].state;
+	struct cs_state *playstate = card->channel[1].state;
+	u32 status;
+
+	spin_lock(&card->lock);
+
+	status = cs461x_peekBA0(card, BA0_HISR);
+	
+	if((status&0x7fffffff)==0)
+	{
+		cs461x_pokeBA0(card, BA0_HICR, HICR_CHGM|HICR_IEV);
+		spin_unlock(&card->lock);
+		return;
+	}
+	
+	if((status & HISR_VC0) && playstate && playstate->dmabuf.ready)
+		cs_play_interrupt(playstate);
+	if((status & HISR_VC1) && recstate && recstate->dmabuf.ready)
+		cs_record_interrupt(recstate);
+	
+ 	/* clear 'em */
+	cs461x_pokeBA0(card, BA0_HICR, HICR_CHGM|HICR_IEV);
+	spin_unlock(&card->lock);
+}
+
+static loff_t cs_llseek(struct file *file, loff_t offset, int origin)
+{
+	return -ESPIPE;
+}
+
+/* in this loop, dmabuf.count signifies the amount of data that is waiting to be copied to
+   the user's buffer.  it is filled by the dma machine and drained by this loop. */
+static ssize_t cs_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct cs_state *state = (struct cs_state *)file->private_data;
+	struct dmabuf *dmabuf = &state->dmabuf;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr;
+	int cnt;
+
+#ifdef DEBUG
+	printk("cs461x: cs_read called, count = %d\n", count);
+#endif
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (dmabuf->mapped)
+		return -ENXIO;
+	if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
+		return ret;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	while (count > 0) {
+		spin_lock_irqsave(&state->card->lock, flags);
+		if (dmabuf->count > (signed) dmabuf->dmasize) {
+			/* buffer overrun, we are recovering from sleep_on_timeout,
+			   resync hwptr and swptr, make process flush the buffer */
+			dmabuf->count = dmabuf->dmasize;
+			dmabuf->swptr = dmabuf->hwptr;
+		}
+		swptr = dmabuf->swptr;
+		cnt = dmabuf->dmasize - swptr;
+		if (dmabuf->count < cnt)
+			cnt = dmabuf->count;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			unsigned long tmo;
+			/* buffer is empty, start the dma machine and wait for data to be
+			   recorded */
+			start_adc(state);
+			if (file->f_flags & O_NONBLOCK) {
+				if (!ret) ret = -EAGAIN;
+				return ret;
+			}
+			/* This isnt strictly right for the 810  but it'll do */
+			tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
+			tmo >>= sample_shift[dmabuf->fmt];
+			/* There are two situations when sleep_on_timeout returns, one is when
+			   the interrupt is serviced correctly and the process is waked up by
+			   ISR ON TIME. Another is when timeout is expired, which means that
+			   either interrupt is NOT serviced correctly (pending interrupt) or it
+			   is TOO LATE for the process to be scheduled to run (scheduler latency)
+			   which results in a (potential) buffer overrun. And worse, there is
+			   NOTHING we can do to prevent it. */
+			if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
+#ifdef DEBUG
+				printk(KERN_ERR "cs461x: recording schedule timeout, "
+				       "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				       dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
+				       dmabuf->hwptr, dmabuf->swptr);
+#endif
+				/* a buffer overrun, we delay the recovery untill next time the
+				   while loop begin and we REALLY have space to record */
+			}
+			if (signal_pending(current)) {
+				ret = ret ? ret : -ERESTARTSYS;
+				return ret;
+			}
+			continue;
+		}
+
+		if (copy_to_user(buffer, dmabuf->rawbuf + swptr, cnt)) {
+			if (!ret) ret = -EFAULT;
+			return ret;
+		}
+
+		swptr = (swptr + cnt) % dmabuf->dmasize;
+
+		spin_lock_irqsave(&state->card->lock, flags);
+		dmabuf->swptr = swptr;
+		dmabuf->count -= cnt;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		start_adc(state);
+	}
+	return ret;
+}
+
+/* in this loop, dmabuf.count signifies the amount of data that is waiting to be dma to
+   the soundcard.  it is drained by the dma machine and filled by this loop. */
+static ssize_t cs_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct cs_state *state = (struct cs_state *)file->private_data;
+	struct dmabuf *dmabuf = &state->dmabuf;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned swptr;
+	int cnt;
+
+#ifdef DEBUG
+	printk("cs461x: cs_write called, count = %d\n", count);
+#endif
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (dmabuf->mapped)
+		return -ENXIO;
+	if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
+		return ret;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+
+	while (count > 0) {
+		spin_lock_irqsave(&state->card->lock, flags);
+		if (dmabuf->count < 0) {
+			/* buffer underrun, we are recovering from sleep_on_timeout,
+			   resync hwptr and swptr */
+			dmabuf->count = 0;
+			dmabuf->swptr = dmabuf->hwptr;
+		}
+		swptr = dmabuf->swptr;
+		cnt = dmabuf->dmasize - swptr;
+		if (dmabuf->count + cnt > dmabuf->dmasize)
+			cnt = dmabuf->dmasize - dmabuf->count;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			unsigned long tmo;
+			/* buffer is full, start the dma machine and wait for data to be
+			   played */
+			start_dac(state);
+			if (file->f_flags & O_NONBLOCK) {
+				if (!ret) ret = -EAGAIN;
+				return ret;
+			}
+			/* Not strictly correct but works */
+			tmo = (dmabuf->dmasize * HZ) / (dmabuf->rate * 2);
+			tmo >>= sample_shift[dmabuf->fmt];
+			/* There are two situations when sleep_on_timeout returns, one is when
+			   the interrupt is serviced correctly and the process is waked up by
+			   ISR ON TIME. Another is when timeout is expired, which means that
+			   either interrupt is NOT serviced correctly (pending interrupt) or it
+			   is TOO LATE for the process to be scheduled to run (scheduler latency)
+			   which results in a (potential) buffer underrun. And worse, there is
+			   NOTHING we can do to prevent it. */
+			if (!interruptible_sleep_on_timeout(&dmabuf->wait, tmo)) {
+#ifdef DEBUG
+				printk(KERN_ERR "cs461x: playback schedule timeout, "
+				       "dmasz %u fragsz %u count %i hwptr %u swptr %u\n",
+				       dmabuf->dmasize, dmabuf->fragsize, dmabuf->count,
+				       dmabuf->hwptr, dmabuf->swptr);
+#endif
+				/* a buffer underrun, we delay the recovery untill next time the
+				   while loop begin and we REALLY have data to play */
+			}
+			if (signal_pending(current)) {
+				if (!ret) ret = -ERESTARTSYS;
+				return ret;
+			}
+			continue;
+		}
+		if (copy_from_user(dmabuf->rawbuf + swptr, buffer, cnt)) {
+			if (!ret) ret = -EFAULT;
+			return ret;
+		}
+
+		swptr = (swptr + cnt) % dmabuf->dmasize;
+
+		spin_lock_irqsave(&state->card->lock, flags);
+		dmabuf->swptr = swptr;
+		dmabuf->count += cnt;
+		dmabuf->endcleared = 0;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		start_dac(state);
+	}
+	return ret;
+}
+
+static unsigned int cs_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct cs_state *state = (struct cs_state *)file->private_data;
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	if (file->f_mode & FMODE_WRITE)
+		poll_wait(file, &dmabuf->wait, wait);
+	if (file->f_mode & FMODE_READ)
+		poll_wait(file, &dmabuf->wait, wait);
+
+	spin_lock_irqsave(&state->card->lock, flags);
+	cs_update_ptr(state);
+	if (file->f_mode & FMODE_READ) {
+		if (dmabuf->count >= (signed)dmabuf->fragsize)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		if (dmabuf->mapped) {
+			if (dmabuf->count >= (signed)dmabuf->fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		} else {
+			if ((signed)dmabuf->dmasize >= dmabuf->count + (signed)dmabuf->fragsize)
+				mask |= POLLOUT | POLLWRNORM;
+		}
+	}
+	spin_unlock_irqrestore(&state->card->lock, flags);
+
+	return mask;
+}
+
+static int cs_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	return -EINVAL;
+#if 0	
+	struct cs_state *state = (struct cs_state *)file->private_data;
+	struct dmabuf *dmabuf = &state->dmabuf;
+	int ret;
+	unsigned long size;
+	
+
+	if (vma->vm_flags & VM_WRITE) {
+		if ((ret = prog_dmabuf(state, 0)) != 0)
+			return ret;
+	} else if (vma->vm_flags & VM_READ) {
+		if ((ret = prog_dmabuf(state, 1)) != 0)
+			return ret;
+	} else 
+		return -EINVAL;
+
+	if (vma->vm_offset != 0)
+		return -EINVAL;
+	size = vma->vm_end - vma->vm_start;
+	if (size > (PAGE_SIZE << dmabuf->buforder))
+		return -EINVAL;
+	if (remap_page_range(vma->vm_start, virt_to_phys(dmabuf->rawbuf),
+			     size, vma->vm_page_prot))
+		return -EAGAIN;
+	dmabuf->mapped = 1;
+
+	return 0;
+#endif	
+}
+
+static int cs_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct cs_state *state = (struct cs_state *)file->private_data;
+	struct dmabuf *dmabuf = &state->dmabuf;
+	unsigned long flags;
+	audio_buf_info abinfo;
+	count_info cinfo;
+	int val, mapped, ret;
+
+	mapped = ((file->f_mode & FMODE_WRITE) && dmabuf->mapped) ||
+		((file->f_mode & FMODE_READ) && dmabuf->mapped);
+#ifdef DEBUG
+	printk("cs461x: cs_ioctl, command = %2d, arg = 0x%08x\n",
+	       _IOC_NR(cmd), arg ? *(int *)arg : 0);
+#endif
+
+	switch (cmd) 
+	{
+	case OSS_GETVERSION:
+		return put_user(SOUND_VERSION, (int *)arg);
+
+	case SNDCTL_DSP_RESET:
+		/* FIXME: spin_lock ? */
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(state);
+			synchronize_irq();
+			dmabuf->ready = 0;
+			resync_dma_ptrs(state);
+			dmabuf->swptr = dmabuf->hwptr = 0;
+			dmabuf->count = dmabuf->total_bytes = 0;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(state);
+			synchronize_irq();
+			resync_dma_ptrs(state);
+			dmabuf->ready = 0;
+			dmabuf->swptr = dmabuf->hwptr = 0;
+			dmabuf->count = dmabuf->total_bytes = 0;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SYNC:
+		if (file->f_mode & FMODE_WRITE)
+			return drain_dac(state, file->f_flags & O_NONBLOCK);
+		return 0;
+
+	case SNDCTL_DSP_SPEED: /* set smaple rate */
+		get_user_ret(val, (int *)arg, -EFAULT);
+		if (val >= 0) {
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(state);
+				dmabuf->ready = 0;
+				cs_set_dac_rate(state, val);
+			}
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(state);
+				dmabuf->ready = 0;
+				cs_set_adc_rate(state, val);
+			}
+		}
+		return put_user(dmabuf->rate, (int *)arg);
+
+	case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
+		get_user_ret(val, (int *)arg, -EFAULT);
+		if (file->f_mode & FMODE_WRITE) {
+			stop_dac(state);
+			dmabuf->ready = 0;
+			if(val)
+				dmabuf->fmt |= CS_FMT_STEREO;
+			else
+				dmabuf->fmt &= ~CS_FMT_STEREO;
+		}
+		if (file->f_mode & FMODE_READ) {
+			stop_adc(state);
+			dmabuf->ready = 0;
+			if(val)
+			{
+				dmabuf->fmt |= CS_FMT_STEREO;
+				return put_user(1, (int *)arg);
+			}
+#if 0				
+			/* Needs extra work to support this */				
+			else
+				dmabuf->fmt &= ~CS_FMT_STEREO;
+#endif				
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		if (file->f_mode & FMODE_WRITE) {
+			if ((val = prog_dmabuf(state, 0)))
+				return val;
+			return put_user(dmabuf->fragsize, (int *)arg);
+		}
+		if (file->f_mode & FMODE_READ) {
+			if ((val = prog_dmabuf(state, 1)))
+				return val;
+			return put_user(dmabuf->fragsize, (int *)arg);
+		}
+
+	case SNDCTL_DSP_GETFMTS: /* Returns a mask of supported sample format*/
+		return put_user(AFMT_S16_LE, (int *)arg);
+
+	case SNDCTL_DSP_SETFMT: /* Select sample format */
+		get_user_ret(val, (int *)arg, -EFAULT);
+		if (val != AFMT_QUERY) {
+			if(val==AFMT_S16_LE/* || val==AFMT_U8*/)
+			{
+				if (file->f_mode & FMODE_WRITE) {
+					stop_dac(state);
+					dmabuf->ready = 0;
+				}
+				if (file->f_mode & FMODE_READ) {
+					stop_adc(state);
+					dmabuf->ready = 0;
+				}
+				if(val==AFMT_S16_LE)
+					dmabuf->fmt |= CS_FMT_16BIT;
+				else
+					dmabuf->fmt &= ~CS_FMT_16BIT;
+			}
+		}
+		if(dmabuf->fmt&CS_FMT_16BIT)
+			return put_user(AFMT_S16_LE, (int *)arg);
+		else
+			return put_user(AFMT_U8, (int *)arg);
+
+	case SNDCTL_DSP_CHANNELS:
+		get_user_ret(val, (int *)arg, -EFAULT);
+		if (val != 0) {
+			if (file->f_mode & FMODE_WRITE) {
+				stop_dac(state);
+				dmabuf->ready = 0;
+				if(val>1)
+					dmabuf->fmt |= CS_FMT_STEREO;
+				else
+					dmabuf->fmt &= ~CS_FMT_STEREO;
+			}
+			if (file->f_mode & FMODE_READ) {
+				stop_adc(state);
+				dmabuf->ready = 0;
+			}
+		}
+		return put_user((dmabuf->fmt & CS_FMT_STEREO) ? 2 : 1,
+				(int *)arg);
+
+	case SNDCTL_DSP_POST:
+		/* FIXME: the same as RESET ?? */
+		return 0;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		if (dmabuf->subdivision)
+			return -EINVAL;
+		get_user_ret(val, (int *)arg, -EFAULT);
+		if (val != 1 && val != 2)
+			return -EINVAL;
+		dmabuf->subdivision = val;
+		return 0;
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		get_user_ret(val, (int *)arg, -EFAULT);
+
+		dmabuf->ossfragshift = val & 0xffff;
+		dmabuf->ossmaxfrags = (val >> 16) & 0xffff;
+		switch(dmabuf->ossmaxfrags)
+		{
+			case 1:
+				dmabuf->ossfragshift=12;
+				return 0;
+			default:
+				/* Fragments must be 2K long */
+				dmabuf->ossfragshift = 11;
+				dmabuf->ossmaxfrags=2;
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETOSPACE:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		if (!dmabuf->enable && (val = prog_dmabuf(state, 0)) != 0)
+			return val;
+		spin_lock_irqsave(&state->card->lock, flags);
+		cs_update_ptr(state);
+		abinfo.fragsize = dmabuf->fragsize;
+		abinfo.bytes = dmabuf->dmasize - dmabuf->count;
+		abinfo.fragstotal = dmabuf->numfrag;
+		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_GETISPACE:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		if (!dmabuf->enable && (val = prog_dmabuf(state, 1)) != 0)
+			return val;
+		spin_lock_irqsave(&state->card->lock, flags);
+		cs_update_ptr(state);
+		abinfo.fragsize = dmabuf->fragsize;
+		abinfo.bytes = dmabuf->count;
+		abinfo.fragstotal = dmabuf->numfrag;
+		abinfo.fragments = abinfo.bytes >> dmabuf->fragshift;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+
+	case SNDCTL_DSP_NONBLOCK:
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_GETCAPS:
+		return put_user(DSP_CAP_REALTIME|DSP_CAP_TRIGGER|DSP_CAP_MMAP,
+			    (int *)arg);
+
+	case SNDCTL_DSP_GETTRIGGER:
+		val = 0;
+		if (file->f_mode & FMODE_READ && dmabuf->enable)
+			val |= PCM_ENABLE_INPUT;
+		if (file->f_mode & FMODE_WRITE && dmabuf->enable)
+			val |= PCM_ENABLE_OUTPUT;
+		return put_user(val, (int *)arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		get_user_ret(val, (int *)arg, -EFAULT);
+		if (file->f_mode & FMODE_READ) {
+			if (val & PCM_ENABLE_INPUT) {
+				if (!dmabuf->ready && (ret = prog_dmabuf(state, 1)))
+					return ret;
+				start_adc(state);
+			} else
+				stop_adc(state);
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			if (val & PCM_ENABLE_OUTPUT) {
+				if (!dmabuf->ready && (ret = prog_dmabuf(state, 0)))
+					return ret;
+				start_dac(state);
+			} else
+				stop_dac(state);
+		}
+		return 0;
+
+	case SNDCTL_DSP_GETIPTR:
+		if (!(file->f_mode & FMODE_READ))
+			return -EINVAL;
+		spin_lock_irqsave(&state->card->lock, flags);
+		cs_update_ptr(state);
+		cinfo.bytes = dmabuf->total_bytes;
+		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
+		cinfo.ptr = dmabuf->hwptr;
+		if (dmabuf->mapped)
+			dmabuf->count &= dmabuf->fragsize-1;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_GETOPTR:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&state->card->lock, flags);
+		cs_update_ptr(state);
+		cinfo.bytes = dmabuf->total_bytes;
+		cinfo.blocks = dmabuf->count >> dmabuf->fragshift;
+		cinfo.ptr = dmabuf->hwptr;
+		if (dmabuf->mapped)
+			dmabuf->count &= dmabuf->fragsize-1;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+		return copy_to_user((void *)arg, &cinfo, sizeof(cinfo));
+
+	case SNDCTL_DSP_SETDUPLEX:
+		return -EINVAL;
+
+	case SNDCTL_DSP_GETODELAY:
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+		spin_lock_irqsave(&state->card->lock, flags);
+		cs_update_ptr(state);
+		val = dmabuf->count;
+		spin_unlock_irqrestore(&state->card->lock, flags);
+		return put_user(val, (int *)arg);
+
+	case SOUND_PCM_READ_RATE:
+		return put_user(dmabuf->rate, (int *)arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+		return put_user((dmabuf->fmt & CS_FMT_STEREO) ? 2 : 1,
+				(int *)arg);
+
+	case SOUND_PCM_READ_BITS:
+		return put_user(AFMT_S16_LE, (int *)arg);
+
+	case SNDCTL_DSP_MAPINBUF:
+	case SNDCTL_DSP_MAPOUTBUF:
+	case SNDCTL_DSP_SETSYNCRO:
+	case SOUND_PCM_WRITE_FILTER:
+	case SOUND_PCM_READ_FILTER:
+		return -EINVAL;
+	}
+	return -EINVAL;
+}
+
+
+/*
+ *	AMP control - null AMP
+ */
+ 
+static void amp_none(struct cs_card *card, int change)
+{	
+}
+
+/*
+ *	Crystal EAPD mode
+ */
+ 
+static void amp_voyetra(struct cs_card *card, int change)
+{
+	/* Manage the EAPD bit on the Crystal 4297 */
+	int old=card->amplifier;
+	
+	card->amplifier+=change;
+	if(card->amplifier && !old)
+	{
+		/* Turn the EAPD amp on */
+		cs_ac97_set(card->ac97_codec[0],  AC97_POWER_CONTROL, 
+			cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) |
+				0x8000);
+	}
+	else if(old && !card->amplifier)
+	{
+		/* Turn the EAPD amp off */
+		cs_ac97_set(card->ac97_codec[0],  AC97_POWER_CONTROL, 
+			cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) &
+				~0x8000);
+	}
+}
+
+
+
+/*
+ *	Untested
+ */
+ 
+static void amp_voyetra_4294(struct cs_card *card, int change)
+{
+	struct ac97_codec *c=card->ac97_codec[0];
+	int old = card->amplifier;
+	
+	card->amplifier+=change;
+
+	if(card->amplifier)
+	{
+		/* Switch the GPIO pins 7 and 8 to open drain */
+		cs_ac97_set(c, 0x4C, cs_ac97_get(c, 0x4C) & 0xFE7F);
+		cs_ac97_set(c, 0x4E, cs_ac97_get(c, 0x4E) | 0x0180);
+		/* Now wake the AMP (this might be backwards) */
+		cs_ac97_set(c, 0x54, cs_ac97_get(c, 0x54) & ~0x0180);
+	}
+	else
+	{
+		cs_ac97_set(c, 0x54, cs_ac97_get(c, 0x54) | 0x0180);
+	}
+}
+
+/*
+ *	Handle the CLKRUN on a thinkpad. We must disable CLKRUN support
+ *	whenever we need to beat on the chip.
+ *
+ *	The original idea and code for this hack comes from David Kaiser at
+ *	Linuxcare. Perhaps one day Crystal will document their chips well
+ *	enough to make them useful.
+ */
+ 
+static void clkrun_hack(struct cs_card *card, int change)
+{
+	struct pci_dev *acpi_dev;
+	u16 control;
+	u8 pp;
+	unsigned long port;
+	int old=card->amplifier;
+	
+	card->amplifier+=change;
+	
+	acpi_dev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82371AB_3, NULL);
+	if(acpi_dev == NULL)
+		return;		/* Not a thinkpad thats for sure */
+
+	/* Find the control port */		
+	pci_read_config_byte(acpi_dev, 0x41, &pp);
+	port=pp<<8;
+
+	/* Read ACPI port */	
+	control=inw(port+0x10);
+
+	/* Flip CLKRUN off while running */
+	if(!card->amplifier && old)
+		outw(control|0x2000, port+0x10);
+	else if(card->amplifier && !old)
+		outw(control&~0x2000, port+0x10);
+}
+
+	
+static int cs_open(struct inode *inode, struct file *file)
+{
+	int i = 0;
+	struct cs_card *card = devs;
+	struct cs_state *state = NULL;
+	struct dmabuf *dmabuf = NULL;
+
+	/* find an avaiable virtual channel (instance of /dev/dsp) */
+	while (card != NULL) {
+		for (i = 0; i < NR_HW_CH; i++) {
+			if (card->states[i] == NULL) {
+				state = card->states[i] = (struct cs_state *)
+					kmalloc(sizeof(struct cs_state), GFP_KERNEL);
+				if (state == NULL)
+					return -ENOMEM;
+				memset(state, 0, sizeof(struct cs_state));
+				dmabuf = &state->dmabuf;
+				dmabuf->pbuf = (void *)get_free_page(GFP_KERNEL);
+				if(dmabuf->pbuf==NULL)
+				{
+					kfree(state);
+					card->states[i]=NULL;
+					return -ENOMEM;
+				}
+				goto found_virt;
+			}
+		}
+		card = card->next;
+	}
+	/* no more virtual channel avaiable */
+	if (!state)
+		return -ENODEV;
+
+ found_virt:
+	/* found a free virtual channel, allocate hardware channels */
+	if(file->f_mode & FMODE_READ)
+		dmabuf->channel = card->alloc_rec_pcm_channel(card);
+	else
+		dmabuf->channel = card->alloc_pcm_channel(card);
+		
+	if (dmabuf->channel == NULL) {
+		kfree (card->states[i]);
+		card->states[i] = NULL;;
+		return -ENODEV;
+	}
+
+	/* Now turn on external AMP if needed */
+	state->card = card;
+	state->card->active_ctrl(state->card,1);
+	state->card->amplifier_ctrl(state->card,1);
+	
+	dmabuf->channel->state = state;
+	/* initialize the virtual channel */
+	state->virt = i;
+	state->magic = CS_STATE_MAGIC;
+	dmabuf->wait = NULL;
+	state->open_sem = MUTEX;
+	file->private_data = state;
+
+	down(&state->open_sem);
+
+	/* set default sample format. According to OSS Programmer's Guide  /dev/dsp
+	   should be default to unsigned 8-bits, mono, with sample rate 8kHz and
+	   /dev/dspW will accept 16-bits sample */
+	if (file->f_mode & FMODE_WRITE) {
+		/* Output is 16bit only mono or stereo */
+		dmabuf->fmt &= ~CS_FMT_MASK;
+		dmabuf->fmt |= CS_FMT_16BIT;
+		dmabuf->ossfragshift = 0;
+		dmabuf->ossmaxfrags  = 0;
+		dmabuf->subdivision  = 0;
+		cs_set_dac_rate(state, 8000);
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		/* Input is 16bit stereo only */
+		dmabuf->fmt &= ~CS_FMT_MASK;
+		dmabuf->fmt |= CS_FMT_16BIT|CS_FMT_STEREO;
+		dmabuf->ossfragshift = 0;
+		dmabuf->ossmaxfrags  = 0;
+		dmabuf->subdivision  = 0;
+		cs_set_adc_rate(state, 8000);
+	}
+
+	state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	up(&state->open_sem);
+	
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int cs_release(struct inode *inode, struct file *file)
+{
+	struct cs_state *state = (struct cs_state *)file->private_data;
+	struct dmabuf *dmabuf = &state->dmabuf;
+
+	if (file->f_mode & FMODE_WRITE) {
+		/* FIXME :.. */
+		cs_clear_tail(state);
+		drain_dac(state, file->f_flags & O_NONBLOCK);
+	}
+
+	/* stop DMA state machine and free DMA buffers/channels */
+	down(&state->open_sem);
+
+	if (file->f_mode & FMODE_WRITE) {
+		stop_dac(state);
+		dealloc_dmabuf(state);
+		state->card->free_pcm_channel(state->card, dmabuf->channel->num);
+	}
+	if (file->f_mode & FMODE_READ) {
+		stop_adc(state);
+		dealloc_dmabuf(state);
+		state->card->free_pcm_channel(state->card, dmabuf->channel->num);
+	}
+
+	free_page((unsigned long)state->dmabuf.pbuf);
+
+	/* we're covered by the open_sem */
+	up(&state->open_sem);
+	state->card->states[state->virt] = NULL;
+	state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
+
+	/* Now turn off external AMP if needed */
+	state->card->amplifier_ctrl(state->card, -1);
+	state->card->active_ctrl(state->card, -1);
+
+	kfree(state);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static /*const*/ struct file_operations cs461x_fops = {
+	llseek:		cs_llseek,
+	read:		cs_read,
+	write:		cs_write,
+	poll:		cs_poll,
+	ioctl:		cs_ioctl,
+	mmap:		cs_mmap,
+	open:		cs_open,
+	release:	cs_release,
+};
+
+/* Write AC97 codec registers */
+
+
+static u16 cs_ac97_get(struct ac97_codec *dev, u8 reg)
+{
+	struct cs_card *card = dev->private_data;
+	int count;
+	
+	/*
+	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+	 *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97 
+	 *  3. Write ACCTL = Control Register = 460h for initiating the write
+	 *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 17h
+	 *  5. if DCV not cleared, break and return error
+	 *  6. Read ACSTS = Status Register = 464h, check VSTS bit
+	 */
+
+
+	cs461x_peekBA0(card, BA0_ACSDA);
+
+	/*
+	 *  Setup the AC97 control registers on the CS461x to send the
+	 *  appropriate command to the AC97 to perform the read.
+	 *  ACCAD = Command Address Register = 46Ch
+	 *  ACCDA = Command Data Register = 470h
+	 *  ACCTL = Control Register = 460h
+	 *  set DCV - will clear when process completed
+	 *  set CRW - Read command
+	 *  set VFRM - valid frame enabled
+	 *  set ESYN - ASYNC generation enabled
+	 *  set RSTN - ARST# inactive, AC97 codec not reset
+	 */
+
+	cs461x_pokeBA0(card, BA0_ACCAD, reg);
+	cs461x_pokeBA0(card, BA0_ACCDA, 0);
+	cs461x_pokeBA0(card, BA0_ACCTL, ACCTL_DCV | ACCTL_CRW |
+					     ACCTL_VFRM | ACCTL_ESYN |
+					     ACCTL_RSTN);
+
+
+	/*
+	 *  Wait for the read to occur.
+	 */
+	for (count = 0; count < 500; count++) {
+		/*
+		 *  First, we want to wait for a short time.
+	 	 */
+		udelay(10);
+		/*
+		 *  Now, check to see if the read has completed.
+		 *  ACCTL = 460h, DCV should be reset by now and 460h = 17h
+		 */
+		if (!(cs461x_peekBA0(card, BA0_ACCTL) & ACCTL_DCV))
+			break;
+	}
+
+	/*
+	 *  Make sure the read completed.
+	 */
+	if (cs461x_peekBA0(card, BA0_ACCTL) & ACCTL_DCV) {
+		printk(KERN_WARNING "cs461x: AC'97 read problem (ACCTL_DCV), reg = 0x%x\n", reg);
+		return 0xffff;
+	}
+
+	/*
+	 *  Wait for the valid status bit to go active.
+	 */
+	for (count = 0; count < 100; count++) {
+		/*
+		 *  Read the AC97 status register.
+		 *  ACSTS = Status Register = 464h
+		 *  VSTS - Valid Status
+		 */
+		if (cs461x_peekBA0(card, BA0_ACSTS) & ACSTS_VSTS)
+			break;
+		udelay(10);
+	}
+	
+	/*
+	 *  Make sure we got valid status.
+	 */
+	if (!(cs461x_peekBA0(card, BA0_ACSTS) & ACSTS_VSTS)) {
+		printk(KERN_WARNING "cs461x: AC'97 read problem (ACSTS_VSTS), reg = 0x%x\n", reg);
+		return 0xffff;
+	}
+
+	/*
+	 *  Read the data returned from the AC97 register.
+	 *  ACSDA = Status Data Register = 474h
+	 */
+#if 0
+	printk("e) reg = 0x%x, val = 0x%x, BA0_ACCAD = 0x%x\n", reg,
+			cs461x_peekBA0(card, BA0_ACSDA),
+			cs461x_peekBA0(card, BA0_ACCAD));
+#endif
+	return cs461x_peekBA0(card, BA0_ACSDA);
+}
+
+/*
+ *	Do we have the CD potentially enabled either left or right ?
+ */
+ 
+static int cd_active(int r)
+{
+	int l=(r>>8)&0x7;
+	r&=7;
+	if(l==1 || r==1)
+		return 1;		/* CD input */
+	if(l==5 || r==5)
+		return 1;		/* Mixer input */
+	if(l==6 || r==6)
+		return 1;		/* Mixer 16bit input */
+	return 0;
+}
+
+static void cs_ac97_set(struct ac97_codec *dev, u8 reg, u16 val)
+{
+	struct cs_card *card = dev->private_data;
+	int count;
+	int val2;
+	int val3;
+	
+	if(reg==AC97_RECORD_SELECT || reg == AC97_CD_VOL)
+	{
+		val2 = cs_ac97_get(dev, AC97_RECORD_SELECT);
+		val3 = cs_ac97_get(dev, AC97_CD_VOL);
+	}
+	
+	/*
+	 *  1. Write ACCAD = Command Address Register = 46Ch for AC97 register address
+	 *  2. Write ACCDA = Command Data Register = 470h    for data to write to AC97
+	 *  3. Write ACCTL = Control Register = 460h for initiating the write
+	 *  4. Read ACCTL = 460h, DCV should be reset by now and 460h = 07h
+	 *  5. if DCV not cleared, break and return error
+	 */
+
+	/*
+	 *  Setup the AC97 control registers on the CS461x to send the
+	 *  appropriate command to the AC97 to perform the read.
+	 *  ACCAD = Command Address Register = 46Ch
+	 *  ACCDA = Command Data Register = 470h
+	 *  ACCTL = Control Register = 460h
+	 *  set DCV - will clear when process completed
+	 *  reset CRW - Write command
+	 *  set VFRM - valid frame enabled
+	 *  set ESYN - ASYNC generation enabled
+	 *  set RSTN - ARST# inactive, AC97 codec not reset
+         */
+	cs461x_pokeBA0(card, BA0_ACCAD, reg);
+	cs461x_pokeBA0(card, BA0_ACCDA, val);
+	cs461x_pokeBA0(card, BA0_ACCTL, ACCTL_DCV | ACCTL_VFRM |
+				             ACCTL_ESYN | ACCTL_RSTN);
+	for (count = 0; count < 1000; count++) {
+		/*
+		 *  First, we want to wait for a short time.
+		 */
+		udelay(10);
+		/*
+		 *  Now, check to see if the write has completed.
+		 *  ACCTL = 460h, DCV should be reset by now and 460h = 07h
+		 */
+		if (!(cs461x_peekBA0(card, BA0_ACCTL) & ACCTL_DCV))
+			break;
+	}
+	/*
+	 *  Make sure the write completed.
+	 */
+	if (cs461x_peekBA0(card, BA0_ACCTL) & ACCTL_DCV)
+		printk(KERN_WARNING "cs461x: AC'97 write problem, reg = 0x%x, val = 0x%x\n", reg, val);
+
+	/*
+	 *	Adjust power if the mixer is selected/deselected according
+	 *	to the CD.
+	 *
+	 *	IF the CD is a valid input source (mixer or direct) AND
+	 *		the CD is not muted THEN power is needed
+	 *
+	 *	We do two things. When record select changes the input to
+	 *	add/remove the CD we adjust the power count if the CD is
+	 *	unmuted.
+	 *
+	 *	When the CD mute changes we adjust the power level if the
+	 *	CD was a valid input.
+	 */
+	 
+	if(reg==AC97_RECORD_SELECT && cd_active(val)!=cd_active(val2))
+	{
+		int n=-1;
+		/* If we are turning on the port and it is not muted then
+		   bump the power level. If we are turning it off and its
+		   not muted drop the power level */
+		if(cd_active(val))
+			n=1;
+		if(!(val3 & 0x8000))
+			card->amplifier_ctrl(card, n);
+	}
+	
+	/* CD mute change ? */
+	
+	if(reg==AC97_CD_VOL)
+	{
+		if(cd_active(val2))
+		{
+			/* Mute bit change ? */
+			if((val3^val)&0x8000)
+			{
+				/* Mute on */
+				if(val&0x8000)
+					card->amplifier_ctrl(card, -1);
+				else /* Mute off power on */
+					card->amplifier_ctrl(card, 1);
+			}
+		}
+	}
+}
+
+
+/* OSS /dev/mixer file operation methods */
+
+static int cs_open_mixdev(struct inode *inode, struct file *file)
+{
+	int i;
+	int minor = MINOR(inode->i_rdev);
+	struct cs_card *card = devs;
+
+	for (card = devs; card != NULL; card = card->next)
+		for (i = 0; i < NR_AC97; i++)
+			if (card->ac97_codec[i] != NULL &&
+			    card->ac97_codec[i]->dev_mixer == minor)
+				goto match;
+
+	if (!card)
+		return -ENODEV;
+
+ match:
+	file->private_data = card->ac97_codec[i];
+
+	card->active_ctrl(card,1);
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+static int cs_release_mixdev(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct cs_card *card = devs;
+	int i;
+	
+	for (card = devs; card != NULL; card = card->next)
+		for (i = 0; i < NR_AC97; i++)
+			if (card->ac97_codec[i] != NULL &&
+			    card->ac97_codec[i]->dev_mixer == minor)
+				goto match;
+
+	if (!card)
+		return -ENODEV;
+match:
+	card->active_ctrl(card, -1);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static int cs_ioctl_mixdev(struct inode *inode, struct file *file, unsigned int cmd,
+				unsigned long arg)
+{
+	struct ac97_codec *codec = (struct ac97_codec *)file->private_data;
+
+	return codec->mixer_ioctl(codec, cmd, arg);
+}
+
+static /*const*/ struct file_operations cs_mixer_fops = {
+	llseek:		cs_llseek,
+	ioctl:		cs_ioctl_mixdev,
+	open:		cs_open_mixdev,
+	release:	cs_release_mixdev,
+};
+
+/* AC97 codec initialisation. */
+static int __init cs_ac97_init(struct cs_card *card)
+{
+	int num_ac97 = 0;
+	int ready_2nd = 0;
+	struct ac97_codec *codec;
+	u16 eid;
+
+	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
+		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
+			return -ENOMEM;
+		memset(codec, 0, sizeof(struct ac97_codec));
+
+		/* initialize some basic codec information, other fields will be filled
+		   in ac97_probe_codec */
+		codec->private_data = card;
+		codec->id = num_ac97;
+
+		codec->codec_read = cs_ac97_get;
+		codec->codec_write = cs_ac97_set;
+	
+		if (ac97_probe_codec(codec) == 0)
+			break;
+
+		eid = cs_ac97_get(codec, AC97_EXTENDED_ID);
+		
+		if(eid==0xFFFFFF)
+		{
+			printk(KERN_WARNING "cs461x: no codec attached ?\n");
+			kfree(codec);
+			break;
+		}
+		
+		card->ac97_features = eid;
+			
+		/* If the card has the CD enabled then bump the power to
+		   account for it */
+		   	
+		if(cd_active(cs_ac97_get(codec, AC97_RECORD_SELECT)))
+			card->amplifier_ctrl(card, 1);
+			
+		if ((codec->dev_mixer = register_sound_mixer(&cs_mixer_fops, -1)) < 0) {
+			printk(KERN_ERR "cs461x: couldn't register mixer!\n");
+			kfree(codec);
+			break;
+		}
+
+		card->ac97_codec[num_ac97] = codec;
+
+		/* if there is no secondary codec at all, don't probe any more */
+		if (!ready_2nd)
+			return num_ac97+1;
+	}
+	return num_ac97;
+}
+
+/* Boot the card
+ */
+ 
+static void cs461x_download(struct cs_card *card, u32 *src, unsigned long offset, unsigned long len)
+{
+	unsigned long counter;
+	void *dst;
+	
+	dst = card->ba1.idx[(offset>>16)&3];
+	dst += (offset&0xFFFF)<<2;
+	for(counter=0;counter<len;counter+=4)
+		writel(*src++, dst+counter);
+}
+
+/* 3*1024 parameter, 3.5*1024 sample, 2*3.5*1024 code */
+#define BA1_DWORD_SIZE		(13 * 1024 + 512)
+#define BA1_MEMORY_COUNT	3
+
+struct BA1struct {
+	struct {
+		unsigned long offset;
+		unsigned long size;
+	} memory[BA1_MEMORY_COUNT];
+	unsigned int map[BA1_DWORD_SIZE];
+};
+
+#include "cs461x_image.h"
+
+static void cs461x_download_image(struct cs_card *card)
+{
+	int idx;
+	unsigned long offset = 0;
+	
+	for (idx = 0; idx < BA1_MEMORY_COUNT; idx++) {
+		cs461x_download(card,&BA1Struct.map[offset],
+			       BA1Struct.memory[idx].offset,
+			       BA1Struct.memory[idx].size);
+		offset += BA1Struct.memory[idx].size >> 2;
+	}	
+}
+
+/*
+ *  Chip reset
+ */
+
+static void cs461x_reset(struct cs_card *card)
+{
+	int idx;
+
+	/*
+	 *  Write the reset bit of the SP control register.
+	 */
+	cs461x_poke(card, BA1_SPCR, SPCR_RSTSP);
+
+	/*
+	 *  Write the control register.
+	 */
+	cs461x_poke(card, BA1_SPCR, SPCR_DRQEN);
+
+	/*
+	 *  Clear the trap registers.
+	 */
+	for (idx = 0; idx < 8; idx++) {
+		cs461x_poke(card, BA1_DREG, DREG_REGID_TRAP_SELECT + idx);
+		cs461x_poke(card, BA1_TWPR, 0xFFFF);
+	}
+	cs461x_poke(card, BA1_DREG, 0);
+
+	/*
+	 *  Set the frame timer to reflect the number of cycles per frame.
+	 */
+	cs461x_poke(card, BA1_FRMT, 0xadf);
+}
+
+static void cs461x_clear_serial_FIFOs(struct cs_card *card)
+{
+	int idx, loop, powerdown = 0;
+	unsigned int tmp;
+
+	/*
+	 *  See if the devices are powered down.  If so, we must power them up first
+	 *  or they will not respond.
+	 */
+	if (!((tmp = cs461x_peekBA0(card, BA0_CLKCR1)) & CLKCR1_SWCE)) {
+		cs461x_pokeBA0(card, BA0_CLKCR1, tmp | CLKCR1_SWCE);
+		powerdown = 1;
+	}
+
+	/*
+	 *  We want to clear out the serial port FIFOs so we don't end up playing
+	 *  whatever random garbage happens to be in them.  We fill the sample FIFOS
+	 *  with zero (silence).
+         */
+	cs461x_pokeBA0(card, BA0_SERBWP, 0);
+
+	/*
+	 *  Fill all 256 sample FIFO locations.
+	 */
+	for (idx = 0; idx < 256; idx++) {
+		/*
+		 *  Make sure the previous FIFO write operation has completed.
+		 */
+		for (loop = 0; loop < 5; loop++) {
+			udelay(50);
+			if (!(cs461x_peekBA0(card, BA0_SERBST) & SERBST_WBSY))
+				break;
+		}
+		if (cs461x_peekBA0(card, BA0_SERBST) & SERBST_WBSY) {
+			if (powerdown)
+				cs461x_pokeBA0(card, BA0_CLKCR1, tmp);
+		}
+		/*
+		 *  Write the serial port FIFO index.
+		 */
+		cs461x_pokeBA0(card, BA0_SERBAD, idx);
+		/*
+		 *  Tell the serial port to load the new value into the FIFO location.
+		 */
+		cs461x_pokeBA0(card, BA0_SERBCM, SERBCM_WRC);
+	}
+	/*
+	 *  Now, if we powered up the devices, then power them back down again.
+	 *  This is kinda ugly, but should never happen.
+	 */
+	if (powerdown)
+		cs461x_pokeBA0(card, BA0_CLKCR1, tmp);
+}
+
+static void cs461x_powerup_dac(struct cs_card *card)
+{
+	int count;
+	unsigned int tmp;
+
+	/*
+	 *  Power on the DACs on the AC97 card.  We turn off the DAC
+	 *  powerdown bit and write the new value of the power control
+	 *  register.
+	 */
+	tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
+	if (tmp & 2)	/* already */
+		return;
+	cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp & 0xfdff);
+
+	/*
+	 *  Now, we wait until we sample a DAC ready state.
+	 */
+	for (count = 0; count < 32; count++) {
+		/*
+		 *  First, lets wait a short while to let things settle out a
+		 *  bit, and to prevent retrying the read too quickly.
+		 */
+		udelay(50);
+
+		/*
+		 *  Read the current state of the power control register.
+		 */
+		if (cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) & 2)
+			break;
+	}
+	
+	/*
+	 *  Check the status..
+	 */
+	if (!(cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) & 2))
+		printk(KERN_WARNING "cs461x: powerup DAC failed\n");
+}
+
+static void cs461x_powerup_adc(struct cs_card *card)
+{
+	int count;
+	unsigned int tmp;
+
+	/*
+	 *  Power on the ADCs on the AC97 card.  We turn off the DAC
+	 *  powerdown bit and write the new value of the power control
+	 *  register.
+	 */
+	tmp = cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL);
+	if (tmp & 1)	/* already */
+		return;
+	cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, tmp & 0xfeff);
+
+	/*
+	 *  Now, we wait until we sample a ADC ready state.
+	 */
+	for (count = 0; count < 32; count++) {
+		/*
+		 *  First, lets wait a short while to let things settle out a
+		 *  bit, and to prevent retrying the read too quickly.
+		 */
+		udelay(50);
+
+		/*
+		 *  Read the current state of the power control register.
+		 */
+		if (cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) & 1)
+			break;
+	}
+
+	/*
+	 *  Check the status..
+	 */
+	if (!(cs_ac97_get(card->ac97_codec[0], AC97_POWER_CONTROL) & 1))
+		printk(KERN_WARNING "cs461x: powerup ADC failed\n");
+}
+
+static void cs461x_proc_start(struct cs_card *card)
+{
+	int cnt;
+
+	/*
+	 *  Set the frame timer to reflect the number of cycles per frame.
+	 */
+	cs461x_poke(card, BA1_FRMT, 0xadf);
+	/*
+	 *  Turn on the run, run at frame, and DMA enable bits in the local copy of
+	 *  the SP control register.
+	 */
+	cs461x_poke(card, BA1_SPCR, SPCR_RUN | SPCR_RUNFR | SPCR_DRQEN);
+	/*
+	 *  Wait until the run at frame bit resets itself in the SP control
+	 *  register.
+	 */
+	for (cnt = 0; cnt < 25; cnt++) {
+		udelay(50);
+		if (!(cs461x_peek(card, BA1_SPCR) & SPCR_RUNFR))
+			break;
+	}
+
+	if (cs461x_peek(card, BA1_SPCR) & SPCR_RUNFR)
+		printk(KERN_WARNING "cs461x: SPCR_RUNFR never reset\n");
+}
+
+static void cs461x_proc_stop(struct cs_card *card)
+{
+	/*
+	 *  Turn off the run, run at frame, and DMA enable bits in the local copy of
+	 *  the SP control register.
+	 */
+	cs461x_poke(card, BA1_SPCR, 0);
+}
+
+
+
+static int cs_hardware_init(struct cs_card *card)
+{
+	unsigned long end_time;
+	unsigned int tmp;
+	
+	/* 
+	 *  First, blast the clock control register to zero so that the PLL starts
+         *  out in a known state, and blast the master serial port control register
+         *  to zero so that the serial ports also start out in a known state.
+         */
+        cs461x_pokeBA0(card, BA0_CLKCR1, 0);
+        cs461x_pokeBA0(card, BA0_SERMC1, 0);
+
+	/*
+	 *  If we are in AC97 mode, then we must set the part to a host controlled
+         *  AC-link.  Otherwise, we won't be able to bring up the link.
+         */        
+        cs461x_pokeBA0(card, BA0_SERACC, SERACC_HSP | SERACC_CODEC_TYPE_1_03);	/* 1.03 card */
+        /* cs461x_pokeBA0(card, BA0_SERACC, SERACC_HSP | SERACC_CODEC_TYPE_2_0); */ /* 2.00 card */
+
+        /*
+         *  Drive the ARST# pin low for a minimum of 1uS (as defined in the AC97
+         *  spec) and then drive it high.  This is done for non AC97 modes since
+         *  there might be logic external to the CS461x that uses the ARST# line
+         *  for a reset.
+         */
+        cs461x_pokeBA0(card, BA0_ACCTL, 0);
+        udelay(50);
+        cs461x_pokeBA0(card, BA0_ACCTL, ACCTL_RSTN);
+
+	/*
+	 *  The first thing we do here is to enable sync generation.  As soon
+	 *  as we start receiving bit clock, we'll start producing the SYNC
+	 *  signal.
+	 */
+	cs461x_pokeBA0(card, BA0_ACCTL, ACCTL_ESYN | ACCTL_RSTN);
+
+	/*
+	 *  Now wait for a short while to allow the AC97 part to start
+	 *  generating bit clock (so we don't try to start the PLL without an
+	 *  input clock).
+	 */
+	mdelay(5);		/* 1 should be enough ?? */
+
+	/*
+	 *  Set the serial port timing configuration, so that
+	 *  the clock control circuit gets its clock from the correct place.
+	 */
+	cs461x_pokeBA0(card, BA0_SERMC1, SERMC1_PTC_AC97);
+
+	/*
+	 *  Write the selected clock control setup to the hardware.  Do not turn on
+	 *  SWCE yet (if requested), so that the devices clocked by the output of
+	 *  PLL are not clocked until the PLL is stable.
+	 */
+	cs461x_pokeBA0(card, BA0_PLLCC, PLLCC_LPF_1050_2780_KHZ | PLLCC_CDR_73_104_MHZ);
+	cs461x_pokeBA0(card, BA0_PLLM, 0x3a);
+	cs461x_pokeBA0(card, BA0_CLKCR2, CLKCR2_PDIVS_8);
+
+	/*
+	 *  Power up the PLL.
+	 */
+	cs461x_pokeBA0(card, BA0_CLKCR1, CLKCR1_PLLP);
+
+	/*
+         *  Wait until the PLL has stabilized.
+	 */
+	mdelay(5);		/* Again 1 should be enough ?? */
+
+	/*
+	 *  Turn on clocking of the core so that we can setup the serial ports.
+	 */
+	tmp = cs461x_peekBA0(card, BA0_CLKCR1) | CLKCR1_SWCE;
+	cs461x_pokeBA0(card, BA0_CLKCR1, tmp);
+
+	/*
+	 *  Fill the serial port FIFOs with silence.
+	 */
+	cs461x_clear_serial_FIFOs(card);
+
+	/*
+	 *  Set the serial port FIFO pointer to the first sample in the FIFO.
+	 */
+	/* cs461x_pokeBA0(card, BA0_SERBSP, 0); */
+
+	/*
+	 *  Write the serial port configuration to the part.  The master
+	 *  enable bit is not set until all other values have been written.
+	 */
+	cs461x_pokeBA0(card, BA0_SERC1, SERC1_SO1F_AC97 | SERC1_SO1EN);
+	cs461x_pokeBA0(card, BA0_SERC2, SERC2_SI1F_AC97 | SERC1_SO1EN);
+	cs461x_pokeBA0(card, BA0_SERMC1, SERMC1_PTC_AC97 | SERMC1_MSPE);
+
+
+	mdelay(5);		/* Shouldnt be needed ?? */
+	
+	/*
+	 * Wait for the card ready signal from the AC97 card.
+	 */
+	end_time = jiffies + 3 * (HZ >> 2);
+	do {
+		/*
+		 *  Read the AC97 status register to see if we've seen a CODEC READY
+		 *  signal from the AC97 card.
+		 */
+		if (cs461x_peekBA0(card, BA0_ACSTS) & ACSTS_CRDY)
+			break;
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout(1);
+	} while (time_before(jiffies, end_time));
+
+	/*
+	 *  Make sure CODEC is READY.
+	 */
+	if (!(cs461x_peekBA0(card, BA0_ACSTS) & ACSTS_CRDY)) {
+		printk(KERN_WARNING "cs461x: create - never read card ready from AC'97\n");
+		printk(KERN_WARNING "cs461x: it is probably not a bug, try using the CS4232 driver\n");
+		return -EIO;
+	}
+
+	/*
+	 *  Assert the vaid frame signal so that we can start sending commands
+	 *  to the AC97 card.
+	 */
+	cs461x_pokeBA0(card, BA0_ACCTL, ACCTL_VFRM | ACCTL_ESYN | ACCTL_RSTN);
+
+	/*
+	 *  Wait until we've sampled input slots 3 and 4 as valid, meaning that
+	 *  the card is pumping ADC data across the AC-link.
+	 */
+	end_time = jiffies + 3 * (HZ >> 2);
+	do {
+		/*
+		 *  Read the input slot valid register and see if input slots 3 and
+		 *  4 are valid yet.
+		 */
+		if ((cs461x_peekBA0(card, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) == (ACISV_ISV3 | ACISV_ISV4))
+			break;
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout(1);
+	} while (time_before(jiffies, end_time));
+
+	/*
+	 *  Make sure input slots 3 and 4 are valid.  If not, then return
+	 *  an error.
+	 */
+	if ((cs461x_peekBA0(card, BA0_ACISV) & (ACISV_ISV3 | ACISV_ISV4)) != (ACISV_ISV3 | ACISV_ISV4)) {
+		printk(KERN_WARNING "cs461x: create - never read ISV3 & ISV4 from AC'97\n");
+		return -EIO;
+	}
+
+	/*
+	 *  Now, assert valid frame and the slot 3 and 4 valid bits.  This will
+	 *  commense the transfer of digital audio data to the AC97 card.
+	 */
+	cs461x_pokeBA0(card, BA0_ACOSV, ACOSV_SLV3 | ACOSV_SLV4);
+
+	/*
+	 *  Power down the DAC and ADC.  We will power them up (if) when we need
+	 *  them.
+	 */
+	/* cs461x_pokeBA0(card, BA0_AC97_POWERDOWN, 0x300); */
+
+	/*
+	 *  Turn off the Processor by turning off the software clock enable flag in 
+	 *  the clock control register.
+	 */
+	/* tmp = cs461x_peekBA0(card, BA0_CLKCR1) & ~CLKCR1_SWCE; */
+	/* cs461x_pokeBA0(card, BA0_CLKCR1, tmp); */
+
+	/*
+         *  Reset the processor.
+         */
+	cs461x_reset(card);
+
+	/*
+         *  Download the image to the processor.
+	 */
+	
+	cs461x_download_image(card);
+
+	/*
+         *  Stop playback DMA.
+	 */
+	tmp = cs461x_peek(card, BA1_PCTL);
+	card->pctl = tmp & 0xffff0000;
+	cs461x_poke(card, BA1_PCTL, tmp & 0x0000ffff);
+
+	/*
+         *  Stop capture DMA.
+	 */
+	tmp = cs461x_peek(card, BA1_CCTL);
+	card->cctl = tmp & 0x0000ffff;
+	cs461x_poke(card, BA1_CCTL, tmp & 0xffff0000);
+
+	/* initialize AC97 codec and register /dev/mixer */
+	if (cs_ac97_init(card) <= 0)
+		return -EIO;
+		
+	mdelay(5);		/* Do we need this ?? */
+	
+	cs461x_powerup_adc(card);
+	cs461x_powerup_dac(card);
+
+	cs461x_proc_start(card);
+
+	/*
+	 *  Enable interrupts on the part.
+	 */
+	cs461x_pokeBA0(card, BA0_HICR, HICR_IEV | HICR_CHGM);
+
+	tmp = cs461x_peek(card, BA1_PFIE);
+	tmp &= ~0x0000f03f;
+	cs461x_poke(card, BA1_PFIE, tmp);	/* playback interrupt enable */
+
+	tmp = cs461x_peek(card, BA1_CIE);
+	tmp &= ~0x0000003f;
+	tmp |=  0x00000001;
+	cs461x_poke(card, BA1_CIE, tmp);	/* capture interrupt enable */	
+	return 0;
+}
+
+/* install the driver, we do not allocate hardware channel nor DMA buffer now, they are defered 
+   untill "ACCESS" time (in prog_dmabuf called by open/read/write/ioctl/mmap) */
+   
+   
+/*
+ *	Card subid table
+ */
+ 
+struct cs_card_type
+{
+	u16 vendor;
+	u16 id;
+	char *name;
+	void (*amp)(struct cs_card *, int);
+	void (*active)(struct cs_card *, int);
+};
+
+static struct cs_card_type __init cards[]={
+	{0x1489, 0x7001, "Genius Soundmaker 128 value", amp_none, NULL},
+	{0x5053, 0x3357, "Voyetra", amp_voyetra, NULL},
+	/* Not sure if the 570 needs the clkrun hack */
+	{PCI_VENDOR_ID_IBM, 0x0132, "Thinkpad 570", amp_none, clkrun_hack},
+	{PCI_VENDOR_ID_IBM, 0x0153, "Thinkpad 600X/A20/T20", amp_none, clkrun_hack},
+	{PCI_VENDOR_ID_IBM, 0x1010, "Thinkpad 600E (unsupported)", NULL, NULL},
+	{0, 0, NULL, NULL}
+};
+
+static int __init cs_install(struct pci_dev *pci_dev)
+{
+	struct cs_card *card;
+	struct cs_card_type *cp = &cards[0];
+	u16 ss_card, ss_vendor;
+	
+	
+	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_VENDOR_ID, &ss_vendor);
+	pci_read_config_word(pci_dev, PCI_SUBSYSTEM_ID, &ss_card);
+
+	if ((card = kmalloc(sizeof(struct cs_card), GFP_KERNEL)) == NULL) {
+		printk(KERN_ERR "cs461x: out of memory\n");
+		return -ENOMEM;
+	}
+	memset(card, 0, sizeof(*card));
+
+	card->ba0_addr = pci_dev->base_address[0]&PCI_BASE_ADDRESS_MEM_MASK;
+	card->ba1_addr = pci_dev->base_address[1]&PCI_BASE_ADDRESS_MEM_MASK;
+	card->pci_dev = pci_dev;
+	card->irq = pci_dev->irq;
+	card->magic = CS_CARD_MAGIC;
+	spin_lock_init(&card->lock);
+
+	pci_set_master(pci_dev);
+
+	printk(KERN_INFO "cs461x: Card found at 0x%08lx and 0x%08lx, IRQ %d\n",
+	       card->ba0_addr, card->ba1_addr, card->irq);
+
+	card->alloc_pcm_channel = cs_alloc_pcm_channel;
+	card->alloc_rec_pcm_channel = cs_alloc_rec_pcm_channel;
+	card->free_pcm_channel = cs_free_pcm_channel;
+	card->amplifier_ctrl = amp_none;
+	card->active_ctrl = amp_none;
+	
+	while(cp->name)
+	{
+		if(cp->vendor == ss_vendor && cp->id == ss_card)
+		{
+			card->amplifier_ctrl = cp->amp;
+			if(cp->active)
+				card->active_ctrl = cp->active;
+			break;
+		}
+		cp++;
+	}
+	if(cp->name==NULL)
+	{
+		printk(KERN_INFO "cs461x: Unknown card (%04X:%04X) at 0x%08lx/0x%08lx, IRQ %d\n",
+			ss_vendor, ss_card, card->ba0_addr, card->ba1_addr,  card->irq);
+	}
+	else
+	{
+		printk(KERN_INFO "cs461x: %s at 0x%08lx/0x%08lx, IRQ %d\n",
+			cp->name, card->ba0_addr, card->ba1_addr, card->irq);
+	}
+	
+	if(card->amplifier_ctrl==NULL)
+	{
+		printk(KERN_ERR "cs461x: Unsupported configuration due to lack of documentation.\n");
+		kfree(card);
+		return -EINVAL;
+	}		
+		       
+	if(external_amp == 1)
+	{
+		printk(KERN_INFO "cs461x: Crystal EAPD support forced on.\n");
+		card->amplifier_ctrl = amp_voyetra;
+	}
+
+	if(thinkpad == 1)
+	{
+		card->active_ctrl = clkrun_hack;
+		printk(KERN_INFO "cs461x: Activating CLKRUN hack for Thinkpad.\n");
+	}
+	
+	card->active_ctrl(card, 1);
+	
+	/* claim our iospace and irq */
+	
+	card->ba0 = ioremap(card->ba0_addr, CS461X_BA0_SIZE);
+	card->ba1.name.data0 = ioremap(card->ba1_addr + BA1_SP_DMEM0, CS461X_BA1_DATA0_SIZE);
+	card->ba1.name.data1 = ioremap(card->ba1_addr + BA1_SP_DMEM1, CS461X_BA1_DATA1_SIZE);
+	card->ba1.name.pmem = ioremap(card->ba1_addr + BA1_SP_PMEM, CS461X_BA1_PRG_SIZE);
+	card->ba1.name.reg = ioremap(card->ba1_addr + BA1_SP_REG, CS461X_BA1_REG_SIZE);
+	
+	if(card->ba0 == 0 || card->ba1.name.data0 == 0 ||
+		card->ba1.name.data1 == 0 || card->ba1.name.pmem == 0 ||
+		card->ba1.name.reg == 0)
+		goto fail2;
+		
+	if (request_irq(card->irq, &cs_interrupt, SA_SHIRQ, "cs461x", card)) {
+		printk(KERN_ERR "cs461x: unable to allocate irq %d\n", card->irq);
+		goto fail2;
+	}
+	/* register /dev/dsp */
+	if ((card->dev_audio = register_sound_dsp(&cs461x_fops, -1)) < 0) {
+		printk(KERN_ERR "cs461x: unable to register dsp\n");
+		goto fail;
+	}
+
+	if (cs_hardware_init(card)<0)
+	{
+		unregister_sound_dsp(card->dev_audio);
+		goto fail;
+	}
+	card->next = devs;
+	devs = card;
+	
+	card->active_ctrl(card, -1);
+	return 0;
+	
+fail:
+	free_irq(card->irq, card);
+fail2:
+	if(card->ba0)
+		iounmap(card->ba0);
+	if(card->ba1.name.data0)
+		iounmap(card->ba1.name.data0);
+	if(card->ba1.name.data1)
+		iounmap(card->ba1.name.data1);
+	if(card->ba1.name.pmem)
+		iounmap(card->ba1.name.pmem);
+	if(card->ba1.name.reg)
+		iounmap(card->ba1.name.reg);
+	kfree(card);
+	return -ENODEV;
+
+}
+
+static void cs_remove(struct cs_card *card)
+{
+	int i;
+	unsigned int tmp;
+	
+	card->active_ctrl(card,1);
+	
+	tmp = cs461x_peek(card, BA1_PFIE);
+	tmp &= ~0x0000f03f;
+	tmp |=  0x00000010;
+	cs461x_poke(card, BA1_PFIE, tmp);	/* playback interrupt disable */
+
+	tmp = cs461x_peek(card, BA1_CIE);
+	tmp &= ~0x0000003f;
+	tmp |=  0x00000011;
+	cs461x_poke(card, BA1_CIE, tmp);	/* capture interrupt disable */
+
+	/*
+         *  Stop playback DMA.
+	 */
+	tmp = cs461x_peek(card, BA1_PCTL);
+	cs461x_poke(card, BA1_PCTL, tmp & 0x0000ffff);
+
+	/*
+         *  Stop capture DMA.
+	 */
+	tmp = cs461x_peek(card, BA1_CCTL);
+	cs461x_poke(card, BA1_CCTL, tmp & 0xffff0000);
+
+	/*
+         *  Reset the processor.
+         */
+	cs461x_reset(card);
+
+	cs461x_proc_stop(card);
+
+	/*
+	 *  Power down the DAC and ADC.  We will power them up (if) when we need
+	 *  them.
+	 */
+	cs_ac97_set(card->ac97_codec[0], AC97_POWER_CONTROL, 0x300);
+
+	/*
+	 *  Power down the PLL.
+	 */
+	cs461x_pokeBA0(card, BA0_CLKCR1, 0);
+
+	/*
+	 *  Turn off the Processor by turning off the software clock enable flag in 
+	 *  the clock control register.
+	 */
+	tmp = cs461x_peekBA0(card, BA0_CLKCR1) & ~CLKCR1_SWCE;
+	cs461x_pokeBA0(card, BA0_CLKCR1, tmp);
+
+	card->active_ctrl(card,-1);
+
+	/* free hardware resources */
+	free_irq(card->irq, card);
+	iounmap(card->ba0);
+	iounmap(card->ba1.name.data0);
+	iounmap(card->ba1.name.data1);
+	iounmap(card->ba1.name.pmem);
+	iounmap(card->ba1.name.reg);
+	
+	/* unregister audio devices */
+	for (i = 0; i < NR_AC97; i++)
+		if (card->ac97_codec[i] != NULL) {
+			unregister_sound_mixer(card->ac97_codec[i]->dev_mixer);
+			kfree (card->ac97_codec[i]);
+		}
+	unregister_sound_dsp(card->dev_audio);
+	kfree(card);
+}
+
+MODULE_AUTHOR("Alan Cox <alan@redhat.com>, Jaroslav Kysela");
+MODULE_DESCRIPTION("Crystal SoundFusion Audio Support");
+
+int __init cs_probe(void)
+{
+	struct pci_dev *pcidev = NULL;
+	int foundone=0;
+	
+	if (!pci_present())   /* No PCI bus in this machine! */
+		return -ENODEV;
+		
+	printk(KERN_INFO "Crystal 4280/461x + AC97 Audio, version "
+	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
+
+	while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6001 , pcidev))!=NULL ) {
+		if (cs_install(pcidev)==0)
+			foundone++;
+	}
+	while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6003 , pcidev))!=NULL ) {
+		if (cs_install(pcidev)==0)
+			foundone++;
+	}
+	while( (pcidev = pci_find_device(PCI_VENDOR_ID_CIRRUS, 0x6004 , pcidev))!=NULL ) {
+		if (cs_install(pcidev)==0)
+			foundone++;
+	}
+
+	printk(KERN_INFO "cs461x: Found %d audio device(s).\n",
+		foundone);
+	return foundone;
+}
+
+#ifdef MODULE
+
+int init_module(void)
+{
+	if(cs_probe()==0)
+		printk(KERN_ERR "cs461x: No devices found.\n");
+	return 0;
+}
+
+void cleanup_module (void)
+{
+	struct cs_card *next;
+	while(devs)
+	{
+		next=devs->next;
+		cs_remove(devs);
+		devs=next;
+	}
+}
+
+MODULE_PARM(external_amp, "i");
+MODULE_PARM(thinkpad, "i");
+
+#endif
\ No newline at end of file
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/dmasound.c linux.17p18/drivers/sound/dmasound.c
--- linux.vanilla/drivers/sound/dmasound.c	Fri Apr 21 12:46:34 2000
+++ linux.17p18/drivers/sound/dmasound.c	Tue Aug  1 07:59:57 2000
@@ -115,6 +115,7 @@
 #include <asm/adb.h>
 #include <asm/cuda.h>
 #include <asm/pmu.h>
+#include <asm/feature.h>
 #include "awacs_defs.h"
 #include <linux/nvram.h>
 #include <linux/vt_kern.h>
@@ -175,6 +176,7 @@
 static int awacs_rate_index;
 static int awacs_subframe;
 static int awacs_spkr_vol;
+static struct device_node* awacs_node;
 
 static int awacs_revision;
 #define AWACS_BURGUNDY	100		/* fake revision # for burgundy */
@@ -3018,6 +3020,12 @@
 	out_le32(&awacs_txdma->control, RUN<<16);
 	/* disable interrupts from awacs interface */
 	out_le32(&awacs->control, in_le32(&awacs->control) & 0xfff);
+#ifdef CONFIG_PMAC_PBOOK
+	if (is_pbook_G3) {
+		feature_clear(awacs_node, FEATURE_Sound_power);
+		feature_clear(awacs_node, FEATURE_Sound_CLK_enable);
+	}
+#endif
 	free_irq(awacs_irq, (void *) awacs);
 	free_irq(awacs_tx_irq, (void *) awacs);
 	kfree(awacs_tx_cmd_space);
@@ -3370,8 +3378,21 @@
 		PMacSilence();
 		disable_irq(awacs_irq);
 		disable_irq(awacs_tx_irq);
+		feature_clear(awacs_node, FEATURE_Sound_CLK_enable);
+		feature_clear(awacs_node, FEATURE_Sound_power);
 		break;
 	case PBOOK_WAKE:
+		/* There is still a problem on wake. Sound seems to work fine
+		   if I launch mpg123 and resumes fine if mpg123 was playing,
+		   but the console beep is dead until I do something with the
+		   mixer. Probably yet another timing issue */
+		if (!feature_test(awacs_node, FEATURE_Sound_CLK_enable)
+		    || !feature_test(awacs_node, FEATURE_Sound_power)) {
+			/* these aren't present on the 3400 AFAIK -- paulus */
+			feature_set(awacs_node, FEATURE_Sound_CLK_enable);
+			feature_set(awacs_node, FEATURE_Sound_power);
+			mdelay(1000);
+		}
 		out_le32(&awacs->control, MASK_IEPC
 			 | (awacs_rate_index << 8) | 0x11
 			 | (awacs_revision < AWACS_BURGUNDY? MASK_IEE: 0));
@@ -3388,6 +3409,16 @@
 			mdelay(2);
 			awacs_write(awacs_reg[1] | MASK_ADDR1);
 		}
+		/* enable CD sound input */
+		if (macio_base && is_pbook_G3) {
+			out_8(macio_base + 0x37, 3);
+		} else if (is_pbook_3400) {
+			feature_set(awacs_node, FEATURE_IOBUS_enable);
+			udelay(10);
+			in_8((unsigned char *)0xf301a190);
+		}
+ 		/* Resume pending sounds. Paul, Is this wrong ? */
+ 		PMacPlay();
 	}
 	return PBOOK_SLEEP_OK;
 }
@@ -4596,6 +4627,7 @@
 	u_long fmt;
 	int data;
 	int size, nbufs;
+	audio_buf_info info;
 
 	switch (cmd) {
 	case SNDCTL_DSP_RESET:
@@ -4671,6 +4703,14 @@
 		sq_setup(numBufs, size, sound_buffers);
 		sq.max_active = nbufs;
 		return 0;
+	case SNDCTL_DSP_GETOSPACE:
+		info.fragments = sq.max_active - sq.count;
+		info.fragstotal = sq.max_active;
+		info.fragsize = sq.block_size;
+		info.bytes = info.fragments * info.fragsize;
+		if (copy_to_user((void *)arg, &info, sizeof(info)))
+			return -EFAULT;
+		return 0;
 
 	default:
 		return mixer_ioctl(inode, file, cmd, arg);
@@ -4777,7 +4817,9 @@
 #endif /* CONFIG_AMIGA */
 #ifdef CONFIG_PPC
 	case DMASND_AWACS:
-		sprintf(mach, "PowerMac (AWACS rev %d) ", awacs_revision);
+		/* BenH: This one used to sprintf in mach which doesn't point to
+		 * a large enough buffer */
+		len += sprintf(buffer+len, "PowerMac (AWACS rev %d) ", awacs_revision);
 		break;
 #endif /* CONFIG_PPC */
 	}
@@ -5022,6 +5064,16 @@
 			printk(KERN_ERR "DMA sound driver: Not enough buffer memory, driver disabled!\n");
 			return;
 		}
+		awacs_node = np;
+#ifdef CONFIG_PMAC_PBOOK
+		if (machine_is_compatible("PowerBook1,1")
+		    || machine_is_compatible("AAPL,PowerBook1998")) {
+			feature_set(np, FEATURE_Sound_CLK_enable);
+			feature_set(np, FEATURE_Sound_power);
+			/* Shorter delay will not work */
+			mdelay(1000);
+		}
+#endif
 		awacs_tx_cmds = (volatile struct dbdma_cmd *)
 			DBDMA_ALIGN(awacs_tx_cmd_space);
 		awacs_reg[0] = MASK_MUX_CD;
@@ -5041,7 +5093,10 @@
 			awacs_revision =
 				(in_le32(&awacs->codec_stat) >> 12) & 0xf;
 			if (awacs_revision == 3) {
+				mdelay(100);
 				awacs_write(0x6000);
+				mdelay(2);
+				awacs_write(awacs_reg[1] + MASK_ADDR1);
 				awacs_enable_amp(100 * 0x101);
 			}
 		}
@@ -5063,27 +5118,35 @@
 		/* Powerbooks have odd ways of enabling inputs such as
 		   an expansion-bay CD or sound from an internal modem
 		   or a PC-card modem. */
-		if (machine_is_compatible("AAPL,3400/2400")) {
+		if (machine_is_compatible("AAPL,3400/2400")
+			|| machine_is_compatible("AAPL,3500")) {
 			is_pbook_3400 = 1;
 			/*
 			 * Enable CD and PC-card sound inputs.
 			 * This is done by reading from address
 			 * f301a000, + 0x10 to enable the expansion-bay
 			 * CD sound input, + 0x80 to enable the PC-card
-			 * sound input.  The 0x100 seems to enable the
-			 * MESH and/or its SCSI bus drivers.
+			 * sound input.  The 0x100 enables the SCSI bus
+			 * terminator power.
 			 */
 			in_8((unsigned char *)0xf301a190);
-		} else if (machine_is_compatible("PowerBook1,1")) {
-			np = find_devices("mac-io");
-			if (np && np->n_addrs > 0) {
-				is_pbook_G3 = 1;
-				macio_base = (unsigned char *)
-					ioremap(np->addrs[0].address, 0x40);
-				/* enable CD sound input */
-				out_8(macio_base + 0x37, 3);
+		} else if (machine_is_compatible("PowerBook1,1")
+			   || machine_is_compatible("AAPL,PowerBook1998")) {
+			struct device_node* mio;
+			macio_base = 0;
+			is_pbook_G3 = 1;
+			for (mio = np->parent; mio; mio = mio->parent) {
+				if (strcmp(mio->name, "mac-io") == 0
+				    && mio->n_addrs > 0) {
+					macio_base = (unsigned char *) ioremap
+						(mio->addrs[0].address, 0x40);
+					break;
+				}
 			}
-		}
+			/* enable CD sound input */
+			if (macio_base)
+				out_8(macio_base + 0x37, 3);
+ 		}
 	}
 #endif /* CONFIG_PPC */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/8010.h linux.17p18/drivers/sound/emu10k1/8010.h
--- linux.vanilla/drivers/sound/emu10k1/8010.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/8010.h	Tue Aug  1 18:30:11 2000
@@ -0,0 +1,664 @@
+/*
+ **********************************************************************
+ *     8010.h
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date		    Author	    Summary of changes
+ *     ----		    ------	    ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox	    Cleaned of 8bit chars, DOS
+ *					    line endings
+ *     December 8, 1999     Jon Taylor	    Added lots of new register info
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ *
+ **********************************************************************
+ */
+
+
+#ifndef _8010_H
+#define _8010_H
+
+#include <linux/types.h>
+
+/* ------------------- DEFINES -------------------- */
+
+#define CMD_WRITEFN0	0x0
+#define CMD_READFN0	0x1
+#define CMD_WRITEPTR	0x2
+#define CMD_READPTR	0x3
+
+struct mixer_private_ioctl {
+	u32 cmd;
+	u32 val[10];
+};
+
+/************************************************************************************************/
+/* PCI function 0 registers, address = <val> + PCIBASE0						*/
+/************************************************************************************************/
+
+#define PTR			0x00		/* Indexed register set pointer register	*/
+						/* NOTE: The CHANNELNUM and ADDRESS words can	*/
+						/* be modified independently of each other.	*/
+#define PTR_CHANNELNUM_MASK	0x0000003f	/* For each per-channel register, indicates the	*/
+						/* channel number of the register to be		*/
+						/* accessed.  For non per-channel registers the	*/
+						/* value should be set to zero.			*/
+#define PTR_ADDRESS_MASK	0x07ff0000	/* Register index				*/
+
+#define DATA			0x04		/* Indexed register set data register		*/
+
+#define IPR			0x08		/* Global interrupt pending register		*/
+						/* Clear pending interrupts by writing a 1 to	*/
+						/* the relevant bits and zero to the other bits	*/
+#define IPR_SAMPLERATETRACKER	0x01000000	/* Sample rate tracker lock status change	*/
+#define IPR_FXDSP		0x00800000	/* Enable FX DSP interrupts			*/
+#define IPR_FORCEINT		0x00400000	/* Force Sound Blaster interrupt		*/
+#define IPR_PCIERROR		0x00200000	/* PCI bus error				*/
+#define IPR_VOLINCR		0x00100000	/* Volume increment button pressed		*/
+#define IPR_VOLDECR		0x00080000	/* Volume decrement button pressed		*/
+#define IPR_MUTE		0x00040000	/* Mute button pressed				*/
+#define IPR_MICBUFFULL		0x00020000	/* Microphone buffer full			*/
+#define IPR_MICBUFHALFFULL	0x00010000	/* Microphone buffer half full			*/
+#define IPR_ADCBUFFULL		0x00008000	/* ADC buffer full				*/
+#define IPR_ADCBUFHALFFULL	0x00004000	/* ADC buffer half full				*/
+#define IPR_EFXBUFFULL		0x00002000	/* Effects buffer full				*/
+#define IPR_EFXBUFHALFFULL	0x00001000	/* Effects buffer half full			*/
+#define IPR_GPSPDIFSTATUSCHANGE	0x00000800	/* GPSPDIF channel status change		*/
+#define IPR_CDROMSTATUSCHANGE	0x00000400	/* CD-ROM channel status change			*/
+#define IPR_INTERVALTIMER	0x00000200	/* Interval timer terminal count		*/
+#define IPR_MIDITRANSBUFEMPTY	0x00000100	/* MIDI UART transmit buffer empty		*/
+#define IPR_MIDIRECVBUFEMPTY	0x00000080	/* MIDI UART receive buffer empty		*/
+#define IPR_CHANNELLOOP		0x00000040	/* One or more channel loop interrupts pending	*/
+#define IPR_CHANNELNUMBERMASK	0x0000003f	/* When IPR_CHANNELLOOP is set, indicates the	*/
+						/* Highest set channel in CLIPL or CLIPH.  When	*/
+						/* IP is written with CL set, the bit in CLIPL	*/
+						/* or CLIPH corresponding to the CIN value 	*/
+						/* written will be cleared.			*/
+
+#define INTE			0x0c		/* Interrupt enable register			*/
+#define INTE_VIRTUALSB_MASK	0xc0000000	/* Virtual Soundblaster I/O port capture	*/
+#define INTE_VIRTUALSB_220	0x00000000	/* Capture at I/O base address 0x220-0x22f	*/
+#define INTE_VIRTUALSB_240	0x40000000	/* Capture at I/O base address 0x240		*/
+#define INTE_VIRTUALSB_260	0x80000000	/* Capture at I/O base address 0x260		*/
+#define INTE_VIRTUALSB_280	0xc0000000	/* Capture at I/O base address 0x280		*/
+#define INTE_VIRTUALMPU_MASK	0x30000000	/* Virtual MPU I/O port capture			*/
+#define INTE_VIRTUALMPU_300	0x00000000	/* Capture at I/O base address 0x300-0x301	*/
+#define INTE_VIRTUALMPU_310	0x10000000	/* Capture at I/O base address 0x310		*/
+#define INTE_VIRTUALMPU_320	0x20000000	/* Capture at I/O base address 0x320		*/
+#define INTE_VIRTUALMPU_330	0x30000000	/* Capture at I/O base address 0x330		*/
+#define INTE_MASTERDMAENABLE	0x08000000	/* Master DMA emulation at 0x000-0x00f		*/
+#define INTE_SLAVEDMAENABLE	0x04000000	/* Slave DMA emulation at 0x0c0-0x0df		*/
+#define INTE_MASTERPICENABLE	0x02000000	/* Master PIC emulation at 0x020-0x021		*/
+#define INTE_SLAVEPICENABLE	0x01000000	/* Slave PIC emulation at 0x0a0-0x0a1		*/
+#define INTE_VSBENABLE		0x00800000	/* Enable virtual Soundblaster			*/
+#define INTE_ADLIBENABLE	0x00400000	/* Enable AdLib emulation at 0x388-0x38b	*/
+#define INTE_MPUENABLE		0x00200000	/* Enable virtual MPU				*/
+#define INTE_FORCEINT		0x00100000	/* Continuously assert INTAN			*/
+
+#define INTE_MRHANDENABLE	0x00080000	/* Enable the "Mr. Hand" logic			*/
+						/* NOTE: There is no reason to use this under	*/
+						/* Linux, and it will cause odd hardware 	*/
+						/* behavior and possibly random segfaults and	*/
+						/* lockups if enabled.				*/
+
+#define INTE_SAMPLERATETRACKER	0x00002000	/* Enable sample rate tracker interrupts	*/
+						/* NOTE: This bit must always be enabled       	*/
+#define INTE_FXDSPENABLE	0x00001000	/* Enable FX DSP interrupts			*/
+#define INTE_PCIERRORENABLE	0x00000800	/* Enable PCI bus error interrupts		*/
+#define INTE_VOLINCRENABLE	0x00000400	/* Enable volume increment button interrupts	*/
+#define INTE_VOLDECRENABLE	0x00000200	/* Enable volume decrement button interrupts	*/
+#define INTE_MUTEENABLE		0x00000100	/* Enable mute button interrupts		*/
+#define INTE_MICBUFENABLE	0x00000080	/* Enable microphone buffer interrupts		*/
+#define INTE_ADCBUFENABLE	0x00000040	/* Enable ADC buffer interrupts			*/
+#define INTE_EFXBUFENABLE	0x00000020	/* Enable Effects buffer interrupts		*/
+#define INTE_GPSPDIFENABLE	0x00000010	/* Enable GPSPDIF status interrupts		*/
+#define INTE_CDSPDIFENABLE	0x00000008	/* Enable CDSPDIF status interrupts		*/
+#define INTE_INTERVALTIMERENB	0x00000004	/* Enable interval timer interrupts		*/
+#define INTE_MIDITXENABLE	0x00000002	/* Enable MIDI transmit-buffer-empty interrupts	*/
+#define INTE_MIDIRXENABLE	0x00000001	/* Enable MIDI receive-buffer-empty interrupts	*/
+
+#define WC			0x10		/* Wall Clock register				*/
+#define WC_SAMPLECOUNTER_MASK	0x03FFFFC0	/* Sample periods elapsed since reset		*/
+#define WC_SAMPLECOUNTER	0x14060010
+#define WC_CURRENTCHANNEL	0x0000003F	/* Channel [0..63] currently being serviced	*/
+						/* NOTE: Each channel takes 1/64th of a sample	*/
+						/* period to be serviced.			*/
+
+#define HCFG			0x14		/* Hardware config register			*/
+						/* NOTE: There is no reason to use the legacy	*/
+						/* SoundBlaster emulation stuff described below	*/
+						/* under Linux, and all kinds of weird hardware	*/
+						/* behavior can result if you try.  Don't.	*/
+#define HCFG_LEGACYFUNC_MASK	0xe0000000	/* Legacy function number 			*/
+#define HCFG_LEGACYFUNC_MPU	0x00000000	/* Legacy MPU	 				*/
+#define HCFG_LEGACYFUNC_SB	0x40000000	/* Legacy SB					*/
+#define HCFG_LEGACYFUNC_AD	0x60000000	/* Legacy AD					*/
+#define HCFG_LEGACYFUNC_MPIC	0x80000000	/* Legacy MPIC					*/
+#define HCFG_LEGACYFUNC_MDMA	0xa0000000	/* Legacy MDMA					*/
+#define HCFG_LEGACYFUNC_SPCI	0xc0000000	/* Legacy SPCI					*/
+#define HCFG_LEGACYFUNC_SDMA	0xe0000000	/* Legacy SDMA					*/
+#define HCFG_IOCAPTUREADDR	0x1f000000	/* The 4 LSBs of the captured I/O address.	*/
+#define HCFG_LEGACYWRITE	0x00800000	/* 1 = write, 0 = read 				*/
+#define HCFG_LEGACYWORD		0x00400000	/* 1 = word, 0 = byte 				*/
+#define HCFG_LEGACYINT		0x00200000	/* 1 = legacy event captured. Write 1 to clear.	*/
+						/* NOTE: The rest of the bits in this register	*/
+						/* _are_ relevant under Linux.			*/
+#define HCFG_CODECFORMAT_MASK	0x00070000	/* CODEC format					*/
+#define HCFG_CODECFORMAT_AC97	0x00000000	/* AC97 CODEC format -- Primary Output		*/
+#define HCFG_CODECFORMAT_I2S	0x00010000	/* I2S CODEC format -- Secondary (Rear) Output	*/
+#define HCFG_GPINPUT0		0x00004000	/* External pin112				*/
+#define HCFG_GPINPUT1		0x00002000	/* External pin110				*/
+#define HCFG_GPOUTPUT_MASK	0x00001c00	/* External pins which may be controlled	*/
+#define HCFG_JOYENABLE      	0x00000200	/* Internal joystick enable    			*/
+#define HCFG_PHASETRACKENABLE	0x00000100	/* Phase tracking enable			*/
+						/* 1 = Force all 3 async digital inputs to use	*/
+						/* the same async sample rate tracker (ZVIDEO)	*/
+#define HCFG_AC3ENABLE_MASK	0x0x0000e0	/* AC3 async input control - Not implemented	*/
+#define HCFG_AC3ENABLE_ZVIDEO	0x00000080	/* Channels 0 and 1 replace ZVIDEO		*/
+#define HCFG_AC3ENABLE_CDSPDIF	0x00000040	/* Channels 0 and 1 replace CDSPDIF		*/
+#define HCFG_AUTOMUTE		0x00000010	/* When set, the async sample rate convertors	*/
+						/* will automatically mute their output when	*/
+						/* they are not rate-locked to the external	*/
+						/* async audio source  				*/
+#define HCFG_LOCKSOUNDCACHE	0x00000008	/* 1 = Cancel bustmaster accesses to soundcache */
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE_MASK	0x00000004	/* 1 = Cancel bustmaster accesses to tankcache	*/
+						/* NOTE: This should generally never be used.  	*/
+#define HCFG_LOCKTANKCACHE	0x01020014
+#define HCFG_MUTEBUTTONENABLE	0x00000002	/* 1 = Master mute button sets AUDIOENABLE = 0.	*/
+						/* NOTE: This is a 'cheap' way to implement a	*/
+						/* master mute function on the mute button, and	*/
+						/* in general should not be used unless a more	*/
+						/* sophisticated master mute function has not	*/
+						/* been written.       				*/
+#define HCFG_AUDIOENABLE	0x00000001	/* 0 = CODECs transmit zero-valued samples	*/
+						/* Should be set to 1 when the EMU10K1 is	*/
+						/* completely initialized.			*/
+
+#define MUDATA			0x18		/* MPU401 data register (8 bits)       		*/
+
+#define MUCMD			0x19		/* MPU401 command register (8 bits)    		*/
+#define MUCMD_RESET		0xff		/* RESET command				*/
+#define MUCMD_ENTERUARTMODE	0x3f		/* Enter_UART_mode command			*/
+						/* NOTE: All other commands are ignored		*/
+
+#define MUSTAT			MUCMD		/* MPU401 status register (8 bits)     		*/
+#define MUSTAT_IRDYN		0x80		/* 0 = MIDI data or command ACK			*/
+#define MUSTAT_ORDYN		0x40		/* 0 = MUDATA can accept a command or data	*/
+
+#define TIMER			0x1a		/* Timer terminal count register		*/
+						/* NOTE: After the rate is changed, a maximum	*/
+						/* of 1024 sample periods should be allowed	*/
+						/* before the new rate is guaranteed accurate.	*/
+#define TIMER_RATE_MASK		0x000003ff	/* Timer interrupt rate in sample periods	*/
+						/* 0 == 1024 periods, [1..4] are not useful	*/
+#define TIMER_RATE		0x0a00001a
+
+#define AC97DATA		0x1c		/* AC97 register set data register (16 bit)	*/
+
+#define AC97ADDRESS		0x1e		/* AC97 register set address register (8 bit)	*/
+#define AC97ADDRESS_READY	0x80		/* Read-only bit, reflects CODEC READY signal	*/
+#define AC97ADDRESS_ADDRESS	0x7f		/* Address of indexed AC97 register		*/
+
+/************************************************************************************************/
+/* PCI function 1 registers, address = <val> + PCIBASE1						*/
+/************************************************************************************************/
+
+#define JOYSTICK1		0x00		/* Analog joystick port register		*/
+#define JOYSTICK2		0x01		/* Analog joystick port register		*/
+#define JOYSTICK3		0x02		/* Analog joystick port register		*/
+#define JOYSTICK4		0x03		/* Analog joystick port register		*/
+#define JOYSTICK5		0x04		/* Analog joystick port register		*/
+#define JOYSTICK6		0x05		/* Analog joystick port register		*/
+#define JOYSTICK7		0x06		/* Analog joystick port register		*/
+#define JOYSTICK8		0x07		/* Analog joystick port register		*/
+
+/* When writing, any write causes JOYSTICK_COMPARATOR output enable to be pulsed on write.	*/
+/* When reading, use these bitfields: */
+#define JOYSTICK_BUTTONS	0x0f		/* Joystick button data				*/
+#define JOYSTICK_COMPARATOR	0xf0		/* Joystick comparator data			*/
+
+
+/********************************************************************************************************/
+/* AC97 pointer-offset register set, accessed through the AC97ADDRESS and AC97DATA registers		*/
+/********************************************************************************************************/
+
+#define AC97_RESET		0x00
+#define AC97_MASTERVOLUME	0x02		/* Master volume					*/
+#define AC97_HEADPHONEVOLUME	0x04		/* Headphone volume					*/
+#define AC97_MASTERVOLUMEMONO	0x06		/* Mast volume mono					*/
+#define AC97_MASTERTONE		0x08
+#define AC97_PCBEEPVOLUME	0x0a		/* PC speaker system beep volume			*/
+#define AC97_PHONEVOLUME	0x0c
+#define AC97_MICVOLUME		0x0e
+#define AC97_LINEINVOLUME	0x10
+#define AC97_CDVOLUME		0x12
+#define AC97_VIDEOVOLUME	0x14
+#define AC97_AUXVOLUME		0x16
+#define AC97_PCMOUTVOLUME	0x18
+#define AC97_RECORDSELECT	0x1a
+#define AC97_RECORDGAIN		0x1c
+#define AC97_RECORDGAINMIC	0x1e
+#define AC97_GENERALPURPOSE	0x20
+#define AC97_3DCONTROL		0x22
+#define AC97_MODEMRATE		0x24
+#define AC97_POWERDOWN		0x26
+#define AC97_VENDORID1		0x7c
+#define AC97_VENDORID2		0x7e
+#define AC97_ZVIDEOVOLUME	0xec
+#define AC97_AC3VOLUME		0xed
+
+/********************************************************************************************************/
+/* Emu10k1 pointer-offset register set, accessed through the PTR and DATA registers			*/
+/********************************************************************************************************/
+
+#define CPF			0x00		/* Current pitch and fraction register			*/
+#define CPF_CURRENTPITCH_MASK	0xffff0000	/* Current pitch (linear, 0x4000 == unity pitch shift) 	*/
+#define CPF_CURRENTPITCH	0x10100000
+#define CPF_STEREO_MASK		0x00008000	/* 1 = Even channel interleave, odd channel locked	*/
+#define CPF_STOP_MASK		0x00004000	/* 1 = Current pitch forced to 0			*/
+#define CPF_FRACADDRESS_MASK	0x00003fff	/* Linear fractional address of the current channel	*/
+
+#define PTRX			0x01		/* Pitch target and send A/B amounts register		*/
+#define PTRX_PITCHTARGET_MASK	0xffff0000	/* Pitch target of specified channel			*/
+#define PTRX_PITCHTARGET	0x10100001
+#define PTRX_FXSENDAMOUNT_A_MASK 0x0000ff00	/* Linear level of channel output sent to FX send bus A	*/
+#define PTRX_FXSENDAMOUNT_A	0x08080001
+#define PTRX_FXSENDAMOUNT_B_MASK 0x000000ff	/* Linear level of channel output sent to FX send bus B	*/
+#define PTRX_FXSENDAMOUNT_B	0x08000001
+
+#define CVCF			0x02		/* Current volume and filter cutoff register		*/
+#define CVCF_CURRENTVOL_MASK	0xffff0000	/* Current linear volume of specified channel		*/
+#define CVCF_CURRENTVOL		0x10100002
+#define CVCF_CURRENTFILTER_MASK	0x0000ffff	/* Current filter cutoff frequency of specified channel	*/
+#define CVCF_CURRENTFILTER	0x10000002
+
+#define VTFT			0x03		/* Volume target and filter cutoff target register	*/
+#define VTFT_VOLUMETARGET_MASK	0xffff0000	/* Volume target of specified channel			*/
+#define VTFT_FILTERTARGET_MASK	0x0000ffff	/* Filter cutoff target of specified channel		*/
+
+#define Z1			0x05		/* Filter delay memory 1 register			*/
+
+#define Z2			0x04		/* Filter delay memory 2 register			*/
+
+#define PSST			0x06		/* Send C amount and loop start address register	*/
+#define PSST_FXSENDAMOUNT_C_MASK 0xff000000	/* Linear level of channel output sent to FX send bus C	*/
+
+#define PSST_FXSENDAMOUNT_C	0x08180006
+
+#define PSST_LOOPSTARTADDR_MASK	0x00ffffff	/* Loop start address of the specified channel		*/
+#define PSST_LOOPSTARTADDR	0x18000006
+
+#define DSL			0x07		/* Send D amount and loop start address register	*/
+#define DSL_FXSENDAMOUNT_D_MASK	0xff000000	/* Linear level of channel output sent to FX send bus D	*/
+
+#define DSL_FXSENDAMOUNT_D	0x08180007
+
+#define DSL_LOOPENDADDR_MASK	0x00ffffff	/* Loop end address of the specified channel		*/
+#define DSL_LOOPENDADDR		0x18000007
+
+#define CCCA			0x08		/* Filter Q, interp. ROM, byte size, cur. addr register */
+#define CCCA_RESONANCE		0xf0000000	/* Lowpass filter resonance (Q) height			*/
+#define CCCA_INTERPROMMASK	0x0e000000	/* Selects passband of interpolation ROM		*/
+						/* 1 == full band, 7 == lowpass				*/
+						/* ROM 0 is used when pitch shifting downward or less	*/
+						/* then 3 semitones upward.  Increasingly higher ROM	*/
+						/* numbers are used, typically in steps of 3 semitones,	*/
+						/* as upward pitch shifting is performed.		*/
+#define CCCA_INTERPROM_0	0x00000000	/* Select interpolation ROM 0				*/
+#define CCCA_INTERPROM_1	0x02000000	/* Select interpolation ROM 1				*/
+#define CCCA_INTERPROM_2	0x04000000	/* Select interpolation ROM 2				*/
+#define CCCA_INTERPROM_3	0x06000000	/* Select interpolation ROM 3				*/
+#define CCCA_INTERPROM_4	0x08000000	/* Select interpolation ROM 4				*/
+#define CCCA_INTERPROM_5	0x0a000000	/* Select interpolation ROM 5				*/
+#define CCCA_INTERPROM_6	0x0c000000	/* Select interpolation ROM 6				*/
+#define CCCA_INTERPROM_7	0x0e000000	/* Select interpolation ROM 7				*/
+#define CCCA_8BITSELECT		0x01000000	/* 1 = Sound memory for this channel uses 8-bit samples	*/
+#define CCCA_CURRADDR_MASK	0x00ffffff	/* Current address of the selected channel		*/
+#define CCCA_CURRADDR		0x18000008
+
+#define CCR			0x09		/* Cache control register				*/
+#define CCR_CACHEINVALIDSIZE	0xfe000000	/* Number of invalid samples cache for this channel    	*/
+#define CCR_CACHELOOPFLAG	0x01000000	/* 1 = Cache has a loop service pending			*/
+#define CCR_INTERLEAVEDSAMPLES	0x00800000	/* 1 = A cache service will fetch interleaved samples	*/
+#define CCR_WORDSIZEDSAMPLES	0x00400000	/* 1 = A cache service will fetch word sized samples	*/
+#define CCR_READADDRESS_MASK	0x003f0000	/* Location of cache just beyond current cache service	*/
+#define CCR_LOOPINVALSIZE	0x0000fe00	/* Number of invalid samples in cache prior to loop	*/
+						/* NOTE: This is valid only if CACHELOOPFLAG is set	*/
+#define CCR_LOOPFLAG		0x00000100	/* Set for a single sample period when a loop occurs	*/
+#define CCR_CACHELOOPADDRHI	0x000000ff	/* DSL_LOOPSTARTADDR's hi byte if CACHELOOPFLAG is set	*/
+
+#define CLP			0x0a		/* Cache loop register (valid if CCR_CACHELOOPFLAG = 1) */
+						/* NOTE: This register is normally not used		*/
+#define CLP_CACHELOOPADDR	0x0000ffff	/* Cache loop address (DSL_LOOPSTARTADDR [0..15])	*/
+
+#define FXRT			0x0b		/* Effects send routing register			*/
+						/* NOTE: It is illegal to assign the same routing to	*/
+						/* two effects sends.					*/
+#define FXRT_CHANNELA		0x000f0000	/* Effects send bus number for channel's effects send A	*/
+#define FXRT_CHANNELB		0x00f00000	/* Effects send bus number for channel's effects send B	*/
+#define FXRT_CHANNELC		0x0f000000	/* Effects send bus number for channel's effects send C	*/
+#define FXRT_CHANNELD		0xf0000000	/* Effects send bus number for channel's effects send D	*/
+
+#define MAPA			0x0c		/* Cache map A						*/
+
+#define MAPB			0x0d		/* Cache map B						*/
+
+#define MAP_PTE_MASK		0xffffe000	/* The 19 MSBs of the PTE indexed by the PTI		*/
+#define MAP_PTI_MASK		0x00001fff	/* The 13 bit index to one of the 8192 PTE dwords      	*/
+
+#define ENVVOL			0x10		/* Volume envelope register				*/
+#define ENVVOL_MASK		0x0000ffff	/* Current value of volume envelope state variable	*/  
+						/* 0x8000-n == 666*n usec delay	       			*/
+
+#define ATKHLDV 		0x11		/* Volume envelope hold and attack register		*/
+#define ATKHLDV_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDV_HOLDTIME_MASK	0x00007f00	/* Envelope hold time (127-n == n*88.2msec)		*/
+#define ATKHLDV_ATTACKTIME_MASK	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 10.9msec, ... 0x7f = 5.5msec	*/
+
+#define DCYSUSV 		0x12		/* Volume envelope sustain and decay register		*/
+#define DCYSUSV_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSV_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSV_CHANNELENABLE_MASK 0x00000080	/* 1 = Inhibit envelope engine from writing values in	*/
+						/* this channel and from writing to pitch, filter and	*/
+						/* volume targets.					*/
+#define DCYSUSV_DECAYTIME_MASK	0x0000007f	/* Volume envelope decay time, log encoded     		*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL1 		0x13		/* Modulation LFO value					*/
+#define LFOVAL_MASK		0x0000ffff	/* Current value of modulation LFO state variable	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ENVVAL			0x14		/* Modulation envelope register				*/
+#define ENVVAL_MASK		0x0000ffff	/* Current value of modulation envelope state variable 	*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define ATKHLDM			0x15		/* Modulation envelope hold and attack register		*/
+#define ATKHLDM_PHASE0		0x00008000	/* 0 = Begin attack phase				*/
+#define ATKHLDM_HOLDTIME	0x00007f00	/* Envelope hold time (127-n == n*42msec)		*/
+#define ATKHLDM_ATTACKTIME	0x0000007f	/* Envelope attack time, log encoded			*/
+						/* 0 = infinite, 1 = 11msec, ... 0x7f = 5.5msec		*/
+
+#define DCYSUSM			0x16		/* Modulation envelope decay and sustain register	*/
+#define DCYSUSM_PHASE1_MASK	0x00008000	/* 0 = Begin attack phase, 1 = begin release phase	*/
+#define DCYSUSM_SUSTAINLEVEL_MASK 0x00007f00	/* 127 = full, 0 = off, 0.75dB increments		*/
+#define DCYSUSM_DECAYTIME_MASK	0x0000007f	/* Envelope decay time, log encoded			*/
+						/* 0 = 43.7msec, 1 = 21.8msec, 0x7f = 22msec		*/
+
+#define LFOVAL2 		0x17		/* Vibrato LFO register					*/
+#define LFOVAL2_MASK		0x0000ffff	/* Current value of vibrato LFO state variable 		*/
+						/* 0x8000-n == 666*n usec delay				*/
+
+#define IP			0x18		/* Initial pitch register				*/
+#define IP_MASK			0x0000ffff	/* Exponential initial pitch shift			*/
+						/* 4 bits of octave, 12 bits of fractional octave	*/
+#define IP_UNITY		0x0000e000	/* Unity pitch shift					*/
+
+#define IFATN			0x19		/* Initial filter cutoff and attenuation register	*/
+#define IFATN_FILTERCUTOFF_MASK	0x0000ff00	/* Initial filter cutoff frequency in exponential units	*/
+						/* 6 most significant bits are semitones		*/
+						/* 2 least significant bits are fractions		*/
+#define IFATN_FILTERCUTOFF	0x08080019
+#define IFATN_ATTENUATION_MASK	0x000000ff	/* Initial attenuation in 0.375dB steps			*/
+#define IFATN_ATTENUATION	0x08000019
+
+
+#define PEFE			0x1a		/* Pitch envelope and filter envelope amount register	*/
+#define PEFE_PITCHAMOUNT_MASK	0x0000ff00	/* Pitch envlope amount					*/
+						/* Signed 2's complement, +/- one octave peak extremes	*/
+#define PEFE_PITCHAMOUNT	0x0808001a
+#define PEFE_FILTERAMOUNT_MASK	0x000000ff	/* Filter envlope amount				*/
+						/* Signed 2's complement, +/- six octaves peak extremes */
+#define PEFE_FILTERAMOUNT	0x0800001a
+#define FMMOD			0x1b		/* Vibrato/filter modulation from LFO register		*/
+#define FMMOD_MODVIBRATO	0x0000ff00	/* Vibrato LFO modulation depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FMMOD_MOFILTER		0x000000ff	/* Filter LFO modulation depth				*/
+						/* Signed 2's complement, +/- three octave extremes	*/
+
+
+#define TREMFRQ 		0x1c		/* Tremolo amount and modulation LFO frequency register	*/
+#define TREMFRQ_DEPTH		0x0000ff00	/* Tremolo depth					*/
+						/* Signed 2's complement, with +/- 12dB extremes	*/
+
+#define FM2FRQ2 		0x1d		/* Vibrato amount and vibrato LFO frequency register	*/
+#define FM2FRQ2_DEPTH		0x0000ff00	/* Vibrato LFO vibrato depth				*/
+						/* Signed 2's complement, +/- one octave extremes	*/
+#define FM2FRQ2_FREQUENCY	0x000000ff	/* Vibrato LFO frequency				*/
+						/* 0.039Hz steps, maximum of 9.85 Hz.			*/
+
+#define TEMPENV 		0x1e		/* Tempory envelope register				*/
+#define TEMPENV_MASK		0x0000ffff	/* 16-bit value						*/
+						/* NOTE: All channels contain internal variables; do	*/
+						/* not write to these locations.			*/
+
+#define CD0			0x20		/* Cache data 0 register				*/
+#define CD1			0x21		/* Cache data 1 register				*/
+#define CD2			0x22		/* Cache data 2 register				*/
+#define CD3			0x23		/* Cache data 3 register				*/
+#define CD4			0x24		/* Cache data 4 register				*/
+#define CD5			0x25		/* Cache data 5 register				*/
+#define CD6			0x26		/* Cache data 6 register				*/
+#define CD7			0x27		/* Cache data 7 register				*/
+#define CD8			0x28		/* Cache data 8 register				*/
+#define CD9			0x29		/* Cache data 9 register				*/
+#define CDA			0x2a		/* Cache data A register				*/
+#define CDB			0x2b		/* Cache data B register				*/
+#define CDC			0x2c		/* Cache data C register				*/
+#define CDD			0x2d		/* Cache data D register				*/
+#define CDE			0x2e		/* Cache data E register				*/
+#define CDF			0x2f		/* Cache data F register				*/
+
+#define PTB			0x40		/* Page table base register				*/
+#define PTB_MASK		0xfffff000	/* Physical address of the page table in host memory	*/
+
+#define TCB			0x41		/* Tank cache base register    				*/
+#define TCB_MASK		0xfffff000	/* Physical address of the bottom of host based TRAM	*/
+
+#define ADCCR			0x42		/* ADC sample rate/stereo control register		*/
+#define ADCCR_RCHANENABLE	0x00000010	/* Enables right channel for writing to the host       	*/
+#define ADCCR_LCHANENABLE	0x00000008	/* Enables left channel for writing to the host		*/
+						/* NOTE: To guarantee phase coherency, both channels	*/
+						/* must be disabled prior to enabling both channels.	*/
+#define ADCCR_SAMPLERATE_MASK	0x00000007	/* Sample rate convertor output rate			*/
+#define ADCCR_SAMPLERATE_48	0x00000000	/* 48kHz sample rate					*/
+#define ADCCR_SAMPLERATE_44	0x00000001	/* 44.1kHz sample rate					*/
+#define ADCCR_SAMPLERATE_32	0x00000002	/* 32kHz sample rate					*/
+#define ADCCR_SAMPLERATE_24	0x00000003	/* 24kHz sample rate					*/
+#define ADCCR_SAMPLERATE_22	0x00000004	/* 22.05kHz sample rate					*/
+#define ADCCR_SAMPLERATE_16	0x00000005	/* 16kHz sample rate					*/
+#define ADCCR_SAMPLERATE_11	0x00000006	/* 11.025kHz sample rate				*/
+#define ADCCR_SAMPLERATE_8	0x00000007	/* 8kHz sample rate					*/
+
+#define FXWC			0x43		/* FX output write channels register			*/
+						/* When set, each bit enables the writing of the	*/
+						/* corresponding FX output channel into host memory	*/
+
+#define TCBS			0x44		/* Tank cache buffer size register			*/
+#define TCBS_MASK		0x00000007	/* Tank cache buffer size field				*/
+#define TCBS_BUFFSIZE_16K	0x00000000
+#define TCBS_BUFFSIZE_32K	0x00000001
+#define TCBS_BUFFSIZE_64K	0x00000002
+#define TCBS_BUFFSIZE_128K	0x00000003
+#define TCBS_BUFFSIZE_256K	0x00000004
+#define TCBS_BUFFSIZE_512K	0x00000005
+#define TCBS_BUFFSIZE_1024K	0x00000006
+#define TCBS_BUFFSIZE_2048K	0x00000007
+
+#define MICBA			0x45		/* AC97 microphone buffer address register		*/
+#define MICBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define ADCBA			0x46		/* ADC buffer address register				*/
+#define ADCBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define FXBA			0x47		/* FX Buffer Address */
+#define FXBA_MASK		0xfffff000	/* 20 bit base address					*/
+
+#define MICBS			0x49		/* Microphone buffer size register			*/
+
+#define ADCBS			0x4a		/* ADC buffer size register				*/
+
+#define FXBS			0x4b		/* FX buffer size register				*/
+
+/* The following mask values define the size of the ADC, MIX and FX buffers in bytes */
+#define ADCBS_BUFSIZE_NONE	0x00000000
+#define ADCBS_BUFSIZE_384	0x00000001
+#define ADCBS_BUFSIZE_448	0x00000002
+#define ADCBS_BUFSIZE_512	0x00000003
+#define ADCBS_BUFSIZE_640	0x00000004
+#define ADCBS_BUFSIZE_768	0x00000005
+#define ADCBS_BUFSIZE_896	0x00000006
+#define ADCBS_BUFSIZE_1024	0x00000007
+#define ADCBS_BUFSIZE_1280	0x00000008
+#define ADCBS_BUFSIZE_1536	0x00000009
+#define ADCBS_BUFSIZE_1792	0x0000000a
+#define ADCBS_BUFSIZE_2048	0x0000000b
+#define ADCBS_BUFSIZE_2560	0x0000000c
+#define ADCBS_BUFSIZE_3072	0x0000000d
+#define ADCBS_BUFSIZE_3584	0x0000000e
+#define ADCBS_BUFSIZE_4096	0x0000000f
+#define ADCBS_BUFSIZE_5120	0x00000010
+#define ADCBS_BUFSIZE_6144	0x00000011
+#define ADCBS_BUFSIZE_7168	0x00000012
+#define ADCBS_BUFSIZE_8192	0x00000013
+#define ADCBS_BUFSIZE_10240	0x00000014
+#define ADCBS_BUFSIZE_12288	0x00000015
+#define ADCBS_BUFSIZE_14366	0x00000016
+#define ADCBS_BUFSIZE_16384	0x00000017
+#define ADCBS_BUFSIZE_20480	0x00000018
+#define ADCBS_BUFSIZE_24576	0x00000019
+#define ADCBS_BUFSIZE_28672	0x0000001a
+#define ADCBS_BUFSIZE_32768	0x0000001b
+#define ADCBS_BUFSIZE_40960	0x0000001c
+#define ADCBS_BUFSIZE_49152	0x0000001d
+#define ADCBS_BUFSIZE_57344	0x0000001e
+#define ADCBS_BUFSIZE_65536	0x0000001f
+
+
+#define CDCS			0x50		/* CD-ROM digital channel status register	*/
+
+#define GPSCS			0x51		/* General Purpose SPDIF channel status register*/
+
+#define DBG			0x52		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+#define REG53			0x53		/* DO NOT PROGRAM THIS REGISTER!!! MAY DESTROY CHIP */
+
+#define SPCS0			0x54		/* SPDIF output Channel Status 0 register	*/
+
+#define SPCS1			0x55		/* SPDIF output Channel Status 1 register	*/
+
+#define SPCS2			0x56		/* SPDIF output Channel Status 2 register	*/
+
+#define SPCS_CLKACCYMASK	0x30000000	/* Clock accuracy				*/
+#define SPCS_CLKACCY_1000PPM	0x00000000	/* 1000 parts per million			*/
+#define SPCS_CLKACCY_50PPM	0x10000000	/* 50 parts per million				*/
+#define SPCS_CLKACCY_VARIABLE	0x20000000	/* Variable accuracy				*/
+#define SPCS_SAMPLERATEMASK	0x0f000000	/* Sample rate					*/
+#define SPCS_SAMPLERATE_44	0x00000000	/* 44.1kHz sample rate				*/
+#define SPCS_SAMPLERATE_48	0x02000000	/* 48kHz sample rate				*/
+#define SPCS_SAMPLERATE_32	0x03000000	/* 32kHz sample rate				*/
+#define SPCS_CHANNELNUMMASK	0x00f00000	/* Channel number				*/
+#define SPCS_CHANNELNUM_UNSPEC	0x00000000	/* Unspecified channel number			*/
+#define SPCS_CHANNELNUM_LEFT	0x00100000	/* Left channel					*/
+#define SPCS_CHANNELNUM_RIGHT	0x00200000	/* Right channel				*/
+#define SPCS_SOURCENUMMASK	0x000f0000	/* Source number				*/
+#define SPCS_SOURCENUM_UNSPEC	0x00000000	/* Unspecified source number			*/
+#define SPCS_GENERATIONSTATUS	0x00008000	/* Originality flag (see IEC-958 spec)		*/
+#define SPCS_CATEGORYCODEMASK	0x00007f00	/* Category code (see IEC-958 spec)		*/
+#define SPCS_MODEMASK		0x000000c0	/* Mode (see IEC-958 spec)			*/
+#define SPCS_EMPHASISMASK	0x00000038	/* Emphasis					*/
+#define SPCS_EMPHASIS_NONE	0x00000000	/* No emphasis					*/
+#define SPCS_EMPHASIS_50_15	0x00000008	/* 50/15 usec 2 channel				*/
+#define SPCS_COPYRIGHT		0x00000004	/* Copyright asserted flag -- do not modify	*/
+#define SPCS_NOTAUDIODATA	0x00000002	/* 0 = Digital audio, 1 = not audio		*/
+#define SPCS_PROFESSIONAL	0x00000001	/* 0 = Consumer (IEC-958), 1 = pro (AES3-1992)	*/
+
+/* The 32-bit CLIx and SOLx registers all have one bit per channel control/status      		*/
+#define CLIEL			0x58		/* Channel loop interrupt enable low register	*/
+
+#define CLIEH			0x59		/* Channel loop interrupt enable high register	*/
+
+#define CLIPL			0x5a		/* Channel loop interrupt pending low register	*/
+
+#define CLIPH			0x5b		/* Channel loop interrupt pending high register	*/
+
+#define SOLEL			0x5c		/* Stop on loop enable low register		*/
+
+#define SOLEH			0x5d		/* Stop on loop enable high register		*/
+
+#define SPBYPASS		0x5e		/* SPDIF BYPASS mode register			*/
+#define SPBYPASS_ENABLE		0x00000001	/* Enable SPDIF bypass mode			*/
+
+#define CDSRCS			0x60		/* CD-ROM Sample Rate Converter status register	*/
+
+#define GPSRCS			0x61		/* General Purpose SPDIF sample rate cvt status */
+
+#define ZVSRCS			0x62		/* ZVideo sample rate converter status		*/
+						/* NOTE: This one has no SPDIFLOCKED field	*/
+						/* Assumes sample lock				*/
+
+/* These three bitfields apply to CDSRCS, GPSRCS, and (except as noted) ZVSRCS.			*/
+#define SRCS_SPDIFLOCKED	0x02000000	/* SPDIF stream locked				*/
+#define SRCS_RATELOCKED		0x01000000	/* Sample rate locked				*/
+#define SRCS_ESTSAMPLERATE	0x0007ffff	/* Do not modify this field.			*/
+
+#define MICIDX                  0x63            /* Microphone recording buffer index register   */
+#define MICIDX_MASK             0x0000ffff      /* 16-bit value                                 */
+#define MICIDX_IDX		0x10000063
+
+#define ADCIDX			0x64		/* ADC recording buffer index register		*/
+#define ADCIDX_MASK		0x0000ffff	/* 16 bit index field				*/
+#define ADCIDX_IDX		0x10000064
+
+#define FXIDX			0x65		/* FX recording buffer index register		*/
+#define FXIDX_MASK		0x0000ffff	/* 16-bit value					*/
+#define FXIDX_IDX		0x10000065
+
+/* Each FX general purpose register is 32 bits in length, all bits are used			*/
+#define FXGPREGBASE		0x100		/* FX general purpose registers base       	*/
+
+/* Tank audio data is logarithmically compressed down to 16 bits before writing to TRAM and is	*/
+/* decompressed back to 20 bits on a read.  There are a total of 160 locations, the last 32	*/
+/* locations are for external TRAM. 								*/
+#define TANKMEMDATAREGBASE	0x200		/* Tank memory data registers base     		*/
+#define TANKMEMDATAREG_MASK	0x000fffff	/* 20 bit tank audio data field			*/
+
+/* Combined address field and memory opcode or flag field.  160 locations, last 32 are external	*/
+#define TANKMEMADDRREGBASE	0x300		/* Tank memory address registers base		*/
+#define TANKMEMADDRREG_ADDR_MASK 0x000fffff	/* 20 bit tank address field			*/
+#define TANKMEMADDRREG_CLEAR	0x00800000	/* Clear tank memory				*/
+#define TANKMEMADDRREG_ALIGN	0x00400000	/* Align read or write relative to tank access	*/
+#define TANKMEMADDRREG_WRITE	0x00200000	/* Write to tank memory				*/
+#define TANKMEMADDRREG_READ	0x00100000	/* Read from tank memory			*/
+
+#define MICROCODEBASE		0x400		/* Microcode data base address			*/
+
+/* Each DSP microcode instruction is mapped into 2 doublewords 					*/
+/* NOTE: When writing, always write the LO doubleword first.  Reads can be in either order.	*/
+#define LOWORD_OPX_MASK		0x000ffc00	/* Instruction operand X			*/
+#define LOWORD_OPY_MASK		0x000003ff	/* Instruction operand Y			*/
+#define HIWORD_OPCODE_MASK	0x00f00000	/* Instruction opcode				*/
+#define HIWORD_RESULT_MASK	0x000ffc00	/* Instruction result				*/
+#define HIWORD_OPA_MASK		0x000003ff	/* Instruction operand A			*/
+
+#endif /* _8010_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/Makefile linux.17p18/drivers/sound/emu10k1/Makefile
--- linux.vanilla/drivers/sound/emu10k1/Makefile	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/Makefile	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,27 @@
+# Makefile for Creative Labs SBLive!
+#
+# 19 Apr 2000 Rui Sousa
+
+ifeq ($(CONFIG_SOUND_EMU10K1),y)
+    O_TARGET := emu10k1.o
+    O_OBJS = audio.o cardmi.o cardmo.o cardwi.o cardwo.o emuadxmg.o \
+             emu_wrapper.o hwaccess.o irqmgr.o main.o midi.o mixer.o \
+             recmgr.o timer.o voicemgr.o
+else
+  ifeq ($(CONFIG_SOUND_EMU10K1),m)
+    M_OBJS := emu10k1.o
+    O_TARGET := emu10k1.o
+    O_OBJS = audio.o cardmi.o cardmo.o cardwi.o cardwo.o emuadxmg.o \
+             emu_wrapper.o hwaccess.o irqmgr.o main.o midi.o mixer.o \
+             recmgr.o timer.o voicemgr.o
+  endif
+endif
+
+ifdef DEBUG
+    EXTRA_CFLAGS += -DEMU10K1_DEBUG
+endif
+
+include $(TOPDIR)/Rules.make
+
+clean:
+	rm -f core *.o *.a *.s
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/audio.c linux.17p18/drivers/sound/emu10k1/audio.c
--- linux.vanilla/drivers/sound/emu10k1/audio.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/audio.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,1499 @@
+/*
+ **********************************************************************
+ *     audio.c -- /dev/dsp interface for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999	    Alan Cox        cleaned up types/leaks
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/malloc.h>
+#include <asm/io.h>
+
+#include "hwaccess.h"
+#include "cardwo.h"
+#include "cardwi.h"
+#include "recmgr.h"
+#include "irqmgr.h"
+#include "audio.h"
+
+static void calculate_ofrag(struct woinst *);
+static void calculate_ifrag(struct wiinst *);
+
+/* Audio file operations */
+static loff_t emu10k1_audio_llseek(struct file *file, loff_t offset, int nOrigin)
+{
+	return -ESPIPE;
+}
+
+static ssize_t emu10k1_audio_read(struct file *file, char *buffer, size_t count, loff_t * ppos)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
+	struct wiinst *wiinst = wave_dev->wiinst;
+	ssize_t ret = 0;
+	unsigned long flags;
+
+	GET_INODE_STRUCT();
+
+	DPD(4, "emu10k1_audio_read(), buffer=%p, count=%d\n", buffer, (u32) count);
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+
+	spin_lock_irqsave(&wiinst->lock, flags);
+
+	if (wiinst->mmapped) {
+		spin_unlock_irqrestore(&wiinst->lock, flags);
+		return -ENXIO;
+	}
+
+	if (wiinst->state == WAVE_STATE_CLOSED) {
+		calculate_ifrag(wiinst);
+
+		while (emu10k1_wavein_open(wave_dev) < 0) {
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+
+			if (file->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			UP_INODE_SEM(&inode->i_sem);
+			interruptible_sleep_on(&wave_dev->card->open_wait);
+			DOWN_INODE_SEM(&inode->i_sem);
+
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+
+			spin_lock_irqsave(&wiinst->lock, flags);
+		}
+	}
+
+	spin_unlock_irqrestore(&wiinst->lock, flags);
+
+	while (count > 0) {
+		u32 bytestocopy;
+
+		spin_lock_irqsave(&wiinst->lock, flags);
+
+		if (!(wiinst->state & WAVE_STATE_STARTED)
+		    && (wave_dev->enablebits & PCM_ENABLE_INPUT))
+			emu10k1_wavein_start(wave_dev);
+
+		emu10k1_wavein_update(wave_dev->card, wiinst);
+		emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
+
+		spin_unlock_irqrestore(&wiinst->lock, flags);
+
+		DPD(4, "bytestocopy --> %d\n", bytestocopy);
+
+		if ((bytestocopy >= wiinst->buffer.fragment_size)
+		    || (bytestocopy >= count)) {
+			bytestocopy = min(bytestocopy, count);
+
+			emu10k1_wavein_xferdata(wiinst, (u8 *) buffer, &bytestocopy);
+
+			count -= bytestocopy;
+			buffer += bytestocopy;
+			ret += bytestocopy;
+		}
+
+		if (count > 0) {
+			if ((file->f_flags & O_NONBLOCK)
+			    || (!(wave_dev->enablebits & PCM_ENABLE_INPUT)))
+				return (ret ? ret : -EAGAIN);
+
+			UP_INODE_SEM(&inode->i_sem);
+			interruptible_sleep_on(&wiinst->wait_queue);
+			DOWN_INODE_SEM(&inode->i_sem);
+
+			if (signal_pending(current))
+				return (ret ? ret : -ERESTARTSYS);
+
+		}
+	}
+
+	DPD(4, "bytes copied -> %d\n", (u32) ret);
+
+	return ret;
+}
+
+static ssize_t emu10k1_audio_write(struct file *file, const char *buffer, size_t count, loff_t * ppos)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
+	struct woinst *woinst = wave_dev->woinst;
+	ssize_t ret;
+	unsigned long flags;
+
+	GET_INODE_STRUCT();
+
+	DPD(4, "emu10k1_audio_write(), buffer=%p, count=%d\n", buffer, (u32) count);
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+
+	spin_lock_irqsave(&woinst->lock, flags);
+
+	if (woinst->mmapped) {
+		spin_unlock_irqrestore(&woinst->lock, flags);
+		return -ENXIO;
+	}
+
+	if (woinst->state == WAVE_STATE_CLOSED) {
+		calculate_ofrag(woinst);
+
+		while (emu10k1_waveout_open(wave_dev) < 0) {
+			spin_unlock_irqrestore(&woinst->lock, flags);
+
+			if (file->f_flags & O_NONBLOCK)
+				return -EAGAIN;
+
+			UP_INODE_SEM(&inode->i_sem);
+			interruptible_sleep_on(&wave_dev->card->open_wait);
+			DOWN_INODE_SEM(&inode->i_sem);
+
+			if (signal_pending(current))
+				return -ERESTARTSYS;
+
+			spin_lock_irqsave(&woinst->lock, flags);
+		}
+	}
+
+	spin_unlock_irqrestore(&woinst->lock, flags);
+
+	ret = 0;
+	while (count > 0) {
+		u32 bytestocopy;
+
+		spin_lock_irqsave(&woinst->lock, flags);
+		emu10k1_waveout_update(woinst);
+		emu10k1_waveout_getxfersize(woinst, &bytestocopy);
+		spin_unlock_irqrestore(&woinst->lock, flags);
+
+		DPD(4, "bytestocopy --> %d\n", bytestocopy);
+
+		if ((bytestocopy >= woinst->buffer.fragment_size)
+		    || (bytestocopy >= count)) {
+
+			bytestocopy = min(bytestocopy, count);
+
+			emu10k1_waveout_xferdata(woinst, (u8 *) buffer, &bytestocopy);
+
+			count -= bytestocopy;
+			buffer += bytestocopy;
+			ret += bytestocopy;
+
+			spin_lock_irqsave(&woinst->lock, flags);
+			woinst->total_copied += bytestocopy;
+
+			if (!(woinst->state & WAVE_STATE_STARTED)
+			    && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
+			    && (woinst->total_copied >= woinst->buffer.fragment_size))
+				emu10k1_waveout_start(wave_dev);
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+		}
+
+		if (count > 0) {
+			if ((file->f_flags & O_NONBLOCK)
+			    || (!(wave_dev->enablebits & PCM_ENABLE_OUTPUT)))
+				return (ret ? ret : -EAGAIN);
+
+			UP_INODE_SEM(&inode->i_sem);
+			interruptible_sleep_on(&woinst->wait_queue);
+			DOWN_INODE_SEM(&inode->i_sem);
+
+			if (signal_pending(current))
+				return (ret ? ret : -ERESTARTSYS);
+		}
+	}
+
+	DPD(4, "bytes copied -> %d\n", (u32) ret);
+
+	return ret;
+}
+
+static int emu10k1_audio_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
+	struct woinst *woinst = NULL;
+	struct wiinst *wiinst = NULL;
+	int val = 0;
+	u32 bytestocopy;
+	unsigned long flags;
+
+	DPF(4, "emu10k1_audio_ioctl()\n");
+
+	if (file->f_mode & FMODE_WRITE)
+		woinst = wave_dev->woinst;
+
+	if (file->f_mode & FMODE_READ)
+		wiinst = wave_dev->wiinst;
+
+	switch (cmd) {
+	case OSS_GETVERSION:
+		DPF(2, "OSS_GETVERSION:\n");
+		return put_user(SOUND_VERSION, (int *) arg);
+
+	case SNDCTL_DSP_RESET:
+		DPF(2, "SNDCTL_DSP_RESET:\n");
+		wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;
+
+		if (file->f_mode & FMODE_WRITE) {
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			if (woinst->state & WAVE_STATE_OPEN) {
+				if (woinst->mmapped) {
+					int i;
+
+					/* Undo marking the pages as reserved */
+					for (i = 0; i < woinst->buffer.pages; i++)
+						set_bit(PG_reserved, &mem_map[MAP_NR(woinst->buffer.addr[i])].flags);
+				}
+
+				emu10k1_waveout_close(wave_dev);
+			}
+
+			woinst->mmapped = 0;
+			woinst->total_copied = 0;
+			woinst->total_played = 0;
+			woinst->blocks = 0;
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+		}
+
+		if (file->f_mode & FMODE_READ) {
+			spin_lock_irqsave(&wiinst->lock, flags);
+
+			if (wiinst->state & WAVE_STATE_OPEN)
+				emu10k1_wavein_close(wave_dev);
+
+			wiinst->mmapped = 0;
+			wiinst->total_recorded = 0;
+			wiinst->blocks = 0;
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+		}
+
+		break;
+
+	case SNDCTL_DSP_SYNC:
+		DPF(2, "SNDCTL_DSP_SYNC:\n");
+
+		if (file->f_mode & FMODE_WRITE) {
+
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			if (woinst->state & WAVE_STATE_OPEN) {
+
+				if (woinst->state & WAVE_STATE_STARTED)
+					while ((woinst->total_played < woinst->total_copied)
+					       && !signal_pending(current)) {
+						spin_unlock_irqrestore(&woinst->lock, flags);
+						interruptible_sleep_on(&woinst->wait_queue);
+						spin_lock_irqsave(&woinst->lock, flags);
+					}
+
+				if (woinst->mmapped) {
+					int i;
+
+					/* Undo marking the pages as reserved */
+					for (i = 0; i < woinst->buffer.pages; i++)
+						set_bit(PG_reserved, &mem_map[MAP_NR(woinst->buffer.addr[i])].flags);
+				}
+
+				emu10k1_waveout_close(wave_dev);
+			}
+
+			woinst->mmapped = 0;
+			woinst->total_copied = 0;
+			woinst->total_played = 0;
+			woinst->blocks = 0;
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+		}
+
+		if (file->f_mode & FMODE_READ) {
+			spin_lock_irqsave(&wiinst->lock, flags);
+
+			if (wiinst->state & WAVE_STATE_OPEN)
+				emu10k1_wavein_close(wave_dev);
+
+			wiinst->mmapped = 0;
+			wiinst->total_recorded = 0;
+			wiinst->blocks = 0;
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+		}
+
+		break;
+
+	case SNDCTL_DSP_SETDUPLEX:
+		DPF(2, "SNDCTL_DSP_SETDUPLEX:\n");
+		break;
+
+	case SNDCTL_DSP_GETCAPS:
+		DPF(2, "SNDCTL_DSP_GETCAPS:\n");
+		return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER | DSP_CAP_MMAP | DSP_CAP_COPROC, (int *) arg);
+
+	case SNDCTL_DSP_SPEED:
+		DPF(2, "SNDCTL_DSP_SPEED:\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+		DPD(2, "val is %d\n", val);
+
+		if (val > 0) {
+			if (file->f_mode & FMODE_READ) {
+				struct wave_format format;
+
+				spin_lock_irqsave(&wiinst->lock, flags);
+
+				format = wiinst->format;
+				format.samplingrate = val;
+
+				if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+					return -EINVAL;
+
+				val = wiinst->format.samplingrate;
+
+				spin_unlock_irqrestore(&wiinst->lock, flags);
+
+				DPD(2, "set recording sampling rate -> %d\n", val);
+			}
+
+			if (file->f_mode & FMODE_WRITE) {
+				struct wave_format format;
+
+				spin_lock_irqsave(&woinst->lock, flags);
+
+				format = woinst->format;
+				format.samplingrate = val;
+
+				if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+					return -EINVAL;
+
+				val = woinst->format.samplingrate;
+
+				spin_unlock_irqrestore(&woinst->lock, flags);
+
+				DPD(2, "set playback sampling rate -> %d\n", val);
+			}
+
+			return put_user(val, (int *) arg);
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = wiinst->format.samplingrate;
+			else if (file->f_mode & FMODE_WRITE)
+				val = woinst->format.samplingrate;
+
+			return put_user(val, (int *) arg);
+		}
+		break;
+
+	case SNDCTL_DSP_STEREO:
+		DPF(2, "SNDCTL_DSP_STEREO:\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+		DPD(2, " val is %d\n", val);
+
+		if (file->f_mode & FMODE_READ) {
+			struct wave_format format;
+
+			spin_lock_irqsave(&wiinst->lock, flags);
+
+			format = wiinst->format;
+			format.channels = val ? 2 : 1;
+
+			if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+				return -EINVAL;
+
+			val = wiinst->format.channels - 1;
+
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+			DPD(2, "set recording stereo -> %d\n", val);
+		}
+
+		if (file->f_mode & FMODE_WRITE) {
+			struct wave_format format;
+
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			format = woinst->format;
+			format.channels = val ? 2 : 1;
+
+			if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+				return -EINVAL;
+
+			val = woinst->format.channels - 1;
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+
+			DPD(2, "set playback stereo -> %d\n", val);
+		}
+
+		return put_user(val, (int *) arg);
+
+		break;
+
+	case SNDCTL_DSP_CHANNELS:
+		DPF(2, "SNDCTL_DSP_CHANNELS:\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+		DPD(2, " val is %d\n", val);
+
+		if (val > 0) {
+			if (file->f_mode & FMODE_READ) {
+				struct wave_format format;
+
+				spin_lock_irqsave(&wiinst->lock, flags);
+
+				format = wiinst->format;
+				format.channels = val;
+
+				if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+					return -EINVAL;
+
+				val = wiinst->format.channels;
+
+				spin_unlock_irqrestore(&wiinst->lock, flags);
+				DPD(2, "set recording number of channels -> %d\n", val);
+			}
+
+			if (file->f_mode & FMODE_WRITE) {
+				struct wave_format format;
+
+				spin_lock_irqsave(&woinst->lock, flags);
+
+				format = woinst->format;
+				format.channels = val;
+
+				if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+					return -EINVAL;
+
+				val = woinst->format.channels;
+
+				spin_unlock_irqrestore(&woinst->lock, flags);
+				DPD(2, "set playback number of channels -> %d\n", val);
+			}
+
+			return put_user(val, (int *) arg);
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = wiinst->format.channels;
+			else if (file->f_mode & FMODE_WRITE)
+				val = woinst->format.channels;
+
+			return put_user(val, (int *) arg);
+		}
+		break;
+
+	case SNDCTL_DSP_GETFMTS:
+		DPF(2, "SNDCTL_DSP_GETFMTS:\n");
+
+		if (file->f_mode & FMODE_READ)
+			val = AFMT_S16_LE;
+		else if (file->f_mode & FMODE_WRITE)
+			val = AFMT_S16_LE | AFMT_U8;
+
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETFMT:	/* Same as SNDCTL_DSP_SAMPLESIZE */
+		DPF(2, "SNDCTL_DSP_SETFMT:\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+		DPD(2, " val is %d\n", val);
+
+		if (val != AFMT_QUERY) {
+			if (file->f_mode & FMODE_READ) {
+				struct wave_format format;
+
+				spin_lock_irqsave(&wiinst->lock, flags);
+
+				format = wiinst->format;
+				format.bitsperchannel = val;
+
+				if (emu10k1_wavein_setformat(wave_dev, &format) < 0)
+					return -EINVAL;
+
+				val = wiinst->format.bitsperchannel;
+
+				spin_unlock_irqrestore(&wiinst->lock, flags);
+				DPD(2, "set recording sample size -> %d\n", val);
+			}
+
+			if (file->f_mode & FMODE_WRITE) {
+				struct wave_format format;
+
+				spin_lock_irqsave(&woinst->lock, flags);
+
+				format = woinst->format;
+				format.bitsperchannel = val;
+
+				if (emu10k1_waveout_setformat(wave_dev, &format) < 0)
+					return -EINVAL;
+
+				val = woinst->format.bitsperchannel;
+
+				spin_unlock_irqrestore(&woinst->lock, flags);
+				DPD(2, "set playback sample size -> %d\n", val);
+			}
+
+			return put_user((val == 16) ? AFMT_S16_LE : AFMT_U8, (int *) arg);
+		} else {
+			if (file->f_mode & FMODE_READ)
+				val = wiinst->format.bitsperchannel;
+			else if (file->f_mode & FMODE_WRITE)
+				val = woinst->format.bitsperchannel;
+
+			return put_user((val == 16) ? AFMT_S16_LE : AFMT_U8, (int *) arg);
+		}
+		break;
+
+	case SOUND_PCM_READ_BITS:
+
+		if (file->f_mode & FMODE_READ)
+			val = wiinst->format.bitsperchannel;
+		else if (file->f_mode & FMODE_WRITE)
+			val = woinst->format.bitsperchannel;
+
+		return put_user((val == 16) ? AFMT_S16_LE : AFMT_U8, (int *) arg);
+
+	case SOUND_PCM_READ_RATE:
+
+		if (file->f_mode & FMODE_READ)
+			val = wiinst->format.samplingrate;
+		else if (file->f_mode & FMODE_WRITE)
+			val = woinst->format.samplingrate;
+
+		return put_user(val, (int *) arg);
+
+	case SOUND_PCM_READ_CHANNELS:
+
+		if (file->f_mode & FMODE_READ)
+			val = wiinst->format.channels;
+		else if (file->f_mode & FMODE_WRITE)
+			val = woinst->format.channels;
+
+		return put_user(val, (int *) arg);
+
+	case SOUND_PCM_WRITE_FILTER:
+		DPF(2, "SOUND_PCM_WRITE_FILTER: not implemented\n");
+		break;
+
+	case SOUND_PCM_READ_FILTER:
+		DPF(2, "SOUND_PCM_READ_FILTER: not implemented\n");
+		break;
+
+	case SNDCTL_DSP_SETSYNCRO:
+		DPF(2, "SNDCTL_DSP_SETSYNCRO: not implemented\n");
+		break;
+
+	case SNDCTL_DSP_GETTRIGGER:
+		DPF(2, "SNDCTL_DSP_GETTRIGGER:\n");
+
+		if (file->f_mode & FMODE_WRITE && (wave_dev->enablebits & PCM_ENABLE_OUTPUT))
+			val |= PCM_ENABLE_OUTPUT;
+
+		if (file->f_mode & FMODE_READ && (wave_dev->enablebits & PCM_ENABLE_INPUT))
+			val |= PCM_ENABLE_INPUT;
+
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:
+		DPF(2, "SNDCTL_DSP_SETTRIGGER:\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+
+		if (file->f_mode & FMODE_WRITE) {
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			if (val & PCM_ENABLE_OUTPUT) {
+				wave_dev->enablebits |= PCM_ENABLE_OUTPUT;
+				if (woinst->state & WAVE_STATE_OPEN)
+					emu10k1_waveout_start(wave_dev);
+			} else {
+				wave_dev->enablebits &= ~PCM_ENABLE_OUTPUT;
+				if (woinst->state & WAVE_STATE_STARTED)
+					emu10k1_waveout_stop(wave_dev);
+			}
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+		}
+
+		if (file->f_mode & FMODE_READ) {
+			spin_lock_irqsave(&wiinst->lock, flags);
+
+			if (val & PCM_ENABLE_INPUT) {
+				wave_dev->enablebits |= PCM_ENABLE_INPUT;
+				if (wiinst->state & WAVE_STATE_OPEN)
+					emu10k1_wavein_start(wave_dev);
+			} else {
+				wave_dev->enablebits &= ~PCM_ENABLE_INPUT;
+				if (wiinst->state & WAVE_STATE_STARTED)
+					emu10k1_wavein_stop(wave_dev);
+			}
+
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+		}
+		break;
+
+	case SNDCTL_DSP_GETOSPACE:
+		{
+			audio_buf_info info;
+
+			DPF(4, "SNDCTL_DSP_GETOSPACE:\n");
+
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			if (woinst->state & WAVE_STATE_OPEN) {
+				emu10k1_waveout_update(woinst);
+				emu10k1_waveout_getxfersize(woinst, &bytestocopy);
+				info.bytes = bytestocopy;
+			} else {
+				calculate_ofrag(woinst);
+				info.bytes = woinst->buffer.size;
+			}
+			spin_unlock_irqrestore(&woinst->lock, flags);
+
+			info.fragstotal = woinst->buffer.numfrags;
+			info.fragments = info.bytes / woinst->buffer.fragment_size;
+			info.fragsize = woinst->buffer.fragment_size;
+
+			if (copy_to_user((int *) arg, &info, sizeof(info)))
+				return -EFAULT;
+		}
+		break;
+
+	case SNDCTL_DSP_GETISPACE:
+		{
+			audio_buf_info info;
+
+			DPF(4, "SNDCTL_DSP_GETISPACE:\n");
+
+			if (!(file->f_mode & FMODE_READ))
+				return -EINVAL;
+
+			spin_lock_irqsave(&wiinst->lock, flags);
+			if (wiinst->state & WAVE_STATE_OPEN) {
+				emu10k1_wavein_update(wave_dev->card, wiinst);
+				emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
+				info.bytes = bytestocopy;
+			} else {
+				calculate_ifrag(wiinst);
+				info.bytes = 0;
+			}
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+
+			info.fragstotal = wiinst->buffer.numfrags;
+			info.fragments = info.bytes / wiinst->buffer.fragment_size;
+			info.fragsize = wiinst->buffer.fragment_size;
+
+			if (copy_to_user((int *) arg, &info, sizeof(info)))
+				return -EFAULT;
+		}
+		break;
+
+	case SNDCTL_DSP_NONBLOCK:
+		DPF(2, "SNDCTL_DSP_NONBLOCK:\n");
+
+		file->f_flags |= O_NONBLOCK;
+		break;
+
+	case SNDCTL_DSP_GETODELAY:
+		DPF(4, "SNDCTL_DSP_GETODELAY:\n");
+
+		if (!(file->f_mode & FMODE_WRITE))
+			return -EINVAL;
+
+		spin_lock_irqsave(&woinst->lock, flags);
+		if (woinst->state & WAVE_STATE_OPEN) {
+			emu10k1_waveout_update(woinst);
+			emu10k1_waveout_getxfersize(woinst, &bytestocopy);
+			val = woinst->buffer.size - bytestocopy;
+		} else
+			val = 0;
+
+		spin_unlock_irqrestore(&woinst->lock, flags);
+
+		return put_user(val, (int *) arg);
+
+	case SNDCTL_DSP_GETIPTR:
+		{
+			count_info cinfo;
+
+			DPF(4, "SNDCTL_DSP_GETIPTR: \n");
+
+			if (!(file->f_mode & FMODE_READ))
+				return -EINVAL;
+
+			spin_lock_irqsave(&wiinst->lock, flags);
+
+			if (wiinst->state & WAVE_STATE_OPEN) {
+				emu10k1_wavein_update(wave_dev->card, wiinst);
+				cinfo.ptr = wiinst->buffer.hw_pos;
+				cinfo.bytes = cinfo.ptr + wiinst->total_recorded - wiinst->total_recorded % wiinst->buffer.size;
+				cinfo.blocks = cinfo.bytes / wiinst->buffer.fragment_size - wiinst->blocks;
+				wiinst->blocks = cinfo.bytes / wiinst->buffer.fragment_size;
+			} else {
+				cinfo.ptr = 0;
+				cinfo.bytes = 0;
+				cinfo.blocks = 0;
+			}
+
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+
+			if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+				return -EFAULT;
+		}
+		break;
+
+	case SNDCTL_DSP_GETOPTR:
+		{
+			count_info cinfo;
+
+			DPF(4, "SNDCTL_DSP_GETOPTR:\n");
+
+			if (!(file->f_mode & FMODE_WRITE))
+				return -EINVAL;
+
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			if (woinst->state & WAVE_STATE_OPEN) {
+				emu10k1_waveout_update(woinst);
+				cinfo.ptr = woinst->buffer.hw_pos;
+				cinfo.bytes = cinfo.ptr + woinst->total_played - woinst->total_played % woinst->buffer.size;
+				cinfo.blocks = cinfo.bytes / woinst->buffer.fragment_size - woinst->blocks;
+				woinst->blocks = cinfo.bytes / woinst->buffer.fragment_size;
+			} else {
+				cinfo.ptr = 0;
+				cinfo.bytes = 0;
+				cinfo.blocks = 0;
+			}
+			if(woinst->mmapped)
+				woinst->buffer.bytestocopy %= woinst->buffer.fragment_size;
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+
+			if (copy_to_user((void *) arg, &cinfo, sizeof(cinfo)))
+				return -EFAULT;
+		}
+		break;
+
+	case SNDCTL_DSP_GETBLKSIZE:
+		DPF(2, "SNDCTL_DSP_GETBLKSIZE:\n");
+
+		if (file->f_mode & FMODE_WRITE) {
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			calculate_ofrag(woinst);
+			val = woinst->buffer.fragment_size;
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+		}
+
+		if (file->f_mode & FMODE_READ) {
+			spin_lock_irqsave(&wiinst->lock, flags);
+
+			calculate_ifrag(wiinst);
+			val = wiinst->buffer.fragment_size;
+
+			spin_unlock_irqrestore(&wiinst->lock, flags);
+		}
+
+		return put_user(val, (int *) arg);
+
+		break;
+
+	case SNDCTL_DSP_POST:
+		if (file->f_mode & FMODE_WRITE) {
+			spin_lock_irqsave(&woinst->lock, flags);
+
+			if (!(woinst->state & WAVE_STATE_STARTED)
+			    && (wave_dev->enablebits & PCM_ENABLE_OUTPUT)
+			    && (woinst->total_copied > 0))
+				emu10k1_waveout_start(wave_dev);
+
+			spin_unlock_irqrestore(&woinst->lock, flags);
+		}
+
+		break;
+
+	case SNDCTL_DSP_SUBDIVIDE:
+		DPF(2, "SNDCTL_DSP_SUBDIVIDE: not implemented\n");
+		break;
+
+	case SNDCTL_DSP_SETFRAGMENT:
+		DPF(2, "SNDCTL_DSP_SETFRAGMENT:\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+
+		DPD(2, "val is 0x%x\n", val);
+
+		if (val == 0)
+			return -EIO;
+
+		if (file->f_mode & FMODE_WRITE) {
+			if (woinst->state & WAVE_STATE_OPEN)
+				return -EINVAL;	/* too late to change */
+
+			woinst->buffer.ossfragshift = val & 0xffff;
+			woinst->buffer.numfrags = (val >> 16) & 0xffff;
+		}
+
+		if (file->f_mode & FMODE_READ) {
+			if (wiinst->state & WAVE_STATE_OPEN)
+				return -EINVAL;	/* too late to change */
+
+			wiinst->buffer.ossfragshift = val & 0xffff;
+			wiinst->buffer.numfrags = (val >> 16) & 0xffff;
+		}
+
+		break;
+
+	case SNDCTL_COPR_LOAD:
+		{
+			copr_buffer buf;
+			u32 i;
+
+			DPF(2, "SNDCTL_COPR_LOAD:\n");
+
+			if (copy_from_user(&buf, (copr_buffer *) arg, sizeof(buf)))
+				return -EFAULT;
+
+			if ((buf.command != 1) && (buf.command != 2))
+				return -EINVAL;
+
+			if ((buf.offs < 0x100)
+			    || (buf.offs < 0x000)
+			    || (buf.offs + buf.len > 0x800) || (buf.len > 1000))
+				return -EINVAL;
+
+			if (buf.command == 1) {
+				for (i = 0; i < buf.len; i++)
+					((u32 *) buf.data)[i] = sblive_readptr(wave_dev->card, buf.offs + i, 0);
+
+				if (copy_to_user((copr_buffer *) arg, &buf, sizeof(buf)))
+					return -EFAULT;
+			} else {
+				for (i = 0; i < buf.len; i++)
+					sblive_writeptr(wave_dev->card, buf.offs + i, 0, ((u32 *) buf.data)[i]);
+			}
+			break;
+		}
+
+	default:		/* Default is unrecognized command */
+		DPD(2, "default: 0x%x\n", cmd);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static int emu10k1_audio_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
+
+	DPF(2, "emu10k1_audio_mmap()\n");
+
+	if (vma_get_pgoff(vma) != 0)
+		return -ENXIO;
+
+	if (vma->vm_flags & VM_WRITE) {
+		struct woinst *woinst = wave_dev->woinst;
+		u32 size;
+		unsigned long flags;
+		int i;
+
+		spin_lock_irqsave(&woinst->lock, flags);
+
+		if (woinst->state == WAVE_STATE_CLOSED) {
+			calculate_ofrag(woinst);
+
+			if (emu10k1_waveout_open(wave_dev) < 0) {
+				spin_unlock_irqrestore(&woinst->lock, flags);
+				ERROR();
+				return -EINVAL;
+			}
+
+			/* Now mark the pages as reserved, otherwise remap_page_range doesn't do what we want */
+			for (i = 0; i < woinst->buffer.pages; i++)
+				set_bit(PG_reserved, &mem_map[MAP_NR(woinst->buffer.addr[i])].flags);
+		}
+
+		size = vma->vm_end - vma->vm_start;
+
+		if (size > (PAGE_SIZE * woinst->buffer.pages)) {
+			spin_unlock_irqrestore(&woinst->lock, flags);
+			return -EINVAL;
+		}
+
+		for (i = 0; i < woinst->buffer.pages; i++) {
+			if (remap_page_range(vma->vm_start + (i * PAGE_SIZE), virt_to_phys(woinst->buffer.addr[i]), PAGE_SIZE, vma->vm_page_prot)) {
+				spin_unlock_irqrestore(&woinst->lock, flags);
+				return -EAGAIN;
+			}
+		}
+
+		woinst->mmapped = 1;
+
+		spin_unlock_irqrestore(&woinst->lock, flags);
+	}
+
+	if (vma->vm_flags & VM_READ) {
+		struct wiinst *wiinst = wave_dev->wiinst;
+		unsigned long flags;
+
+		spin_lock_irqsave(&wiinst->lock, flags);
+		wiinst->mmapped = 1;
+		spin_unlock_irqrestore(&wiinst->lock, flags);
+	}
+
+	return 0;
+}
+
+static int emu10k1_audio_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct emu10k1_card *card;
+	struct list_head *entry;
+	struct emu10k1_wavedevice *wave_dev;
+
+	DPF(2, "emu10k1_audio_open()\n");
+
+	/* Check for correct device to open */
+
+	list_for_each(entry, &emu10k1_devs) {
+		card = list_entry(entry, struct emu10k1_card, list);
+
+		if (!((card->audio1_num ^ minor) & ~0xf) || !((card->audio2_num ^ minor) & ~0xf))
+			break;
+	}
+
+	if (entry == &emu10k1_devs)
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+
+	if ((wave_dev = (struct emu10k1_wavedevice *)
+	     kmalloc(sizeof(struct emu10k1_wavedevice), GFP_KERNEL)) == NULL) {
+		ERROR();
+		MOD_DEC_USE_COUNT;
+		return -EINVAL;
+	}
+
+	wave_dev->card = card;
+	wave_dev->wiinst = NULL;
+	wave_dev->woinst = NULL;
+	wave_dev->enablebits = PCM_ENABLE_OUTPUT | PCM_ENABLE_INPUT;	/* Default */
+
+	if (file->f_mode & FMODE_READ) {
+		/* Recording */
+		struct wiinst *wiinst;
+
+		if ((wiinst = (struct wiinst *) kmalloc(sizeof(struct wiinst), GFP_KERNEL)) == NULL) {
+			ERROR();
+			MOD_DEC_USE_COUNT;
+			return -ENODEV;
+		}
+
+		switch (card->wavein->recsrc) {
+		case WAVERECORD_AC97:
+			wiinst->format.samplingrate = 8000;
+			wiinst->format.bitsperchannel = 16;
+			wiinst->format.channels = 1;
+			break;
+		case WAVERECORD_MIC:
+			wiinst->format.samplingrate = 8000;
+			wiinst->format.bitsperchannel = 16;
+			wiinst->format.channels = 1;
+			break;
+		case WAVERECORD_FX:
+			wiinst->format.samplingrate = 48000;
+			wiinst->format.bitsperchannel = 16;
+			wiinst->format.channels = 2;
+			break;
+		default:
+			BUG();
+			break;
+		}
+
+		wiinst->state = WAVE_STATE_CLOSED;
+
+		wiinst->recsrc = card->wavein->recsrc;
+		wiinst->buffer.ossfragshift = 0;
+		wiinst->buffer.fragment_size = 0;
+		wiinst->buffer.numfrags = 0;
+
+		init_waitqueue_head(&wiinst->wait_queue);
+
+		wiinst->mmapped = 0;
+		wiinst->total_recorded = 0;
+		wiinst->blocks = 0;
+		wiinst->lock = SPIN_LOCK_UNLOCKED;
+		tasklet_init(&wiinst->timer.tasklet, emu10k1_wavein_bh, (unsigned long) wave_dev);
+		wave_dev->wiinst = wiinst;
+		emu10k1_wavein_setformat(wave_dev, &wiinst->format);
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		struct woinst *woinst;
+
+		if ((woinst = (struct woinst *) kmalloc(sizeof(struct woinst), GFP_KERNEL)) == NULL) {
+			ERROR();
+			MOD_DEC_USE_COUNT;
+			return -ENODEV;
+		}
+
+		if (wave_dev->wiinst != NULL) {
+			woinst->format = wave_dev->wiinst->format;
+		} else {
+			woinst->format.samplingrate = 8000;
+			woinst->format.bitsperchannel = 8;
+			woinst->format.channels = 1;
+		}
+
+		woinst->state = WAVE_STATE_CLOSED;
+
+		woinst->buffer.fragment_size = 0;
+		woinst->buffer.ossfragshift = 0;
+		woinst->buffer.numfrags = 0;
+		woinst->device = (card->audio2_num == minor);
+
+		init_waitqueue_head(&woinst->wait_queue);
+
+		woinst->mmapped = 0;
+		woinst->total_copied = 0;
+		woinst->total_played = 0;
+		woinst->blocks = 0;
+		woinst->lock = SPIN_LOCK_UNLOCKED;
+		tasklet_init(&woinst->timer.tasklet, emu10k1_waveout_bh, (unsigned long) wave_dev);
+		wave_dev->woinst = woinst;
+		emu10k1_waveout_setformat(wave_dev, &woinst->format);
+
+#ifdef PRIVATE_PCM_VOLUME
+		{
+			int i;
+			int j = -1;
+
+			/*
+			 * find out if we've already been in this table
+			 * xmms reopens dsp on every move of slider
+			 * this way we keep the same local pcm for such
+			 * process
+			 */
+			for (i = 0; i < MAX_PCM_CHANNELS; i++) {
+				if (sblive_pcm_volume[i].files == current->files)
+					break;
+				// here we should select last used memeber
+				// improve me in case its not sufficient
+				if (j < 0 && !sblive_pcm_volume[i].opened)
+					j = i;
+			}
+			// current task not found
+			if (i == MAX_PCM_CHANNELS) {
+				// add new entry
+				if (j < 0)
+					printk(KERN_WARNING "emu10k1: too many writters!\n");
+				i = (j >= 0) ? j : 0;
+				DPD(2, "new pcm private %p\n", current->files);
+				sblive_pcm_volume[i].files = current->files;
+				sblive_pcm_volume[i].mixer = pcm_last_mixer;
+				sblive_pcm_volume[i].attn_l = 0;
+				sblive_pcm_volume[i].attn_r = 0;
+				sblive_pcm_volume[i].channel_l = NUM_G;
+				sblive_pcm_volume[i].channel_r = NUM_G;
+			} else
+				DPD(2, "old pcm private %p  0x%x\n", current->files,
+				    sblive_pcm_volume[i].mixer);
+
+			sblive_pcm_volume[i].opened++;
+		}
+#endif
+	}
+
+	file->private_data = (void *) wave_dev;
+
+	return 0;
+}
+
+static int emu10k1_audio_release(struct inode *inode, struct file *file)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
+	struct emu10k1_card *card = wave_dev->card;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_audio_release()\n");
+
+	if (file->f_mode & FMODE_WRITE) {
+		struct woinst *woinst = wave_dev->woinst;
+
+		spin_lock_irqsave(&woinst->lock, flags);
+
+		if (woinst->state & WAVE_STATE_OPEN) {
+			if (woinst->state & WAVE_STATE_STARTED) {
+				if (!(file->f_flags & O_NONBLOCK)) {
+					while (!signal_pending(current)
+					       && (woinst->total_played < woinst->total_copied)) {
+						DPF(4, "Buffer hasn't been totally played, sleep....\n");
+						spin_unlock_irqrestore(&woinst->lock, flags);
+						interruptible_sleep_on(&woinst->wait_queue);
+						spin_lock_irqsave(&woinst->lock, flags);
+					}
+				}
+			}
+
+			if (woinst->mmapped) {
+				int i;
+
+				/* Undo marking the pages as reserved */
+				for (i = 0; i < woinst->buffer.pages; i++)
+					set_bit(PG_reserved, &mem_map[MAP_NR(woinst->buffer.addr[i])].flags);
+			}
+
+			emu10k1_waveout_close(wave_dev);
+		}
+#ifdef PRIVATE_PCM_VOLUME
+		{
+			int i;
+
+			/* mark as closed
+			 * NOTE: structure remains unchanged for next reopen */
+			for (i = 0; i < MAX_PCM_CHANNELS; i++) {
+				if (sblive_pcm_volume[i].files == current->files) {
+					sblive_pcm_volume[i].opened--;
+					break;
+				}
+			}
+		}
+#endif
+		spin_unlock_irqrestore(&woinst->lock, flags);
+		/* wait for the tasklet (bottom-half) to finish */
+		tasklet_unlock_wait(&woinst->timer.tasklet);
+		kfree(wave_dev->woinst);
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		struct wiinst *wiinst = wave_dev->wiinst;
+
+		spin_lock_irqsave(&wiinst->lock, flags);
+
+		if (wiinst->state & WAVE_STATE_OPEN)
+			emu10k1_wavein_close(wave_dev);
+
+		spin_unlock_irqrestore(&wiinst->lock, flags);
+		tasklet_unlock_wait(&wiinst->timer.tasklet);
+		kfree(wave_dev->wiinst);
+	}
+
+	kfree(wave_dev);
+
+	wake_up_interruptible(&card->open_wait);
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static unsigned int emu10k1_audio_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) file->private_data;
+	struct woinst *woinst = wave_dev->woinst;
+	struct wiinst *wiinst = wave_dev->wiinst;
+	unsigned int mask = 0;
+	u32 bytestocopy;
+	unsigned long flags;
+
+	DPF(4, "emu10k1_audio_poll()\n");
+
+	if (file->f_mode & FMODE_WRITE)
+		poll_wait(file, &woinst->wait_queue, wait);
+
+	if (file->f_mode & FMODE_READ)
+		poll_wait(file, &wiinst->wait_queue, wait);
+
+	if (file->f_mode & FMODE_WRITE) {
+		spin_lock_irqsave(&woinst->lock, flags);
+
+		if (woinst->state & WAVE_STATE_OPEN) {
+			emu10k1_waveout_update(woinst);
+			emu10k1_waveout_getxfersize(woinst, &bytestocopy);
+
+			if (bytestocopy >= woinst->buffer.fragment_size)
+				mask |= POLLOUT | POLLWRNORM;
+		} else
+			mask |= POLLOUT | POLLWRNORM;
+
+		if(woinst->mmapped) {
+			spin_unlock_irqrestore(&woinst->lock, flags);
+			return mask;
+		}
+
+		spin_unlock_irqrestore(&woinst->lock, flags);
+	}
+
+	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_STARTED)) {
+			wave_dev->enablebits |= PCM_ENABLE_INPUT;
+			emu10k1_wavein_start(wave_dev);
+		}
+		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);
+	}
+
+	return mask;
+}
+
+static void calculate_ofrag(struct woinst *woinst)
+{
+	struct waveout_buffer *buffer = &woinst->buffer;
+	u32 fragsize;
+
+	if (buffer->fragment_size)
+		return;
+
+	if (!buffer->ossfragshift) {
+		fragsize = (woinst->format.bytespersec * WAVEOUT_DEFAULTFRAGLEN) / 1000 - 1;
+
+		while (fragsize) {
+			fragsize >>= 1;
+			buffer->ossfragshift++;
+		}
+	}
+
+	if (buffer->ossfragshift < WAVEOUT_MINFRAGSHIFT)
+		buffer->ossfragshift = WAVEOUT_MINFRAGSHIFT;
+
+	buffer->fragment_size = 1 << buffer->ossfragshift;
+
+	if (!buffer->numfrags) {
+		u32 numfrags;
+
+		numfrags = (woinst->format.bytespersec * WAVEOUT_DEFAULTBUFLEN) / (buffer->fragment_size * 1000) - 1;
+
+		buffer->numfrags = 1;
+
+		while (numfrags) {
+			numfrags >>= 1;
+			buffer->numfrags <<= 1;
+		}
+	}
+
+	if (buffer->numfrags < MINFRAGS)
+		buffer->numfrags = MINFRAGS;
+
+	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;
+
+	buffer->size = buffer->fragment_size * buffer->numfrags;
+	buffer->pages = buffer->size / PAGE_SIZE + ((buffer->size % PAGE_SIZE) ? 1 : 0);
+
+	DPD(2, " calculated playback fragment_size -> %d\n", buffer->fragment_size);
+	DPD(2, " calculated playback numfrags -> %d\n", buffer->numfrags);
+
+	return;
+}
+
+static void calculate_ifrag(struct wiinst *wiinst)
+{
+	struct wavein_buffer *buffer = &wiinst->buffer;
+	u32 fragsize, bufsize, size[4];
+	int i, j;
+
+	if (buffer->fragment_size)
+		return;
+
+	if (!buffer->ossfragshift) {
+		fragsize = (wiinst->format.bytespersec * WAVEIN_DEFAULTFRAGLEN) / 1000 - 1;
+
+		while (fragsize) {
+			fragsize >>= 1;
+			buffer->ossfragshift++;
+		}
+	}
+
+	if (buffer->ossfragshift < WAVEIN_MINFRAGSHIFT)
+		buffer->ossfragshift = WAVEIN_MINFRAGSHIFT;
+
+	buffer->fragment_size = 1 << buffer->ossfragshift;
+
+	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 * 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;
+
+	bufsize = buffer->fragment_size * buffer->numfrags;
+
+	if (bufsize >= 0x10000) {
+		buffer->size = 0x10000;
+		buffer->sizeregval = 0x1f;
+	} else {
+		buffer->size = 0;
+		size[0] = 384;
+		size[1] = 448;
+		size[2] = 512;
+		size[3] = 640;
+
+		for (i = 0; i < 8; i++)
+			for (j = 0; j < 4; j++)
+				if (bufsize >= size[j]) {
+					buffer->size = size[j];
+					size[j] *= 2;
+					buffer->sizeregval = i * 4 + j + 1;
+				} else
+					goto exitloop;
+	      exitloop:
+		if (buffer->size == 0) {
+			buffer->size = 384;
+			buffer->sizeregval = 0x01;
+		}
+	}
+
+	buffer->numfrags = buffer->size / buffer->fragment_size;
+
+	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);
+	DPD(2, " buffer size register -> 0x%2x\n", buffer->sizeregval);
+
+	return;
+}
+
+void emu10k1_wavein_bh(unsigned long refdata)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
+	struct wiinst *wiinst = wave_dev->wiinst;
+	u32 bytestocopy;
+	unsigned long flags;
+
+	spin_lock_irqsave(&wiinst->lock, flags);
+
+	if (!(wiinst->state & WAVE_STATE_STARTED)) {
+		spin_unlock_irqrestore(&wiinst->lock, flags);
+		return;
+	}
+
+	emu10k1_wavein_update(wave_dev->card, wiinst);
+
+	if (wiinst->mmapped) {
+		spin_unlock_irqrestore(&wiinst->lock, flags);
+		return;
+	}
+
+	emu10k1_wavein_getxfersize(wiinst, &bytestocopy);
+
+	spin_unlock_irqrestore(&wiinst->lock, flags);
+
+	if (bytestocopy >= wiinst->buffer.fragment_size)
+		wake_up_interruptible(&wiinst->wait_queue);
+	else
+		DPD(4, "Not enough transfer size, %d\n", bytestocopy);
+
+	return;
+}
+
+void emu10k1_waveout_bh(unsigned long refdata)
+{
+	struct emu10k1_wavedevice *wave_dev = (struct emu10k1_wavedevice *) refdata;
+	struct woinst *woinst = wave_dev->woinst;
+	u32 bytestocopy;
+	unsigned long flags;
+
+	spin_lock_irqsave(&woinst->lock, flags);
+
+	if (!(woinst->state & WAVE_STATE_STARTED)) {
+		spin_unlock_irqrestore(&woinst->lock, flags);
+		return;
+	}
+
+	emu10k1_waveout_update(woinst);
+	emu10k1_waveout_getxfersize(woinst, &bytestocopy);
+
+	if (woinst->buffer.fill_silence) {
+		spin_unlock_irqrestore(&woinst->lock, flags);
+		emu10k1_waveout_fillsilence(woinst);
+	} else
+		spin_unlock_irqrestore(&woinst->lock, flags);
+
+	if (bytestocopy >= woinst->buffer.fragment_size)
+		wake_up_interruptible(&woinst->wait_queue);
+	else
+		DPD(4, "Not enough transfer size -> %d\n", bytestocopy);
+
+	return;
+}
+
+struct file_operations emu10k1_audio_fops = {
+	llseek:emu10k1_audio_llseek,
+	read:emu10k1_audio_read,
+	write:emu10k1_audio_write,
+	poll:emu10k1_audio_poll,
+	ioctl:emu10k1_audio_ioctl,
+	mmap:emu10k1_audio_mmap,
+	open:emu10k1_audio_open,
+	release:emu10k1_audio_release,
+};
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/audio.h linux.17p18/drivers/sound/emu10k1/audio.h
--- linux.vanilla/drivers/sound/emu10k1/audio.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/audio.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,49 @@
+/*
+ **********************************************************************
+ *     audio.c -- /dev/dsp interface for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999	    Alan Cox        cleaned up types/leaks
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _AUDIO_H
+#define _AUDIO_H
+
+#define MINFRAGS	2	/* _don't_ got bellow 2 */
+
+struct emu10k1_wavedevice
+{
+        struct emu10k1_card *card;
+        struct wiinst *wiinst;
+        struct woinst *woinst;
+        u16 enablebits;
+};
+
+void emu10k1_waveout_bh(unsigned long);
+void emu10k1_wavein_bh(unsigned long);
+
+#endif /* _AUDIO_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardmi.c linux.17p18/drivers/sound/emu10k1/cardmi.c
--- linux.vanilla/drivers/sound/emu10k1/cardmi.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardmi.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,818 @@
+
+/*
+ **********************************************************************
+ *     sblive_mi.c - MIDI UART input HAL for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox        clean up
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include <linux/malloc.h>
+#include <linux/sched.h>
+
+#include "hwaccess.h"
+#include "8010.h"
+#include "cardmi.h"
+#include "irqmgr.h"
+
+static struct {
+	int (*Fn) (struct emu10k1_mpuin *, u8);
+} midistatefn[] = {
+
+	{
+	sblive_miStateParse}, {
+	sblive_miState3Byte},	/* 0x8n, 0x9n, 0xAn, 0xBn, 0xEn */
+	{
+	sblive_miState3ByteKey},	/* Byte 1                       */
+	{
+	sblive_miState3ByteVel},	/* Byte 2                       */
+	{
+	sblive_miState2Byte},	/* 0xCn, 0xDn                   */
+	{
+	sblive_miState2ByteKey},	/* Byte 1                       */
+	{
+	sblive_miStateSysCommon2},	/* 0xF1 , 0xF3                  */
+	{
+	sblive_miStateSysCommon2Key},	/* 0xF1 , 0xF3, Byte 1          */
+	{
+	sblive_miStateSysCommon3},	/* 0xF2                         */
+	{
+	sblive_miStateSysCommon3Key},	/* 0xF2 , Byte 1                */
+	{
+	sblive_miStateSysCommon3Vel},	/* 0xF2 , Byte 2                */
+	{
+	sblive_miStateSysExNorm},	/* 0xF0, 0xF7, Normal mode      */
+	{
+	sblive_miStateSysReal}	/* 0xF4 - 0xF6 ,0xF8 - 0xFF     */
+};
+
+/* Installs the IRQ handler for the MPU in port                 */
+
+/* and initialize parameters                                    */
+
+int emu10k1_mpuin_open(struct emu10k1_card *card, struct midi_openinfo *openinfo)
+{
+	struct emu10k1_mpuin *card_mpuin = card->mpuin;
+
+	DPF(2, "emu10k1_mpuin_open\n");
+
+	if (!(card_mpuin->status & FLAGS_AVAILABLE))
+		return CTSTATUS_INUSE;
+
+	/* Copy open info and mark channel as in use */
+	card_mpuin->openinfo = *openinfo;
+	card_mpuin->status &= ~FLAGS_AVAILABLE;	/* clear */
+	card_mpuin->status |= FLAGS_READY;	/* set */
+	card_mpuin->status &= ~FLAGS_MIDM_STARTED;	/* clear */
+	card_mpuin->firstmidiq = NULL;
+	card_mpuin->lastmidiq = NULL;
+	card_mpuin->qhead = 0;
+	card_mpuin->qtail = 0;
+
+	sblive_miStateInit(card_mpuin);
+
+	emu10k1_mpu_reset(card);
+	emu10k1_mpu_acquire(card);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int emu10k1_mpuin_close(struct emu10k1_card *card)
+{
+	struct emu10k1_mpuin *card_mpuin = card->mpuin;
+
+	DPF(2, "emu10k1_mpuin_close()\n");
+
+	/* Check if there are pending input SysEx buffers */
+	if (card_mpuin->firstmidiq != NULL) {
+		ERROR();
+		return CTSTATUS_ERROR;
+	}
+
+	/* Disable RX interrupt */
+	emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
+
+	emu10k1_mpu_release(card);
+
+	card_mpuin->status |= FLAGS_AVAILABLE;	/* set */
+	card_mpuin->status &= ~FLAGS_MIDM_STARTED;	/* clear */
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* Adds MIDI buffer to local queue list                         */
+
+int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *card_mpuin, struct midi_hdr *midihdr)
+{
+	struct midi_queue *midiq;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_mpuin_add_buffer()\n");
+
+	/* Update MIDI buffer flags */
+	midihdr->flags |= MIDIBUF_INQUEUE;	/* set */
+	midihdr->flags &= ~MIDIBUF_DONE;	/* clear */
+
+	if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_ATOMIC)) == NULL) {
+		/* Message lost */
+		return CTSTATUS_ERROR;
+	}
+
+	midiq->next = NULL;
+	midiq->qtype = 1;
+	midiq->length = midihdr->bufferlength;
+	midiq->sizeLeft = midihdr->bufferlength;
+	midiq->midibyte = midihdr->data;
+	midiq->refdata = (unsigned long) midihdr;
+
+	spin_lock_irqsave(&card_mpuin->lock, flags);
+
+	if (card_mpuin->firstmidiq == NULL) {
+		card_mpuin->firstmidiq = midiq;
+		card_mpuin->lastmidiq = midiq;
+	} else {
+		(card_mpuin->lastmidiq)->next = midiq;
+		card_mpuin->lastmidiq = midiq;
+	}
+
+	spin_unlock_irqrestore(&card_mpuin->lock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* First set the Time Stamp if MIDI IN has not started.         */
+
+/* Then enable RX Irq.                                          */
+
+int emu10k1_mpuin_start(struct emu10k1_card *card)
+{
+	struct emu10k1_mpuin *card_mpuin = card->mpuin;
+	u8 dummy;
+
+	DPF(2, "emu10k1_mpuin_start()\n");
+
+	/* Set timestamp if not set */
+	if (card_mpuin->status & FLAGS_MIDM_STARTED) {
+		DPF(2, "Time Stamp not changed\n");
+	} else {
+		while (emu10k1_mpu_read_data(card, &dummy) == CTSTATUS_SUCCESS);
+
+		card_mpuin->status |= FLAGS_MIDM_STARTED;	/* set */
+
+		/* Set new time stamp */
+		card_mpuin->timestart = (jiffies * 1000) / HZ;
+		DPD(2, "New Time Stamp = %d\n", card_mpuin->timestart);
+
+		card_mpuin->qhead = 0;
+		card_mpuin->qtail = 0;
+
+		emu10k1_irq_enable(card, INTE_MIDIRXENABLE);
+	}
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* Disable the RX Irq.  If a partial recorded buffer            */
+
+/* exist, send it up to IMIDI level.                            */
+
+int emu10k1_mpuin_stop(struct emu10k1_card *card)
+{
+	struct emu10k1_mpuin *card_mpuin = card->mpuin;
+	struct midi_queue *midiq;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_mpuin_stop()\n");
+
+	emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
+
+	card_mpuin->status &= ~FLAGS_MIDM_STARTED;	/* clear */
+
+	if (card_mpuin->firstmidiq) {
+		spin_lock_irqsave(&card_mpuin->lock, flags);
+
+		midiq = card_mpuin->firstmidiq;
+		if (midiq != NULL) {
+			if (midiq->sizeLeft == midiq->length)
+				midiq = NULL;
+			else {
+				card_mpuin->firstmidiq = midiq->next;
+				if (card_mpuin->firstmidiq == NULL)
+					card_mpuin->lastmidiq = NULL;
+			}
+		}
+
+		spin_unlock_irqrestore(&card_mpuin->lock, flags);
+
+		if (midiq) {
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
+			kfree(midiq);
+		}
+	}
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* Disable the RX Irq.  If any buffer                           */
+
+/* exist, send it up to IMIDI level.                            */
+int emu10k1_mpuin_reset(struct emu10k1_card *card)
+{
+	struct emu10k1_mpuin *card_mpuin = card->mpuin;
+	struct midi_queue *midiq;
+
+	DPF(2, "emu10k1_mpuin_reset()\n");
+
+	emu10k1_irq_disable(card, INTE_MIDIRXENABLE);
+
+	while (card_mpuin->firstmidiq) {
+		midiq = card_mpuin->firstmidiq;
+		card_mpuin->firstmidiq = midiq->next;
+
+		if (midiq->sizeLeft == midiq->length)
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
+		else
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
+
+		kfree(midiq);
+	}
+
+	card_mpuin->lastmidiq = NULL;
+	card_mpuin->status &= ~FLAGS_MIDM_STARTED;
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* Passes the message with the data back to the client          */
+
+/* via IRQ & DPC callbacks to Ring 3                            */
+int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid)
+{
+	unsigned long timein;
+	struct midi_queue *midiq;
+	unsigned long callback_msg[3];
+	struct midi_hdr *midihdr;
+
+	/* Called during ISR. The data & code touched are:
+	 * 1. card_mpuin
+	 * 2. The function to be called
+	 */
+
+	timein = card_mpuin->timein;
+	if (card_mpuin->timestart <= timein)
+		callback_msg[0] = timein - card_mpuin->timestart;
+	else
+		callback_msg[0] = (~0x0L - card_mpuin->timestart) + timein;
+
+	if (msg == ICARDMIDI_INDATA || msg == ICARDMIDI_INDATAERROR) {
+		callback_msg[1] = data;
+		callback_msg[2] = bytesvalid;
+		DPD(2, "emu10k1_mpuin_callback: midimsg = %lx\n", data);
+	} else {
+		midiq = (struct midi_queue *) data;
+		midihdr = (struct midi_hdr *) midiq->refdata;
+
+		callback_msg[1] = midiq->length - midiq->sizeLeft;
+		callback_msg[2] = midiq->refdata;
+		midihdr->flags &= ~MIDIBUF_INQUEUE;
+		midihdr->flags |= MIDIBUF_DONE;
+
+		midihdr->bytesrecorded = midiq->length - midiq->sizeLeft;
+	}
+
+	/* Notify client that Sysex buffer has been sent */
+	emu10k1_midi_callback(msg, card_mpuin->openinfo.refdata, callback_msg);
+
+	return CTSTATUS_SUCCESS;
+}
+
+void emu10k1_mpuin_bh(unsigned long refdata)
+{
+	u8 data;
+	unsigned idx;
+	struct emu10k1_mpuin *card_mpuin = (struct emu10k1_mpuin *) refdata;
+	unsigned long flags;
+
+	while (card_mpuin->qhead != card_mpuin->qtail) {
+		spin_lock_irqsave(&card_mpuin->lock, flags);
+		idx = card_mpuin->qhead;
+		data = card_mpuin->midiq[idx].data;
+		card_mpuin->timein = card_mpuin->midiq[idx].timein;
+		idx = (idx + 1) % MIDIIN_MAX_BUFFER_SIZE;
+		card_mpuin->qhead = idx;
+		spin_unlock_irqrestore(&card_mpuin->lock, flags);
+
+		sblive_miStateEntry(card_mpuin, data);
+	}
+
+	return;
+}
+
+/* IRQ callback handler routine for the MPU in port */
+
+int emu10k1_mpuin_irqhandler(struct emu10k1_card *card)
+{
+	unsigned idx;
+	unsigned count;
+	u8 MPUIvalue;
+	struct emu10k1_mpuin *card_mpuin = card->mpuin;
+
+	/* IRQ service routine. The data and code touched are:
+	 * 1. card_mpuin
+	 */
+
+	count = 0;
+	idx = card_mpuin->qtail;
+
+	while (1) {
+		if (emu10k1_mpu_read_data(card, &MPUIvalue) == CTSTATUS_SUCCESS) {
+			++count;
+			card_mpuin->midiq[idx].data = MPUIvalue;
+			card_mpuin->midiq[idx].timein = (jiffies * 1000) / HZ;
+			idx = (idx + 1) % MIDIIN_MAX_BUFFER_SIZE;
+		} else {
+			break;
+		}
+	}
+
+	if (count) {
+		card_mpuin->qtail = idx;
+
+		tasklet_hi_schedule(&card_mpuin->tasklet);
+	}
+
+	return CTSTATUS_SUCCESS;
+}
+
+/*****************************************************************************/
+
+/*   Supporting functions for Midi-In Interpretation State Machine           */
+
+/*****************************************************************************/
+
+/* FIXME: This should be a macro */
+int sblive_miStateInit(struct emu10k1_mpuin *card_mpuin)
+{
+	card_mpuin->status = 0;	/* For MIDI running status */
+	card_mpuin->fstatus = 0;	/* For 0xFn status only */
+	card_mpuin->curstate = STIN_PARSE;
+	card_mpuin->laststate = STIN_PARSE;
+	card_mpuin->data = 0;
+	card_mpuin->timestart = 0;
+	card_mpuin->timein = 0;
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* FIXME: This should be a macro */
+int sblive_miStateEntry(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
+}
+
+int sblive_miStateParse(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	switch (data & 0xf0) {
+	case 0x80:
+	case 0x90:
+	case 0xA0:
+	case 0xB0:
+	case 0xE0:
+		card_mpuin->curstate = STIN_3BYTE;
+		break;
+
+	case 0xC0:
+	case 0xD0:
+		card_mpuin->curstate = STIN_2BYTE;
+		break;
+
+	case 0xF0:
+		/* System messages do not affect the previous running status! */
+		switch (data & 0x0f) {
+		case 0x0:
+			card_mpuin->laststate = card_mpuin->curstate;
+			card_mpuin->curstate = STIN_SYS_EX_NORM;
+
+			if (card_mpuin->firstmidiq) {
+				struct midi_queue *midiq;
+
+				midiq = card_mpuin->firstmidiq;
+				*midiq->midibyte = data;
+				--midiq->sizeLeft;
+				++midiq->midibyte;
+			}
+
+			return CTSTATUS_NEXT_BYTE;
+
+		case 0x7:
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, 0xf7, 0);
+			return CTSTATUS_ERROR;
+
+		case 0x2:
+			card_mpuin->laststate = card_mpuin->curstate;
+			card_mpuin->curstate = STIN_SYS_COMMON_3;
+			break;
+
+		case 0x1:
+		case 0x3:
+			card_mpuin->laststate = card_mpuin->curstate;
+			card_mpuin->curstate = STIN_SYS_COMMON_2;
+			break;
+
+		default:
+			/* includes 0xF4 - 0xF6, 0xF8 - 0xFF */
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+		}
+
+		break;
+
+	default:
+		DPF(2, "BUG: default case hit\n");
+		return CTSTATUS_ERROR;
+	}
+
+	return midistatefn[card_mpuin->curstate].Fn(card_mpuin, data);
+}
+
+int sblive_miState3Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	u8 temp = data & 0xf0;
+
+	if (temp < 0x80) {
+		return midistatefn[STIN_3BYTE_KEY].Fn(card_mpuin, data);
+	} else if (temp <= 0xe0 && temp != 0xc0 && temp != 0xd0) {
+		card_mpuin->status = data;
+		card_mpuin->curstate = STIN_3BYTE_KEY;
+
+		return CTSTATUS_NEXT_BYTE;
+	}
+
+	return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
+}
+
+int sblive_miState3ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
+
+/* byte 1 */
+{
+	unsigned long tmp;
+
+	if (data > 0x7f) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = STIN_PARSE;
+		tmp = ((unsigned long) data) << 8;
+		tmp |= (unsigned long) card_mpuin->status;
+
+		emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
+
+		return CTSTATUS_ERROR;
+	}
+
+	card_mpuin->data = data;
+	card_mpuin->curstate = STIN_3BYTE_VEL;
+
+	return CTSTATUS_NEXT_BYTE;
+}
+
+int sblive_miState3ByteVel(struct emu10k1_mpuin *card_mpuin, u8 data)
+
+/* byte 2 */
+{
+	unsigned long tmp;
+
+	if (data > 0x7f) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = STIN_PARSE;
+		tmp = ((unsigned long) data) << 8;
+		tmp |= card_mpuin->data;
+		tmp = tmp << 8;
+		tmp |= (unsigned long) card_mpuin->status;
+
+		emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
+
+		return CTSTATUS_ERROR;
+	}
+
+	card_mpuin->curstate = STIN_3BYTE;
+	tmp = (unsigned long) data;
+	tmp = tmp << 8;
+	tmp |= (unsigned long) card_mpuin->data;
+	tmp = tmp << 8;
+	tmp |= (unsigned long) card_mpuin->status;
+
+	emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 3);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int sblive_miState2Byte(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	u8 temp = data & 0xf0;
+
+	if ((temp == 0xc0) || (temp == 0xd0)) {
+		card_mpuin->status = data;
+		card_mpuin->curstate = STIN_2BYTE_KEY;
+
+		return CTSTATUS_NEXT_BYTE;
+	}
+
+	if (temp < 0x80)
+		return midistatefn[STIN_2BYTE_KEY].Fn(card_mpuin, data);
+
+	return midistatefn[STIN_PARSE].Fn(card_mpuin, data);
+}
+
+int sblive_miState2ByteKey(struct emu10k1_mpuin *card_mpuin, u8 data)
+
+/* byte 1 */
+{
+	unsigned long tmp;
+
+	if (data > 0x7f) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = STIN_PARSE;
+		tmp = (unsigned long) data;
+		tmp = tmp << 8;
+		tmp |= (unsigned long) card_mpuin->status;
+
+		emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
+
+		return CTSTATUS_ERROR;
+	}
+
+	card_mpuin->curstate = STIN_2BYTE;
+	tmp = (unsigned long) data;
+	tmp = tmp << 8;
+	tmp |= (unsigned long) card_mpuin->status;
+
+	emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 2);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int sblive_miStateSysCommon2(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	card_mpuin->fstatus = data;
+	card_mpuin->curstate = STIN_SYS_COMMON_2_KEY;
+
+	return CTSTATUS_NEXT_BYTE;
+}
+
+int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *card_mpuin, u8 data)
+
+/* byte 1 */
+{
+	unsigned long tmp;
+
+	if (data > 0x7f) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = card_mpuin->laststate;
+		tmp = (unsigned long) data;
+		tmp = tmp << 8;
+		tmp |= (unsigned long) card_mpuin->fstatus;
+
+		emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
+
+		return CTSTATUS_ERROR;
+	}
+
+	card_mpuin->curstate = card_mpuin->laststate;
+	tmp = (unsigned long) data;
+	tmp = tmp << 8;
+	tmp |= (unsigned long) card_mpuin->fstatus;
+
+	emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 2);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int sblive_miStateSysCommon3(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	card_mpuin->fstatus = data;
+	card_mpuin->curstate = STIN_SYS_COMMON_3_KEY;
+
+	return CTSTATUS_NEXT_BYTE;
+}
+
+int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *card_mpuin, u8 data)
+
+/* byte 1 */
+{
+	unsigned long tmp;
+
+	if (data > 0x7f) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = card_mpuin->laststate;
+		tmp = (unsigned long) data;
+		tmp = tmp << 8;
+		tmp |= (unsigned long) card_mpuin->fstatus;
+
+		emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
+
+		return CTSTATUS_ERROR;
+	}
+
+	card_mpuin->data = data;
+	card_mpuin->curstate = STIN_SYS_COMMON_3_VEL;
+
+	return CTSTATUS_NEXT_BYTE;
+}
+
+int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *card_mpuin, u8 data)
+
+/* byte 2 */
+{
+	unsigned long tmp;
+
+	if (data > 0x7f) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = card_mpuin->laststate;
+		tmp = (unsigned long) data;
+		tmp = tmp << 8;
+		tmp |= (unsigned long) card_mpuin->data;
+		tmp = tmp << 8;
+		tmp |= (unsigned long) card_mpuin->fstatus;
+
+		emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATAERROR, tmp, 0);
+
+		return CTSTATUS_ERROR;
+	}
+
+	card_mpuin->curstate = card_mpuin->laststate;
+	tmp = (unsigned long) data;
+	tmp = tmp << 8;
+	tmp |= (unsigned long) card_mpuin->data;
+	tmp = tmp << 8;
+	tmp |= (unsigned long) card_mpuin->fstatus;
+
+	emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, tmp, 3);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int sblive_miStateSysExNorm(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	unsigned long flags;
+
+	if ((data > 0x7f) && (data != 0xf7)) {
+		/* Real-time messages check */
+		if (data > 0xf7)
+			return midistatefn[STIN_SYS_REAL].Fn(card_mpuin, data);
+
+		/* Invalid Data! */
+		DPF(2, "Invalid data!\n");
+
+		card_mpuin->curstate = card_mpuin->laststate;
+
+		if (card_mpuin->firstmidiq) {
+			struct midi_queue *midiq;
+
+			midiq = card_mpuin->firstmidiq;
+			*midiq->midibyte = data;
+			--midiq->sizeLeft;
+			++midiq->midibyte;
+
+			spin_lock_irqsave(&card_mpuin->lock, flags);
+
+			card_mpuin->firstmidiq = midiq->next;
+			if (card_mpuin->firstmidiq == NULL)
+				card_mpuin->lastmidiq = NULL;
+
+			spin_unlock_irqrestore(&card_mpuin->lock, flags);
+
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGERROR, (unsigned long) midiq, 0);
+
+			kfree(midiq);
+		}
+
+		return CTSTATUS_ERROR;
+	}
+
+	if (card_mpuin->firstmidiq) {
+		struct midi_queue *midiq;
+
+		midiq = card_mpuin->firstmidiq;
+		*midiq->midibyte = data;
+		--midiq->sizeLeft;
+		++midiq->midibyte;
+	}
+
+	if (data == 0xf7) {
+		/* End of Sysex buffer */
+		/* Send down the buffer */
+
+		card_mpuin->curstate = card_mpuin->laststate;
+
+		if (card_mpuin->firstmidiq) {
+			struct midi_queue *midiq;
+
+			midiq = card_mpuin->firstmidiq;
+
+			spin_lock_irqsave(&card_mpuin->lock, flags);
+
+			card_mpuin->firstmidiq = midiq->next;
+			if (card_mpuin->firstmidiq == NULL)
+				card_mpuin->lastmidiq = NULL;
+
+			spin_unlock_irqrestore(&card_mpuin->lock, flags);
+
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
+
+			kfree(midiq);
+		}
+
+		return CTSTATUS_SUCCESS;
+	}
+
+	if (card_mpuin->firstmidiq) {
+		struct midi_queue *midiq;
+
+		midiq = card_mpuin->firstmidiq;
+
+		if (midiq->sizeLeft == 0) {
+			/* Special case */
+
+			spin_lock_irqsave(&card_mpuin->lock, flags);
+
+			card_mpuin->firstmidiq = midiq->next;
+			if (card_mpuin->firstmidiq == NULL)
+				card_mpuin->lastmidiq = NULL;
+
+			spin_unlock_irqrestore(&card_mpuin->lock, flags);
+
+			emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INLONGDATA, (unsigned long) midiq, 0);
+
+			kfree(midiq);
+
+			return CTSTATUS_NEXT_BYTE;
+		}
+	}
+
+	return CTSTATUS_NEXT_BYTE;
+}
+
+int sblive_miStateSysReal(struct emu10k1_mpuin *card_mpuin, u8 data)
+{
+	emu10k1_mpuin_callback(card_mpuin, ICARDMIDI_INDATA, data, 1);
+
+	return CTSTATUS_NEXT_BYTE;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardmi.h linux.17p18/drivers/sound/emu10k1/cardmi.h
--- linux.vanilla/drivers/sound/emu10k1/cardmi.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardmi.h	Tue Aug  1 18:30:11 2000
@@ -0,0 +1,114 @@
+/*
+ **********************************************************************
+ *     sblive_mi.h
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox        cleaned up
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _CARDMI_H
+#define _CARDMI_H
+
+#include "icardmid.h"
+#include <linux/interrupt.h>
+
+typedef enum
+{
+	STIN_PARSE = 0,
+	STIN_3BYTE,                     /* 0x80, 0x90, 0xA0, 0xB0, 0xE0 */
+	STIN_3BYTE_KEY,                 /* Byte 1 */
+	STIN_3BYTE_VEL,                 /* Byte 1 */
+	STIN_2BYTE,                     /* 0xC0, 0xD0 */
+	STIN_2BYTE_KEY,                 /* Byte 1 */
+	STIN_SYS_COMMON_2,              /* 0xF1, 0xF3  */
+	STIN_SYS_COMMON_2_KEY,
+	STIN_SYS_COMMON_3,              /* 0xF2 */
+	STIN_SYS_COMMON_3_KEY,
+	STIN_SYS_COMMON_3_VEL,
+	STIN_SYS_EX_NORM,               /* 0xF0, Normal mode */
+	STIN_SYS_REAL
+} midi_in_state;
+
+
+/* flags for card MIDI in object */
+#define FLAGS_MIDM_STARTED          0x00001000      // Data has started to come in after Midm Start
+#define MIDIIN_MAX_BUFFER_SIZE      200             // Definition for struct emu10k1_mpuin
+
+struct midi_data
+{
+	u8 data;
+	u32 timein;
+};
+
+struct emu10k1_mpuin
+{
+	spinlock_t        lock;
+	struct midi_queue *firstmidiq;
+	struct midi_queue *lastmidiq;
+	unsigned          qhead, qtail;
+	struct midi_data  midiq[MIDIIN_MAX_BUFFER_SIZE];
+	struct tasklet_struct tasklet;
+	struct midi_openinfo    openinfo;
+
+	/* For MIDI state machine */
+	u8              status;        /* For MIDI running status */
+	u8              fstatus;       /* For 0xFn status only */
+	midi_in_state   curstate;
+	midi_in_state   laststate;
+	u32             timestart;
+	u32             timein;
+	u8              data;
+};
+
+int emu10k1_mpuin_open(struct emu10k1_card *, struct midi_openinfo *);
+int emu10k1_mpuin_close(struct emu10k1_card *);
+int emu10k1_mpuin_add_buffer(struct emu10k1_mpuin *, struct midi_hdr *);
+int emu10k1_mpuin_start(struct emu10k1_card *);
+int emu10k1_mpuin_stop(struct emu10k1_card *);
+int emu10k1_mpuin_reset(struct emu10k1_card *);
+
+int sblive_miStateInit(struct emu10k1_mpuin *);
+int sblive_miStateEntry(struct emu10k1_mpuin *, u8);
+int sblive_miStateParse(struct emu10k1_mpuin *, u8);
+int sblive_miState3Byte(struct emu10k1_mpuin *, u8);
+int sblive_miState3ByteKey(struct emu10k1_mpuin *, u8);
+int sblive_miState3ByteVel(struct emu10k1_mpuin *, u8);
+int sblive_miState2Byte(struct emu10k1_mpuin *, u8);
+int sblive_miState2ByteKey(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysCommon2(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysCommon2Key(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysCommon3(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysCommon3Key(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysCommon3Vel(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysExNorm(struct emu10k1_mpuin *, u8);
+int sblive_miStateSysReal(struct emu10k1_mpuin *, u8);
+
+int emu10k1_mpuin_irqhandler(struct emu10k1_card *);
+void emu10k1_mpuin_bh(unsigned long);
+int emu10k1_mpuin_callback(struct emu10k1_mpuin *card_mpuin, u32 msg, unsigned long data, u32 bytesvalid);
+
+#endif  /* _CARDMI_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardmo.c linux.17p18/drivers/sound/emu10k1/cardmo.c
--- linux.vanilla/drivers/sound/emu10k1/cardmo.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardmo.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,233 @@
+
+/*     
+ **********************************************************************
+ *     cardmo.c - MIDI UART output HAL for emu10k1 driver 
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ *     November 2, 1999     Alan Cox        cleaned up
+ * 
+ ********************************************************************** 
+ * 
+ *     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. 
+ * 
+ ********************************************************************** 
+ */
+
+#include <linux/malloc.h>
+
+#include "hwaccess.h"
+#include "8010.h"
+#include "cardmo.h"
+#include "irqmgr.h"
+
+/* Installs the IRQ handler for the MPU out port               *
+ * and initialize parameters                                    */
+
+int emu10k1_mpuout_open(struct emu10k1_card *card, struct midi_openinfo *openinfo)
+{
+	struct emu10k1_mpuout *card_mpuout = card->mpuout;
+
+	DPF(2, "emu10k1_mpuout_open()\n");
+
+	if (!(card_mpuout->status & FLAGS_AVAILABLE))
+		return CTSTATUS_INUSE;
+
+	/* Copy open info and mark channel as in use */
+	card_mpuout->intr = 0;
+	card_mpuout->openinfo = *openinfo;
+	card_mpuout->status &= ~FLAGS_AVAILABLE;
+	card_mpuout->laststatus = 0x80;
+	card_mpuout->firstmidiq = NULL;
+	card_mpuout->lastmidiq = NULL;
+
+	emu10k1_mpu_reset(card);
+	emu10k1_mpu_acquire(card);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int emu10k1_mpuout_close(struct emu10k1_card *card)
+{
+	struct emu10k1_mpuout *card_mpuout = card->mpuout;
+	struct midi_queue *midiq;
+	struct midi_hdr *midihdr;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_mpuout_close()\n");
+
+	emu10k1_irq_disable(card, INTE_MIDITXENABLE);
+
+	spin_lock_irqsave(&card_mpuout->lock, flags);
+
+	while (card_mpuout->firstmidiq != NULL) {
+		midiq = card_mpuout->firstmidiq;
+		midihdr = (struct midi_hdr *) midiq->refdata;
+
+		card_mpuout->firstmidiq = midiq->next;
+
+		kfree(midihdr->data);
+		kfree(midihdr);
+		kfree(midiq);
+	}
+
+	card_mpuout->lastmidiq = NULL;
+
+	emu10k1_mpu_release(card);
+
+	card_mpuout->status |= FLAGS_AVAILABLE;
+
+	spin_unlock_irqrestore(&card_mpuout->lock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* If there isn't enough buffer space, reject Midi Buffer.     *
+* Otherwise, disable TX, create object to hold Midi            *
+*  uffer, update buffer flags and other parameters             *
+* before enabling TX again.                                    */
+
+int emu10k1_mpuout_add_buffer(struct emu10k1_card *card, struct midi_hdr *midihdr)
+{
+	struct emu10k1_mpuout *card_mpuout = card->mpuout;
+	struct midi_queue *midiq;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_mpuout_add_buffer()\n");
+
+	if (card_mpuout->state == CARDMIDIOUT_STATE_SUSPEND)
+		return CTSTATUS_SUCCESS;
+
+	midihdr->flags |= MIDIBUF_INQUEUE;
+	midihdr->flags &= ~MIDIBUF_DONE;
+
+	if ((midiq = (struct midi_queue *) kmalloc(sizeof(struct midi_queue), GFP_KERNEL)) == NULL) {
+		/* Message lost */
+		return CTSTATUS_NOMEMORY;
+	}
+
+	midiq->next = NULL;
+	midiq->qtype = 1;
+	midiq->length = midihdr->bufferlength;
+	midiq->sizeLeft = midihdr->bufferlength;
+	midiq->midibyte = midihdr->data;
+
+	midiq->refdata = (unsigned long) midihdr;
+
+	spin_lock_irqsave(&card_mpuout->lock, flags);
+
+	if (card_mpuout->firstmidiq == NULL) {
+		card_mpuout->firstmidiq = midiq;
+		card_mpuout->lastmidiq = midiq;
+	} else {
+		(card_mpuout->lastmidiq)->next = midiq;
+		card_mpuout->lastmidiq = midiq;
+	}
+
+	card_mpuout->intr = 0;
+
+	emu10k1_irq_enable(card, INTE_MIDITXENABLE);
+
+	spin_unlock_irqrestore(&card_mpuout->lock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+void emu10k1_mpuout_bh(unsigned long refdata)
+{
+	struct emu10k1_card *card = (struct emu10k1_card *) refdata;
+	struct emu10k1_mpuout *card_mpuout = card->mpuout;
+	int cByteSent = 0;
+	int status;
+	struct midi_queue *midiq;
+	struct midi_queue *doneq = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card_mpuout->lock, flags);
+
+	while (card_mpuout->firstmidiq != NULL) {
+		midiq = card_mpuout->firstmidiq;
+
+		while (cByteSent < 4 && midiq->sizeLeft) {
+			status = emu10k1_mpu_write_data(card, *midiq->midibyte);
+
+			if (status == CTSTATUS_SUCCESS) {
+				++cByteSent;
+				--midiq->sizeLeft;
+				++midiq->midibyte;
+			} else {
+				DPF(2, "emu10k1_mpuoutDpcCallback error!!\n");
+			}
+		}
+
+		if (midiq->sizeLeft == 0) {
+			if (doneq == NULL)
+				doneq = midiq;
+			card_mpuout->firstmidiq = midiq->next;
+		} else
+			break;
+	}
+
+	if (card_mpuout->firstmidiq == NULL)
+		card_mpuout->lastmidiq = NULL;
+
+	if (doneq != NULL) {
+		while (doneq != card_mpuout->firstmidiq) {
+			unsigned long callback_msg[3];
+
+			midiq = doneq;
+			doneq = midiq->next;
+
+			if (midiq->qtype) {
+				callback_msg[0] = 0;
+				callback_msg[1] = midiq->length;
+				callback_msg[2] = midiq->refdata;
+
+				emu10k1_midi_callback(ICARDMIDI_OUTLONGDATA, card_mpuout->openinfo.refdata, callback_msg);
+			} else if (((u8) midiq->refdata) < 0xF0 && ((u8) midiq->refdata) > 0x7F)
+				card_mpuout->laststatus = (u8) midiq->refdata;
+
+			kfree(midiq);
+		}
+	}
+
+	if ((card_mpuout->firstmidiq != NULL) || cByteSent) {
+		card_mpuout->intr = 0;
+		emu10k1_irq_enable(card, INTE_MIDITXENABLE);
+	}
+
+	spin_unlock_irqrestore(&card_mpuout->lock, flags);
+
+	return;
+}
+
+int emu10k1_mpuout_irqhandler(struct emu10k1_card *card)
+{
+	struct emu10k1_mpuout *card_mpuout = card->mpuout;
+
+	DPF(4, "emu10k1_mpuout_irqhandler\n");
+
+	card_mpuout->intr = 1;
+	emu10k1_irq_disable(card, INTE_MIDITXENABLE);
+
+	tasklet_hi_schedule(&card_mpuout->tasklet);
+
+	return CTSTATUS_SUCCESS;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardmo.h linux.17p18/drivers/sound/emu10k1/cardmo.h
--- linux.vanilla/drivers/sound/emu10k1/cardmo.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardmo.h	Tue Aug  1 18:30:12 2000
@@ -0,0 +1,62 @@
+/*
+ **********************************************************************
+ *     cardmo.h
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox	    cleaned up
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _CARDMO_H
+#define _CARDMO_H
+
+#include "icardmid.h"
+#include <linux/interrupt.h>
+
+#define CARDMIDIOUT_STATE_DEFAULT    0x00000000
+#define CARDMIDIOUT_STATE_SUSPEND    0x00000001
+
+struct emu10k1_mpuout
+{
+	u32			status;
+	u32			state;
+	volatile int		intr;
+	struct midi_queue	*firstmidiq;
+	struct midi_queue	*lastmidiq;
+	u8			laststatus;
+	struct tasklet_struct 	tasklet;
+	spinlock_t		lock;
+	struct midi_openinfo	openinfo;
+};
+
+int emu10k1_mpuout_open(struct emu10k1_card *, struct midi_openinfo *);
+int emu10k1_mpuout_close(struct emu10k1_card *);
+int emu10k1_mpuout_add_buffer(struct emu10k1_card *, struct midi_hdr *);
+
+int emu10k1_mpuout_irqhandler(struct emu10k1_card *);
+void emu10k1_mpuout_bh(unsigned long);
+
+#endif  /* _CARDMO_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardwi.c linux.17p18/drivers/sound/emu10k1/cardwi.c
--- linux.vanilla/drivers/sound/emu10k1/cardwi.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardwi.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,378 @@
+/*
+ **********************************************************************
+ *     cardwi.c - PCM input HAL for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include <linux/poll.h>
+#include "hwaccess.h"
+#include "timer.h"
+#include "recmgr.h"
+#include "audio.h"
+#include "cardwi.h"
+
+void query_format(int recsrc, struct wave_format *wave_fmt)
+{
+
+	switch (recsrc) {
+	case WAVERECORD_AC97:
+
+		if ((wave_fmt->channels != 1) && (wave_fmt->channels != 2))
+			wave_fmt->channels = 2;
+
+		if (wave_fmt->samplingrate >= (0xBB80 + 0xAC44) / 2)
+			wave_fmt->samplingrate = 0xBB80;
+		else if (wave_fmt->samplingrate >= (0xAC44 + 0x7D00) / 2)
+			wave_fmt->samplingrate = 0xAC44;
+		else if (wave_fmt->samplingrate >= (0x7D00 + 0x5DC0) / 2)
+			wave_fmt->samplingrate = 0x7D00;
+		else if (wave_fmt->samplingrate >= (0x5DC0 + 0x5622) / 2)
+			wave_fmt->samplingrate = 0x5DC0;
+		else if (wave_fmt->samplingrate >= (0x5622 + 0x3E80) / 2)
+			wave_fmt->samplingrate = 0x5622;
+		else if (wave_fmt->samplingrate >= (0x3E80 + 0x2B11) / 2)
+			wave_fmt->samplingrate = 0x3E80;
+		else if (wave_fmt->samplingrate >= (0x2B11 + 0x1F40) / 2)
+			wave_fmt->samplingrate = 0x2B11;
+		else
+			wave_fmt->samplingrate = 0x1F40;
+
+		if ((wave_fmt->bitsperchannel != 8) && (wave_fmt->bitsperchannel != 16))
+			wave_fmt->bitsperchannel = 16;
+
+		break;
+
+	case WAVERECORD_MIC:
+		wave_fmt->channels = 1;
+		wave_fmt->samplingrate = 0x1F40;
+		wave_fmt->bitsperchannel = 16;
+		break;
+
+	case WAVERECORD_FX:
+		if (wave_fmt->channels > 16)
+			wave_fmt->channels = 16;
+		else if (wave_fmt->channels < 1)
+			wave_fmt->channels = 1;
+
+		wave_fmt->samplingrate = 0xBB80;
+		wave_fmt->bitsperchannel = 16;
+		break;
+
+	default:
+		BUG();
+		break;
+	}
+
+	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;
+
+	return;
+}
+
+static int alloc_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
+{
+	if ((buffer->addr = pci_alloc_consistent(card->pci_dev, buffer->size * buffer->cov, &buffer->dma_handle)) == NULL)
+		return -1;
+
+	return 0;
+}
+
+static void free_buffer(struct emu10k1_card *card, struct wavein_buffer *buffer)
+{
+	if (buffer->addr != NULL)
+		pci_free_consistent(card->pci_dev, buffer->size * buffer->cov, buffer->addr, buffer->dma_handle);
+
+	return;
+}
+
+int emu10k1_wavein_open(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct wiinst *wiinst = wave_dev->wiinst;
+	struct wiinst **wiinst_tmp = NULL;
+	u32 delay;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_wavein_open()\n");
+
+	switch (wiinst->recsrc) {
+	case WAVERECORD_AC97:
+		wiinst_tmp = &card->wavein->ac97;
+		break;
+	case WAVERECORD_MIC:
+		wiinst_tmp = &card->wavein->mic;
+		break;
+	case WAVERECORD_FX:
+		wiinst_tmp = &card->wavein->fx;
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	spin_lock_irqsave(&card->lock, flags);
+	if (*wiinst_tmp != NULL) {
+		spin_unlock_irqrestore(&card->lock, flags);
+		return -1;
+	}
+
+	*wiinst_tmp = wiinst;
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	/* handle 8 bit recording */
+	if (wiinst->format.bytesperchannel == 1) {
+		if (wiinst->buffer.size > 0x8000) {
+			wiinst->buffer.size = 0x8000;
+			wiinst->buffer.sizeregval = 0x1f;
+		} else
+			wiinst->buffer.sizeregval += 4;
+
+		wiinst->buffer.cov = 2;
+	} else
+		wiinst->buffer.cov = 1;
+
+	if (alloc_buffer(card, &wiinst->buffer) < 0) {
+		ERROR();
+		emu10k1_wavein_close(wave_dev);
+		return -1;
+	}
+
+	emu10k1_set_record_src(card, wiinst);
+
+	delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
+
+	emu10k1_timer_install(card, &wiinst->timer, delay / 2);
+
+	wiinst->state = WAVE_STATE_OPEN;
+
+	return 0;
+}
+
+void emu10k1_wavein_close(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct wiinst *wiinst = wave_dev->wiinst;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_wavein_close()\n");
+
+	emu10k1_wavein_stop(wave_dev);
+
+	emu10k1_timer_uninstall(card, &wiinst->timer);
+
+	free_buffer(card, &wiinst->buffer);
+
+	spin_lock_irqsave(&card->lock, flags);
+	switch (wave_dev->wiinst->recsrc) {
+	case WAVERECORD_AC97:
+		card->wavein->ac97 = NULL;
+		break;
+	case WAVERECORD_MIC:
+		card->wavein->mic = NULL;
+		break;
+	case WAVERECORD_FX:
+		card->wavein->fx = NULL;
+		break;
+	default:
+		BUG();
+		break;
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	wiinst->state = WAVE_STATE_CLOSED;
+
+	return;
+}
+
+void emu10k1_wavein_start(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct wiinst *wiinst = wave_dev->wiinst;
+
+	DPF(2, "emu10k1_wavein_start()\n");
+
+	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;
+
+	return;
+}
+
+void emu10k1_wavein_stop(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct wiinst *wiinst = wave_dev->wiinst;
+
+	DPF(2, "emu10k1_wavein_stop()\n");
+
+	if (!(wiinst->state & WAVE_STATE_STARTED))
+		return;
+
+	emu10k1_timer_disable(card, &wiinst->timer);
+	emu10k1_stop_record(card, &wiinst->buffer);
+
+	wiinst->state &= ~WAVE_STATE_STARTED;
+
+	return;
+}
+
+int emu10k1_wavein_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct wiinst *wiinst = wave_dev->wiinst;
+	u32 delay;
+
+	DPF(2, "emu10k1_wavein_setformat()\n");
+
+	if (wiinst->state & WAVE_STATE_STARTED)
+		return -1;
+
+	query_format(wiinst->recsrc, format);
+
+	if ((wiinst->format.samplingrate != format->samplingrate)
+	    || (wiinst->format.bitsperchannel != format->bitsperchannel)
+	    || (wiinst->format.channels != format->channels)) {
+
+		wiinst->format = *format;
+
+		if (wiinst->state == WAVE_STATE_CLOSED)
+			return 0;
+
+		wiinst->buffer.size *= wiinst->buffer.cov;
+
+		if (wiinst->format.bytesperchannel == 1) {
+			wiinst->buffer.cov = 2;
+			wiinst->buffer.size /= wiinst->buffer.cov;
+		} else
+			wiinst->buffer.cov = 1;
+
+		emu10k1_timer_uninstall(card, &wiinst->timer);
+
+		delay = (48000 * wiinst->buffer.fragment_size) / wiinst->format.bytespersec;
+
+		emu10k1_timer_install(card, &wiinst->timer, delay / 2);
+	}
+
+	return 0;
+}
+
+void emu10k1_wavein_getxfersize(struct wiinst *wiinst, u32 * size)
+{
+	struct wavein_buffer *buffer = &wiinst->buffer;
+
+	*size = buffer->bytestocopy;
+
+	if (*size > buffer->size) {
+		*size = buffer->size;
+		buffer->pos = buffer->hw_pos;
+		buffer->bytestocopy = buffer->size;
+		DPF(1, "buffer overrun\n");
+	}
+
+	return;
+}
+
+static void copy_block(u8 *dst, u8 * src, u32 str, u32 len, u8 cov)
+{
+	if (cov == 1)
+		copy_to_user(dst, src + str, len);
+	else {
+		u8 byte;
+		u32 i;
+
+		src += 1 + 2 * str;
+
+		for (i = 0; i < len; i++) {
+			byte = src[2 * i] ^ 0x80;
+			copy_to_user(dst + i, &byte, 1);
+		}
+	}
+
+	return;
+}
+
+void emu10k1_wavein_xferdata(struct wiinst *wiinst, u8 * data, u32 * size)
+{
+	struct wavein_buffer *buffer = &wiinst->buffer;
+	u32 sizetocopy, sizetocopy_now, start;
+	unsigned long flags;
+
+	sizetocopy = min(buffer->size, *size);
+	*size = sizetocopy;
+
+	if (!sizetocopy)
+		return;
+
+	spin_lock_irqsave(&wiinst->lock, flags);
+	start = buffer->pos;
+	buffer->pos += sizetocopy;
+	buffer->pos %= buffer->size;
+	buffer->bytestocopy -= sizetocopy;
+	sizetocopy_now = buffer->size - start;
+
+	spin_unlock_irqrestore(&wiinst->lock, flags);
+
+	if (sizetocopy > sizetocopy_now) {
+		sizetocopy -= sizetocopy_now;
+
+		copy_block(data, buffer->addr, start, sizetocopy_now, buffer->cov);
+		copy_block(data + sizetocopy_now, buffer->addr, 0, sizetocopy, buffer->cov);
+	} else {
+		copy_block(data, buffer->addr, start, sizetocopy, buffer->cov);
+	}
+
+	return;
+}
+
+void emu10k1_wavein_update(struct emu10k1_card *card, struct wiinst *wiinst)
+{
+	u32 hw_pos;
+	u32 diff;
+
+	/* There is no actual start yet */
+	if (!(wiinst->state & WAVE_STATE_STARTED)) {
+		hw_pos = wiinst->buffer.hw_pos;
+	} else {
+		/* hw_pos in byte units */
+		hw_pos = sblive_readptr(card, wiinst->buffer.idxreg, 0) / wiinst->buffer.cov;
+	}
+
+	diff = (wiinst->buffer.size + hw_pos - wiinst->buffer.hw_pos) % wiinst->buffer.size;
+	wiinst->total_recorded += diff;
+	wiinst->buffer.bytestocopy += diff;
+
+	wiinst->buffer.hw_pos = hw_pos;
+
+	return;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardwi.h linux.17p18/drivers/sound/emu10k1/cardwi.h
--- linux.vanilla/drivers/sound/emu10k1/cardwi.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardwi.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,100 @@
+/*
+ **********************************************************************
+ *     cardwi.h -- header file for card wave input functions
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+#ifndef _CARDWI_H
+#define _CARDWI_H
+
+#include "icardwav.h"
+#include "audio.h"
+#include "timer.h"
+
+struct wavein_buffer {
+	u16 ossfragshift;
+        u32 fragment_size;
+        u32 numfrags;
+	u32 hw_pos;		/* hardware cursor position */
+	u32 pos;		/* software cursor position */
+	u32 bytestocopy;	/* bytes of recorded data available */
+	u32 size;
+	u32 sizereg;
+	u32 sizeregval;
+        u32 addrreg;
+        u32 idxreg;
+        u32 adcctl;
+	u32 fxwc;
+	void *addr;
+	u8 cov;
+	dma_addr_t dma_handle;	
+};
+
+struct wiinst
+{
+	u8 state;
+	struct emu_timer timer;
+	struct wave_format format;
+	struct wavein_buffer buffer;
+	wait_queue_head_t wait_queue;
+	u8 mmapped;
+	u32 total_recorded;	/* total bytes read() from device */
+	u32 blocks;
+	spinlock_t lock;
+	u8 recsrc;
+};
+
+struct emu10k1_wavein 
+{
+	struct wiinst *ac97;
+	struct wiinst *mic;
+	struct wiinst *fx;
+
+	u8 recsrc;
+	u32 fxwc;
+};
+
+
+#define WAVEIN_MAXBUFSIZE         65536
+#define WAVEIN_MINBUFSIZE	  368
+
+#define WAVEIN_DEFAULTFRAGLEN     100 
+#define WAVEIN_DEFAULTBUFLEN      1000
+
+#define WAVEIN_MINFRAGSHIFT   	  8 
+
+int emu10k1_wavein_open(struct emu10k1_wavedevice *);
+void emu10k1_wavein_close(struct emu10k1_wavedevice *);
+void emu10k1_wavein_start(struct emu10k1_wavedevice *);
+void emu10k1_wavein_stop(struct emu10k1_wavedevice *);
+void emu10k1_wavein_getxfersize(struct wiinst *, u32 *);
+void emu10k1_wavein_xferdata(struct wiinst *, u8 *, u32 *);
+int emu10k1_wavein_setformat(struct emu10k1_wavedevice *, struct wave_format *);
+void emu10k1_wavein_update(struct emu10k1_card *, struct wiinst *);
+
+
+#endif /* _CARDWI_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardwo.c linux.17p18/drivers/sound/emu10k1/cardwo.c
--- linux.vanilla/drivers/sound/emu10k1/cardwo.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardwo.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,490 @@
+/*
+ **********************************************************************
+ *     cardwo.c - PCM output HAL for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include <linux/poll.h>
+#include "hwaccess.h"
+#include "8010.h"
+#include "voicemgr.h"
+#include "cardwo.h"
+#include "audio.h"
+
+static u32 samplerate_to_linearpitch(u32 samplingrate)
+{
+	samplingrate = (samplingrate << 8) / 375;
+	return (samplingrate >> 1) + (samplingrate & 1);
+}
+
+static void query_format(struct wave_format *wave_fmt)
+{
+	if ((wave_fmt->channels != 1) && (wave_fmt->channels != 2))
+		wave_fmt->channels = 2;
+
+	if (wave_fmt->samplingrate >= 0x2ee00)
+		wave_fmt->samplingrate = 0x2ee00;
+
+	if ((wave_fmt->bitsperchannel != 8) && (wave_fmt->bitsperchannel != 16))
+		wave_fmt->bitsperchannel = 16;
+
+	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;
+
+	return;
+}
+
+static int alloc_buffer(struct emu10k1_card *card, struct waveout_buffer *buffer)
+{
+	u32 pageindex, pagecount;
+	unsigned long busaddx;
+	int i;
+
+	DPD(2, "requested pages is: %d\n", buffer->pages);
+
+	if ((buffer->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->addr[pagecount] = pci_alloc_consistent(card->pci_dev, PAGE_SIZE, &buffer->dma_handle[pagecount])) == NULL) {
+			buffer->pages = pagecount;
+			return -1;
+		}
+
+		DPD(2, "Virtual Addx: %p\n", buffer->addr[pagecount]);
+
+		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
+			busaddx = buffer->dma_handle[pagecount] + i * EMUPAGESIZE;
+
+			DPD(3, "Bus Addx: %lx\n", busaddx);
+
+			pageindex = buffer->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
+
+			((u32 *) card->virtualpagetable.addr)[pageindex] = (busaddx * 2) | pageindex;
+		}
+	}
+
+	return 0;
+}
+
+static void free_buffer(struct emu10k1_card *card, struct waveout_buffer *buffer)
+{
+	u32 pagecount, pageindex;
+	int i;
+
+	if (buffer->emupageindex < 0)
+		return;
+
+	for (pagecount = 0; pagecount < buffer->pages; pagecount++) {
+		pci_free_consistent(card->pci_dev, PAGE_SIZE, buffer->addr[pagecount], buffer->dma_handle[pagecount]);
+
+		for (i = 0; i < PAGE_SIZE / EMUPAGESIZE; i++) {
+			pageindex = buffer->emupageindex + pagecount * PAGE_SIZE / EMUPAGESIZE + i;
+			((u32 *) card->virtualpagetable.addr)[pageindex] = (card->silentpage.dma_handle * 2) | pageindex;
+		}
+	}
+
+	emu10k1_addxmgr_free(card, buffer->emupageindex);
+	buffer->emupageindex = -1;
+
+	return;
+}
+
+static int get_voice(struct emu10k1_card *card, struct woinst *woinst)
+{
+	struct voice_allocdesc voice_allocdesc;
+
+	/* Allocate voices here, if no voices available, return error.
+	 * Init voice_allocdesc first.*/
+
+	voice_allocdesc.usage = VOICE_USAGE_PLAYBACK;
+
+	voice_allocdesc.flags = 0;
+
+	if (woinst->format.channels == 2)
+		voice_allocdesc.flags |= VOICE_FLAGS_STEREO;
+
+	if (woinst->format.bitsperchannel == 16)
+		voice_allocdesc.flags |= VOICE_FLAGS_16BIT;
+
+	if (emu10k1_voice_alloc(card, &woinst->voice, &voice_allocdesc) < 0)
+		return -1;
+
+	/* Calculate pitch */
+	woinst->voice.initial_pitch = (u16) (srToPitch(woinst->format.samplingrate) >> 8);
+	woinst->voice.pitch_target = samplerate_to_linearpitch(woinst->format.samplingrate);
+
+	DPD(2, "Initial pitch --> 0x%x\n", woinst->voice.initial_pitch);
+
+	woinst->voice.start = (woinst->buffer.emupageindex << 12) / woinst->format.bytespersample;
+	woinst->voice.end = woinst->voice.start + woinst->buffer.size / woinst->format.bytespersample;
+	woinst->voice.startloop = woinst->voice.start;
+	woinst->voice.endloop = woinst->voice.end;
+
+	woinst->voice.params[0].send_a=0x00;
+	woinst->voice.params[0].send_b=0x00;
+	woinst->voice.params[0].send_c=0xff;
+	woinst->voice.params[0].send_d=0x00;
+
+	woinst->voice.params[0].bus_routing= (woinst->device == 1) ? 0xd23c : 0xd01c;
+	woinst->voice.params[0].volume_target=0xffff;
+	woinst->voice.params[0].initial_fc=0xff;
+	woinst->voice.params[0].initial_attn=0x00;
+	woinst->voice.params[0].byampl_env_sustain = 0x7f;
+	woinst->voice.params[0].byampl_env_decay = 0x7f;
+
+	if (woinst->voice.flags & VOICE_FLAGS_STEREO) {
+		woinst->voice.params[1].send_a=0x00;
+		woinst->voice.params[1].send_b=0xff;		
+		woinst->voice.params[1].send_c=0x00;
+		woinst->voice.params[1].send_d=0x00;
+
+		woinst->voice.params[1].bus_routing= (woinst->device == 1) ? 0xd23c : 0xd01c;
+		woinst->voice.params[1].volume_target=0xffff;
+		woinst->voice.params[1].initial_fc=0xff;
+		woinst->voice.params[1].initial_attn=0x00;
+		woinst->voice.params[1].byampl_env_sustain = 0x7f;
+		woinst->voice.params[1].byampl_env_decay = 0x7f;
+	} else {
+		woinst->voice.params[0].send_b=0xff;
+	}
+
+	DPD(2, "voice: start=0x%x, end=0x%x, startloop=0x%x, endloop=0x%x\n", woinst->voice.start, woinst->voice.end,woinst->voice.startloop, woinst->voice.endloop);
+
+	emu10k1_voice_playback_setup(&woinst->voice);
+
+	return 0;
+}
+
+int emu10k1_waveout_open(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct woinst *woinst = wave_dev->woinst;
+	u32 delay;
+
+	DPF(2, "emu10k1_waveout_open()\n");
+
+	if (alloc_buffer(card, &woinst->buffer) < 0) {
+		ERROR();
+		emu10k1_waveout_close(wave_dev);
+		return -1;
+	}
+
+	woinst->buffer.fill_silence = 0;
+	woinst->buffer.silence_bytes = 0;
+	woinst->buffer.silence_pos = 0;
+	woinst->buffer.hw_pos = 0;
+	woinst->buffer.bytestocopy = woinst->buffer.size;
+
+	if (get_voice(card, woinst) < 0) {
+		ERROR();
+		emu10k1_waveout_close(wave_dev);
+		return -1;
+	}
+
+	delay = (48000 * woinst->buffer.fragment_size) / woinst->format.bytespersec;
+
+	emu10k1_timer_install(card, &woinst->timer, delay / 2);
+
+	woinst->state = WAVE_STATE_OPEN;
+
+	return 0;
+}
+
+void emu10k1_waveout_close(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct woinst *woinst = wave_dev->woinst;
+
+	DPF(2, "emu10k1_waveout_close()\n");
+
+	emu10k1_waveout_stop(wave_dev);
+
+	emu10k1_timer_uninstall(card, &woinst->timer);
+
+	emu10k1_voice_free(&woinst->voice);
+
+	free_buffer(card, &woinst->buffer);
+
+	woinst->state = WAVE_STATE_CLOSED;
+
+	return;
+}
+
+void emu10k1_waveout_start(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct woinst *woinst = wave_dev->woinst;
+
+	DPF(2, "emu10k1_waveout_start()\n");
+	/* Actual start */
+	emu10k1_voice_start(&woinst->voice);
+
+	emu10k1_timer_enable(card, &woinst->timer);
+
+	woinst->state |= WAVE_STATE_STARTED;
+
+	return;
+}
+
+int emu10k1_waveout_setformat(struct emu10k1_wavedevice *wave_dev, struct wave_format *format)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct woinst *woinst = wave_dev->woinst;
+	u32 delay;
+
+	DPF(2, "emu10k1_waveout_setformat()\n");
+
+	if (woinst->state & WAVE_STATE_STARTED)
+		return -1;
+
+	query_format(format);
+
+	if (woinst->format.samplingrate != format->samplingrate ||
+	    woinst->format.channels != format->channels ||
+	    woinst->format.bitsperchannel != format->bitsperchannel) {
+
+		woinst->format = *format;
+
+		if (woinst->state == WAVE_STATE_CLOSED)
+			return 0;
+
+		emu10k1_timer_uninstall(card, &woinst->timer);
+		emu10k1_voice_free(&woinst->voice);
+
+		if (get_voice(card, woinst) < 0) {
+			ERROR();
+			emu10k1_waveout_close(wave_dev);
+			return -1;
+		}
+
+		delay = (48000 * woinst->buffer.fragment_size) / woinst->format.bytespersec;
+
+		emu10k1_timer_install(card, &woinst->timer, delay / 2);
+	}
+
+	return 0;
+}
+
+void emu10k1_waveout_stop(struct emu10k1_wavedevice *wave_dev)
+{
+	struct emu10k1_card *card = wave_dev->card;
+	struct woinst *woinst = wave_dev->woinst;
+
+	DPF(2, "emu10k1_waveout_stop()\n");
+
+	if (!(woinst->state & WAVE_STATE_STARTED))
+		return;
+
+	emu10k1_timer_disable(card, &woinst->timer);
+
+	/* Stop actual voice */
+	emu10k1_voice_stop(&woinst->voice);
+
+	emu10k1_waveout_update(woinst);
+
+	woinst->state &= ~WAVE_STATE_STARTED;
+
+	return;
+}
+
+void emu10k1_waveout_getxfersize(struct woinst *woinst, u32 * size)
+{
+	struct waveout_buffer *buffer = &woinst->buffer;
+	int pending;
+
+	if (woinst->mmapped) {
+		*size = buffer->bytestocopy;
+		return;
+	}
+
+	pending = buffer->size - buffer->bytestocopy;
+
+	buffer->fill_silence = (pending < (signed) buffer->fragment_size) ? 1 : 0;
+
+	if (pending > (signed) buffer->silence_bytes) {
+		*size = buffer->bytestocopy + buffer->silence_bytes;
+	} else {
+		*size = buffer->size;
+		buffer->silence_bytes = pending;
+		if (pending < 0) {
+			buffer->silence_pos = buffer->hw_pos;
+			buffer->silence_bytes = 0;
+			buffer->bytestocopy = buffer->size;
+			DPF(1, "buffer underrun\n");
+		}
+	}
+
+	return;
+}
+
+static void copy_block(void **dst, u32 str, u8 *src, u32 len)
+{
+	int i, j, k;
+
+	i = str / PAGE_SIZE;
+	j = str % PAGE_SIZE;
+	k = (len > PAGE_SIZE - j) ? PAGE_SIZE - j : len;
+	copy_from_user(dst[i] + j, src, k);
+	len -= k;
+	while (len >= PAGE_SIZE) {
+		copy_from_user(dst[++i], src + k, PAGE_SIZE);
+		k += PAGE_SIZE;
+		len -= PAGE_SIZE;
+	}
+	copy_from_user(dst[++i], src + k, len);
+
+	return;
+}
+
+static void fill_block(void **dst, u32 str, u8 src, u32 len)
+{
+	int i, j, k;
+
+	i = str / PAGE_SIZE;
+	j = str % PAGE_SIZE;
+	k = (len > PAGE_SIZE - j) ? PAGE_SIZE - j : len;
+	memset(dst[i] + j, src, k);
+	len -= k;
+	while (len >= PAGE_SIZE) {
+		memset(dst[++i], src, PAGE_SIZE);
+		len -= PAGE_SIZE;
+	}
+	memset(dst[++i], src, len);
+
+	return;
+}
+
+void emu10k1_waveout_xferdata(struct woinst *woinst, u8 *data, u32 *size)
+{
+	struct waveout_buffer *buffer = &woinst->buffer;
+	u32 sizetocopy, sizetocopy_now, start;
+	unsigned long flags;
+
+	sizetocopy = min(buffer->size, *size);
+	*size = sizetocopy;
+
+	if (!sizetocopy)
+		return;
+
+	spin_lock_irqsave(&woinst->lock, flags);
+	start = (buffer->size + buffer->silence_pos - buffer->silence_bytes) % buffer->size;
+
+	if(sizetocopy > buffer->silence_bytes) {
+		buffer->silence_pos += sizetocopy - buffer->silence_bytes;
+		buffer->bytestocopy -= sizetocopy - buffer->silence_bytes;
+		buffer->silence_bytes = 0;
+	} else
+		buffer->silence_bytes -= sizetocopy;
+
+	sizetocopy_now = buffer->size - start;
+
+	spin_unlock_irqrestore(&woinst->lock, flags);
+
+	if (sizetocopy > sizetocopy_now) {
+		sizetocopy -= sizetocopy_now;
+		copy_block(buffer->addr, start, data, sizetocopy_now);
+		copy_block(buffer->addr, 0, data + sizetocopy_now, sizetocopy);
+	} else {
+		copy_block(buffer->addr, start, data, sizetocopy);
+	}
+
+	return;
+}
+
+void emu10k1_waveout_fillsilence(struct woinst *woinst)
+{
+	struct waveout_buffer *buffer = &woinst->buffer;
+	u16 filldata;
+	u32 sizetocopy, sizetocopy_now, start;
+	unsigned long flags;
+
+	sizetocopy = woinst->buffer.fragment_size;
+
+	if (woinst->format.bitsperchannel == 16)
+		filldata = 0x0000;
+	else
+		filldata = 0x8080;
+
+	spin_lock_irqsave(&woinst->lock, flags);
+	buffer->silence_bytes += sizetocopy;
+	buffer->bytestocopy -= sizetocopy;
+	buffer->silence_pos %= buffer->size;
+	start = buffer->silence_pos;
+	buffer->silence_pos += sizetocopy;
+	sizetocopy_now = buffer->size - start;
+
+	spin_unlock_irqrestore(&woinst->lock, flags);
+
+	if (sizetocopy > sizetocopy_now) {
+		sizetocopy -= sizetocopy_now;
+		fill_block(buffer->addr, start, filldata, sizetocopy_now);
+		fill_block(buffer->addr, 0, filldata, sizetocopy);
+	} else {
+		fill_block(buffer->addr, start, filldata, sizetocopy);
+	}
+
+	return;
+}
+
+void emu10k1_waveout_update(struct woinst *woinst)
+{
+	u32 hw_pos;
+	u32 diff;
+
+	/* There is no actual start yet */
+	if (!(woinst->state & WAVE_STATE_STARTED)) {
+		hw_pos = woinst->buffer.hw_pos;
+	} else {
+		u32 samples;
+		/* hw_pos in sample units */
+		emu10k1_voice_getcontrol(&woinst->voice, CCCA_CURRADDR, &hw_pos);
+
+		hw_pos -= woinst->voice.start;
+
+		hw_pos *= woinst->format.bytespersample;
+
+		/* Refer to voicemgr.c, CA is not started at zero.
+		 * We need to take this into account. */
+		samples = 64 * woinst->format.channels - 4 * woinst->format.bytesperchannel;
+
+		if (hw_pos >= samples)
+			hw_pos -= samples;
+		else
+			hw_pos += woinst->buffer.size - samples;
+	}
+
+	diff = (woinst->buffer.size + hw_pos - woinst->buffer.hw_pos) % woinst->buffer.size;
+	woinst->total_played += diff;
+	woinst->buffer.bytestocopy += diff;
+	woinst->buffer.hw_pos = hw_pos;
+
+	return;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/cardwo.h linux.17p18/drivers/sound/emu10k1/cardwo.h
--- linux.vanilla/drivers/sound/emu10k1/cardwo.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/cardwo.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,101 @@
+/*     
+ **********************************************************************
+ *     cardwo.h -- header file for card wave out functions
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ * 
+ ********************************************************************** 
+ * 
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version. 
+ * 
+ *     This program is distributed in the hope that it will be useful, 
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ *     GNU General Public License for more details. 
+ * 
+ *     You should have received a copy of the GNU General Public 
+ *     License along with this program; if not, write to the Free 
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 
+ *     USA. 
+ * 
+ ********************************************************************** 
+ */
+
+#ifndef _CARDWO_H
+#define _CARDWO_H
+
+#include "icardwav.h"
+#include "audio.h"
+#include "voicemgr.h"
+#include "timer.h"
+
+/* 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	4
+
+struct waveout_buffer {
+	u16 ossfragshift;
+        u32 numfrags;
+	u32 fragment_size;	/* in bytes units */
+	u32 size;		/* in bytes units */
+	u32 pages;		/* buffer size in page units*/
+	int emupageindex;
+	void *addr[BUFMAXPAGES];
+	dma_addr_t dma_handle[BUFMAXPAGES];
+        u32 silence_pos;	/* software cursor position (including silence) */
+	u32 hw_pos;		/* hardware cursor position */
+	u32 bytestocopy;	/* free space on buffer (including silence) */
+	u8 fill_silence;
+	u32 silence_bytes;      /* silence bytes in buffer */
+};
+
+struct woinst 
+{
+	u8 state;
+	struct emu_voice voice;
+	struct emu_timer timer;
+        struct wave_format format;
+	struct waveout_buffer buffer;
+        wait_queue_head_t wait_queue;
+        u8 mmapped;
+        u32 total_copied;	/* total number of bytes written() to the buffer (excluding silence) */
+        u32 total_played;	/* total number of bytes played including silence */
+        u32 blocks;
+	u8 device;
+	spinlock_t lock;
+};
+
+struct emu10k1_waveout
+{
+	u32 globalvol;
+	u32 mute;
+	u32 left;
+	u32 right;
+	u32 globalreverb;
+	u32 globalchorus;
+};
+
+int emu10k1_waveout_open(struct emu10k1_wavedevice *);
+void emu10k1_waveout_close(struct emu10k1_wavedevice *);
+void emu10k1_waveout_start(struct emu10k1_wavedevice *);
+void emu10k1_waveout_stop(struct emu10k1_wavedevice *);
+void emu10k1_waveout_getxfersize(struct woinst*, u32 *);
+void emu10k1_waveout_xferdata(struct woinst*, u8*, u32 *);
+void emu10k1_waveout_fillsilence(struct woinst*);
+int emu10k1_waveout_setformat(struct emu10k1_wavedevice*, struct wave_format*);
+void emu10k1_waveout_update(struct woinst*);
+
+#endif /* _CARDWO_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/efxmgr.h linux.17p18/drivers/sound/emu10k1/efxmgr.h
--- linux.vanilla/drivers/sound/emu10k1/efxmgr.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/efxmgr.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,43 @@
+/*     
+ **********************************************************************
+ *     sblive_fx.h
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ * 
+ ********************************************************************** 
+ * 
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version. 
+ * 
+ *     This program is distributed in the hope that it will be useful, 
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ *     GNU General Public License for more details. 
+ * 
+ *     You should have received a copy of the GNU General Public 
+ *     License along with this program; if not, write to the Free 
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 
+ *     USA. 
+ * 
+ ********************************************************************** 
+ */
+
+#ifndef _EFXMGR_H
+#define _EFXMGR_H
+
+#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)
+
+
+#endif /* _EFXMGR_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/emu_wrapper.c linux.17p18/drivers/sound/emu10k1/emu_wrapper.c
--- linux.vanilla/drivers/sound/emu10k1/emu_wrapper.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/emu_wrapper.c	Tue Aug  1 08:12:24 2000
@@ -0,0 +1,166 @@
+#include "emu_wrapper.h"
+#include <asm/page.h>
+#include <asm/io.h>
+
+static LIST_HEAD(pci_drivers);
+
+struct pci_driver_mapping {
+        struct pci_dev *dev;
+        struct pci_driver *drv;
+        void *driver_data;
+};
+
+#define PCI_MAX_MAPPINGS 16
+static struct pci_driver_mapping drvmap [PCI_MAX_MAPPINGS] = { { NULL, } , };
+
+void * pci_compat_get_driver_data (struct pci_dev *dev)
+{
+        int i;
+        
+        for (i = 0; i < PCI_MAX_MAPPINGS; i++)
+                if (drvmap[i].dev == dev)
+                        return drvmap[i].driver_data;
+        
+        return NULL;
+}
+
+void pci_compat_set_driver_data (struct pci_dev *dev, void *driver_data)
+{
+        int i;
+        
+        for (i = 0; i < PCI_MAX_MAPPINGS; i++)
+                if (drvmap[i].dev == dev) {
+                        drvmap[i].driver_data = driver_data;
+                        return;
+                } 
+}
+
+const struct pci_device_id *
+pci_compat_match_device(const struct pci_device_id *ids, struct pci_dev *dev)
+{
+        u16 subsystem_vendor, subsystem_device;
+
+        pci_read_config_word(dev, PCI_SUBSYSTEM_VENDOR_ID, &subsystem_vendor);
+        pci_read_config_word(dev, PCI_SUBSYSTEM_ID, &subsystem_device);
+
+        while (ids->vendor || ids->subvendor || ids->class_mask) {
+                if ((ids->vendor == PCI_ANY_ID || ids->vendor == dev->vendor) &&
+                    (ids->device == PCI_ANY_ID || ids->device == dev->device) &&
+                    (ids->subvendor == PCI_ANY_ID || ids->subvendor == subsystem_vendor) &&
+                    (ids->subdevice == PCI_ANY_ID || ids->subdevice == subsystem_device) &&
+                    !((ids->class ^ dev->class) & ids->class_mask))
+                        return ids;
+                ids++;
+        }
+        return NULL;
+}
+
+static int
+pci_announce_device(struct pci_driver *drv, struct pci_dev *dev)
+{
+        const struct pci_device_id *id;
+	int found, i;
+
+        if (drv->id_table) {
+                id = pci_compat_match_device(drv->id_table, dev);
+                if (!id)
+                        return 0;
+        } else
+                id = NULL;
+
+	found = 0;
+	for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+		if (!drvmap[i].dev) {
+			drvmap[i].dev = dev;
+			drvmap[i].drv = drv;
+			found = 1;
+		}
+
+        if (drv->probe(dev, id) >= 0) { 
+		if(found)
+			return 1;
+	} else {
+               drvmap[i - 1].dev = NULL; 
+        }
+        return 0;
+}
+
+int
+pci_compat_register_driver(struct pci_driver *drv)
+{
+        struct pci_dev *dev;
+        int count = 0, found, i;
+#ifdef CONFIG_PCI
+        list_add_tail(&drv->node, &pci_drivers);
+        pci_for_each_dev(dev) {
+                found = 0;
+                for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+                        if (drvmap[i].dev == dev)
+                                found = 1;
+                if (!found)
+                        count += pci_announce_device(drv, dev);
+        }
+#endif        
+        return count;
+}
+
+void
+pci_compat_unregister_driver(struct pci_driver *drv)
+{
+        struct pci_dev *dev;
+        int i, found;
+#ifdef CONFIG_PCI
+        list_del(&drv->node);
+        pci_for_each_dev(dev) {
+                found = 0;
+                for (i = 0; i < PCI_MAX_MAPPINGS && !found; i++)
+                        if (drvmap[i].dev == dev)
+                                found = 1;
+                if (found) {
+                        if (drv->remove)
+                                drv->remove(dev);
+                        drvmap[i].dev = NULL;
+                }
+        }
+#endif        
+}
+
+unsigned long pci_compat_get_size (struct pci_dev *dev, int n_base)
+{
+        u32 l, sz;
+        int reg = PCI_BASE_ADDRESS_0 + (n_base << 2);
+
+        /* XXX temporarily disable I/O and memory decoding for this device? */
+
+        pci_read_config_dword (dev, reg, &l);
+        if (l == 0xffffffff)
+                return 0;
+
+        pci_write_config_dword (dev, reg, ~0);
+        pci_read_config_dword (dev, reg, &sz);
+        pci_write_config_dword (dev, reg, l);
+
+        if (!sz || sz == 0xffffffff)
+                return 0;
+        if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY) {
+                sz = ~(sz & PCI_BASE_ADDRESS_MEM_MASK);
+        } else {
+                sz = ~(sz & PCI_BASE_ADDRESS_IO_MASK) & 0xffff;
+        }
+
+        return sz + 1;
+}
+
+int pci_compat_enable_device(struct pci_dev *dev)
+{
+        return 0;
+}
+
+void *compat_request_region (unsigned long start, unsigned long n, const char *name)
+{
+        if (check_region (start, n) != 0)
+                return NULL;
+        request_region (start, n, name);
+        return (void *) 1;
+}
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/emu_wrapper.h linux.17p18/drivers/sound/emu10k1/emu_wrapper.h
--- linux.vanilla/drivers/sound/emu10k1/emu_wrapper.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/emu_wrapper.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,178 @@
+#ifndef __EMU_WRAPPER_H
+#define __EMU_WRAPPER_H
+
+/* wrapper for 2.2 kernel */
+
+#include <linux/wrapper.h>
+#include <linux/list.h>
+#include <linux/pci.h>
+#include <asm/page.h>
+#include <linux/mm.h>
+#include <asm/io.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/tqueue.h>
+
+#define vma_get_pgoff(v)	vma_get_offset(v)
+#define wait_queue_head_t	struct wait_queue *
+#define DECLARE_WAITQUEUE(a, b)	struct wait_queue a = {b, NULL};
+#define init_waitqueue_head(a)	init_waitqueue(a)
+
+#define init_MUTEX(a)		*(a) = MUTEX
+
+#define UP_INODE_SEM(a)		up(a)
+#define DOWN_INODE_SEM(a)	down(a)
+
+#define GET_INODE_STRUCT()	struct inode *inode = file->f_dentry->d_inode
+
+#define tasklet_hi_schedule(t)	queue_task((t), &tq_immediate); \
+				mark_bh(IMMEDIATE_BH)
+
+#define tasklet_init(t,f,d)	(t)->next = NULL; \
+				(t)->sync = 0; \
+				(t)->routine = (void (*)(void *))(f); \
+				(t)->data = (void *)(d)
+
+#define tasklet_struct		tq_struct 
+
+#define tasklet_unlock_wait(t)	while (test_bit(0, &(t)->sync)) { }
+
+#define __exit
+#define __exitdata
+#define __devinit
+#define __devinitdata
+#define __devexit
+#define __devexitdata
+
+/* Not sure what version aliases were introduced in, but certainly in 2.91.66.  */
+#ifdef MODULE
+  #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
+    #define module_init(x)      int init_module(void) __attribute__((alias(#x)));
+    #define module_exit(x)      void cleanup_module(void) __attribute__((alias(#x)));
+  #else
+    #define module_init(x)      int init_module(void) { return x(); }
+    #define module_exit(x)      void cleanup_module(void) { x(); }
+  #endif
+#else
+  #define module_init(x)
+  #define module_exit(x)
+#endif
+
+#define MODULE_DEVICE_TABLE(foo,bar)
+
+static __inline__ void list_add_tail(struct list_head *new, struct list_head *head)
+{
+        __list_add(new, head->prev, head);
+}
+
+#define list_for_each(pos, head) \
+        for (pos = (head)->next; pos != (head); pos = pos->next)
+
+#define pci_dma_supported(dev, mask) 1
+
+#define PCI_ANY_ID (~0)
+
+#define PCI_GET_DRIVER_DATA pci_compat_get_driver_data
+#define PCI_SET_DRIVER_DATA pci_compat_set_driver_data
+
+#define PCI_SET_DMA_MASK(dev,data)
+
+#define pci_enable_device pci_compat_enable_device
+#define pci_register_driver pci_compat_register_driver
+#define pci_unregister_driver pci_compat_unregister_driver
+
+#define pci_for_each_dev(dev) \
+        for(dev = pci_devices; dev; dev = dev->next)
+
+#define pci_resource_start(dev,bar) \
+(((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_SPACE) ? \
+ ((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_IO_MASK) : \
+ ((dev)->base_address[(bar)] & PCI_BASE_ADDRESS_MEM_MASK))
+#define pci_resource_len pci_compat_get_size
+
+struct pci_device_id {
+        unsigned int vendor, device;
+        unsigned int subvendor, subdevice;
+        unsigned int class, class_mask;
+        unsigned long driver_data;
+};
+
+struct pci_driver {
+        struct list_head node;
+        struct pci_dev *dev;
+        char *name;
+        const struct pci_device_id *id_table;   /* NULL if wants all devices */
+        int (*probe)(struct pci_dev *dev, const struct pci_device_id *id);      /* New device inserted */
+        void (*remove)(struct pci_dev *dev);    /* Device removed (NULL if not a hot-plug capable driver) */
+        void (*suspend)(struct pci_dev *dev);   /* Device suspended */
+        void (*resume)(struct pci_dev *dev);    /* Device woken up */
+};
+
+const struct pci_device_id * pci_compat_match_device(const struct pci_device_id *ids, struct pci_dev *dev);
+int pci_compat_register_driver(struct pci_driver *drv);
+void pci_compat_unregister_driver(struct pci_driver *drv);
+unsigned long pci_compat_get_size (struct pci_dev *dev, int n_base);
+int pci_compat_enable_device(struct pci_dev *dev);
+void *compat_request_region (unsigned long start, unsigned long n, const char *name);
+void * pci_compat_get_driver_data (struct pci_dev *dev);
+void pci_compat_set_driver_data (struct pci_dev *dev, void *driver_data);
+
+typedef u32 dma_addr_t;
+
+extern __inline__ int __compat_get_order(unsigned long size)
+{
+        int order;
+
+        size = (size-1) >> (PAGE_SHIFT-1);
+        order = -1;
+        do {
+                size >>= 1;
+                order++;
+        } while (size);
+        return order;
+}
+
+extern __inline__ void *
+pci_alloc_consistent(struct pci_dev *hwdev,
+                     size_t size, dma_addr_t *dma_handle) {
+        void *ret;
+        int gfp = GFP_ATOMIC;
+
+        if (hwdev == NULL)
+                gfp |= GFP_DMA;
+        ret = (void *)__get_free_pages(gfp, __compat_get_order(size));
+
+        if (ret != NULL) {
+                memset(ret, 0, size);
+                *dma_handle = virt_to_bus(ret);
+        }
+        return ret;
+}
+
+extern __inline__ void
+pci_free_consistent(struct pci_dev *hwdev, size_t size,
+                    void *vaddr, dma_addr_t dma_handle)
+{
+        free_pages((unsigned long)vaddr, __compat_get_order(size));
+}
+
+static inline int pci_module_init(struct pci_driver *drv)
+{
+        int rc = pci_register_driver (drv);
+
+        if (rc > 0)
+                return 0;
+
+        /* if we get here, we need to clean up pci driver instance
+         * and return some sort of error */
+        pci_unregister_driver (drv);
+        
+        return -ENODEV;
+}
+
+#define BUG() do { \
+        printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \
+        __asm__ __volatile__(".byte 0x0f,0x0b"); \
+} while (0)
+
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/emuadxmg.c linux.17p18/drivers/sound/emu10k1/emuadxmg.c
--- linux.vanilla/drivers/sound/emu10k1/emuadxmg.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/emuadxmg.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,104 @@
+
+/*     
+ **********************************************************************
+ *     emuadxmg.c - Address space manager for emu10k1 driver 
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ * 
+ ********************************************************************** 
+ * 
+ *     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. 
+ * 
+ ********************************************************************** 
+ */
+
+#include "hwaccess.h"
+
+/* Allocates emu address space */
+
+int emu10k1_addxmgr_alloc(u32 size, struct emu10k1_card *card)
+{
+	u16 *pagetable = card->emupagetable;
+	u16 index = 0;
+	u16 numpages;
+	unsigned long flags;
+
+	/* Convert bytes to pages */
+	numpages = (size / EMUPAGESIZE) + ((size % EMUPAGESIZE) ? 1 : 0);
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	while (index < (MAXPAGES - 1)) {
+		if (pagetable[index] & 0x8000) {
+			/* This block of pages is in use, jump to the start of the next block. */
+			index += (pagetable[index] & 0x7fff);
+		} else {
+			/* Found free block */
+			if (pagetable[index] >= numpages) {
+
+				/* Block is large enough */
+
+				/* If free block is larger than the block requested
+				 * then adjust the size of the block remaining */
+				if (pagetable[index] > numpages)
+					pagetable[index + numpages] = pagetable[index] - numpages;
+
+				pagetable[index] = (numpages | 0x8000);	/* Mark block as used */
+
+				spin_unlock_irqrestore(&card->lock, flags);
+
+				return index;
+			} else {
+				/* Block too small, jump to the start of the next block */
+				index += pagetable[index];
+			}
+		}
+	}
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return -1;
+}
+
+/* Frees a previously allocated emu address space. */
+
+void emu10k1_addxmgr_free(struct emu10k1_card *card, int index)
+{
+	u16 *pagetable = card->emupagetable;
+	u16 origsize = 0;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	if (pagetable[index] & 0x8000) {
+		/* Block is allocated - mark block as free */
+		origsize = pagetable[index] & 0x7fff;
+		pagetable[index] = origsize;
+
+		/* If next block is free, we concat both blocks */
+		if (!(pagetable[index + origsize] & 0x8000))
+			pagetable[index] += pagetable[index + origsize] & 0x7fff;
+	}
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/hwaccess.c linux.17p18/drivers/sound/emu10k1/hwaccess.c
--- linux.vanilla/drivers/sound/emu10k1/hwaccess.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/hwaccess.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,498 @@
+/*
+ **********************************************************************
+ *     hwaccess.c -- Hardware access layer
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     December 9, 1999     Jon Taylor      rewrote the I/O subsystem
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include <asm/io.h>
+
+#include "hwaccess.h"
+#include "8010.h"
+#include "icardmid.h"
+
+/*************************************************************************
+* Function : srToPitch                                                   *
+* Input    : sampleRate - sampling rate                                  *
+* Return   : pitch value                                                 *
+* About    : convert sampling rate to pitch                              *
+* Note     : for 8010, sampling rate is at 48kHz, this function should   *
+*            be changed.                                                 *
+*************************************************************************/
+u32 srToPitch(u32 sampleRate)
+{
+	int i;
+
+	/* FIXME: These tables should be defined in a headerfile */
+	static u32 logMagTable[128] = {
+		0x00000, 0x02dfc, 0x05b9e, 0x088e6, 0x0b5d6, 0x0e26f, 0x10eb3, 0x13aa2,
+		0x1663f, 0x1918a, 0x1bc84, 0x1e72e, 0x2118b, 0x23b9a, 0x2655d, 0x28ed5,
+		0x2b803, 0x2e0e8, 0x30985, 0x331db, 0x359eb, 0x381b6, 0x3a93d, 0x3d081,
+		0x3f782, 0x41e42, 0x444c1, 0x46b01, 0x49101, 0x4b6c4, 0x4dc49, 0x50191,
+		0x5269e, 0x54b6f, 0x57006, 0x59463, 0x5b888, 0x5dc74, 0x60029, 0x623a7,
+		0x646ee, 0x66a00, 0x68cdd, 0x6af86, 0x6d1fa, 0x6f43c, 0x7164b, 0x73829,
+		0x759d4, 0x77b4f, 0x79c9a, 0x7bdb5, 0x7dea1, 0x7ff5e, 0x81fed, 0x8404e,
+		0x86082, 0x88089, 0x8a064, 0x8c014, 0x8df98, 0x8fef1, 0x91e20, 0x93d26,
+		0x95c01, 0x97ab4, 0x9993e, 0x9b79f, 0x9d5d9, 0x9f3ec, 0xa11d8, 0xa2f9d,
+		0xa4d3c, 0xa6ab5, 0xa8808, 0xaa537, 0xac241, 0xadf26, 0xafbe7, 0xb1885,
+		0xb3500, 0xb5157, 0xb6d8c, 0xb899f, 0xba58f, 0xbc15e, 0xbdd0c, 0xbf899,
+		0xc1404, 0xc2f50, 0xc4a7b, 0xc6587, 0xc8073, 0xc9b3f, 0xcb5ed, 0xcd07c,
+		0xceaec, 0xd053f, 0xd1f73, 0xd398a, 0xd5384, 0xd6d60, 0xd8720, 0xda0c3,
+		0xdba4a, 0xdd3b4, 0xded03, 0xe0636, 0xe1f4e, 0xe384a, 0xe512c, 0xe69f3,
+		0xe829f, 0xe9b31, 0xeb3a9, 0xecc08, 0xee44c, 0xefc78, 0xf148a, 0xf2c83,
+		0xf4463, 0xf5c2a, 0xf73da, 0xf8b71, 0xfa2f0, 0xfba57, 0xfd1a7, 0xfe8df
+	};
+
+	static char logSlopeTable[128] = {
+		0x5c, 0x5c, 0x5b, 0x5a, 0x5a, 0x59, 0x58, 0x58,
+		0x57, 0x56, 0x56, 0x55, 0x55, 0x54, 0x53, 0x53,
+		0x52, 0x52, 0x51, 0x51, 0x50, 0x50, 0x4f, 0x4f,
+		0x4e, 0x4d, 0x4d, 0x4d, 0x4c, 0x4c, 0x4b, 0x4b,
+		0x4a, 0x4a, 0x49, 0x49, 0x48, 0x48, 0x47, 0x47,
+		0x47, 0x46, 0x46, 0x45, 0x45, 0x45, 0x44, 0x44,
+		0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x41, 0x41,
+		0x41, 0x40, 0x40, 0x40, 0x3f, 0x3f, 0x3f, 0x3e,
+		0x3e, 0x3e, 0x3d, 0x3d, 0x3d, 0x3c, 0x3c, 0x3c,
+		0x3b, 0x3b, 0x3b, 0x3b, 0x3a, 0x3a, 0x3a, 0x39,
+		0x39, 0x39, 0x39, 0x38, 0x38, 0x38, 0x38, 0x37,
+		0x37, 0x37, 0x37, 0x36, 0x36, 0x36, 0x36, 0x35,
+		0x35, 0x35, 0x35, 0x34, 0x34, 0x34, 0x34, 0x34,
+		0x33, 0x33, 0x33, 0x33, 0x32, 0x32, 0x32, 0x32,
+		0x32, 0x31, 0x31, 0x31, 0x31, 0x31, 0x30, 0x30,
+		0x30, 0x30, 0x30, 0x2f, 0x2f, 0x2f, 0x2f, 0x2f
+	};
+
+	if (sampleRate == 0)
+		return 0;	/* Bail out if no leading "1" */
+
+	sampleRate *= 11185;	/* Scale 48000 to 0x20002380 */
+
+	for (i = 31; i > 0; i--) {
+		if (sampleRate & 0x80000000) {	/* Detect leading "1" */
+			return (u32) (((s32) (i - 15) << 20) +
+				      logMagTable[0x7f & (sampleRate >> 24)] +
+				      (0x7f & (sampleRate >> 17)) * logSlopeTable[0x7f & (sampleRate >> 24)]);
+		}
+		sampleRate = sampleRate << 1;
+	}
+
+	DPF(2, "srToPitch: BUG!\n");
+	return 0;		/* Should never reach this point */
+}
+
+/* Returns an attenuation based upon a cumulative volume value */
+
+/* Algorithm calculates 0x200 - 0x10 log2 (input) */
+u8 sumVolumeToAttenuation(u32 value)
+{
+	u16 count = 16;
+	s16 ans;
+
+	if (value == 0)
+		return 0xFF;
+
+	/* Find first SET bit. This is the integer part of the value */
+	while ((value & 0x10000) == 0) {
+		value <<= 1;
+		count--;
+	}
+
+	/* The REST of the data is the fractional part. */
+	ans = (s16) (0x110 - ((count << 4) + ((value & 0x0FFFFL) >> 12)));
+	if (ans > 0xFF)
+		ans = 0xFF;
+
+	return (u8) ans;
+}
+
+/*******************************************
+* write/read PCI function 0 registers      *
+********************************************/
+void emu10k1_writefn0(struct emu10k1_card *card, u32 reg, u32 data)
+{
+	unsigned long flags;
+
+	if (reg & 0xff000000) {
+		u32 mask;
+		u8 size, offset;
+
+		size = (reg >> 24) & 0x3f;
+		offset = (reg >> 16) & 0x1f;
+		mask = ((1 << size) - 1) << offset;
+		data = (data << offset) & mask;
+		reg &= 0x7f;
+
+		spin_lock_irqsave(&card->lock, flags);
+		data |= inl(card->iobase + reg) & ~mask;
+		outl(data, card->iobase + reg);
+		spin_unlock_irqrestore(&card->lock, flags);
+	} else {
+		spin_lock_irqsave(&card->lock, flags);
+		outl(data, card->iobase + reg);
+		spin_unlock_irqrestore(&card->lock, flags);
+	}
+
+	return;
+}
+
+u32 emu10k1_readfn0(struct emu10k1_card * card, u32 reg)
+{
+	u32 val;
+	unsigned long flags;
+
+	if (reg & 0xff000000) {
+		u32 mask;
+		u8 size, offset;
+
+		size = (reg >> 24) & 0x3f;
+		offset = (reg >> 16) & 0x1f;
+		mask = ((1 << size) - 1) << offset;
+		reg &= 0x7f;
+
+		spin_lock_irqsave(&card->lock, flags);
+		val = inl(card->iobase + reg);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		return (val & mask) >> offset;
+        } else {
+		spin_lock_irqsave(&card->lock, flags);
+		val = inl(card->iobase + reg);
+		spin_unlock_irqrestore(&card->lock, flags);
+		return val;
+	}
+}
+
+/************************************************************************
+* write/read Emu10k1 pointer-offset register set, accessed through      *
+*  the PTR and DATA registers                                           *
+*************************************************************************/
+void sblive_writeptr(struct emu10k1_card *card, u32 reg, u32 channel, u32 data)
+{
+	u32 regptr;
+	unsigned long flags;
+
+	regptr = ((reg << 16) & PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
+
+	if (reg & 0xff000000) {
+		u32 mask;
+		u8 size, offset;
+
+		size = (reg >> 24) & 0x3f;
+		offset = (reg >> 16) & 0x1f;
+		mask = ((1 << size) - 1) << offset;
+		data = (data << offset) & mask;
+
+		spin_lock_irqsave(&card->lock, flags);
+		outl(regptr, card->iobase + PTR);
+		data |= inl(card->iobase + DATA) & ~mask;
+		outl(data, card->iobase + DATA);
+		spin_unlock_irqrestore(&card->lock, flags);
+	} else {
+		spin_lock_irqsave(&card->lock, flags);
+		outl(regptr, card->iobase + PTR);
+		outl(data, card->iobase + DATA);
+		spin_unlock_irqrestore(&card->lock, flags);
+	}
+}
+
+/* ... :  data, reg, ... , TAGLIST_END */
+void sblive_writeptr_tag(struct emu10k1_card *card, u32 channel, ...)
+{
+	va_list args;
+
+	unsigned long flags;
+        u32 reg;
+
+	va_start(args, channel);
+
+	spin_lock_irqsave(&card->lock, flags);
+	while ((reg = va_arg(args, u32)) != TAGLIST_END) {
+		u32 data = va_arg(args, u32);
+		u32 regptr = (((reg << 16) & PTR_ADDRESS_MASK)
+			      | (channel & PTR_CHANNELNUM_MASK));
+		outl(regptr, card->iobase + PTR);
+		if (reg & 0xff000000) {
+			int size = (reg >> 24) & 0x3f;
+                        int offset = (reg >> 16) & 0x1f;
+			u32 mask = ((1 << size) - 1) << offset;
+			data = (data << offset) & mask;
+
+			data |= inl(card->iobase + DATA) & ~mask;
+		}
+		outl(data, card->iobase + DATA);
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	va_end(args);
+
+	return;
+}
+
+u32 sblive_readptr(struct emu10k1_card * card, u32 reg, u32 channel)
+{
+	u32 regptr, val;
+	unsigned long flags;
+
+	regptr = ((reg << 16) & PTR_ADDRESS_MASK) | (channel & PTR_CHANNELNUM_MASK);
+
+	if (reg & 0xff000000) {
+		u32 mask;
+		u8 size, offset;
+
+		size = (reg >> 24) & 0x3f;
+		offset = (reg >> 16) & 0x1f;
+		mask = ((1 << size) - 1) << offset;
+
+		spin_lock_irqsave(&card->lock, flags);
+		outl(regptr, card->iobase + PTR);
+		val = inl(card->iobase + DATA);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		return (val & mask) >> offset;
+	} else {
+		spin_lock_irqsave(&card->lock, flags);
+		outl(regptr, card->iobase + PTR);
+		val = inl(card->iobase + DATA);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		return val;
+	}
+}
+
+void emu10k1_irq_enable(struct emu10k1_card *card, u32 irq_mask)
+{
+	u32 val;
+	unsigned long flags;
+
+	DPF(2,"emu10k1_irq_enable()\n");
+
+	spin_lock_irqsave(&card->lock, flags);
+        val = inl(card->iobase + INTE) | irq_mask;
+        outl(val, card->iobase + INTE);
+	spin_unlock_irqrestore(&card->lock, flags);
+	return;
+}
+
+void emu10k1_irq_disable(struct emu10k1_card *card, u32 irq_mask)
+{
+        u32 val;
+        unsigned long flags;
+
+        DPF(2,"emu10k1_irq_disable()\n");
+
+        spin_lock_irqsave(&card->lock, flags);
+        val = inl(card->iobase + INTE) & ~irq_mask;
+        outl(val, card->iobase + INTE);
+        spin_unlock_irqrestore(&card->lock, flags);
+        return;
+}
+
+void emu10k1_set_stop_on_loop(struct emu10k1_card *card, u32 voicenum)
+{
+	/* Voice interrupt */
+	if (voicenum >= 32)
+		sblive_writeptr(card, SOLEH | ((0x0100 | (voicenum - 32)) << 16), 0, 1);
+	else
+		sblive_writeptr(card, SOLEL | ((0x0100 | voicenum) << 16), 0, 1);
+
+	return;
+}
+
+void emu10k1_clear_stop_on_loop(struct emu10k1_card *card, u32 voicenum)
+{
+	/* Voice interrupt */
+	if (voicenum >= 32)
+		sblive_writeptr(card, SOLEH | ((0x0100 | (voicenum - 32)) << 16), 0, 0);
+	else
+		sblive_writeptr(card, SOLEL | ((0x0100 | voicenum) << 16), 0, 0);
+
+	return;
+}
+
+static void sblive_wcwait(struct emu10k1_card *card, u32 wait)
+{
+	volatile unsigned uCount;
+	u32 newtime = 0, curtime;
+
+	curtime = emu10k1_readfn0(card, WC_SAMPLECOUNTER);
+	while (wait--) {
+		uCount = 0;
+		while (uCount++ < TIMEOUT) {
+			newtime = emu10k1_readfn0(card, WC_SAMPLECOUNTER);
+			if (newtime != curtime)
+				break;
+		}
+
+		if (uCount >= TIMEOUT)
+			break;
+
+		curtime = newtime;
+	}
+}
+
+int sblive_readac97(struct emu10k1_card *card, u8 index, u16 * data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	outb(index, card->iobase + AC97ADDRESS);
+	*data = inw(card->iobase + AC97DATA);
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int sblive_writeac97(struct emu10k1_card *card, u8 index, u16 data)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	outb(index, card->iobase + AC97ADDRESS);
+	outw(data, card->iobase + AC97DATA);
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+int sblive_rmwac97(struct emu10k1_card *card, u8 index, u16 data, u16 mask)
+{
+	u16 temp;
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	outb(index, card->iobase + AC97ADDRESS);
+	temp = inw(card->iobase + AC97DATA);
+	temp &= ~mask;
+	data &= mask;
+	temp |= data;
+	outw(temp, card->iobase + AC97DATA);
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+/*********************************************************
+*            MPU access functions                        *
+**********************************************************/
+
+int emu10k1_mpu_write_data(struct emu10k1_card *card, u8 data)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	if ((inb(card->iobase + MUSTAT) & MUSTAT_ORDYN) == 0) {
+		outb(data, card->iobase + MUDATA);
+		ret = CTSTATUS_SUCCESS;
+	} else
+		ret = CTSTATUS_BUSY;
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return ret;
+}
+
+int emu10k1_mpu_read_data(struct emu10k1_card *card, u8 * data)
+{
+	unsigned long flags;
+	int ret;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	if ((inb(card->iobase + MUSTAT) & MUSTAT_IRDYN) == 0) {
+		*data = inb(card->iobase + MUDATA);
+		ret = CTSTATUS_SUCCESS;
+	} else
+		ret = CTSTATUS_NODATA;
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return ret;
+}
+
+int emu10k1_mpu_reset(struct emu10k1_card *card)
+{
+	u8 status;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_mpu_reset()\n");
+
+	if (card->mpuacqcount == 0) {
+		spin_lock_irqsave(&card->lock, flags);
+		outb(MUCMD_RESET, card->iobase + MUCMD);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		sblive_wcwait(card, 8);
+
+		spin_lock_irqsave(&card->lock, flags);
+		outb(MUCMD_RESET, card->iobase + MUCMD);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		sblive_wcwait(card, 8);
+
+		spin_lock_irqsave(&card->lock, flags);
+		outb(MUCMD_ENTERUARTMODE, card->iobase + MUCMD);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		sblive_wcwait(card, 8);
+
+		spin_lock_irqsave(&card->lock, flags);
+		status = inb(card->iobase + MUDATA);
+		spin_unlock_irqrestore(&card->lock, flags);
+
+		if (status == 0xfe)
+			return CTSTATUS_SUCCESS;
+		else
+			return CTSTATUS_ERROR;
+	}
+
+	return CTSTATUS_SUCCESS;
+}
+
+int emu10k1_mpu_acquire(struct emu10k1_card *card)
+{
+	/* FIXME: This should be a macro */
+	++card->mpuacqcount;
+
+	return CTSTATUS_SUCCESS;
+}
+
+int emu10k1_mpu_release(struct emu10k1_card *card)
+{
+	/* FIXME: this should be a macro */
+	--card->mpuacqcount;
+
+	return CTSTATUS_SUCCESS;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/hwaccess.h linux.17p18/drivers/sound/emu10k1/hwaccess.h
--- linux.vanilla/drivers/sound/emu10k1/hwaccess.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/hwaccess.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,189 @@
+/*
+ **********************************************************************
+ *     hwaccess.h
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date		    Author	    Summary of changes
+ *     ----		    ------	    ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _HWACCESS_H
+#define _HWACCESS_H
+
+#include <linux/fs.h>
+#include <linux/sound.h>
+#include <linux/soundcard.h>
+#include <linux/pci.h>
+
+#include "emu_wrapper.h"
+
+#define EMUPAGESIZE     4096            /* don't change */
+#define NUM_G           64              /* use all channels */
+#define NUM_FXSENDS     4               /* don't change */
+/* setting this to other than a power of two may break some applications */
+#define MAXBUFSIZE	65536
+#define MAXPAGES	8192 
+#define BUFMAXPAGES     (MAXBUFSIZE / PAGE_SIZE)
+
+enum GlobalErrorCode
+{
+	CTSTATUS_SUCCESS = 0x0000,
+	CTSTATUS_ERROR,
+	CTSTATUS_NOMEMORY,
+	CTSTATUS_INUSE,
+};
+
+#define FLAGS_AVAILABLE     0x0001
+#define FLAGS_READY         0x0002
+
+#define min(x,y) ((x) < (y)) ? (x) : (y)
+
+struct memhandle
+{
+	dma_addr_t dma_handle;
+	void *addr;
+	u32 size;
+};
+
+#define DEBUG_LEVEL 2
+
+#ifdef EMU10K1_DEBUG
+# define DPD(level,x,y...) do {if(level <= DEBUG_LEVEL) printk( KERN_NOTICE "emu10k1: %s: %d: " x , __FILE__ , __LINE__ , y );} while(0)
+# define DPF(level,x)   do {if(level <= DEBUG_LEVEL) printk( KERN_NOTICE "emu10k1: %s: %d: " x , __FILE__ , __LINE__ );} while(0)
+#define ERROR() DPF(1,"error\n");
+#else
+# define DPD(level,x,y...) do { } while (0) /* not debugging: nothing */
+# define DPF(level,x) do { } while (0)
+#define ERROR() do { } while (0)
+#endif /* EMU10K1_DEBUG */
+
+/* DATA STRUCTURES */
+
+struct emu10k1_card 
+{
+	struct list_head list;
+
+	struct memhandle	virtualpagetable;
+	struct memhandle	tankmem;
+	struct memhandle	silentpage;
+
+	spinlock_t		lock;
+
+	u8			voicetable[NUM_G];
+	u16			emupagetable[MAXPAGES];
+
+	struct list_head	timers;
+	unsigned		timer_delay;
+	spinlock_t		timer_lock;
+
+	struct pci_dev		*pci_dev;
+	unsigned long           iobase;
+	unsigned long		length;
+	unsigned short		model;
+	unsigned int irq; 
+
+	unsigned long	audio1_num;
+	unsigned long	audio2_num;
+	unsigned long	mixer_num;
+	unsigned long	midi_num;
+
+	struct emu10k1_waveout	*waveout;
+	struct emu10k1_wavein	*wavein;
+	struct emu10k1_mpuout	*mpuout;
+	struct emu10k1_mpuin	*mpuin;
+
+	u16			arrwVol[SOUND_MIXER_NRDEVICES + 1];
+	/* array is used from the member 1 to save (-1) operation */
+	u32			digmix[9 * 6 * 2];
+	unsigned int		modcnt;
+	struct semaphore	open_sem;
+	mode_t			open_mode;
+	wait_queue_head_t	open_wait;
+
+	u32	    mpuacqcount;	  // Mpu acquire count
+	u32	    has_toslink;	       // TOSLink detection
+
+	u8 chiprev;                    /* Chip revision                */
+};
+
+int emu10k1_addxmgr_alloc(u32, struct emu10k1_card *);
+void emu10k1_addxmgr_free(struct emu10k1_card *, int);
+
+#ifdef PRIVATE_PCM_VOLUME
+
+#define MAX_PCM_CHANNELS NUM_G 
+struct sblive_pcm_volume_rec {
+	struct files_struct *files; // identification of the same thread
+	u8 attn_l;		// attenuation for left channel
+	u8 attn_r;		// attenuation for right channel
+	u16 mixer;		// saved mixer value for return
+	u8 channel_l;		// idx of left channel
+	u8 channel_r;		// idx of right channel
+	int opened;		// counter - locks element
+};
+extern struct sblive_pcm_volume_rec sblive_pcm_volume[];
+extern u16 pcm_last_mixer;
+#endif
+
+
+#define ENABLE 			0xffffffff
+#define DISABLE 		0x00000000
+
+#define TIMEOUT 		    16384
+
+u32 srToPitch(u32);
+u8 sumVolumeToAttenuation(u32);
+
+extern struct list_head emu10k1_devs;
+
+/* Hardware Abstraction Layer access functions */
+
+void emu10k1_writefn0(struct emu10k1_card *, u32 , u32 );
+u32 emu10k1_readfn0(struct emu10k1_card *, u32 );
+
+void sblive_writeptr(struct emu10k1_card *, u32 , u32 , u32 );
+void sblive_writeptr_tag(struct emu10k1_card *card, u32 channel, ...);
+#define TAGLIST_END 0
+
+u32 sblive_readptr(struct emu10k1_card *, u32 , u32 );
+
+void emu10k1_irq_enable(struct emu10k1_card *, u32);
+void emu10k1_irq_disable(struct emu10k1_card *, u32);
+void emu10k1_set_stop_on_loop(struct emu10k1_card *, u32);
+void emu10k1_clear_stop_on_loop(struct emu10k1_card *, u32);
+
+/* AC97 Mixer access function */
+int sblive_readac97(struct emu10k1_card *, u8, u16 *);
+int sblive_writeac97(struct emu10k1_card *, u8, u16);
+int sblive_rmwac97(struct emu10k1_card *, u8, u16, u16);
+
+/* MPU access function*/
+int emu10k1_mpu_write_data(struct emu10k1_card *, u8);
+int emu10k1_mpu_read_data(struct emu10k1_card *, u8 *);
+int emu10k1_mpu_reset(struct emu10k1_card *);
+int emu10k1_mpu_acquire(struct emu10k1_card *);
+int emu10k1_mpu_release(struct emu10k1_card *);
+
+#endif  /* _HWACCESS_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/icardmid.h linux.17p18/drivers/sound/emu10k1/icardmid.h
--- linux.vanilla/drivers/sound/emu10k1/icardmid.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/icardmid.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,163 @@
+/*
+ **********************************************************************
+ *     isblive_mid.h
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _ICARDMIDI_H
+#define _ICARDMIDI_H
+
+/* MIDI defines */
+#define MIDI_DATA_FIRST                 0x00
+#define MIDI_DATA_LAST                  0x7F
+#define MIDI_STATUS_FIRST               0x80
+#define MIDI_STATUS_LAST                0xFF
+
+/* Channel status bytes */
+#define MIDI_STATUS_CHANNEL_FIRST       0x80
+#define MIDI_STATUS_CHANNEL_LAST        0xE0
+#define MIDI_STATUS_CHANNEL_MASK        0xF0
+
+/* Channel voice messages */
+#define MIDI_VOICE_NOTE_OFF             0x80
+#define MIDI_VOICE_NOTE_ON              0x90
+#define MIDI_VOICE_POLY_PRESSURE        0xA0
+#define MIDI_VOICE_CONTROL_CHANGE       0xB0
+#define MIDI_VOICE_PROGRAM_CHANGE       0xC0
+#define MIDI_VOICE_CHANNEL_PRESSURE     0xD0
+#define MIDI_VOICE_PITCH_BEND           0xE0
+
+/* Channel mode messages */
+#define MIDI_MODE_CHANNEL               MIDI_VOICE_CONTROL_CHANGE
+
+/* System status bytes */
+#define MIDI_STATUS_SYSTEM_FIRST        0xF0
+#define MIDI_STATUS_SYSTEM_LAST         0xFF
+
+/* System exclusive messages */
+#define MIDI_SYSEX_BEGIN                0xF0
+#define MIDI_SYSEX_EOX                  0xF7
+
+/* System common messages */
+#define MIDI_COMMON_TCQF                0xF1	/* Time code quarter frame  */
+#define MIDI_COMMON_SONG_POSITION       0xF2
+#define MIDI_COMMON_SONG_SELECT         0xF3
+#define MIDI_COMMON_UNDEFINED_F4        0xF4
+#define MIDI_COMMON_UNDEFINED_F5        0xF5
+#define MIDI_COMMON_TUNE_REQUEST        0xF6
+
+/* System real-time messages */
+#define MIDI_RTIME_TIMING_CLOCK         0xF8
+#define MIDI_RTIME_UNDEFINED_F9         0xF9
+#define MIDI_RTIME_START                0xFA
+#define MIDI_RTIME_CONTINUE             0xFB
+#define MIDI_RTIME_STOP                 0xFC
+#define MIDI_RTIME_UNDEFINED_FD         0xFD
+#define MIDI_RTIME_ACTIVE_SENSING       0xFE
+#define MIDI_RTIME_SYSTEM_RESET         0xFF
+
+/* Flags for flags parm of midiOutCachePatches(), midiOutCacheDrumPatches() */
+#define MIDI_CACHE_ALL                  1
+#define MIDI_CACHE_BESTFIT              2
+#define MIDI_CACHE_QUERY                3
+#define MIDI_UNCACHE                    4
+
+/* Event declarations for MPU IRQ Callbacks */
+#define ICARDMIDI_INLONGDATA            0x00000001 /* MIM_LONGDATA */
+#define ICARDMIDI_INLONGERROR           0x00000002 /* MIM_LONGERROR */
+#define ICARDMIDI_OUTLONGDATA           0x00000004 /* MOM_DONE for MPU OUT buffer */
+#define ICARDMIDI_INDATA                0x00000010 /* MIM_DATA */
+#define ICARDMIDI_INDATAERROR           0x00000020 /* MIM_ERROR */
+
+/* Declaration for flags in CARDMIDIBUFFERHDR */
+/* Make it the same as MHDR_DONE, MHDR_INQUEUE in mmsystem.h */
+#define MIDIBUF_DONE                    0x00000001
+#define MIDIBUF_INQUEUE                 0x00000004
+
+/* Declaration for msg parameter in midiCallbackFn */
+#define ICARDMIDI_OUTBUFFEROK           0x00000001
+#define ICARDMIDI_INMIDIOK              0x00000002
+
+/* Declaration for technology in struct midi_caps */
+#define MT_MIDIPORT                     0x00000001	/* In original MIDIOUTCAPS structure */
+#define MT_FMSYNTH                      0x00000004	/* In original MIDIOUTCAPS structure */
+#define MT_AWESYNTH                     0x00001000
+#define MT_PCISYNTH                     0x00002000
+#define MT_PCISYNTH64                   0x00004000
+#define CARDMIDI_AWEMASK                0x0000F000
+
+enum LocalErrorCode
+{
+        CTSTATUS_NOTENABLED = 0x7000,
+        CTSTATUS_READY,
+        CTSTATUS_BUSY,
+        CTSTATUS_DATAAVAIL,
+        CTSTATUS_NODATA,
+        CTSTATUS_NEXT_BYTE
+};
+
+/* MIDI data block header */
+struct midi_hdr
+{
+	u8 *reserved;		/* Pointer to original locked data block */
+	u32 bufferlength;	/* Length of data in data block */
+	u32 bytesrecorded;	/* Used for input only */
+	u32 user;		/* For client's use */
+	u32 flags;		/* Assorted flags (see defines) */
+	struct list_head list;	/* Reserved for driver */
+	u8 *data;		/* Second copy of first pointer */
+};
+
+/* Enumeration for SetControl */
+enum
+{
+	MIDIOBJVOLUME = 0x1,
+	MIDIQUERYACTIVEINST
+};
+
+struct midi_queue
+{
+	struct midi_queue  *next;
+	u32 qtype;            /* 0 = short message, 1 = long data */
+	u32 length;
+	u32 sizeLeft;
+	u8 *midibyte;
+	unsigned long refdata;
+};
+
+struct midi_openinfo
+{
+	u32     cbsize;
+	u32     flags;
+	unsigned long  refdata;
+	u32     streamid;
+};
+
+int emu10k1_midi_callback(unsigned long , unsigned long, unsigned long *);
+
+#endif /* _ICARDMIDI_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/icardwav.h linux.17p18/drivers/sound/emu10k1/icardwav.h
--- linux.vanilla/drivers/sound/emu10k1/icardwav.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/icardwav.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,50 @@
+/*     
+ **********************************************************************
+ *     icardwav.h
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ * 
+ ********************************************************************** 
+ * 
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version. 
+ * 
+ *     This program is distributed in the hope that it will be useful, 
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ *     GNU General Public License for more details. 
+ * 
+ *     You should have received a copy of the GNU General Public 
+ *     License along with this program; if not, write to the Free 
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 
+ *     USA. 
+ * 
+ ********************************************************************** 
+ */
+
+#ifndef _ICARDWAV_H
+#define _ICARDWAV_H
+
+struct wave_format 
+{
+	int samplingrate;
+	u8 bitsperchannel;
+	u8 channels;		/* 1 = Mono, 2 = Stereo */
+	u8 bytesperchannel;
+	u8 bytespersample;
+	int bytespersec;
+};
+
+/* emu10k1_wave states */
+#define WAVE_STATE_OPEN		0x01	
+#define WAVE_STATE_STARTED	0x02
+#define WAVE_STATE_CLOSED	0x04
+
+#endif /* _ICARDWAV_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/irqmgr.c linux.17p18/drivers/sound/emu10k1/irqmgr.c
--- linux.vanilla/drivers/sound/emu10k1/irqmgr.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/irqmgr.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,92 @@
+
+/*
+ **********************************************************************
+ *     irqmgr.c - IRQ manager for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include "hwaccess.h"
+#include "8010.h"
+#include "cardmi.h"
+#include "cardmo.h"
+#include "irqmgr.h"
+
+/* Interrupt handler */
+
+void emu10k1_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct emu10k1_card *card = (struct emu10k1_card *) dev_id;
+	u32 irqstatus, tmp;
+
+	if (!(irqstatus = emu10k1_readfn0(card, IPR)))
+		return;
+
+	DPD(4, "emu10k1_interrupt called, irq =  %u\n", irq);
+
+	/*
+	 ** NOTE :
+	 ** We do a 'while loop' here cos on certain machines, with both
+	 ** playback and recording going on at the same time, IRQs will
+	 ** stop coming in after a while. Checking IPND indeed shows that
+	 ** there are interrupts pending but the PIC says no IRQs pending.
+	 ** I suspect that some boards need edge-triggered IRQs but are not
+	 ** getting that condition if we don't completely clear the IPND
+	 ** (make sure no more interrupts are pending).
+	 ** - Eric
+	 */
+
+	do {
+		DPD(4, "irq status %x\n", irqstatus);
+
+		tmp = irqstatus;
+
+		if (irqstatus & IRQTYPE_TIMER) {
+			emu10k1_timer_irqhandler(card);
+			irqstatus &= ~IRQTYPE_TIMER;
+		}
+
+		if (irqstatus & IRQTYPE_MPUIN) {
+			emu10k1_mpuin_irqhandler(card);
+			irqstatus &= ~IRQTYPE_MPUIN;
+		}
+
+		if (irqstatus & IRQTYPE_MPUOUT) {
+			emu10k1_mpuout_irqhandler(card);
+			irqstatus &= ~IRQTYPE_MPUOUT;
+		}
+
+		if (irqstatus)
+			emu10k1_irq_disable(card, irqstatus);
+
+		emu10k1_writefn0(card, IPR, tmp);
+
+	} while ((irqstatus = emu10k1_readfn0(card, IPR)));
+
+	return;
+}
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/irqmgr.h linux.17p18/drivers/sound/emu10k1/irqmgr.h
--- linux.vanilla/drivers/sound/emu10k1/irqmgr.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/irqmgr.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,48 @@
+/*
+ **********************************************************************
+ *     irq.h
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _IRQ_H
+#define _IRQ_H
+
+/* EMU Irq Types */
+#define IRQTYPE_PCIBUSERROR         IPR_PCIERROR
+#define IRQTYPE_MIXERBUTTON         (IPR_VOLINCR | IPR_VOLDECR | IPR_MUTE)
+#define IRQTYPE_VOICE               (IPR_CHANNELLOOP | IPR_CHANNELNUMBERMASK)
+#define IRQTYPE_RECORD              (IPR_ADCBUFFULL | IPR_ADCBUFHALFFULL | IPR_MICBUFFULL | IPR_MICBUFHALFFULL | IPR_EFXBUFFULL | IPR_EFXBUFHALFFULL)
+#define IRQTYPE_MPUOUT              IPR_MIDITRANSBUFEMPTY
+#define IRQTYPE_MPUIN               IPR_MIDIRECVBUFEMPTY
+#define IRQTYPE_TIMER               IPR_INTERVALTIMER
+#define IRQTYPE_SPDIF               (IPR_GPSPDIFSTATUSCHANGE | IPR_CDROMSTATUSCHANGE)
+#define IRQTYPE_DSP                 IPR_FXDSP
+
+void emu10k1_timer_irqhandler(struct emu10k1_card *);
+
+#endif /* _IRQ_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/main.c linux.17p18/drivers/sound/emu10k1/main.c
--- linux.vanilla/drivers/sound/emu10k1/main.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/main.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,777 @@
+/*
+ **********************************************************************
+ *     main.c - Creative EMU10K1 audio driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox        cleaned up stuff
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ *
+ *      Supported devices:
+ *      /dev/dsp:     Standard /dev/dsp device, OSS-compatible
+ *      /dev/mixer:   Standard /dev/mixer device, OSS-compatible
+ *      /dev/midi:    Raw MIDI UART device, mostly OSS-compatible
+ *
+ *      Revision history:
+ *      0.1 beta Initial release
+ *      0.2 Lowered initial mixer vol. Improved on stuttering wave playback. Added MIDI UART support.
+ *      0.3 Fixed mixer routing bug, added APS, joystick support.
+ *      0.4 Added rear-channel, SPDIF support.
+ *	0.5 Source cleanup, SMP fixes, multiopen support, 64 bit arch fixes,
+ *	    moved bh's to tasklets, moved to the new PCI driver initialization style.
+ *	0.6 Make use of pci_alloc_consistent, improve compatibility layer for 2.2 kernels,
+ *	    code reorganization and cleanup.
+ **********************************************************************
+ */
+
+/* These are only included once per module */
+#include <linux/version.h>
+#include <linux/module.h>
+#include <linux/malloc.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+
+#include "hwaccess.h"
+#include "8010.h"
+#include "efxmgr.h"
+#include "cardwo.h"
+#include "cardwi.h"
+#include "cardmo.h"
+#include "cardmi.h"
+#include "recmgr.h"
+
+#define DRIVER_VERSION "0.6"
+
+/* FIXME: is this right? */
+/* does the card support 32 bit bus master?*/
+#define EMU10K1_DMA_MASK                0xffffffff	/* DMA buffer mask for pci_alloc_consist */
+
+#ifndef PCI_VENDOR_ID_CREATIVE
+#define PCI_VENDOR_ID_CREATIVE 0x1102
+#endif
+
+#ifndef PCI_DEVICE_ID_CREATIVE_EMU10K1
+#define PCI_DEVICE_ID_CREATIVE_EMU10K1 0x0002
+#endif
+
+enum {
+	EMU10K1 = 0,
+};
+
+static char *card_names[] __devinitdata = {
+	"EMU10K1",
+};
+
+static struct pci_device_id emu10k1_pci_tbl[] = {
+	{PCI_VENDOR_ID_CREATIVE, PCI_DEVICE_ID_CREATIVE_EMU10K1,
+	 PCI_ANY_ID, PCI_ANY_ID, 0, 0, EMU10K1},
+	{0,}
+};
+
+MODULE_DEVICE_TABLE(pci, emu10k1_pci_tbl);
+
+/* Global var instantiation */
+
+LIST_HEAD(emu10k1_devs);
+
+extern struct file_operations emu10k1_audio_fops;
+extern struct file_operations emu10k1_mixer_fops;
+extern struct file_operations emu10k1_midi_fops;
+
+extern void emu10k1_interrupt(int, void *, struct pt_regs *s);
+extern int emu10k1_mixer_wrch(struct emu10k1_card *, unsigned int, int);
+
+static int __devinit audio_init(struct emu10k1_card *card)
+{
+	if ((card->waveout = kmalloc(sizeof(struct emu10k1_waveout), GFP_KERNEL)) == NULL) {
+		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_waveout: out of memory\n");
+		return -1;
+	}
+	memset(card->waveout, 0, sizeof(struct emu10k1_waveout));
+
+	/* Assign default global volume, reverb, chorus */
+	card->waveout->globalvol = 0xffffffff;
+	card->waveout->left = 0xffff;
+	card->waveout->right = 0xffff;
+	card->waveout->mute = 0;
+	card->waveout->globalreverb = 0xffffffff;
+	card->waveout->globalchorus = 0xffffffff;
+
+	if ((card->wavein = kmalloc(sizeof(struct emu10k1_wavein), GFP_KERNEL))
+	    == NULL) {
+		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_wavein: out of memory\n");
+		return -1;
+	}
+	memset(card->wavein, 0, sizeof(struct emu10k1_wavein));
+
+	card->wavein->recsrc = WAVERECORD_AC97;
+
+	return 0;
+}
+
+static void __devinit mixer_init(struct emu10k1_card *card)
+{
+	int count;
+	struct initvol {
+		int mixch;
+		int vol;
+	} initvol[] = {
+		{
+		SOUND_MIXER_VOLUME, 0x5050}, {
+		SOUND_MIXER_OGAIN, 0x3232}, {
+		SOUND_MIXER_SPEAKER, 0x3232}, {
+		SOUND_MIXER_PHONEIN, 0x3232}, {
+		SOUND_MIXER_MIC, 0x0000}, {
+		SOUND_MIXER_LINE, 0x0000}, {
+		SOUND_MIXER_CD, 0x4b4b}, {
+		SOUND_MIXER_LINE1, 0x4b4b}, {
+		SOUND_MIXER_LINE3, 0x3232}, {
+		SOUND_MIXER_DIGITAL1, 0x6464}, {
+		SOUND_MIXER_DIGITAL2, 0x6464}, {
+		SOUND_MIXER_PCM, 0x6464}, {
+		SOUND_MIXER_RECLEV, 0x0404}, {
+		SOUND_MIXER_TREBLE, 0x3232}, {
+		SOUND_MIXER_BASS, 0x3232}, {
+		SOUND_MIXER_LINE2, 0x4b4b}};
+
+	int initdig[] = { 0, 1, 2, 3, 6, 7, 18, 19, 20, 21, 24, 25, 72, 73, 74, 75, 78, 79,
+		94, 95
+	};
+
+	/* Reset */
+	sblive_writeac97(card, AC97_RESET, 0);
+
+#if 0
+	/* Check status word */
+	{
+		u16 reg;
+
+		sblive_readac97(card, AC97_RESET, &reg);
+		DPD(2, "RESET 0x%x\n", reg);
+		sblive_readac97(card, AC97_MASTERTONE, &reg);
+		DPD(2, "MASTER_TONE 0x%x\n", reg);
+	}
+#endif
+
+	/* Set default recording source to mic in */
+	sblive_writeac97(card, AC97_RECORDSELECT, 0);
+
+	/* Set default AC97 "PCM" volume to acceptable max */
+	//sblive_writeac97(card, AC97_PCMOUTVOLUME, 0);
+	//sblive_writeac97(card, AC97_LINE2, 0);
+
+	/* Set default volumes for all mixer channels */
+
+	for (count = 0; count < sizeof(card->digmix) / sizeof(card->digmix[0]); count++) {
+		card->digmix[count] = 0x80000000;
+		sblive_writeptr(card, FXGPREGBASE + 0x10 + count, 0, 0);
+	}
+
+	for (count = 0; count < sizeof(initdig) / sizeof(initdig[0]); count++) {
+		card->digmix[initdig[count]] = 0x7fffffff;
+		sblive_writeptr(card, FXGPREGBASE + 0x10 + initdig[count], 0, 0x7fffffff);
+	}
+
+	for (count = 0; count < sizeof(initvol) / sizeof(initvol[0]); count++) {
+		emu10k1_mixer_wrch(card, initvol[count].mixch, initvol[count].vol);
+	}
+
+	card->modcnt = 0;	// Should this be here or in open() ?
+
+	return;
+}
+
+static int __devinit midi_init(struct emu10k1_card *card)
+{
+	if ((card->mpuout = kmalloc(sizeof(struct emu10k1_mpuout), GFP_KERNEL))
+	    == NULL) {
+		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuout: out of memory\n");
+		return -1;
+	}
+
+	memset(card->mpuout, 0, sizeof(struct emu10k1_mpuout));
+
+	card->mpuout->intr = 1;
+	card->mpuout->status = FLAGS_AVAILABLE;
+	card->mpuout->state = CARDMIDIOUT_STATE_DEFAULT;
+
+	tasklet_init(&card->mpuout->tasklet, emu10k1_mpuout_bh, (unsigned long) card);
+
+	spin_lock_init(&card->mpuout->lock);
+
+	if ((card->mpuin = kmalloc(sizeof(struct emu10k1_mpuin), GFP_KERNEL)) == NULL) {
+		kfree(card->mpuout);
+		printk(KERN_WARNING "emu10k1: Unable to allocate emu10k1_mpuin: out of memory\n");
+		return -1;
+	}
+
+	memset(card->mpuin, 0, sizeof(struct emu10k1_mpuin));
+
+	card->mpuin->status = FLAGS_AVAILABLE;
+
+	tasklet_init(&card->mpuin->tasklet, emu10k1_mpuin_bh, (unsigned long) card->mpuin);
+
+	spin_lock_init(&card->mpuin->lock);
+
+	/* Reset the MPU port */
+	if (emu10k1_mpu_reset(card) != CTSTATUS_SUCCESS) {
+		ERROR();
+		return -1;
+	}
+
+	return 0;
+}
+
+static void __devinit voice_init(struct emu10k1_card *card)
+{
+	int i;
+
+	for (i = 0; i < NUM_G; i++)
+		card->voicetable[i] = VOICE_USAGE_FREE;
+
+	return;
+}
+
+static void __devinit timer_init(struct emu10k1_card *card)
+{
+	INIT_LIST_HEAD(&card->timers);
+	card->timer_delay = TIMER_STOPPED;
+	card->timer_lock = SPIN_LOCK_UNLOCKED;
+
+	return;
+}
+
+static void __devinit addxmgr_init(struct emu10k1_card *card)
+{
+	u32 count;
+
+	for (count = 0; count < MAXPAGES; count++)
+		card->emupagetable[count] = 0;
+
+	/* Mark first page as used */
+	/* This page is reserved by the driver */
+	card->emupagetable[0] = 0x8001;
+	card->emupagetable[1] = MAXPAGES - 1;
+
+	return;
+}
+
+static void __devinit fx_init(struct emu10k1_card *card)
+{
+	int i, j, k, l;
+	u32 pc = 0;
+
+	for (i = 0; i < 512; i++)
+		OP(6, 0x40, 0x40, 0x40, 0x40);
+
+	for (i = 0; i < 256; i++)
+		sblive_writeptr_tag(card, 0,
+				    FXGPREGBASE + i, 0,
+				    TANKMEMADDRREGBASE + i, 0,
+				    TAGLIST_END);
+
+	pc = 0;
+
+	for (j = 0; j < 2; j++) {
+
+		OP(4, 0x100, 0x40, j, 0x44);
+		OP(4, 0x101, 0x40, j + 2, 0x44);
+
+		for (i = 0; i < 6; i++) {
+			k = i * 18 + j;
+			OP(0, 0x102, 0x40, 0x110 + k, 0x100);
+			OP(0, 0x102, 0x102, 0x112 + k, 0x101);
+			OP(0, 0x102, 0x102, 0x114 + k, 0x10 + j);
+			OP(0, 0x102, 0x102, 0x116 + k, 0x12 + j);
+			OP(0, 0x102, 0x102, 0x118 + k, 0x14 + j);
+			OP(0, 0x102, 0x102, 0x11a + k, 0x16 + j);
+			OP(0, 0x102, 0x102, 0x11c + k, 0x18 + j);
+			OP(0, 0x102, 0x102, 0x11e + k, 0x1a + j);
+			OP(0, 0x102, 0x102, 0x120 + k, 0x1c + j);
+
+			k = 0x1a0 + i * 8 + j * 4;
+			OP(0, 0x40, 0x40, 0x102, 0x180 + j);
+			OP(7, k + 1, k, k + 1, 0x184 + j);
+			OP(7, k, 0x102, k, 0x182 + j);
+			OP(7, k + 3, k + 2, k + 3, 0x188 + j);
+			OP(0, k + 2, 0x56, k + 2, 0x186 + j);
+			OP(6, k + 2, k + 2, k + 2, 0x40);
+
+			l = 0x1d0 + i * 8 + j * 4;
+			OP(0, 0x40, 0x40, k + 2, 0x190 + j);
+			OP(7, l + 1, l, l + 1, 0x194 + j);
+			OP(7, l, k + 2, l, 0x192 + j);
+			OP(7, l + 3, l + 2, l + 3, 0x198 + j);
+			OP(0, l + 2, 0x56, l + 2, 0x196 + j);
+			OP(4, l + 2, 0x40, l + 2, 0x46);
+
+			if (i == 0)
+				OP(0, 0x20 + (i * 2) + j, 0x40, l + 2, 0x4e);	/* FIXME: Is this really needed? */
+			else
+				OP(6, 0x20 + (i * 2) + j, l + 2, 0x40, 0x40);
+		}
+	}
+	sblive_writeptr(card, DBG, 0, 0);
+
+	return;
+}
+
+static int __devinit hw_init(struct emu10k1_card *card)
+{
+	int nCh;
+	u32 pagecount; /* tmp */
+
+	/* Disable audio and lock cache */
+	emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE);
+
+	/* Reset recording buffers */
+	sblive_writeptr_tag(card, 0,
+			    MICBS, ADCBS_BUFSIZE_NONE,
+			    MICBA, 0,
+			    FXBS, ADCBS_BUFSIZE_NONE,
+			    FXBA, 0,
+			    ADCBS, ADCBS_BUFSIZE_NONE,
+			    ADCBA, 0,
+			    TAGLIST_END);
+
+	/* Disable channel interrupt */
+	emu10k1_writefn0(card, INTE, 0);
+	sblive_writeptr_tag(card, 0,
+			    CLIEL, 0,
+			    CLIEH, 0,
+			    SOLEL, 0,
+			    SOLEH, 0,
+			    TAGLIST_END);
+
+	/* Init envelope engine */
+	for (nCh = 0; nCh < NUM_G; nCh++) {
+		sblive_writeptr_tag(card, nCh,
+				    DCYSUSV, 0,
+				    IP, 0,
+				    VTFT, 0xffff,
+				    CVCF, 0xffff,
+				    PTRX, 0,
+				    CPF, 0,
+				    CCR, 0,
+
+				    PSST, 0,
+				    DSL, 0x10,
+				    CCCA, 0,
+				    Z1, 0,
+				    Z2, 0,
+				    FXRT, 0xd01c0000,
+
+				    ATKHLDM, 0,
+				    DCYSUSM, 0,
+				    IFATN, 0xffff,
+				    PEFE, 0,
+				    FMMOD, 0,
+				    TREMFRQ, 24,	/* 1 Hz */
+				    FM2FRQ2, 24,	/* 1 Hz */
+				    TEMPENV, 0,
+
+				    /*** These are last so OFF prevents writing ***/
+				    LFOVAL2, 0,
+				    LFOVAL1, 0,
+				    ATKHLDV, 0,
+				    ENVVOL, 0,
+				    ENVVAL, 0,
+                                    TAGLIST_END);
+	}
+
+	/*
+	 ** Init to 0x02109204 :
+	 ** Clock accuracy    = 0     (1000ppm)
+	 ** Sample Rate       = 2     (48kHz)
+	 ** Audio Channel     = 1     (Left of 2)
+	 ** Source Number     = 0     (Unspecified)
+	 ** Generation Status = 1     (Original for Cat Code 12)
+	 ** Cat Code          = 12    (Digital Signal Mixer)
+	 ** Mode              = 0     (Mode 0)
+	 ** Emphasis          = 0     (None)
+	 ** CP                = 1     (Copyright unasserted)
+	 ** AN                = 0     (Digital audio)
+	 ** P                 = 0     (Consumer)
+	 */
+
+	sblive_writeptr_tag(card, 0,
+
+			    /* SPDIF0 */
+			    SPCS0, (SPCS_CLKACCY_1000PPM | 0x002000000 |
+				    SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
+
+			    /* SPDIF1 */
+			    SPCS1, (SPCS_CLKACCY_1000PPM | 0x002000000 |
+				    SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
+
+			    /* SPDIF2 & SPDIF3 */
+			    SPCS2, (SPCS_CLKACCY_1000PPM | 0x002000000 |
+				    SPCS_CHANNELNUM_LEFT | SPCS_SOURCENUM_UNSPEC | SPCS_GENERATIONSTATUS | 0x00001200 | SPCS_EMPHASIS_NONE | SPCS_COPYRIGHT),
+
+			    TAGLIST_END);
+
+	fx_init(card);		/* initialize effects engine */
+
+	card->tankmem.size = 0;
+
+	card->virtualpagetable.size = MAXPAGES * sizeof(u32);
+
+	if ((card->virtualpagetable.addr = pci_alloc_consistent(card->pci_dev, card->virtualpagetable.size, &card->virtualpagetable.dma_handle)) ==
+	    NULL) {
+		ERROR();
+		return -1;
+	}
+
+	card->silentpage.size = EMUPAGESIZE;
+
+	if ((card->silentpage.addr = pci_alloc_consistent(card->pci_dev, card->silentpage.size, &card->silentpage.dma_handle)) == NULL) {
+		ERROR();
+		pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
+		return -1;
+	}
+
+	for (pagecount = 0; pagecount < MAXPAGES; pagecount++)
+		((u32 *) card->virtualpagetable.addr)[pagecount] = (card->silentpage.dma_handle * 2) | pagecount;
+
+	/* Init page table & tank memory base register */
+	sblive_writeptr_tag(card, 0,
+			    PTB, 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),
+				    TAGLIST_END);
+	}
+
+	/* Hokay, now enable the AUD bit */
+	/* Enable Audio = 1 */
+	/* Mute Disable Audio = 0 */
+	/* Lock Tank Memory = 1 */
+	/* Lock Sound Memory = 0 */
+	/* Auto Mute = 1 */
+
+	sblive_rmwac97(card, AC97_MASTERVOLUME, 0x8000, 0x8000);
+
+	sblive_writeac97(card, AC97_MASTERVOLUME, 0);
+	sblive_writeac97(card, AC97_PCMOUTVOLUME, 0);
+
+	if(card->model == 0x20 || card->model == 0xc400 ||
+	  (card->model == 0x21 && card->chiprev <= 3))
+	        emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE);
+	else
+		emu10k1_writefn0(card, HCFG, HCFG_AUDIOENABLE  | HCFG_LOCKTANKCACHE_MASK | HCFG_AUTOMUTE | HCFG_JOYENABLE);
+
+	/* FIXME: TOSLink detection */
+	card->has_toslink = 0;
+
+/*	tmp = sblive_readfn0(card, HCFG);
+	if (tmp & (HCFG_GPINPUT0 | HCFG_GPINPUT1)) {
+		sblive_writefn0(card, HCFG, tmp | 0x800);
+
+		udelay(512);
+
+		if (tmp != (sblive_readfn0(card, HCFG) & ~0x800)) {
+			card->has_toslink = 1;
+			sblive_writefn0(card, HCFG, tmp);
+		}
+	}
+*/
+	return 0;
+}
+
+static int __devinit emu10k1_init(struct emu10k1_card *card)
+{
+	/* Init Card */
+	if (hw_init(card) < 0)
+		return -1;
+
+	voice_init(card);
+	timer_init(card);
+	addxmgr_init(card);
+
+	DPD(2, "  hw control register -> 0x%x\n", emu10k1_readfn0(card, HCFG));
+
+	return 0;
+}
+
+static void __devinit audio_exit(struct emu10k1_card *card)
+{
+	kfree(card->waveout);
+	kfree(card->wavein);
+	return;
+}
+
+static void __devexit midi_exit(struct emu10k1_card *card)
+{
+	tasklet_unlock_wait(&card->mpuout->tasklet);
+	kfree(card->mpuout);
+
+	tasklet_unlock_wait(&card->mpuin->tasklet);
+	kfree(card->mpuin);
+
+	return;
+}
+
+static void __devinit emu10k1_exit(struct emu10k1_card *card)
+{
+	int ch;
+
+	emu10k1_writefn0(card, INTE, 0);
+
+	/** Shutdown the chip **/
+	for (ch = 0; ch < NUM_G; ch++)
+		sblive_writeptr(card, DCYSUSV, ch, 0);
+
+	for (ch = 0; ch < NUM_G; ch++) {
+		sblive_writeptr_tag(card, ch,
+				    VTFT, 0,
+				    CVCF, 0,
+				    PTRX, 0,
+				    CPF, 0,
+				    TAGLIST_END);
+	}
+
+	/* Disable audio and lock cache */
+	emu10k1_writefn0(card, HCFG, HCFG_LOCKSOUNDCACHE | HCFG_LOCKTANKCACHE_MASK | HCFG_MUTEBUTTONENABLE);
+
+	sblive_writeptr_tag(card, 0,
+                            PTB, 0,
+
+			    /* Reset recording buffers */
+			    MICBS, ADCBS_BUFSIZE_NONE,
+			    MICBA, 0,
+			    FXBS, ADCBS_BUFSIZE_NONE,
+			    FXBA, 0,
+			    FXWC, 0,
+			    ADCBS, ADCBS_BUFSIZE_NONE,
+			    ADCBA, 0,
+			    TCBS, 0,
+			    TCB, 0,
+			    DBG, 0x8000,
+
+			    /* Disable channel interrupt */
+			    CLIEL, 0,
+			    CLIEH, 0,
+			    SOLEL, 0,
+			    SOLEH, 0,
+			    TAGLIST_END);
+
+
+	pci_free_consistent(card->pci_dev, card->virtualpagetable.size, card->virtualpagetable.addr, card->virtualpagetable.dma_handle);
+	pci_free_consistent(card->pci_dev, card->silentpage.size, card->silentpage.addr, card->silentpage.dma_handle);
+	
+	if(card->tankmem.size != 0)
+		pci_free_consistent(card->pci_dev, card->tankmem.size, card->tankmem.addr, card->tankmem.dma_handle);
+
+	return;
+}
+
+/* Driver initialization routine */
+static int __devinit emu10k1_probe(struct pci_dev *pci_dev, const struct pci_device_id *pci_id)
+{
+	struct emu10k1_card *card;
+
+	if ((card = kmalloc(sizeof(struct emu10k1_card), GFP_KERNEL)) == NULL) {
+		printk(KERN_ERR "emu10k1: out of memory\n");
+		return -ENOMEM;
+	}
+	memset(card, 0, sizeof(struct emu10k1_card));
+
+	if (!pci_dma_supported(pci_dev, EMU10K1_DMA_MASK)) {
+		printk(KERN_ERR "emu10k1: architecture does not support 32bit PCI busmaster DMA\n");
+		kfree(card);
+		return -ENODEV;
+	}
+
+	if (pci_enable_device(pci_dev)) {
+		kfree(card);
+		return -ENODEV;
+	}
+
+	pci_set_master(pci_dev);
+
+	card->iobase = pci_resource_start(pci_dev, 0);
+	card->length = pci_resource_len(pci_dev, 0); 
+
+	if (compat_request_region(card->iobase, card->length, card_names[pci_id->driver_data]) == NULL) {
+		printk(KERN_ERR "emu10k1: IO space in use\n");
+		kfree(card);
+		return -ENODEV;
+	}
+
+	PCI_SET_DRIVER_DATA(pci_dev, card);
+	PCI_SET_DMA_MASK(pci_dev, EMU10K1_DMA_MASK);
+
+	card->irq = pci_dev->irq;
+	card->pci_dev = pci_dev;
+
+	/* Reserve IRQ Line */
+	if (request_irq(card->irq, emu10k1_interrupt, SA_SHIRQ, card_names[pci_id->driver_data], card)) {
+		printk(KERN_ERR "emu10k1: IRQ in use\n");
+		goto err_irq;
+	}
+
+	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",
+		card_names[pci_id->driver_data], card->chiprev, card->model, card->iobase,
+		card->iobase + card->length - 1, card->irq);
+
+	spin_lock_init(&card->lock);
+	init_MUTEX(&card->open_sem);
+	card->open_mode = 0;
+	init_waitqueue_head(&card->open_wait);
+
+	/* Register devices */
+	if ((card->audio1_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
+		printk(KERN_ERR "emu10k1: cannot register first audio device!\n");
+		goto err_dev0;
+	}
+
+	if ((card->audio2_num = register_sound_dsp(&emu10k1_audio_fops, -1)) < 0) {
+		printk(KERN_ERR "emu10k1: cannot register second audio device!\n");
+		goto err_dev1;
+	}
+
+	if ((card->mixer_num = register_sound_mixer(&emu10k1_mixer_fops, -1)) < 0) {
+		printk(KERN_ERR "emu10k1: cannot register mixer device!\n");
+		goto err_dev2;
+	}
+
+	if ((card->midi_num = register_sound_midi(&emu10k1_midi_fops, -1)) < 0) {
+		printk(KERN_ERR "emu10k1: cannot register midi device!\n");
+		goto err_dev3;
+	}
+
+	if (emu10k1_init(card) < 0) {
+		printk(KERN_ERR "emu10k1: cannot initialize device!\n");
+		goto err_emu10k1_init;
+	}
+
+	if (audio_init(card) < 0) {
+		printk(KERN_ERR "emu10k1: cannot initialize audio!\n");
+		goto err_audio_init;
+	}
+
+	if (midi_init(card) < 0) {
+		printk(KERN_ERR "emu10k1: cannot initialize midi!\n");
+		goto err_midi_init;
+	}
+
+	mixer_init(card);
+
+	list_add(&card->list, &emu10k1_devs);
+
+	return 0;
+
+      err_midi_init:
+	audio_exit(card);
+
+      err_audio_init:
+	emu10k1_exit(card);
+
+      err_emu10k1_init:
+	unregister_sound_midi(card->midi_num);
+
+      err_dev3:
+	unregister_sound_mixer(card->mixer_num);
+
+      err_dev2:
+	unregister_sound_dsp(card->audio2_num);
+
+      err_dev1:
+	unregister_sound_dsp(card->audio1_num);
+
+      err_dev0:
+	free_irq(card->irq, card);
+
+      err_irq:
+	release_region(card->iobase, card->length);
+	kfree(card);
+
+	return -ENODEV;
+}
+
+static void __devexit emu10k1_remove(struct pci_dev *pci_dev)
+{
+	struct emu10k1_card *card = PCI_GET_DRIVER_DATA(pci_dev);
+
+	midi_exit(card);
+	audio_exit(card);
+	emu10k1_exit(card);
+
+	unregister_sound_midi(card->midi_num);
+	unregister_sound_mixer(card->mixer_num);
+	unregister_sound_dsp(card->audio2_num);
+	unregister_sound_dsp(card->audio1_num);
+
+	free_irq(card->irq, card);
+	release_region(card->iobase, card->length);
+
+	list_del(&card->list);
+
+	kfree(card);
+
+	return;
+}
+
+MODULE_AUTHOR("Bertrand Lee, Cai Ying. (Email to: emu10k1-devel@opensource.creative.com)");
+MODULE_DESCRIPTION("Creative EMU10K1 PCI Audio Driver v" DRIVER_VERSION "\nCopyright (C) 1999 Creative Technology Ltd.");
+
+static struct pci_driver emu10k1_pci_driver = {
+	name:"emu10k1",
+	id_table:emu10k1_pci_tbl,
+	probe:emu10k1_probe,
+	remove:emu10k1_remove,
+};
+
+static int __init emu10k1_init_module(void)
+{
+	printk(KERN_INFO "Creative EMU10K1 PCI Audio Driver, version " DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
+
+	return pci_module_init(&emu10k1_pci_driver);
+}
+
+static void __exit emu10k1_cleanup_module(void)
+{
+	pci_unregister_driver(&emu10k1_pci_driver);
+
+	return;
+}
+
+module_init(emu10k1_init_module);
+module_exit(emu10k1_cleanup_module);
+
+#ifndef MODULE
+int __init init_emu10k1(void)
+{
+	return emu10k1_init_module();
+}
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/midi.c linux.17p18/drivers/sound/emu10k1/midi.c
--- linux.vanilla/drivers/sound/emu10k1/midi.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/midi.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,447 @@
+
+/*
+ **********************************************************************
+ *     midi.c - /dev/midi interface for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#define __NO_VERSION__
+#include <linux/module.h>
+#include <linux/malloc.h>
+#include <asm/uaccess.h>
+
+#include "hwaccess.h"
+#include "cardmo.h"
+#include "cardmi.h"
+#include "midi.h"
+
+static spinlock_t midi_spinlock = SPIN_LOCK_UNLOCKED;
+
+static void init_midi_hdr(struct midi_hdr *midihdr)
+{
+	midihdr->bufferlength = MIDIIN_BUFLEN;
+	midihdr->bytesrecorded = 0;
+	midihdr->flags = 0;
+}
+
+static int midiin_add_buffer(struct emu10k1_mididevice *midi_dev, struct midi_hdr **midihdrptr)
+{
+	struct midi_hdr *midihdr;
+
+	if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr *), GFP_KERNEL)) == NULL) {
+		ERROR();
+		return -EINVAL;
+	}
+
+	init_midi_hdr(midihdr);
+
+	if ((midihdr->data = (u8 *) kmalloc(MIDIIN_BUFLEN, GFP_KERNEL)) == NULL) {
+		ERROR();
+		kfree(midihdr);
+		return CTSTATUS_ERROR;
+	}
+
+	if (emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr) != CTSTATUS_SUCCESS) {
+		ERROR();
+		kfree(midihdr->data);
+		kfree(midihdr);
+		return CTSTATUS_ERROR;
+	}
+
+	*midihdrptr = midihdr;
+	list_add_tail(&midihdr->list, &midi_dev->mid_hdrs);
+
+	return CTSTATUS_SUCCESS;
+}
+
+static int emu10k1_midi_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct emu10k1_card *card;
+	struct emu10k1_mididevice *midi_dev;
+	struct list_head *entry;
+
+	DPF(2, "emu10k1_midi_open()\n");
+
+	/* Check for correct device to open */
+	list_for_each(entry, &emu10k1_devs) {
+		card = list_entry(entry, struct emu10k1_card, list);
+
+		if (card->midi_num == minor)
+			break;
+	}
+
+	if (entry == &emu10k1_devs)
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+
+	/* Wait for device to become free */
+	down(&card->open_sem);
+	while (card->open_mode & (file->f_mode << FMODE_MIDI_SHIFT)) {
+		if (file->f_flags & O_NONBLOCK) {
+			up(&card->open_sem);
+			MOD_DEC_USE_COUNT;
+			return -EBUSY;
+		}
+
+		up(&card->open_sem);
+		interruptible_sleep_on(&card->open_wait);
+
+		if (signal_pending(current)) {
+			MOD_DEC_USE_COUNT;
+			return -ERESTARTSYS;
+		}
+
+		down(&card->open_sem);
+	}
+
+	if ((midi_dev = (struct emu10k1_mididevice *) kmalloc(sizeof(*midi_dev), GFP_KERNEL)) == NULL) {
+		MOD_DEC_USE_COUNT;
+		return -EINVAL;
+	}
+
+	midi_dev->card = card;
+	midi_dev->mistate = MIDIIN_STATE_STOPPED;
+	init_waitqueue_head(&midi_dev->oWait);
+	init_waitqueue_head(&midi_dev->iWait);
+	midi_dev->ird = 0;
+	midi_dev->iwr = 0;
+	midi_dev->icnt = 0;
+	INIT_LIST_HEAD(&midi_dev->mid_hdrs);
+
+	if (file->f_mode & FMODE_READ) {
+		struct midi_openinfo dsCardMidiOpenInfo;
+		struct midi_hdr *midihdr1;
+		struct midi_hdr *midihdr2;
+
+		dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
+
+		if (emu10k1_mpuin_open(card, &dsCardMidiOpenInfo)
+		    != CTSTATUS_SUCCESS) {
+			ERROR();
+			kfree(midi_dev);
+			MOD_DEC_USE_COUNT;
+			return -ENODEV;
+		}
+
+		/* Add two buffers to receive sysex buffer */
+		if (midiin_add_buffer(midi_dev, &midihdr1) != CTSTATUS_SUCCESS) {
+			kfree(midi_dev);
+			MOD_DEC_USE_COUNT;
+			return -ENODEV;
+		}
+
+		if (midiin_add_buffer(midi_dev, &midihdr2) != CTSTATUS_SUCCESS) {
+			list_del(&midihdr1->list);
+			kfree(midihdr1->data);
+			kfree(midihdr1);
+			kfree(midi_dev);
+			MOD_DEC_USE_COUNT;
+			return -ENODEV;
+		}
+	}
+
+	if (file->f_mode & FMODE_WRITE) {
+		struct midi_openinfo dsCardMidiOpenInfo;
+
+		dsCardMidiOpenInfo.refdata = (unsigned long) midi_dev;
+
+		if (emu10k1_mpuout_open(card, &dsCardMidiOpenInfo)
+		    != CTSTATUS_SUCCESS) {
+			ERROR();
+			kfree(midi_dev);
+			MOD_DEC_USE_COUNT;
+			return -ENODEV;
+		}
+	}
+
+	file->private_data = (void *) midi_dev;
+
+	card->open_mode |= (file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE);
+
+	up(&card->open_sem);
+
+	return 0;
+}
+
+static int emu10k1_midi_release(struct inode *inode, struct file *file)
+{
+	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
+	struct emu10k1_card *card = midi_dev->card;
+
+	DPF(2, "emu10k1_midi_release()\n");
+
+	if (file->f_mode & FMODE_WRITE) {
+		if (!(file->f_flags & O_NONBLOCK)) {
+
+			while (!signal_pending(current) && (card->mpuout->firstmidiq != NULL)) {
+				DPF(4, "Cannot close - buffers not empty\n");
+
+				interruptible_sleep_on(&midi_dev->oWait);
+
+			}
+		}
+
+		emu10k1_mpuout_close(card);
+	}
+
+	if (file->f_mode & FMODE_READ) {
+		struct midi_hdr *midihdr;
+
+		if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
+			emu10k1_mpuin_stop(card);
+			midi_dev->mistate = MIDIIN_STATE_STOPPED;
+		}
+
+		emu10k1_mpuin_reset(card);
+		emu10k1_mpuin_close(card);
+
+		while (!list_empty(&midi_dev->mid_hdrs)) {
+			midihdr = list_entry(midi_dev->mid_hdrs.next, struct midi_hdr, list);
+
+			list_del(midi_dev->mid_hdrs.next);
+			kfree(midihdr->data);
+			kfree(midihdr);
+		}
+	}
+
+	kfree(midi_dev);
+
+	down(&card->open_sem);
+	card->open_mode &= ~((file->f_mode << FMODE_MIDI_SHIFT) & (FMODE_MIDI_READ | FMODE_MIDI_WRITE));
+	up(&card->open_sem);
+	wake_up_interruptible(&card->open_wait);
+
+	MOD_DEC_USE_COUNT;
+
+	return 0;
+}
+
+static ssize_t emu10k1_midi_read(struct file *file, char *buffer, size_t count, loff_t * pos)
+{
+	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
+	ssize_t ret = 0;
+	u16 cnt;
+	unsigned long flags;
+
+	DPD(4, "emu10k1_midi_read(), count %x\n", (u32) count);
+
+	if (pos != &file->f_pos)
+		return -ESPIPE;
+
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+
+	if (midi_dev->mistate == MIDIIN_STATE_STOPPED) {
+		if (emu10k1_mpuin_start(midi_dev->card)
+		    != CTSTATUS_SUCCESS) {
+			ERROR();
+			return -EINVAL;
+		}
+
+		midi_dev->mistate = MIDIIN_STATE_STARTED;
+	}
+
+	while (count > 0) {
+		cnt = MIDIIN_BUFLEN - midi_dev->ird;
+
+		spin_lock_irqsave(&midi_spinlock, flags);
+
+		if (midi_dev->icnt < cnt)
+			cnt = midi_dev->icnt;
+
+		spin_unlock_irqrestore(&midi_spinlock, flags);
+
+		if (cnt > count)
+			cnt = count;
+
+		if (cnt <= 0) {
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			DPF(2, " Go to sleep...\n");
+
+			interruptible_sleep_on(&midi_dev->iWait);
+
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+
+			continue;
+		}
+
+		if (copy_to_user(buffer, midi_dev->iBuf + midi_dev->ird, cnt)) {
+			ERROR();
+			return ret ? ret : -EFAULT;
+		}
+
+		midi_dev->ird += cnt;
+		midi_dev->ird %= MIDIIN_BUFLEN;
+
+		spin_lock_irqsave(&midi_spinlock, flags);
+
+		midi_dev->icnt -= cnt;
+
+		spin_unlock_irqrestore(&midi_spinlock, flags);
+
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+
+		if (midi_dev->icnt == 0)
+			break;
+	}
+
+	return ret;
+}
+
+static ssize_t emu10k1_midi_write(struct file *file, const char *buffer, size_t count, loff_t * pos)
+{
+	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) file->private_data;
+	struct midi_hdr *midihdr;
+	ssize_t ret = 0;
+	unsigned long flags;
+
+	DPD(4, "emu10k1_midi_write(), count=%x\n", (u32) count);
+
+	if (pos != &file->f_pos)
+		return -ESPIPE;
+
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+
+	if ((midihdr = (struct midi_hdr *) kmalloc(sizeof(struct midi_hdr *), GFP_KERNEL)) == NULL)
+		return -EINVAL;
+
+	midihdr->bufferlength = count;
+	midihdr->bytesrecorded = 0;
+	midihdr->flags = 0;
+
+	if ((midihdr->data = (u8 *) kmalloc(count, GFP_KERNEL)) == NULL) {
+		ERROR();
+		kfree(midihdr);
+		return -EINVAL;
+	}
+
+	if (copy_from_user(midihdr->data, buffer, count)) {
+		kfree(midihdr->data);
+		kfree(midihdr);
+		return ret ? ret : -EFAULT;
+	}
+
+	spin_lock_irqsave(&midi_spinlock, flags);
+
+	if (emu10k1_mpuout_add_buffer(midi_dev->card, midihdr) != CTSTATUS_SUCCESS) {
+		ERROR();
+		kfree(midihdr->data);
+		kfree(midihdr);
+		spin_unlock_irqrestore(&midi_spinlock, flags);
+		return -EINVAL;
+	}
+
+	spin_unlock_irqrestore(&midi_spinlock, flags);
+
+	return count;
+}
+
+static unsigned int emu10k1_midi_poll(struct file *file, struct poll_table_struct *wait)
+{
+	DPF(4, "emu10k1_midi_poll() called\n");
+	return 0;
+}
+
+int emu10k1_midi_callback(unsigned long msg, unsigned long refdata, unsigned long *pmsg)
+{
+	struct emu10k1_mididevice *midi_dev = (struct emu10k1_mididevice *) refdata;
+	struct midi_hdr *midihdr = NULL;
+	unsigned long flags;
+	int i;
+
+	DPF(4, "emu10k1_midi_callback()\n");
+
+	spin_lock_irqsave(&midi_spinlock, flags);
+
+	switch (msg) {
+	case ICARDMIDI_OUTLONGDATA:
+		midihdr = (struct midi_hdr *) pmsg[2];
+
+		kfree(midihdr->data);
+		kfree(midihdr);
+		wake_up_interruptible(&midi_dev->oWait);
+
+		break;
+
+	case ICARDMIDI_INLONGDATA:
+		midihdr = (struct midi_hdr *) pmsg[2];
+
+		for (i = 0; i < midihdr->bytesrecorded; i++) {
+			midi_dev->iBuf[midi_dev->iwr++] = midihdr->data[i];
+			midi_dev->iwr %= MIDIIN_BUFLEN;
+		}
+
+		midi_dev->icnt += midihdr->bytesrecorded;
+
+		if (midi_dev->mistate == MIDIIN_STATE_STARTED) {
+			init_midi_hdr(midihdr);
+			emu10k1_mpuin_add_buffer(midi_dev->card->mpuin, midihdr);
+			wake_up_interruptible(&midi_dev->iWait);
+		}
+		break;
+
+	case ICARDMIDI_INDATA:
+		{
+			u8 *pBuf = (u8 *) & pmsg[1];
+			u16 bytesvalid = pmsg[2];
+
+			for (i = 0; i < bytesvalid; i++) {
+				midi_dev->iBuf[midi_dev->iwr++] = pBuf[i];
+				midi_dev->iwr %= MIDIIN_BUFLEN;
+			}
+
+			midi_dev->icnt += bytesvalid;
+		}
+
+		wake_up_interruptible(&midi_dev->iWait);
+		break;
+
+	default:		/* Unknown message */
+		return CTSTATUS_ERROR;
+	}
+
+	spin_unlock_irqrestore(&midi_spinlock, flags);
+
+	return CTSTATUS_SUCCESS;
+}
+
+/* MIDI file operations */
+struct file_operations emu10k1_midi_fops = {
+	read:emu10k1_midi_read,
+	write:emu10k1_midi_write,
+	poll:emu10k1_midi_poll,
+	open:emu10k1_midi_open,
+	release:emu10k1_midi_release,
+};
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/midi.h linux.17p18/drivers/sound/emu10k1/midi.h
--- linux.vanilla/drivers/sound/emu10k1/midi.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/midi.h	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,55 @@
+/*     
+ **********************************************************************
+ *     midi.h
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ * 
+ ********************************************************************** 
+ * 
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version. 
+ * 
+ *     This program is distributed in the hope that it will be useful, 
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ *     GNU General Public License for more details. 
+ * 
+ *     You should have received a copy of the GNU General Public 
+ *     License along with this program; if not, write to the Free 
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 
+ *     USA. 
+ * 
+ ********************************************************************** 
+ */ 
+
+#ifndef _MIDI_H
+#define _MIDI_H
+
+#define FMODE_MIDI_SHIFT 3
+#define FMODE_MIDI_READ  (FMODE_READ << FMODE_MIDI_SHIFT)
+#define FMODE_MIDI_WRITE (FMODE_WRITE << FMODE_MIDI_SHIFT)
+
+#define MIDIIN_STATE_STARTED 0x00000001
+#define MIDIIN_STATE_STOPPED 0x00000002
+
+#define MIDIIN_BUFLEN 1024
+
+struct emu10k1_mididevice
+{
+	struct emu10k1_card *card;
+	u32 mistate;
+	wait_queue_head_t oWait;
+	wait_queue_head_t iWait;
+	s8 iBuf[MIDIIN_BUFLEN];
+	u16 ird, iwr, icnt;
+	struct list_head mid_hdrs;
+};
+
+#endif /* _MIDI_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/mixer.c linux.17p18/drivers/sound/emu10k1/mixer.c
--- linux.vanilla/drivers/sound/emu10k1/mixer.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/mixer.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,949 @@
+/*
+ **********************************************************************
+ *     mixer.c - /dev/mixer interface for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ *     This program uses some code from es1371.c, Copyright 1998-1999
+ *     Thomas Sailer
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *     November 2, 1999     Alan Cox        cleaned up stuff
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#define __NO_VERSION__		/* Kernel version only defined once */
+#include <linux/module.h>
+#include <asm/uaccess.h>
+
+#include "hwaccess.h"
+#include "8010.h"
+
+#define AC97_PESSIMISTIC
+#undef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+#define vol_to_hw_5(swvol) (31 - (((swvol) * 31) / 100))
+#define vol_to_hw_4(swvol) (15 - (((swvol) * 15) / 100))
+
+#define vol_to_sw_5(hwvol) (((31 - (hwvol)) * 100) / 31)
+#define vol_to_sw_4(hwvol) (((15 - (hwvol)) * 100) / 15)
+
+#ifdef PRIVATE_PCM_VOLUME
+struct sblive_pcm_volume_rec sblive_pcm_volume[MAX_PCM_CHANNELS];
+u16 pcm_last_mixer = 0x6464;
+#endif
+
+/* --------------------------------------------------------------------- */
+
+/*
+ * hweightN: returns the hamming weight (i.e. the number
+ * of bits set) of a N-bit word
+ */
+
+#ifdef hweight32
+#undef hweight32
+#endif
+
+extern __inline__ unsigned int hweight32(unsigned int w)
+{
+	unsigned int res = (w & 0x55555555) + ((w >> 1) & 0x55555555);
+
+	res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
+	res = (res & 0x0F0F0F0F) + ((res >> 4) & 0x0F0F0F0F);
+	res = (res & 0x00FF00FF) + ((res >> 8) & 0x00FF00FF);
+	return (res & 0x0000FFFF) + ((res >> 16) & 0x0000FFFF);
+}
+
+/* Mapping arrays */
+static const unsigned int recsrc[] = {
+	SOUND_MASK_MIC,
+	SOUND_MASK_CD,
+	SOUND_MASK_VIDEO,
+	SOUND_MASK_LINE1,
+	SOUND_MASK_LINE,
+	SOUND_MASK_VOLUME,
+	SOUND_MASK_OGAIN,	/* Used to be PHONEOUT */
+	SOUND_MASK_PHONEIN,
+	SOUND_MASK_TREBLE,
+	SOUND_MASK_BASS,
+	SOUND_MASK_MONITOR,
+	SOUND_MASK_PCM,
+};
+
+static const unsigned char volreg[SOUND_MIXER_NRDEVICES] = {
+	/* 5 bit stereo */
+	[SOUND_MIXER_LINE] = AC97_LINEINVOLUME,
+	[SOUND_MIXER_CD] = AC97_CDVOLUME,
+	[SOUND_MIXER_VIDEO] = AC97_VIDEOVOLUME,
+	[SOUND_MIXER_LINE1] = AC97_AUXVOLUME,
+
+/*	[SOUND_MIXER_PCM] = AC97_PCMOUTVOLUME, */
+	/* 5 bit stereo, setting 6th bit equal to maximum attenuation */
+
+/*	[SOUND_MIXER_VOLUME] = AC97_MASTERVOLUME, */
+	[SOUND_MIXER_PHONEOUT] = AC97_HEADPHONEVOLUME,
+	/* 5 bit mono, setting 6th bit equal to maximum attenuation */
+	[SOUND_MIXER_OGAIN] = AC97_MASTERVOLUMEMONO,
+	/* 5 bit mono */
+	[SOUND_MIXER_PHONEIN] = AC97_PHONEVOLUME,
+	/* 4 bit mono but shifted by 1 */
+	[SOUND_MIXER_SPEAKER] = AC97_PCBEEPVOLUME,
+	/* 5 bit mono, 7th bit = preamp */
+	[SOUND_MIXER_MIC] = AC97_MICVOLUME,
+	/* 4 bit stereo */
+	[SOUND_MIXER_RECLEV] = AC97_RECORDGAIN,
+	/* 4 bit mono */
+	[SOUND_MIXER_IGAIN] = AC97_RECORDGAINMIC,
+	/* test code */
+	[SOUND_MIXER_BASS] = AC97_GENERALPURPOSE,
+	[SOUND_MIXER_TREBLE] = AC97_MASTERTONE,
+	[SOUND_MIXER_LINE2] = AC97_PCMOUTVOLUME,
+	[SOUND_MIXER_DIGITAL2] = AC97_MASTERVOLUME
+};
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+
+#define swab(x) ((((x) >> 8) & 0xff) | (((x) << 8) & 0xff00))
+
+/* FIXME: mixer_rdch() is broken. */
+
+static int mixer_rdch(struct emu10k1_card *card, unsigned int ch, int *arg)
+{
+	u16 reg;
+	int j;
+	int nL, nR;
+
+	switch (ch) {
+	case SOUND_MIXER_LINE:
+	case SOUND_MIXER_CD:
+	case SOUND_MIXER_VIDEO:
+	case SOUND_MIXER_LINE1:
+	case SOUND_MIXER_PCM:
+	case SOUND_MIXER_VOLUME:
+		sblive_readac97(card, volreg[ch], &reg);
+		nL = ((~(reg >> 8) & 0x1f) * 100) / 32;
+		nR = (~(reg & 0x1f) * 100) / 32;
+		DPD(2, "mixer_rdch: l=%d, r=%d\n", nL, nR);
+		return put_user(reg & 0x8000 ? 0 : (nL << 8) | nR, (int *) arg);
+
+	case SOUND_MIXER_OGAIN:
+	case SOUND_MIXER_PHONEIN:
+		sblive_readac97(card, volreg[ch], &reg);
+		return put_user(reg & 0x8000 ? 0 : ~(reg & 0x1f) * 0x64 / 0x20 * 0x101, (int *) arg);
+
+	case SOUND_MIXER_SPEAKER:
+		sblive_readac97(card, volreg[ch], &reg);
+		return put_user(reg & 0x8000 ? 0 : ~((reg >> 1) & 0xf) * 0x64 / 0x10 * 0x101, (int *) arg);
+
+	case SOUND_MIXER_MIC:
+		sblive_readac97(card, volreg[ch], &reg);
+		return put_user(reg & 0x8000 ? 0 : ~(reg & 0x1f) * 0x64 / 0x20 * 0x101 + ((reg & 0x40) ? 0x1e1e : 0), (int *) arg);
+
+	case SOUND_MIXER_RECLEV:
+		sblive_readac97(card, volreg[ch], &reg);
+		nL = ((~(reg >> 8) & 0x1f) * 100) / 16;
+		nR = (~(reg & 0x1f) * 100) / 16;
+		return put_user(reg & 0x8000 ? 0 : (nL << 8) | nR, (int *) arg);
+
+	case SOUND_MIXER_TREBLE:
+	case SOUND_MIXER_BASS:
+		return put_user(0x0000, (int *) arg);
+	default:
+		return -EINVAL;
+	}
+}
+
+#endif				/* OSS_DOCUMENTED_MIXER_SEMANTICS */
+
+static const unsigned char volidx[SOUND_MIXER_NRDEVICES] = {
+	/* 5 bit stereo */
+	[SOUND_MIXER_LINE] = 1,
+	[SOUND_MIXER_CD] = 2,
+	[SOUND_MIXER_VIDEO] = 3,
+	[SOUND_MIXER_LINE1] = 4,
+	[SOUND_MIXER_PCM] = 5,
+	/* 6 bit stereo */
+	[SOUND_MIXER_VOLUME] = 6,
+	[SOUND_MIXER_PHONEOUT] = 7,
+	/* 6 bit mono */
+	[SOUND_MIXER_OGAIN] = 8,
+	[SOUND_MIXER_PHONEIN] = 9,
+	/* 4 bit mono but shifted by 1 */
+	[SOUND_MIXER_SPEAKER] = 10,
+	/* 6 bit mono + preamp */
+	[SOUND_MIXER_MIC] = 11,
+	/* 4 bit stereo */
+	[SOUND_MIXER_RECLEV] = 12,
+	/* 4 bit mono */
+	[SOUND_MIXER_IGAIN] = 13,
+	[SOUND_MIXER_TREBLE] = 14,
+	[SOUND_MIXER_BASS] = 15,
+	[SOUND_MIXER_LINE2] = 16,
+	[SOUND_MIXER_LINE3] = 17,
+	[SOUND_MIXER_DIGITAL1] = 18,
+	[SOUND_MIXER_DIGITAL2] = 19
+};
+
+static const u32 bass_table[41][5] = {
+	{ 0x3e4f844f, 0x84ed4cc3, 0x3cc69927, 0x7b03553a, 0xc4da8486 },
+	{ 0x3e69a17a, 0x84c280fb, 0x3cd77cd4, 0x7b2f2a6f, 0xc4b08d1d },
+	{ 0x3e82ff42, 0x849991d5, 0x3ce7466b, 0x7b5917c6, 0xc48863ee },
+	{ 0x3e9bab3c, 0x847267f0, 0x3cf5ffe8, 0x7b813560, 0xc461f22c },
+	{ 0x3eb3b275, 0x844ced29, 0x3d03b295, 0x7ba79a1c, 0xc43d223b },
+	{ 0x3ecb2174, 0x84290c8b, 0x3d106714, 0x7bcc5ba3, 0xc419dfa5 },
+	{ 0x3ee2044b, 0x8406b244, 0x3d1c2561, 0x7bef8e77, 0xc3f8170f },
+	{ 0x3ef86698, 0x83e5cb96, 0x3d26f4d8, 0x7c114600, 0xc3d7b625 },
+	{ 0x3f0e5390, 0x83c646c9, 0x3d30dc39, 0x7c319498, 0xc3b8ab97 },
+	{ 0x3f23d60b, 0x83a81321, 0x3d39e1af, 0x7c508b9c, 0xc39ae704 },
+	{ 0x3f38f884, 0x838b20d2, 0x3d420ad2, 0x7c6e3b75, 0xc37e58f1 },
+	{ 0x3f4dc52c, 0x836f60ef, 0x3d495cab, 0x7c8ab3a6, 0xc362f2be },
+	{ 0x3f6245e8, 0x8354c565, 0x3d4fdbb8, 0x7ca602d6, 0xc348a69b },
+	{ 0x3f76845f, 0x833b40ec, 0x3d558bf0, 0x7cc036df, 0xc32f677c },
+	{ 0x3f8a8a03, 0x8322c6fb, 0x3d5a70c4, 0x7cd95cd7, 0xc317290b },
+	{ 0x3f9e6014, 0x830b4bc3, 0x3d5e8d25, 0x7cf1811a, 0xc2ffdfa5 },
+	{ 0x3fb20fae, 0x82f4c420, 0x3d61e37f, 0x7d08af56, 0xc2e9804a },
+	{ 0x3fc5a1cc, 0x82df2592, 0x3d6475c3, 0x7d1ef294, 0xc2d40096 },
+	{ 0x3fd91f55, 0x82ca6632, 0x3d664564, 0x7d345541, 0xc2bf56b9 },
+	{ 0x3fec9120, 0x82b67cac, 0x3d675356, 0x7d48e138, 0xc2ab796e },
+	{ 0x40000000, 0x82a36037, 0x3d67a012, 0x7d5c9fc9, 0xc2985fee },
+	{ 0x401374c7, 0x8291088a, 0x3d672b93, 0x7d6f99c3, 0xc28601f2 },
+	{ 0x4026f857, 0x827f6dd7, 0x3d65f559, 0x7d81d77c, 0xc27457a3 },
+	{ 0x403a939f, 0x826e88c5, 0x3d63fc63, 0x7d9360d4, 0xc2635996 },
+	{ 0x404e4faf, 0x825e5266, 0x3d613f32, 0x7da43d42, 0xc25300c6 },
+	{ 0x406235ba, 0x824ec434, 0x3d5dbbc3, 0x7db473d7, 0xc243468e },
+	{ 0x40764f1f, 0x823fd80c, 0x3d596f8f, 0x7dc40b44, 0xc23424a2 },
+	{ 0x408aa576, 0x82318824, 0x3d545787, 0x7dd309e2, 0xc2259509 },
+	{ 0x409f4296, 0x8223cf0b, 0x3d4e7012, 0x7de175b5, 0xc2179218 },
+	{ 0x40b430a0, 0x8216a7a1, 0x3d47b505, 0x7def5475, 0xc20a1670 },
+	{ 0x40c97a0a, 0x820a0d12, 0x3d4021a1, 0x7dfcab8d, 0xc1fd1cf5 },
+	{ 0x40df29a6, 0x81fdfad6, 0x3d37b08d, 0x7e098028, 0xc1f0a0ca },
+	{ 0x40f54ab1, 0x81f26ca9, 0x3d2e5bd1, 0x7e15d72b, 0xc1e49d52 },
+	{ 0x410be8da, 0x81e75e89, 0x3d241cce, 0x7e21b544, 0xc1d90e24 },
+	{ 0x41231051, 0x81dcccb3, 0x3d18ec37, 0x7e2d1ee6, 0xc1cdef10 },
+	{ 0x413acdd0, 0x81d2b39e, 0x3d0cc20a, 0x7e38184e, 0xc1c33c13 },
+	{ 0x41532ea7, 0x81c90ffb, 0x3cff9585, 0x7e42a58b, 0xc1b8f15a },
+	{ 0x416c40cd, 0x81bfdeb2, 0x3cf15d21, 0x7e4cca7c, 0xc1af0b3f },
+	{ 0x418612ea, 0x81b71cdc, 0x3ce20e85, 0x7e568ad3, 0xc1a58640 },
+	{ 0x41a0b465, 0x81aec7c5, 0x3cd19e7c, 0x7e5fea1e, 0xc19c5f03 },
+	{ 0x41bc3573, 0x81a6dcea, 0x3cc000e9, 0x7e68ebc2, 0xc1939250 }
+};
+
+static const u32 treble_table[41][5] = {
+	{ 0x0125cba9, 0xfed5debd, 0x00599b6c, 0x0d2506da, 0xfa85b354 },
+	{ 0x0142f67e, 0xfeb03163, 0x0066cd0f, 0x0d14c69d, 0xfa914473 },
+	{ 0x016328bd, 0xfe860158, 0x0075b7f2, 0x0d03eb27, 0xfa9d32d2 },
+	{ 0x0186b438, 0xfe56c982, 0x00869234, 0x0cf27048, 0xfaa97fca },
+	{ 0x01adf358, 0xfe21f5fe, 0x00999842, 0x0ce051c2, 0xfab62ca5 },
+	{ 0x01d949fa, 0xfde6e287, 0x00af0d8d, 0x0ccd8b4a, 0xfac33aa7 },
+	{ 0x02092669, 0xfda4d8bf, 0x00c73d4c, 0x0cba1884, 0xfad0ab07 },
+	{ 0x023e0268, 0xfd5b0e4a, 0x00e27b54, 0x0ca5f509, 0xfade7ef2 },
+	{ 0x0278645c, 0xfd08a2b0, 0x01012509, 0x0c911c63, 0xfaecb788 },
+	{ 0x02b8e091, 0xfcac9d1a, 0x0123a262, 0x0c7b8a14, 0xfafb55df },
+	{ 0x03001a9a, 0xfc45e9ce, 0x014a6709, 0x0c65398f, 0xfb0a5aff },
+	{ 0x034ec6d7, 0xfbd3576b, 0x0175f397, 0x0c4e2643, 0xfb19c7e4 },
+	{ 0x03a5ac15, 0xfb5393ee, 0x01a6d6ed, 0x0c364b94, 0xfb299d7c },
+	{ 0x0405a562, 0xfac52968, 0x01ddafae, 0x0c1da4e2, 0xfb39dca5 },
+	{ 0x046fa3fe, 0xfa267a66, 0x021b2ddd, 0x0c042d8d, 0xfb4a8631 },
+	{ 0x04e4b17f, 0xf975be0f, 0x0260149f, 0x0be9e0f2, 0xfb5b9ae0 },
+	{ 0x0565f220, 0xf8b0fbe5, 0x02ad3c29, 0x0bceba73, 0xfb6d1b60 },
+	{ 0x05f4a745, 0xf7d60722, 0x030393d4, 0x0bb2b578, 0xfb7f084d },
+	{ 0x06923236, 0xf6e279bd, 0x03642465, 0x0b95cd75, 0xfb916233 },
+	{ 0x07401713, 0xf5d3aef9, 0x03d01283, 0x0b77fded, 0xfba42984 },
+	{ 0x08000000, 0xf4a6bd88, 0x0448a161, 0x0b594278, 0xfbb75e9f },
+	{ 0x08d3c097, 0xf3587131, 0x04cf35a4, 0x0b3996c9, 0xfbcb01cb },
+	{ 0x09bd59a2, 0xf1e543f9, 0x05655880, 0x0b18f6b2, 0xfbdf1333 },
+	{ 0x0abefd0f, 0xf04956ca, 0x060cbb12, 0x0af75e2c, 0xfbf392e8 },
+	{ 0x0bdb123e, 0xee806984, 0x06c739fe, 0x0ad4c962, 0xfc0880dd },
+	{ 0x0d143a94, 0xec85d287, 0x0796e150, 0x0ab134b0, 0xfc1ddce5 },
+	{ 0x0e6d5664, 0xea547598, 0x087df0a0, 0x0a8c9cb6, 0xfc33a6ad },
+	{ 0x0fe98a2a, 0xe7e6ba35, 0x097edf83, 0x0a66fe5b, 0xfc49ddc2 },
+	{ 0x118c4421, 0xe536813a, 0x0a9c6248, 0x0a4056d7, 0xfc608185 },
+	{ 0x1359422e, 0xe23d19eb, 0x0bd96efb, 0x0a18a3bf, 0xfc77912c },
+	{ 0x1554982b, 0xdef33645, 0x0d3942bd, 0x09efe312, 0xfc8f0bc1 },
+	{ 0x1782b68a, 0xdb50deb1, 0x0ebf676d, 0x09c6133f, 0xfca6f019 },
+	{ 0x19e8715d, 0xd74d64fd, 0x106fb999, 0x099b3337, 0xfcbf3cd6 },
+	{ 0x1c8b07b8, 0xd2df56ab, 0x124e6ec8, 0x096f4274, 0xfcd7f060 },
+	{ 0x1f702b6d, 0xcdfc6e92, 0x14601c10, 0x0942410b, 0xfcf108e5 },
+	{ 0x229e0933, 0xc89985cd, 0x16a9bcfa, 0x09142fb5, 0xfd0a8451 },
+	{ 0x261b5118, 0xc2aa8409, 0x1930bab6, 0x08e50fdc, 0xfd24604d },
+	{ 0x29ef3f5d, 0xbc224f28, 0x1bfaf396, 0x08b4e3aa, 0xfd3e9a3b },
+	{ 0x2e21a59b, 0xb4f2ba46, 0x1f0ec2d6, 0x0883ae15, 0xfd592f33 },
+	{ 0x32baf44b, 0xad0c7429, 0x227308a3, 0x085172eb, 0xfd741bfd },
+	{ 0x37c4448b, 0xa45ef51d, 0x262f3267, 0x081e36dc, 0xfd8f5d14 }
+};
+
+static void set_bass(struct emu10k1_card *card, int l, int r)
+{
+	int i;
+
+	l = (l * 40 + 50) / 100;
+	r = (r * 40 + 50) / 100;
+	for (i = 0; i < 5; i++) {
+		sblive_writeptr(card, FXGPREGBASE + 0x80 + (i * 2), 0, bass_table[l][i]);
+		sblive_writeptr(card, FXGPREGBASE + 0x80 + (i * 2) + 1, 0, bass_table[r][i]);
+	}
+}
+
+static void set_treble(struct emu10k1_card *card, int l, int r)
+{
+	int i;
+
+	l = (l * 40 + 50) / 100;
+	r = (r * 40 + 50) / 100;
+	for (i = 0; i < 5; i++) {
+		sblive_writeptr(card, FXGPREGBASE + 0x90 + (i * 2), 0, treble_table[l][i]);
+		sblive_writeptr(card, FXGPREGBASE + 0x90 + (i * 2) + 1, 0, treble_table[r][i]);
+	}
+}
+
+static const u32 db_table[101] = {
+	0x00000000, 0x01571f82, 0x01674b41, 0x01783a1b, 0x0189f540,
+	0x019c8651, 0x01aff763, 0x01c45306, 0x01d9a446, 0x01eff6b8,
+	0x0207567a, 0x021fd03d, 0x0239714c, 0x02544792, 0x027061a1,
+	0x028dcebb, 0x02ac9edc, 0x02cce2bf, 0x02eeabe8, 0x03120cb0,
+	0x0337184e, 0x035de2df, 0x03868173, 0x03b10a18, 0x03dd93e9,
+	0x040c3713, 0x043d0cea, 0x04702ff3, 0x04a5bbf2, 0x04ddcdfb,
+	0x0518847f, 0x0555ff62, 0x05966005, 0x05d9c95d, 0x06206005,
+	0x066a4a52, 0x06b7b067, 0x0708bc4c, 0x075d9a01, 0x07b6779d,
+	0x08138561, 0x0874f5d5, 0x08dafde1, 0x0945d4ed, 0x09b5b4fd,
+	0x0a2adad1, 0x0aa58605, 0x0b25f936, 0x0bac7a24, 0x0c3951d8,
+	0x0ccccccc, 0x0d673b17, 0x0e08f093, 0x0eb24510, 0x0f639481,
+	0x101d3f2d, 0x10dfa9e6, 0x11ab3e3f, 0x12806ac3, 0x135fa333,
+	0x144960c5, 0x153e2266, 0x163e6cfe, 0x174acbb7, 0x1863d04d,
+	0x198a1357, 0x1abe349f, 0x1c00db77, 0x1d52b712, 0x1eb47ee6,
+	0x2026f30f, 0x21aadcb6, 0x23410e7e, 0x24ea64f9, 0x26a7c71d,
+	0x287a26c4, 0x2a62812c, 0x2c61df84, 0x2e795779, 0x30aa0bcf,
+	0x32f52cfe, 0x355bf9d8, 0x37dfc033, 0x3a81dda4, 0x3d43c038,
+	0x4026e73c, 0x432ce40f, 0x46575af8, 0x49a8040f, 0x4d20ac2a,
+	0x50c335d3, 0x54919a57, 0x588dead1, 0x5cba514a, 0x611911ea,
+	0x65ac8c2f, 0x6a773c39, 0x6f7bbc23, 0x74bcc56c, 0x7a3d3272,
+	0x7fffffff,
+};
+
+static void update_digital(struct emu10k1_card *card)
+{
+	int i, k, l1, r1, l2, r2, l3, r3, l4, r4;
+	u64 j;
+
+	i = card->arrwVol[volidx[SOUND_MIXER_VOLUME]];
+	l1 = (i & 0xff);
+	r1 = ((i >> 8) & 0xff);
+	i = card->arrwVol[volidx[SOUND_MIXER_LINE3]];
+	l2 = i & 0xff;
+	r2 = (i >> 8) & 0xff;
+
+	i = card->arrwVol[volidx[SOUND_MIXER_PCM]];
+	l3 = i & 0xff;
+	r3 = (i >> 8) & 0xff;
+
+	i = card->arrwVol[volidx[SOUND_MIXER_DIGITAL1]];
+	l4 = i & 0xff;
+	r4 = (i >> 8) & 0xff;
+
+	i = (r1 * r2) / 50;
+	if (r2 > 50)
+		r2 = 2 * r1 - i;
+	else {
+		r2 = r1;
+		r1 = i;
+	}
+
+	i = (l1 * l2) / 50;
+	if (l2 > 50)
+		l2 = 2 * l1 - i;
+	else {
+		l2 = l1;
+		l1 = i;
+	}
+
+	for (i = 0; i < 36; i++) {
+		if (card->digmix[i] != 0x80000000) {
+			if (((i >= 0) && (i < 4)) || ((i >= 18) && (i < 22)))
+				j = (i & 1) ? ((u64) db_table[r1] * (u64) db_table[r3]) : ((u64) db_table[l1] * (u64) db_table[l3]);
+			else if ((i == 6) || (i == 7) || (i == 24) || (i == 25))
+				j = (i & 1) ? ((u64) db_table[r1] * (u64) db_table[r4]) : ((u64) db_table[l1] * (u64) db_table[l4]);
+			else
+				j = ((i & 1) ? db_table[r1] : db_table[l1]) << 31;
+			card->digmix[i] = j >> 31;
+			sblive_writeptr(card, FXGPREGBASE + 0x10 + i, 0, card->digmix[i]);
+		}
+	}
+
+	for (i = 72; i < 90; i++) {
+		if (card->digmix[i] != 0x80000000) {
+			if ((i >= 72) && (i < 76))
+				j = (i & 1) ? ((u64) db_table[r2] * (u64) db_table[r3]) : ((u64) db_table[l2] * (u64) db_table[l3]);
+			else if ((i == 78) || (i == 79))
+				j = (i & 1) ? ((u64) db_table[r2] * (u64) db_table[r4]) : ((u64) db_table[l2] * (u64) db_table[l4]);
+			else
+				j = ((i & 1) ? db_table[r2] : db_table[l2]) << 31;
+			card->digmix[i] = j >> 31;
+			sblive_writeptr(card, FXGPREGBASE + 0x10 + i, 0, card->digmix[i]);
+		}
+	}
+
+	for (i = 36; i <= 90; i += 18) {
+		if (i != 72) {
+			for (k = 0; k < 4; k++)
+				if (card->digmix[i + k] != 0x80000000) {
+					card->digmix[i + k] = db_table[l3];
+					sblive_writeptr(card, FXGPREGBASE + 0x10 + i + k, 0, card->digmix[i + k]);
+				}
+			if (card->digmix[i + 6] != 0x80000000) {
+				card->digmix[i + 6] = db_table[l4];
+				sblive_writeptr(card, FXGPREGBASE + 0x10 + i + 6, 0, card->digmix[i + 6]);
+			}
+			if (card->digmix[i + 7] != 0x80000000) {
+				card->digmix[i + 7] = db_table[r4];
+				sblive_writeptr(card, FXGPREGBASE + 0x10 + i + 7, 0, card->digmix[i + 7]);
+			}
+		}
+	}
+
+}
+
+#ifdef PRIVATE_PCM_VOLUME
+
+/* calc & set attenuation factor for given channel */
+static int set_pcm_attn(struct emu10k1_card *card, int ch, int l)
+{
+#ifndef PCMLEVEL
+#define PCMLEVEL 110		/* almost silence */
+#endif
+	int vol = IFATN_ATTENUATION_MASK;	/* silence */
+
+	if (l > 0)
+		vol = (PCMLEVEL - (l * PCMLEVEL + 50) / 100);
+	sblive_writeptr(card, IFATN, ch, IFATN_FILTERCUTOFF_MASK | vol);
+	DPD(2, "SOUND_MIXER_PCM: channel:%d  level:%d  attn:%d\n", ch, l, vol);
+
+	return vol;
+#undef PCMLEVEL
+}
+
+/* update value of local PCM volume level (using channel attenuation)
+ *
+ * return 1: in case its local change
+ *        0: if the current process doesn't have entry in table
+ *	     (it means this process have not opened audio (mixer usually)
+ */
+static int update_pcm_attn(struct emu10k1_card *card, unsigned l1, unsigned r1)
+{
+	int i;
+	int mixer = (r1 << 8) | l1;
+
+	for (i = 0; i < MAX_PCM_CHANNELS; i++) {
+		if (sblive_pcm_volume[i].files == current->files) {
+			sblive_pcm_volume[i].mixer = pcm_last_mixer = mixer;
+			if (sblive_pcm_volume[i].opened) {
+				if (sblive_pcm_volume[i].channel_r < NUM_G) {
+					sblive_pcm_volume[i].attn_r = set_pcm_attn(card, sblive_pcm_volume[i].channel_r, r1);
+					if (sblive_pcm_volume[i].channel_l < NUM_G)
+						sblive_pcm_volume[i].attn_l = set_pcm_attn(card, sblive_pcm_volume[i].channel_l, l1);
+				} else {
+					/* mono voice */
+					if (sblive_pcm_volume[i].channel_l < NUM_G)
+						sblive_pcm_volume[i].attn_l =
+						    set_pcm_attn(card, sblive_pcm_volume[i].channel_l, (l1 >= r1) ? l1 : r1);
+						/* to correctly handle mono voice here we would need
+						   to go into stereo mode and move the voice to the right & left
+						   looks a bit overcomplicated... */
+				}
+			}
+
+			return 1;
+
+		}
+	}
+
+	card->arrwVol[volidx[SOUND_MIXER_PCM]] = mixer;
+	return 0;
+}
+#endif
+
+int emu10k1_mixer_wrch(struct emu10k1_card *card, unsigned int ch, int val)
+{
+	int i;
+	unsigned l1, r1;
+	u16 wval;
+
+	l1 = val & 0xff;
+	r1 = (val >> 8) & 0xff;
+	if (l1 > 100)
+		l1 = 100;
+	if (r1 > 100)
+		r1 = 100;
+
+	DPD(4, "emu10k1_mixer_wrch() called: ch=%u, l1=%u, r1=%u\n", ch, l1, r1);
+
+	if (!volidx[ch])
+		return -EINVAL;
+#ifdef PRIVATE_PCM_VOLUME
+	if (ch != SOUND_MIXER_PCM)
+#endif
+		card->arrwVol[volidx[ch]] = (r1 << 8) | l1;
+
+	switch (ch) {
+	case SOUND_MIXER_VOLUME:
+	case SOUND_MIXER_DIGITAL1:
+	case SOUND_MIXER_LINE3:
+		DPD(4, "SOUND_MIXER_%s:\n", (ch == SOUND_MIXER_VOLUME) ? "VOLUME" : (ch == SOUND_MIXER_DIGITAL1) ? "DIGITAL1" : "LINE3");
+		update_digital(card);
+		return 0;
+	case SOUND_MIXER_PCM:
+		DPF(4, "SOUND_MIXER_PCM\n");
+#ifdef PRIVATE_PCM_VOLUME
+		if (update_pcm_attn(card, l1, r1))
+			return 0;
+#endif
+		update_digital(card);
+		return 0;
+	case SOUND_MIXER_DIGITAL2:
+	case SOUND_MIXER_LINE2:
+	case SOUND_MIXER_LINE1:
+	case SOUND_MIXER_LINE:
+	case SOUND_MIXER_CD:
+		DPD(4, "SOUND_MIXER_%s:\n",
+		    (ch == SOUND_MIXER_LINE1) ? "LINE1" :
+		    (ch == SOUND_MIXER_LINE2) ? "LINE2" : (ch == SOUND_MIXER_LINE) ? "LINE" : (ch == SOUND_MIXER_DIGITAL2) ? "DIGITAL2" : "CD");
+		wval = ((((100 - l1) * 32 + 50) / 100) << 8) | (((100 - r1) * 32 + 50) / 100);
+		if (wval == 0x2020)
+			wval = 0x8000;
+		else
+			wval -= ((wval & 0x2020) / 0x20);
+		sblive_writeac97(card, volreg[ch], wval);
+		return 0;
+
+	case SOUND_MIXER_OGAIN:
+	case SOUND_MIXER_PHONEIN:
+		DPD(4, "SOUND_MIXER_%s:\n", (ch == SOUND_MIXER_PHONEIN) ? "PHONEIN" : "OGAIN");
+		sblive_writeac97(card, volreg[ch], (l1 < 2) ? 0x8000 : ((100 - l1) * 32 + 50) / 100);
+		return 0;
+
+	case SOUND_MIXER_SPEAKER:
+		DPF(4, "SOUND_MIXER_SPEAKER:\n");
+		sblive_writeac97(card, volreg[ch], (l1 < 4) ? 0x8000 : (((100 - l1) * 16 + 50) / 100) << 1);
+		return 0;
+
+	case SOUND_MIXER_MIC:
+		DPF(4, "SOUND_MIXER_MIC:\n");
+		i = 0;
+		if (l1 >= 30)
+			/* 20dB / (34.5dB + 12dB + 20dB) * 100 = 30 */
+		{
+			l1 -= 30;
+			i = 0x40;
+		}
+		sblive_writeac97(card, volreg[ch], (l1 < 2) ? 0x8000 : ((((70 - l1) * 0x20 + 35) / 70) | i));
+		return 0;
+
+	case SOUND_MIXER_RECLEV:
+		DPF(4, "SOUND_MIXER_RECLEV:\n");
+
+		wval = (((l1 * 16 + 50) / 100) << 8) | ((r1 * 16 + 50) / 100);
+		if (wval == 0)
+			wval = 0x8000;
+		else {
+			if (wval & 0xff)
+				wval--;
+			if (wval & 0xff00)
+				wval -= 0x0100;
+		}
+		sblive_writeac97(card, volreg[ch], wval);
+		return 0;
+
+	case SOUND_MIXER_TREBLE:
+		DPF(4, "SOUND_MIXER_TREBLE:\n");
+		set_treble(card, l1, r1);
+		return 0;
+
+	case SOUND_MIXER_BASS:
+		DPF(4, "SOUND_MIXER_BASS:\n");
+		set_bass(card, l1, r1);
+		return 0;
+
+	default:
+		DPF(2, "Got unknown SOUND_MIXER ioctl\n");
+		return -EINVAL;
+	}
+}
+
+static loff_t emu10k1_mixer_llseek(struct file *file, loff_t offset, int origin)
+{
+	DPF(2, "sblive_mixer_llseek() called\n");
+	return -ESPIPE;
+}
+
+/* Mixer file operations */
+
+/* FIXME: Do we need spinlocks in here? */
+static int emu10k1_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	static const char id[] = "SBLive";
+	static const char name[] = "Creative SBLive";
+	int i, val;
+	struct emu10k1_card *card = (struct emu10k1_card *) file->private_data;
+	u16 reg;
+
+	switch (cmd) {
+
+	case SOUND_MIXER_INFO:{
+			mixer_info info;
+
+			DPF(4, "SOUND_MIXER_INFO\n");
+
+			strncpy(info.id, id, sizeof(info.id));
+			strncpy(info.name, name, sizeof(info.name));
+
+			info.modify_counter = card->modcnt;
+			if (copy_to_user((void *) arg, &info, sizeof(info)))
+				return -EFAULT;
+
+			return 0;
+		}
+		break;
+	case SOUND_OLD_MIXER_INFO:{
+			_old_mixer_info info;
+
+			DPF(4, "SOUND_OLD_MIXER_INFO\n");
+
+			strncpy(info.id, id, sizeof(info.id));
+			strncpy(info.name, name, sizeof(info.name));
+
+			if (copy_to_user((void *) arg, &info, sizeof(info)))
+				return -EFAULT;
+
+			return 0;
+		}
+		break;
+
+	case OSS_GETVERSION:
+		DPF(4, "OSS_GETVERSION\n");
+		return put_user(SOUND_VERSION, (int *) arg);
+		break;
+
+	case SOUND_MIXER_PRIVATE1:
+		DPF(4, "SOUND_MIXER_PRIVATE1");
+
+		if (copy_to_user((void *) arg, card->digmix, sizeof(card->digmix)))
+			return -EFAULT;
+
+		return 0;
+
+		break;
+	case SOUND_MIXER_PRIVATE2:
+		DPF(4, "SOUND_MIXER_PRIVATE2");
+
+		if (copy_from_user(card->digmix, (void *) arg, sizeof(card->digmix)))
+			return -EFAULT;
+
+		for (i = 0; i < sizeof(card->digmix) / sizeof(card->digmix[0]); i++)
+			sblive_writeptr(card, FXGPREGBASE + 0x10 + i, 0, (card->digmix[i] & 0x80000000) ? 0 : card->digmix[i]);
+		return 0;
+
+		break;
+#ifdef EMU10K1_DEBUG
+	case SOUND_MIXER_PRIVATE3: {
+			struct mixer_private_ioctl ctl;
+
+			if (copy_from_user(&ctl, (void *) arg, sizeof(struct mixer_private_ioctl)))
+				return -EFAULT;
+
+			switch (ctl.cmd) {
+			case CMD_WRITEFN0:
+				if(ctl.val[0] >= 0x7f)
+					return -EINVAL;
+
+				emu10k1_writefn0(card, ctl.val[0], ctl.val[1]);
+				return 0;
+				break;
+
+			case CMD_READFN0:
+				if(ctl.val[0] >= 0x7f)
+					return -EINVAL;
+
+				ctl.val[2] = emu10k1_readfn0(card, ctl.val[0]);
+
+				if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl)))
+					return -EFAULT;
+
+				return 0;
+				break;
+
+			case CMD_WRITEPTR:
+				if(ctl.val[1] < 0x00 || ctl.val[1] >= 0x40)
+					return -EINVAL;
+
+				if(ctl.val[0] >= 0x100)
+					return -EINVAL;
+
+				if(ctl.val[0] >= 0x40)
+					ctl.val[1] = 0x00;
+
+				sblive_writeptr(card, ctl.val[0], ctl.val[1], ctl.val[2]);
+
+				return 0;
+				break;
+
+			case CMD_READPTR:
+				if(ctl.val[1] < 0x00 || ctl.val[1] >= 0x40)
+					return -EINVAL;
+
+				if(ctl.val[0] >= 0x100)
+					return -EINVAL;
+
+				if(ctl.val[0] > 0x40)
+					ctl.val[1] = 0x00;
+
+				ctl.val[2] = sblive_readptr(card, ctl.val[0], ctl.val[1]);
+
+				if (copy_to_user((void *) arg, &ctl, sizeof(struct mixer_private_ioctl)))
+					return -EFAULT;
+
+				return 0;
+				break;
+
+			default:
+				return -EINVAL;
+				break;
+			}
+		}
+		break;
+#endif
+	case SOUND_MIXER_PRIVATE4:{
+			u32 size;
+			int size_reg = 0;
+
+			if (copy_from_user(&size, (void *) arg, sizeof(size)))
+				return -EFAULT;
+
+			DPD(2,"External tram size 0x%x\n", size);
+
+			if(size > 0x1fffff)
+				return -EINVAL;
+
+			if (size != 0) {	
+				size = (size - 1) >> 14;
+
+        	                while (size) {
+                	                size >>= 1;
+                        	        size_reg++;
+                        	}
+
+                        	size = 0x4000 << size_reg;
+			}
+
+			DPD(2,"External tram size 0x%x 0x%x\n", size, size_reg);
+
+			if (size != card->tankmem.size) {
+				if (card->tankmem.size > 0) {
+					emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 1);
+
+					sblive_writeptr_tag(card, 0, TCB, 0,
+							    TCBS, 0,
+							    TAGLIST_END);
+
+					pci_free_consistent(card->pci_dev, card->tankmem.size,
+							    card->tankmem.addr, card->tankmem.dma_handle);
+
+					card->tankmem.size = 0;
+				}
+
+				if (size != 0) {
+					if ((card->tankmem.addr = pci_alloc_consistent(card->pci_dev, size,
+					     &card->tankmem.dma_handle)) == NULL)
+						return -ENOMEM;
+
+					card->tankmem.size = size;
+
+					sblive_writeptr_tag(card, 0, TCB, card->tankmem.dma_handle,
+                        	                            TCBS, size_reg,
+                                	                    TAGLIST_END);
+
+					emu10k1_writefn0(card, HCFG_LOCKTANKCACHE, 0);
+				}
+			}
+			return 0;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	if (_IOC_TYPE(cmd) != 'M' || _IOC_SIZE(cmd) != sizeof(int))
+		return -EINVAL;
+
+	if (_IOC_DIR(cmd) == _IOC_READ) {
+		switch (_IOC_NR(cmd)) {
+		case SOUND_MIXER_RECSRC:	/* Arg contains a bit for each recording source */
+			DPF(2, "SOUND_MIXER_READ_RECSRC\n");
+			sblive_readac97(card, AC97_RECORDSELECT, &reg);
+			return put_user(recsrc[reg & 7], (int *) arg);
+
+		case SOUND_MIXER_DEVMASK:	/* Arg contains a bit for each supported device */
+			DPF(4, "SOUND_MIXER_READ_DEVMASK\n");
+			return put_user(SOUND_MASK_LINE | SOUND_MASK_CD |
+					SOUND_MASK_OGAIN | SOUND_MASK_LINE1 |
+					SOUND_MASK_PCM | SOUND_MASK_VOLUME |
+					SOUND_MASK_PHONEIN | SOUND_MASK_MIC |
+					SOUND_MASK_BASS | SOUND_MASK_TREBLE |
+					SOUND_MASK_RECLEV | SOUND_MASK_SPEAKER |
+					SOUND_MASK_LINE3 | SOUND_MASK_DIGITAL1 | 
+					SOUND_MASK_DIGITAL2 | SOUND_MASK_LINE2, (int *) arg);
+		case SOUND_MIXER_RECMASK:	/* Arg contains a bit for each supported recording source */
+			DPF(2, "SOUND_MIXER_READ_RECMASK\n");
+			return put_user(SOUND_MASK_MIC | SOUND_MASK_CD |
+					SOUND_MASK_LINE1 | SOUND_MASK_LINE | 
+					SOUND_MASK_VOLUME | SOUND_MASK_OGAIN | 
+					SOUND_MASK_PHONEIN | SOUND_MASK_MONITOR | 
+					SOUND_MASK_PCM, (int *) arg);
+
+		case SOUND_MIXER_STEREODEVS:	/* Mixer channels supporting stereo */
+			DPF(2, "SOUND_MIXER_READ_STEREODEVS\n");
+			return put_user(SOUND_MASK_LINE | SOUND_MASK_CD |
+					SOUND_MASK_OGAIN | SOUND_MASK_LINE1 |
+					SOUND_MASK_PCM | SOUND_MASK_VOLUME |
+					SOUND_MASK_BASS | SOUND_MASK_TREBLE |
+					SOUND_MASK_RECLEV | SOUND_MASK_LINE3 |
+					SOUND_MASK_DIGITAL1 | SOUND_MASK_DIGITAL2 | 
+					SOUND_MASK_LINE2, (int *) arg);
+
+		case SOUND_MIXER_CAPS:
+			DPF(2, "SOUND_MIXER_READ_CAPS\n");
+			return put_user(SOUND_CAP_EXCL_INPUT, (int *) arg);
+
+#ifdef PRIVATE_PCM_VOLUME
+		case SOUND_MIXER_PCM:
+			/* needs to be before default: !!*/
+			{
+				int i;
+
+				for (i = 0; i < MAX_PCM_CHANNELS; i++) {
+					if (sblive_pcm_volume[i].files == current->files) {
+						return put_user((int) sblive_pcm_volume[i].mixer, (int *) arg);
+					}
+				}
+			}
+#endif
+		default:
+			i = _IOC_NR(cmd);
+			DPD(4, "SOUND_MIXER_READ(%d)\n", i);
+			if (i >= SOUND_MIXER_NRDEVICES)
+				return -EINVAL;
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+			return mixer_rdch(card, i, (int *) arg);
+#else				/* OSS_DOCUMENTED_MIXER_SEMANTICS */
+			if (!volidx[i])
+				return -EINVAL;
+			return put_user(card->arrwVol[volidx[i]], (int *) arg);
+
+#endif				/* OSS_DOCUMENTED_MIXER_SEMANTICS */
+		}
+	}
+	/* End of _IOC_READ */
+	if (_IOC_DIR(cmd) != (_IOC_READ | _IOC_WRITE))
+		return -EINVAL;
+
+	/* _IOC_WRITE */
+	card->modcnt++;
+
+	switch (_IOC_NR(cmd)) {
+	case SOUND_MIXER_RECSRC:	/* Arg contains a bit for each recording source */
+		DPF(2, "SOUND_MIXER_WRITE_RECSRC\n");
+
+		get_user_ret(val, (int *) arg, -EFAULT);
+		i = hweight32(val);
+		if (i == 0)
+			return 0;	/* val = mixer_recmask(s); */
+		else if (i > 1) {
+			sblive_readac97(card, AC97_RECORDSELECT, &reg);
+			val &= ~recsrc[reg & 7];
+		}
+
+		for (i = 0; i < 8; i++) {
+			if (val & recsrc[i]) {
+				DPD(2, "Selecting record source to be 0x%04x\n", 0x0101 * i);
+				sblive_writeac97(card, AC97_RECORDSELECT, 0x0101 * i);
+				return 0;
+			}
+		}
+		return 0;
+
+	default:
+		i = _IOC_NR(cmd);
+		DPD(4, "SOUND_MIXER_WRITE(%d)\n", i);
+
+		if (i >= SOUND_MIXER_NRDEVICES)
+			return -EINVAL;
+		get_user_ret(val, (int *) arg, -EFAULT);
+		if (emu10k1_mixer_wrch(card, i, val))
+			return -EINVAL;
+
+#ifdef OSS_DOCUMENTED_MIXER_SEMANTICS
+		return mixer_rdch(card, i, (int *) arg);
+#else				/* OSS_DOCUMENTED_MIXER_SEMANTICS */
+		return put_user(card->arrwVol[volidx[i]], (int *) arg);
+#endif				/* OSS_DOCUMENTED_MIXER_SEMANTICS */
+
+	}
+}
+
+static int emu10k1_mixer_open(struct inode *inode, struct file *file)
+{
+	int minor = MINOR(inode->i_rdev);
+	struct emu10k1_card *card;
+	struct list_head *entry;
+
+	DPF(4, "emu10k1_mixer_open()\n");
+
+	list_for_each(entry, &emu10k1_devs) {
+		card = list_entry(entry, struct emu10k1_card, list);
+
+		if (card->mixer_num == minor)
+			break;
+	}
+
+	if (entry == &emu10k1_devs)
+		return -ENODEV;
+
+	MOD_INC_USE_COUNT;
+
+	file->private_data = card;
+	return 0;
+}
+
+static int emu10k1_mixer_release(struct inode *inode, struct file *file)
+{
+	DPF(3, "emu10k1_mixer_release()\n");
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+struct file_operations emu10k1_mixer_fops = {
+	llseek:emu10k1_mixer_llseek,
+	ioctl:emu10k1_mixer_ioctl,
+	open:emu10k1_mixer_open,
+	release:emu10k1_mixer_release,
+};
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/recmgr.c linux.17p18/drivers/sound/emu10k1/recmgr.c
--- linux.vanilla/drivers/sound/emu10k1/recmgr.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/recmgr.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,143 @@
+/*
+ **********************************************************************
+ *     recmgr.c -- Recording manager for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include "8010.h"
+#include "recmgr.h"
+
+void emu10k1_start_record(struct emu10k1_card *card, struct wavein_buffer *buffer)
+{
+	DPF(2, "emu10k1_start_record()\n");
+
+	if(buffer->fxwc)
+		sblive_writeptr(card, FXWC, 0, buffer->fxwc);
+
+	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)
+{
+	DPF(2, "emu10k1_stop_record()\n");
+
+	/* 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)
+{
+	struct wavein_buffer *buffer = &wiinst->buffer;
+
+	DPF(2, "emu10k1_set_record_src()\n");
+
+	switch (wiinst->recsrc) {
+
+	case WAVERECORD_AC97:
+		DPF(2, "recording source: AC97\n");
+		buffer->sizereg = ADCBS;
+		buffer->addrreg = ADCBA;
+		buffer->idxreg = ADCIDX_IDX;
+
+		switch (wiinst->format.samplingrate) {
+		case 0xBB80:
+			buffer->adcctl = ADCCR_SAMPLERATE_48;
+			break;
+		case 0xAC44:
+			buffer->adcctl = ADCCR_SAMPLERATE_44;
+			break;
+		case 0x7D00:
+			buffer->adcctl = ADCCR_SAMPLERATE_32;
+			break;
+		case 0x5DC0:
+			buffer->adcctl = ADCCR_SAMPLERATE_24;
+			break;
+		case 0x5622:
+			buffer->adcctl = ADCCR_SAMPLERATE_22;
+			break;
+		case 0x3E80:
+			buffer->adcctl = ADCCR_SAMPLERATE_16;
+			break;
+		case 0x2B11:
+			buffer->adcctl = ADCCR_SAMPLERATE_11;
+			break;
+		case 0x1F40:
+			buffer->adcctl = ADCCR_SAMPLERATE_8;
+			break;
+		default:
+			BUG();
+			break;
+		}
+
+		buffer->adcctl |= ADCCR_LCHANENABLE;
+
+		if (wiinst->format.channels == 2)
+			buffer->adcctl |= ADCCR_RCHANENABLE;
+
+			buffer->fxwc = 0;
+
+		break;
+
+	case WAVERECORD_MIC:
+		DPF(2, "recording source: MIC\n");
+		buffer->sizereg = MICBS;
+		buffer->addrreg = MICBA;
+		buffer->idxreg = MICIDX_IDX;
+		buffer->adcctl = 0;
+		buffer->fxwc = 0;
+		break;
+
+	case WAVERECORD_FX:
+		DPF(2, "recording source: FX\n");
+		buffer->sizereg = FXBS;
+		buffer->addrreg = FXBA;
+		buffer->idxreg = FXIDX_IDX;
+		buffer->adcctl = 0;
+		buffer->fxwc = 0x0001;
+		break;
+	default:
+		BUG();
+		break;
+	}
+
+	DPD(2, "bus addx: %x\n", buffer->dma_handle);
+
+	sblive_writeptr(card, buffer->addrreg, 0, buffer->dma_handle);
+
+	return;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/recmgr.h linux.17p18/drivers/sound/emu10k1/recmgr.h
--- linux.vanilla/drivers/sound/emu10k1/recmgr.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/recmgr.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,48 @@
+/*     
+ **********************************************************************
+ *     recmgr.h
+ *     Copyright 1999, 2000 Creative Labs, Inc. 
+ * 
+ ********************************************************************** 
+ * 
+ *     Date                 Author          Summary of changes 
+ *     ----                 ------          ------------------ 
+ *     October 20, 1999     Bertrand Lee    base code release 
+ * 
+ ********************************************************************** 
+ * 
+ *     This program is free software; you can redistribute it and/or 
+ *     modify it under the terms of the GNU General Public License as 
+ *     published by the Free Software Foundation; either version 2 of 
+ *     the License, or (at your option) any later version. 
+ * 
+ *     This program is distributed in the hope that it will be useful, 
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of 
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
+ *     GNU General Public License for more details. 
+ * 
+ *     You should have received a copy of the GNU General Public 
+ *     License along with this program; if not, write to the Free 
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 
+ *     USA. 
+ * 
+ ********************************************************************** 
+ */
+
+#ifndef _RECORDMGR_H
+#define _RECORDMGR_H
+
+#include "hwaccess.h"
+#include "cardwi.h"
+
+/* Recording resources */
+#define WAVERECORD_AC97		0x01
+#define WAVERECORD_MIC		0x02
+#define WAVERECORD_FX		0x03
+
+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 -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/timer.c linux.17p18/drivers/sound/emu10k1/timer.c
--- linux.vanilla/drivers/sound/emu10k1/timer.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/timer.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,176 @@
+
+/*
+ **********************************************************************
+ *     timer.c
+ *     Copyright (C) 1999, 2000 Creative Labs, inc.
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+/* 3/6/2000	Improved support for different timer delays  Rui Sousa */
+
+/* 4/3/2000	Implemented timer list using list.h 	     Rui Sousa */
+
+#include "hwaccess.h"
+#include "8010.h"
+#include "irqmgr.h"
+#include "timer.h"
+
+/* Try to schedule only once per fragment */
+
+void emu10k1_timer_irqhandler(struct emu10k1_card *card)
+{
+	struct emu_timer *t;
+	struct list_head *entry;
+
+	spin_lock(&card->timer_lock);
+
+	list_for_each(entry, &card->timers) {
+		t = list_entry(entry, struct emu_timer, list);
+
+		if (t->state & TIMER_STATE_ACTIVE) {
+			t->count++;
+			if (t->count == t->count_max) {
+				t->count = 0;
+				tasklet_hi_schedule(&t->tasklet);
+			}
+		}
+	}
+
+	spin_unlock(&card->timer_lock);
+
+	return;
+}
+
+void emu10k1_timer_install(struct emu10k1_card *card, struct emu_timer *timer, u32 delay)
+{
+	struct emu_timer *t;
+	struct list_head *entry;
+	unsigned long flags;
+
+	if (delay < 5)
+		delay = 5;
+
+	timer->delay = delay;
+	timer->state = TIMER_STATE_INSTALLED;
+
+	spin_lock_irqsave(&card->timer_lock, flags);
+
+	timer->count_max = timer->delay / (card->timer_delay < 1024 ? card->timer_delay : 1024);
+	timer->count = timer->count_max - 1;
+
+	list_add(&timer->list, &card->timers);
+
+	if (card->timer_delay > delay) {
+		if (card->timer_delay == TIMER_STOPPED)
+			emu10k1_irq_enable(card, INTE_INTERVALTIMERENB);
+
+		card->timer_delay = delay;
+		delay = (delay < 1024 ? delay : 1024);
+
+		emu10k1_writefn0(card, TIMER_RATE, delay);
+
+		list_for_each(entry, &card->timers) {
+			t = list_entry(entry, struct emu_timer, list);
+
+			t->count_max = t->delay / delay;
+			/* don't want to think much, just force scheduling 
+			   on the next interrupt */
+			t->count = t->count_max - 1;
+		}
+
+		DPD(2, "timer rate --> %u\n", delay);
+	}
+
+	spin_unlock_irqrestore(&card->timer_lock, flags);
+
+	return;
+}
+
+void emu10k1_timer_uninstall(struct emu10k1_card *card, struct emu_timer *timer)
+{
+	struct emu_timer *t;
+	struct list_head *entry;
+	u32 delay = TIMER_STOPPED;
+	unsigned long flags;
+
+	if (timer->state == TIMER_STATE_UNINSTALLED)
+		return;
+
+	spin_lock_irqsave(&card->timer_lock, flags);
+
+	list_del(&timer->list);
+
+	list_for_each(entry, &card->timers) {
+		t = list_entry(entry, struct emu_timer, list);
+
+		if (t->delay < delay)
+			delay = t->delay;
+	}
+
+	if (card->timer_delay != delay) {
+		card->timer_delay = delay;
+
+		if (delay == TIMER_STOPPED)
+			emu10k1_irq_disable(card, INTE_INTERVALTIMERENB);
+		else {
+			delay = (delay < 1024 ? delay : 1024);
+
+			emu10k1_writefn0(card, TIMER_RATE, delay);
+
+			list_for_each(entry, &card->timers) {
+				t = list_entry(entry, struct emu_timer, list);
+
+				t->count_max = t->delay / delay;
+				t->count = t->count_max - 1;
+			}
+		}
+
+		DPD(2, "timer rate --> %u\n", delay);
+	}
+
+	spin_unlock_irqrestore(&card->timer_lock, flags);
+
+	timer->state = TIMER_STATE_UNINSTALLED;
+
+	return;
+}
+
+void emu10k1_timer_enable(struct emu10k1_card *card, struct emu_timer *timer)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->timer_lock, flags);
+	timer->state |= TIMER_STATE_ACTIVE;
+	spin_unlock_irqrestore(&card->timer_lock, flags);
+
+	return;
+}
+
+void emu10k1_timer_disable(struct emu10k1_card *card, struct emu_timer *timer)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&card->timer_lock, flags);
+	timer->state &= ~TIMER_STATE_ACTIVE;
+	spin_unlock_irqrestore(&card->timer_lock, flags);
+
+	return;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/timer.h linux.17p18/drivers/sound/emu10k1/timer.h
--- linux.vanilla/drivers/sound/emu10k1/timer.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/timer.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,53 @@
+/*
+ **********************************************************************
+ *     timer.h
+ *     Copyright (C) 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+
+#ifndef _TIMER_H
+#define _TIMER_H
+
+#include <linux/interrupt.h>
+#include "hwaccess.h"
+
+struct emu_timer 
+{
+	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 */
+};
+
+void emu10k1_timer_install(struct emu10k1_card *, struct emu_timer *, u32);
+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_STATE_INSTALLED 		0x01
+#define TIMER_STATE_ACTIVE		0x02
+#define TIMER_STATE_UNINSTALLED 	0x04
+
+#endif /* _TIMER_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/voicemgr.c linux.17p18/drivers/sound/emu10k1/voicemgr.c
--- linux.vanilla/drivers/sound/emu10k1/voicemgr.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/voicemgr.c	Tue Aug  1 07:59:57 2000
@@ -0,0 +1,364 @@
+/*
+ **********************************************************************
+ *     voicemgr.c - Voice manager for emu10k1 driver
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     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.
+ *
+ **********************************************************************
+ */
+
+#include "voicemgr.h"
+#include "8010.h"
+
+int emu10k1_voice_alloc(struct emu10k1_card *card, struct emu_voice *voice, struct voice_allocdesc *voiceallocdesc)
+{
+	u8 *voicetable = card->voicetable;
+	int i;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_voice_alloc()\n");
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	if (voiceallocdesc->flags & VOICE_FLAGS_STEREO) {
+		for (i = 0; i < NUM_G; i += 2)
+			if ((voicetable[i] == VOICE_USAGE_FREE) && (voicetable[i + 1] == VOICE_USAGE_FREE)) {
+				voicetable[i] = voiceallocdesc->usage;
+				voicetable[i + 1] = voiceallocdesc->usage;
+				break;
+			}
+	} else {
+		for (i = 0; i < NUM_G; i++)
+			if (voicetable[i] == VOICE_USAGE_FREE) {
+				voicetable[i] = voiceallocdesc->usage;
+				break;
+			}
+	}
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	if (i >= NUM_G)
+		return -1;
+
+	voice->card = card;
+	voice->flags = voiceallocdesc->flags;
+	voice->usage = voiceallocdesc->usage;
+	voice->num = i;
+
+#ifdef PRIVATE_PCM_VOLUME
+
+	for (i = 0; i < MAX_PCM_CHANNELS; i++) {
+		if (sblive_pcm_volume[i].files == current->files) {
+			sblive_pcm_volume[i].channel_l = voice->num;
+			DPD(2, "preset left: %d\n", voice->num);
+			if (voice->flags & VOICE_FLAGS_STEREO) {
+				sblive_pcm_volume[i].channel_r = voice->num + 1;
+				DPD(2, "preset right: %d\n", voice->num + 1);
+			}
+			break;
+		}
+	}
+#endif
+
+	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
+		DPD(2, " voice allocated -> %d\n", voice->num + i);
+
+		sblive_writeptr_tag(card, voice->num + i, IFATN, 0xffff,
+							DCYSUSV, 0,
+							VTFT, 0x0000ffff,
+							PTRX, 0,
+							TAGLIST_END);
+	}
+
+	return 0;
+}
+
+void emu10k1_voice_free(struct emu_voice *voice)
+{
+	struct emu10k1_card *card = voice->card;
+	int i;
+	u32 cra, sample;
+	unsigned long flags;
+
+	DPF(2, "emu10k1_voice_free()\n");
+
+	if (voice->usage == VOICE_USAGE_FREE)
+		return;
+
+#ifdef PRIVATE_PCM_VOLUME
+	for (i = 0; i < MAX_PCM_CHANNELS; i++) {
+		if (sblive_pcm_volume[i].files == current->files) {
+			if (voice->num == sblive_pcm_volume[i].channel_l)
+				sblive_pcm_volume[i].channel_l = NUM_G;
+			if ((voice->flags & VOICE_FLAGS_STEREO)
+			    && (voice->num + 1) == sblive_pcm_volume[i].channel_r) {
+				sblive_pcm_volume[i].channel_r = NUM_G;
+			}
+			break;
+		}
+	}
+#endif
+
+	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
+		int cra1;
+
+		DPD(2, " voice freed -> %d\n", voice->num + i);
+
+		sblive_writeptr_tag(card, voice->num + i, DCYSUSV, 0, 
+							VTFT, 0x0000ffff,
+							PTRX_PITCHTARGET, 0,
+							CVCF, 0x0000ffff,
+							CPF, 0,
+							TAGLIST_END);
+
+		sample = (voice->flags & VOICE_FLAGS_16BIT) ? 0 : 0x80808080;
+		cra = sblive_readptr(card, CCR, voice->num) & CCR_READADDRESS_MASK;
+		cra1 = (cra >> 18) & 0xf;
+
+		sblive_writeptr_tag(card, voice->num + i, CCR, cra,
+							CD0 + cra1, sample,
+							CD0 + ((cra1 + 0x1) & 0xf), sample,
+							TAGLIST_END);
+	}
+
+	voice->usage = VOICE_USAGE_FREE;
+
+	spin_lock_irqsave(&card->lock, flags);
+
+	card->voicetable[voice->num] = VOICE_USAGE_FREE;
+
+	if (voice->flags & VOICE_FLAGS_STEREO)
+		card->voicetable[voice->num + 1] = VOICE_USAGE_FREE;
+
+	spin_unlock_irqrestore(&card->lock, flags);
+
+	return;
+}
+
+/*       Sets up a voices for Wave Playback */
+
+void emu10k1_voice_playback_setup(struct emu_voice *voice)
+{
+	struct emu10k1_card *card = voice->card;
+	u32 sample, cra = 0, start = 0;
+	int i;
+
+	DPF(2, "emu10k1_voice_playback_setup()\n");
+
+	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
+		sblive_writeptr(card, FXRT, voice->num + i, voice->params[i].bus_routing << 16);
+
+		/* Stop CA */
+		/* Assumption that PT is alreadt 0 so no harm overwriting */
+		sblive_writeptr(card, PTRX, voice->num + i, (voice->params[i].send_a << 8) | voice->params[i].send_b);
+
+		if (i == 0) {
+			if (voice->flags & VOICE_FLAGS_STEREO) {
+				/* Set stereo bit */
+				cra = 64;
+				sblive_writeptr(card, CPF, voice->num, CPF_STEREO_MASK);
+				sblive_writeptr(card, CPF, voice->num + 1, CPF_STEREO_MASK);
+			} else {
+				cra = 32;
+				sblive_writeptr(card, CPF, voice->num, 0);
+			}
+
+			if (voice->flags & VOICE_FLAGS_16BIT)
+				sample = 0;
+			else {
+				cra = cra * 2;
+				sample = 0x80808080;
+			}
+			cra -= 4;
+
+			if (voice->flags & VOICE_FLAGS_STEREO) {
+				/* CCR_READADDRESS_MASK */
+				sblive_writeptr(card, CCR, voice->num, 0x3c << 16);
+				sblive_writeptr_tag(card, voice->num + 1, CCR, cra << 16, CDE, sample, CDF, sample, TAGLIST_END);
+				start = voice->start + cra / 2;
+			} else {
+				sblive_writeptr_tag(card, voice->num, CCR, 0x1c << 16,	/* FIXME: Is 0x1c correct? */
+						    CDE, sample, CDF, sample, TAGLIST_END);
+				start = voice->start + cra;
+			}
+
+			if (start > voice->endloop) {
+				start -= voice->endloop;
+
+				if (voice->flags & VOICE_FLAGS_STEREO)
+					cra = (cra << 25) | 0x1bc0000 | ((cra - start) << 9);
+				else
+					cra = (cra << 25) | 0x11c0000 | ((cra - start) << 9);
+
+				start += voice->startloop;
+
+				if (start >= voice->endloop)
+					start = voice->endloop - 1;
+			} else if (voice->flags & VOICE_FLAGS_STEREO)
+				cra = (cra << 25) | (0x3c << 16);
+			else
+				cra = (cra << 25) | (0x1c << 16);
+
+			start |= CCCA_INTERPROM_0;
+		}
+
+		/* CSL, ST, CA */
+		sblive_writeptr_tag(card, voice->num + i,
+				    DSL, voice->endloop | (voice->params[i].send_d << 24),
+				    PSST, voice->startloop | (voice->params[i].send_c << 24),
+				    CCCA, start | ((voice->flags & VOICE_FLAGS_16BIT) ? 0 : CCCA_8BITSELECT),
+				    /* Clear filter delay memory */
+				    Z1, 0,
+				    Z2, 0,
+				    /* Invalidate maps */
+				    MAPA, MAP_PTI_MASK | (card->silentpage.dma_handle * 2),
+				    MAPB, MAP_PTI_MASK | (card->silentpage.dma_handle * 2), TAGLIST_END);
+
+		/* Fill cache */
+		if (i == 0)
+			sblive_writeptr(card, CCR, voice->num, cra);
+
+		/* modulation envelope */
+		sblive_writeptr_tag(card, voice->num + i,
+				    CVCF, 0x0000ffff,
+				    VTFT, 0x0000ffff,
+				    ATKHLDM, 0,
+				    DCYSUSM, 0x007f,
+				    LFOVAL1, 0x8000,
+				    LFOVAL2, 0x8000,
+				    FMMOD, 0,
+				    TREMFRQ, 0,
+				    FM2FRQ2, 0,
+				    ENVVAL, 0x8000,
+				    /* volume envelope */
+				    ATKHLDV, 0x7f7f,
+				    ENVVOL, 0x8000,
+				    /* filter envelope */
+				    PEFE_FILTERAMOUNT, 0x7f,
+				    /* pitch envelope */
+				    PEFE_PITCHAMOUNT, 0, TAGLIST_END);
+
+#ifdef PRIVATE_PCM_VOLUME
+{
+int j;
+        for (j = 0; j < MAX_PCM_CHANNELS; j++) {
+                if (sblive_pcm_volume[j].channel_l == voice->num + i) {
+                        voice->params[i].initial_attn = (sblive_pcm_volume[j].channel_r < NUM_G) ? sblive_pcm_volume[i].attn_l :
+                // test for mono channel (reverse logic is correct here!)
+                                            (sblive_pcm_volume[j].attn_r >
+                                             sblive_pcm_volume[j].attn_l) ? sblive_pcm_volume[j].attn_l : sblive_pcm_volume[j].attn_r;
+                                        DPD(2, "set left volume %d\n", voice->params[i].initial_attn);
+                                        break;
+                                } else if (sblive_pcm_volume[j].channel_r == voice->num + i) {
+                                        voice->params[i].initial_attn = sblive_pcm_volume[j].attn_r;
+                                        DPD(2, "set right volume %d\n", voice->params[i].initial_attn);
+                                        break;
+                                }
+                        }
+                }
+#endif
+
+		voice->params[i].fc_target = 0xffff;
+	}
+
+	return;
+}
+
+void emu10k1_voice_start(struct emu_voice *voice)
+{
+	struct emu10k1_card *card = voice->card;
+	int i;
+
+	DPF(2, "emu10k1_voice_start()\n");
+
+	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
+		sblive_writeptr_tag(card, voice->num + i,
+				    IFATN, (voice->params[i].initial_fc << 8) | voice->params[i].initial_attn,
+				    VTFT, (voice->params[i].volume_target << 16) | voice->params[i].fc_target,
+				    CVCF, (voice->params[i].volume_target << 16) | voice->params[i].fc_target,
+				    DCYSUSV, (voice->params[i].byampl_env_sustain << 8) | voice->params[i].byampl_env_decay,
+				    TAGLIST_END);
+
+		/* Using StopOnLoop for MIDI stops the playback
+		   too early, which may cause a DC level to be played
+		   until the note is released. */
+
+		if (voice->usage == VOICE_USAGE_MIDI)
+			emu10k1_clear_stop_on_loop(card, voice->num + i);
+		else {
+			if (voice->startloop > voice->end)
+				emu10k1_set_stop_on_loop(card, voice->num + i);
+			else
+				emu10k1_clear_stop_on_loop(card, voice->num + i);
+		}
+
+		sblive_writeptr(card, PTRX_PITCHTARGET, voice->num + i, voice->pitch_target);
+
+		if (i == 0)
+			sblive_writeptr(card, CPF_CURRENTPITCH, voice->num, voice->pitch_target);
+
+		sblive_writeptr(card, IP, voice->num + i, voice->initial_pitch);
+	}
+
+	return;
+}
+
+void emu10k1_voice_stop(struct emu_voice *voice)
+{
+	struct emu10k1_card *card = voice->card;
+	int i;
+
+	DPF(2, "emu10k1_voice_stop()\n");
+
+	for (i = 0; i < (voice->flags & VOICE_FLAGS_STEREO ? 2 : 1); i++) {
+		sblive_writeptr_tag(card, voice->num + i, IFATN, 0xffff,
+				    VTFT, 0x0000ffff,
+				    PTRX_PITCHTARGET, 0,
+				    IP, 0,
+				    TAGLIST_END);
+	}
+
+	return;
+}
+
+void emu10k1_voice_setcontrol(struct emu_voice *voice, struct voice_cntlset *setting, u32 numparam)
+{
+	struct emu10k1_card *card = voice->card;
+	int count;
+
+	for (count = 0; count < numparam; count++)
+		sblive_writeptr(card, setting[count].paramID, voice->num, setting[count].value);
+
+	return;
+}
+
+void emu10k1_voice_getcontrol(struct emu_voice *voice, u32 controlid, u32 * value)
+{
+	struct emu10k1_card *card = voice->card;
+
+	*value = sblive_readptr(card, controlid, voice->num);
+
+	return;
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/emu10k1/voicemgr.h linux.17p18/drivers/sound/emu10k1/voicemgr.h
--- linux.vanilla/drivers/sound/emu10k1/voicemgr.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/sound/emu10k1/voicemgr.h	Wed Aug  9 22:47:14 2000
@@ -0,0 +1,105 @@
+/*
+ **********************************************************************
+ *     sblive_voice.h -- EMU Voice Resource Manager header file
+ *     Copyright 1999, 2000 Creative Labs, Inc.
+ *
+ **********************************************************************
+ *
+ *     Date                 Author          Summary of changes
+ *     ----                 ------          ------------------
+ *     October 20, 1999     Bertrand Lee    base code release
+ *
+ **********************************************************************
+ *
+ *     This program is free software; you can redistribute it and/or
+ *     modify it under the terms of the GNU General Public License as
+ *     published by the Free Software Foundation; either version 2 of
+ *     the License, or (at your option) any later version.
+ *
+ *     This program is distributed in the hope that it will be useful,
+ *     but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *     GNU General Public License for more details.
+ *
+ *     You should have received a copy of the GNU General Public
+ *     License along with this program; if not, write to the Free
+ *     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ *     USA.
+ *
+ **********************************************************************
+ */
+
+#ifndef _VOICEMGR_H
+#define _VOICEMGR_H
+
+#include "hwaccess.h"
+
+/* struct emu_voice.usage flags */
+#define VOICE_USAGE_FREE		0x01
+#define VOICE_USAGE_MIDI		0x02
+#define VOICE_USAGE_PLAYBACK		0x04
+
+/* struct emu_voice.flags flags */
+#define VOICE_FLAGS_STEREO		0x02
+#define VOICE_FLAGS_16BIT		0x04
+
+struct voice_param
+{
+	/* FX bus amount send */
+
+	u32 bus_routing;
+
+	u32 send_a;
+	u32 send_b;
+	u32 send_c;
+	u32 send_d;
+
+	u32 initial_fc;
+	u32 fc_target;
+
+	u32 initial_attn;
+	u32 volume_target;
+
+	u32 byampl_env_sustain;
+	u32 byampl_env_decay;
+};
+
+struct voice_allocdesc
+{
+	u8 usage;			/* playback, Midi */
+	u8 flags;			/* stereo/mono rec/playback 8/16 bit*/
+};
+
+struct emu_voice
+{
+	struct emu10k1_card *card;
+	u8 usage;		/* Free, MIDI, playback */
+	u8 num;			/* Voice ID */
+	u8 flags;		/* Stereo/mono, 8/16 bit */
+
+	u32 start;
+        u32 startloop;
+        u32 endloop;
+        u32 end;
+
+	u32 initial_pitch;
+	u32 pitch_target;
+
+	struct voice_param params[2];
+};
+
+struct voice_cntlset
+{
+	u32 paramID;
+	u32 value;
+};
+
+int emu10k1_voice_alloc(struct emu10k1_card *, struct emu_voice *, struct voice_allocdesc *);
+void emu10k1_voice_free(struct emu_voice *);
+void emu10k1_voice_playback_setup(struct emu_voice *);
+void emu10k1_voice_start(struct emu_voice *);
+void emu10k1_voice_stop(struct emu_voice *);
+void emu10k1_voice_setcontrol(struct emu_voice *, struct voice_cntlset *, u32);
+void emu10k1_voice_getcontrol(struct emu_voice *, u32, u32 *);
+
+#endif /* _VOICEMGR_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/es1370.c linux.17p18/drivers/sound/es1370.c
--- linux.vanilla/drivers/sound/es1370.c	Fri Apr 21 12:46:34 2000
+++ linux.17p18/drivers/sound/es1370.c	Tue Aug  8 21:54:31 2000
@@ -1993,7 +1993,7 @@
 		return 0;
 
 	case SNDCTL_DSP_GETOSPACE:
-		if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac1(s)) != 0)
+		if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0)
 			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		es1370_update_ptr(s);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/es1371.c linux.17p18/drivers/sound/es1371.c
--- linux.vanilla/drivers/sound/es1371.c	Fri Apr 21 12:46:34 2000
+++ linux.17p18/drivers/sound/es1371.c	Tue Aug  8 21:54:42 2000
@@ -182,6 +182,7 @@
 #define CT5880REV_CT5880_C  0x02
 #define ES1371REV_ES1371_B  0x09
 #define EV1938REV_EV1938_A  0x00
+#define ES1371REV_ES1373_8  0x08
 
 #define ES1371_MAGIC  ((PCI_VENDOR_ID_ENSONIQ<<16)|PCI_DEVICE_ID_ENSONIQ_ES1371)
 
@@ -2563,7 +2564,7 @@
 		return 0;
 
 	case SNDCTL_DSP_GETOSPACE:
-		if (!(s->ctrl & CTRL_DAC2_EN) && (val = prog_dmabuf_dac1(s)) != 0)
+		if (!(s->ctrl & CTRL_DAC1_EN) && (val = prog_dmabuf_dac1(s)) != 0)
 			return val;
 		spin_lock_irqsave(&s->lock, flags);
 		es1371_update_ptr(s);
@@ -3166,7 +3167,8 @@
 	/* if we are a 5880 turn on the AC97 */
 	if (s->vendor == PCI_VENDOR_ID_ENSONIQ &&
 	    ((s->device == PCI_DEVICE_ID_ENSONIQ_CT5880 && s->rev == CT5880REV_CT5880_C) || 
-	     (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A))) { 
+	     (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_CT5880_A) || 
+	     (s->device == PCI_DEVICE_ID_ENSONIQ_ES1371 && s->rev == ES1371REV_ES1373_8))) { 
 		cssr |= CSTAT_5880_AC97_RST;
 		outl(cssr, s->io+ES1371_REG_STATUS);
 		/* need to delay around 20ms(bleech) to give
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/esssolo1.c linux.17p18/drivers/sound/esssolo1.c
--- linux.vanilla/drivers/sound/esssolo1.c	Fri Apr 21 12:46:34 2000
+++ linux.17p18/drivers/sound/esssolo1.c	Mon Aug 14 16:28:45 2000
@@ -2169,7 +2169,7 @@
 	{ SOUND_MIXER_WRITE_LINE2, 0x4040 },
 	{ SOUND_MIXER_WRITE_RECLEV, 0x4040 },
 	{ SOUND_MIXER_WRITE_SPEAKER, 0x4040 },
-	{ SOUND_MIXER_WRITE_MIC, 0x4040 }
+	{ SOUND_MIXER_WRITE_MIC, 0x0000 }
 };
 
 /*static*/ int __init init_solo1(void)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/i810_audio.c linux.17p18/drivers/sound/i810_audio.c
--- linux.vanilla/drivers/sound/i810_audio.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/sound/i810_audio.c	Tue Aug  8 21:56:44 2000
@@ -14,6 +14,11 @@
  *	Analog Devices (A major AC97 codec maker)
  *	Intel Corp  (you've probably heard of them already)
  *
+ * AC97 clues and assistance provided by
+ *	Analog Devices
+ *	Zach 'Fufu' Brown
+ *	Jeff Garzik
+ *
  *	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
@@ -46,6 +51,18 @@
  *	There is no midi support, no synth support. Use timidity. To get
  *	esd working you need to use esd -r 48000 as it won't probe 48KHz
  *	by default. mpg123 can't handle 48Khz only audio so use xmms.
+ *
+ *	Fix The Sound On Dell
+ *
+ *	Not everyone uses 48KHz. We know of no way to detect this reliably
+ *	and certainly not to get the right data. If your i810 audio sounds
+ *	stupid you may need to investigate other speeds. According to Analog
+ *	they tend to use a 14.318MHz clock which gives you a base rate of
+ *	41194Hz.
+ *
+ *	This is available via the 'ftsodell=1' option. 
+ *
+ *	If you need to force a specific rate set the clocking= option
  */
  
 #include <linux/module.h>
@@ -74,10 +91,16 @@
 #ifndef PCI_DEVICE_ID_INTEL_82901
 #define PCI_DEVICE_ID_INTEL_82901	0x2425
 #endif
+#ifndef PCI_DEVICE_ID_INTEL_ICH2
+#define PCI_DEVICE_ID_INTEL_ICH2	0x2445
+#endif
 #ifndef PCI_DEVICE_ID_INTEL_440MX
 #define PCI_DEVICE_ID_INTEL_440MX	0x7195
 #endif
 
+static int ftsodell=0;
+static int clocking=48000;
+
 #define ADC_RUNNING	1
 #define DAC_RUNNING	2
 
@@ -158,7 +181,7 @@
 #define INT_MASK (INT_SEC|INT_PRI|INT_MC|INT_PO|INT_PI|INT_MO|INT_NI|INT_GPI)
 
 
-#define DRIVER_VERSION "0.02"
+#define DRIVER_VERSION "0.17"
 
 /* magic numbers to protect our data structures */
 #define I810_CARD_MAGIC		0x5072696E /* "Prin" */
@@ -180,7 +203,8 @@
 enum {
 	ICH82801AA = 0,
 	ICH82901AB,
-	INTEL440MX
+	INTEL440MX,
+	INTELICH2
 };
 
 /* "software" or virtual channel, an instance of opened /dev/dsp */
@@ -327,7 +351,7 @@
 	card->channel[0].used=1;
 	card->channel[0].offset = 0;
 	card->channel[0].port = 0x00;
-	card->channel[1].num=0;
+	card->channel[0].num=0;
 	return &card->channel[0];
 }
 
@@ -340,20 +364,32 @@
 static unsigned int i810_set_dac_rate(struct i810_state * state, unsigned int rate)
 {	
 	struct dmabuf *dmabuf = &state->dmabuf;
-	u16 dacp, rp;
+	u32 dacp, rp;
 	struct ac97_codec *codec=state->card->ac97_codec[0];
 	
 	if(!(state->card->ac97_features&0x0001))
 	{
-		dmabuf->rate=48000;
-		return 48000;
+		dmabuf->rate=clocking;
+		return clocking;
 	}
 			
 	if (rate > 48000)
 		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
-
+	if (rate < 8000)
+		rate = 8000;
+	
+	/*
+	 *	Adjust for misclocked crap
+	 */
+	 
+	rate = ( rate * clocking)/48000;
+	
+	/* Analog codecs can go lower via magic registers but others
+	   might not */
+	   
+	if(rate < 8000)
+		rate = 8000;
+		
 	/* Power down the DAC */
 	dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
 	i810_ac97_set(codec, AC97_POWER_CONTROL, dacp|0x0200);
@@ -362,11 +398,8 @@
 	i810_ac97_set(codec, AC97_PCM_FRONT_DAC_RATE, rate);
 	rp=i810_ac97_get(codec, AC97_PCM_FRONT_DAC_RATE);
 	
-//	printk("DAC rate set to %d Returned %d\n", 
-//		rate, (int)rp);
-		
-	rate=rp;
-		
+	rate=(rp*48000) / clocking;
+	
 	/* Power it back up */
 	i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
 	
@@ -382,19 +415,31 @@
 static unsigned int i810_set_adc_rate(struct i810_state * state, unsigned int rate)
 {
 	struct dmabuf *dmabuf = &state->dmabuf;
-	u16 dacp, rp;
+	u32 dacp, rp;
 	struct ac97_codec *codec=state->card->ac97_codec[0];
 	
 	if(!(state->card->ac97_features&0x0001))
 	{
-		dmabuf->rate = 48000;
-		return 48000;
+		dmabuf->rate = clocking;
+		return clocking;
 	}
 			
 	if (rate > 48000)
 		rate = 48000;
-	if (rate < 4000)
-		rate = 4000;
+	if (rate < 8000)
+		rate = 8000;
+
+	/*
+	 *	Adjust for misclocked crap
+	 */
+	 
+	rate = ( rate * clocking)/48000;
+	
+	/* Analog codecs can go lower via magic registers but others
+	   might not */
+	   
+	if(rate < 8000)
+		rate = 8000;
 
 	/* Power down the ADC */
 	dacp=i810_ac97_get(codec, AC97_POWER_CONTROL);
@@ -407,7 +452,7 @@
 //	printk("ADC rate set to %d Returned %d\n", 
 //		rate, (int)rp);
 		
-	rate=rp;
+	rate = (rp * 48000) / clocking;
 		
 	/* Power it back up */
 	i810_ac97_set(codec, AC97_POWER_CONTROL, dacp);
@@ -676,6 +721,9 @@
 	outl(virt_to_bus(&dmabuf->channel->sg[0]), state->card->iobase+dmabuf->channel->port+OFF_BDBAR);
 	outb(16, state->card->iobase+dmabuf->channel->port+OFF_LVI);
 	outb(0, state->card->iobase+dmabuf->channel->port+OFF_CIV);
+	
+	resync_dma_ptrs(state);
+	
 	if (rec) {
 		i810_rec_setup(state);
 	} else {
@@ -696,44 +744,6 @@
 	return 0;
 }
 
-/* we are doing quantum mechanics here, the buffer can only be empty, half or full filled i.e.
-   |------------|------------|   or   |xxxxxxxxxxxx|------------|   or   |xxxxxxxxxxxx|xxxxxxxxxxxx|
-   but we almost always get this
-   |xxxxxx------|------------|   or   |xxxxxxxxxxxx|xxxxx-------|
-   so we have to clear the tail space to "silence"
-   |xxxxxx000000|------------|   or   |xxxxxxxxxxxx|xxxxxx000000|
-*/
-static void i810_clear_tail(struct i810_state *state)
-{
-	struct dmabuf *dmabuf = &state->dmabuf;
-	unsigned swptr;
-	unsigned char silence = (dmabuf->fmt & I810_FMT_16BIT) ? 0 : 0x80;
-	unsigned int len;
-	unsigned long flags;
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	swptr = dmabuf->swptr;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	if (swptr == 0 || swptr == dmabuf->dmasize / 2 || swptr == dmabuf->dmasize)
-		return;
-
-	if (swptr < dmabuf->dmasize/2)
-		len = dmabuf->dmasize/2 - swptr;
-	else
-		len = dmabuf->dmasize - swptr;
-
-	memset(dmabuf->rawbuf + swptr, silence, len);
-
-	spin_lock_irqsave(&state->card->lock, flags);
-	dmabuf->swptr += len;
-	dmabuf->count += len;
-	spin_unlock_irqrestore(&state->card->lock, flags);
-
-	/* restart the dma machine in case it is halted */
-	start_dac(state);
-}
-
 static int drain_dac(struct i810_state *state, int nonblock)
 {
 	struct wait_queue wait = {current, NULL};
@@ -1251,8 +1261,6 @@
 
 	case SNDCTL_DSP_STEREO: /* set stereo or mono channel */
 		get_user_ret(val, (int *)arg, -EFAULT);
-		if(val==0)
-			return -EINVAL;
 		if (file->f_mode & FMODE_WRITE) {
 			stop_dac(state);
 			dmabuf->ready = 0;
@@ -1263,6 +1271,7 @@
 			dmabuf->ready = 0;
 			dmabuf->fmt = I810_FMT_STEREO;
 		}
+		put_user(1, (int *)arg);
 		return 0;
 
 	case SNDCTL_DSP_GETBLKSIZE:
@@ -1516,7 +1525,7 @@
 		dmabuf->ossfragshift = 0;
 		dmabuf->ossmaxfrags  = 0;
 		dmabuf->subdivision  = 0;
-		i810_set_dac_rate(state, 48000);
+		i810_set_dac_rate(state, 8000);
 	}
 
 	if (file->f_mode & FMODE_READ) {
@@ -1525,7 +1534,7 @@
 		dmabuf->ossfragshift = 0;
 		dmabuf->ossmaxfrags  = 0;
 		dmabuf->subdivision  = 0;
-		i810_set_adc_rate(state, 48000);
+		i810_set_adc_rate(state, 8000);
 	}
 
 	state->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
@@ -1540,12 +1549,6 @@
 	struct i810_state *state = (struct i810_state *)file->private_data;
 	struct dmabuf *dmabuf = &state->dmabuf;
 
-	if (file->f_mode & FMODE_WRITE) {
-		/* FIXME :.. */
-		i810_clear_tail(state);
-		drain_dac(state, file->f_flags & O_NONBLOCK);
-	}
-
 	/* stop DMA state machine and free DMA buffers/channels */
 	down(&state->open_sem);
 
@@ -1560,13 +1563,12 @@
 		state->card->free_pcm_channel(state->card, dmabuf->channel->num);
 	}
 
-	kfree(state->card->states[state->virt]);
-	state->card->states[state->virt] = NULL;
 	state->open_mode &= (~file->f_mode) & (FMODE_READ|FMODE_WRITE);
 
 	/* we're covered by the open_sem */
 	up(&state->open_sem);
-
+	kfree(state->card->states[state->virt]);
+	state->card->states[state->virt] = NULL;
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -1587,20 +1589,35 @@
 static u16 i810_ac97_get(struct ac97_codec *dev, u8 reg)
 {
 	struct i810_card *card = dev->private_data;
-	int count = 100;
+	int count = 1000;
 
+	while(count-- && (inl(card->iobase + GLOB_STA) & 0x0100))
+		udelay(10);
+	if(!count)
+		printk("i810_audio: AC97 access failed.\n");
+	count=1000;
 	while(count-- && (inb(card->iobase + CAS) & 1)) 
-		udelay(1);
+		udelay(10);
+	if(!count)
+		printk("i810_audio: AC97 access failed.\n");
 	return inw(card->ac97base + (reg&0x7f));
 }
 
 static void i810_ac97_set(struct ac97_codec *dev, u8 reg, u16 data)
 {
 	struct i810_card *card = dev->private_data;
-	int count = 100;
+	int count = 1000;
+
+	while(count-- && (inl(card->iobase + GLOB_STA) & 0x0100))
+		udelay(10);
+	if(!count)
+		printk("i810_audio: AC97 write access failed.\n");
 
+	count=1000;
 	while(count-- && (inb(card->iobase + CAS) & 1)) 
-		udelay(1);
+		udelay(10);
+	if(!count)
+		printk("i810_audio: AC97 write access failed.\n");
 	outw(data, card->ac97base + (reg&0x7f));
 }
 
@@ -1657,10 +1674,28 @@
 	int ready_2nd = 0;
 	struct ac97_codec *codec;
 	u16 eid;
+	int i=0;
 
-	outl(0, card->iobase + GLOB_CNT);
-	udelay(500);
-	outl(1<<1, card->iobase + GLOB_CNT);
+
+	outl(6 , card->iobase + GLOB_CNT);
+	while(i<10)
+	{
+		if((inl(card->iobase+GLOB_CNT)&4)==0)
+			break;
+		current->state = TASK_UNINTERRUPTIBLE;
+		schedule_timeout(HZ/20);
+		i++;
+	}
+	if(i==10)
+	{
+		printk(KERN_ERR "i810_audio: AC'97 reset failed.\n");
+		return 0;
+	}
+	
+	current->state = TASK_UNINTERRUPTIBLE;
+	schedule_timeout(HZ/5);
+		
+	inw(card->ac97base);
 
 	for (num_ac97 = 0; num_ac97 < NR_AC97; num_ac97++) {
 		if ((codec = kmalloc(sizeof(struct ac97_codec), GFP_KERNEL)) == NULL)
@@ -1692,9 +1727,17 @@
 		if(!(eid&0x0001))
 			printk(KERN_WARNING "i810_audio: only 48Khz playback available.\n");
 		else
+		{
 			/* Enable variable rate mode */
-			i810_ac97_set(codec, AC97_EXTENDED_STATUS, 
-				i810_ac97_get(codec,AC97_EXTENDED_STATUS)|1);
+			i810_ac97_set(codec, AC97_EXTENDED_STATUS, 9);
+			i810_ac97_set(codec,AC97_EXTENDED_STATUS,
+				i810_ac97_get(codec, AC97_EXTENDED_STATUS)|0xE800);
+			if(!(i810_ac97_get(codec, AC97_EXTENDED_STATUS)&1))
+			{
+				printk(KERN_WARNING "i810_audio: Codec refused to allow VRA, using 48Khz only.\n");
+				card->ac97_features&=~1;
+			}
+		}
 			
 		if ((codec->dev_mixer = register_sound_mixer(&i810_mixer_fops, -1)) < 0) {
 			printk(KERN_ERR "i810_audio: couldn't register mixer!\n");
@@ -1777,12 +1820,6 @@
 		kfree(card);
 		return -ENODEV;
 	}
-
-//	printk("resetting codec?\n");
-	outl(0, card->iobase + GLOB_CNT);
-	udelay(500);
-//	printk("bringing it back?\n");
-	outl(1<<1, card->iobase + GLOB_CNT);
 	return 0;
 }
 
@@ -1806,6 +1843,8 @@
 
 MODULE_AUTHOR("Assorted");
 MODULE_DESCRIPTION("Intel 810 audio support");
+MODULE_PARM(ftsodell, "i");
+MODULE_PARM(clocking, "i");
 
 int __init i810_probe(void)
 {
@@ -1815,6 +1854,9 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
 
+	if(ftsodell==1)
+		clocking=41194;
+		
 	printk(KERN_INFO "Intel 810 + AC97 Audio, version "
 	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
 
@@ -1828,6 +1870,11 @@
 	}
 	while( (pcidev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_440MX, pcidev))!=NULL ) {
 		if (i810_install(pcidev, INTEL440MX, "Intel 440MX")==0)
+			foundone++;
+	}
+
+	while( (pcidev = pci_find_device(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_ICH2, pcidev))!=NULL ) {
+		if (i810_install(pcidev, INTELICH2, "Intel ICH2")==0)
 			foundone++;
 	}
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/maestro.c linux.17p18/drivers/sound/maestro.c
--- linux.vanilla/drivers/sound/maestro.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/sound/maestro.c	Tue Aug  8 21:55:08 2000
@@ -3476,7 +3476,7 @@
 #ifdef MODULE
 int init_module(void)
 #else
-int SILLY_MAKE_INIT(init_maestro(void))
+SILLY_MAKE_INIT(int init_maestro(void))
 #endif
 {
 	struct pci_dev *pcidev = NULL;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/sb_ess.c linux.17p18/drivers/sound/sb_ess.c
--- linux.vanilla/drivers/sound/sb_ess.c	Fri Apr 21 12:46:36 2000
+++ linux.17p18/drivers/sound/sb_ess.c	Wed Aug  9 22:22:50 2000
@@ -1215,6 +1215,12 @@
 	/* FKS: sb_dsp_reset to enable extended mode???? */
 	sb_dsp_reset(devc); /* Turn on extended mode */
 
+	/* Disable audio 2 data if boot from another OS w/o HW reset */
+	if (devc->submodel == SUBMDL_ES1879)
+	{
+		ess_setmixer(devc, 0x71, 0x00);
+	}   
+                       
 	/*
 	 *  Enable joystick and OPL3
 	 */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/sound_core.c linux.17p18/drivers/sound/sound_core.c
--- linux.vanilla/drivers/sound/sound_core.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/sound/sound_core.c	Mon Aug 14 18:50:46 2000
@@ -80,7 +80,13 @@
 extern int init_solo1(void);
 #endif
 #ifdef CONFIG_SOUND_YMPCI
-extern init_ymf7xxsb_module();
+extern int init_ymf7xxsb_module(void);
+#endif
+#ifdef CONFIG_SOUND_FUSION
+extern int cs_probe(void);
+#endif
+#ifdef CONFIG_SOUND_EMU10K1
+extern int init_emu10k1(void);
 #endif
 
 /*
@@ -442,6 +448,15 @@
 #endif
 #ifdef CONFIG_SOUND_YMPCI
 	init_ymf7xxsb_module();
+#endif
+#ifdef CONFIG_SOUND_FUSION
+	cs_probe();
+#endif
+#ifdef CONFIG_SOUND_CS4281
+	cs4281_probe();
+#endif
+#ifdef CONFIG_SOUND_EMU10K1
+	init_emu10k1();
 #endif
 	return 0;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/trident.c linux.17p18/drivers/sound/trident.c
--- linux.vanilla/drivers/sound/trident.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/sound/trident.c	Mon Aug 14 13:09:41 2000
@@ -1,6 +1,6 @@
 /*
  *
- *	Trident 4D-Wave/SiS 7018 OSS driver for Linux 2.2.x
+ *	Trident 4D-Wave/SiS 7018/ALi 5451 OSS driver for Linux 2.2.x
  *
  *	Driver: Alan Cox <alan@redhat.com>
  *
@@ -12,6 +12,7 @@
  *  Hacked up by:
  *	Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
  *	Ollie Lho <ollie@sis.com.tw> SiS 7018 Audio Core Support
+ *	Ching Ling Lee <cling-li@ali.com.tw> ALi 5451 Audio Core Support 
  *
  *
  *	This program is free software; you can redistribute it and/or modify
@@ -112,9 +113,11 @@
 #include <asm/hardirq.h>
 #include <linux/bitops.h>
 
+#include "dm.h"
+
 #include "trident.h"
 
-#define DRIVER_VERSION "0.14.5"
+#define DRIVER_VERSION "0.14.6a"
 
 /* magic numbers to protect our data structures */
 #define TRIDENT_CARD_MAGIC	0x5072696E /* "Prin" */
@@ -137,6 +140,10 @@
 /* minor number of /dev/swmodem (temporary, experimental) */
 #define SND_DEV_SWMODEM	7
 
+/* Size of the MIDI buffer */
+#define MIDIINBUF	256
+#define MIDIOUTBUF	256
+
 static const unsigned sample_size[] = { 1, 2, 2, 4 };
 static const unsigned sample_shift[] = { 0, 1, 1, 2 };
 
@@ -155,6 +162,15 @@
 	{PCI_VENDOR_ID_ALI, PCI_DEVICE_ID_ALI_5451, "ALi Audio Accelerator"}
 };
 
+struct midi_stuff{
+	unsigned ird, iwr, icnt;
+	unsigned ord, owr, ocnt;
+	struct wait_queue *iwait;
+	struct wait_queue *owait;
+	unsigned char ibuf[MIDIINBUF];
+	unsigned char obuf[MIDIOUTBUF];
+};
+
 /* "software" or virtual channel, an instance of opened /dev/dsp */
 struct trident_state {
 	unsigned int magic;
@@ -266,15 +282,24 @@
 
 	/* soundcore stuff */
 	int dev_audio;
-
+	int dev_midi;
+	int dev_dmfm;
+	
+	/* Device locks */
+	int midi_on;
+	int dmfm_on;
+	
 	/* structures for abstraction of hardware facilities, codecs, banks and channels*/
 	struct ac97_codec *ac97_codec[NR_AC97];
 	struct trident_pcm_bank banks[NR_BANKS];
 	struct trident_state *states[NR_HW_CH];
+	struct midi_stuff midi;
 
 	/* hardware resources */
 	unsigned long iobase;
 	u32 irq;
+	unsigned long midi_io;
+	unsigned long synth_io;
 	
 	/* Function support */
 	struct trident_channel *(*alloc_pcm_channel)(struct trident_card *);
@@ -1268,6 +1293,35 @@
 
 }
 
+static void trident_handle_midi(struct trident_card *card)
+{
+	unsigned char ch;
+	int wake = 0;
+
+	while (!(inb(card->iobase + ALI_MPUR1) & 0x80)) {	
+		ch = inb(card->iobase + ALI_MPUR0);
+		if (card->midi.icnt < MIDIINBUF) {
+			card->midi.ibuf[card->midi.iwr] = ch;
+			card->midi.iwr = (card->midi.iwr + 1) % MIDIINBUF;
+			card->midi.icnt++;
+		}
+		wake = 1;
+	}
+	if (wake)
+		wake_up(&card->midi.iwait);
+	wake = 0;
+	while (!(inb(card->iobase + ALI_MPUR1) & 0x40) && card->midi.ocnt > 0) {
+		inb(card->iobase + ALI_MPUR0);
+		outb(card->midi.obuf[card->midi.ord], card->iobase + ALI_MPUR0);
+		card->midi.ord = (card->midi.ord + 1) % MIDIOUTBUF;
+		card->midi.ocnt--;
+		if (card->midi.ocnt < MIDIOUTBUF-16)
+			wake = 1;
+	}
+	if (wake)
+		wake_up(&card->midi.owait);
+}
+
 static void trident_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct trident_card *card = (struct trident_card *)dev_id;
@@ -1283,7 +1337,11 @@
 	if (event & ADDRESS_IRQ) {
 		card->address_interrupt(card);
 	}
-
+	
+	if(event & MPU401_IRQ) {
+		if(card->midi_on)
+			trident_handle_midi(card);
+	}
 	/* manually clear interrupt status, bad hardware design, blame T^2 */
 	outl((ST_TARGET_REACHED | MIXER_OVERFLOW | MIXER_UNDERFLOW),
 	     TRID_REG(card, T4D_MISCINT));
@@ -2017,6 +2075,385 @@
 	release:	trident_release,
 };
 
+/* --------------------------------------------------------------------- */
+
+/*
+ *	MIDI and direct synth support for the ALI 5451. These functions
+ *	are taken directly from Ching Ling Lee's original ALI only
+ *	driver.
+ */
+ 
+static ssize_t trident_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned ptr;
+	int cnt;
+	struct midi_stuff *midi;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+		
+	midi = &card->midi;
+	
+	ret = 0;
+	while (count > 0) {
+		spin_lock_irqsave(&card->lock, flags);
+		ptr = midi->ird;
+		cnt = MIDIINBUF - ptr;
+		if (midi->icnt < cnt)
+			cnt = midi->icnt;
+		spin_unlock_irqrestore(&card->lock, flags);
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : EAGAIN;
+			interruptible_sleep_on(&midi->iwait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		if (copy_to_user(buffer, midi->ibuf + ptr, cnt))
+			return ret ? ret : -EFAULT;
+		ptr = (ptr + cnt) % MIDIINBUF;
+		spin_lock_irqsave(&card->lock, flags);
+		midi->ird = ptr;
+		midi->icnt -= cnt;
+		spin_unlock_irqrestore(&card->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+	}
+	return ret;
+}
+
+static ssize_t trident_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+	ssize_t ret;
+	unsigned long flags;
+	unsigned ptr;
+	int cnt;
+	struct midi_stuff *midi;
+
+	if (ppos != &file->f_pos)
+		return -ESPIPE;
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+		
+	midi = &card->midi;
+	
+	ret = 0;
+	while (count > 0) {
+		spin_lock_irqsave(&card->lock, flags);
+		ptr = midi->owr;
+		cnt = MIDIOUTBUF - ptr;
+		if (midi->ocnt + cnt > MIDIOUTBUF)
+			cnt = MIDIOUTBUF - midi->ocnt;
+		if (cnt <= 0)
+			trident_handle_midi(card);
+		spin_unlock_irqrestore(&card->lock, flags);
+		if (cnt > count)
+			cnt = count;
+		if (cnt <= 0) {
+			if (file->f_flags & O_NONBLOCK)
+				return ret ? ret : -EAGAIN;
+			interruptible_sleep_on(&midi->owait);
+			if (signal_pending(current))
+				return ret ? ret : -ERESTARTSYS;
+			continue;
+		}
+		if (copy_from_user(midi->obuf + ptr, buffer, cnt))
+			return ret ? ret : -EFAULT;
+		ptr = (ptr + cnt) % MIDIOUTBUF;
+		spin_lock_irqsave(&card->lock, flags);
+		midi->owr = ptr;
+		midi->ocnt += cnt;
+		spin_unlock_irqrestore(&card->lock, flags);
+		count -= cnt;
+		buffer += cnt;
+		ret += cnt;
+		spin_lock_irqsave(&card->lock, flags);
+		trident_handle_midi(card);
+		spin_unlock_irqrestore(&card->lock, flags);
+	}
+	return ret;
+}
+
+
+static unsigned int trident_midi_poll(struct file *file, struct poll_table_struct *wait)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	if (file->f_flags & FMODE_WRITE)
+		poll_wait(file, &card->midi.owait, wait);
+	if (file->f_flags & FMODE_READ)
+		poll_wait(file, &card->midi.iwait, wait);
+	spin_lock_irqsave(&card->lock, flags);
+	if (file->f_flags & FMODE_READ) {
+		if (card->midi.icnt > 0)
+			mask |= POLLIN | POLLRDNORM;
+	}
+	if (file->f_flags & FMODE_WRITE) {
+		if (card->midi.ocnt < MIDIOUTBUF)
+			mask |= POLLOUT | POLLWRNORM;
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+	return mask;
+}
+
+static int trident_midi_open(struct inode *inode, struct file *file)
+{
+	struct trident_card *card = devs;
+	struct midi_stuff *midi;
+	unsigned long flags;
+
+	while(card!=NULL)
+	{
+		if(card->midi_on == 0 && card->dev_midi!=-1)
+			break;
+		card=card->next;
+	}
+	if(card==NULL)
+		return -EBUSY;
+		
+	spin_lock_irqsave(&card->lock, flags);
+	card->midi_on = 1;
+	midi = &card->midi;
+	file->private_data = card;
+	if (file->f_mode & FMODE_READ) {
+		midi->ird = midi->iwr = midi->icnt = 0;
+	}
+	if (file->f_mode & FMODE_WRITE) {
+		midi->ord = midi->owr = midi->ocnt = 0;
+	}
+	spin_unlock_irqrestore(&card->lock, flags);
+	return 0;
+}
+
+static int trident_midi_release(struct inode *inode, struct file *file)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+        struct wait_queue wait = { current, NULL };
+	unsigned long flags;
+	unsigned count, tmo;
+
+	if (file->f_mode & FMODE_WRITE) {
+		current->state = TASK_INTERRUPTIBLE;
+		add_wait_queue(&card->midi.owait, &wait);
+		for (;;) {
+			spin_lock_irqsave(&card->lock, flags);
+			count = card->midi.ocnt;
+			spin_unlock_irqrestore(&card->lock, flags);
+			if (count <= 0)
+				break;
+			if (signal_pending(current))
+				break;
+			if (file->f_flags & O_NONBLOCK) {
+				remove_wait_queue(&card->midi.owait, &wait);
+				current->state = TASK_RUNNING;
+				return -EBUSY;
+			}
+			tmo = (count * HZ) / 3100;
+			if (!schedule_timeout(tmo ? : 1) && tmo)
+				printk(KERN_DEBUG "trident: midi timed out??\n");
+		}
+		remove_wait_queue(&card->midi.owait, &wait);
+		current->state = TASK_RUNNING;
+	}
+	spin_lock_irqsave(&card->lock, flags);
+	outb(0xff, card->iobase + ALI_MPUR1);
+	card->midi_on = 0;
+	spin_unlock_irqrestore(&card->lock, flags);
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static /*const*/ struct file_operations trident_midi_fops = {
+	&trident_llseek,
+	&trident_midi_read,
+	&trident_midi_write,
+	NULL,  /* readdir */
+	&trident_midi_poll,
+	NULL,  /* ioctl */
+	NULL,  /* mmap */
+	&trident_midi_open,
+	NULL,	/* flush */
+	&trident_midi_release,
+	NULL,  /* fsync */
+	NULL,  /* fasync */
+	NULL,  /* check_media_change */
+	NULL,  /* revalidate */
+	NULL,  /* lock */
+};
+
+/* --------------------------------------------------------------------- */
+
+static int trident_dmfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
+{
+	static const unsigned char op_offset[18] = {
+		0x00, 0x01, 0x02, 0x03, 0x04, 0x05,
+		0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D,
+		0x10, 0x11, 0x12, 0x13, 0x14, 0x15
+	};
+	struct trident_card *card = (struct trident_card *)file->private_data;
+	struct dm_fm_voice v;
+	struct dm_fm_note n;
+	struct dm_fm_params p;
+	unsigned int io;
+	unsigned int regb;
+
+	switch (cmd) {		
+	case FM_IOCTL_RESET:
+		for (regb = 0xb0; regb < 0xb9; regb++) {
+			outb(regb, card->synth_io);
+			outb(0, card->synth_io+1);
+			outb(regb, card->synth_io+2);
+			outb(0, card->synth_io+3);
+		}
+		return 0;
+
+	case FM_IOCTL_PLAY_NOTE:
+		if (copy_from_user(&n, (void *)arg, sizeof(n)))
+			return -EFAULT;
+		if (n.voice >= 18)
+			return -EINVAL;
+		if (n.voice >= 9) {
+			regb = n.voice - 9;
+			io = card->synth_io+2;
+		} else {
+			regb = n.voice;
+			io = card->synth_io;
+		}
+		outb(0xa0 + regb, io);
+		outb(n.fnum & 0xff, io+1);
+		outb(0xb0 + regb, io);
+		outb(((n.fnum >> 8) & 3) | ((n.octave & 7) << 2) | ((n.key_on & 1) << 5), io+1);
+		return 0;
+
+	case FM_IOCTL_SET_VOICE:
+		if (copy_from_user(&v, (void *)arg, sizeof(v)))
+			return -EFAULT;
+		if (v.voice >= 18)
+			return -EINVAL;
+		regb = op_offset[v.voice];
+		io = card->synth_io + ((v.op & 1) << 1);
+		outb(0x20 + regb, io);
+		outb(((v.am & 1) << 7) | ((v.vibrato & 1) << 6) | ((v.do_sustain & 1) << 5) | 
+		     ((v.kbd_scale & 1) << 4) | (v.harmonic & 0xf), io+1);
+		outb(0x40 + regb, io);
+		outb(((v.scale_level & 0x3) << 6) | (v.volume & 0x3f), io+1);
+		outb(0x60 + regb, io);
+		outb(((v.attack & 0xf) << 4) | (v.decay & 0xf), io+1);
+		outb(0x80 + regb, io);
+		outb(((v.sustain & 0xf) << 4) | (v.release & 0xf), io+1);
+		outb(0xe0 + regb, io);
+		outb(v.waveform & 0x7, io+1);
+		if (n.voice >= 9) {
+			regb = n.voice - 9;
+			io = card->synth_io+2;
+		} else {
+			regb = n.voice;
+			io = card->synth_io;
+		}
+		outb(0xc0 + regb, io);
+		outb(((v.right & 1) << 5) | ((v.left & 1) << 4) | ((v.feedback & 7) << 1) |
+		     (v.connection & 1), io+1);
+		return 0;
+		
+	case FM_IOCTL_SET_PARAMS:
+		if (copy_from_user(&p, (void *)arg, sizeof(p)))
+			return -EFAULT;
+		outb(0x08, card->synth_io);
+		outb((p.kbd_split & 1) << 6, card->synth_io+1);
+		outb(0xbd, card->synth_io);
+		outb(((p.am_depth & 1) << 7) | ((p.vib_depth & 1) << 6) | ((p.rhythm & 1) << 5) | ((p.bass & 1) << 4) |
+		     ((p.snare & 1) << 3) | ((p.tomtom & 1) << 2) | ((p.cymbal & 1) << 1) | (p.hihat & 1), card->synth_io+1);
+		return 0;
+
+	case FM_IOCTL_SET_OPL:
+		outb(4, card->synth_io+2);
+		outb(arg, card->synth_io+3);
+		return 0;
+
+	case FM_IOCTL_SET_MODE:
+		outb(5, card->synth_io+2);
+		outb(arg & 1, card->synth_io+3);
+		return 0;
+
+	default:
+		return -EINVAL;
+	}
+}
+
+static int trident_dmfm_open(struct inode *inode, struct file *file)
+{
+	struct trident_card *card = devs;
+
+	file->private_data = card;
+	while(card!=NULL)
+	{
+		if(card->midi_on == 0 && card->dev_midi!=-1)
+			break;
+		card=card->next;
+	}
+	if(card==NULL)
+		return -EBUSY;
+	MOD_INC_USE_COUNT;		
+	card->dmfm_on = 1;
+
+	/* init the stuff */
+	outb(1, card->synth_io);
+	outb(0x20, card->synth_io+1); /* enable waveforms */
+	outb(4, card->synth_io+2);
+	outb(0, card->synth_io+3);  /* no 4op enabled */
+	outb(5, card->synth_io+2);
+	outb(1, card->synth_io+3);  /* enable OPL3 */
+	return 0;
+}
+
+static int trident_dmfm_release(struct inode *inode, struct file *file)
+{
+	struct trident_card *card = (struct trident_card *)file->private_data;
+	unsigned int regb;
+
+	for (regb = 0xb0; regb < 0xb9; regb++) {
+		outb(regb, card->synth_io);
+		outb(0, card->synth_io+1);
+		outb(regb, card->synth_io+2);
+		outb(0, card->synth_io+3);
+	}
+	card->dmfm_on = 0;
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+static /*const*/ struct file_operations trident_dmfm_fops = {
+	&trident_llseek,
+	NULL,  /* read */
+	NULL,  /* write */
+	NULL,  /* readdir */
+	NULL,  /* poll */
+	&trident_dmfm_ioctl,
+	NULL,  /* mmap */
+	&trident_dmfm_open,
+	NULL,	/* fl600
+	ush */
+	&trident_dmfm_release,
+	NULL,  /* fsync */
+	NULL,  /* fasync */
+	NULL,  /* check_media_change */
+	NULL,  /* revalidate */
+	NULL,  /* lock */
+};
+
+
 /* trident specific AC97 functions */
 /* Write AC97 codec registers */
 static void trident_ac97_set(struct ac97_codec *codec, u8 reg, u16 val)
@@ -2370,6 +2807,8 @@
 	memset(card, 0, sizeof(*card));
 
 	card->iobase = iobase;
+	card->midi_io = iobase + 0x20;
+	card->synth_io = iobase + 0x10;
 	card->pci_info = pci_info;
 	card->pci_id = pci_info->device;
 	card->irq = pci_dev->irq;
@@ -2423,6 +2862,31 @@
 		kfree(card);
 		return -ENODEV;
 	}
+	
+	if ((card->dev_midi = register_sound_midi(&trident_midi_fops, -1))<0)
+		printk(KERN_WARNING "trident: Unable to register midi.\n");
+	else
+	{
+		struct midi_stuff *midi = &card->midi;
+		init_waitqueue(&midi->iwait);
+		init_waitqueue(&midi->owait);
+		midi->ird = midi->iwr = midi->icnt = 0;
+		midi->ord = midi->owr = midi->ocnt = 0;
+		outb(0xbc, card->iobase+ALI_MPUR2);
+		
+		/* reset command */
+		while (inb(card->iobase + ALI_MPUR1) & 0x40);
+		outb(0xff, card->iobase + ALI_MPUR1);
+		while (inb(card->iobase + ALI_MPUR1) & 0x80);
+		while ((inb(card->iobase + ALI_MPUR0) != 0xfe) && (inb(card->iobase+ALI_MPUR1) != 0x10)) 
+			while (inb(card->iobase + ALI_MPUR1) & 0x80);
+			
+		midi->ird = midi->iwr = midi->icnt = 0;
+	}
+		
+	if ((card->dev_dmfm = register_sound_special(&trident_dmfm_fops, 15))<0)
+		printk(KERN_WARNING "trident: Unable to register FM.\n");
+	
 	outl(0x00, TRID_REG(card, T4D_MUSICVOL_WAVEVOL));
 
 	if (card->pci_id == PCI_DEVICE_ID_ALI_5451) {
@@ -2454,7 +2918,7 @@
 	if (!pci_present())   /* No PCI bus in this machine! */
 		return -ENODEV;
  
-	printk(KERN_INFO "Trident 4DWave/SiS 7018 PCI Audio, version "
+	printk(KERN_INFO "Trident 4DWave/SiS 7018/Ali 5451 PCI Audio, version "
 	       DRIVER_VERSION ", " __TIME__ " " __DATE__ "\n");
  
 	for (i = 0; i < sizeof (pci_audio_devices); i++) {
@@ -2496,6 +2960,10 @@
 				kfree (devs->ac97_codec[i]);
 			}
 		unregister_sound_dsp(devs->dev_audio);
+		if(devs->dev_midi!=-1)
+			unregister_sound_midi(devs->dev_midi);
+		if(devs->dev_dmfm!=-1)
+			unregister_sound_special(devs->dev_dmfm);
  
 		kfree(devs);
 		devs = devs->next;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/trident.h linux.17p18/drivers/sound/trident.h
--- linux.vanilla/drivers/sound/trident.h	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/sound/trident.h	Mon Aug 14 12:55:01 2000
@@ -246,6 +246,13 @@
 	ST_IRQ_EN       = 0x00800000, ACGPIO_IRQ      = 0x01000000
 };
 
+enum ali_mpuports {
+	ALI_MPUR0=0x20,
+	ALI_MPUR1=0x21,
+	ALI_MPUR2=0x22,
+	ALI_MPUR3=0x23
+};
+
 #define TRID_REG( trident, x ) ( (trident) -> iobase + (x) )
 
 #define VALIDATE_MAGIC(FOO,MAG)				\
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/sound/ymf_sb.c linux.17p18/drivers/sound/ymf_sb.c
--- linux.vanilla/drivers/sound/ymf_sb.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/sound/ymf_sb.c	Tue Aug  1 07:59:58 2000
@@ -14,6 +14,8 @@
     * OPL3-compatible FM synthesizer
     * MPU-401 compatible "external" MIDI interface
 
+  and AC'97 mixer of these cards.
+
   -------------------------------------------------------------------------
 
   Revision history
@@ -39,6 +41,23 @@
      in 724hwmcode.h.
    * fixed wrong legacy_io setting on YMF744/YMF754 .
 
+   Sat Jun  3 23:44:08 2000   0.0.5
+
+   * correct all return value -1 to appropriate -E* value.
+   * add pci_enable_device() for linux-2.3.x.
+
+   Sat Jun  7 00:17:32 2000   0.1.0
+
+   * Remove SBPro mixer support.
+   * Added AC'97 mixer support and remove option 'master_volume'.
+   * Correct all separated valuables into struct ymf_cards.
+
+   Mon Jun 12 21:36:50 2000   0.1.1
+
+   * Invalid dma setting fixed.
+     -- John A. Boyd Jr. <jaboydjr@netwalk.com>
+
+   * ymfsb only compiled as module: fixed
  */
 
 #include <linux/module.h>
@@ -55,40 +74,39 @@
 #include "sound_config.h"
 #include "soundmodule.h"
 #include "sb.h"
-#include "ac97.h"
-
 #include "724hwmcode.h"
 
+#include "ac97.h"
+
 #undef YMF_DEBUG
-#define SUPPORT_UART401_MIDI 1
 
 /* ---------------------------------------------------------------------- */
 
 #ifndef SOUND_LOCK
-#define SOUND_LOCK do {} while (0)
-#define SOUND_LOCK_END do {} while (0)
+# define SOUND_LOCK do {} while (0)
+# define SOUND_LOCK_END do {} while (0)
 #endif
 
 #ifndef PCI_VENDOR_ID_YAMAHA
-#define PCI_VENDOR_ID_YAMAHA  0x1073
+# define PCI_VENDOR_ID_YAMAHA  0x1073
 #endif
 #ifndef PCI_DEVICE_ID_YMF724
-#define PCI_DEVICE_ID_YMF724  0x0004
+# define PCI_DEVICE_ID_YMF724  0x0004
 #endif
 #ifndef PCI_DEVICE_ID_YMF740
-#define PCI_DEVICE_ID_YMF740  0x000A
+# define PCI_DEVICE_ID_YMF740  0x000A
 #endif
 #ifndef PCI_DEVICE_ID_YMF740C
-#define PCI_DEVICE_ID_YMF740C 0x000C
+# define PCI_DEVICE_ID_YMF740C 0x000C
 #endif
 #ifndef PCI_DEVICE_ID_YMF724F
-#define PCI_DEVICE_ID_YMF724F 0x000D
+# define PCI_DEVICE_ID_YMF724F 0x000D
 #endif
 #ifndef PCI_DEVICE_ID_YMF744
-#define PCI_DEVICE_ID_YMF744  0x0010
+# define PCI_DEVICE_ID_YMF744  0x0010
 #endif
 #ifndef PCI_DEVICE_ID_YMF754
-#define PCI_DEVICE_ID_YMF754  0x0012
+# define PCI_DEVICE_ID_YMF754  0x0012
 #endif
 
 /* ---------------------------------------------------------------------- */
@@ -223,127 +241,97 @@
 
 #define PFX		"ymf_sb: "
 
-#define YMFSB_VERSION	"0.0.4"
+#define YMFSB_VERSION	"0.1.1"
 #define YMFSB_CARD_NAME	"YMF7xx Legacy Audio driver " YMFSB_VERSION
 
-#ifdef SUPPORT_UART401_MIDI
-#if 0
-# define ymf7xxsb_probe_midi probe_uart401
-# define ymf7xxsb_attach_midi attach_uart401
-# define ymf7xxsb_unload_midi unload_uart401
-#else
-# define ymf7xxsb_probe_midi probe_sbmpu
-# define ymf7xxsb_attach_midi attach_sbmpu
-# define ymf7xxsb_unload_midi unload_sbmpu
-#endif
-#endif
+#define ymf7xxsb_probe_midi probe_sbmpu
+#define ymf7xxsb_attach_midi attach_sbmpu
+#define ymf7xxsb_unload_midi unload_sbmpu
 
 /* ---------------------------------------------------------------------- */
 
-static struct address_info	sb_data[MAX_CARDS];
-static struct address_info	opl3_data[MAX_CARDS];
-#ifdef SUPPORT_UART401_MIDI
-static struct address_info	mpu_data[MAX_CARDS];
-#endif
-static unsigned			cards = 0;
-static unsigned short          *ymfbase[MAX_CARDS];
+static struct ymf_card {
+  int                  card;
+  unsigned short      *ymfbase;
+
+  struct address_info sb_data, opl3_data, mpu_data;
+
+  struct ac97_hwint   ac97_dev;
+  int                 mixer_oss_dev;
+} ymf_cards[MAX_CARDS];
+
+static unsigned int cards = 0;
 
 /* ---------------------------------------------------------------------- */
 
 #ifdef MODULE
-#ifdef SUPPORT_UART401_MIDI
-static int mpu_io   = 0;
-#endif
-static int synth_io = 0;
-static int io       = 0;
-static int dma      = 0;
-static int master_vol = -1;
-static int spdif_out = 0;
-#ifdef SUPPORT_UART401_MIDI
+static int mpu_io     = 0;
+static int synth_io   = 0;
+static int io         = 0;
+static int dma        = 0;
+static int spdif_out  = 1;
 MODULE_PARM(mpu_io, "i");
-#endif
 MODULE_PARM(synth_io, "i");
 MODULE_PARM(io,"i");
 MODULE_PARM(dma,"i");
-MODULE_PARM(master_vol,"i");
 MODULE_PARM(spdif_out,"i");
 #else
-#ifdef SUPPORT_UART401_MIDI
 static int mpu_io     = 0x330;
-#endif
 static int synth_io   = 0x388;
 static int io         = 0x220;
 static int dma        = 1;
-static int master_vol = 80;
-static int spdif_out  = 0;
+static int spdif_out  = 1;
 #endif
 
 /* ---------------------------------------------------------------------- */
 
-static int readRegWord( int adr ) {
+static int readRegWord( struct ymf_card *card, int adr ) {
 
-	if (ymfbase[cards]==NULL) return 0;
+	if (card->ymfbase==NULL) return 0;
 
-	return readw(ymfbase[cards]+adr/2);
+	return readw(card->ymfbase+adr/2);
 }
 
-static void writeRegWord( int adr, int val ) {
+static void writeRegWord( struct ymf_card *card, int adr, int val ) {
 
-	if (ymfbase[cards]==NULL) return;
+	if (card->ymfbase==NULL) return;
 
-	writew((unsigned short)(val&0xffff), ymfbase[cards] + adr/2);
+	writew((unsigned short)(val&0xffff), card->ymfbase + adr/2);
 
 	return;
 }
 
-static int readRegDWord( int adr ) {
+static int readRegDWord( struct ymf_card *card, int adr ) {
 
-	if (ymfbase[cards]==NULL) return 0;
+	if (card->ymfbase==NULL) return 0;
 
-	return (readl(ymfbase[cards]+adr/2));
+	return (readl(card->ymfbase+adr/2));
 }
 
-static void writeRegDWord( int adr, int val ) {
+static void writeRegDWord( struct ymf_card *card, int adr, int val ) {
 
-	if (ymfbase[cards]==NULL) return;
+	if (card->ymfbase==NULL) return;
 
-	writel((unsigned int)(val&0xffffffff), ymfbase[cards]+adr/2);
+	writel((unsigned int)(val&0xffffffff), card->ymfbase+adr/2);
 
 	return;
 }
 
 /* ---------------------------------------------------------------------- */
 
-static int checkPrimaryBusy( void )
+static int checkPrimaryBusy( struct ymf_card *card )
 {
 	int timeout=0;
 
 	while ( timeout++ < YMFSB_AC97TIMEOUT )
 	{
-		if ( (readRegWord(YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 )
+		if ( (readRegWord(card, YMFSB_PRISTATUSADR) & 0x8000) == 0x0000 )
 			return 0;
 	}
-	return -1;
+	return -EBUSY;
 }
 
-static int writeAc97( int adr, unsigned short val )
-{
-
-	if ( adr > 0x7f || adr < 0x00 ) return -1;
-
-	if ( checkPrimaryBusy() ) return -1;
-
-#ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "AC97 0x%0x = 0x%0x\n",adr,val);
-#endif
-
-	writeRegWord( YMFSB_AC97CMDADR,  0x0000 | adr );
-	writeRegWord( YMFSB_AC97CMDDATA, val );
-
-	return 0;
-}
-
-static int checkCodec( struct pci_dev *pcidev )
+static int checkCodec( struct ymf_card *card, struct pci_dev *pcidev )
 {
 	u8 tmp8;
 
@@ -357,17 +345,17 @@
 		mdelay(YMFSB_RESET_DELAY);
 	}
 
-	if ( checkPrimaryBusy() ) return -1;
+	if ( checkPrimaryBusy( card ) ) return -EBUSY;
 
 	return 0;
 }
 
-static int setupLegacyIO( struct pci_dev *pcidev )
+static int setupLegacyIO( struct ymf_card *card, struct pci_dev *pcidev )
 {
 	int v;
 	int sbio=0, mpuio=0, oplio=0,dma=0;
 
-	switch(sb_data[cards].io_base) {
+	switch(card->sb_data.io_base) {
 	case 0x220:
 		sbio = 0;
 		break;
@@ -381,15 +369,14 @@
 		sbio = 3;
 		break;
 	default:
-		return -1;
+		return -EINVAL;
 		break;
 	}
 #ifdef YMF_DEBUG
-	printk(PFX "set SBPro I/O at 0x%x\n",sb_data[cards].io_base);
+	printk(PFX "set SBPro I/O at 0x%x\n",card->sb_data.io_base);
 #endif
 
-#ifdef SUPPORT_UART401_MIDI
-	switch(mpu_data[cards].io_base) {
+	switch(card->mpu_data.io_base) {
 	case 0x330:
 		mpuio = 0;
 		break;
@@ -406,12 +393,11 @@
 		mpuio = 0;
 		break;
 	}
-# ifdef YMF_DEBUG
-	printk(PFX "set MPU401 I/O at 0x%x\n",mpu_data[cards].io_base);
-# endif
+#ifdef YMF_DEBUG
+	printk(PFX "set MPU401 I/O at 0x%x\n",card->mpu_data.io_base);
 #endif
 
-	switch(opl3_data[cards].io_base) {
+	switch(card->opl3_data.io_base) {
 	case 0x388:
 		oplio = 0;
 		break;
@@ -425,19 +411,19 @@
 		oplio = 3;
 		break;
 	default:
-		return -1;
+		return -EINVAL;
 		break;
 	}
 #ifdef YMF_DEBUG
-	printk(PFX "set OPL3 I/O at 0x%x\n",opl3_data[cards].io_base);
+	printk(PFX "set OPL3 I/O at 0x%x\n",card->opl3_data.io_base);
 #endif
 
-	dma = sb_data[cards].dma;
+	dma = card->sb_data.dma;
 #ifdef YMF_DEBUG
-	printk(PFX "set DMA address at 0x%x\n",sb_data[cards].dma);
+	printk(PFX "set DMA address at 0x%x\n",card->sb_data.dma);
 #endif
 
-	v = 0x0000 | ((dma<<6)&0x03) | 0x003f;
+	v = 0x0000 | ((dma&0x03)<<6) | 0x003f;
 	pci_write_config_word(pcidev, YMFSB_PCIR_LEGCTRL, v);
 #ifdef YMF_DEBUG
 	printk(PFX "LEGCTRL: 0x%x\n",v);
@@ -458,16 +444,14 @@
 	case PCI_DEVICE_ID_YMF754:
 		v = 0x8800;
 		pci_write_config_word(pcidev, YMFSB_PCIR_ELEGCTRL, v);
-		pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, opl3_data[cards].io_base);
-		pci_write_config_word(pcidev, YMFSB_PCIR_SBADR,  sb_data[cards].io_base);
-#ifdef SUPPORT_UART401_MIDI
-		pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, mpu_data[cards].io_base);
-#endif
+		pci_write_config_word(pcidev, YMFSB_PCIR_OPLADR, card->opl3_data.io_base);
+		pci_write_config_word(pcidev, YMFSB_PCIR_SBADR,  card->sb_data.io_base);
+		pci_write_config_word(pcidev, YMFSB_PCIR_MPUADR, card->mpu_data.io_base);
 		break;
 
 	default:
 		printk(KERN_ERR PFX "Invalid device ID: %d\n",pcidev->device);
-		return -1;
+		return -EINVAL;
 		break;
 	}
 
@@ -475,56 +459,169 @@
 }
 
 /* ---------------------------------------------------------------------- */
+/* AC'97 stuff */
+static int ymfsb_readAC97Reg( struct ac97_hwint *dev, u8 reg )
+{
+	struct ymf_card *card = (struct ymf_card *)dev->driver_private;
+	unsigned long flags;
+	int ret;
+
+	if ( reg > 0x7f ) return -EINVAL;
+
+	save_flags(flags);
+	cli();
+	writeRegWord( card, YMFSB_AC97CMDADR, 0x8000 | reg );
+	if ( checkPrimaryBusy( card ) ) {
+		restore_flags(flags);
+		return -EBUSY;
+	}
+	ret = readRegWord( card, YMFSB_AC97CMDDATA );
+	restore_flags(flags);
+
+	return ret;
+}
+
+static int ymfsb_writeAC97Reg( struct ac97_hwint *dev, u8 reg, u16 value )
+{
+	struct ymf_card *card = (struct ymf_card *)dev->driver_private;
+	unsigned long flags;
+
+	if ( reg > 0x7f ) return -EINVAL;
+
+	save_flags(flags);
+	cli();
+	if ( checkPrimaryBusy( card ) ) {
+	  restore_flags(flags);
+	  return -EBUSY;
+	}
+
+	writeRegWord( card, YMFSB_AC97CMDADR, 0x0000 | reg );
+	writeRegWord( card, YMFSB_AC97CMDDATA, value );
+
+	restore_flags(flags);
+	return 0;
+}
+
+struct initialValues
+{
+    unsigned short port;
+    unsigned short value;
+};
+
+static struct initialValues ymfsb_ac97_initial_values[] =
+{
+    { AC97_RESET,             0x0000 },
+    { AC97_MASTER_VOL_STEREO, 0x0000 },
+    { AC97_HEADPHONE_VOL,     0x8000 },
+    { AC97_PCMOUT_VOL,        0x0606 },
+    { AC97_MASTER_VOL_MONO,   0x0000 },
+    { AC97_PCBEEP_VOL,        0x0000 },
+    { AC97_PHONE_VOL,         0x0008 },
+    { AC97_MIC_VOL,           0x8000 },
+    { AC97_LINEIN_VOL,        0x8808 },
+    { AC97_CD_VOL,            0x8808 },
+    { AC97_VIDEO_VOL,         0x8808 },
+    { AC97_AUX_VOL,           0x8808 },
+    { AC97_RECORD_SELECT,     0x0000 },
+    { AC97_RECORD_GAIN,       0x0B0B },
+    { AC97_GENERAL_PURPOSE,   0x0000 },
+    { 0xffff, 0xffff }
+};
+
+static int ymfsb_resetAC97( struct ac97_hwint *dev )
+{
+	int i;
+
+	for ( i=0 ; ymfsb_ac97_initial_values[i].port != 0xffff ; i++ )
+	{
+		ac97_put_register ( dev,
+				    ymfsb_ac97_initial_values[i].port,
+				    ymfsb_ac97_initial_values[i].value );
+	}
+
+	return 0;
+}
+
+static int ymfsb_ac97_mixer_ioctl( int dev, unsigned int cmd, caddr_t arg )
+{
+	int i;
+
+	for ( i=0 ; i < MAX_CARDS ; i++ )
+	{
+		if ( ymf_cards[i].mixer_oss_dev == dev ) break;
+	}
+
+	if ( i < MAX_CARDS )
+		return ac97_mixer_ioctl(&(ymf_cards[i].ac97_dev), cmd, arg);
+	else
+		return -ENODEV;
+}
+
+static struct mixer_operations ymfsb_ac97_mixer_operations = {
+	"YAMAHA",
+	"YAMAHA PCI",
+	ymfsb_ac97_mixer_ioctl
+};
+
+static struct ac97_mixer_value_list ymfsb_ac97_mixer_defaults[] = {
+    { SOUND_MIXER_VOLUME,  { { 85, 85 } } },
+    { SOUND_MIXER_SPEAKER, { { 100 } } },
+    { SOUND_MIXER_PCM,     { { 65, 65 } } },
+    { SOUND_MIXER_CD,      { { 65, 65 } } },
+    { -1,                  {  { 0,  0 } } }
+};
+
+/* ---------------------------------------------------------------------- */
 
-static void enableDSP( void )
+static void enableDSP( struct ymf_card *card )
 {
-	writeRegDWord( YMFSB_CONFIG, 0x00000001 );
+	writeRegDWord( card, YMFSB_CONFIG, 0x00000001 );
 	return;
 }
 
-static void disableDSP( void )
+static void disableDSP( struct ymf_card *card )
 {
 	int val;
 	int i;
 
-	val = readRegDWord( YMFSB_CONFIG );
+	val = readRegDWord( card, YMFSB_CONFIG );
 	if ( val ) {
-		writeRegDWord( YMFSB_CONFIG, 0 );
+		writeRegDWord( card, YMFSB_CONFIG, 0 );
 	}
 
 	i=0;
 	while( ++i < YMFSB_WORKBITTIMEOUT ) {
-		val = readRegDWord(YMFSB_STATUS);
+		val = readRegDWord( card, YMFSB_STATUS );
 		if ( (val & 0x00000002) == 0x00000000 ) break;
 	}
 
 	return;
 }
 
-static int setupInstruction( struct pci_dev *pcidev )
+static int setupInstruction( struct ymf_card *card, struct pci_dev *pcidev )
 {
 	int i;
 	int val;
 
-	writeRegDWord( YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */
-	disableDSP();
+	writeRegDWord( card, YMFSB_NATIVEDACOUTVOL, 0 ); /* mute dac */
+	disableDSP( card );
 
-	writeRegDWord( YMFSB_MODE, 0x00010000 );
+	writeRegDWord( card, YMFSB_MODE, 0x00010000 );
 
 	/* DS-XG Software Reset */
-	writeRegDWord( YMFSB_MODE,         0x00000000 );
-	writeRegDWord( YMFSB_MAPOFREC,     0x00000000 );
-	writeRegDWord( YMFSB_MAPOFEFFECT,  0x00000000 );
-	writeRegDWord( YMFSB_PLAYCTRLBASE, 0x00000000 );
-	writeRegDWord( YMFSB_RECCTRLBASE,  0x00000000 );
-	writeRegDWord( YMFSB_EFFCTRLBASE,  0x00000000 );
+	writeRegDWord( card, YMFSB_MODE,         0x00000000 );
+	writeRegDWord( card, YMFSB_MAPOFREC,     0x00000000 );
+	writeRegDWord( card, YMFSB_MAPOFEFFECT,  0x00000000 );
+	writeRegDWord( card, YMFSB_PLAYCTRLBASE, 0x00000000 );
+	writeRegDWord( card, YMFSB_RECCTRLBASE,  0x00000000 );
+	writeRegDWord( card, YMFSB_EFFCTRLBASE,  0x00000000 );
 
-	val = readRegWord( YMFSB_GLOBALCTRL );
-	writeRegWord( YMFSB_GLOBALCTRL, (val&~0x0007) );
+	val = readRegWord( card, YMFSB_GLOBALCTRL );
+	writeRegWord( card, YMFSB_GLOBALCTRL, (val&~0x0007) );
 
 	/* setup DSP instruction code */
 	for ( i=0 ; i<YMFSB_DSPLENGTH ; i+=4 ) {
-	  writeRegDWord( YMFSB_DSPINSTRAM+i, DspInst[i>>2] );
+	  writeRegDWord( card, YMFSB_DSPINSTRAM+i, DspInst[i>>2] );
 	}
 
 	switch( pcidev->device ) {
@@ -532,7 +629,7 @@
 	case PCI_DEVICE_ID_YMF740:
 		/* setup Control instruction code */
 		for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {
-			writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst[i>>2] );
+			writeRegDWord( card, YMFSB_CTRLINSTRAM+i, CntrlInst[i>>2] );
 		}
 		break;
 
@@ -543,24 +640,25 @@
 		/* setup Control instruction code */
 	
 		for ( i=0 ; i<YMFSB_CTRLLENGTH ; i+=4 ) {
-			writeRegDWord( YMFSB_CTRLINSTRAM+i, CntrlInst1E[i>>2] );
+			writeRegDWord( card, YMFSB_CTRLINSTRAM+i, CntrlInst1E[i>>2] );
 		}
 		break;
 
 	default:
-		return -1;
+		return -ENXIO;
 	}
 
-	enableDSP();
+	enableDSP( card );
 
 	return 0;
 }
 
 /* ---------------------------------------------------------------------- */
 
-static int __init ymf7xx_init(struct pci_dev *pcidev)
+static int __init ymf7xx_init( struct ymf_card *card, struct pci_dev *pcidev )
 {
 	unsigned short v;
+	int mixer;
 
 	/* Read hardware information */
 #ifdef YMF_DEBUG
@@ -585,51 +683,50 @@
 #ifdef YMF_DEBUG
 	printk(KERN_INFO PFX "check codec...\n");
 #endif
-	if (checkCodec(pcidev)) return -1;
+	if (checkCodec(card, pcidev)) return -EBUSY;
 
 	/* setup legacy I/O */
 #ifdef YMF_DEBUG
 	printk(KERN_INFO PFX "setup legacy I/O...\n");
 #endif
-	if (setupLegacyIO(pcidev)) return -1;
+	if (setupLegacyIO(card, pcidev)) return -EBUSY;
 	
 	/* setup instruction code */	
 #ifdef YMF_DEBUG
 	printk(KERN_INFO PFX "setup instructions...\n");
 #endif
-	if (setupInstruction(pcidev)) return -1;
+	if (setupInstruction(card, pcidev)) return -EBUSY;
 
 	/* AC'97 setup */	
 #ifdef YMF_DEBUG
 	printk(KERN_INFO PFX "setup AC'97...\n");
 #endif
-	if ( writeAc97(AC97_RESET            ,0x0000) )  /* Reset */
-		return -1;
-	if ( writeAc97(AC97_MASTER_VOL_STEREO,0x0000) )  /* Master Volume */
-		return -1;
-
-	v = 31*(100-master_vol)/100;
-	v = (v<<8 | v)&0x7fff;
-	if ( writeAc97(AC97_PCMOUT_VOL       ,v     ) )  /* PCM out Volume */
-		return -1;
+	if ( ac97_init( &card->ac97_dev ) ) return -EBUSY;
+
+	mixer = sound_alloc_mixerdev();
+	if ( num_mixers >= MAX_MIXER_DEV ) return -EBUSY;
+	
+	mixer_devs[mixer] = &ymfsb_ac97_mixer_operations;
+	card->mixer_oss_dev = mixer;
+	ac97_set_values( &card->ac97_dev, ymfsb_ac97_mixer_defaults );
 
 #ifdef YMF_DEBUG
 	printk(KERN_INFO PFX "setup Legacy Volume...\n");
 #endif
 	/* Legacy Audio Output Volume L & R ch */
-	writeRegDWord( YMFSB_LEGACYOUTVOL, 0x3fff3fff );
+	writeRegDWord( card, YMFSB_LEGACYOUTVOL, 0x3fff3fff );
 
 #ifdef YMF_DEBUG
 	printk(KERN_INFO PFX "setup SPDIF output control...\n");
 #endif
 	/* SPDIF Output control */
 	v = spdif_out != 0 ? 0x0001 : 0x0000;
-	writeRegWord( YMFSB_SPDIFOUTCTRL, v );
+	writeRegWord( card, YMFSB_SPDIFOUTCTRL, v );
 	/* no copyright protection, 
 	   sample-rate converted,
 	   re-recorded software comercially available (the 1st generation),
 	   original */
-	writeRegWord( YMFSB_SPDIFOUTSTATUS, 0x9a04 );
+	writeRegWord( card, YMFSB_SPDIFOUTSTATUS, 0x9a04 );
 
 	return 0;
 }
@@ -638,6 +735,7 @@
 
 static void __init ymf7xxsb_attach_sb(struct address_info *hw_config)
 {
+	hw_config->driver_use_1 |= SB_NO_MIXER;
 	if(!sb_dsp_init(hw_config))
 		hw_config->slots[0] = -1;
 }
@@ -680,14 +778,21 @@
 	char		*devicename = "unknown";
 	int		i;
 	unsigned long   iobase;
+	struct ymf_card *card;
 
-	if ( pcidev->irq == 0 ) return -1;
+	if ( pcidev->irq == 0 ) return -ENODEV;
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,3,0)
+	if ( pci_enable_device(pcidev) ) {
+		printk (KERN_ERR PFX "cannot enable PCI device\n");
+		return -EIO;
+	}
+#endif
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,13)
 	iobase = pcidev->base_address[0]&PCI_BASE_ADDRESS_MEM_MASK;
 #else
 	iobase = pcidev->resource[0].start&PCI_BASE_ADDRESS_MEM_MASK;
 #endif
-	if ( iobase == 0x00000000 ) return -1;
+	if ( iobase == 0x00000000 ) return -ENODEV;
 
 	for ( i=0 ; i<sizeof(devicetable) / sizeof(devicetable[0]); i++ )
 	{
@@ -698,78 +803,80 @@
 		}
 	}
 
+	card = &ymf_cards[cards];
+
 	/* remap memory mapped I/O onto kernel virtual memory */
-	if ( (ymfbase[cards] = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 )
+	if ( (card->ymfbase = ioremap_nocache(iobase, YMFSB_REGSIZE)) == 0 )
 	{
 		printk(KERN_ERR PFX "ioremap (0x%lx) returns zero\n", iobase);
-		return -1;
+		return -ENODEV;
 	}
 	printk(KERN_INFO PFX "found %s at 0x%lx\n", devicename, iobase);
 #ifdef YMF_DEBUG
-	printk(KERN_INFO PFX "remappling to 0x%p\n", ymfbase[cards]);
+	printk(KERN_INFO PFX "remappling to 0x%p\n", card->ymfbase);
 #endif
 
-	memset (&sb_data[cards], 0, sizeof (struct address_info));
-	memset (&opl3_data[cards], 0, sizeof (struct address_info));
-#ifdef SUPPORT_UART401_MIDI
-	memset (&mpu_data[cards], 0, sizeof (struct address_info));
-#endif
+	memset (&card->sb_data,   0, sizeof (struct address_info));
+	memset (&card->opl3_data, 0, sizeof (struct address_info));
+	memset (&card->mpu_data,  0, sizeof (struct address_info));
+	memset (&card->ac97_dev,  0, sizeof (struct ac97_hwint));
 
-	sb_data[cards].name   = YMFSB_CARD_NAME;
-	opl3_data[cards].name = YMFSB_CARD_NAME;
-#ifdef SUPPORT_UART401_MIDI
-	mpu_data[cards].name  = YMFSB_CARD_NAME;
-#endif
+	card->card = cards;
+
+	card->sb_data.name   = YMFSB_CARD_NAME;
+	card->opl3_data.name = YMFSB_CARD_NAME;
+	card->mpu_data.name  = YMFSB_CARD_NAME;
 
-	sb_data[cards].card_subtype = MDL_YMPCI;
+	card->sb_data.card_subtype = MDL_YMPCI;
 
 	if ( io == 0 ) io      = 0x220;
-	sb_data[cards].io_base = io;
-	sb_data[cards].irq     = pcidev->irq;
-	sb_data[cards].dma     = dma;
+	card->sb_data.io_base = io;
+	card->sb_data.irq     = pcidev->irq;
+	card->sb_data.dma     = dma;
 
 	if ( synth_io == 0 ) synth_io = 0x388;
-	opl3_data[cards].io_base = synth_io;
-	opl3_data[cards].irq     = -1;
+	card->opl3_data.io_base = synth_io;
+	card->opl3_data.irq     = -1;
 
-#ifdef SUPPORT_UART401_MIDI
 	if ( mpu_io == 0 ) mpu_io = 0x330;
-	mpu_data[cards].io_base = mpu_io;
-	mpu_data[cards].irq     = -1;
-#endif
+	card->mpu_data.io_base = mpu_io;
+	card->mpu_data.irq     = -1;
+
+	card->ac97_dev.reset_device   = ymfsb_resetAC97;
+	card->ac97_dev.read_reg       = ymfsb_readAC97Reg;
+	card->ac97_dev.write_reg      = ymfsb_writeAC97Reg;
+	card->ac97_dev.driver_private = (void *)card;
 
-	if ( ymf7xx_init(pcidev) ) {
+	if ( ymf7xx_init(card, pcidev) ) {
 		printk (KERN_ERR PFX
 			"Cannot initialize %s, aborting\n",
 			devicename);
-		return -1;
+		return -ENODEV;
 	}
 
-	/* register legacy SoundBlaster Pro */
-	if (!ymf7xxsb_probe_sb(&sb_data[cards])) {
+	/* regist legacy SoundBlaster Pro */
+	if (!ymf7xxsb_probe_sb(&card->sb_data)) {
 		printk (KERN_ERR PFX
 			"SB probe at 0x%X failed, aborting\n",
 			io);
-		return -1;
+		return -ENODEV;
 	}
-	ymf7xxsb_attach_sb (&sb_data[cards]);
+	ymf7xxsb_attach_sb (&card->sb_data);
 
-#ifdef SUPPORT_UART401_MIDI
-	/* register legacy MIDI */
+	/* regist legacy MIDI */
 	if ( mpu_io > 0 && 0)
 	{
-		if (!ymf7xxsb_probe_midi (&mpu_data[cards])) {
+		if (!ymf7xxsb_probe_midi (&card->mpu_data)) {
 			printk (KERN_ERR PFX
 				"MIDI probe @ 0x%X failed, aborting\n",
 				mpu_io);
-			ymf7xxsb_unload_sb (&sb_data[cards], 0);
-			return -1;
+			ymf7xxsb_unload_sb (&card->sb_data, 0);
+			return -ENODEV;
 		}
-		ymf7xxsb_attach_midi (&mpu_data[cards]);
+		ymf7xxsb_attach_midi (&card->mpu_data);
 	}
-#endif
 
-	/* register legacy OPL3 */
+	/* regist legacy OPL3 */
 
 	cards++;	
 	return 0;
@@ -781,7 +888,7 @@
 	int i;
 
 	for (i=0 ; i<MAX_CARDS ; i++ )
-		ymfbase[i] = NULL;
+		ymf_cards[i].ymfbase = NULL;
 
 	while ( pcidev == NULL && (
 	       (pcidev = pci_find_device (PCI_VENDOR_ID_YAMAHA,
@@ -796,9 +903,9 @@
 					  PCI_DEVICE_ID_YMF744, pcidev)) ||
 	       (pcidev = pci_find_device (PCI_VENDOR_ID_YAMAHA,
 					  PCI_DEVICE_ID_YMF754, pcidev)))) {
-		  if (ymf7xxsb_install (pcidev) != 0) {
+		  if (ymf7xxsb_install (pcidev)) {
 			  printk (KERN_ERR PFX "audio init failed\n");
-			  return -1;
+			  return -ENODEV;
 		  }
 
 		  if (cards == MAX_CARDS) {
@@ -815,24 +922,21 @@
 	int i;
 
 	for ( i=0 ; i<MAX_CARDS ; i++ ) {
-		if ( ymfbase[i]!=NULL )
-			iounmap(ymfbase[i]);
+		if ( ymf_cards[i].ymfbase!=NULL )
+			iounmap(ymf_cards[i].ymfbase);
 	}
 
 	return;
 }
 
-static int __init init_ymf7xxsb_module(void)
+int __init init_ymf7xxsb_module(void)
 {
-	if ( master_vol < 0 ) master_vol  = 50;
-	if ( master_vol > 100 ) master_vol = 100;
-
 	if (!pci_present ()) {
 		printk (KERN_DEBUG PFX "PCI not present, exiting\n");
 		return -ENODEV;
 	}
 
-	if (probe_ymf7xxsb() != 0) {
+	if (probe_ymf7xxsb()) {
 		printk(KERN_ERR PFX "probe failed, aborting\n");
 		/* XXX unload cards registered so far, if any */
 		free_iomaps();
@@ -859,12 +963,10 @@
 	int i;
 	
 	for (i = 0; i < cards; i++) {
-#ifdef SUPPORT_UART401_MIDI
-		ymf7xxsb_unload_sb (&sb_data[i], 0);
-		ymf7xxsb_unload_midi (&mpu_data[i]);
-#else
-		ymf7xxsb_unload_sb (&sb_data[i], 1);
-#endif
+		ymf7xxsb_unload_sb (&(ymf_cards[i].sb_data), 0);
+		ymf7xxsb_unload_midi (&(ymf_cards[i].mpu_data));
+		if ( ymf_cards[i].mixer_oss_dev >= 0 ) 
+			sound_unload_mixerdev( ymf_cards[i].mixer_oss_dev );
 	}
 
 	free_iomaps();
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/telephony/ixj.c linux.17p18/drivers/telephony/ixj.c
--- linux.vanilla/drivers/telephony/ixj.c	Fri Apr 21 12:46:37 2000
+++ linux.17p18/drivers/telephony/ixj.c	Tue Aug  1 18:16:30 2000
@@ -1,10 +1,10 @@
-/*
+/****************************************************************************
  *    ixj.c
  *
  *    Device Driver for the Internet PhoneJACK and
  *    Internet LineJACK Telephony Cards.
  *
- *    (c) Copyright 1999 Quicknet Technologies, Inc.
+ *    (c) Copyright 1999-2000  Quicknet Technologies, Inc.
  *
  *    This program is free software; you can redistribute it and/or
  *    modify it under the terms of the GNU General Public License
@@ -12,25 +12,42 @@
  *    2 of the License, or (at your option) any later version.
  *
  * Author:          Ed Okerson, <eokerson@quicknet.net>
- *    
+ *
  * Contributors:    Greg Herlein, <gherlein@quicknet.net>
  *                  David W. Erhart, <derhart@quicknet.net>
  *                  John Sellers, <jsellers@quicknet.net>
  *                  Mike Preston, <mpreston@quicknet.net>
- *
+ *    
  * Fixes:
- *
- * More information about the hardware related to this driver can be found
+ * 
+ * More information about the hardware related to this driver can be found  
  * at our website:    http://www.quicknet.net
  *
- */
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *    
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ ***************************************************************************/
 
-static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.4 1999/12/16 22:18:36 root Exp root $";
+static char ixj_c_rcsid[] = "$Id: ixj.c,v 3.31 2000/04/14 19:24:47 jaugenst Exp $";
+static char ixj_c_revision[] = "$Revision: 3.31 $";
 
 //#define PERFMON_STATS
 #define IXJDEBUG 0
 #define MAXRINGS 5
 
+#ifdef CONFIG_PCMCIA
+#include <pcmcia/config.h>
+#include <pcmcia/k_compat.h>
+#endif
+
 #include <linux/module.h>
 
 #include <linux/init.h>
@@ -54,8 +71,18 @@
 #include <asm/uaccess.h>
 
 #ifdef CONFIG_ISAPNP
-#include "../pnp/pnpio.h"
-#include "../pnp/isapnp.h"
+#include "../isapnp/pnpio.h"
+#include "../isapnp/isapnp.h"
+#endif
+
+#ifdef CONFIG_PCMCIA
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/cs.h>
+#include <pcmcia/cistpl.h>
+#include <pcmcia/ds.h>
+#include <pcmcia/cisreg.h>
+#include <pcmcia/ciscode.h>
 #endif
 
 #include "ixj.h"
@@ -100,14 +127,17 @@
 static void ixj_write_frame(int board);
 static void ixj_init_timer(void);
 static void ixj_add_timer(void);
-static void ixj_del_timer(void);
 static void ixj_timeout(unsigned long ptr);
 static int read_filters(int board);
 static int LineMonitor(int board);
 static int ixj_fasync(int fd, struct file *, int mode);
+static int ixj_set_port(int board, int arg);
+static int ixj_set_pots(int board, int arg);
 static int ixj_hookstate(int board);
 static int ixj_record_start(int board);
 static void ixj_record_stop(int board);
+static void set_rec_volume(int board, int volume);
+static void ixj_vad(int board, int arg);
 static int ixj_play_start(int board);
 static void ixj_play_stop(int board);
 static int ixj_set_tone_on(unsigned short arg, int board);
@@ -124,6 +154,7 @@
 static char daa_int_read(int board);
 static int daa_set_mode(int board, int mode);
 static int ixj_linetest(int board);
+static int ixj_daa_write(int board);
 static int ixj_daa_cid_read(int board);
 static void DAA_Coeff_US(int board);
 static void DAA_Coeff_UK(int board);
@@ -134,12 +165,18 @@
 static int ixj_init_filter(int board, IXJ_FILTER * jf);
 static int ixj_init_tone(int board, IXJ_TONE * ti);
 static int ixj_build_cadence(int board, IXJ_CADENCE * cp);
+static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp);
 // Serial Control Interface funtions
 static int SCI_Control(int board, int control);
 static int SCI_Prepare(int board);
 static int SCI_WaitHighSCI(int board);
 static int SCI_WaitLowSCI(int board);
 static DWORD PCIEE_GetSerialNumber(WORD wAddress);
+static int ixj_PCcontrol_wait(int board);
+static void ixj_write_cid(int board);
+static void ixj_write_cid_bit(int board, int bit);
+static int set_base_frame(int board, int size);
+static int set_play_codec(int board, int rate);
 
 /************************************************************************
 CT8020/CT8021 Host Programmers Model
@@ -160,12 +197,19 @@
 	ixj[board].hsr.bytes.low = inb_p(ixj[board].DSPbase + 8);
 	ixj[board].hsr.bytes.high = inb_p(ixj[board].DSPbase + 9);
 }
+
 extern __inline__ int IsControlReady(int board)
 {
 	ixj_read_HSR(board);
 	return ixj[board].hsr.bits.controlrdy ? 1 : 0;
 }
 
+extern __inline__ int IsPCControlReady(int board)
+{
+	ixj[board].pccr1.byte = inb_p(ixj[board].XILINXbase + 3);
+	return ixj[board].pccr1.bits.crr ? 1 : 0;
+}
+
 extern __inline__ int IsStatusReady(int board)
 {
 	ixj_read_HSR(board);
@@ -175,21 +219,54 @@
 extern __inline__ int IsRxReady(int board)
 {
 	ixj_read_HSR(board);
+#ifdef PERFMON_STATS
+	++ixj[board].rxreadycheck;
+#endif
 	return ixj[board].hsr.bits.rxrdy ? 1 : 0;
 }
 
 extern __inline__ int IsTxReady(int board)
 {
 	ixj_read_HSR(board);
+#ifdef PERFMON_STATS
+	++ixj[board].txreadycheck;
+#endif
 	return ixj[board].hsr.bits.txrdy ? 1 : 0;
 }
 
+extern __inline__ void set_play_volume(int board, int volume)
+{
+	ixj_WriteDSPCommand(0xCF02, board);
+	ixj_WriteDSPCommand(volume, board);
+}
+
+extern __inline__ int get_play_volume(int board)
+{
+	ixj_WriteDSPCommand(0xCF00, board);
+	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+}
+
 extern __inline__ BYTE SLIC_GetState(int board)
 {
 	IXJ *j = &ixj[board];
 
-	j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
-
+	if (j->cardtype == 600) {
+		j->pccr1.byte = 0;
+		j->psccr.bits.dev = 3;
+		j->psccr.bits.rw = 1;
+		outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
+		ixj_PCcontrol_wait(board);
+		j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
+		ixj_PCcontrol_wait(board);
+		if (j->pslic.bits.powerdown)
+			return PLD_SLIC_STATE_OC;
+		else if (!j->pslic.bits.ring0 && !j->pslic.bits.ring1)
+			return PLD_SLIC_STATE_ACTIVE;
+		else
+			return PLD_SLIC_STATE_RINGING;
+	} else {
+		j->pld_slicr.byte = inb_p(j->XILINXbase + 0x01);
+	}
 	return j->pld_slicr.bits.state;
 }
 
@@ -198,78 +275,122 @@
 	BOOL fRetVal = FALSE;
 	IXJ *j = &ixj[board];
 
-	// Set the C1, C2, C3 & B2EN signals.
-	switch (byState) {
-	case PLD_SLIC_STATE_OC:
-		j->pld_slicw.bits.c1 = 0;
-		j->pld_slicw.bits.c2 = 0;
-		j->pld_slicw.bits.c3 = 0;
-		j->pld_slicw.bits.b2en = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_RINGING:
-		j->pld_slicw.bits.c1 = 1;
-		j->pld_slicw.bits.c2 = 0;
-		j->pld_slicw.bits.c3 = 0;
-		j->pld_slicw.bits.b2en = 1;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_ACTIVE:
-		j->pld_slicw.bits.c1 = 0;
-		j->pld_slicw.bits.c2 = 1;
-		j->pld_slicw.bits.c3 = 0;
-		j->pld_slicw.bits.b2en = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_OHT:	// On-hook transmit
+	if (j->cardtype == 600) {
+		if (j->flags.pcmciasct) {
+			switch (byState) {
+			case PLD_SLIC_STATE_TIPOPEN:
+			case PLD_SLIC_STATE_OC:
+				j->pslic.bits.powerdown = 1;
+				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
+				fRetVal = TRUE;
+				break;
+			case PLD_SLIC_STATE_RINGING:
+				if (j->readers || j->writers) {
+					j->pslic.bits.powerdown = 0;
+					j->pslic.bits.ring0 = 1;
+					j->pslic.bits.ring1 = 0;
+					fRetVal = TRUE;
+				}
+				break;
+			case PLD_SLIC_STATE_OHT:	// On-hook transmit
 
-		j->pld_slicw.bits.c1 = 1;
-		j->pld_slicw.bits.c2 = 1;
-		j->pld_slicw.bits.c3 = 0;
-		j->pld_slicw.bits.b2en = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_TIPOPEN:
-		j->pld_slicw.bits.c1 = 0;
-		j->pld_slicw.bits.c2 = 0;
-		j->pld_slicw.bits.c3 = 1;
-		j->pld_slicw.bits.b2en = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_STANDBY:
-		j->pld_slicw.bits.c1 = 1;
-		j->pld_slicw.bits.c2 = 0;
-		j->pld_slicw.bits.c3 = 1;
-		j->pld_slicw.bits.b2en = 1;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_APR:	// Active polarity reversal
+			case PLD_SLIC_STATE_STANDBY:
+			case PLD_SLIC_STATE_ACTIVE:
+				if (j->readers || j->writers) {
+					j->pslic.bits.powerdown = 0;
+				} else {
+					j->pslic.bits.powerdown = 1;
+				}
+				j->pslic.bits.ring0 = j->pslic.bits.ring1 = 0;
+				fRetVal = TRUE;
+				break;
+			case PLD_SLIC_STATE_APR:	// Active polarity reversal
 
-		j->pld_slicw.bits.c1 = 0;
-		j->pld_slicw.bits.c2 = 1;
-		j->pld_slicw.bits.c3 = 1;
-		j->pld_slicw.bits.b2en = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal
+			case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal
 
-		j->pld_slicw.bits.c1 = 1;
-		j->pld_slicw.bits.c2 = 1;
-		j->pld_slicw.bits.c3 = 1;
-		j->pld_slicw.bits.b2en = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		fRetVal = TRUE;
-		break;
-	default:
-		fRetVal = FALSE;
-		break;
+			default:
+				fRetVal = FALSE;
+				break;
+			}
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 0;
+			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+			ixj_PCcontrol_wait(board);
+		}
+	} else {
+		// Set the C1, C2, C3 & B2EN signals.
+		switch (byState) {
+		case PLD_SLIC_STATE_OC:
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_RINGING:
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 1;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_ACTIVE:
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_OHT:	// On-hook transmit
+
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 0;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_TIPOPEN:
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_STANDBY:
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 0;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 1;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_APR:	// Active polarity reversal
+
+			j->pld_slicw.bits.c1 = 0;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		case PLD_SLIC_STATE_OHTPR:	// OHT polarity reversal
+
+			j->pld_slicw.bits.c1 = 1;
+			j->pld_slicw.bits.c2 = 1;
+			j->pld_slicw.bits.c3 = 1;
+			j->pld_slicw.bits.b2en = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			fRetVal = TRUE;
+			break;
+		default:
+			fRetVal = FALSE;
+			break;
+		}
 	}
 
 	return fRetVal;
@@ -361,51 +482,42 @@
 	add_timer(&ixj_timer);
 }
 
-static void ixj_del_timer(void)
-{
-	del_timer(&ixj_timer);
-}
-
 static void ixj_tone_timeout(int board)
 {
 	IXJ *j = &ixj[board];
 	IXJ_TONE ti;
-	
+
 	j->tone_state++;
 	if (j->tone_state == 3) {
 		j->tone_state = 0;
 		if (j->cadence_t) {
 			j->tone_cadence_state++;
-			if (j->tone_cadence_state >= j->cadence_t->elements_used) 
-			{
-				switch (j->cadence_t->termination) 
-				{
-					case PLAY_ONCE:
-						ixj_cpt_stop(board);
-							break;
-					case REPEAT_LAST_ELEMENT:
-						j->tone_cadence_state--;
-						ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
-						break;
-					case REPEAT_ALL:
-						j->tone_cadence_state = 0;
-						if (j->cadence_t->ce[j->tone_cadence_state].freq0) 
-						{
-							ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
-							ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
-							ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
-							ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
-							ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
-							ixj_init_tone(board, &ti);
-						}
-						ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);
-						ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, board);
-						ixj_play_tone(board, j->cadence_t->ce[0].index);
-						break;
+			if (j->tone_cadence_state >= j->cadence_t->elements_used) {
+				switch (j->cadence_t->termination) {
+				case PLAY_ONCE:
+					ixj_cpt_stop(board);
+					break;
+				case REPEAT_LAST_ELEMENT:
+					j->tone_cadence_state--;
+					ixj_play_tone(board, j->cadence_t->ce[j->tone_cadence_state].index);
+					break;
+				case REPEAT_ALL:
+					j->tone_cadence_state = 0;
+					if (j->cadence_t->ce[j->tone_cadence_state].freq0) {
+						ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
+						ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
+						ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
+						ti.freq1 = j->cadence_t->ce[j->tone_cadence_state].freq1;
+						ti.gain1 = j->cadence_t->ce[j->tone_cadence_state].gain1;
+						ixj_init_tone(board, &ti);
+					}
+					ixj_set_tone_on(j->cadence_t->ce[0].tone_on_time, board);
+					ixj_set_tone_off(j->cadence_t->ce[0].tone_off_time, board);
+					ixj_play_tone(board, j->cadence_t->ce[0].index);
+					break;
 				}
 			} else {
-				if (j->cadence_t->ce[j->tone_cadence_state].gain0) 
-				{
+				if (j->cadence_t->ce[j->tone_cadence_state].gain0) {
 					ti.tone_index = j->cadence_t->ce[j->tone_cadence_state].index;
 					ti.freq0 = j->cadence_t->ce[j->tone_cadence_state].freq0;
 					ti.gain0 = j->cadence_t->ce[j->tone_cadence_state].gain0;
@@ -421,50 +533,50 @@
 	}
 }
 
+extern __inline__ void ixj_kill_fasync(int board)
+{
+	if (ixj[board].async_queue)
+		kill_fasync(ixj[board].async_queue, SIGIO);	// Send apps notice of change
+
+}
 static void ixj_timeout(unsigned long ptr)
 {
 	int board;
 	unsigned long jifon;
 	IXJ *j;
 
-	for (board = 0; board < IXJMAX; board++) 
-	{
+	for (board = 0; board < IXJMAX; board++) {
 		j = &ixj[board];
 
-		if (j->DSPbase) 
-		{
+		if (j->DSPbase) {
 #ifdef PERFMON_STATS
 			j->timerchecks++;
 #endif
-			if (j->tone_state) 
-			{
-				if (!ixj_hookstate(board)) 
-				{
+			if (j->tone_state) {
+				if (!ixj_hookstate(board)) {
 					ixj_cpt_stop(board);
-					if (j->m_hook) 
-					{
+					if (j->m_hook) {
 						j->m_hook = 0;
 						j->ex.bits.hookstate = 1;
-						if (j->async_queue)
-							kill_fasync(j->async_queue, SIGIO);	// Send apps notice of change
+						ixj_kill_fasync(board);
 					}
-					goto timer_end;
+					continue;
 				}
 				if (j->tone_state == 1)
 					jifon = (hertz * j->tone_on_time * 25 / 100000);
 				else
 					jifon = (hertz * j->tone_on_time * 25 / 100000) +
 					    (hertz * j->tone_off_time * 25 / 100000);
-				if (jiffies < j->tone_start_jif + jifon) {
+				if (time_before(jiffies, j->tone_start_jif + jifon)) {
 					if (j->tone_state == 1) {
 						ixj_play_tone(board, j->tone_index);
 						if (j->dsp.low == 0x20) {
-							goto timer_end;
+							continue;
 						}
 					} else {
 						ixj_play_tone(board, 0);
 						if (j->dsp.low == 0x20) {
-							goto timer_end;
+							continue;
 						}
 					}
 				} else {
@@ -475,13 +587,13 @@
 					if (j->flags.busytone) {
 						ixj_busytone(board);
 						if (j->dsp.low == 0x20) {
-							goto timer_end;
+							continue;
 						}
 					}
 					if (j->flags.ringback) {
 						ixj_ringback(board);
 						if (j->dsp.low == 0x20) {
-							goto timer_end;
+							continue;
 						}
 					}
 					if (!j->tone_state) {
@@ -498,7 +610,7 @@
 				if (IsRxReady(board)) {
 					ixj_read_frame(board);
 				}
-				if (IsTxReady(board)) {
+				if (IsTxReady(board) && !j->flags.cidplay) {
 					ixj_write_frame(board);
 				}
 			}
@@ -507,7 +619,12 @@
 					j->flags.cringing = 0;
 					ixj_ring_off(board);
 				} else {
-					if (jiffies - j->ring_cadence_jif >= (hertz/2)) {
+					if (jiffies - j->ring_cadence_jif >= (.5 * hertz)) {
+						if (j->flags.cidring && !j->flags.cidsent) {
+							j->flags.cidsent = 1;
+							ixj_write_cid(board);
+							j->flags.cidring = 0;
+						}
 						j->ring_cadence_t--;
 						if (j->ring_cadence_t == -1)
 							j->ring_cadence_t = 15;
@@ -517,16 +634,15 @@
 						ixj_ring_on(board);
 					} else {
 						ixj_ring_off(board);
+						j->flags.cidring = 1;
 					}
-					goto timer_end;
+					continue;
 				}
 			}
 			if (!j->flags.ringing) {
 				if (ixj_hookstate(board)) {
-					if ((j->dsp.low == 0x21 || j->dsp.low == 0x22 )&&
-					    j->pld_slicr.bits.state != PLD_SLIC_STATE_ACTIVE)
-               // Internet LineJACK
-					{
+					if (j->dsp.low != 0x20 &&
+					    SLIC_GetState(board) != PLD_SLIC_STATE_ACTIVE) {
 						SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
 					}
 					LineMonitor(board);
@@ -535,13 +651,12 @@
 					j->proc_load = j->ssr.high << 8 | j->ssr.low;
 					if (!j->m_hook) {
 						j->m_hook = j->ex.bits.hookstate = 1;
-						if (j->async_queue)
-							kill_fasync(j->async_queue, SIGIO);	// Send apps notice of change
+						ixj_kill_fasync(board);
 					}
 				} else {
-					if ((j->dsp.low == 0x21 || j->dsp.low == 0x22) &&
-					    j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE)
-               // Internet LineJACK
+					if (j->dsp.low != 0x20 &&
+					    SLIC_GetState(board) == PLD_SLIC_STATE_ACTIVE)
+						// Internet LineJACK
 					{
 						SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
 					}
@@ -551,15 +666,14 @@
 					if (j->m_hook) {
 						j->m_hook = 0;
 						j->ex.bits.hookstate = 1;
-						if (j->async_queue)
-							kill_fasync(j->async_queue, SIGIO);	// Send apps notice of change
+						ixj_kill_fasync(board);
 					}
 				}
 			}
-			if (j->cardtype == 300) {
+			if (j->cardtype == 300 && !j->flags.incheck) {
 				if (j->flags.pstn_present) {
 					j->pld_scrr.byte = inb_p(j->XILINXbase);
-					if (jiffies >= j->pstn_sleeptil && j->pld_scrr.bits.daaflag) {
+					if (j->pld_scrr.bits.daaflag) {
 						daa_int_read(board);
 						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.RING) {
 							if (!j->flags.pstn_ringing) {
@@ -568,22 +682,38 @@
 									daa_set_mode(board, SOP_PU_RINGING);
 							}
 						}
-						if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+						if (time_after(jiffies, j->pstn_sleeptil) && j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
 							j->pstn_winkstart = 0;
+							j->pstn_ring_stop = 0;
+							ixj[board].pld_scrw.bits.led1 = 1;
 							if (j->flags.pstn_ringing && !j->pstn_envelope) {
+								if (j->daa_mode != SOP_PU_RINGING) {
+									j->flags.pstn_ringing = 0;
+								} else {
+									ixj[board].pld_scrw.bits.led2 = 0;
+									j->pstn_envelope = 1;
+									j->pstn_ring_start = jiffies;
+									j->pstn_ring_stop = 0;
+								}
 								j->ex.bits.pstn_ring = 0;
-								j->pstn_envelope = 1;
-								j->pstn_ring_start = jiffies;
 							}
+							outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
 						} else {
-							if (j->flags.pstn_ringing && j->pstn_envelope &&
-							    jiffies > j->pstn_ring_start + ((hertz * 15) / 10)) {
-								j->ex.bits.pstn_ring = 1;
-								j->pstn_envelope = 0;
+							ixj[board].pld_scrw.bits.led1 = 0;
+							ixj[board].pld_scrw.bits.led2 = 1;
+							outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
+							if (j->flags.pstn_ringing && j->pstn_envelope) {
+								if(!j->pstn_ring_stop) {
+									j->pstn_ring_stop = jiffies;
+								} else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
+									j->pstn_ring_stop = 0;
+									j->ex.bits.pstn_ring = 1;
+									j->pstn_envelope = 0;
+								}
 							} else if (j->daa_mode == SOP_PU_CONVERSATION) {
 								if (!j->pstn_winkstart) {
 									j->pstn_winkstart = jiffies;
-								} else if (jiffies > j->pstn_winkstart + (hertz * j->winktime / 1000)) {
+								} else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
 									daa_set_mode(board, SOP_PU_SLEEP);
 									j->pstn_winkstart = 0;
 									j->ex.bits.pstn_wink = 1;
@@ -620,13 +750,23 @@
 							j->ex.bits.caller_id = 0;
 						}
 						if (!j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+							ixj[board].pld_scrw.bits.led1 = 0;
+							ixj[board].pld_scrw.bits.led2 = 1;
+							outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
 							if (j->flags.pstn_ringing && j->pstn_envelope) {
-								j->ex.bits.pstn_ring = 1;
-								j->pstn_envelope = 0;
+								if(!j->pstn_ring_stop) {
+									j->pstn_ring_stop = jiffies;
+								} else if (time_after(jiffies, j->pstn_ring_stop + ((hertz * 5) / 100))){
+									j->pstn_ring_stop = 0;
+									j->ex.bits.pstn_ring = 1;
+									j->pstn_envelope = 0;
+								}
+								ixj[board].pld_scrw.bits.led1 = 0;
+								outb_p(ixj[board].pld_scrw.byte, ixj[board].XILINXbase);
 							} else if (j->daa_mode == SOP_PU_CONVERSATION) {
 								if (!j->pstn_winkstart) {
 									j->pstn_winkstart = jiffies;
-								} else if (jiffies > j->pstn_winkstart + (hertz * 320 / 1000)) {
+								} else if (time_after(jiffies, j->pstn_winkstart + (hertz * j->winktime / 1000))) {
 									daa_set_mode(board, SOP_PU_SLEEP);
 									j->pstn_winkstart = 0;
 									j->ex.bits.pstn_wink = 1;
@@ -636,19 +776,15 @@
 					}
 				}
 			}
-			if ((j->ex.bits.f0 || j->ex.bits.f1 || j->ex.bits.f2 || j->ex.bits.f3)
-			    && j->filter_cadence) {
-			}
 			if (j->ex.bytes) {
 				wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
-				if (j->async_queue)
-					kill_fasync(j->async_queue, SIGIO);	// Send apps notice of change
+
+				ixj_kill_fasync(board);
 			}
 		} else {
 			break;
 		}
 	}
-timer_end:
 	ixj_add_timer();
 }
 
@@ -665,6 +801,19 @@
 	return 0;
 }
 
+static int ixj_PCcontrol_wait(int board)
+{
+	unsigned long jif;
+
+	jif = jiffies;
+	while (!IsPCControlReady(board)) {
+		if (jiffies - jif > (60 * (hertz / 100))) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
 int ixj_WriteDSPCommand(unsigned short cmd, int board)
 {
 	BYTES bytes;
@@ -710,7 +859,7 @@
 
 extern __inline__ void LED_SetState(int state, int board)
 {
-	if (ixj[board].dsp.low == 0x21) {
+	if (ixj[board].cardtype == 300) {
 		ixj[board].pld_scrw.bits.led1 = state & 0x1 ? 1 : 0;
 		ixj[board].pld_scrw.bits.led2 = state & 0x2 ? 1 : 0;
 		ixj[board].pld_scrw.bits.led3 = state & 0x4 ? 1 : 0;
@@ -748,12 +897,19 @@
 	case PORT_POTS:
 		j->port = PORT_POTS;
 		switch (j->cardtype) {
+		case 600:
+			if (j->flags.pcmciasct == 1)
+				SLIC_SetState(PLD_SLIC_STATE_ACTIVE, board);
+			else
+				return 11;
+			break;
 		case 500:
 			j->pld_slicw.pcib.mic = 0;
 			j->pld_slicw.pcib.spk = 0;
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			break;
 		case 300:
+			ixj_set_pots(board, 0);
 			if (ixj_WriteDSPCommand(0xC528, board))		/* Write CODEC config to
 									   Software Control Register */
 				return 2;
@@ -791,12 +947,21 @@
 	case PORT_SPEAKER:
 		j->port = PORT_SPEAKER;
 		switch (j->cardtype) {
+		case 600:
+			if (j->flags.pcmciasct) {
+				SLIC_SetState(PLD_SLIC_STATE_OC, board);
+//                              while(SLIC_GetState(board) != PLD_SLIC_STATE_OC) {
+				//                                      SLIC_SetState(PLD_SLIC_STATE_OC,board);
+				//                              }
+			}
+			break;
 		case 500:
 			j->pld_slicw.pcib.mic = 1;
 			j->pld_slicw.pcib.spk = 1;
 			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
 			break;
 		case 300:
+			ixj_set_pots(board, 0);
 			break;
 		case 100:
 			j->gpio.bytes.high = 0x0B;
@@ -861,8 +1026,7 @@
 		j->gpio.bits.gpio2 = 1;
 		j->gpio.bits.gpio5 = 0;
 		ixj_WriteDSPCommand(j->gpio.word, board);	/* send the ring signal */
-	} else			//  Internet LineJACK, Internet PhoneJACK Lite or
-              //  Internet PhoneJACK PCI
+	} else			// Internet LineJACK, Internet PhoneJACK Lite or Internet PhoneJACK PCI
 	 {
 		if (ixjdebug > 0)
 			printk(KERN_INFO "IXJ Ring On /dev/phone%d\n", board);
@@ -871,6 +1035,212 @@
 	}
 }
 
+static int ixj_pcmcia_cable_check(int board)
+{
+	IXJ *j = &ixj[board];
+
+	j->pccr1.byte = inb_p(j->XILINXbase + 0x03);
+	if (!j->flags.pcmciastate) {
+		j->pccr2.byte = inb_p(j->XILINXbase + 0x02);
+		if (j->pccr1.bits.drf || j->pccr2.bits.rstc) {
+			j->flags.pcmciastate = 4;
+			return 0;
+		}
+		if (j->pccr1.bits.ed) {
+			j->pccr1.bits.ed = 0;
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 1;
+			outw_p(j->psccr.byte << 8, j->XILINXbase + 0x00);
+			ixj_PCcontrol_wait(board);
+			j->pslic.byte = inw_p(j->XILINXbase + 0x00) & 0xFF;
+			j->pslic.bits.led2 = j->pslic.bits.det ? 1 : 0;
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 0;
+			outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+			ixj_PCcontrol_wait(board);
+			return j->pslic.bits.led2 ? 1 : 0;
+		} else if (j->flags.pcmciasct) {
+			return j->r_hook;
+		} else {
+			return 1;
+		}
+	} else if (j->flags.pcmciastate == 4) {
+		if (!j->pccr1.bits.drf) {
+			j->flags.pcmciastate = 3;
+		}
+		return 0;
+	} else if (j->flags.pcmciastate == 3) {
+		j->pccr2.bits.pwr = 0;
+		j->pccr2.bits.rstc = 1;
+		outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+		j->checkwait = jiffies + hertz * 2;
+		j->flags.incheck = 1;
+		j->flags.pcmciastate = 2;
+		return 0;
+	} else if (j->flags.pcmciastate == 2) {
+		if (j->flags.incheck) {
+			if (time_before(jiffies, j->checkwait)) {
+				return 0;
+			} else {
+				j->flags.incheck = 0;
+			}
+		}
+		j->pccr2.bits.pwr = 0;
+		j->pccr2.bits.rstc = 0;
+		outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+		j->flags.pcmciastate = 1;
+		return 0;
+	} else if (j->flags.pcmciastate == 1) {
+		j->flags.pcmciastate = 0;
+		if (!j->pccr1.bits.drf) {
+			j->psccr.bits.dev = 3;
+			j->psccr.bits.rw = 1;
+			outb_p(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->flags.pcmciascp = 1;		// Set Cable Present Flag
+
+			j->flags.pcmciasct = (inw_p(j->XILINXbase + 0x00) >> 8) & 0x03;		// Get Cable Type
+
+			if (j->flags.pcmciasct == 3) {
+				j->flags.pcmciastate = 4;
+				return 0;
+			} else if (j->flags.pcmciasct == 0) {
+				j->pccr2.bits.pwr = 1;
+				j->pccr2.bits.rstc = 0;
+				outb_p(j->pccr2.byte, j->XILINXbase + 0x02);
+				j->port = PORT_SPEAKER;
+			} else {
+				j->port = PORT_POTS;
+			}
+			j->sic1.bits.cpd = 0;	// Chip Power Down
+
+			j->sic1.bits.mpd = 0;	// MIC Bias Power Down
+
+			j->sic1.bits.hpd = 0;	// Handset Bias Power Down
+
+			j->sic1.bits.lpd = 0;	// Line Bias Power Down
+
+			j->sic1.bits.spd = 1;	// Speaker Drive Power Down
+
+			j->psccr.bits.addr = 1;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(j->sic1.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->sic2.bits.al = 0;	// Analog Loopback DAC analog -> ADC analog
+
+			j->sic2.bits.dl2 = 0;	// Digital Loopback DAC -> ADC one bit
+
+			j->sic2.bits.dl1 = 0;	// Digital Loopback ADC -> DAC one bit
+
+			j->sic2.bits.pll = 0;	// 1 = div 10, 0 = div 5
+
+			j->sic2.bits.hpd = 0;	// HPF disable
+
+			j->psccr.bits.addr = 2;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(j->sic2.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->psccr.bits.addr = 3;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(0x00, j->XILINXbase + 0x00);	// PLL Divide N1
+
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->psccr.bits.addr = 4;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(0x09, j->XILINXbase + 0x00);	// PLL Multiply M1
+
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->sirxg.bits.lig = 1;	// Line In Gain
+
+			j->sirxg.bits.lim = 1;	// Line In Mute
+
+			j->sirxg.bits.mcg = 0;	// MIC In Gain // was 3
+
+			j->sirxg.bits.mcm = 0;	// MIC In Mute
+
+			j->sirxg.bits.him = 0;	// Handset In Mute
+
+			j->sirxg.bits.iir = 1;	// IIR
+
+			j->psccr.bits.addr = 5;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(j->sirxg.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->siadc.bits.hom = 0;	// Handset Out Mute
+
+			j->siadc.bits.lom = 0;	// Line Out Mute
+
+			j->siadc.bits.rxg = 23;		//(0xC000 - 0x41C8) / 0x4EF;    // RX PGA Gain
+
+			j->psccr.bits.addr = 6;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(j->siadc.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->sidac.bits.srm = 1;	// Speaker Right Mute
+
+			j->sidac.bits.slm = 1;	// Speaker Left Mute
+
+			j->sidac.bits.txg = (0xC000 - 0x45E4) / 0x5D3;	// TX PGA Gain
+
+			j->psccr.bits.addr = 7;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(j->sidac.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+			j->siaatt.bits.sot = 0;
+			j->psccr.bits.addr = 9;		// R/W Smart Cable Register Address
+
+			j->psccr.bits.rw = 0;	// Read / Write flag
+
+			j->psccr.bits.dev = 0;
+			outb(j->siaatt.byte, j->XILINXbase + 0x00);
+			outb(j->psccr.byte, j->XILINXbase + 0x01);
+			ixj_PCcontrol_wait(board);
+
+			if (j->flags.pcmciasct == 1 && !j->readers && !j->writers) {
+				j->psccr.byte = j->pslic.byte = 0;
+				j->pslic.bits.powerdown = 1;
+				j->psccr.bits.dev = 3;
+				j->psccr.bits.rw = 0;
+				outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+				ixj_PCcontrol_wait(board);
+			}
+		}
+		return 0;
+	} else {
+		j->flags.pcmciascp = 0;
+		return 0;
+	}
+	return 0;
+}
+
 static int ixj_hookstate(int board)
 {
 	unsigned long det;
@@ -887,12 +1257,9 @@
 	case 500:
 		SLIC_GetState(board);
 		if (j->pld_slicr.bits.state == PLD_SLIC_STATE_ACTIVE ||
-		    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) 
-		{
-			if (j->flags.ringing) 
-			{
-				if(!in_interrupt())
-				{
+		    j->pld_slicr.bits.state == PLD_SLIC_STATE_STANDBY) {
+			if (j->flags.ringing) {
+				if (!in_interrupt()) {
 					det = jiffies + (hertz / 50);
 					while (time_before(jiffies, det)) {
 						current->state = TASK_INTERRUPTIBLE;
@@ -911,14 +1278,17 @@
 				fOffHook = j->pld_slicr.bits.det ? 1 : 0;
 		}
 		break;
+	case 600:
+		fOffHook = ixj_pcmcia_cable_check(board);
+		break;
 	}
 	if (j->r_hook != fOffHook) {
 		j->r_hook = fOffHook;
 		if (j->port != PORT_POTS) {
 			j->ex.bits.hookstate = 1;
-			if (j->async_queue)
-				kill_fasync(j->async_queue, SIGIO);	// Send apps notice of change
-
+			ixj_kill_fasync(board);
+		} else if (!fOffHook) {
+			j->flash_end = jiffies + (hertz / 10 * 6);
 		}
 	}
 	if (j->port == PORT_PSTN && j->daa_mode == SOP_PU_CONVERSATION)
@@ -930,7 +1300,10 @@
 	if (j->port == PORT_HANDSET)
 		fOffHook |= 2;
 
-	return fOffHook;
+	if (fOffHook && time_before(jiffies, j->flash_end))
+		return 0;
+	else
+		return fOffHook;
 }
 
 static void ixj_ring_off(board)
@@ -952,7 +1325,7 @@
 		if (ixjdebug > 0)
 			printk(KERN_INFO "IXJ Ring Off\n");
 
-		SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);	
+		SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
 
 		SLIC_GetState(board);
 	}
@@ -1002,7 +1375,7 @@
 			}
 			current->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(1);
-			if(signal_pending(current))
+			if (signal_pending(current))
 				break;
 		}
 		jif = jiffies + (3 * hertz);
@@ -1013,7 +1386,7 @@
 				while (time_before(jiffies, det)) {
 					current->state = TASK_INTERRUPTIBLE;
 					schedule_timeout(1);
-					if(signal_pending(current))
+					if (signal_pending(current))
 						break;
 				}
 				if (ixj_hookstate(board) & 1) {
@@ -1023,7 +1396,7 @@
 			}
 			current->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(1);
-			if(signal_pending(current))
+			if (signal_pending(current))
 				break;
 		}
 	}
@@ -1034,40 +1407,70 @@
 
 int ixj_open(struct phone_device *p, struct file *file_p)
 {
-	IXJ *j = &ixj[p->board];
+	IXJ *j = file_p->private_data = &ixj[p->board];
 
 	if (!j->DSPbase)
 		return -ENODEV;
 
-	if (file_p->f_mode & FMODE_READ)
-		j->readers++;
-	if (file_p->f_mode & FMODE_WRITE)
-		j->writers++;
+        if (file_p->f_mode & FMODE_READ) {
+		if(!j->readers) {
+	                j->readers++;
+        	} else {
+                	return -EBUSY;
+		}
+        }
+
+	if (file_p->f_mode & FMODE_WRITE) {
+		if(!j->writers) {
+			j->writers++;
+		} else {
+			if (file_p->f_mode & FMODE_READ){
+				j->readers--;
+			}
+			return -EBUSY;
+		}
+	}
 
+	if (j->cardtype == 600) {
+		j->pslic.bits.powerdown = 0;
+		j->psccr.bits.dev = 3;
+		j->psccr.bits.rw = 0;
+		outw_p(j->psccr.byte << 8 | j->pslic.byte, j->XILINXbase + 0x00);
+		ixj_PCcontrol_wait(p->board);
+	}
 	MOD_INC_USE_COUNT;
 
 	if (ixjdebug > 0)
-//    printk(KERN_INFO "Opening board %d\n", NUM(inode->i_rdev));
 		printk(KERN_INFO "Opening board %d\n", p->board);
 
+	j->framesread = j->frameswritten = 0;
 	return 0;
 }
 
 int ixj_release(struct inode *inode, struct file *file_p)
 {
 	IXJ_TONE ti;
-	int board = NUM(inode->i_rdev);
-	IXJ *j = &ixj[board];
+//	int board = NUM(inode->i_rdev);
+	IXJ *j = file_p->private_data;
+	int board = j->p.board;
+//	IXJ *j = &ixj[board];
 
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Closing board %d\n", NUM(inode->i_rdev));
 
 	daa_set_mode(board, SOP_PU_SLEEP);
-	ixj_set_port(board, PORT_POTS);
+	if (j->cardtype == 600)
+		ixj_set_port(board, PORT_SPEAKER);
+	else
+		ixj_set_port(board, PORT_POTS);
 	aec_stop(board);
 	ixj_play_stop(board);
 	ixj_record_stop(board);
+	set_play_volume(board, 0x100);
+	set_rec_volume(board, 0x100);
+	ixj_ring_off(board);
 
+	// Restore the tone table to default settings.
 	ti.tone_index = 10;
 	ti.gain0 = 1;
 	ti.freq0 = hz941;
@@ -1176,6 +1579,10 @@
 
 	idle(board);
 
+//        if(j->cardtype == 600) { // && j->flags.pcmciasct == 1 && j->readers == 1 && j->writers == 1) {
+	SLIC_SetState(PLD_SLIC_STATE_OC, board);
+//      }
+
 	if (file_p->f_mode & FMODE_READ)
 		j->readers--;
 	if (file_p->f_mode & FMODE_WRITE)
@@ -1193,8 +1600,16 @@
 	}
 	j->rec_codec = j->play_codec = 0;
 	j->rec_frame_size = j->play_frame_size = 0;
+	j->flags.cidsent = j->flags.cidring = 0;
 	ixj_fasync(-1, file_p, 0);	// remove from list of async notification
 
+	if(j->cardtype == 300 && !j->readers && !j->writers) {
+		ixj_set_port(board, PORT_PSTN);
+		ixj_set_pots(board, 1);
+	}
+	ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+
+	file_p->private_data = NULL;
 	MOD_DEC_USE_COUNT;
 	return 0;
 }
@@ -1202,6 +1617,7 @@
 static int read_filters(int board)
 {
 	unsigned short fc, cnt;
+	int var;
 	IXJ *j = &ixj[board];
 
 	if (ixj_WriteDSPCommand(0x5144, board))
@@ -1213,6 +1629,11 @@
 
 	j->frame_count = fc;
 
+	if (j->dtmf_proc)
+		return 1;
+
+	var = 10;
+
 	for (cnt = 0; cnt < 4; cnt++) {
 		if (ixj_WriteDSPCommand(0x5154 + cnt, board))
 			return -1;
@@ -1221,8 +1642,108 @@
 			return -1;
 
 		j->filter_hist[cnt] = j->ssr.high << 8 | j->ssr.low;
-		if ((j->filter_hist[cnt] & 1 && !(j->filter_hist[cnt] & 2)) ||
-		(j->filter_hist[cnt] & 2 && !(j->filter_hist[cnt] & 1))) {
+
+		if (j->cadence_f[cnt].enable) {
+			if (j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) {
+				if (j->cadence_f[cnt].state == 0) {
+					j->cadence_f[cnt].state = 1;
+					j->cadence_f[cnt].on1min = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 - var) / 10000);
+					j->cadence_f[cnt].on1dot = jiffies + (j->cadence_f[cnt].on1 * hertz * (100) / 10000);
+					j->cadence_f[cnt].on1max = jiffies + (j->cadence_f[cnt].on1 * hertz * (100 + var) / 10000);
+				} else if (j->cadence_f[cnt].state == 2 &&
+					   (time_after(jiffies, j->cadence_f[cnt].off1min) &&
+					    time_before(jiffies, j->cadence_f[cnt].off1max))) {
+					if (j->cadence_f[cnt].on2) {
+						j->cadence_f[cnt].state = 3;
+						j->cadence_f[cnt].on2min = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 - var) / 10000);
+						j->cadence_f[cnt].on2dot = jiffies + (j->cadence_f[cnt].on2 * hertz * (100) / 10000);
+						j->cadence_f[cnt].on2max = jiffies + (j->cadence_f[cnt].on2 * hertz * (100 + var) / 10000);
+					} else {
+						j->cadence_f[cnt].state = 6;
+					}
+				} else if (j->cadence_f[cnt].state == 4 &&
+					   (time_after(jiffies, j->cadence_f[cnt].off2min) &&
+					    time_before(jiffies, j->cadence_f[cnt].off2max))) {
+					if (j->cadence_f[cnt].on2) {
+						j->cadence_f[cnt].state = 5;
+						j->cadence_f[cnt].on3min = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 - var) / 10000);
+						j->cadence_f[cnt].on3dot = jiffies + (j->cadence_f[cnt].on3 * hertz * (100) / 10000);
+						j->cadence_f[cnt].on3max = jiffies + (j->cadence_f[cnt].on3 * hertz * (100 + var) / 10000);
+					} else {
+						j->cadence_f[cnt].state = 6;
+					}
+				} else {
+					j->cadence_f[cnt].state = 0;
+				}
+			} else if (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)) {
+				if (j->cadence_f[cnt].state == 1 &&
+				    (time_after(jiffies, j->cadence_f[cnt].on1min) &&
+				     time_before(jiffies, j->cadence_f[cnt].on1max))) {
+					j->cadence_f[cnt].state = 2;
+					j->cadence_f[cnt].off1min = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 - var) / 10000);
+					j->cadence_f[cnt].off1max = jiffies + (j->cadence_f[cnt].off1 * hertz * (100 + var) / 10000);
+				} else if (j->cadence_f[cnt].state == 3 &&
+					   (time_after(jiffies, j->cadence_f[cnt].on2min) &&
+					    time_before(jiffies, j->cadence_f[cnt].on2max))) {
+					j->cadence_f[cnt].state = 4;
+					j->cadence_f[cnt].off2min = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 - var) / 10000);
+					j->cadence_f[cnt].off2max = jiffies + (j->cadence_f[cnt].off2 * hertz * (100 + var) / 10000);
+				} else if (j->cadence_f[cnt].state == 5 &&
+					   (time_after(jiffies, j->cadence_f[cnt].on3min) &&
+					    time_before(jiffies, j->cadence_f[cnt].on3max))) {
+					j->cadence_f[cnt].state = 6;
+					j->cadence_f[cnt].off3min = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 - var) / 10000);
+					j->cadence_f[cnt].off3max = jiffies + (j->cadence_f[cnt].off3 * hertz * (100 + var) / 10000);
+				} else {
+					j->cadence_f[cnt].state = 0;
+				}
+			} else {
+				switch(j->cadence_f[cnt].state) {
+					case 1:
+						if(time_after(jiffies, j->cadence_f[cnt].on1dot) &&
+						   !j->cadence_f[cnt].off1 &&
+						   !j->cadence_f[cnt].on2 && !j->cadence_f[cnt].off2 &&
+						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 6;
+						}
+						break;
+					case 3:
+						if(time_after(jiffies, j->cadence_f[cnt].on2dot) &&
+						   !j->cadence_f[cnt].off2 &&
+						   !j->cadence_f[cnt].on3 && !j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 6;
+						}
+						break;
+					case 5:
+						if(time_after(jiffies, j->cadence_f[cnt].on3dot) &&
+						   !j->cadence_f[cnt].off3) {
+							j->cadence_f[cnt].state = 6;
+						}
+						break;
+				}
+			}
+		}
+		if (j->cadence_f[cnt].state == 6) {
+			j->cadence_f[cnt].state = 0;
+			if (j->cadence_f[cnt].enable == 1)
+				j->cadence_f[cnt].enable = 0;
+			switch (cnt) {
+			case 0:
+				j->ex.bits.fc0 = 1;
+				break;
+			case 1:
+				j->ex.bits.fc1 = 1;
+				break;
+			case 2:
+				j->ex.bits.fc2 = 1;
+				break;
+			case 3:
+				j->ex.bits.fc3 = 1;
+				break;
+			}
+		}
+		if (j->filter_en[cnt] && ((j->filter_hist[cnt] & 3 && !(j->filter_hist[cnt] & 12)) ||
+					  (j->filter_hist[cnt] & 12 && !(j->filter_hist[cnt] & 3)))) {
 			switch (cnt) {
 			case 0:
 				j->ex.bits.f0 = 1;
@@ -1263,11 +1784,16 @@
 	}
 	if (j->dtmf_state && !j->dtmf.bits.dtmf_valid)	// && j->dtmf_wp != j->dtmf_rp)
 	 {
-		j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
-		j->dtmf_wp++;
-		if (j->dtmf_wp == 79)
-			j->dtmf_wp = 0;
-		j->ex.bits.dtmf_ready = 1;
+		if(!j->flags.cidplay) {
+			j->dtmfbuffer[j->dtmf_wp] = j->dtmf_current;
+			j->dtmf_wp++;
+			if (j->dtmf_wp == 79)
+				j->dtmf_wp = 0;
+			j->ex.bits.dtmf_ready = 1;
+		}
+		else if(j->dtmf_current == 25 || j->dtmf_current == 31) {
+			j->flags.cidcw_ack = 1;
+		}
 		j->dtmf_state = 0;
 	}
 	j->dtmf_proc = 0;
@@ -1282,26 +1808,38 @@
 	struct wait_queue wait =
 	{current, NULL};
 
+	if (j->flags.inread)
+		return -EALREADY;
+
+	j->flags.inread = 1;
+
 	add_wait_queue(&j->read_q, &wait);
 	current->state = TASK_INTERRUPTIBLE;
 	mb();
 
 	while (!j->read_buffer_ready || (j->dtmf_state && j->flags.dtmf_oob)) {
 		++j->read_wait;
+		if(j->tone_state) {
+			j->flags.inread = 0;
+			return -EAGAIN;
+		}
 		if (file_p->f_flags & O_NONBLOCK) {
 			current->state = TASK_RUNNING;
 			remove_wait_queue(&j->read_q, &wait);
+			j->flags.inread = 0;
 			return -EAGAIN;
 		}
 		if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
 			current->state = TASK_RUNNING;
 			remove_wait_queue(&j->read_q, &wait);
+			j->flags.inread = 0;
 			return 0;
 		}
 		interruptible_sleep_on(&j->read_q);
 		if (signal_pending(current)) {
 			current->state = TASK_RUNNING;
 			remove_wait_queue(&j->read_q, &wait);
+			j->flags.inread = 0;
 			return -EINTR;
 		}
 	}
@@ -1311,10 +1849,13 @@
 	/* Don't ever copy more than the user asks */
 	i = copy_to_user(buf, j->read_buffer, min(length, j->read_buffer_size));
 	j->read_buffer_ready = 0;
-	if (i)
+	if (i) {
+		j->flags.inread = 0;
 		return -EFAULT;
-	else
+	} else {
+		j->flags.inread = 0;
 		return min(length, j->read_buffer_size);
+	}
 }
 
 ssize_t ixj_enhanced_read(struct file * file_p, char *buf, size_t length,
@@ -1342,51 +1883,63 @@
 	return read_retval;
 }
 
-ssize_t ixj_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
+ssize_t ixj_write(struct file *file_p, const char *buf, size_t count, loff_t * ppos)
 {
 	unsigned long i = *ppos;
-	int board = NUM(file_p->f_dentry->d_inode->i_rdev);
-	IXJ *j = &ixj[board];
+	IXJ *j = file_p->private_data;
 	struct wait_queue wait =
 	{current, NULL};
 
-	add_wait_queue(&j->read_q, &wait);
+	if (j->flags.inwrite)
+		return -EALREADY;
+
+	j->flags.inwrite = 1;
+
+	add_wait_queue(&j->write_q, &wait);
 	current->state = TASK_INTERRUPTIBLE;
 	mb();
 
 
 	while (!j->write_buffers_empty) {
 		++j->write_wait;
+		if(j->tone_state) {
+			j->flags.inwrite = 0;
+			return -EAGAIN;
+		}
 		if (file_p->f_flags & O_NONBLOCK) {
 			current->state = TASK_RUNNING;
-			remove_wait_queue(&j->read_q, &wait);
+			remove_wait_queue(&j->write_q, &wait);
+			j->flags.inwrite = 0;
 			return -EAGAIN;
 		}
 		if (!ixj_hookstate(NUM(file_p->f_dentry->d_inode->i_rdev))) {
 			current->state = TASK_RUNNING;
-			remove_wait_queue(&j->read_q, &wait);
+			remove_wait_queue(&j->write_q, &wait);
+			j->flags.inwrite = 0;
 			return 0;
 		}
 		interruptible_sleep_on(&j->write_q);
 		if (signal_pending(current)) {
 			current->state = TASK_RUNNING;
-			remove_wait_queue(&j->read_q, &wait);
+			remove_wait_queue(&j->write_q, &wait);
+			j->flags.inwrite = 0;
 			return -EINTR;
 		}
 	}
 	current->state = TASK_RUNNING;
-	remove_wait_queue(&j->read_q, &wait);
+	remove_wait_queue(&j->write_q, &wait);
 	if (j->write_buffer_wp + count >= j->write_buffer_end)
 		j->write_buffer_wp = j->write_buffer;
 	i = copy_from_user(j->write_buffer_wp, buf, min(count, j->write_buffer_size));
-	if (i)
+	if (i) {
+		j->flags.inwrite = 0;
 		return -EFAULT;
-
+	}
+	j->flags.inwrite = 0;
 	return min(count, j->write_buffer_size);
 }
 
-ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count,
-			   loff_t * ppos)
+ssize_t ixj_enhanced_write(struct file * file_p, const char *buf, size_t count, loff_t * ppos)
 {
 	int pre_retval;
 	ssize_t write_retval = 0;
@@ -1443,9 +1996,7 @@
 			*(j->read_buffer + cnt) = inb_p(j->DSPbase + 0x0E);
 			*(j->read_buffer + cnt + 1) = inb_p(j->DSPbase + 0x0F);
 		}
-#ifdef PERFMON_STATS
 		++j->framesread;
-#endif
 		if (j->intercom != -1) {
 			if (IsTxReady(j->intercom)) {
 				for (cnt = 0; cnt < j->rec_frame_size * 2; cnt += 2) {
@@ -1462,21 +2013,478 @@
 					outb_p(*(j->read_buffer + cnt), ixj[j->intercom].DSPbase + 0x0C);
 					outb_p(*(j->read_buffer + cnt + 1), ixj[j->intercom].DSPbase + 0x0D);
 				}
-#ifdef PERFMON_STATS
 				++ixj[j->intercom].frameswritten;
-#endif
 			}
 		} else {
 			j->read_buffer_ready = 1;
 			wake_up_interruptible(&j->read_q);	// Wake any blocked readers
 
-			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
+			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
+
+			ixj_kill_fasync(board);
+		}
+	}
+}
+
+static short fsk[][6][20] =
+{
+	{
+		{
+			0, 17846, 29934, 32364, 24351, 8481, -10126, -25465, -32587, -29196,
+			-16384, 1715, 19260, 30591, 32051, 23170, 6813, -11743, -26509, -32722
+		},
+		{
+			-28377, -14876, 3425, 20621, 31163, 31650, 21925, 5126, -13328, -27481,
+			-32767, -27481, -13328, 5126, 21925, 31650, 31163, 20621, 3425, -14876
+		},
+		{
+			-28377, -32722, -26509, -11743, 6813, 23170, 32051, 30591, 19260, 1715,
+			-16384, -29196, -32587, -25465, -10126, 8481, 24351, 32364, 29934, 17846
+		},
+		{
+			0, -17846, -29934, -32364, -24351, -8481, 10126, 25465, 32587, 29196,
+			16384, -1715, -19260, -30591, -32051, -23170, -6813, 11743, 26509, 32722
+		},
+		{
+			28377, 14876, -3425, -20621, -31163, -31650, -21925, -5126, 13328, 27481,
+			32767, 27481, 13328, -5126, -21925, -31650, -31163, -20621, -3425, 14876
+		},
+		{
+			28377, 32722, 26509, 11743, -6813, -23170, -32051, -30591, -19260, -1715,
+			16384, 29196, 32587, 25465, 10126, -8481, -24351, -32364, -29934, -17846
+		}
+	},
+	{
+		{
+			0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126,
+			0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126
+		},
+		{
+			-28377, -21925, -13328, -3425, 6813, 16384, 24351, 29934, 32587, 32051,
+			28377, 21925, 13328, 3425, -6813, -16384, -24351, -29934, -32587, -32051
+		},
+		{
+			-28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925,
+			28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925
+		},
+		{
+			0, -10126, -19260, -26509, -31163, -32767, -31163, -26509, -19260, -10126,
+			0, 10126, 19260, 26509, 31163, 32767, 31163, 26509, 19260, 10126
+		},
+		{
+			28377, 21925, 13328, 3425, -6813, -16383, -24351, -29934, -32587, -32051,
+			-28377, -21925, -13328, -3425, 6813, 16383, 24351, 29934, 32587, 32051
+		},
+		{
+			28377, 32051, 32587, 29934, 24351, 16384, 6813, -3425, -13328, -21925,
+			-28377, -32051, -32587, -29934, -24351, -16384, -6813, 3425, 13328, 21925
+		}
+	}
+};
+
+
+static void ixj_write_cid_bit(int board, int bit)
+{
+	int dly;
+	IXJ_WORD dat;
+	IXJ *j = &ixj[board];
+
+	while (j->fskcnt < 20) {
+		if (!IsTxReady(board)) {
+			dly = 0;
+			while (!IsTxReady(board)) {
+				if (dly++ > 5) {
+					dly = 0;
+					//      break;
+					//      printk("CID delay\n");
+				}
+				udelay(10);
+			}
+		}
+		dat.word = j->fskdata[j->fskdcnt++] =
+		    fsk[bit][j->fskz][j->fskcnt];
+		outb_p(dat.bytes.low, j->DSPbase + 0x0C);
+		outb_p(dat.bytes.high, j->DSPbase + 0x0D);
+		j->fskcnt += 3;
+	}
+	j->fskcnt %= 20;
+
+	if (!bit)
+		j->fskz++;
+	if (j->fskz >= 6)
+		j->fskz = 0;
+
+}
+
+static void ixj_write_cid_byte(int board, char byte)
+{
+	IXJ_CBYTE cb;
+
+//  printk("Writing CID data %x - %c\n", byte, byte);
+	cb.cbyte = byte;
+	ixj_write_cid_bit(board, 0);
+	ixj_write_cid_bit(board, cb.cbits.b0 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b1 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b2 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b3 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b4 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b5 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b6 ? 1 : 0);
+	ixj_write_cid_bit(board, cb.cbits.b7 ? 1 : 0);
+	ixj_write_cid_bit(board, 1);
+}
+
+static void ixj_write_cid_seize(int board)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < 150; cnt++) {
+		ixj_write_cid_bit(board, 0);
+		ixj_write_cid_bit(board, 1);
+	}
+	for (cnt = 0; cnt < 180; cnt++) {
+		ixj_write_cid_bit(board, 1);
+	}
+}
+
+static void ixj_write_cidcw_seize(int board)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < 80; cnt++) {
+		ixj_write_cid_bit(board, 1);
+	}
+}
+
+static int ixj_write_cid_string(int board, char *s, int checksum)
+{
+	int cnt;
+
+	for (cnt = 0; cnt < strlen(s); cnt++) {
+		ixj_write_cid_byte(board, s[cnt]);
+		checksum = (checksum + s[cnt]);
+	}
+	return checksum;
+}
+
+static void ixj_pad_fsk(int board, int pad)
+{
+	int cnt, dly;
+	IXJ *j = &ixj[board];
+
+	for (cnt = 0; cnt < pad; cnt++) {
+		if (!IsTxReady(board)) {
+			dly = 0;
+			while (!IsTxReady(board)) {
+				if (dly++ > 5) {
+					dly = 0;
+				}
+				udelay(10);
+			}
+		}
+		outb_p(0x00, j->DSPbase + 0x0C);
+		outb_p(0x00, j->DSPbase + 0x0D);
+	}
+	for (cnt = 0; cnt < 720; cnt++) {
+		if (!IsTxReady(board)) {
+			dly = 0;
+			while (!IsTxReady(board)) {
+				if (dly++ > 5) {
+					dly = 0;
+				}
+				udelay(10);
+			}
+		}
+		outb_p(0x00, j->DSPbase + 0x0C);
+		outb_p(0x00, j->DSPbase + 0x0D);
+	}
+}
+
+static void ixj_write_cid(int board)
+{
+	IXJ *j = &ixj[board];
+
+	char sdmf1[50];
+	char sdmf2[50];
+	char sdmf3[80];
+	char mdmflen, len1, len2, len3;
+	int pad;
+
+	int checksum = 0;
+
+	if (ixj[board].dsp.low == 0x20)
+		return;
+
+	ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt =
+	    ixj[board].fskdcnt = 0;
+
+	ixj[board].flags.cidplay = 1;
+
+	strcpy(sdmf1, j->cid_send.month);
+	strcat(sdmf1, j->cid_send.day);
+	strcat(sdmf1, j->cid_send.hour);
+	strcat(sdmf1, j->cid_send.min);
+	strcpy(sdmf2, j->cid_send.number);
+	strcpy(sdmf3, j->cid_send.name);
+
+	len1 = strlen(sdmf1);
+	len2 = strlen(sdmf2);
+	len3 = strlen(sdmf3);
+	mdmflen = len1 + len2 + len3 + 6;
+
+	printk("CID Lengths = %d %d %d %d\n", len1, len2, len3, mdmflen);
+
+	set_base_frame(board, 30);
+	set_play_codec(board, LINEAR16);
+
+	if (ixj[board].port == PORT_POTS)
+		if(!j->r_hook)
+			SLIC_SetState(PLD_SLIC_STATE_OHT, board);
+
+	set_play_volume(board, 0x1B);
+	ixj_play_start(board);
+	ixj_write_cid_seize(board);
+
+	ixj_write_cid_byte(board, 0x80);
+	checksum = 0x80;
+	ixj_write_cid_byte(board, mdmflen);
+	checksum = checksum + mdmflen;
+
+	ixj_write_cid_byte(board, 0x01);
+	checksum = checksum + 0x01;
+	ixj_write_cid_byte(board, len1);
+	checksum = checksum + len1;
+	checksum = ixj_write_cid_string(board, sdmf1, checksum);
+
+	ixj_write_cid_byte(board, 0x02);
+	checksum = checksum + 0x02;
+	ixj_write_cid_byte(board, len2);
+	checksum = checksum + len2;
+	checksum = ixj_write_cid_string(board, sdmf2, checksum);
+
+	ixj_write_cid_byte(board, 0x07);
+	checksum = checksum + 0x07;
+	ixj_write_cid_byte(board, len3);
+	checksum = checksum + len3;
+	checksum = ixj_write_cid_string(board, sdmf3, checksum);
+
+	checksum %= 256;
+	checksum ^= 0xFF;
+	checksum += 1;
+	printk("14Checksum = %d\n", checksum);
+
+	ixj_write_cid_byte(board, (char) checksum);
+
+	pad = j->fskdcnt % 240;
+	if (pad) {
+		pad = 240 - pad;
+	}
+	ixj_pad_fsk(board, pad);
+	SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+	ixj[board].flags.cidplay = 0;
+	ixj_play_stop(board);
+}
+
+static void ixj_write_cidcw(int board)
+{
+	IXJ_TONE ti;
+
+	IXJ *j = &ixj[board];
+
+	char sdmf1[50];
+	char sdmf2[50];
+	char sdmf3[80];
+	char mdmflen, len1, len2, len3;
+	int pad;
+
+	int checksum = 0;
+
+	if (ixj[board].dsp.low == 0x20)
+		return;
+
+	ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt = ixj[board].fskdcnt = 0;
+
+	ixj[board].flags.cidplay = 1;
+
+	ti.tone_index = 23;
+	ti.gain0 = 1;
+	ti.freq0 = hz440;
+	ti.gain1 = 0;
+	ti.freq1 = 0;
+	ixj_init_tone(board, &ti);
+
+	ti.tone_index = 24;
+	ti.gain0 = 1;
+	ti.freq0 = hz2130;
+	ti.gain1 = 0;
+	ti.freq1 = hz2750;
+	ixj_init_tone(board, &ti);
+
+	ixj_set_tone_on(1200, board);
+	ixj_play_tone(board, 23);
+
+	while(j->tone_state) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+
+	ixj_set_tone_on(320, board);
+	ixj_play_tone(board, 24);
+
+	while(j->tone_state) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+
+	j->cidcw_wait = jiffies + (200 * hertz / 100000);
+
+	while(!j->flags.cidcw_ack && time_before(jiffies, j->cidcw_wait)) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+
+	if(!j->flags.cidcw_ack) {
+		return;
+	}
+
+	strcpy(sdmf1, j->cid_send.month);
+	strcat(sdmf1, j->cid_send.day);
+	strcat(sdmf1, j->cid_send.hour);
+	strcat(sdmf1, j->cid_send.min);
+	strcpy(sdmf2, j->cid_send.number);
+	strcpy(sdmf3, j->cid_send.name);
+
+	len1 = strlen(sdmf1);
+	len2 = strlen(sdmf2);
+	len3 = strlen(sdmf3);
+	mdmflen = len1 + len2 + len3 + 6;
+
+	printk("CID Lengths = %d %d %d %d\n", len1, len2, len3, mdmflen);
+
+	j->cid_play_codec = j->play_codec;
+	ixj_play_stop(board);
+
+	switch(j->baseframe.low) {
+		case 0xA0:
+			j->cid_base_frame_size = 20;
+			break;
+		case 0x50:
+			j->cid_base_frame_size = 10;
+			break;
+		default:
+			j->cid_base_frame_size = 30;
+			break;
+	}
+	set_base_frame(board, 30);
+	set_play_codec(board, LINEAR16);
+
+	set_play_volume(board, 0x1B);
+	ixj_play_start(board);
+	ixj_write_cidcw_seize(board);
+
+	ixj_write_cid_byte(board, 0x80);
+	checksum = 0x80;
+	ixj_write_cid_byte(board, mdmflen);
+	checksum = checksum + mdmflen;
+
+	ixj_write_cid_byte(board, 0x01);
+	checksum = checksum + 0x01;
+	ixj_write_cid_byte(board, len1);
+	checksum = checksum + len1;
+	checksum = ixj_write_cid_string(board, sdmf1, checksum);
+
+	ixj_write_cid_byte(board, 0x02);
+	checksum = checksum + 0x02;
+	ixj_write_cid_byte(board, len2);
+	checksum = checksum + len2;
+	checksum = ixj_write_cid_string(board, sdmf2, checksum);
+
+	ixj_write_cid_byte(board, 0x07);
+	checksum = checksum + 0x07;
+	ixj_write_cid_byte(board, len3);
+	checksum = checksum + len3;
+	checksum = ixj_write_cid_string(board, sdmf3, checksum);
+
+	checksum %= 256;
+	checksum ^= 0xFF;
+	checksum += 1;
+	printk("14Checksum = %d\n", checksum);
+
+	ixj_write_cid_byte(board, (char) checksum);
+
+	pad = j->fskdcnt % 240;
+	if (pad) {
+		pad = 240 - pad;
+	}
+	ixj_pad_fsk(board, pad);
+	ixj[board].flags.cidplay = 0;
+	ixj_play_stop(board);
+
+	set_base_frame(board, j->cid_base_frame_size);
+	set_play_codec(board, j->cid_play_codec);
+}
+
+static void ixj_write_vmwi(int board, int msg)
+{
+	IXJ *j = &ixj[board];
 
-			if (j->async_queue)
-				kill_fasync(j->async_queue, SIGIO);	// Send apps notice of frame
+	char mdmflen;
+	int pad;
 
-		}
+	int checksum = 0;
+
+	if (ixj[board].dsp.low == 0x20)
+		return;
+
+	ixj[board].fskz = ixj[board].fskphase = ixj[board].fskcnt = ixj[board].fskdcnt = 0;
+
+	ixj[board].flags.cidplay = 1;
+
+	mdmflen = 3;
+
+	set_base_frame(board, 30);
+	set_play_codec(board, LINEAR16);
+
+	if (ixj[board].port == PORT_POTS)
+		SLIC_SetState(PLD_SLIC_STATE_OHT, board);
+
+	set_play_volume(board, 0x1B);
+	ixj_play_start(board);
+	ixj_write_cid_seize(board);
+
+	ixj_write_cid_byte(board, 0x82);
+	checksum = 0x82;
+	ixj_write_cid_byte(board, mdmflen);
+	checksum = checksum + mdmflen;
+
+	ixj_write_cid_byte(board, 0x0B);
+	checksum = checksum + 0x0B;
+	ixj_write_cid_byte(board, 1);
+	checksum = checksum + 1;
+
+	if(msg) {
+		ixj_write_cid_byte(board, 0xFF);
+		checksum = checksum + 0xFF;
 	}
+	else {
+		ixj_write_cid_byte(board, 0x00);
+		checksum = checksum + 0x00;
+	}
+
+	checksum %= 256;
+	checksum ^= 0xFF;
+	checksum += 1;
+
+	ixj_write_cid_byte(board, (char) checksum);
+
+	pad = j->fskdcnt % 240;
+	if (pad) {
+		pad = 240 - pad;
+	}
+	ixj_pad_fsk(board, pad);
+	SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+	ixj[board].flags.cidplay = 0;
+	ixj_play_stop(board);
 }
 
 static void ixj_write_frame(int board)
@@ -1554,15 +2562,12 @@
 				j->write_buffer_rp = j->write_buffer;
 			}
 			j->write_buffers_empty++;
-			wake_up_interruptible(&(j->write_q));	// Wake any blocked writers
+			wake_up_interruptible(&j->write_q);	// Wake any blocked writers
 
 			wake_up_interruptible(&j->poll_q);	// Wake any blocked selects
 
-			if (j->async_queue)
-				kill_fasync(j->async_queue, SIGIO);	// Send apps notice of empty buffer
-#ifdef PERFMON_STATS
+			ixj_kill_fasync(board);
 			++j->frameswritten;
-#endif
 		}
 	} else {
 		j->drybuffer++;
@@ -1795,6 +2800,12 @@
 	unsigned short cmd = 0x0000;
 	IXJ *j = &ixj[board];
 
+	if (j->read_buffer) {
+		ixj_record_stop(board);
+	}
+	j->flags.recording = 1;
+	ixj_WriteDSPCommand(0x0FE0, board);	// Put the DSP in full power mode.
+
 	if (!j->rec_mode) {
 		switch (j->rec_codec) {
 		case G723_63:
@@ -1893,10 +2904,26 @@
 {
 	IXJ *j = &ixj[board];
 
+	if (j->read_buffer) {
+		kfree(j->read_buffer);
+		j->read_buffer = NULL;
+		j->read_buffer_size = 0;
+	}
 	if (j->rec_mode > -1) {
 		ixj_WriteDSPCommand(0x5120, board);
 		j->rec_mode = -1;
 	}
+	j->flags.recording = 0;
+	if (!j->flags.playing)
+		ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+
+}
+static void ixj_vad(int board, int arg)
+{
+	if (arg)
+		ixj_WriteDSPCommand(0x513F, board);
+	else
+		ixj_WriteDSPCommand(0x513E, board);
 }
 
 static void set_rec_depth(int board, int depth)
@@ -1914,13 +2941,23 @@
 	ixj_WriteDSPCommand(volume, board);
 }
 
+static int get_rec_volume(int board)
+{
+	ixj_WriteDSPCommand(0xCF03, board);
+	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+}
+
 static int get_rec_level(int board)
 {
+	int retval;
+
 	IXJ *j = &ixj[board];
 
 	ixj_WriteDSPCommand(0xCF88, board);
 
-	return j->ssr.high << 8 | j->ssr.low;
+	retval = j->ssr.high << 8 | j->ssr.low;
+	retval = (retval * 256) / 240;
+	return retval;
 }
 
 static void ixj_aec_start(int board, int level)
@@ -1929,7 +2966,7 @@
 
 	j->aec_level = level;
 	if (!level) {
-		ixj_WriteDSPCommand(0xB002, board);
+		aec_stop(board);
 	} else {
 		if (j->rec_codec == G729 || j->play_codec == G729) {
 			ixj_WriteDSPCommand(0xE022, board);	// Move AEC filter buffer
@@ -1941,26 +2978,41 @@
 		ixj_WriteDSPCommand(0xE013, board);	// Advanced AEC C1
 
 		switch (level) {
-		case 1:
+		case AEC_LOW:
 			ixj_WriteDSPCommand(0x0000, board);	// Advanced AEC C2 = off
 
 			ixj_WriteDSPCommand(0xE011, board);
 			ixj_WriteDSPCommand(0xFFFF, board);
 			break;
 
-		case 2:
+		case AEC_MED:
 			ixj_WriteDSPCommand(0x0600, board);	// Advanced AEC C2 = on medium
 
 			ixj_WriteDSPCommand(0xE011, board);
 			ixj_WriteDSPCommand(0x0080, board);
 			break;
 
-		case 3:
+		case AEC_HIGH:
 			ixj_WriteDSPCommand(0x0C00, board);	// Advanced AEC C2 = on high
 
 			ixj_WriteDSPCommand(0xE011, board);
 			ixj_WriteDSPCommand(0x0080, board);
 			break;
+
+		case AEC_AUTO:
+			ixj_WriteDSPCommand(0x0002, board);	// Attenuation scaling factor of 2
+
+			ixj_WriteDSPCommand(0xE011, board);
+			ixj_WriteDSPCommand(0x0100, board);	// Higher Threshold Floor
+
+			ixj_WriteDSPCommand(0xE012, board);	// Set Train and Lock
+
+			ixj_WriteDSPCommand(0x0023, board);
+
+			ixj_WriteDSPCommand(0xE014, board);
+			ixj_WriteDSPCommand(0x0003, board);	// Lock threashold at 3dB
+
+			break;
 		}
 	}
 }
@@ -2148,6 +3200,12 @@
 	unsigned short cmd = 0x0000;
 	IXJ *j = &ixj[board];
 
+	if (j->write_buffer) {
+		ixj_play_stop(board);
+	}
+	j->flags.playing = 1;
+	ixj_WriteDSPCommand(0x0FE0, board);	// Put the DSP in full power mode.
+
 	j->flags.play_first_frame = 1;
 	j->drybuffer = 0;
 
@@ -2183,12 +3241,10 @@
 		if (ixj_WriteDSPCommand(cmd, board))
 			return -1;
 	}
+	j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
 	if (!j->write_buffer) {
-		j->write_buffer = kmalloc(j->play_frame_size * 2, GFP_ATOMIC);
-		if (!j->write_buffer) {
-			printk("Write buffer allocation for ixj board %d failed!\n", board);
-			return -ENOMEM;
-		}
+		printk("Write buffer allocation for ixj board %d failed!\n", board);
+		return -ENOMEM;
 	}
 	j->write_buffers_empty = 2;
 	j->write_buffer_size = j->play_frame_size * 2;
@@ -2250,11 +3306,20 @@
 {
 	IXJ *j = &ixj[board];
 
+	if (j->write_buffer) {
+		kfree(j->write_buffer);
+		j->write_buffer = NULL;
+		j->write_buffer_size = 0;
+	}
 	if (j->play_mode > -1) {
-		ixj_WriteDSPCommand(0x5221, board);	// Stop playback
+		ixj_WriteDSPCommand(0x5221, board);	// Stop playback and flush buffers.  8022 reference page 9-40
 
 		j->play_mode = -1;
 	}
+	j->flags.playing = 0;
+	if (!j->flags.recording)
+		ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
+
 }
 
 extern __inline__ void set_play_depth(int board, int depth)
@@ -2266,16 +3331,15 @@
 	ixj_WriteDSPCommand(0x5280 + depth, board);
 }
 
-extern __inline__ void set_play_volume(int board, int volume)
-{
-	ixj_WriteDSPCommand(0xCF02, board);
-	ixj_WriteDSPCommand(volume, board);
-}
-
 extern __inline__ int get_play_level(int board)
 {
-	ixj_WriteDSPCommand(0xCF8F, board);
+	int retval;
+
+	ixj_WriteDSPCommand(0xCF8F, board); // 8022 Reference page 9-38
 	return ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+	retval = ixj[board].ssr.high << 8 | ixj[board].ssr.low;
+	retval = (retval * 256) / 240;
+	return retval;
 }
 
 static unsigned int ixj_poll(struct file *file_p, poll_table * wait)
@@ -2484,6 +3548,8 @@
 		break;
 	}
 
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = reg;
+
 	switch (j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGX) {
 	case 0:
 		j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.bitreg.AGR_Z = 0;
@@ -2653,7 +3719,7 @@
 		}
 		pIn += 5, pOut += 4;
 	}
-	memset(&j->cid, 0, sizeof(IXJ_CID));
+	memset(&j->cid, 0, sizeof(PHONE_CID));
 	pOut = j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID;
 	pOut += 4;
 	strncpy(j->cid.month, pOut, 2);
@@ -2729,7 +3795,6 @@
 	//      ALIS-A part.
 	//
 
-
 	BYTES bytes;
 	IXJ *j = &ixj[board];
 
@@ -2738,6 +3803,19 @@
 
 	switch (mode) {
 	case SOP_PU_SLEEP:
+		if(j->daa_mode == SOP_PU_CONVERSATION)
+		{
+			j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
+
+			outb_p(j->pld_scrw.byte, j->XILINXbase);
+			j->pld_slicw.bits.rly2 = 0;
+			outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+			bytes.high = 0x10;
+			bytes.low = j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg;
+			daa_load(&bytes, board);
+			if (!SCI_Prepare(board))
+				return 0;
+		}
 		j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
 
 		outb_p(j->pld_scrw.byte, j->XILINXbase);
@@ -2748,10 +3826,15 @@
 		daa_load(&bytes, board);
 		if (!SCI_Prepare(board))
 			return 0;
+
 		j->daa_mode = SOP_PU_SLEEP;
 		j->flags.pstn_ringing = 0;
-		j->pstn_sleeptil = jiffies + (hertz * 3);
-		break;
+		j->ex.bits.pstn_ring = 0;
+		j->pstn_sleeptil = jiffies + (hertz / 2);
+		wake_up_interruptible(&j->read_q);      // Wake any blocked readers
+		wake_up_interruptible(&j->write_q);     // Wake any blocked writers
+		wake_up_interruptible(&j->poll_q);      // Wake any blocked selects
+ 		break;
 	case SOP_PU_RINGING:
 		j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
 
@@ -3289,14 +4372,11 @@
 int ixj_set_tone_off(unsigned short arg, int board)
 {
 	ixj[board].tone_off_time = arg;
-
 	if (ixj_WriteDSPCommand(0x6E05, board))		// Set Tone Off Period
 
 		return -1;
-
 	if (ixj_WriteDSPCommand(arg, board))
 		return -1;
-
 	return 0;
 }
 
@@ -3305,7 +4385,6 @@
 	if (ixj_WriteDSPCommand(0x6E06, board))		// Get Tone On Period
 
 		return -1;
-
 	return 0;
 }
 
@@ -3314,7 +4393,6 @@
 	if (ixj_WriteDSPCommand(0x6E07, board))		// Get Tone Off Period
 
 		return -1;
-
 	return 0;
 }
 
@@ -3323,7 +4401,6 @@
 	ixj[board].flags.ringback = 0;
 	ixj[board].flags.dialtone = 0;
 	ixj[board].flags.busytone = 1;
-
 	ixj_set_tone_on(0x07D0, board);
 	ixj_set_tone_off(0x07D0, board);
 	ixj_play_tone(board, 27);
@@ -3334,13 +4411,11 @@
 	ixj[board].flags.ringback = 0;
 	ixj[board].flags.dialtone = 1;
 	ixj[board].flags.busytone = 0;
-
 	if (ixj[board].dsp.low == 0x20) {
 		return;
 	} else {
 		ixj_set_tone_on(0xFFFF, board);
 		ixj_set_tone_off(0x0000, board);
-
 		ixj_play_tone(board, 25);
 	}
 }
@@ -3348,28 +4423,24 @@
 static void ixj_cpt_stop(board)
 {
 	IXJ *j = &ixj[board];
-
-	j->flags.dialtone = 0;
-	j->flags.busytone = 0;
-	j->flags.ringback = 0;
-
-	ixj_set_tone_on(0x0001, board);
-	ixj_set_tone_off(0x0000, board);
-
-	ixj_play_tone(board, 0);
-
-	j->tone_state = 0;
-
-	ixj_del_timer();
-	if (j->cadence_t) {
-		if (j->cadence_t->ce) {
-			kfree(j->cadence_t->ce);
+	if(j->tone_state)
+	{
+		j->flags.dialtone = 0;
+		j->flags.busytone = 0;
+		j->flags.ringback = 0;
+		ixj_set_tone_on(0x0001, board);
+		ixj_set_tone_off(0x0000, board);
+		ixj_play_tone(board, 0);
+		j->tone_state = 0;
+		if (j->cadence_t) {
+			if (j->cadence_t->ce) {
+				kfree(j->cadence_t->ce);
+			}
+			kfree(j->cadence_t);
+			j->cadence_t = NULL;
 		}
-		kfree(j->cadence_t);
-		j->cadence_t = NULL;
 	}
-	ixj_add_timer();
-	if (j->dsp.low == 0x20 || (j->play_mode == -1 && j->rec_mode == -1))
+	if (j->play_mode == -1 && j->rec_mode == -1)
 		idle(board);
 	if (j->play_mode != -1)
 		ixj_play_start(board);
@@ -3382,7 +4453,6 @@
 	ixj[board].flags.busytone = 0;
 	ixj[board].flags.dialtone = 0;
 	ixj[board].flags.ringback = 1;
-
 	ixj_set_tone_on(0x0FA0, board);
 	ixj_set_tone_off(0x2EE0, board);
 	ixj_play_tone(board, 26);
@@ -3399,14 +4469,11 @@
 	IXJ_CADENCE_ELEMENT *lcep;
 	IXJ_TONE ti;
 	IXJ *j = &ixj[board];
-
 	lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
 	if (lcp == NULL)
 		return -ENOMEM;
-
 	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_CADENCE)))
 		return -EFAULT;
-
 	lcep = kmalloc(sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used, GFP_KERNEL);
 	if (lcep == NULL) {
 		kfree(lcp);
@@ -3414,13 +4481,10 @@
 	}
 	if (copy_from_user(lcep, lcp->ce, sizeof(IXJ_CADENCE_ELEMENT) * lcp->elements_used))
 		return -EFAULT;
-
-	if(j->cadence_t)
-	{
+	if (j->cadence_t) {
 		kfree(j->cadence_t->ce);
 		kfree(j->cadence_t);
 	}
-	
 	lcp->ce = (void *) lcep;
 	j->cadence_t = lcp;
 	j->tone_cadence_state = 0;
@@ -3435,16 +4499,50 @@
 		ixj_init_tone(board, &ti);
 	}
 	ixj_play_tone(board, lcp->ce[0].index);
-
 	return 1;
 }
 
+static int ixj_build_filter_cadence(int board, IXJ_FILTER_CADENCE * cp)
+{
+	IXJ_FILTER_CADENCE *lcp;
+	IXJ *j = &ixj[board];
+	lcp = kmalloc(sizeof(IXJ_CADENCE), GFP_KERNEL);
+	if (lcp == NULL)
+		return -ENOMEM;
+	if (copy_from_user(lcp, (char *) cp, sizeof(IXJ_FILTER_CADENCE)))
+		return -EFAULT;
+	if (lcp->filter > 4)
+		return -1;
+	j->cadence_f[lcp->filter].state = 0;
+	j->cadence_f[lcp->filter].enable = lcp->enable;
+	j->filter_en[lcp->filter] = j->cadence_f[lcp->filter].en_filter = lcp->en_filter;
+	j->cadence_f[lcp->filter].on1 = lcp->on1;
+	j->cadence_f[lcp->filter].on1min = 0;
+	j->cadence_f[lcp->filter].on1max = 0;
+	j->cadence_f[lcp->filter].off1 = lcp->off1;
+	j->cadence_f[lcp->filter].off1min = 0;
+	j->cadence_f[lcp->filter].off1max = 0;
+	j->cadence_f[lcp->filter].on2 = lcp->on2;
+	j->cadence_f[lcp->filter].on2min = 0;
+	j->cadence_f[lcp->filter].on2max = 0;
+	j->cadence_f[lcp->filter].off2 = lcp->off2;
+	j->cadence_f[lcp->filter].off2min = 0;
+	j->cadence_f[lcp->filter].off2max = 0;
+	j->cadence_f[lcp->filter].on3 = lcp->on3;
+	j->cadence_f[lcp->filter].on3min = 0;
+	j->cadence_f[lcp->filter].on3max = 0;
+	j->cadence_f[lcp->filter].off3 = lcp->off3;
+	j->cadence_f[lcp->filter].off3min = 0;
+	j->cadence_f[lcp->filter].off3max = 0;
+	kfree(lcp);
+	return 0;
+}
+
 static void add_caps(int board)
 {
 	IXJ *j = &ixj[board];
 	j->caps = 0;
-
-	j->caplist[j->caps].cap = vendor;
+	j->caplist[j->caps].cap = PHONE_VENDOR_QUICKNET;
 	strcpy(j->caplist[j->caps].desc, "Quicknet Technologies, Inc. (www.quicknet.net)");
 	j->caplist[j->caps].captype = vendor;
 	j->caplist[j->caps].handle = j->caps++;
@@ -3540,10 +4638,9 @@
 	int cnt;
 	IXJ *j = &ixj[board];
 	int retval = 0;
-
 	for (cnt = 0; cnt < j->caps; cnt++) {
-		if (pcreq->captype == j->caplist[cnt].captype &&
-		    pcreq->cap == j->caplist[cnt].cap) {
+		if (pcreq->captype == j->caplist[cnt].captype
+		    && pcreq->cap == j->caplist[cnt].cap) {
 			retval = 1;
 			break;
 		}
@@ -3551,8 +4648,7 @@
 	return retval;
 }
 
-int ixj_ioctl(struct inode *inode, struct file *file_p,
-	      unsigned int cmd, unsigned long arg)
+int ixj_ioctl(struct inode *inode, struct file *file_p, unsigned int cmd, unsigned long arg)
 {
 	IXJ_TONE ti;
 	IXJ_FILTER jf;
@@ -3560,16 +4656,13 @@
 	int board = NUM(inode->i_rdev);
 	IXJ *j = &ixj[NUM(inode->i_rdev)];
 	int retval = 0;
-
 	if (ixjdebug > 1)
 		printk(KERN_DEBUG "phone%d ioctl, cmd: 0x%x, arg: 0x%lx\n", minor, cmd, arg);
 	if (minor >= IXJMAX)
 		return -ENODEV;
-
 	/*
 	 *    Check ioctls only root can use.
 	 */
-
 	if (!capable(CAP_SYS_ADMIN)) {
 		switch (cmd) {
 		case IXJCTL_TESTRAM:
@@ -3588,10 +4681,33 @@
 	case IXJCTL_SERIAL:
 		retval = j->serial;
 		break;
+	case IXJCTL_VERSION:
+		if (copy_to_user((char *) arg, ixj_c_revision, strlen(ixj_c_revision)))
+			return -EFAULT;
+		break;
 	case PHONE_RING_CADENCE:
 		j->ring_cadence = arg;
 		break;
+	case IXJCTL_CIDCW:
+		if(arg) {
+			copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+		}
+		else {
+			memcpy(&j->cid_send, 0, sizeof(PHONE_CID));
+		}
+		ixj_write_cidcw(board);
+		break;
+	/* Binary compatbility */
+	case OLD_PHONE_RING_START:
+		arg = 0;
+		/* Fall through */
 	case PHONE_RING_START:
+		if(arg) {
+			copy_from_user(&j->cid_send, (char *)arg, sizeof(PHONE_CID));
+		}
+		else {
+			memcpy(&j->cid_send, 0, sizeof(PHONE_CID));
+		}
 		ixj_ring_start(board);
 		break;
 	case PHONE_RING_STOP:
@@ -3603,7 +4719,19 @@
 		break;
 	case PHONE_EXCEPTION:
 		retval = j->ex.bytes;
-		j->ex.bytes &= 0x03;
+		j->ex.bits.flash = 0;
+		j->ex.bits.pstn_ring = 0;
+		j->ex.bits.caller_id = 0;
+		j->ex.bits.pstn_wink = 0;
+		j->ex.bits.f0 = 0;
+		j->ex.bits.f1 = 0;
+		j->ex.bits.f2 = 0;
+		j->ex.bits.f3 = 0;
+		j->ex.bits.fc0 = 0;
+		j->ex.bits.fc1 = 0;
+		j->ex.bits.fc2 = 0;
+		j->ex.bits.fc3 = 0;
+		j->ex.bits.reserved = 0;
 		break;
 	case PHONE_HOOKSTATE:
 		j->ex.bits.hookstate = 0;
@@ -3618,6 +4746,9 @@
 	case PHONE_REC_CODEC:
 		retval = set_rec_codec(board, arg);
 		break;
+	case PHONE_VAD:
+		ixj_vad(board, arg);
+		break;
 	case PHONE_REC_START:
 		ixj_record_start(board);
 		break;
@@ -3628,7 +4759,13 @@
 		set_rec_depth(board, arg);
 		break;
 	case PHONE_REC_VOLUME:
-		set_rec_volume(board, arg);
+		if(arg == -1) {
+			retval = get_rec_volume(board);
+		}
+		else {
+			set_rec_volume(board, arg);
+			retval = arg;
+		}
 		break;
 	case PHONE_REC_LEVEL:
 		retval = get_rec_level(board);
@@ -3646,7 +4783,7 @@
 		retval = set_play_codec(board, arg);
 		break;
 	case PHONE_PLAY_START:
-		ixj_play_start(board);
+		retval = ixj_play_start(board);
 		break;
 	case PHONE_PLAY_STOP:
 		ixj_play_stop(board);
@@ -3655,7 +4792,13 @@
 		set_play_depth(board, arg);
 		break;
 	case PHONE_PLAY_VOLUME:
-		set_play_volume(board, arg);
+		if(arg == -1) {
+			retval = get_play_volume(board);
+		}
+		else {
+			set_play_volume(board, arg);
+			retval = arg;
+		}
 		break;
 	case PHONE_PLAY_LEVEL:
 		retval = get_play_level(board);
@@ -3836,41 +4979,45 @@
 		switch (arg) {
 		case DAA_US:
 			DAA_Coeff_US(board);
-			ixj_daa_write(board);
+			retval = ixj_daa_write(board);
 			break;
 		case DAA_UK:
 			DAA_Coeff_UK(board);
-			ixj_daa_write(board);
+			retval = ixj_daa_write(board);
 			break;
 		case DAA_FRANCE:
 			DAA_Coeff_France(board);
-			ixj_daa_write(board);
+			retval = ixj_daa_write(board);
 			break;
 		case DAA_GERMANY:
 			DAA_Coeff_Germany(board);
-			ixj_daa_write(board);
+			retval = ixj_daa_write(board);
 			break;
 		case DAA_AUSTRALIA:
 			DAA_Coeff_Australia(board);
-			ixj_daa_write(board);
+			retval = ixj_daa_write(board);
 			break;
 		case DAA_JAPAN:
 			DAA_Coeff_Japan(board);
-			ixj_daa_write(board);
+			retval = ixj_daa_write(board);
 			break;
 		default:
+			retval = 1;
 			break;
 		}
+		j->country = arg;
 		break;
 	case IXJCTL_DAA_AGAIN:
 		ixj_daa_cr4(board, arg | 0x02);
 		break;
 	case IXJCTL_PSTN_LINETEST:
-	case PHONE_PSTN_LINETEST:
 		retval = ixj_linetest(board);
 		break;
+	case IXJCTL_VMWI:
+		ixj_write_vmwi(board, arg);
+		break;
 	case IXJCTL_CID:
-		if (copy_to_user((char *) arg, &j->cid, sizeof(IXJ_CID)))
+		if (copy_to_user((char *) arg, &j->cid, sizeof(PHONE_CID)))
 			return -EFAULT;
 		j->ex.bits.caller_id = 0;
 		break;
@@ -3891,7 +5038,7 @@
 		break;
 	case PHONE_CAPABILITIES_LIST:
 		if (copy_to_user((char *) arg, j->caplist, sizeof(struct phone_capability) * j->caps))
-			return -EFAULT;
+			 return -EFAULT;
 		break;
 	case PHONE_CAPABILITIES_CHECK:
 		retval = capabilities_check(board, (struct phone_capability *) arg);
@@ -3904,7 +5051,7 @@
 		j->ex.bits.pstn_ring = 0;
 		break;
 	case IXJCTL_SET_FILTER:
-		if (copy_from_user(&jf, (char *) arg, sizeof(ti)))
+		if (copy_from_user(&jf, (char *) arg, sizeof(jf)))
 			return -EFAULT;
 		retval = ixj_init_filter(board, &jf);
 		break;
@@ -3918,6 +5065,9 @@
 	case IXJCTL_TONE_CADENCE:
 		retval = ixj_build_cadence(board, (IXJ_CADENCE *) arg);
 		break;
+	case IXJCTL_FILTER_CADENCE:
+		retval = ixj_build_filter_cadence(board, (IXJ_FILTER_CADENCE *) arg);
+		break;
 	case IXJCTL_INTERCOM_STOP:
 		ixj[board].intercom = -1;
 		ixj[arg].intercom = -1;
@@ -3967,14 +5117,14 @@
 	NULL,			/* revalidate */
 	NULL			/* lock */
 };
-
 static int ixj_linetest(int board)
 {
 	unsigned long jifwait;
 	IXJ *j = &ixj[board];
 
+	j->flags.incheck = 1;	// Testing
 	if (!j->flags.pots_correct) {
-		j->flags.pots_correct = 1;	// Testing
+		j->flags.pots_correct = 1;
 
 		daa_int_read(board);	//Clear DAA Interrupt flags
 		//
@@ -4026,23 +5176,23 @@
 			}
 		}
 	}
-	if (!j->flags.pstn_present) {
-		j->pld_slicw.bits.rly3 = 0;
-		outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
-		daa_set_mode(board, SOP_PU_CONVERSATION);
-		jifwait = jiffies + hertz;
-		while (time_before(jiffies, jifwait)) {
-			current->state = TASK_INTERRUPTIBLE;
-			schedule_timeout(1);
-		}
-		daa_int_read(board);
-		daa_set_mode(board, SOP_PU_SLEEP);
-		if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
-			j->flags.pstn_present = 1;
-		} else {
-			j->flags.pstn_present = 0;
-		}
+//      if (!j->flags.pstn_present) {
+	j->pld_slicw.bits.rly3 = 0;
+	outb_p(j->pld_slicw.byte, j->XILINXbase + 0x01);
+	daa_set_mode(board, SOP_PU_CONVERSATION);
+	jifwait = jiffies + hertz;
+	while (time_before(jiffies, jifwait)) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule_timeout(1);
+	}
+	daa_int_read(board);
+	daa_set_mode(board, SOP_PU_SLEEP);
+	if (j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.bitreg.VDD_OK) {
+		j->flags.pstn_present = 1;
+	} else {
+		j->flags.pstn_present = 0;
 	}
+//      }
 	if (j->flags.pstn_present) {
 		if (j->flags.pots_correct) {
 			LED_SetState(0xA, board);
@@ -4056,6 +5206,7 @@
 			LED_SetState(0x5, board);
 		}
 	}
+	j->flags.incheck = 0;	// Testing
 	return j->flags.pstn_present;
 }
 
@@ -4063,46 +5214,39 @@
 {
 	unsigned short cmd;
 	unsigned long jif;
+	int cnt;
 	BYTES bytes;
 	IXJ *j = &ixj[board];
-
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Write IDLE to Software Control Register\n");
+	ixj_WriteDSPCommand(0x0FE0, board);	// Put the DSP in full power mode.
 
 	if (ixj_WriteDSPCommand(0x0000, board))		/* Write IDLE to Software Control Register */
 		return -1;
-
 // The read values of the SSR should be 0x00 for the IDLE command
 	if (j->ssr.low || j->ssr.high)
 		return -1;
-
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Get Device ID Code\n");
-
 	if (ixj_WriteDSPCommand(0x3400, board))		/* Get Device ID Code */
 		return -1;
-
 	j->dsp.low = j->ssr.low;
 	j->dsp.high = j->ssr.high;
-
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Get Device Version Code\n");
-
 	if (ixj_WriteDSPCommand(0x3800, board))		/* Get Device Version Code */
 		return -1;
-
 	j->ver.low = j->ssr.low;
 	j->ver.high = j->ssr.high;
-
 	if (!j->cardtype) {
 		if (j->dsp.low == 0x21) {
 //      j->XILINXbase = j->DSPbase + 0x10;
 			bytes.high = bytes.low = inb_p(j->XILINXbase + 0x02);
 			outb_p(bytes.low ^ 0xFF, j->XILINXbase + 0x02);
-      // Test for Internet LineJACK or Internet PhoneJACK Lite
+// Test for Internet LineJACK or Internet PhoneJACK Lite
 			bytes.low = inb_p(j->XILINXbase + 0x02);
 			if (bytes.low == bytes.high)	//  Register is read only on
-                                    //  Internet PhoneJack Lite
+				//  Internet PhoneJack Lite
 			 {
 				j->cardtype = 400;	// Internet PhoneJACK Lite
 
@@ -4163,18 +5307,18 @@
 			j->pld_slicw.pcib.e1 = 1;
 			outb_p(j->pld_slicw.byte, j->XILINXbase);
 			break;
+		case 600:	//Internet PhoneCARD
+
+			break;
 		}
 	}
 	if (j->dsp.low == 0x20 || j->cardtype == 400 || j->cardtype == 500) {
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-
 		if (ixj_WriteDSPCommand(0xC462, board))		/* Write CODEC config to Software Control Register */
 			return -1;
-
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Write CODEC timing to Software Control Register\n");
-
 		if (j->cardtype == 100) {
 			cmd = 0x9FF2;
 		} else {
@@ -4185,17 +5329,17 @@
 	} else {
 		if (set_base_frame(board, 30) != 30)
 			return -1;
-
+		if (ixjdebug > 0)
+			printk(KERN_INFO "Write CODEC config to Software Control Register\n");
+		if (j->cardtype == 600) {
+			if (ixj_WriteDSPCommand(0xC528, board))		/* Write CODEC config to Software Control Register */
+				return -1;
+		}
 		if (j->cardtype == 300) {
-			if (ixjdebug > 0)
-				printk(KERN_INFO "Write CODEC config to Software Control Register\n");
-
 			if (ixj_WriteDSPCommand(0xC528, board))		/* Write CODEC config to Software Control Register */
 				return -1;
-
 			if (ixjdebug > 0)
 				printk(KERN_INFO "Turn on the PLD Clock at 8Khz\n");
-
 			j->pld_clock.byte = 0;
 			outb_p(j->pld_clock.byte, j->XILINXbase + 0x04);
 		}
@@ -4204,7 +5348,6 @@
 	if (j->dsp.low == 0x20) {
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Configure GPIO pins\n");
-
 		j->gpio.bytes.high = 0x09;
 /*  bytes.low = 0xEF;  0xF7 */
 		j->gpio.bits.gpio1 = 1;
@@ -4215,10 +5358,8 @@
 		j->gpio.bits.gpio6 = 1;
 		j->gpio.bits.gpio7 = 1;
 		ixj_WriteDSPCommand(ixj[board].gpio.word, board);	/* Set GPIO pin directions */
-
 		if (ixjdebug > 0)
 			printk(KERN_INFO "Enable SLIC\n");
-
 		j->gpio.bytes.high = 0x0B;
 		j->gpio.bytes.low = 0x00;
 		j->gpio.bits.gpio1 = 0;
@@ -4253,23 +5394,16 @@
 				schedule_timeout(1);
 			}
 			LED_SetState(0x0, board);
-
 			daa_get_version(board);
-
 			if (ixjdebug > 0)
 				printk("Loading DAA Coefficients\n");
-
 			DAA_Coeff_US(board);
 			if (!ixj_daa_write(board))
 				printk("DAA write failed on board %d\n", board);
-
 			ixj_daa_cid_reset(board);
-
 			j->flags.pots_correct = 0;
 			j->flags.pstn_present = 0;
-
 			ixj_linetest(board);
-
 			if (j->flags.pots_correct) {
 				j->pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
 
@@ -4280,9 +5414,10 @@
 				SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
 				j->port = PORT_POTS;
 			}
+			ixj_set_port(board, PORT_PSTN);
+			ixj_set_pots(board, 1);
 			if (ixjdebug > 0)
 				printk(KERN_INFO "Enable Mixer\n");
-
 			ixj_mixer(0x0000, board);	//Master Volume Left unmute 0db
 
 			ixj_mixer(0x0100, board);	//Master Volume Right unmute 0db
@@ -4306,43 +5441,43 @@
 			ixj_mixer(0x1800, board);	//ADC Source select
 
 		} else {
-			j->port = PORT_POTS;
-			SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+			if (j->cardtype == 600) {
+				ixj_WriteDSPCommand(0xCF07, board);
+				ixj_WriteDSPCommand(0x00B0, board);
+				ixj_set_port(board, PORT_SPEAKER);
+			} else {
+				ixj_set_port(board, PORT_POTS);
+				SLIC_SetState(PLD_SLIC_STATE_STANDBY, board);
+			}
 		}
 	}
 
 	j->intercom = -1;
 	j->framesread = j->frameswritten = 0;
+	j->read_wait = j->write_wait = 0;
 	j->rxreadycheck = j->txreadycheck = 0;
-
+	set_play_volume(board, 0x100);
+	set_rec_volume(board, 0x100);
 	if (ixj_WriteDSPCommand(0x0000, board))		/* Write IDLE to Software Control Register */
 		return -1;
-
 // The read values of the SSR should be 0x00 for the IDLE command
 	if (j->ssr.low || j->ssr.high)
 		return -1;
-
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Enable Line Monitor\n");
-
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Set Line Monitor to Asyncronous Mode\n");
-
 	if (ixj_WriteDSPCommand(0x7E01, board))		// Asynchronous Line Monitor
 
 		return -1;
-
 	if (ixjdebug > 0)
 		printk(KERN_INFO "Enable DTMF Detectors\n");
-
 	if (ixj_WriteDSPCommand(0x5151, board))		// Enable DTMF detection
 
 		return -1;
-
 	if (ixj_WriteDSPCommand(0x6E01, board))		// Set Asyncronous Tone Generation
 
 		return -1;
-
 	set_rec_depth(board, 2);	// Set Record Channel Limit to 2 frames
 
 	set_play_depth(board, 2);	// Set Playback Channel Limit to 2 frames
@@ -4350,7 +5485,6 @@
 	j->ex.bits.dtmf_ready = 0;
 	j->dtmf_state = 0;
 	j->dtmf_wp = ixj[board].dtmf_rp = 0;
-
 	j->rec_mode = ixj[board].play_mode = -1;
 	j->flags.ringing = 0;
 	j->maxrings = MAXRINGS;
@@ -4358,15 +5492,16 @@
 	j->drybuffer = 0;
 	j->winktime = 320;
 	j->flags.dtmf_oob = 0;
-
+	for (cnt = 0; cnt < 4; cnt++)
+		j->cadence_f[cnt].enable = 0;
 	/* must be a device on the specified address */
+	ixj_WriteDSPCommand(0x0FE3, board);	// Put the DSP in 1/5 power mode.
 	/* Register with the Telephony for Linux subsystem */
 	j->p.f_op = &ixj_fops;
 	j->p.open = ixj_open;
+	j->p.board = board;
 	phone_register_device(&j->p, PHONE_UNIT_ANY);
-
 	add_caps(board);
-
 	return 0;
 }
 
@@ -4375,11 +5510,9 @@
 	int cnt;
 	IXJ *j;
 	len = 0;
-
 	len += sprintf(buf + len, "\n%s", ixj_c_rcsid);
 	len += sprintf(buf + len, "\n%s", ixj_h_rcsid);
 	len += sprintf(buf + len, "\n%s", ixjuser_h_rcsid);
-
 	for (cnt = 0; cnt < IXJMAX; cnt++) {
 		j = &ixj[cnt];
 		if (j->DSPbase) {
@@ -4398,6 +5531,7 @@
 				len += sprintf(buf + len, "\nCard Type = Internet LineJACK");
 				if (j->flags.g729_loaded)
 					len += sprintf(buf + len, " w/G.729 A/B");
+				len += sprintf(buf + len, " Country = %d", j->country);
 				break;
 			case (400):
 				len += sprintf(buf + len, "\nCard Type = Internet PhoneJACK Lite");
@@ -4409,18 +5543,35 @@
 				if (j->flags.g729_loaded)
 					len += sprintf(buf + len, " w/G.729 A/B");
 				break;
+			case (600):
+				len += sprintf(buf + len, "\nCard Type = Internet PhoneCARD");
+				if (j->flags.g729_loaded)
+					len += sprintf(buf + len, " w/G.729 A/B");
+				len += sprintf(buf + len, "\nSmart Cable %spresent", j->pccr1.bits.drf ? "not " : "");
+				if (!j->pccr1.bits.drf)
+					len += sprintf(buf + len, "\nSmart Cable type %d", j->flags.pcmciasct);
+				len += sprintf(buf + len, "\nSmart Cable state %d", j->flags.pcmciastate);
+				break;
 			default:
 				len += sprintf(buf + len, "\nCard Type = %d", j->cardtype);
 				break;
 			}
+			len += sprintf(buf + len, "\nReaders %d", j->readers);
+			len += sprintf(buf + len, "\nWriters %d", j->writers);
+			len += sprintf(buf + len, "\nFSK words %d", ixj[2].fskdcnt);
 			len += sprintf(buf + len, "\nCapabilities %d", j->caps);
 			if (j->dsp.low != 0x20)
 				len += sprintf(buf + len, "\nDSP Processor load %d", j->proc_load);
-//    if(j->intercom != -1)
-			//      len += sprintf(buf+len, "\nIntercom call to board %2.2x", j->intercom);
+			if (j->flags.cidsent)
+				len += sprintf(buf + len, "\nCaller ID data sent");
+			else
+				len += sprintf(buf + len, "\nCaller ID data not sent");
+
+			len += sprintf(buf + len, "\nCaller ID Date %s%s", j->cid_send.month, j->cid_send.day);
+			len += sprintf(buf + len, "\nCaller ID Time %s%s", j->cid_send.hour, j->cid_send.min);
+			len += sprintf(buf + len, "\nCaller ID Name %s", j->cid_send.name);
+			len += sprintf(buf + len, "\nCaller ID Number %s", j->cid_send.number);
 
-//    len += sprintf(buf+len, "\nRead buffer size %d", j->read_buffer_size);
-			//    len += sprintf(buf+len, "\nWrite buffer size %d", j->write_buffer_size);
 			len += sprintf(buf + len, "\nPlay CODEC ");
 			switch (j->play_codec) {
 			case G723_63:
@@ -4463,9 +5614,6 @@
 				len += sprintf(buf + len, "NO CODEC CHOSEN");
 				break;
 			}
-//    len += sprintf(buf+len, "\nPlay Frame Size %d", j->play_frame_size);
-			//    len += sprintf(buf+len, "\nInfo_write.convert_mode = %d", j->Info_write.convert_mode);
-			//    len += sprintf(buf+len, "\nInfo_write.convert_dir = %d", j->Info_write.convert_dir);
 			len += sprintf(buf + len, "\nRecord CODEC ");
 			switch (j->rec_codec) {
 			case G723_63:
@@ -4508,7 +5656,6 @@
 				len += sprintf(buf + len, "NO CODEC CHOSEN");
 				break;
 			}
-//    len += sprintf(buf+len, "\nRecord Frame Size %d", j->rec_frame_size);
 			switch (j->aec_level) {
 			case AEC_OFF:
 				len += sprintf(buf + len, "\n AEC OFF");
@@ -4523,16 +5670,13 @@
 				len += sprintf(buf + len, "\n AEC HIGH");
 				break;
 			}
-//    len += sprintf(buf+len, "\nInfo_read.convert_mode = %d", j->Info_read.convert_mode);
-			//    len += sprintf(buf+len, "\nInfo_read.convert_dir = %d", j->Info_read.convert_dir);
 			len += sprintf(buf + len, "\nHook state %d", j->r_hook);	// ixj_hookstate(cnt));
 
 			if (j->cardtype == 300) {
 				len += sprintf(buf + len, "\nPOTS Correct %d", j->flags.pots_correct);
 				len += sprintf(buf + len, "\nPSTN Present %d", j->flags.pstn_present);
 				len += sprintf(buf + len, "\nPOTS to PSTN %d", j->flags.pots_pstn);
-//      len += sprintf(buf+len, "\nDAA Interrupt flags %d", j->m_DAAShadowRegs.XOP_REGS.XOP.xr0.reg);
-				//      len += sprintf(buf+len, "\nDAA version %d", j->m_DAAShadowRegs.SOP_REGS.SOP.cr5.reg);
+				len += sprintf(buf + len, "\nPSTN sleeptil %ld - jiffies %ld", j->pstn_sleeptil, jiffies);
 				switch (j->daa_mode) {
 				case SOP_PU_SLEEP:
 					len += sprintf(buf + len, "\nDAA PSTN On Hook");
@@ -4547,7 +5691,6 @@
 					len += sprintf(buf + len, "\nDAA PSTN Pulse Dialing");
 					break;
 				}
-//      len += sprintf(buf+len, "\nDAA PSTN Ring flag = %d", j->pstn_ringing);
 			}
 			switch (j->port) {
 			case PORT_POTS:
@@ -4598,23 +5741,8 @@
 					break;
 				}
 			}
-//    len += sprintf(buf+len, "\nRead buffers ready %d", j->read_buffer_ready);
-			//    len += sprintf(buf+len, "\nWrite buffers empty %d",j->write_buffers_empty);
-
-//    len += sprintf(buf+len, "\nDTMF ready %d", j->ex.bits.dtmf_ready);
-			//    len += sprintf(buf+len, "\nDTMF proc %d", j->dtmf_proc);
-			//    len += sprintf(buf+len, "\nDTMF wp %d", j->dtmf_wp);
-			//    len += sprintf(buf+len, "\nDTMF rp %d", j->dtmf_rp);
-			//    len += sprintf(buf+len, "\nDTMF digits ");
-			//    for(x=j->dtmf_rp; x <j->dtmf_wp; x++)
-			//    {
-			//      if(x == 79)
-			//        x = 0;
-			//      len += sprintf(buf+len, "%x", j->dtmfbuffer[x]);
-			//    }
 #ifdef PERFMON_STATS
 			len += sprintf(buf + len, "\nTimer Checks %ld", j->timerchecks);
-
 			len += sprintf(buf + len, "\nRX Ready Checks %ld", j->rxreadycheck);
 			len += sprintf(buf + len, "\nTX Ready Checks %ld", j->txreadycheck);
 			len += sprintf(buf + len, "\nBase Frame %2.2x.%2.2x", j->baseframe.high, j->baseframe.low);
@@ -4629,7 +5757,15 @@
 	}
 	return len;
 }
-
+int ixj_read_proc_fsk(char *buf, char **start, off_t offset, int len, int unused)
+{
+	len = 0;
+	if (ixj[2].fskdcnt) {
+		memcpy(buf, &ixj[2].fskdata, (ixj[2].fskdcnt) * 2);
+		len += ixj[2].fskdcnt * 2;
+	}
+	return len;
+}
 static struct proc_dir_entry ixj_proc_entry =
 {
 	0,
@@ -4640,14 +5776,310 @@
 	NULL,
 	&ixj_read_proc
 };
+static struct proc_dir_entry ixjfsk_proc_entry =
+{
+	0,
+	6, "ixjfsk",
+	S_IFREG | S_IRUGO,
+	1, 0, 0,
+	0,
+	NULL,
+	&ixj_read_proc_fsk
+};
+
+MODULE_DESCRIPTION("Internet Phone/Internet LineJack module - www.quicknet.net");
+MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
+#ifdef CONFIG_PCMCIA
+#ifdef PCMCIA_DEBUG
+static int pc_debug = PCMCIA_DEBUG;
+MODULE_PARM(pc_debug, "i");
+#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
+#else
+#define DEBUG(n, args...)
+#endif
+typedef struct ixj_info_t {
+	int ndev;
+	dev_node_t node;
+	struct ixj *port;
+} ixj_info_t;
+static dev_link_t *ixj_attach(void);
+static void ixj_detach(dev_link_t *);
+static void ixj_config(dev_link_t * link);
+static void ixj_cs_release(u_long arg);
+static int ixj_event(event_t event, int priority, event_callback_args_t * args);
+static dev_info_t dev_info = "ixj_cs";
+static dev_link_t *dev_list = NULL;
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+	error_info_t err =
+	{
+		func, ret
+	};
+	CardServices(ReportError, handle, &err);
+}
+
+static dev_link_t *ixj_attach(void)
+{
+	client_reg_t client_reg;
+	dev_link_t *link;
+	int ret;
+	DEBUG(0, "ixj_attach()\n");
+	/* Create new ixj device */
+	link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL);
+	memset(link, 0, sizeof(struct dev_link_t));
+	link->release.function = &ixj_cs_release;
+	link->release.data = (u_long) link;
+	link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;
+	link->io.IOAddrLines = 3;
+	link->conf.Vcc = 50;
+	link->conf.IntType = INT_MEMORY_AND_IO;
+	link->priv = kmalloc(sizeof(struct ixj_info_t), GFP_KERNEL);
+	memset(link->priv, 0, sizeof(struct ixj_info_t));
+	/* Register with Card Services */
+	link->next = dev_list;
+	dev_list = link;
+	client_reg.dev_info = &dev_info;
+	client_reg.Attributes = INFO_IO_CLIENT | INFO_CARD_SHARE;
+	client_reg.EventMask =
+	    CS_EVENT_CARD_INSERTION | CS_EVENT_CARD_REMOVAL |
+	    CS_EVENT_RESET_PHYSICAL | CS_EVENT_CARD_RESET |
+	    CS_EVENT_PM_SUSPEND | CS_EVENT_PM_RESUME;
+	client_reg.event_handler = &ixj_event;
+	client_reg.Version = 0x0210;
+	client_reg.event_callback_args.client_data = link;
+	ret = CardServices(RegisterClient, &link->handle, &client_reg);
+	if (ret != CS_SUCCESS) {
+		cs_error(link->handle, RegisterClient, ret);
+		ixj_detach(link);
+		return NULL;
+	}
+	return link;
+}
+
+static void ixj_detach(dev_link_t * link)
+{
+	dev_link_t **linkp;
+	long flags;
+	int ret;
+	DEBUG(0, "ixj_detach(0x%p)\n", link);
+	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next)
+		if (*linkp == link)
+			break;
+	if (*linkp == NULL)
+		return;
+	save_flags(flags);
+	cli();
+	if (link->state & DEV_RELEASE_PENDING) {
+		del_timer(&link->release);
+		link->state &= ~DEV_RELEASE_PENDING;
+	}
+	restore_flags(flags);
+	if (link->state & DEV_CONFIG)
+		ixj_cs_release((u_long) link);
+	if (link->handle) {
+		ret = CardServices(DeregisterClient, link->handle);
+		if (ret != CS_SUCCESS)
+			cs_error(link->handle, DeregisterClient, ret);
+	}
+	/* Unlink device structure, free bits */
+	*linkp = link->next;
+	kfree_s(link->priv, sizeof(ixj_info_t));
+	kfree_s(link, sizeof(struct dev_link_t));
+}
+
+#define CS_CHECK(fn, args...) \
+while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failed
+
+#define CFG_CHECK(fn, args...) \
+if (CardServices(fn, args) != 0) goto next_entry
+
+void ixj_get_serial(dev_link_t * link, IXJ * j)
+{
+	client_handle_t handle;
+	tuple_t tuple;
+	u_short buf[128];
+	char *str;
+	int last_ret, last_fn, i, place;
+	handle = link->handle;
+	DEBUG(0, "ixj_get_serial(0x%p)\n", link);
+	tuple.TupleData = (cisdata_t *) buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 80;
+	tuple.Attributes = 0;
+	tuple.DesiredTuple = CISTPL_VERS_1;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData, handle, &tuple);
+	str = (char *) buf;
+	printk("PCMCIA Version %d.%d\n", str[0], str[1]);
+	str += 2;
+	printk("%s", str);
+	str = str + strlen(str) + 1;
+	printk(" %s", str);
+	str = str + strlen(str) + 1;
+	place = 1;
+	for (i = strlen(str) - 1; i >= 0; i--) {
+		switch (str[i]) {
+		case '0':
+		case '1':
+		case '2':
+		case '3':
+		case '4':
+		case '5':
+		case '6':
+		case '7':
+		case '8':
+		case '9':
+			j->serial += (str[i] - 48) * place;
+			break;
+		case 'A':
+		case 'B':
+		case 'C':
+		case 'D':
+		case 'E':
+		case 'F':
+			j->serial += (str[i] - 55) * place;
+			break;
+		case 'a':
+		case 'b':
+		case 'c':
+		case 'd':
+		case 'e':
+		case 'f':
+			j->serial += (str[i] - 87) * place;
+			break;
+		}
+		place = place * 0x10;
+	}
+	str = str + strlen(str) + 1;
+	printk(" version %s\n", str);
+      cs_failed:
+	return;
+}
+
+void ixj_config(dev_link_t * link)
+{
+	client_handle_t handle;
+	ixj_info_t *info;
+	tuple_t tuple;
+	u_short buf[128];
+	cisparse_t parse;
+	config_info_t conf;
+	cistpl_cftable_entry_t *cfg = &parse.cftable_entry;
+	cistpl_cftable_entry_t dflt =
+	{
+		0
+	};
+	int last_ret, last_fn;
+	handle = link->handle;
+	info = link->priv;
+	DEBUG(0, "ixj_config(0x%p)\n", link);
+	tuple.TupleData = (cisdata_t *) buf;
+	tuple.TupleOffset = 0;
+	tuple.TupleDataMax = 255;
+	tuple.Attributes = 0;
+	tuple.DesiredTuple = CISTPL_CONFIG;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	CS_CHECK(GetTupleData, handle, &tuple);
+	CS_CHECK(ParseTuple, handle, &tuple, &parse);
+	link->conf.ConfigBase = parse.config.base;
+	link->conf.Present = parse.config.rmask[0];
+	link->state |= DEV_CONFIG;
+	CS_CHECK(GetConfigurationInfo, handle, &conf);
+	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
+	tuple.Attributes = 0;
+	CS_CHECK(GetFirstTuple, handle, &tuple);
+	while (1) {
+		CFG_CHECK(GetTupleData, handle, &tuple);
+		CFG_CHECK(ParseTuple, handle, &tuple, &parse);
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->conf.ConfigIndex = cfg->index;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin == 2) {
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			CFG_CHECK(RequestIO, link->handle, &link->io);
+			/* If we've got this far, we're done */
+			break;
+		}
+	      next_entry:
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
+			dflt = *cfg;
+		CS_CHECK(GetNextTuple, handle, &tuple);
+	}
+
+	CS_CHECK(RequestConfiguration, handle, &link->conf);
+	ixj[0].DSPbase = link->io.BasePort1;
+	ixj[0].XILINXbase = link->io.BasePort1 + 0x10;
+	ixj[0].cardtype = 600;
+	ixj_selfprobe(0);
+	info->ndev = 1;
+	info->node.major = PHONE_MAJOR;
+	link->dev = &info->node;
+	ixj_get_serial(link, &ixj[0]);
+	link->state &= ~DEV_CONFIG_PENDING;
+	return;
+      cs_failed:
+	cs_error(link->handle, last_fn, last_ret);
+	ixj_cs_release((u_long) link);
+}
+
+void ixj_cs_release(u_long arg)
+{
+	dev_link_t *link = (dev_link_t *) arg;
+	ixj_info_t *info = link->priv;
+	DEBUG(0, "ixj_cs_release(0x%p)\n", link);
+	info->ndev = 0;
+	link->dev = NULL;
+	CardServices(ReleaseConfiguration, link->handle);
+	CardServices(ReleaseIO, link->handle, &link->io);
+	link->state &= ~DEV_CONFIG;
+}
+
+int ixj_event(event_t event, int priority, event_callback_args_t * args)
+{
+	dev_link_t *link = args->client_data;
+	DEBUG(1, "ixj_event(0x%06x)\n", event);
+	switch (event) {
+	case CS_EVENT_CARD_REMOVAL:
+		link->state &= ~DEV_PRESENT;
+		if (link->state & DEV_CONFIG) {
+			link->release.expires = RUN_AT(HZ / 20);
+			link->state |= DEV_RELEASE_PENDING;
+			add_timer(&link->release);
+		}
+		break;
+	case CS_EVENT_CARD_INSERTION:
+		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+		ixj_config(link);
+		break;
+	case CS_EVENT_PM_SUSPEND:
+		link->state |= DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_RESET_PHYSICAL:
+		if (link->state & DEV_CONFIG)
+			CardServices(ReleaseConfiguration, link->handle);
+		break;
+	case CS_EVENT_PM_RESUME:
+		link->state &= ~DEV_SUSPEND;
+		/* Fall through... */
+	case CS_EVENT_CARD_RESET:
+		if (DEV_OK(link))
+			CardServices(RequestConfiguration, link->handle, &link->conf);
+		break;
+	}
+	return 0;
+}
+
+#endif				// PCMCIA
 
 static void cleanup(void)
 {
 	int cnt;
-
 	del_timer(&ixj_timer);
-//  if (ixj_major)
-	//    unregister_chrdev(ixj_major, "ixj");
 	for (cnt = 0; cnt < IXJMAX; cnt++) {
 		if (ixj[cnt].cardtype == 300) {
 			ixj[cnt].pld_scrw.bits.daafsyncen = 0;	// Turn off DAA Frame Sync
@@ -4658,7 +6090,6 @@
 			ixj[cnt].pld_slicw.bits.rly3 = 0;
 			outb_p(ixj[cnt].pld_slicw.byte, ixj[cnt].XILINXbase + 0x01);
 			LED_SetState(0x0, cnt);
-
 			release_region(ixj[cnt].XILINXbase, 8);
 		}
 		if (ixj[cnt].cardtype == 400 || ixj[cnt].cardtype == 500) {
@@ -4676,17 +6107,22 @@
 		if (ixj[cnt].dev)
 			ixj[cnt].dev->deactivate(ixj[cnt].dev);
 #endif
+#ifdef CONFIG_PCMCIA
+		DEBUG(0, "ixj_cs: unloading\n");
+		unregister_pcmcia_driver(&dev_info);
+		while (dev_list != NULL)
+			ixj_detach(dev_list);
+#endif
 	}
 	proc_unregister(&proc_root, ixj_proc_entry.low_ino);
+	proc_unregister(&proc_root, ixjfsk_proc_entry.low_ino);
 }
 
-
 // Typedefs
 typedef struct {
 	BYTE length;
 	DWORD bits;
 } DATABLOCK;
-
 static void PCIEE_WriteBit(WORD wEEPROMAddress, BYTE lastLCC, BYTE byData)
 {
 	lastLCC = lastLCC & 0xfb;
@@ -4699,7 +6135,6 @@
 
 	byData = byData << 1;
 	lastLCC = lastLCC & 0xfe;
-
 	udelay(1000);
 	outb(lastLCC, wEEPROMAddress);	//after delay, SK falling edge
 
@@ -4724,11 +6159,8 @@
 	WORD wEEPROMAddress = wAddress + 3;
 	DWORD i;
 	BYTE byResult;
-
 	*pwResult = 0;
-
 	lastLCC = inb(wEEPROMAddress);
-
 	lastLCC = lastLCC | 0x02;
 	lastLCC = lastLCC & 0xfe;
 	outb(lastLCC, wEEPROMAddress);	// CS hi, SK lo
@@ -4738,7 +6170,6 @@
 	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
 	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 1);
 	PCIEE_WriteBit(wEEPROMAddress, lastLCC, 0);
-
 	for (i = 0; i < 8; i++) {
 		PCIEE_WriteBit(wEEPROMAddress, lastLCC, wLoc & 0x80 ? 1 : 0);
 		wLoc <<= 1;
@@ -4760,27 +6191,29 @@
 static DWORD PCIEE_GetSerialNumber(WORD wAddress)
 {
 	WORD wLo, wHi;
-
 	if (PCIEE_ReadWord(wAddress, 62, &wLo))
 		return 0;
-
 	if (PCIEE_ReadWord(wAddress, 63, &wHi))
 		return 0;
-
 	return (((DWORD) wHi << 16) | wLo);
 }
 
-static int dspio[IXJMAX + 1] = {0,};
-static int xio[IXJMAX + 1] = {0,};
-
-MODULE_DESCRIPTION("Internet PhoneJACK/Internet LineJACK module - www.quicknet.net");
-MODULE_AUTHOR("Ed Okerson <eokerson@quicknet.net>");
+#ifndef CONFIG_PCMCIA
+#ifndef CONFIG_ISAPNP
+static int dspio[IXJMAX + 1] =
+{
+	0,
+};
+static int xio[IXJMAX + 1] =
+{
+	0,
+};
 
 MODULE_PARM(dspio, "1-" __MODULE_STRING(IXJMAX) "i");
 MODULE_PARM(xio, "1-" __MODULE_STRING(IXJMAX) "i");
-
+#endif
+#endif
 #ifdef MODULE
-
 void cleanup_module(void)
 {
 	cleanup();
@@ -4792,23 +6225,35 @@
 #endif
 {
 	int result;
-
-	int func = 0x110, i = 0;
+	int i = 0;
 	int cnt = 0;
 	int probe = 0;
+#ifdef CONFIG_ISAPNP
+	int func = 0x110;
 	struct pnp_dev *dev = NULL, *old_dev = NULL;
+#endif
+#ifdef CONFIG_PCI
 	struct pci_dev *pci = NULL;
-
+#endif
+#ifdef CONFIG_PCMCIA
+	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 -1;
+	}
+	register_pcmcia_driver(&dev_info, &ixj_attach, &ixj_detach);
+	probe = 0;
+#else
 #ifdef CONFIG_ISAPNP
 	while (1) {
 		do {
 			old_dev = dev;
 			dev = isapnp_find_dev(NULL, ISAPNP_VENDOR('Q', 'T', 'I'),
 					 ISAPNP_FUNCTION(func), old_dev);
-//(old_dev==NULL?NULL:old_dev));
 			if (!dev)
 				break;
-			printk("preparing %x\n", func);
 			result = dev->prepare(dev);
 			if (result < 0) {
 				printk("preparing failed %d \n", result);
@@ -4826,7 +6271,6 @@
 			ixj[cnt].DSPbase = dev->resource[0].start;	/* get real port */
 			if (func != 0x110)
 				ixj[cnt].XILINXbase = dev->resource[1].start;	/* get real port */
-
 			result = check_region(ixj[cnt].DSPbase, 16);
 			if (result) {
 				printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
@@ -4846,13 +6290,21 @@
 				break;
 			}
 			probe = ixj_selfprobe(cnt);
-
 			ixj[cnt].serial = dev->bus->serial;
 			ixj[cnt].dev = dev;
-			printk(KERN_INFO "ixj: found card at 0x%x\n", ixj[cnt].DSPbase);
+			switch (func) {
+			case 0x110:
+				printk(KERN_INFO "ixj: found Internet PhoneJACK at 0x%x\n", ixj[cnt].DSPbase);
+				break;
+			case 0x310:
+				printk(KERN_INFO "ixj: found Internet LineJACK at 0x%x\n", ixj[cnt].DSPbase);
+				break;
+			case 0x410:
+				printk(KERN_INFO "ixj: found Internet PhoneJACK Lite at 0x%x\n", ixj[cnt].DSPbase);
+				break;
+			}
 			cnt++;
 		} while (dev);
-
 		if (func == 0x410)
 			break;
 		if (func == 0x310)
@@ -4863,11 +6315,10 @@
 	}
 #else				//CONFIG_ISAPNP
 	/* Use passed parameters for older kernels without PnP */
-
-	for (cnt = 0; cnt < IXJMAX; cnt++) {
-		if (dspio[cnt]) {
-			ixj[cnt].DSPbase = dspio[cnt];
-			ixj[cnt].XILINXbase = xio[cnt];
+	for (i = 0; i < IXJMAX; i++) {
+		if (dspio[i]) {
+			ixj[cnt].DSPbase = dspio[i];
+			ixj[cnt].XILINXbase = xio[i];
 			ixj[cnt].cardtype = 0;
 			result = check_region(ixj[cnt].DSPbase, 16);
 			if (result) {
@@ -4878,9 +6329,11 @@
 			request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
 			probe = ixj_selfprobe(cnt);
 			ixj[cnt].dev = NULL;
+			cnt++;
 		}
 	}
-#endif
+#endif				// !CONFIG_ISAPNP
+#endif				// CONFIG_PCMCIA
 #ifdef CONFIG_PCI
 	if (pci_present()) {
 		for (i = 0; i < IXJMAX - cnt; i++) {
@@ -4891,7 +6344,6 @@
 				ixj[cnt].DSPbase = pci->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
 				ixj[cnt].XILINXbase = ixj[cnt].DSPbase + 0x10;
 				ixj[cnt].serial = PCIEE_GetSerialNumber(pci->base_address[2] & PCI_BASE_ADDRESS_IO_MASK);
-
 				result = check_region(ixj[cnt].DSPbase, 16);
 				if (result) {
 					printk(KERN_INFO "ixj: can't get I/O address 0x%x\n", ixj[cnt].DSPbase);
@@ -4901,43 +6353,35 @@
 				request_region(ixj[cnt].DSPbase, 16, "ixj DSP");
 				ixj[cnt].cardtype = 500;
 				probe = ixj_selfprobe(cnt);
+				if (probe)
+					printk(KERN_INFO "ixj: found Internet PhoneJACK PCI at 0x%x\n", ixj[cnt].DSPbase);
 				cnt++;
 			}
 		}
 	}
 #endif
 	printk("%s\n", ixj_c_rcsid);
-
-//  result = register_chrdev(ixj_major, "ixj", &ixj_fops);
-	//  if (result < 0) {
-	//    printk(KERN_INFO "ixj: can't get major number\n");
-	//    cleanup();
-	//    return result;
-	//  }
-	//  if (ixj_major == 0)
-	//    ixj_major = result;               /* dynamic */
-
 	proc_register(&proc_root, &ixj_proc_entry);
-
+	proc_register(&proc_root, &ixjfsk_proc_entry);
 	ixj_init_timer();
-	ixj_add_timer();	
+	ixj_add_timer();
 	return probe;
 }
 
 static void DAA_Coeff_US(int board)
 {
 	IXJ *j = &ixj[board];
-
 	int i;
 
+	j->daa_country = DAA_US;
 	//-----------------------------------------------
 	// CAO
 	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
 		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
 	}
 
-	// Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00
-	    j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x0E;
+// Bytes for IM-filter part 1 (04): 0E,32,E2,2F,C2,5A,C0,00
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x0E;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2F;
@@ -4945,7 +6389,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xC0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
 // Bytes for IM-filter part 2 (05): 72,85,00,0E,2B,3A,D0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x72;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x85;
@@ -4955,7 +6398,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
 // Bytes for FRX-filter       (08): 03,8F,48,F2,8F,48,70,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x03;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
@@ -4965,7 +6407,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x48;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x70;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
 // Bytes for FRR-filter       (07): 04,8F,38,7F,9B,EA,B0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x04;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
@@ -4975,19 +6416,16 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
 // Bytes for AX-filter        (0A): 16,55,DD,CA
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x55;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
 // Bytes for AR-filter        (09): 52,D3,11,42
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xD3;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x42;
-
 // Bytes for TH-filter part 1 (00): 00,42,48,81,B3,80,00,98
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
@@ -4997,7 +6435,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
 // Bytes for TH-filter part 2 (01): 02,F2,33,A0,68,AB,8A,AD
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xF2;
@@ -5007,7 +6444,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAB;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAD;
-
 // Bytes for TH-filter part 3 (02): 00,88,DA,54,A4,BA,2D,BB
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5017,7 +6453,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2D;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBB;
-
 // ;  (10K, 0.68uF)
 	// 
 	// Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
@@ -5029,7 +6464,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
 // Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
@@ -5039,14 +6473,12 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
 // 
 	// Levelmetering Ringing        (0D):B2,45,0F,8E      
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
 // Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5056,7 +6488,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
 // Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5066,64 +6497,52 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
 // 
 	// ;CR Registers
 	// Config. Reg. 0 (filters)       (cr0):FE ; CLK gen. by crystal
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
-
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
 // Config. Reg. 1 (dialing)       (cr1):05
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
 // Config. Reg. 2 (caller ID)     (cr2):04
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
 // Config. Reg. 3 (testloops)     (cr3):03 ; SEL Bit==0, HP-disabled
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x03;
-
 // Config. Reg. 4 (analog gain)   (cr4):01
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;		//0x01;
-
-// Config. Reg. 5 (Version)       (cr5):02
+	// Config. Reg. 5 (Version)       (cr5):02
 	// Config. Reg. 6 (Reserved)      (cr6):00
 	// Config. Reg. 7 (Reserved)      (cr7):00
 	// 
-
-// ;xr Registers
+	// ;xr Registers
 	// Ext. Reg. 0 (Interrupt Reg.)   (xr0):02
+
 	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	// SO_1 set to '1' because it is inverted.
+	// Ext. Reg. 1 (Interrupt enable) (xr1):1C // Cadence, RING, Caller ID, VDD_OK
 
-// Ext. Reg. 1 (Interrupt enable) (xr1):1C // Cadence, RING, Caller ID, VDD_OK
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x3C;
-
 // Ext. Reg. 2 (Cadence Time Out) (xr2):7D
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
 // Ext. Reg. 3 (DC Char)          (xr3):32 ; B-Filter Off == 1
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x12;		//0x32;
+	// Ext. Reg. 4 (Cadence)          (xr4):00
 
-// Ext. Reg. 4 (Cadence)          (xr4):00
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
 // Ext. Reg. 5 (Ring timer)       (xr5):22
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
 // Ext. Reg. 6 (Power State)      (xr6):00
 	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
 // Ext. Reg. 7 (Vdd)              (xr7):40
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		// 0x40 ??? Should it be 0x00?
-
-// 
+	// 
 	// DTMF Tone 1                     (0B): 11,B3,5A,2C ;   697 Hz  
 	//                                       12,33,5A,C3 ;  770 Hz  
 	//                                       13,3C,5B,32 ;  852 Hz  
 	//                                       1D,1B,5C,CC ;  941 Hz  
+
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
 // DTMF Tone 2                     (0C): 32,32,52,B3 ;  1209 Hz  
 	//                                       EC,1D,52,22 ;  1336 Hz  
 	//                                       AA,AC,51,D2 ;  1477 Hz  
@@ -5132,23 +6551,22 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
 }
 
 static void DAA_Coeff_UK(int board)
 {
 	IXJ *j = &ixj[board];
-
 	int i;
 
+	j->daa_country = DAA_UK;
 	//-----------------------------------------------
 	// CAO
 	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
 		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
 	}
 
-	//  Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00
-	    j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+//  Bytes for IM-filter part 1 (04): 00,C2,BB,A8,CB,81,A0,00
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xC2;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xA8;
@@ -5156,8 +6574,7 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
-	// Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08
+// Bytes for IM-filter part 2 (05): 40,00,00,0A,A4,33,E0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x40;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[5] = 0x00;
@@ -5166,7 +6583,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
 // Bytes for FRX-filter       (08): 07,9B,ED,24,B2,A2,A0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9B;
@@ -5176,7 +6592,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0xA2;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xA0;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
 // Bytes for FRR-filter       (07): 0F,92,F2,B2,87,D2,30,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x92;
@@ -5186,19 +6601,16 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xD2;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x30;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
 // Bytes for AX-filter        (0A): 1B,A5,DD,CA
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xA5;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
 // Bytes for AR-filter        (09): E2,27,10,D6
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x27;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-
 // Bytes for TH-filter part 1 (00): 80,2D,38,8B,D0,00,00,98
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x2D;
@@ -5208,7 +6620,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
 // Bytes for TH-filter part 2 (01): 02,5A,53,F0,0B,5F,84,D4
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x5A;
@@ -5218,7 +6629,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5F;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x84;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xD4;
-
 // Bytes for TH-filter part 3 (02): 00,88,6A,A4,8F,52,F5,32
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5228,10 +6638,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xF5;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x32;
-
 // ; idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+	// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -5240,7 +6648,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
 // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
@@ -5250,13 +6657,11 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
 // Levelmetering Ringing           (0D):AA,35,0F,8E     ; 25Hz 30V less possible?
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
 // Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5266,7 +6671,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
 // Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5276,61 +6680,49 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
 // ;CR Registers
 	// Config. Reg. 0 (filters)        (cr0):FF
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;		//0xFE;
-
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
 // Config. Reg. 1 (dialing)        (cr1):05
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
 // Config. Reg. 2 (caller ID)      (cr2):04
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
 // Config. Reg. 3 (testloops)      (cr3):00        ; 
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
 // Config. Reg. 4 (analog gain)    (cr4):01
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;		//0x01;
-
-// Config. Reg. 5 (Version)        (cr5):02
+	// Config. Reg. 5 (Version)        (cr5):02
 	// Config. Reg. 6 (Reserved)       (cr6):00
 	// Config. Reg. 7 (Reserved)       (cr7):00
-
-// ;xr Registers
+	// ;xr Registers
 	// Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+
 	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	// SO_1 set to '1' because it is inverted.
+	// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 
-// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		// RING, Caller ID, VDD_OK
+	// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 
-// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
 // Ext. Reg. 3 (DC Char)           (xr3):36        ; 
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-
 // Ext. Reg. 4 (Cadence)           (xr4):00
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
 // Ext. Reg. 5 (Ring timer)        (xr5):22
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
 // Ext. Reg. 6 (Power State)       (xr6):00
 	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
 // Ext. Reg. 7 (Vdd)               (xr7):46
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;		// 0x46 ??? Should it be 0x00?
-
-// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
+	// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
 	//                                       12,33,5A,C3    ;  770 Hz  
 	//                                       13,3C,5B,32    ;  852 Hz  
 	//                                       1D,1B,5C,CC    ;  941 Hz  
+
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
 // DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
 	//                                       EC,1D,52,22    ;  1336 Hz  
 	//                                       AA,AC,51,D2    ;  1477 Hz  
@@ -5339,24 +6731,23 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
 }
 
 
 static void DAA_Coeff_France(int board)
 {
 	IXJ *j = &ixj[board];
-
 	int i;
 
+	j->daa_country = DAA_FRANCE;
 	//-----------------------------------------------
 	// CAO
 	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
 		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
 	}
 
-	// Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00
-	    j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
+// Bytes for IM-filter part 1 (04): 02,A2,43,2C,22,AF,A0,00
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA2;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0x43;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2C;
@@ -5364,7 +6755,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xAF;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
 // Bytes for IM-filter part 2 (05): 67,CE,00,0C,22,33,E0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x67;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xCE;
@@ -5374,7 +6764,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
 // Bytes for FRX-filter       (08): 07,9A,28,F6,23,4A,B0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x9A;
@@ -5384,7 +6773,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x4A;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xB0;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
 // Bytes for FRR-filter       (07): 03,8F,F9,2F,9E,FA,20,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
@@ -5394,19 +6782,16 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xFA;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
 // Bytes for AX-filter        (0A): 16,B5,DD,CA
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x16;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xB5;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
 // Bytes for AR-filter        (09): 52,C7,10,D6
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0xE2;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xC7;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-
 // Bytes for TH-filter part 1 (00): 00,42,48,81,A6,80,00,98
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
@@ -5416,7 +6801,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
 // Bytes for TH-filter part 2 (01): 02,AC,2A,30,78,AC,8A,2C
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAC;
@@ -5426,7 +6810,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0xAC;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x8A;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x2C;
-
 // Bytes for TH-filter part 3 (02): 00,88,DA,A5,22,BA,2C,45
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5436,10 +6819,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xBA;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x2C;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x45;
-
 // ; idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+	// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -5448,7 +6829,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
 // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
@@ -5458,13 +6838,11 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
 // Levelmetering Ringing           (0D):32,45,B5,84     ; 50Hz 20V
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-
 // Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5474,7 +6852,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
 // Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5484,61 +6861,49 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
 // ;CR Registers
 	// Config. Reg. 0 (filters)        (cr0):FF
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
 // Config. Reg. 1 (dialing)        (cr1):05
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
 // Config. Reg. 2 (caller ID)      (cr2):04
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
 // Config. Reg. 3 (testloops)      (cr3):00        ; 
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
 // Config. Reg. 4 (analog gain)    (cr4):01
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;		//0x01;
-
-// Config. Reg. 5 (Version)        (cr5):02
+	// Config. Reg. 5 (Version)        (cr5):02
 	// Config. Reg. 6 (Reserved)       (cr6):00
 	// Config. Reg. 7 (Reserved)       (cr7):00
-
-// ;xr Registers
+	// ;xr Registers
 	// Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+
 	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	// SO_1 set to '1' because it is inverted.
+	// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 
-// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		// RING, Caller ID, VDD_OK
+	// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 
-// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
 // Ext. Reg. 3 (DC Char)           (xr3):36        ; 
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x36;
-
 // Ext. Reg. 4 (Cadence)           (xr4):00
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
 // Ext. Reg. 5 (Ring timer)        (xr5):22
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
 // Ext. Reg. 6 (Power State)       (xr6):00
 	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
 // Ext. Reg. 7 (Vdd)               (xr7):46
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x46;		// 0x46 ??? Should it be 0x00?
-
-// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
+	// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
 	//                                       12,33,5A,C3    ;  770 Hz  
 	//                                       13,3C,5B,32    ;  852 Hz  
 	//                                       1D,1B,5C,CC    ;  941 Hz  
+
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
 // DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
 	//                                       EC,1D,52,22    ;  1336 Hz  
 	//                                       AA,AC,51,D2    ;  1477 Hz  
@@ -5547,24 +6912,23 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
 }
 
 
 static void DAA_Coeff_Germany(int board)
 {
 	IXJ *j = &ixj[board];
-
 	int i;
 
+	j->daa_country = DAA_GERMANY;
 	//-----------------------------------------------
 	// CAO
 	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
 		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
 	}
 
-	// Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00
-	    j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+// Bytes for IM-filter part 1 (04): 00,CE,BB,B8,D2,81,B0,00
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xCE;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xBB;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0xB8;
@@ -5572,7 +6936,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x81;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xB0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
 // Bytes for IM-filter part 2 (05): 45,8F,00,0C,D2,3A,D0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x45;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x8F;
@@ -5582,7 +6945,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x3A;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xD0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
 // Bytes for FRX-filter       (08): 07,AA,E2,34,24,89,20,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0xAA;
@@ -5592,7 +6954,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x89;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x20;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
 // Bytes for FRR-filter       (07): 02,87,FA,37,9A,CA,B0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x87;
@@ -5602,19 +6963,16 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xB0;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
 // Bytes for AX-filter        (0A): 72,D5,DD,CA
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x72;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xD5;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
 // Bytes for AR-filter        (09): 72,42,13,4B
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x72;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x42;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x13;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0x4B;
-
 // Bytes for TH-filter part 1 (00): 80,52,48,81,AD,80,00,98
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
@@ -5624,7 +6982,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
 // Bytes for TH-filter part 2 (01): 02,42,5A,20,E8,1A,81,27
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0x42;
@@ -5634,7 +6991,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x1A;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x81;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x27;
-
 // Bytes for TH-filter part 3 (02): 00,88,63,26,BD,4B,A3,C2
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5644,10 +7000,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x4B;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0xA3;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xC2;
-
 // ;  (10K, 0.68uF)
-
-// Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
+	// Bytes for Ringing part 1 (03):1B,3B,9B,BA,D4,1C,B3,23
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3B;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x9B;
@@ -5656,7 +7010,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x1C;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
 // Bytes for Ringing part 2 (06):13,42,A6,BA,D4,73,CA,D5
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x13;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0x42;
@@ -5666,13 +7019,11 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x73;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
 // Levelmetering Ringing        (0D):B2,45,0F,8E      
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xB2;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
 // Caller ID 1st Tone           (0E):CA,0E,CA,09,99,99,99,99
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5682,7 +7033,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
 // Caller ID 2nd Tone           (0F):FD,B5,BA,07,DA,00,00,00
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5692,61 +7042,49 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
 // ;CR Registers
 	// Config. Reg. 0 (filters)        (cr0):FF ; all Filters enabled, CLK from ext. source
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
 // Config. Reg. 1 (dialing)        (cr1):05 ; Manual Ring, Ring metering enabled
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
 // Config. Reg. 2 (caller ID)      (cr2):04 ; Analog Gain 0dB, FSC internal
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
 // Config. Reg. 3 (testloops)      (cr3):00 ; SEL Bit==0, HP-enabled
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
 // Config. Reg. 4 (analog gain)    (cr4):01
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;		//0x01;
-
-// Config. Reg. 5 (Version)        (cr5):02
+	// Config. Reg. 5 (Version)        (cr5):02
 	// Config. Reg. 6 (Reserved)       (cr6):00
 	// Config. Reg. 7 (Reserved)       (cr7):00
-
-// ;xr Registers
+	// ;xr Registers
 	// Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+
 	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	// SO_1 set to '1' because it is inverted.
+	// Ext. Reg. 1 (Interrupt enable)  (xr1):1C ; Ring, CID, VDDOK Interrupts enabled
 
-// Ext. Reg. 1 (Interrupt enable)  (xr1):1C ; Ring, CID, VDDOK Interrupts enabled
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		// RING, Caller ID, VDD_OK
+	// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 
-// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
 // Ext. Reg. 3 (DC Char)           (xr3):32 ; B-Filter Off==1, U0=3.5V, R=200Ohm
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x32;
-
 // Ext. Reg. 4 (Cadence)           (xr4):00
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
 // Ext. Reg. 5 (Ring timer)        (xr5):22
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
 // Ext. Reg. 6 (Power State)       (xr6):00
 	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
 // Ext. Reg. 7 (Vdd)               (xr7):40 ; VDD=4.25 V
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		// 0x40 ??? Should it be 0x00?
-
-// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
+	// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
 	//                                       12,33,5A,C3    ;  770 Hz  
 	//                                       13,3C,5B,32    ;  852 Hz  
 	//                                       1D,1B,5C,CC    ;  941 Hz  
+
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
 // DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
 	//                                       EC,1D,52,22    ;  1336 Hz  
 	//                                       AA,AC,51,D2    ;  1477 Hz  
@@ -5755,24 +7093,23 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
 }
 
 
 static void DAA_Coeff_Australia(int board)
 {
 	IXJ *j = &ixj[board];
-
 	int i;
 
+	j->daa_country = DAA_AUSTRALIA;
 	//-----------------------------------------------
 	// CAO
 	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
 		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
 	}
 
-	// Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00
-	    j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
+// Bytes for IM-filter part 1 (04): 00,A3,AA,28,B3,82,D0,00
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xA3;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xAA;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x28;
@@ -5780,7 +7117,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0x82;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xD0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
 // Bytes for IM-filter part 2 (05): 70,96,00,09,32,6B,C0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x70;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0x96;
@@ -5790,7 +7126,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x6B;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xC0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
 // Bytes for FRX-filter       (08): 07,96,E2,34,32,9B,30,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x07;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x96;
@@ -5800,7 +7135,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x9B;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0x30;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
 // Bytes for FRR-filter       (07): 0F,9A,E9,2F,22,CC,A0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x0F;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x9A;
@@ -5810,19 +7144,16 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xCC;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0xA0;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
 // Bytes for AX-filter        (0A): CB,45,DD,CA
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0xCB;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0x45;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
 // Bytes for AR-filter        (09): 1B,67,10,D6
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0x67;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-
 // Bytes for TH-filter part 1 (00): 80,52,48,81,AF,80,00,98
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x52;
@@ -5832,7 +7163,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
 // Bytes for TH-filter part 2 (01): 02,DB,52,B0,38,01,82,AC
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xDB;
@@ -5842,7 +7172,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x01;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x82;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0xAC;
-
 // Bytes for TH-filter part 3 (02): 00,88,4A,3E,2C,3B,24,46
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -5852,10 +7181,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0x3B;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x24;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0x46;
-
 // ;  idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+	// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -5864,7 +7191,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
 // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
@@ -5874,13 +7200,11 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
 // Levelmetering Ringing           (0D):32,45,B5,84   ; 50Hz 20V
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x45;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0xB5;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x84;
-
 // Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -5890,7 +7214,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
 // Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -5900,61 +7223,49 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
 // ;CR Registers
 	// Config. Reg. 0 (filters)        (cr0):FF
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-
 // Config. Reg. 1 (dialing)        (cr1):05
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
 // Config. Reg. 2 (caller ID)      (cr2):04
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
 // Config. Reg. 3 (testloops)      (cr3):00        ; 
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
 // Config. Reg. 4 (analog gain)    (cr4):01
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;		//0x01;
-
-// Config. Reg. 5 (Version)        (cr5):02
+	// Config. Reg. 5 (Version)        (cr5):02
 	// Config. Reg. 6 (Reserved)       (cr6):00
 	// Config. Reg. 7 (Reserved)       (cr7):00
-
-// ;xr Registers
+	// ;xr Registers
 	// Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+
 	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	// SO_1 set to '1' because it is inverted.
+	// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 
-// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		// RING, Caller ID, VDD_OK
+	// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 
-// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
 // Ext. Reg. 3 (DC Char)           (xr3):2B      ; 
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x2B;
-
 // Ext. Reg. 4 (Cadence)           (xr4):00
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
 // Ext. Reg. 5 (Ring timer)        (xr5):22
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
 // Ext. Reg. 6 (Power State)       (xr6):00
 	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
 // Ext. Reg. 7 (Vdd)               (xr7):40
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		// 0x40 ??? Should it be 0x00?
-
-// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
+	// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
 	//                                       12,33,5A,C3    ;  770 Hz  
 	//                                       13,3C,5B,32    ;  852 Hz  
 	//                                       1D,1B,5C,CC    ;  941 Hz  
+
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
 // DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
 	//                                       EC,1D,52,22    ;  1336 Hz  
 	//                                       AA,AC,51,D2    ;  1477 Hz  
@@ -5963,23 +7274,22 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
 }
 
 static void DAA_Coeff_Japan(int board)
 {
 	IXJ *j = &ixj[board];
-
 	int i;
 
+	j->daa_country = DAA_JAPAN;
 	//-----------------------------------------------
 	// CAO
 	for (i = 0; i < ALISDAA_CALLERID_SIZE; i++) {
 		j->m_DAAShadowRegs.CAO_REGS.CAO.CallerID[i] = 0;
 	}
 
-	// Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00
-	    j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
+// Bytes for IM-filter part 1 (04): 06,BD,E2,2D,BA,F9,A0,00
+	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[7] = 0x06;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[6] = 0xBD;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[5] = 0xE2;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[4] = 0x2D;
@@ -5987,7 +7297,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[2] = 0xF9;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[1] = 0xA0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_1[0] = 0x00;
-
 // Bytes for IM-filter part 2 (05): 6F,F7,00,0E,34,33,E0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[7] = 0x6F;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[6] = 0xF7;
@@ -5997,7 +7306,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[2] = 0x33;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[1] = 0xE0;
 	j->m_DAAShadowRegs.COP_REGS.COP.IMFilterCoeff_2[0] = 0x08;
-
 // Bytes for FRX-filter       (08): 02,8F,68,77,9C,58,F0,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[6] = 0x8F;
@@ -6007,7 +7315,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[2] = 0x58;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[1] = 0xF0;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRXFilterCoeff[0] = 0x08;
-
 // Bytes for FRR-filter       (07): 03,8F,38,73,87,EA,20,08
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[7] = 0x03;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[6] = 0x8F;
@@ -6017,19 +7324,16 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[2] = 0xEA;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[1] = 0x20;
 	j->m_DAAShadowRegs.COP_REGS.COP.FRRFilterCoeff[0] = 0x08;
-
 // Bytes for AX-filter        (0A): 51,C5,DD,CA
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[3] = 0x51;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[2] = 0xC5;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[1] = 0xDD;
 	j->m_DAAShadowRegs.COP_REGS.COP.AXFilterCoeff[0] = 0xCA;
-
 // Bytes for AR-filter        (09): 25,A7,10,D6
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[3] = 0x25;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[2] = 0xA7;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[1] = 0x10;
 	j->m_DAAShadowRegs.COP_REGS.COP.ARFilterCoeff[0] = 0xD6;
-
 // Bytes for TH-filter part 1 (00): 00,42,48,81,AE,80,00,98
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[6] = 0x42;
@@ -6039,7 +7343,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[2] = 0x80;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_1[0] = 0x98;
-
 // Bytes for TH-filter part 2 (01): 02,AB,2A,20,99,5B,89,28
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[7] = 0x02;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[6] = 0xAB;
@@ -6049,7 +7352,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[2] = 0x5B;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[1] = 0x89;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_2[0] = 0x28;
-
 // Bytes for TH-filter part 3 (02): 00,88,DA,25,34,C5,4C,BA
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[7] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[6] = 0x88;
@@ -6059,10 +7361,8 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[2] = 0xC5;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[1] = 0x4C;
 	j->m_DAAShadowRegs.COP_REGS.COP.THFilterCoeff_3[0] = 0xBA;
-
 // ;  idle
-
-// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
+	// Bytes for Ringing part 1 (03):1B,3C,93,3A,22,12,A3,23
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[7] = 0x1B;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[6] = 0x3C;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[5] = 0x93;
@@ -6071,7 +7371,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[2] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[1] = 0xA3;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_1[0] = 0x23;
-
 // Bytes for Ringing part 2 (06):12,A2,A6,BA,22,7A,0A,D5
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[7] = 0x12;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[6] = 0xA2;
@@ -6081,13 +7380,11 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[2] = 0x7A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[1] = 0x0A;
 	j->m_DAAShadowRegs.COP_REGS.COP.RingerImpendance_2[0] = 0xD5;
-
 // Levelmetering Ringing           (0D):AA,35,0F,8E    ; 25Hz 30V ?????????
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[3] = 0xAA;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[2] = 0x35;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[1] = 0x0F;
 	j->m_DAAShadowRegs.COP_REGS.COP.LevelmeteringRinging[0] = 0x8E;
-
 // Caller ID 1st Tone              (0E):CA,0E,CA,09,99,99,99,99
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[7] = 0xCA;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[6] = 0x0E;
@@ -6097,7 +7394,6 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[2] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[1] = 0x99;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID1stTone[0] = 0x99;
-
 // Caller ID 2nd Tone              (0F):FD,B5,BA,07,DA,00,00,00
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[7] = 0xFD;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[6] = 0xB5;
@@ -6107,76 +7403,62 @@
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[2] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[1] = 0x00;
 	j->m_DAAShadowRegs.COP_REGS.COP.CallerID2ndTone[0] = 0x00;
-
 // ;CR Registers
 	// Config. Reg. 0 (filters)        (cr0):FF
-	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFF;
-
+	j->m_DAAShadowRegs.SOP_REGS.SOP.cr0.reg = 0xFE;
 // Config. Reg. 1 (dialing)        (cr1):05
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr1.reg = 0x05;
-
 // Config. Reg. 2 (caller ID)      (cr2):04
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr2.reg = 0x04;
-
 // Config. Reg. 3 (testloops)      (cr3):00        ; 
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr3.reg = 0x00;
-
 // Config. Reg. 4 (analog gain)    (cr4):01
 	j->m_DAAShadowRegs.SOP_REGS.SOP.cr4.reg = 0x02;		//0x01;
-
-// Config. Reg. 5 (Version)        (cr5):02
+	// Config. Reg. 5 (Version)        (cr5):02
 	// Config. Reg. 6 (Reserved)       (cr6):00
 	// Config. Reg. 7 (Reserved)       (cr7):00
-
-// ;xr Registers
+	// ;xr Registers
 	// Ext. Reg. 0 (Interrupt Reg.)    (xr0):02
+
 	j->m_DAAShadowRegs.XOP_xr0_W.reg = 0x02;	// SO_1 set to '1' because it is inverted.
+	// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 
-// Ext. Reg. 1 (Interrupt enable)  (xr1):1C
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr1.reg = 0x1C;		// RING, Caller ID, VDD_OK
+	// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 
-// Ext. Reg. 2 (Cadence Time Out)  (xr2):7D
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr2.reg = 0x7D;
-
 // Ext. Reg. 3 (DC Char)           (xr3):22        ; 
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr3.reg = 0x22;
-
 // Ext. Reg. 4 (Cadence)           (xr4):00
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr4.reg = 0x00;
-
 // Ext. Reg. 5 (Ring timer)        (xr5):22
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr5.reg = 0x22;
-
 // Ext. Reg. 6 (Power State)       (xr6):00
 	j->m_DAAShadowRegs.XOP_xr6_W.reg = 0x00;
-
 // Ext. Reg. 7 (Vdd)               (xr7):40
 	j->m_DAAShadowRegs.XOP_REGS.XOP.xr7.reg = 0x40;		// 0x40 ??? Should it be 0x00?
-
-// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
+	// DTMF Tone 1                     (0B): 11,B3,5A,2C    ;   697 Hz  
 	//                                       12,33,5A,C3    ;  770 Hz  
 	//                                       13,3C,5B,32    ;  852 Hz  
 	//                                       1D,1B,5C,CC    ;  941 Hz  
+
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[3] = 0x11;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[2] = 0xB3;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[1] = 0x5A;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone1Coeff[0] = 0x2C;
-
 // DTMF Tone 2                     (0C): 32,32,52,B3    ;  1209 Hz  
 	//                                       EC,1D,52,22    ;  1336 Hz  
 	//                                       AA,AC,51,D2    ;  1477 Hz  
 	//                                       9B,3B,51,25    ;  1633 Hz  
-
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[3] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[2] = 0x32;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[1] = 0x52;
 	j->m_DAAShadowRegs.COP_REGS.COP.Tone2Coeff[0] = 0xB3;
-
 }
 
 static s16 tone_table[][19] =
 {
-	{			// f20_50[]
+	{			// f20_50[] 11
 		32538,		// A1 = 1.985962
 		 -32325,	// A2 = -0.986511
 		 -343,		// B2 = -0.010493
@@ -6197,7 +7479,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// f133_200[]
+	{			// f133_200[] 12
 		32072,		// A1 = 1.95752
 		 -31896,	// A2 = -0.973419
 		 -435,		// B2 = -0.013294
@@ -6218,7 +7500,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// 300.txt
+	{			// 300.txt 13
 		31769,		// A1 = -1.939026
 		 -32584,	// A2 = 0.994385
 		 -475,		// B2 = -0.014522
@@ -6239,7 +7521,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// f300_420[]
+	{			// f300_420[] 14
 		30750,		// A1 = 1.876892
 		 -31212,	// A2 = -0.952515
 		 -804,		// B2 = -0.024541
@@ -6260,7 +7542,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// 330.txt
+	{			// 330.txt 15
 		31613,		// A1 = -1.929565
 		 -32646,	// A2 = 0.996277
 		 -185,		// B2 = -0.005657
@@ -6281,7 +7563,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// f300_425[]
+	{			// f300_425[] 16
 		30741,		// A1 = 1.876282
 		 -31475,	// A2 = -0.960541
 		 -703,		// B2 = -0.021484
@@ -6302,7 +7584,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// f330_440[]
+	{			// f330_440[] 17
 		30627,		// A1 = 1.869324
 		 -31338,	// A2 = -0.95636
 		 -843,		// B2 = -0.025749
@@ -6323,7 +7605,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// 340.txt
+	{			// 340.txt 18
 		31546,		// A1 = -1.925476
 		 -32646,	// A2 = 0.996277
 		 -445,		// B2 = -0.013588
@@ -6344,7 +7626,7 @@
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
 	},
-	{			// f350_400[]
+	{			// f350_400[] 19
 		31006,		// A1 = 1.892517
 		 -32029,	// A2 = -0.977448
 		 -461,		// B2 = -0.014096
@@ -7708,21 +8990,19 @@
 		 159,		// Minimum in-band energy threshold
 		 21,		// 21/32 in-band to broad-band ratio
 		 0x0FF5		// shift-mask 0x0FF (look at 16 half-frames) bit count = 5
-	},};
-
+	},
+};
 static int ixj_init_filter(int board, IXJ_FILTER * jf)
 {
 	unsigned short cmd;
 	int cnt, max;
 	IXJ *j = &ixj[board];
-
 	if (jf->filter > 3) {
 		return -1;
 	}
 	if (ixj_WriteDSPCommand(0x5154 + jf->filter, board))	// Select Filter
 
 		return -1;
-
 	if (!jf->enable) {
 		if (ixj_WriteDSPCommand(0x5152, board))		// Disable Filter
 
@@ -7733,7 +9013,6 @@
 		if (ixj_WriteDSPCommand(0x5153, board))		// Enable Filter
 
 			return -1;
-
 		// Select the filter (f0 - f3) to use.
 		if (ixj_WriteDSPCommand(0x5154 + jf->filter, board))
 			return -1;
@@ -7750,7 +9029,6 @@
 		// frequency we want.
 		if (ixj_WriteDSPCommand(0x5170 + jf->filter, board))
 			return -1;
-
 		if (j->ver.low != 0x12) {
 			cmd = 0x515B;
 			max = 19;
@@ -7760,23 +9038,12 @@
 		}
 		if (ixj_WriteDSPCommand(cmd, board))
 			return -1;
-
 		for (cnt = 0; cnt < max; cnt++) {
-			if (ixj_WriteDSPCommand(tone_table[jf->freq][cnt], board))
+			if (ixj_WriteDSPCommand(tone_table[jf->freq - 12][cnt], board))
 				return -1;
 		}
-/*    if(j->ver.low != 0x12)
-   {
-   if(ixj_WriteDSPCommand(7, board))
-   return -1;
-   if(ixj_WriteDSPCommand(159, board))
-   return -1;
-   if(ixj_WriteDSPCommand(21, board))
-   return -1;
-   if(ixj_WriteDSPCommand(0x0FF5, board))
-   return -1;
-   } */
 	}
+	j->filter_en[jf->filter] = jf->enable;
 	return 0;
 }
 
@@ -7784,7 +9051,6 @@
 {
 	int freq0, freq1;
 	unsigned short data;
-
 	if (ti->freq0) {
 		freq0 = ti->freq0;
 	} else {
@@ -7797,18 +9063,15 @@
 		freq1 = 0x7FFF;
 	}
 
-//  if(ti->tone_index > 12 && ti->tone_index < 28)
+	if(ti->tone_index > 12 && ti->tone_index < 28)
 	{
 		if (ixj_WriteDSPCommand(0x6800 + ti->tone_index, board))
 			return -1;
-
 		if (ixj_WriteDSPCommand(0x6000 + (ti->gain0 << 4) + ti->gain1, board))
 			return -1;
-
 		data = freq0;
 		if (ixj_WriteDSPCommand(data, board))
 			return -1;
-
 		data = freq1;
 		if (ixj_WriteDSPCommand(data, board))
 			return -1;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/telephony/ixj.h linux.17p18/drivers/telephony/ixj.h
--- linux.vanilla/drivers/telephony/ixj.h	Wed May  3 22:34:44 2000
+++ linux.17p18/drivers/telephony/ixj.h	Thu Aug 17 18:15:14 2000
@@ -1,4 +1,4 @@
-/*
+/******************************************************************************
  *    ixj.h
  *
  *    Device Driver for the Internet PhoneJACK and
@@ -22,8 +22,20 @@
  * at our website:    http://www.quicknet.net
  *
  * Fixes:
- */
-static char ixj_h_rcsid[] = "$Id: ixj.h,v 3.4 1999/12/16 22:18:36 root Exp root $";
+ *
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION 
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ *****************************************************************************/
+static char ixj_h_rcsid[] = "$Id: ixj.h,v 3.14 2000/03/30 22:06:48 eokerson Exp $";
 
 #ifndef _I386_TYPES_H
 #include <asm/types.h>
@@ -60,6 +72,27 @@
 	unsigned char high;
 } BYTES;
 
+typedef union {
+        BYTES bytes;
+        short word;
+} IXJ_WORD;
+
+typedef struct{
+	unsigned int b0:1;
+	unsigned int b1:1;
+	unsigned int b2:1;
+	unsigned int b3:1;
+	unsigned int b4:1;
+	unsigned int b5:1;
+	unsigned int b6:1;
+	unsigned int b7:1;
+} IXJ_CBITS;
+
+typedef union{
+	IXJ_CBITS cbits;
+	  char  cbyte;
+} IXJ_CBYTE;
+
 int ixj_WriteDSPCommand(unsigned short, int board);
 
 /******************************************************************************
@@ -327,6 +360,199 @@
 
 /******************************************************************************
 *
+*  These structures deal with the control logic on the Internet PhoneCARD
+*
+******************************************************************************/
+typedef struct {
+	unsigned int x0:4;	// unused bits
+
+	unsigned int ed:1;	// Event Detect
+
+	unsigned int drf:1;	// Smart Cable Removal Flag 1=no cable
+
+	unsigned int dspf:1;	// DSP Flag 1=DSP Ready
+
+	unsigned int crr:1;	// Control Register Ready
+
+} COMMAND_REG1;
+
+typedef union {
+	COMMAND_REG1 bits;
+	unsigned char byte;
+} PCMCIA_CR1;
+
+typedef struct {
+	unsigned int x0:4;	// unused bits
+
+	unsigned int rstc:1;	// Smart Cable Reset
+
+	unsigned int pwr:1;	// Smart Cable Power
+
+	unsigned int x1:2;	// unused bits
+
+} COMMAND_REG2;
+
+typedef union {
+	COMMAND_REG2 bits;
+	unsigned char byte;
+} PCMCIA_CR2;
+
+typedef struct {
+	unsigned int addr:5;	// R/W Smart Cable Register Address
+
+	unsigned int rw:1;	// Read / Write flag
+
+	unsigned int dev:2;	// 2 bit Smart Cable Device Address
+
+} CONTROL_REG;
+
+typedef union {
+	CONTROL_REG bits;
+	unsigned char byte;
+} PCMCIA_SCCR;
+
+typedef struct {
+	unsigned int hsw:1;
+	unsigned int det:1;
+	unsigned int led2:1;
+	unsigned int led1:1;
+	unsigned int ring1:1;
+	unsigned int ring0:1;
+	unsigned int x:1;
+	unsigned int powerdown:1;
+} PCMCIA_SLIC_REG;
+
+typedef union {
+	PCMCIA_SLIC_REG bits;
+	unsigned char byte;
+} PCMCIA_SLIC;
+
+typedef struct {
+	unsigned int cpd:1;	// Chip Power Down
+
+	unsigned int mpd:1;	// MIC Bias Power Down
+
+	unsigned int hpd:1;	// Handset Drive Power Down
+
+	unsigned int lpd:1;	// Line Drive Power Down
+
+	unsigned int spd:1;	// Speaker Drive Power Down
+
+	unsigned int x:2;	// unused bits
+
+	unsigned int sr:1;	// Software Reset
+
+} Si3CONTROL1;
+
+typedef union {
+	Si3CONTROL1 bits;
+	unsigned char byte;
+} Si3C1;
+
+typedef struct {
+	unsigned int al:1;	// Analog Loopback DAC analog -> ADC analog
+
+	unsigned int dl2:1;	// Digital Loopback DAC -> ADC one bit
+
+	unsigned int dl1:1;	// Digital Loopback ADC -> DAC one bit
+
+	unsigned int pll:1;	// 1 = div 10, 0 = div 5
+
+	unsigned int hpd:1;	// HPF disable
+
+	unsigned int x:3;	// unused bits
+
+} Si3CONTROL2;
+
+typedef union {
+	Si3CONTROL2 bits;
+	unsigned char byte;
+} Si3C2;
+
+typedef struct {
+	unsigned int iir:1;	// 1 enables IIR, 0 enables FIR
+
+	unsigned int him:1;	// Handset Input Mute
+
+	unsigned int mcm:1;	// MIC In Mute
+
+	unsigned int mcg:2;	// MIC In Gain
+
+	unsigned int lim:1;	// Line In Mute
+
+	unsigned int lig:2;	// Line In Gain
+
+} Si3RXGAIN;
+
+typedef union {
+	Si3RXGAIN bits;
+	unsigned char byte;
+} Si3RXG;
+
+typedef struct {
+	unsigned int hom:1;	// Handset Out Mute
+
+	unsigned int lom:1;	// Line Out Mute
+
+	unsigned int rxg:5;	// RX PGA Gain
+
+	unsigned int x:1;	// unused bit
+
+} Si3ADCVOLUME;
+
+typedef union {
+	Si3ADCVOLUME bits;
+	unsigned char byte;
+} Si3ADC;
+
+typedef struct {
+	unsigned int srm:1;	// Speaker Right Mute
+
+	unsigned int slm:1;	// Speaker Left Mute
+
+	unsigned int txg:5;	// TX PGA Gain
+
+	unsigned int x:1;	// unused bit
+
+} Si3DACVOLUME;
+
+typedef union {
+	Si3DACVOLUME bits;
+	unsigned char byte;
+} Si3DAC;
+
+typedef struct {
+	unsigned int x:5;	// unused bit
+
+	unsigned int losc:1;	// Line Out Short Circuit
+
+	unsigned int srsc:1;	// Speaker Right Short Circuit
+
+	unsigned int slsc:1;	// Speaker Left Short Circuit
+
+} Si3STATUSREPORT;
+
+typedef union {
+	Si3STATUSREPORT bits;
+	unsigned char byte;
+} Si3STAT;
+
+typedef struct {
+	unsigned int sot:2;	// Speaker Out Attenuation
+
+	unsigned int lot:2;	// Line Out Attenuation
+
+	unsigned int x:4;	// unused bits
+
+} Si3ANALOGATTN;
+
+typedef union {
+	Si3ANALOGATTN bits;
+	unsigned char byte;
+} Si3AATT;
+
+/******************************************************************************
+*
 *  These structures deal with the DAA on the Internet LineJACK
 *
 ******************************************************************************/
@@ -854,10 +1080,49 @@
 };
 
 typedef struct {
+	char enable;
+	char en_filter;
+	unsigned int filter;
+	unsigned int state;	// State 0 when cadence has not started.
+
+	unsigned int on1;	// State 1
+
+	unsigned long on1min;	// State 1 - 10% + jiffies
+ 	unsigned long on1dot;	// State 1 + jiffies
+
+	unsigned long on1max;	// State 1 + 10% + jiffies
+
+	unsigned int off1;	// State 2
+
+	unsigned long off1min;
+	unsigned long off1max;
+	unsigned int on2;	// State 3
+
+	unsigned long on2min;
+	unsigned long on2dot;
+	unsigned long on2max;
+	unsigned int off2;	// State 4
+
+	unsigned long off2min;
+	unsigned long off2max;
+	unsigned int on3;	// State 5
+
+	unsigned long on3min;
+	unsigned long on3dot;
+	unsigned long on3max;
+	unsigned int off3;	// State 6
+
+	unsigned long off3min;
+	unsigned long off3max;
+} IXJ_CADENCE_F;
+
+typedef struct {
 	unsigned int busytone:1;
 	unsigned int dialtone:1;
 	unsigned int ringback:1;
 	unsigned int ringing:1;
+	unsigned int playing:1;
+	unsigned int recording:1;
 	unsigned int cringing:1;
 	unsigned int play_first_frame:1;
 	unsigned int pstn_present:1;
@@ -868,6 +1133,28 @@
 	unsigned int ts85_loaded:1;
 	unsigned int dtmf_oob:1;	// DTMF Out-Of-Band
 
+	unsigned int pcmciascp:1;	// Smart Cable Present
+
+	unsigned int pcmciasct:2;	// Smart Cable Type
+
+	unsigned int pcmciastate:3;	// Smart Cable Init State
+
+	unsigned int inwrite:1;	// Currently writing
+
+	unsigned int inread:1;	// Currently reading
+
+	unsigned int incheck:1;	// Currently checking the smart cable
+
+	unsigned int cidplay:1; // Currently playing Caller ID
+
+	unsigned int cidring:1; // This is the ring for Caller ID
+
+	unsigned int cidsent:1; // Caller ID has been sent
+
+	unsigned int cidcw_ack:1; // Caller ID CW ACK (from CPE)
+
+	unsigned int x:6;	// unsed bits
+
 } IXJ_FLAGS;
 
 /******************************************************************************
@@ -884,15 +1171,19 @@
 	unsigned int serial;
 	struct phone_capability caplist[30];
 	unsigned int caps;
+	unsigned int country;
 	struct pnp_dev *dev;
 	unsigned int cardtype;
 	unsigned int rec_codec;
 	char rec_mode;
 	unsigned int play_codec;
+	unsigned int cid_play_codec;
 	char play_mode;
 	IXJ_FLAGS flags;
 	unsigned int rec_frame_size;
 	unsigned int play_frame_size;
+	unsigned int cid_base_frame_size;
+	unsigned long cidcw_wait;
 	int aec_level;
 	int readers, writers;
 	struct wait_queue *poll_q;
@@ -919,6 +1210,7 @@
 	char maxrings;
 	IXJ_CADENCE *cadence_t;
 	int tone_cadence_state;
+	IXJ_CADENCE_F cadence_f[4];
 	DTMF dtmf;
 	CPTF cptf;
 	BYTES dsp;
@@ -933,30 +1225,50 @@
 	PLD_SLICW pld_slicw;
 	PLD_SLICR pld_slicr;
 	PLD_CLOCK pld_clock;
+	PCMCIA_CR1 pccr1;
+	PCMCIA_CR2 pccr2;
+	PCMCIA_SCCR psccr;
+	PCMCIA_SLIC pslic;
+	char pscdd;
+	Si3C1 sic1;
+	Si3C2 sic2;
+	Si3RXG sirxg;
+	Si3ADC siadc;
+	Si3DAC sidac;
+	Si3STAT sistat;
+	Si3AATT siaatt;
 	MIX mix;
 	unsigned short ring_cadence;
 	int ring_cadence_t;
 	unsigned long ring_cadence_jif;
+	unsigned long checkwait;
 	int intercom;
 	int m_hook;
 	int r_hook;
 	char pstn_envelope;
 	char pstn_cid_intr;
+	unsigned char fskz;
+	unsigned char fskphase;
+	unsigned char fskcnt;
 	unsigned pstn_cid_recieved;
-	IXJ_CID cid;
+	PHONE_CID cid;
+	PHONE_CID cid_send;
 	unsigned long pstn_ring_start;
+	unsigned long pstn_ring_stop;
 	unsigned long pstn_winkstart;
 	unsigned int winktime;
+	unsigned long flash_end;
 	char port;
 	union telephony_exception ex;
 	char daa_mode;
+	char daa_country;
 	unsigned long pstn_sleeptil;
 	DAA_REGS m_DAAShadowRegs;
 	Proc_Info_Type Info_read;
 	Proc_Info_Type Info_write;
 	unsigned short frame_count;
-	unsigned int filter_cadence;
 	unsigned int filter_hist[4];
+	unsigned char filter_en[4];
 	unsigned short proc_load;
 	unsigned long framesread;
 	unsigned long frameswritten;
@@ -965,6 +1277,8 @@
 	unsigned long timerchecks;
 	unsigned long txreadycheck;
 	unsigned long rxreadycheck;
+	short fskdata[8000];
+	int fskdcnt;
 } IXJ;
 
 typedef int (*IXJ_REGFUNC) (IXJ * j, unsigned long arg);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/Config.in linux.17p18/drivers/video/Config.in
--- linux.vanilla/drivers/video/Config.in	Fri Apr 21 12:46:38 2000
+++ linux.17p18/drivers/video/Config.in	Tue Aug  1 18:08:17 2000
@@ -49,6 +49,8 @@
   fi
   if [ "$CONFIG_ATARI" = "y" ]; then
     bool 'Atari native chipset support' CONFIG_FB_ATARI
+  fi
+  if [ "$CONFIG_ATARI" = "y" -o "$CONFIG_PCI" != "n" ]; then
     bool 'ATI Mach64 display support' CONFIG_FB_ATY
   fi
   if [ "$CONFIG_PPC" = "y" ]; then
@@ -60,6 +62,7 @@
       bool 'IMS Twin Turbo display support' CONFIG_FB_IMSTT
       bool 'Chips 65550 display support' CONFIG_FB_CT65550
       bool 'S3 Trio display support' CONFIG_FB_S3TRIO
+      bool 'Backward compatibility mode for Xpmac' CONFIG_FB_COMPAT_XPMAC
     fi
   fi
   if [ "$CONFIG_MAC" = "y" ]; then
@@ -89,7 +92,7 @@
         bool '  G100/G200 support' CONFIG_FB_MATROX_G100
         bool '  Multihead support' CONFIG_FB_MATROX_MULTIHEAD
       fi
-      bool 'ATI Mach64 display support' CONFIG_FB_ATY
+      bool 'ATI Rage128 display support' CONFIG_FB_ATY128
     fi
   fi
   if [ "$ARCH" = "sparc" -o "$ARCH" = "sparc64" ]; then
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/Makefile linux.17p18/drivers/video/Makefile
--- linux.vanilla/drivers/video/Makefile	Fri Apr 21 12:46:39 2000
+++ linux.17p18/drivers/video/Makefile	Tue Aug  1 07:59:59 2000
@@ -104,6 +104,10 @@
 L_OBJS += atyfb.o
 endif
 
+ifeq ($(CONFIG_FB_ATY128),y)
+  L_OBJS += aty128fb.o
+endif
+
 ifeq ($(CONFIG_FB_IGA),y)
 L_OBJS += igafb.o
 endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/aty.h linux.17p18/drivers/video/aty.h
--- linux.vanilla/drivers/video/aty.h	Fri Apr 21 12:46:38 2000
+++ linux.17p18/drivers/video/aty.h	Fri Aug  4 15:28:41 2000
@@ -67,6 +67,8 @@
 #define CUR_HORZ_VERT_POSN	0x006C	/* Dword offset 0_1B */
 #define CUR_HORZ_VERT_OFF	0x0070	/* Dword offset 0_1C */
 
+#define CONFIG_PANEL_LG		0x0074	/* Dword offset 0_1D */
+
 #define GP_IO			0x0078	/* Dword offset 0_1E */
 
 #define HW_DEBUG		0x007C	/* Dword offset 0_1F */
@@ -82,6 +84,9 @@
 
 #define BUS_CNTL		0x00A0	/* Dword offset 0_28 */
 
+#define LCD_INDEX		0x00A4	/* Dword offset 0_29 */
+#define LCD_DATA		0x00A8	/* Dword offset 0_2A */
+
 #define EXT_MEM_CNTL		0x00AC	/* Dword offset 0_2B */
 #define MEM_CNTL		0x00B0	/* Dword offset 0_2C */
 
@@ -100,8 +105,9 @@
 #define GEN_TEST_CNTL		0x00D0	/* Dword offset 0_34 */
 
 #define CUSTOM_MACRO_CNTL	0x00D4	/* Dword offset 0_35 */
+#define LCD_GEN_CNTL_LG		0x00D4	/* Dword offset 0_35 */
 
-#define POWER_MANAGEMENT	0x00D8	/* Dword offset 0_36 (LG) */
+#define POWER_MANAGEMENT_LG	0x00D8	/* Dword offset 0_36 (LG) */
 
 #define CONFIG_CNTL		0x00DC	/* Dword offset 0_37 (CT, ET, VT) */
 #define CONFIG_CHIP_ID		0x00E0	/* Dword offset 0_38 */
@@ -453,6 +459,7 @@
 #define VERTEX_2_SECONDARY_T	0x0738	/* Dword offset 1_CE */
 #define VERTEX_2_SECONDARY_W	0x073C	/* Dword offset 1_CF */
 
+#define GTC_3D_RESET_DELAY	3	/* 3D engine reset delay in ms */
 
 /* CRTC control values (mostly CRTC_GEN_CNTL) */
 
@@ -725,7 +732,7 @@
 /* mach64CT family / mach64GT (3D RAGE) class */
 #define LB_CHIP_ID	0x4c42	/* RAGE LT PRO, AGP */
 #define LD_CHIP_ID	0x4c44	/* RAGE LT PRO */
-#define LG_CHIP_ID	0x4c47	/* RAGE LT PRO */
+#define LG_CHIP_ID	0x4c47	/* RAGE LT */
 #define LI_CHIP_ID	0x4c49	/* RAGE LT PRO */
 #define LP_CHIP_ID	0x4c50	/* RAGE LT PRO */
 #define LT_CHIP_ID	0x4c54	/* RAGE LT */
@@ -739,6 +746,8 @@
 #define GI_CHIP_ID	0x4749	/* RAGE PRO, BGA, PCI33 only */
 #define GP_CHIP_ID	0x4750	/* RAGE PRO, PQFP, PCI33, full 3D */
 #define GQ_CHIP_ID	0x4751	/* RAGE PRO, PQFP, PCI33, limited 3D */
+#define LM_CHIP_ID	0x4c4d	/* RAGE Mobility PCI */
+#define LN_CHIP_ID	0x4c4e	/* RAGE Mobility AGP */
 
 
 /* Mach64 major ASIC revisions */
@@ -951,15 +960,50 @@
 #define MACH64_NUM_CLOCKS	16
 #define MACH64_NUM_FREQS	50
 
-/* Power Management register constants (LTG and LT Pro) */
+/* Power Management register constants (LT & LT Pro) */
 #define PWR_MGT_ON		0x00000001
 #define PWR_MGT_MODE_MASK	0x00000006
 #define AUTO_PWR_UP		0x00000008
+#define USE_F32KHZ		0x00000400
+#define TRISTATE_MEM_EN		0x00000800
 #define SELF_REFRESH		0x00000080
 #define PWR_BLON		0x02000000
 #define STANDBY_NOW		0x10000000
 #define SUSPEND_NOW		0x20000000
 #define PWR_MGT_STATUS_MASK	0xC0000000
 #define PWR_MGT_STATUS_SUSPEND	0x80000000
+
+/* PM Mode constants  */
+#define PWR_MGT_MODE_PIN	0x00000000
+#define PWR_MGT_MODE_REG	0x00000002
+#define PWR_MGT_MODE_TIMER	0x00000004
+#define PWR_MGT_MODE_PCI	0x00000006
+
+/* LCD registers (LT Pro) */
+
+/* LCD Index register */
+#define LCD_INDEX_MASK		0x0000003F
+#define LCD_DISPLAY_DIS		0x00000100
+#define LCD_SRC_SEL		0x00000200
+#define CRTC2_DISPLAY_DIS	0x00000400
+
+/* LCD register indices */
+#define LCD_CONFIG_PANEL	0x00
+#define LCD_GEN_CTRL		0x01
+#define LCD_DSTN_CONTROL	0x02
+#define LCD_HFB_PITCH_ADDR	0x03
+#define LCD_HORZ_STRETCHING	0x04
+#define LCD_VERT_STRETCHING	0x05
+#define LCD_EXT_VERT_STRETCH	0x06
+#define LCD_LT_GIO		0x07
+#define LCD_POWER_MANAGEMENT	0x08
+#define LCD_ZVGPIO		0x09
+#define LCD_MISC_CNTL		0x14
+
+/* Values in LCD_MISC_CNTL */
+#define BIAS_MOD_LEVEL_MASK	0x0000ff00
+#define BIAS_MOD_LEVEL_SHIFT	8
+#define BLMOD_EN		0x00010000
+#define BIASMOD_EN		0x00020000
 
 #endif /* REGMACH64_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/aty128.h linux.17p18/drivers/video/aty128.h
--- linux.vanilla/drivers/video/aty128.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/video/aty128.h	Tue Aug  1 07:59:59 2000
@@ -0,0 +1,342 @@
+/*  $Id: aty128.h,v 1.1 1999/10/12 11:00:40 geert Exp $
+ *  linux/drivers/video/aty128.h
+ *  Register definitions for ATI Rage128 boards
+ *
+ *  Anthony Tong <atong@uiuc.edu>, 1999
+ *  Brad Douglas <brad@neruo.com>, 2000
+ */
+
+#ifndef REG_RAGE128_H
+#define REG_RAGE128_H
+
+#define CLOCK_CNTL_INDEX			0x0008
+#define CLOCK_CNTL_DATA				0x000c
+#define BIOS_0_SCRATCH				0x0010
+#define BUS_CNTL				0x0030
+#define GEN_INT_CNTL				0x0040
+#define CRTC_GEN_CNTL				0x0050
+#define CRTC_EXT_CNTL				0x0054
+#define DAC_CNTL				0x0058
+#define I2C_CNTL_1				0x0094
+#define PALETTE_INDEX				0x00b0
+#define PALETTE_DATA				0x00b4
+#define CONFIG_CNTL				0x00e0
+#define GEN_RESET_CNTL				0x00f0
+#define CONFIG_MEMSIZE				0x00f8
+#define MEM_CNTL				0x0140
+#define AGP_BASE				0x0170
+#define AGP_CNTL				0x0174
+#define AGP_APER_OFFSET				0x0178
+#define PCI_GART_PAGE				0x017c
+#define PC_NGUI_MODE				0x0180
+#define PC_NGUI_CTLSTAT				0x0184
+#define MPP_TB_CONFIG				0x01C0
+#define MPP_GP_CONFIG				0x01C8
+#define VIPH_CONTROL				0x01D0
+#define CRTC_H_TOTAL_DISP			0x0200
+#define CRTC_H_SYNC_STRT_WID			0x0204
+#define CRTC_V_TOTAL_DISP			0x0208
+#define CRTC_V_SYNC_STRT_WID			0x020c
+#define CRTC_OFFSET				0x0224
+#define CRTC_OFFSET_CNTL			0x0228
+#define CRTC_PITCH				0x022c
+#define OVR_CLR					0x0230
+#define OVR_WID_LEFT_RIGHT			0x0234
+#define OVR_WID_TOP_BOTTOM			0x0238
+#define DDA_CONFIG				0x02e0
+#define DDA_ON_OFF				0x02e4
+#define VGA_DDA_CONFIG				0x02e8
+#define VGA_DDA_ON_OFF				0x02ec
+#define OV0_SCALE_CNTL				0x0420
+#define SUBPIC_CNTL				0x0540
+#define PM4_BUFFER_OFFSET			0x0700
+#define PM4_BUFFER_CNTL				0x0704
+#define PM4_BUFFER_WM_CNTL			0x0708
+#define PM4_BUFFER_DL_RPTR_ADDR			0x070c
+#define PM4_BUFFER_DL_RPTR			0x0710
+#define PM4_BUFFER_DL_WPTR			0x0714
+#define PM4_VC_FPU_SETUP			0x071c
+#define PM4_FPU_CNTL				0x0720
+#define PM4_VC_FORMAT				0x0724
+#define PM4_VC_CNTL				0x0728
+#define PM4_VC_I01				0x072c
+#define PM4_VC_VLOFF				0x0730
+#define PM4_VC_VLSIZE				0x0734
+#define PM4_IW_INDOFF				0x0738
+#define PM4_IW_INDSIZE				0x073c
+#define PM4_FPU_FPX0				0x0740
+#define PM4_FPU_FPY0				0x0744
+#define PM4_FPU_FPX1				0x0748
+#define PM4_FPU_FPY1				0x074c
+#define PM4_FPU_FPX2				0x0750
+#define PM4_FPU_FPY2				0x0754
+#define PM4_FPU_FPY3				0x0758
+#define PM4_FPU_FPY4				0x075c
+#define PM4_FPU_FPY5				0x0760
+#define PM4_FPU_FPY6				0x0764
+#define PM4_FPU_FPR				0x0768
+#define PM4_FPU_FPG				0x076c
+#define PM4_FPU_FPB				0x0770
+#define PM4_FPU_FPA				0x0774
+#define PM4_FPU_INTXY0				0x0780
+#define PM4_FPU_INTXY1				0x0784
+#define PM4_FPU_INTXY2				0x0788
+#define PM4_FPU_INTARGB				0x078c
+#define PM4_FPU_FPTWICEAREA			0x0790
+#define PM4_FPU_DMAJOR01			0x0794
+#define PM4_FPU_DMAJOR12			0x0798
+#define PM4_FPU_DMAJOR02			0x079c
+#define PM4_FPU_STAT				0x07a0
+#define PM4_STAT				0x07b8
+#define PM4_TEST_CNTL				0x07d0
+#define PM4_MICROCODE_ADDR			0x07d4
+#define PM4_MICROCODE_RADDR			0x07d8
+#define PM4_MICROCODE_DATAH			0x07dc
+#define PM4_MICROCODE_DATAL			0x07e0
+#define PM4_CMDFIFO_ADDR			0x07e4
+#define PM4_CMDFIFO_DATAH			0x07e8
+#define PM4_CMDFIFO_DATAL			0x07ec
+#define PM4_BUFFER_ADDR				0x07f0
+#define PM4_BUFFER_DATAH			0x07f4
+#define PM4_BUFFER_DATAL			0x07f8
+#define PM4_MICRO_CNTL				0x07fc
+#define CAP0_TRIG_CNTL				0x0950
+#define CAP1_TRIG_CNTL				0x09c0
+
+/******************************************************************************
+ *                  GUI Block Memory Mapped Registers                         *
+ *                     These registers are FIFOed.                            *
+ *****************************************************************************/
+#define PM4_FIFO_DATA_EVEN			0x1000
+#define PM4_FIFO_DATA_ODD			0x1004
+
+#define DST_OFFSET				0x1404
+#define DST_PITCH				0x1408
+#define DST_WIDTH				0x140c
+#define DST_HEIGHT				0x1410
+#define SRC_X					0x1414
+#define SRC_Y					0x1418
+#define DST_X					0x141c
+#define DST_Y					0x1420
+#define SRC_PITCH_OFFSET			0x1428
+#define DST_PITCH_OFFSET			0x142c
+#define SRC_Y_X					0x1434
+#define DST_Y_X					0x1438
+#define DST_HEIGHT_WIDTH			0x143c
+#define DP_GUI_MASTER_CNTL			0x146c
+#define BRUSH_SCALE				0x1470
+#define BRUSH_Y_X				0x1474
+#define DP_BRUSH_BKGD_CLR			0x1478
+#define DP_BRUSH_FRGD_CLR			0x147c
+#define DST_WIDTH_X				0x1588
+#define DST_HEIGHT_WIDTH_8			0x158c
+#define SRC_X_Y					0x1590
+#define DST_X_Y					0x1594
+#define DST_WIDTH_HEIGHT			0x1598
+#define DST_WIDTH_X_INCY			0x159c
+#define DST_HEIGHT_Y				0x15a0
+#define DST_X_SUB				0x15a4
+#define DST_Y_SUB				0x15a8
+#define SRC_OFFSET				0x15ac
+#define SRC_PITCH				0x15b0
+#define DST_HEIGHT_WIDTH_BW			0x15b4
+#define CLR_CMP_CNTL				0x15c0
+#define CLR_CMP_CLR_SRC				0x15c4
+#define CLR_CMP_CLR_DST				0x15c8
+#define CLR_CMP_MASK				0x15cc
+#define DP_SRC_FRGD_CLR				0x15d8
+#define DP_SRC_BKGD_CLR				0x15dc
+#define DST_BRES_ERR				0x1628
+#define DST_BRES_INC				0x162c
+#define DST_BRES_DEC				0x1630
+#define DST_BRES_LNTH				0x1634
+#define DST_BRES_LNTH_SUB			0x1638
+#define SC_LEFT					0x1640
+#define SC_RIGHT				0x1644
+#define SC_TOP					0x1648
+#define SC_BOTTOM				0x164c
+#define SRC_SC_RIGHT				0x1654
+#define SRC_SC_BOTTOM				0x165c
+#define GUI_DEBUG0				0x16a0
+#define GUI_DEBUG1				0x16a4
+#define GUI_TIMEOUT				0x16b0
+#define GUI_TIMEOUT0				0x16b4
+#define GUI_TIMEOUT1				0x16b8
+#define GUI_PROBE				0x16bc
+#define DP_CNTL					0x16c0
+#define DP_DATATYPE				0x16c4
+#define DP_MIX					0x16c8
+#define DP_WRITE_MASK				0x16cc
+#define DP_CNTL_XDIR_YDIR_YMAJOR		0x16d0
+#define DEFAULT_OFFSET				0x16e0
+#define DEFAULT_PITCH				0x16e4
+#define DEFAULT_SC_BOTTOM_RIGHT			0x16e8
+#define SC_TOP_LEFT				0x16ec
+#define SC_BOTTOM_RIGHT				0x16f0
+#define SRC_SC_BOTTOM_RIGHT			0x16f4
+#define WAIT_UNTIL				0x1720
+#define CACHE_CNTL				0x1724
+#define GUI_STAT				0x1740
+#define PC_GUI_MODE				0x1744
+#define PC_GUI_CTLSTAT				0x1748
+#define PC_DEBUG_MODE				0x1760
+#define BRES_DST_ERR_DEC			0x1780
+#define TRAIL_BRES_T12_ERR_DEC			0x1784
+#define TRAIL_BRES_T12_INC			0x1788
+#define DP_T12_CNTL				0x178c
+#define DST_BRES_T1_LNTH			0x1790
+#define DST_BRES_T2_LNTH			0x1794
+#define SCALE_SRC_HEIGHT_WIDTH			0x1994
+#define SCALE_OFFSET_0				0x1998
+#define SCALE_PITCH				0x199c
+#define SCALE_X_INC				0x19a0
+#define SCALE_Y_INC				0x19a4
+#define SCALE_HACC				0x19a8
+#define SCALE_VACC				0x19ac
+#define SCALE_DST_X_Y				0x19b0
+#define SCALE_DST_HEIGHT_WIDTH			0x19b4
+#define SCALE_3D_CNTL				0x1a00
+#define SCALE_3D_DATATYPE			0x1a20
+#define SETUP_CNTL				0x1bc4
+#define SOLID_COLOR				0x1bc8
+#define WINDOW_XY_OFFSET			0x1bcc
+#define DRAW_LINE_POINT				0x1bd0
+#define SETUP_CNTL_PM4				0x1bd4
+#define DST_PITCH_OFFSET_C			0x1c80
+#define DP_GUI_MASTER_CNTL_C			0x1c84
+#define SC_TOP_LEFT_C				0x1c88
+#define SC_BOTTOM_RIGHT_C			0x1c8c
+
+#define CLR_CMP_MASK_3D				0x1A28
+#define MISC_3D_STATE_CNTL_REG			0x1CA0
+#define MC_SRC1_CNTL				0x19D8
+#define TEX_CNTL				0x1800
+
+/* CONSTANTS */
+#define GUI_ACTIVE				0x80000000
+#define ENGINE_IDLE				0x0
+
+#define PLL_WR_EN				0x00000080
+
+#define CLK_PIN_CNTL				0x0001
+#define PPLL_CNTL				0x0002
+#define PPLL_REF_DIV				0x0003
+#define PPLL_DIV_0				0x0004
+#define PPLL_DIV_1				0x0005
+#define PPLL_DIV_2				0x0006
+#define PPLL_DIV_3				0x0007
+#define VCLK_ECP_CNTL				0x0008
+#define HTOTAL_CNTL				0x0009
+#define X_MPLL_REF_FB_DIV			0x000a
+#define XPLL_CNTL				0x000b
+#define XDLL_CNTL				0x000c
+#define XCLK_CNTL				0x000d
+#define MPLL_CNTL				0x000e
+#define MCLK_CNTL				0x000f
+#define AGP_PLL_CNTL				0x0010
+#define FCP_CNTL				0x0012
+#define PLL_TEST_CNTL				0x0013
+
+#define PPLL_RESET				0x01
+#define PPLL_ATOMIC_UPDATE_EN			0x10000
+#define PPLL_VGA_ATOMIC_UPDATE_EN		0x20000
+#define PPLL_REF_DIV_MASK			0x3FF
+#define PPLL_FB3_DIV_MASK			0x7FF
+#define PPLL_POST3_DIV_MASK			0x70000
+#define PPLL_ATOMIC_UPDATE_R			0x8000
+#define PPLL_ATOMIC_UPDATE_W			0x8000
+#define MEM_CFG_TYPE_MASK			0x3
+#define XCLK_SRC_SEL_MASK			0x7
+#define XPLL_FB_DIV_MASK			0xFF00
+#define X_MPLL_REF_DIV_MASK			0xFF
+
+/* CRTC control values (CRTC_GEN_CNTL) */
+#define CRTC_CSYNC_EN				0x00000010
+
+#define CRTC_PIX_WIDTH_MASK			0x00000700
+#define CRTC_PIX_WIDTH_4BPP			0x00000100
+#define CRTC_PIX_WIDTH_8BPP			0x00000200
+#define CRTC_PIX_WIDTH_15BPP			0x00000300
+#define CRTC_PIX_WIDTH_16BPP			0x00000400
+#define CRTC_PIX_WIDTH_24BPP			0x00000500
+#define CRTC_PIX_WIDTH_32BPP			0x00000600
+
+/* DAC_CNTL bit constants */                       
+#define DAC_8BIT_EN				0x00000100
+#define DAC_MASK				0xFF000000
+#define DAC_BLANKING				0x00000004
+#define DAC_RANGE_CNTL				0x00000003
+#define PALETTE_ACCESS_CNTL			0x00000020
+
+/* GEN_RESET_CNTL bit constants */
+#define SOFT_RESET_GUI				0x00000001
+#define SOFT_RESET_VCLK				0x00000100
+#define SOFT_RESET_PCLK				0x00000200
+#define SOFT_RESET_ECP				0x00000400
+#define SOFT_RESET_DISPENG_XCLK			0x00000800
+
+/* PC_GUI_CTLSTAT bit constants */
+#define PC_BUSY_INIT				0x10000000                 
+#define PC_BUSY_GUI				0x20000000                 
+#define PC_BUSY_NGUI				0x40000000
+#define PC_BUSY					0x80000000
+
+#define BUS_MASTER_DIS				0x00000040
+#define PM4_BUFFER_CNTL_NONPM4			0x00000000
+
+/* DP_DATATYPE bit constants */
+#define DST_8BPP				0x00000002
+#define DST_15BPP				0x00000003
+#define DST_16BPP				0x00000004
+#define DST_24BPP				0x00000005
+#define DST_32BPP				0x00000006
+
+#define BRUSH_SOLIDCOLOR			0x00000d00
+
+/* DP_GUI_MASTER_CNTL bit constants */
+#define	GMC_SRC_PITCH_OFFSET_DEFAULT		0x00000000
+#define GMC_DST_PITCH_OFFSET_DEFAULT		0x00000000
+#define GMC_SRC_CLIP_DEFAULT			0x00000000
+#define GMC_DST_CLIP_DEFAULT			0x00000000
+#define GMC_BRUSH_SOLIDCOLOR			0x000000d0
+#define GMC_SRC_DSTCOLOR			0x00003000
+#define GMC_BYTE_ORDER_MSB_TO_LSB		0x00000000
+#define GMC_DP_SRC_RECT				0x02000000
+#define GMC_3D_FCN_EN_CLR			0x00000000
+#define GMC_AUX_CLIP_CLEAR			0x20000000
+#define GMC_DST_CLR_CMP_FCN_CLEAR		0x10000000
+#define GMC_WRITE_MASK_SET			0x40000000
+#define GMC_DP_CONVERSION_TEMP_6500		0x00000000
+
+/* DP_GUI_MASTER_CNTL ROP3 named constants */
+#define	ROP3_PATCOPY				0x00f00000
+#define ROP3_SRCCOPY				0x00cc0000
+
+#define SRC_DSTCOLOR				0x00030000
+
+/* DP_CNTL bit constants */
+#define DST_X_RIGHT_TO_LEFT			0x00000000
+#define DST_X_LEFT_TO_RIGHT			0x00000001
+#define DST_Y_BOTTOM_TO_TOP			0x00000000
+#define DST_Y_TOP_TO_BOTTOM			0x00000002
+#define DST_X_MAJOR				0x00000000
+#define DST_Y_MAJOR				0x00000004
+#define DST_X_TILE				0x00000008
+#define DST_Y_TILE				0x00000010
+#define DST_LAST_PEL				0x00000020
+#define DST_TRAIL_X_RIGHT_TO_LEFT		0x00000000
+#define DST_TRAIL_X_LEFT_TO_RIGHT		0x00000040
+#define DST_TRAP_FILL_RIGHT_TO_LEFT		0x00000000
+#define DST_TRAP_FILL_LEFT_TO_RIGHT		0x00000080
+#define DST_BRES_SIGN				0x00000100
+#define DST_HOST_BIG_ENDIAN_EN			0x00000200
+#define DST_POLYLINE_NONLAST			0x00008000
+#define DST_RASTER_STALL			0x00010000
+#define DST_POLY_EDGE				0x00040000
+
+/* DP_MIX bit constants */
+#define DP_SRC_RECT				0x00000200
+#define DP_SRC_HOST				0x00000300
+#define DP_SRC_HOST_BYTEALIGN			0x00000400
+
+#endif /* REG_RAGE128_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/aty128fb.c linux.17p18/drivers/video/aty128fb.c
--- linux.vanilla/drivers/video/aty128fb.c	Thu Jan  1 01:00:00 1970
+++ linux.17p18/drivers/video/aty128fb.c	Tue Aug  1 07:59:59 2000
@@ -0,0 +1,2644 @@
+/* $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
+ *
+ *  Based off of Geert's atyfb.c and vfb.c.
+ *
+ *  TODO:
+ *		- panning
+ *		- monitor sensing (DDC)
+ *              - virtual display
+ *		- other platform support (only ppc/x86 supported)
+ *		- PPLL_REF_DIV & XTALIN calculation    -done for x86
+ *		- determine MCLK from previous setting -done for x86            
+ *              - calculate XCLK, rather than probe BIOS
+ *		- hardware cursor support
+ *              - acceleration ( do not use with Rage128 Pro!)
+ *		- ioctl()'s
+ */
+
+/*
+ * A special note of gratitude to ATI's devrel for providing documentation,
+ * example code and hardware. Thanks Nitya.	-atong and brad
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/tty.h>
+#include <linux/malloc.h>
+#include <linux/vmalloc.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/uaccess.h>
+#include <linux/fb.h>
+#include <linux/init.h>
+#include <linux/selection.h>
+#include <linux/pci.h>
+#include <linux/ioport.h>
+#include <asm/io.h>
+
+#ifdef CONFIG_PPC
+#include <asm/prom.h>
+#include <asm/pci-bridge.h>
+#include <linux/nvram.h>
+#include <video/macmodes.h>
+#endif
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+#include <asm/vc_ioctl.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>
+
+#ifdef CONFIG_MTRR
+#include <asm/mtrr.h>
+#endif /* CONFIG_MTRR */
+
+#include "aty128.h"
+
+/* Debug flag */
+#undef DEBUG
+
+#ifdef DEBUG
+#define DBG(x)		printk(KERN_DEBUG "aty128fb: %s\n",(x));
+#else
+#define DBG(x)
+#endif
+
+#ifndef CONFIG_PPC
+/* default mode */
+static struct fb_var_screeninfo default_var = {
+    /* 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_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_PPC */
+
+/* struct to hold chip description information */
+struct aty128_chip_info {
+    const char *name;
+    unsigned short device;
+    int chip_gen;
+};
+
+/* Chip generations */
+enum {
+	rage_128,
+	rage_128_pro,
+	rage_M3
+};
+
+/* supported Rage128 chipsets */
+static const struct aty128_chip_info aty128_pci_probe_list[] __initdata =
+{
+    {"Rage128 RE (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RE, rage_128},
+    {"Rage128 RF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RF, rage_128},
+    {"Rage128 RK (PCI)", PCI_DEVICE_ID_ATI_RAGE128_RK, rage_128},
+    {"Rage128 RL (AGP)", PCI_DEVICE_ID_ATI_RAGE128_RL, rage_128},
+    {"Rage128 Pro PF (AGP)", PCI_DEVICE_ID_ATI_RAGE128_PF, rage_128_pro},
+    {"Rage128 Pro PR (PCI)", PCI_DEVICE_ID_ATI_RAGE128_PR, rage_128_pro},
+    {"Rage Mobility M3 (PCI)", PCI_DEVICE_ID_ATI_RAGE128_LE, rage_M3},
+    {"Rage Mobility M3 (AGP)", PCI_DEVICE_ID_ATI_RAGE128_LF, rage_M3},
+    {NULL, 0, rage_128}
+ };
+
+/* packed BIOS settings */
+#pragma pack(1)
+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;
+} PLL_BLOCK;
+#pragma pack()
+
+/* 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 */
+const struct aty128_meminfo sdr_128   =
+    { 4, 4, 3, 3, 1, 3, 1, 16, 30, 16, "128-bit SDR SGRAM (1:1)" };
+const struct aty128_meminfo sdr_64    =
+    { 4, 8, 3, 3, 1, 3, 1, 17, 46, 17, "64-bit SDR SGRAM (1:1)" };
+const struct aty128_meminfo sdr_sgram =
+    { 4, 4, 1, 2, 1, 2, 1, 16, 24, 16, "64-bit SDR SGRAM (2:1)" };
+const struct aty128_meminfo ddr_sgram =
+    { 4, 4, 3, 3, 2, 3, 1, 16, 31, 16, "64-bit DDR SGRAM" };
+
+static int currcon = 0;
+static char *aty128fb_name = "ATY Rage128";
+static char fontname[40]  = { 0 };
+static char noaccel = 1;
+static unsigned int initdepth = 8;
+
+#ifndef MODULE
+static const char *mode_option = NULL;
+#endif
+
+#ifndef CONFIG_PPC
+static void *bios_seg = NULL;
+#endif
+
+#if defined(CONFIG_PPC)
+static int default_vmode = VMODE_CHOOSE;
+static int default_cmode = CMODE_8;
+#endif
+
+#ifdef CONFIG_MTRR
+static int mtrr = 1;
+#endif /* CONFIG_MTRR */
+
+/* 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 ext_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 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 fb_info_aty128 {
+    struct fb_info fb_info;
+    struct fb_info_aty128 *next;
+    struct aty128_constants constants;  /* PLL and others      */
+    unsigned long regbase_phys;         /* physical mmio       */
+    void *regbase;                      /* remapped mmio       */
+    unsigned long frame_buffer_phys;    /* physical fb memory  */
+    unsigned long frame_buffer;         /* remaped framebuffer */
+    const struct aty128_meminfo *mem;   /* onboard mem info    */
+    u32 vram_size;                      /* onboard video ram   */
+    int chip_gen;
+    struct aty128fb_par default_par, current_par;
+    struct display disp;
+    struct display_switch dispsw;       /* for cursor and font */
+    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;
+    int blitter_may_be_busy;
+#ifdef CONFIG_PCI
+    struct pci_dev *pdev;
+#endif
+#ifdef CONFIG_MTRR
+    struct { int vram; int vram_valid; } mtrr;
+#endif
+    int fifo_slots;
+};
+
+static struct fb_info_aty128 *board_list = NULL;
+
+#define round_div(n, d) ((n+(d/2))/d)
+
+    /*
+     *  Interface used by the world
+     */
+
+int aty128fb_setup(char *options);
+
+static int aty128fb_open(struct fb_info *info, int user);
+static int aty128fb_release(struct fb_info *info, int user);
+static int aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con,
+		       struct fb_info *info);
+static int aty128fb_get_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info);
+static int aty128fb_set_var(struct fb_var_screeninfo *var, int con,
+		       struct fb_info *info);
+static int aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+static int aty128fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info);
+static int aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *fb);
+static int aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		     u_long arg, int con, struct fb_info *info);
+
+
+    /*
+     *  Interface to the low level console driver
+     */
+
+#ifdef CONFIG_FB_OF
+void aty128fb_of_init(struct device_node *dp);
+#endif
+int aty128fb_init(void);
+static int aty128fbcon_switch(int con, struct fb_info *info);
+static void aty128fbcon_blank(int blank, struct fb_info *info);
+
+
+    /*
+     *  Internal routines
+     */
+
+static void aty128_encode_fix(struct fb_fix_screeninfo *fix,
+				struct aty128fb_par *par,
+				const struct fb_info_aty128 *info);
+static void aty128_set_disp(struct display *disp,
+			struct fb_info_aty128 *info, int bpp, int accel);
+static int aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+				u_int *transp, struct fb_info *info);
+static int aty128_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+				u_int transp, struct fb_info *info);
+static void do_install_cmap(int con, struct fb_info *info);
+#ifndef CONFIG_FB_OF
+static int aty128_pci_register(struct pci_dev *pdev,
+                               const struct aty128_chip_info *aci);
+#endif
+
+static int aty128_encode_var(struct fb_var_screeninfo *var,
+                             const struct aty128fb_par *par,
+                             const struct fb_info_aty128 *info);
+static int aty128_decode_var(struct fb_var_screeninfo *var,
+                             struct aty128fb_par *par,
+                             const struct fb_info_aty128 *info);
+static struct fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128
+				*board_list, struct fb_info_aty128 *new_node);
+static int aty128find_ROM(struct fb_info_aty128 *info);
+#ifndef CONFIG_PPC
+static void aty128_get_pllinfo(struct fb_info_aty128 *info);
+#endif
+static void aty128_timings(struct fb_info_aty128 *info);
+static void aty128_init_engine(const struct aty128fb_par *par, 
+				struct fb_info_aty128 *info);
+static void aty128_reset_engine(const struct fb_info_aty128 *info);
+static void aty128_flush_pixel_cache(const struct fb_info_aty128 *info);
+static void do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
+static void wait_for_fifo(u16 entries, struct fb_info_aty128 *info);
+static void wait_for_idle(struct fb_info_aty128 *info);
+static u32 bpp_to_depth(u32 bpp);
+
+#ifdef FBCON_HAS_CFB8
+static struct display_switch fbcon_aty128_8;
+static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
+#endif
+#ifdef FBCON_HAS_CFB16
+static struct display_switch fbcon_aty128_16;
+static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
+#endif
+#ifdef FBCON_HAS_CFB24
+static struct display_switch fbcon_aty128_24;
+static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
+#endif
+#ifdef FBCON_HAS_CFB32
+static struct display_switch fbcon_aty128_32;
+static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx);
+static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx);
+#endif
+
+static struct fb_ops aty128fb_ops = {
+    aty128fb_open, aty128fb_release, aty128fb_get_fix,
+    aty128fb_get_var, aty128fb_set_var, aty128fb_get_cmap,
+    aty128fb_set_cmap, aty128fb_pan_display, aty128fb_ioctl
+};
+
+
+    /*
+     * Functions to read from/write to the mmio registers
+     *	- endian conversions may possibly be avoided by flipping CONFIG_CNTL
+     *  or using the other register aperture? TODO.
+     */
+static inline u32
+_aty_ld_le32(volatile unsigned int regindex, 
+                              const struct fb_info_aty128 *info)
+{
+    unsigned long *temp;
+    u32 val;
+
+#if defined(__powerpc__)
+    temp = info->regbase;
+    __asm__ __volatile__("eieio;lwbrx %0,%1,%2" : "=b"(val) : "b" (regindex), "b" (temp));
+#else
+    temp = info->regbase+regindex;
+    val = readl (temp);
+#endif
+
+    return val;
+}
+
+static inline void
+_aty_st_le32(volatile unsigned int regindex, u32 val, 
+                               const struct fb_info_aty128 *info)
+{
+    unsigned long *temp;
+
+#if defined(__powerpc__)
+    temp = info->regbase;
+    __asm__ __volatile__("eieio; stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) :
+        "memory");
+#elif defined(__mc68000__)
+    *((volatile u32 *)(info->regbase+regindex)) = cpu_to_le32(val);
+#else
+    temp = info->regbase+regindex;
+    writel (val, temp);
+#endif
+}
+
+static inline u8
+_aty_ld_8(unsigned int regindex, const struct fb_info_aty128 *info)
+{
+#if defined(__powerpc__)
+    eieio();
+#endif
+    return readb (info->regbase + regindex);
+}
+
+static inline void
+_aty_st_8(unsigned int regindex, u8 val, const struct fb_info_aty128 *info)
+{
+#if defined(__powerpc__)
+    eieio();
+#endif
+    writeb (val, info->regbase + regindex);
+}
+
+#define aty_ld_le32(regindex)		_aty_ld_le32(regindex, info)
+#define aty_st_le32(regindex, val)	_aty_st_le32(regindex, val, info)
+#define aty_ld_8(regindex)		_aty_ld_8(regindex, info)
+#define aty_st_8(regindex, val)		_aty_st_8(regindex, val, info)
+
+    /*
+     * Functions to read from/write to the pll registers
+     */
+
+#define aty_ld_pll(pll_index)		_aty_ld_pll(pll_index, info)
+#define aty_st_pll(pll_index, val)	_aty_st_pll(pll_index, val, info)
+
+
+static u32
+_aty_ld_pll(unsigned int pll_index,
+			const struct fb_info_aty128 *info)
+{       
+    aty_st_8(CLOCK_CNTL_INDEX, pll_index & 0x1F);
+    return aty_ld_le32(CLOCK_CNTL_DATA);
+}
+
+    
+static void
+_aty_st_pll(unsigned int pll_index, u32 val,
+			const struct fb_info_aty128 *info)
+{   
+    aty_st_8(CLOCK_CNTL_INDEX, (pll_index & 0x1F) | 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 fb_info_aty128 *info)
+{
+    return !(aty_ld_pll(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
+}
+
+
+static void
+aty_pll_wait_readupdate(const struct fb_info_aty128 *info)
+{
+    unsigned long timeout = jiffies + HZ/100;	// should be more than enough
+    int reset = 1;
+
+    while (time_before(jiffies, timeout))
+	if (aty_pll_readupdate(info)) {
+	    reset = 0;
+	    break;
+	}
+
+#ifdef DEBUG
+    if (reset)	/* reset engine?? */
+	DBG("PLL write timeout!");
+#endif
+}
+
+
+/* tell PLL to update */
+static void
+aty_pll_writeupdate(const struct fb_info_aty128 *info)
+{
+    aty_pll_wait_readupdate(info);
+
+    aty_st_pll(PPLL_REF_DIV,
+	aty_ld_pll(PPLL_REF_DIV) | PPLL_ATOMIC_UPDATE_W);
+}
+
+    /*
+     * Accelerator engine functions
+     */
+static void
+do_wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
+{
+    int i;
+
+    for (;;) {
+        for (i = 0; i < 2000000; i++) {
+            info->fifo_slots = aty_ld_le32(GUI_STAT) & 0x0fff;
+            if (info->fifo_slots >= entries)
+                return;
+        }
+	aty128_reset_engine(info);
+    }
+}
+
+static void
+wait_for_idle(struct fb_info_aty128 *info)
+{
+    int i;
+
+    do_wait_for_fifo(64, info);
+
+    for (;;) {
+        for (i = 0; i < 2000000; i++) {
+            if (!(aty_ld_le32(GUI_STAT) & (1 << 31))) {
+                aty128_flush_pixel_cache(info);
+                info->blitter_may_be_busy = 0;
+                return;
+            }
+        }
+        aty128_reset_engine(info);
+    }
+}
+
+
+static void
+aty128_flush_pixel_cache(const struct fb_info_aty128 *info)
+{
+    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
+wait_for_fifo(u16 entries, struct fb_info_aty128 *info)
+{
+    if (info->fifo_slots < entries)
+        do_wait_for_fifo(64, info);
+    info->fifo_slots -= entries;
+}
+
+
+static void
+aty128_reset_engine(const struct fb_info_aty128 *info)
+{
+    u32 gen_reset_cntl, clock_cntl_index, mclk_cntl;
+
+    aty128_flush_pixel_cache(info);
+
+    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);
+
+#ifdef DEBUG
+    DBG("engine reset");
+#endif
+}
+
+
+static void
+aty128_init_engine(const struct aty128fb_par *par,
+		struct fb_info_aty128 *info)
+{
+    u32 pitch_value;
+
+    wait_for_idle(info);
+
+    /* 3D scaler not spoken here */
+    aty_st_le32(SCALE_3D_CNTL, 0x00000000);
+
+    aty128_reset_engine(info);
+
+    pitch_value = par->crtc.pitch;	/* fix this up */
+    if (par->crtc.bpp == 24) {
+        pitch_value = pitch_value * 3;
+    }
+
+    /* setup engine offset registers */
+    wait_for_fifo(4, info);
+    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 */
+    wait_for_fifo(1, info);
+    aty_st_le32(DEFAULT_SC_BOTTOM_RIGHT, (0x1FFF << 16) | 0x1FFF);
+
+    /* set the drawing controls registers */
+    wait_for_fifo(1, info);
+    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			|
+		(bpp_to_depth(par->crtc.bpp) << 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, info);
+
+    /* 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(info);
+}
+
+
+/* convert bpp values to their register representation */
+static u32
+bpp_to_depth(u32 bpp)
+{
+    if (bpp <= 8)
+	return DST_8BPP;
+    else if (bpp <= 16)
+        return DST_15BPP;
+    else if (bpp <= 24)
+	return DST_24BPP;
+    else if (bpp <= 32)
+	return DST_32BPP;
+
+    return -EINVAL;
+}
+
+    /*
+     * CRTC programming
+     */
+
+
+/* Program the CRTC registers */
+static void
+aty128_set_crtc(const struct aty128_crtc *crtc,
+		const struct fb_info_aty128 *info)
+{
+    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?
+     * -- BenH: Breaks on my G4
+     */
+#if 0
+    aty_st_le32(PPLL_CNTL, aty_ld_le32(PPLL_CNTL) & ~(0x00030000));
+#endif
+}
+
+
+static int
+aty128_var_to_crtc(const struct fb_var_screeninfo *var,
+			struct aty128_crtc *crtc,
+			const struct fb_info_aty128 *info)
+{
+    u32 xres, yres, vxres, vyres, xoffset, yoffset, bpp;
+    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 hsync_strt_pix[5] = { 0, 0x12, 9, 6, 5 };
+    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;
+
+    /* 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;
+
+    depth = bpp_to_depth(bpp);
+
+    /* make sure we didn't get an invalid depth */
+    if (depth == -EINVAL) {
+        printk(KERN_ERR "aty128fb: Invalid depth\n");
+        return -EINVAL;
+    }
+
+   bytpp = mode_bytpp[depth];
+
+    /* make sure there is enough video ram for the mode */
+    if ((u32)(vxres * vyres * bytpp) > info->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) / 8) - 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/8 - 1) > 0x1ff || (v_total - 1) > 0x7FF) {
+        printk(KERN_ERR "aty128fb: invalid width ranges\n");
+        return -EINVAL;
+    }
+
+    h_sync_wid = (hslen+7)/8;
+    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 + (right/8);
+
+    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 = 0x03000000L | c_sync | (depth << 8);
+
+    crtc->h_total = h_total | (h_disp << 16);
+    crtc->v_total = v_total | (v_disp << 16);
+
+    crtc->h_sync_strt_wid = hsync_strt_pix[bytpp] | (h_sync_strt << 3) |
+                (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 = xres >> 3;
+
+    crtc->offset = 0;
+    crtc->offset_cntl = 0;
+
+    crtc->vxres = vxres;
+    crtc->vyres = vyres;
+    crtc->xoffset = xoffset;
+    crtc->yoffset = yoffset;
+    crtc->bpp = bpp;
+
+    return 0;
+}
+
+
+static int
+aty128_bpp_to_var(int pix_width, struct fb_var_screeninfo *var)
+{
+
+    /* fill in pixel info */
+    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.offset = 0;
+	var->blue.length = 8;
+	var->transp.offset = 0;
+	var->transp.length = 0;
+	break;
+    case CRTC_PIX_WIDTH_15BPP:
+    case CRTC_PIX_WIDTH_16BPP:
+	var->bits_per_pixel = 16;
+	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 = 0;
+	var->transp.length = 0;
+	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.offset = 0;
+        var->blue.length = 8;
+        var->transp.offset = 0;
+        var->transp.length = 0;
+        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.offset = 0;
+	var->blue.length = 8;
+	var->transp.offset = 24;
+	var->transp.length = 8;
+	break;
+    default:
+        printk(KERN_ERR "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;
+
+    xres  = (h_disp+1) << 3;
+    yres  = v_disp+1;
+    left  = (h_total-h_sync_strt-h_sync_wid)*8-h_sync_dly;
+    right = (h_sync_strt-h_disp)*8+h_sync_dly;
+    hslen = h_sync_wid*8;
+    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_bpp_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;
+}
+
+static void
+aty128_set_pll(struct aty128_pll *pll, const struct fb_info_aty128 *info)
+{
+    int 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_st_pll(PPLL_REF_DIV, info->constants.ref_divider & 0x3ff);
+    aty_pll_writeupdate(info);
+    aty_pll_wait_readupdate(info);
+
+    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_st_pll(PPLL_DIV_3, div3);
+    aty_pll_writeupdate(info);
+    aty_pll_wait_readupdate(info);
+
+    aty_st_pll(HTOTAL_CNTL, 0);	/* no horiz crtc adjustment */
+
+    aty_pll_writeupdate(info);
+
+    /* 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 fb_info_aty128 *info)
+{
+    const struct aty128_constants c = info->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;
+
+#ifdef DEBUG
+    printk(KERN_DEBUG "var_to_pll: post %d feedback %d vlck %d output %d ref_divider %d\n", 
+           pll->post_divider, pll->feedback_divider, vclk, output_freq,
+           c.ref_divider);
+    printk(KERN_DEBUG "var_to_pll: vclk_per: %d\n", period_in_ps);
+#endif
+
+    return 0;
+}
+
+
+static int
+aty128_pll_to_var(const struct aty128_pll *pll, struct fb_var_screeninfo *var,
+		const struct fb_info_aty128 *info)
+{
+    var->pixclock = 100000000 / pll->vclk;
+
+    return 0;
+}
+
+
+static void
+aty128_set_fifo(const struct aty128_ddafifo *dsp,
+			const struct fb_info_aty128 *info)
+{
+    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 bpp,
+		const struct fb_info_aty128 *info)
+{
+    const struct aty128_meminfo *m = info->mem;
+    u32 xclk = info->constants.xclk;
+    u32 fifo_width = info->constants.fifo_width;
+    u32 fifo_depth = info->constants.fifo_depth;
+    s32 x, b, p, ron, roff;
+    u32 n, d;
+
+    /* 15bpp is really 16bpp */
+    if (bpp == 15)
+	bpp = 16;
+
+    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;
+
+#ifdef DEBUG
+    printk(KERN_DEBUG "aty128fb: x %x\n", x);
+#endif
+    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;
+    }
+
+#ifdef DEBUG
+    printk(KERN_DEBUG "aty128fb: p: %x rloop: %x x: %x ron: %x roff: %x\n",
+                       p, m->Rloop, x, ron, roff);
+#endif
+    dsp->dda_config = p << 16 | m->Rloop << 20 | x;
+    dsp->dda_on_off = ron << 16 | roff;
+
+    return 0;
+}
+
+
+/*
+ * This actually sets the video mode.
+ */
+static void
+aty128_set_par(struct aty128fb_par *par,
+			struct fb_info_aty128 *info)
+{ 
+    u32 config;
+#ifdef CONFIG_FB_COMPAT_XPMAC
+    struct fb_var_screeninfo var;
+    int cmode, vmode;
+#endif
+    
+    info->current_par = *par;
+    
+    if (info->blitter_may_be_busy)
+        wait_for_idle(info);
+
+    /* 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, info);
+    aty128_set_pll(&par->pll, info);
+    aty128_set_fifo(&par->fifo_reg, info);
+
+    config = aty_ld_le32(CONFIG_CNTL) & ~3;
+
+#if defined(__BIG_ENDIAN)
+    if (par->crtc.bpp >= 24)
+	config |= 2;	/* make aperture do 32 byte swapping */
+    else if (par->crtc.bpp > 8)
+	config |= 1;	/* make aperture do 16 byte swapping */
+#endif
+
+    aty_st_le32(CONFIG_CNTL, config);
+    aty_st_8(CRTC_EXT_CNTL + 1, 0);	/* turn the video back on */
+
+    if (par->accel_flags & FB_ACCELF_TEXT)
+        aty128_init_engine(par, info);
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+    if (!console_fb_info || console_fb_info == &info->fb_info) {
+	display_info.height = ((par->crtc.v_total >> 16) & 0x7ff)+1;
+	display_info.width = (((par->crtc.h_total >> 16) & 0xff)+1) << 3;
+	display_info.depth = par->crtc.bpp;
+	display_info.pitch = par->crtc.vxres*par->crtc.bpp >> 3;
+        aty128_encode_var(&var, par, info);
+	if (mac_var_to_vmode(&var, &vmode, &cmode))
+	    display_info.mode = 0;
+	else
+	    display_info.mode = vmode;
+	strcpy(display_info.name, aty128fb_name);
+	display_info.fb_address = info->frame_buffer_phys;
+	display_info.cmap_adr_address = 0;
+	display_info.cmap_data_address = 0;
+	display_info.disp_reg_address = info->regbase_phys;
+    }
+#endif /* CONFIG_FB_COMPAT_XPMAC */
+}
+
+
+    /*
+     *  Open/Release the frame buffer device
+     */
+
+static int aty128fb_open(struct fb_info *info, int user)
+{
+    MOD_INC_USE_COUNT;
+    return(0);                              
+}
+        
+
+static int aty128fb_release(struct fb_info *info, int user)
+{
+    MOD_DEC_USE_COUNT;
+    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,
+			const struct fb_info_aty128 *info)
+{
+    int err;
+
+    if ((err = aty128_var_to_crtc(var, &par->crtc, info)))
+ 	return err;
+
+    if ((err = aty128_var_to_pll(var->pixclock, &par->pll, info)))
+	return err;
+
+    if ((err = aty128_ddafifo(&par->fifo_reg, &par->pll, par->crtc.bpp, info)))
+	return err;
+
+    if (var->accel_flags & FB_ACCELF_TEXT)
+	par->accel_flags = FB_ACCELF_TEXT;
+    else
+	par->accel_flags = 0;
+
+    return 0;
+}
+
+
+static int
+aty128_encode_var(struct fb_var_screeninfo *var,
+			const struct aty128fb_par *par,
+			const struct fb_info_aty128 *info)
+{
+    int err;
+
+    if ((err = aty128_crtc_to_var(&par->crtc, var)))
+	return err;
+
+    if ((err = aty128_pll_to_var(&par->pll, var, info)))
+	return err;
+
+    var->red.msb_right = 0;
+    var->green.msb_right = 0;
+    var->blue.msb_right = 0;
+    var->transp.msb_right = 0;
+
+    var->nonstd = 0;
+    var->activate = 0;
+
+    var->height = -1;
+    var->width = -1;
+    var->accel_flags = par->accel_flags;
+
+    return 0;
+}           
+
+
+    /*
+     *  Get the User Defined Part of the Display
+     */
+
+static int
+aty128fb_get_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+{
+    const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+
+    if (con == -1)
+	aty128_encode_var(var, &info->default_par, info); 
+    else
+	*var = fb_display[con].var;
+    return 0;
+}
+
+
+    /*
+     *  Set the User Defined Part of the Display
+     */
+
+static int
+aty128fb_set_var(struct fb_var_screeninfo *var, int con, struct fb_info *fb)
+{
+    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+    struct aty128fb_par par;
+    struct display *display;
+    int oldxres, oldyres, oldvxres, oldvyres, oldbpp, oldaccel;
+    int accel, err;
+
+    display = (con >= 0) ? &fb_display[con] : fb->disp;
+
+    /* basic (in)sanity checks */
+    if (!var->xres)
+        var->xres = 1;
+    if (!var->yres)
+        var->yres = 1;
+    if (var->xres > var->xres_virtual)
+        var->xres_virtual = var->xres;
+    if (var->yres > var->yres_virtual)
+        var->yres_virtual = var->yres;
+    switch (var->bits_per_pixel) {
+        case 0 ... 8:
+            var->bits_per_pixel = 8;
+            break;
+        case 9 ... 16:
+            var->bits_per_pixel = 16;
+            break;
+        case 17 ... 24:
+            var->bits_per_pixel = 24;
+            break;
+       case 25 ... 32:
+            var->bits_per_pixel = 32;
+            break;
+        default:
+            return -EINVAL;
+    }
+
+    if ((err = aty128_decode_var(var, &par, info)))
+	return err;
+
+    aty128_encode_var(var, &par, info);
+
+    if ((var->activate & FB_ACTIVATE_MASK) != FB_ACTIVATE_NOW)
+	return 0;
+
+    oldxres = display->var.xres;
+    oldyres = display->var.yres;
+    oldvxres = display->var.xres_virtual;
+    oldvyres = display->var.yres_virtual;
+    oldbpp = display->var.bits_per_pixel;
+    oldaccel = display->var.accel_flags;
+    display->var = *var;
+    if (oldxres != var->xres || oldyres != var->yres ||
+	oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+	oldbpp != var->bits_per_pixel || oldaccel != var->accel_flags) {
+
+	struct fb_fix_screeninfo fix;
+
+	aty128_encode_fix(&fix, &par, info);
+        display->screen_base = (char *)info->frame_buffer;
+	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 = 0;
+
+	accel = var->accel_flags & FB_ACCELF_TEXT;
+        aty128_set_disp(display, info, par.crtc.bpp, accel);
+
+	if (accel)
+	    display->scrollmode = SCROLL_YNOMOVE;
+	else
+	    display->scrollmode = SCROLL_YREDRAW;
+
+	if (info->fb_info.changevar)
+	    (*info->fb_info.changevar)(con);
+    }
+
+    if (!info->fb_info.display_fg || info->fb_info.display_fg->vc_num == con)
+	aty128_set_par(&par, info);
+
+    if (oldbpp != var->bits_per_pixel) {
+	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+	    return err;
+	do_install_cmap(con, &info->fb_info);
+    } 
+
+    return 0;
+}
+
+
+static void
+aty128_set_disp(struct display *disp,
+			struct fb_info_aty128 *info, int bpp, int accel)
+{
+    switch (bpp) {
+#ifdef FBCON_HAS_CFB8
+    case 8:
+	info->dispsw = accel ? fbcon_aty128_8 : fbcon_cfb8;
+        disp->dispsw = &info->dispsw;
+	break;
+#endif
+#ifdef FBCON_HAS_CFB16
+    case 15:
+    case 16:
+	info->dispsw = accel ? fbcon_aty128_16 : fbcon_cfb16;
+        disp->dispsw = &info->dispsw;
+	disp->dispsw_data = info->fbcon_cmap.cfb16;
+	break;
+#endif
+#ifdef FBCON_HAS_CFB24
+    case 24:
+	info->dispsw = accel ? fbcon_aty128_24 : fbcon_cfb24;
+        disp->dispsw = &info->dispsw;
+	disp->dispsw_data = info->fbcon_cmap.cfb24;
+	break;
+#endif
+#ifdef FBCON_HAS_CFB32
+    case 32:
+	info->dispsw = accel ? fbcon_aty128_32 : fbcon_cfb32;
+        disp->dispsw = &info->dispsw;
+	disp->dispsw_data = info->fbcon_cmap.cfb32;
+	break;
+#endif
+    default:
+	disp->dispsw = &fbcon_dummy;
+    }
+}
+
+
+static void
+aty128_encode_fix(struct fb_fix_screeninfo *fix,
+			struct aty128fb_par *par,
+			const struct fb_info_aty128 *info)
+{
+    memset(fix, 0, sizeof(struct fb_fix_screeninfo));
+    
+    strcpy(fix->id, aty128fb_name);
+
+    fix->smem_start = (void *)info->frame_buffer_phys;
+    fix->mmio_start = (void *)info->regbase_phys;
+
+    fix->smem_len = (u32)info->vram_size;
+    fix->mmio_len = 0x1fff;
+
+    fix->type = FB_TYPE_PACKED_PIXELS;
+    fix->type_aux = 0;
+    fix->line_length = par->crtc.vxres*par->crtc.bpp/8;
+    fix->visual = par->crtc.bpp <= 8 ? FB_VISUAL_PSEUDOCOLOR
+                                     : FB_VISUAL_DIRECTCOLOR;
+    fix->ywrapstep = 0;
+    fix->xpanstep = 8;
+    fix->ypanstep = 1;
+
+    fix->accel = FB_ACCEL_ATI_RAGE128;
+
+    return;
+}
+
+
+    /*
+     *  Get the Fixed Part of the Display
+     */
+static int
+aty128fb_get_fix(struct fb_fix_screeninfo *fix, int con, struct fb_info *fb)
+{
+    const struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+    struct aty128fb_par par;
+
+    if (con == -1)
+	par = info->default_par;
+    else
+	aty128_decode_var(&fb_display[con].var, &par, info); 
+
+    aty128_encode_fix(fix, &par, info);
+
+    return 0;            
+}
+
+
+    /*
+     *  Pan or Wrap the Display
+     *
+     *  Not supported (yet!)
+     */
+static int
+aty128fb_pan_display(struct fb_var_screeninfo *var, int con,
+			   struct fb_info *fb)
+{
+    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+    struct aty128fb_par *par = &info->current_par;
+    u32 xoffset, yoffset;
+    u32 offset;
+    u32 xres, yres;
+
+    xres = (((par->crtc.h_total >> 16) & 0xff) + 1) * 8;
+    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) >> 6;
+
+    aty_st_le32(CRTC_OFFSET, offset);
+
+    return 0;
+}
+
+
+    /*
+     *  Get the Colormap
+     */
+
+static int
+aty128fb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    if (con == currcon) /* current console? */
+	return fb_get_cmap(cmap, kspc, aty128_getcolreg, info);
+    else if (fb_display[con].cmap.len) /* non default colormap? */
+	fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
+    else {  
+	int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 32;
+	fb_copy_cmap(fb_default_cmap(size), cmap, kspc ? 0 : 2);
+    }
+
+    return 0;
+}
+
+    /*
+     *  Set the Colormap
+     */
+
+static int
+aty128fb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
+			struct fb_info *info)
+{
+    int err;
+    struct display *disp;  
+
+    if (con >= 0)
+	disp = &fb_display[con];
+    else
+	disp = info->disp;
+    if (!disp->cmap.len) {      /* no colormap allocated? */
+        int size = (disp->var.bits_per_pixel <= 8) ? 256 : 32;
+	if ((err = fb_alloc_cmap(&disp->cmap, size, 0)))
+	    return err;
+    }
+
+    if (con == currcon) /* current console? */
+	return fb_set_cmap(cmap, kspc, aty128_setcolreg, info);
+    else
+	fb_copy_cmap(cmap, &disp->cmap, kspc ? 0 : 1);
+
+    return 0;                
+}
+
+
+    /*
+     *  Frame Buffer Specific ioctls
+     */
+
+static int
+aty128fb_ioctl(struct inode *inode, struct file *file, u_int cmd,
+		     u_long arg, int con, struct fb_info *info)
+{
+    return -EINVAL;
+}
+
+
+#ifndef MODULE
+int __init
+aty128fb_setup(char *options)
+{
+    char *this_opt;
+
+    if (!options || !*options)
+	return 0;
+
+    for (this_opt = strtok(options, ","); this_opt;
+	 this_opt = strtok(NULL, ",")) {
+	if (!strncmp(this_opt, "font:", 5)) {
+	    char *p;
+	    int i;
+	    
+	    p = this_opt +5;
+	    for (i = 0; i < sizeof(fontname) - 1; i++)
+		if (!*p || *p == ' ' || *p == ',')
+		    break;
+	    memcpy(fontname, this_opt + 5, i);
+	    fontname[i] = 0;
+	} else if (!strncmp(this_opt, "noaccel", 7)) {
+	    noaccel = 1;
+	} else if (!strncmp(this_opt, "depth:", 6)) {
+            unsigned int depth = simple_strtoul(this_opt+6, NULL, 0);
+            switch (depth) {
+            case 0 ... 8:
+                initdepth = 8;
+#ifdef CONFIG_PPC
+                default_cmode = CMODE_8;
+#endif
+                break;
+            case 9 ... 16:
+                initdepth = 16;
+#ifdef CONFIG_PPC
+                default_cmode = CMODE_16;
+#endif
+                break;
+            case 17 ... 24:
+                initdepth = 24;
+                break;
+            case 25 ... 32:
+                initdepth = 32;
+#ifdef CONFIG_PPC
+                default_cmode = CMODE_32;
+#endif
+                break;
+            default:
+                initdepth = 8;
+            }
+        }
+#ifdef CONFIG_MTRR
+        else if(!strncmp(this_opt, "nomtrr", 6)) {
+            mtrr = 0;
+        }
+#endif /* CONFIG_MTRR */
+#ifdef CONFIG_PPC
+        /* vmode and cmode depreciated */
+	else if (!strncmp(this_opt, "vmode:", 6)) {
+            unsigned int vmode = simple_strtoul(this_opt+6, NULL, 0);
+            if (vmode > 0 && vmode <= VMODE_MAX)
+                default_vmode = vmode;
+        } else if (!strncmp(this_opt, "cmode:", 6)) {
+            unsigned int cmode = simple_strtoul(this_opt+6, NULL, 0);
+            switch (cmode) {
+	    case 0:
+	    case 8:
+		default_cmode = CMODE_8;
+		break;
+	    case 15:
+	    case 16:
+		default_cmode = CMODE_16;
+		break;
+	    case 24:
+	    case 32:
+		default_cmode = CMODE_32;
+		break;
+            }
+        }
+#endif /* CONFIG_PPC */
+        else
+            mode_option = this_opt;
+    }
+    return 0;
+}
+#endif /* !MODULE */
+
+
+    /*
+     *  Initialisation
+     */
+
+static int __init
+aty128_init(struct fb_info_aty128 *info, const char *name)
+{
+    struct fb_var_screeninfo var;
+    u32 dac;
+    int j, k;
+    u8 chip_rev;
+    const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
+    char *video_card = "Rage128";
+
+    if (!info->vram_size)	/* may have already been probed */
+	info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+
+    /* Get the chip revision */
+    chip_rev = (aty_ld_le32(CONFIG_CNTL) >> 16) & 0x1F;
+
+    /* put a name with the face */
+    while (aci->name && info->pdev->device != aci->device) { aci++; }
+    video_card = (char *)aci->name;
+    info->chip_gen = aci->chip_gen;
+
+    printk(KERN_INFO "aty128fb: %s [chip rev 0x%x] ", video_card, chip_rev);
+
+    if (info->vram_size % (1024 * 1024) == 0)
+	printk("%dM %s\n", info->vram_size / (1024*1024), info->mem->name);
+    else
+	printk("%dk %s\n", info->vram_size / 1024, info->mem->name);
+
+    /* fill in info */
+    strcpy(info->fb_info.modename, aty128fb_name);
+    info->fb_info.node = -1;
+    info->fb_info.fbops = &aty128fb_ops;
+    info->fb_info.disp = &info->disp;
+    strcpy(info->fb_info.fontname, fontname);
+    info->fb_info.changevar = NULL;
+    info->fb_info.switch_con = &aty128fbcon_switch;
+    info->fb_info.blank = &aty128fbcon_blank;
+    info->fb_info.flags = FBINFO_FLAG_DEFAULT;
+    
+#ifdef MODULE
+    var = default_var;
+#else
+    memset(&var, 0, sizeof(var));
+
+#ifdef CONFIG_PMAC
+    if (default_vmode == VMODE_CHOOSE) {
+#endif /* CONFIG_PMAC */
+        var = default_var;
+
+#ifdef CONFIG_PMAC
+    } else {
+	if (mac_vmode_to_var(default_vmode, default_cmode, &var))
+	    var = default_var;
+    }
+#endif /* CONFIG_PMAC */
+
+#endif /* MODULE */
+
+    if (noaccel)
+        var.accel_flags &= ~FB_ACCELF_TEXT;
+    else
+        var.accel_flags |= FB_ACCELF_TEXT;
+
+    if (aty128_decode_var(&var, &info->default_par, info)) {
+	printk(KERN_ERR "aty128fb: Cannot set default mode.\n");
+	return 0;
+    }
+
+    /* load up the palette with default colors */
+    for (j = 0; j < 16; j++) {
+        k = color_table[j];
+        info->palette[j].red = default_red[k];
+        info->palette[j].green = default_grn[k];
+        info->palette[j].blue = default_blu[k];
+    }
+
+    dac = aty_ld_le32(DAC_CNTL);
+    dac |= (DAC_8BIT_EN | DAC_RANGE_CNTL | DAC_BLANKING);
+    dac |= DAC_8BIT_EN;			/* set 8 bit dac             */
+    dac |= DAC_MASK;			/* set DAC mask              */
+    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);
+
+    aty128fb_set_var(&var, -1, &info->fb_info);
+    aty128_init_engine(&info->default_par, info);
+
+    board_list = aty128_board_list_add(board_list, info);
+
+    if (register_framebuffer(&info->fb_info) < 0)
+	return 0;
+
+    printk(KERN_INFO "fb%d: %s frame buffer device on %s\n",
+	   GET_FB_IDX(info->fb_info.node), aty128fb_name, name);
+
+    return 1;	/* success! */
+}
+
+
+/* add a new card to the list  ++ajoshi */
+static struct
+fb_info_aty128 *aty128_board_list_add(struct fb_info_aty128 *board_list,
+                                       struct fb_info_aty128 *new_node)
+{
+    struct fb_info_aty128 *i_p = board_list;
+
+    new_node->next = NULL;
+    if(board_list == NULL)
+	return new_node;
+    while(i_p->next != NULL)
+	i_p = i_p->next;
+    i_p->next = new_node;
+
+    return board_list;
+}
+
+
+int __init
+aty128fb_init(void)
+{
+#if defined(CONFIG_FB_OF)
+    /* let offb handle init */
+#elif defined (CONFIG_PCI)
+    struct pci_dev *pdev = NULL;
+    const struct aty128_chip_info *aci = &aty128_pci_probe_list[0];
+
+    while (aci->name != NULL) {
+        pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
+        while (pdev != NULL) {
+            if (aty128_pci_register(pdev, aci) == 0)
+                return 0;
+            pdev = pci_find_device(PCI_VENDOR_ID_ATI, aci->device, pdev);
+        }
+ 	aci++;
+    }
+#endif
+    return 0;
+}
+
+
+#if defined(CONFIG_PCI) && !defined(CONFIG_FB_OF)
+
+/* register a card    ++ajoshi */
+static int __init
+aty128_pci_register(struct pci_dev *pdev,
+                               const struct aty128_chip_info *aci)
+{
+    struct fb_info_aty128 *info = NULL;
+    unsigned long fb_addr, reg_addr;
+    u16 tmp;
+
+    fb_addr = pdev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
+    reg_addr = pdev->base_address[2] & PCI_BASE_ADDRESS_MEM_MASK;
+    if (!reg_addr)
+	return -1;
+
+    info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC);
+    if(!info) {
+        printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
+	goto unmap_out;
+    }
+    memset(info, 0, sizeof(struct fb_info_aty128));
+
+    info->pdev = pdev;
+
+    info->regbase_phys = reg_addr;
+    info->regbase = ioremap(reg_addr, 0x1FFF);
+
+    if (!info->regbase)
+        goto err_out;
+
+    info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+
+    info->frame_buffer_phys = fb_addr;
+    info->frame_buffer = (unsigned long)ioremap(fb_addr, info->vram_size);
+
+    if (!info->frame_buffer)
+        goto err_out;
+
+    pci_read_config_word(pdev, PCI_COMMAND, &tmp);
+    if (!(tmp & PCI_COMMAND_MEMORY)) {
+        tmp |= PCI_COMMAND_MEMORY;
+        pci_write_config_word(pdev, PCI_COMMAND, tmp);
+    }
+
+    if (!aty128find_ROM(info)) {
+       printk(KERN_INFO "aty128fb: Rage128 BIOS not located. Guessing...\n");
+       aty128_timings(info);
+    }
+#ifndef CONFIG_PPC
+   else
+        aty128_get_pllinfo(info);
+
+    /* free up to-be unused resources. bios_seg is mapped by
+     * aty128find_ROM() and used by aty128_get_pllinfo()
+     *
+     * TODO: make more elegant. doesn't need to be global
+     */
+   if (bios_seg)
+        iounmap(bios_seg);
+#endif
+#ifdef CONFIG_MTRR
+    if (mtrr) {
+        info->mtrr.vram = mtrr_add(info->frame_buffer_phys, info->vram_size,
+                                   MTRR_TYPE_WRCOMB, 1);
+        info->mtrr.vram_valid = 1;
+        /* let there be speed */
+        printk(KERN_INFO "aty128fb: Rage128 MTRR set to ON\n");
+    }
+#endif /* CONFIG_MTRR */
+    if (!aty128_init(info, "PCI"))
+        goto err_out;
+
+    return 0;
+
+err_out:
+    kfree (info);
+unmap_out:
+
+    return -1;
+}
+#endif /* ! CONFIG_FB_OF */
+
+static int __init
+aty128find_ROM(struct fb_info_aty128 *info)
+{
+    int  flag = 0;
+#ifndef CONFIG_PPC
+    u32  segstart;
+    char *rom_base;
+    char *rom;
+    int  stage;
+    int  i;
+    char aty_rom_sig[] = "761295520";   /* ATI ROM Signature      */
+    char R128_sig[] = "R128";           /* Rage128 ROM identifier */
+
+    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++) {
+            if (R128_sig[0] == *rom) {
+                if (strncmp(R128_sig, rom, strlen(R128_sig)) == 0) {
+                    stage = 4;
+                }
+            }
+            rom++;
+        }
+        if (stage != 4) {
+            iounmap(rom_base);
+            continue;
+        }
+
+        bios_seg = rom_base;
+        printk(KERN_INFO "aty128fb: Rage128 BIOS located at segment %4.4X\n",
+                         (unsigned int)rom_base);
+
+        flag = 1;
+        break;
+    }
+#endif /* !CONFIG_PPC */
+    return (flag);
+}
+
+#ifndef CONFIG_PPC
+static void __init
+aty128_get_pllinfo(struct fb_info_aty128 *info)
+{   
+    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);
+
+    info->constants.ppll_max = pll.PCLK_max_freq;
+    info->constants.ppll_min = pll.PCLK_min_freq;
+    info->constants.xclk = (u32)pll.XCLK;
+    info->constants.ref_divider = (u32)pll.PCLK_ref_divider;
+    info->constants.dotclock = (u32)pll.PCLK_ref_freq;
+
+    aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider);
+    aty_pll_writeupdate(info);
+
+    info->constants.fifo_width = 128;
+    info->constants.fifo_depth = 32;
+
+#ifdef DEBUG
+    printk(KERN_DEBUG "get_pllinfo: ppll_max %d ppll_min %d xclk %d "
+                      "ref_divider %d dotclock %d\n", 
+                   info->constants.ppll_max, info->constants.ppll_min,
+                   info->constants.xclk, info->constants.ref_divider,
+                   info->constants.dotclock);
+#endif
+
+    switch(aty_ld_le32(MEM_CNTL) & 0x03) {
+    case 0:
+        info->mem = &sdr_128; 
+        break;
+    case 1:
+        info->mem = &sdr_sgram;
+        break;  
+    case 2: 
+        info->mem = &ddr_sgram;
+        break;  
+    default:        
+        info->mem = &sdr_sgram;
+    }       
+
+    return;
+}           
+#endif /* ! CONFIG_PPC */
+
+
+#ifdef CONFIG_FB_OF
+void __init
+aty128fb_get_of_val(struct device_node *dp, char *property, int *value)
+{
+    int *result, size = 0;
+
+    result = (int *) get_property(dp, property, &size);
+    if (size)
+	*value = *result;
+}
+
+void __init
+aty128fb_of_init(struct device_node *dp)
+{
+    unsigned long addr, reg_addr, fb_addr;
+    struct fb_info_aty128 *info;
+    u8 bus, devfn;
+    u16 cmd;
+
+    if (device_is_compatible(dp, "ATY,RageM3p")) {
+	/* XXX kludge for now */
+	if (dp->name == 0 || strcmp(dp->name, "ATY,RageM3pA") != 0
+	    || dp->parent == 0)
+	    return;
+	dp = dp->parent;
+    }
+
+    switch (dp->n_addrs) {
+    case 3:
+	fb_addr = dp->addrs[0].address;
+	reg_addr = dp->addrs[2].address;
+	break;
+    default:
+	printk(KERN_ERR "aty128fb: TODO unexpected addresses\n");
+	return;
+    }
+
+    addr = (unsigned long) ioremap(reg_addr, 0x1FFF);
+    if (!addr) {
+	printk(KERN_ERR "aty128fb: can't map memory registers\n");
+	return;
+    }
+
+    info = kmalloc(sizeof(struct fb_info_aty128), GFP_ATOMIC);
+    if (!info) {
+	printk(KERN_ERR "aty128fb: can't alloc fb_info_aty128\n");
+	return;
+    }
+    memset((void *) info, 0, sizeof(struct fb_info_aty128));
+
+    info->regbase_phys = reg_addr;
+    info->regbase = (void *) addr;
+
+    /* enabled memory-space accesses using config-space command register */
+    if (pci_device_loc(dp, &bus, &devfn) == 0) {
+	pcibios_read_config_word(bus, devfn, PCI_COMMAND, &cmd);
+	if (!(cmd & PCI_COMMAND_MEMORY)) {
+	    cmd |= PCI_COMMAND_MEMORY;
+	    pcibios_write_config_word(bus, devfn, PCI_COMMAND, cmd);
+	}
+	info->pdev = pci_find_slot(bus, devfn);
+    }
+
+    info->vram_size = aty_ld_le32(CONFIG_MEMSIZE) & 0x03FFFFFF;
+    info->frame_buffer_phys = fb_addr;
+    info->frame_buffer = (unsigned long)ioremap(fb_addr, info->vram_size);
+
+    if (!info->frame_buffer) {
+	printk(KERN_ERR "aty128fb: can't map frame buffer\n");
+	kfree(info);
+	return;
+    }
+
+    /* fall back to defaults */
+    aty128_timings(info);
+
+    if (!aty128_init(info, dp->full_name)) {
+	kfree(info);
+	return;
+    }
+
+#ifdef CONFIG_FB_COMPAT_XPMAC
+    if (!console_fb_info)
+	console_fb_info = &info->fb_info;
+#endif
+}
+#endif /* CONFIG_FB_OF */
+
+
+/* fill in known card constants if pll_block is not available */
+static void __init
+aty128_timings(struct fb_info_aty128 *info)
+{
+#if defined(__powerpc__)
+    /* instead of a table lookup assume OF has properly set up
+       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};
+  
+    /* Assume REF clock is 2950 (in units of 10khz) */
+    /* and that all pllclk must be between 125 Mhz and 250Mhz */
+    info->constants.dotclock = 2950; 
+    info->constants.ppll_min = 12500;
+    info->constants.ppll_max = 25000;
+
+    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);
+
+    info->constants.xclk =  round_div((2 * Nx * info->constants.dotclock), 
+			  (M * PostDivSet[xclk_cntl]));
+
+    info->constants.ref_divider = aty_ld_pll(PPLL_REF_DIV) & PPLL_REF_DIV_MASK;
+
+    printk("aty128fb: detected XCLK=0x%x, ref_div=0x%x\n",
+    	info->constants.xclk, info->constants.ref_divider);
+#else
+    
+    /* TODO make an attempt at probing */
+    if (!info->constants.dotclock)
+	info->constants.dotclock = 2950;
+
+    /* from documentation */
+    if (!info->constants.ppll_min)
+	info->constants.ppll_min = 12500;
+    if (!info->constants.ppll_max)
+	info->constants.ppll_max = 25000;	/* 23000 on some cards? */
+
+    /* XXX TODO. Calculuate properly. */
+    if (!info->constants.ref_divider)
+	info->constants.ref_divider = 0x3b;
+    aty_st_pll(PPLL_REF_DIV, info->constants.ref_divider);
+    aty_pll_writeupdate(info);
+
+    info->constants.xclk = 0x1d4d;
+    aty_st_pll(X_MPLL_REF_FB_DIV, 0x004c4c1e);
+    aty_pll_writeupdate(info);
+ 
+#endif
+
+    info->constants.fifo_width = 128;
+    info->constants.fifo_depth = 32;
+
+    switch (aty_ld_le32(MEM_CNTL) & 0x3) {
+    case 0:
+	info->mem = &sdr_128;
+	break;
+    case 1:
+	info->mem = &sdr_sgram;
+	break;
+    case 2:
+	info->mem = &ddr_sgram;
+	break;
+    default:
+	info->mem = &sdr_sgram;
+    }
+}
+
+
+static int
+aty128fbcon_switch(int con, struct fb_info *fb)
+{
+    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+    struct aty128fb_par par;
+
+    /* Do we have to save the colormap? */
+    if (fb_display[currcon].cmap.len)
+    	fb_get_cmap(&fb_display[currcon].cmap, 1, aty128_getcolreg, fb);
+
+    /* set the current console */
+    currcon = con;
+
+    aty128_decode_var(&fb_display[con].var, &par, info);
+    aty128_set_par(&par, info);
+
+    aty128_set_disp(&fb_display[con], info, par.crtc.bpp,
+        par.accel_flags & FB_ACCELF_TEXT);
+
+    do_install_cmap(con, fb);
+
+    return 1;
+}
+
+
+    /*
+     *  Blank the display.
+     */
+static void
+aty128fbcon_blank(int blank, struct fb_info *fb)
+{
+    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+    u8 state = 0;
+
+    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);
+}
+
+
+    /*
+     *  Read a single color register and split it into
+     *  colors/transparent. Return != 0 for invalid regno.
+     */
+static int
+aty128_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
+                         u_int *transp, struct fb_info *fb)
+{
+    struct fb_info_aty128 *info = (struct fb_info_aty128 *) fb;
+
+    if (regno > 255)
+	return 1;
+
+    *red = (info->palette[regno].red<<8) | info->palette[regno].red;
+    *green = (info->palette[regno].green<<8) | info->palette[regno].green;
+    *blue = (info->palette[regno].blue<<8) | info->palette[regno].blue;
+    *transp = 0;
+
+    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
+aty128_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
+                         u_int transp, struct fb_info *fb)
+{
+    struct fb_info_aty128 *info = (struct fb_info_aty128 *)fb;
+    u32 col;
+
+    if (regno > 255)
+	return 1;
+
+    red >>= 8;
+    green >>= 8;
+    blue >>= 8;
+    info->palette[regno].red = red;
+    info->palette[regno].green = green;
+    info->palette[regno].blue = blue;
+    	
+    /* Note: For now, on M3, we set palette on both heads, which may
+     * be useless. Can someone with a M3 check this ? */    	
+    	
+    /* initialize gamma ramp for hi-color+ */
+
+    if ((info->current_par.crtc.bpp > 8) && (regno == 0)) {
+        int i;
+
+        if (info->chip_gen == rage_M3)
+            aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~PALETTE_ACCESS_CNTL);
+
+        for (i=16; i<256; i++) {
+            aty_st_8(PALETTE_INDEX, i);
+            col = (i << 16) | (i << 8) | i;
+            aty_st_le32(PALETTE_DATA, col);
+        }
+
+        if (info->chip_gen == rage_M3) {
+            aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | PALETTE_ACCESS_CNTL);
+
+            for (i=16; i<256; i++) {
+                aty_st_8(PALETTE_INDEX, i);
+                col = (i << 16) | (i << 8) | i;
+                aty_st_le32(PALETTE_DATA, col);
+            }
+        }
+    }
+
+    /* initialize palette */
+
+    if (info->chip_gen == rage_M3)
+        aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) & ~PALETTE_ACCESS_CNTL);
+
+    if (info->current_par.crtc.bpp == 16)
+        aty_st_8(PALETTE_INDEX, (regno << 3));
+    else
+        aty_st_8(PALETTE_INDEX, regno);
+    col = (red << 16) | (green << 8) | blue;
+    aty_st_le32(PALETTE_DATA, col);
+    if (info->chip_gen == rage_M3) {
+    	aty_st_le32(DAC_CNTL, aty_ld_le32(DAC_CNTL) | PALETTE_ACCESS_CNTL);
+        if (info->current_par.crtc.bpp == 16)
+            aty_st_8(PALETTE_INDEX, (regno << 3));
+        else
+            aty_st_8(PALETTE_INDEX, regno);
+        aty_st_le32(PALETTE_DATA, col);
+    }
+    
+    if (regno < 16)
+	switch (info->current_par.crtc.bpp) {
+#ifdef FBCON_HAS_CFB16
+	case 9 ... 16:
+	    info->fbcon_cmap.cfb16[regno] = (regno << 10) | (regno << 5) |
+                regno;
+	    break;
+#endif
+#ifdef FBCON_HAS_CFB24
+	case 17 ... 24:
+	    info->fbcon_cmap.cfb24[regno] = (regno << 16) | (regno << 8) |
+		regno;
+	    break;
+#endif
+#ifdef FBCON_HAS_CFB32
+	case 25 ... 32: {
+            u32 i;
+
+            i = (regno << 8) | regno;
+            info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+	    break;
+        }
+#endif
+	}
+    return 0;
+}
+
+
+static void
+do_install_cmap(int con, struct fb_info *info)
+{
+    if (con != currcon)
+	return;
+
+    if (fb_display[con].cmap.len)
+	fb_set_cmap(&fb_display[con].cmap, 1, aty128_setcolreg, info);
+    else {
+	int size = (fb_display[con].var.bits_per_pixel <= 8) ? 256 : 16;
+	fb_set_cmap(fb_default_cmap(size), 1, aty128_setcolreg, info);
+    }
+}
+
+
+    /*
+     *  Accelerated functions
+     */
+
+static void
+aty128_rectcopy(int srcx, int srcy, int dstx, int dsty,
+		u_int width, u_int height,
+		struct fb_info_aty128 *info)
+{
+    u32 save_dp_datatype, save_dp_cntl;
+
+    wait_for_fifo(1, info);
+    aty_st_le32(CLR_CMP_CNTL, 0);
+    
+    wait_for_fifo(2, info);
+    save_dp_datatype = aty_ld_le32(DP_DATATYPE);
+    save_dp_cntl     = aty_ld_le32(DP_CNTL);
+
+    wait_for_fifo(6, info);
+    aty_st_le32(DP_DATATYPE, (BRUSH_SOLIDCOLOR << 16) | SRC_DSTCOLOR);
+    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(SRC_Y_X, (srcy << 16) | srcx);
+    aty_st_le32(DST_Y_X, (dsty << 16) | dstx);
+    aty_st_le32(DST_HEIGHT_WIDTH, (height << 16) | width);
+
+    info->blitter_may_be_busy = 1;
+
+    wait_for_fifo(2, info);
+    aty_st_le32(DP_DATATYPE, save_dp_datatype);
+    aty_st_le32(DP_CNTL, save_dp_cntl); 
+
+    wait_for_idle(info);
+}
+
+
+    /*
+     * 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);
+}
+
+
+#ifdef FBCON_HAS_CFB8
+static void fbcon_aty8_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb8_putc(conp, p, c, yy, xx);
+}
+
+
+static void fbcon_aty8_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb8_putcs(conp, p, s, count, yy, xx);
+}
+
+
+static void fbcon_aty8_clear_margins(struct vc_data *conp,
+                                     struct display *p, int bottom_only)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb8_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_aty128_8 = {
+    fbcon_cfb8_setup, fbcon_aty128_bmove, fbcon_cfb8_clear,
+    fbcon_aty8_putc, fbcon_aty8_putcs, fbcon_cfb8_revc, NULL, NULL,
+    fbcon_aty8_clear_margins,
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB16
+static void fbcon_aty16_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb16_putc(conp, p, c, yy, xx);
+}
+
+
+static void fbcon_aty16_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb16_putcs(conp, p, s, count, yy, xx);
+}
+
+
+static void fbcon_aty16_clear_margins(struct vc_data *conp,
+                                     struct display *p, int bottom_only)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb16_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_aty128_16 = {
+    fbcon_cfb16_setup, fbcon_aty128_bmove, fbcon_cfb16_clear,
+    fbcon_aty16_putc, fbcon_aty16_putcs, fbcon_cfb16_revc, NULL, NULL,
+    fbcon_aty16_clear_margins,
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB24
+static void fbcon_aty24_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb24_putc(conp, p, c, yy, xx);
+}
+
+
+static void fbcon_aty24_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb24_putcs(conp, p, s, count, yy, xx);
+}
+
+
+static void fbcon_aty24_clear_margins(struct vc_data *conp,
+                                     struct display *p, int bottom_only)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb24_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_aty128_24 = {
+    fbcon_cfb24_setup, fbcon_aty128_bmove, fbcon_cfb24_clear,
+    fbcon_aty24_putc, fbcon_aty24_putcs, fbcon_cfb24_revc, NULL, NULL,
+    fbcon_aty24_clear_margins,
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+#ifdef FBCON_HAS_CFB32
+static void fbcon_aty32_putc(struct vc_data *conp, struct display *p,
+                            int c, int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb32_putc(conp, p, c, yy, xx);
+}
+
+
+static void fbcon_aty32_putcs(struct vc_data *conp, struct display *p,
+                             const unsigned short *s, int count,
+                             int yy, int xx)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb32_putcs(conp, p, s, count, yy, xx);
+}
+
+
+static void fbcon_aty32_clear_margins(struct vc_data *conp,
+                                     struct display *p, int bottom_only)
+{
+    struct fb_info_aty128 *fb = (struct fb_info_aty128 *)(p->fb_info);
+
+    if (fb->blitter_may_be_busy)
+        wait_for_idle(fb);
+
+    fbcon_cfb32_clear_margins(conp, p, bottom_only);
+}
+
+static struct display_switch fbcon_aty128_32 = {
+    fbcon_cfb32_setup, fbcon_aty128_bmove, fbcon_cfb32_clear,
+    fbcon_aty32_putc, fbcon_aty32_putcs, fbcon_cfb32_revc, NULL, NULL,
+    fbcon_aty32_clear_margins,
+    FONTWIDTH(4)|FONTWIDTH(8)|FONTWIDTH(12)|FONTWIDTH(16)
+};
+#endif
+
+#ifdef MODULE
+MODULE_AUTHOR("(c)1999-2000 Brad Douglas <brad@neruo.com>");
+MODULE_DESCRIPTION("FBDev driver for ATI Rage128 / Pro cards");
+
+int __init
+init_module(void)
+{
+    aty128fb_init();
+    return 0;
+}
+
+void __exit
+cleanup_module(void)
+{
+    struct fb_info_aty128 *info = board_list;
+
+    while (board_list) {
+        info = board_list;
+        board_list = board_list->next;
+
+        unregister_framebuffer(&info->fb_info);
+#ifdef CONFIG_MTRR
+        if (info->mtrr.vram_valid)
+            mtrr_del(info->mtrr.vram, info->frame_buffer_phys,
+                     info->vram_size);
+#endif /* CONFIG_MTRR */
+        iounmap (tmp->regbase);
+        iounmap (tmp->frame_buffer);
+        kfree (tmp);
+    }
+}
+#endif /* MODULE */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/atyfb.c linux.17p18/drivers/video/atyfb.c
--- linux.vanilla/drivers/video/atyfb.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/drivers/video/atyfb.c	Fri Aug  4 15:28:41 2000
@@ -1,4 +1,4 @@
-/*  $Id: atyfb.c,v 1.106.2.8 2000/04/28 04:40:09 davem Exp $
+/*  $Id: atyfb.c,v 1.106.2.9 2000/06/23 12:06:38 davem Exp $
  *  linux/drivers/video/atyfb.c -- Frame buffer device for ATI Mach64
  *
  *	Copyright (C) 1997-1998  Geert Uytterhoeven
@@ -20,6 +20,8 @@
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License. See the file COPYING in the main directory of this archive for
  *  more details.
+ *
+ *  Many thanks to Nitya from ATI devrel for support and patience !
  */
 
 /******************************************************************************
@@ -87,7 +89,7 @@
 /*
  * Debug flags.
  */
-#undef DEBUG
+#define DEBUG
 
 #define GUI_RESERVE	0x00001000
 
@@ -419,7 +421,7 @@
 static int default_mclk __initdata = 0;
 
 #if defined(CONFIG_PPC)
-static int default_vmode __initdata = VMODE_NVRAM;
+static int default_vmode __initdata = VMODE_CHOOSE;
 static int default_cmode __initdata = CMODE_NVRAM;
 #endif
 
@@ -452,7 +454,7 @@
     /* mach64CT family / mach64GT (3D RAGE) class */
     { 0x4c42, 0x4c42, "3D RAGE LT PRO (AGP)" },
     { 0x4c44, 0x4c44, "3D RAGE LT PRO" },
-    { 0x4c47, 0x4c47, "3D RAGE LT PRO" },
+    { 0x4c47, 0x4c47, "3D RAGE LT-G" },
     { 0x4c49, 0x4c49, "3D RAGE LT PRO" },
     { 0x4c50, 0x4c50, "3D RAGE LT PRO" },
     { 0x4c54, 0x4c54, "3D RAGE LT" },
@@ -466,6 +468,8 @@
     { 0x4749, 0x4749, "3D RAGE PRO (BGA, PCI)" },
     { 0x4750, 0x4750, "3D RAGE PRO (PQFP, PCI)" },
     { 0x4751, 0x4751, "3D RAGE PRO (PQFP, PCI, limited 3D)" },
+    { 0x4c4d, 0x4c4d, "3D RAGE Mobility (PCI)" },
+    { 0x4c4e, 0x4c4e, "3D RAGE Mobility (AGP)" },
 };
 
 static const char *aty_gx_ram[8] __initdata = {
@@ -477,15 +481,19 @@
 };
 
 
-static inline u32 aty_ld_le32(volatile unsigned int regindex,
+static inline u32 aty_ld_le32(volatile int regindex,
 			      const struct fb_info_aty *info)
 {
     unsigned long temp;
     u32 val;
 
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
 #if defined(__powerpc__)
     temp = info->ati_regbase;
-    asm("lwbrx %0,%1,%2" : "=r"(val) : "b" (regindex), "r" (temp));
+     __asm__ __volatile__("lwbrx %0,%1,%2;eieio" : "=r"(val) : "b" (regindex), "r" (temp));
 #elif defined(__sparc_v9__)
     temp = info->ati_regbase + regindex;
     asm("lduwa [%1] %2, %0" : "=r" (val) : "r" (temp), "i" (ASI_PL));
@@ -496,14 +504,18 @@
     return val;
 }
 
-static inline void aty_st_le32(volatile unsigned int regindex, u32 val,
+static inline void aty_st_le32(volatile int regindex, u32 val,
 			       const struct fb_info_aty *info)
 {
     unsigned long temp;
 
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
 #if defined(__powerpc__)
     temp = info->ati_regbase;
-    asm("stwbrx %0,%1,%2" : : "r" (val), "b" (regindex), "r" (temp) :
+     __asm__ __volatile__("stwbrx %0,%1,%2;eieio" : : "r" (val), "b" (regindex), "r" (temp) :
 	"memory");
 #elif defined(__sparc_v9__)
     temp = info->ati_regbase + regindex;
@@ -514,18 +526,56 @@
 #endif
 }
 
-static inline u8 aty_ld_8(volatile unsigned int regindex,
+static inline u8 aty_ld_8(volatile int regindex,
 			  const struct fb_info_aty *info)
 {
-    return *(volatile u8 *)(info->ati_regbase+regindex);
+    u8 val;
+
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
+    val = *(volatile u8 *)(info->ati_regbase+regindex);
+#if defined(__powerpc__)
+    eieio();
+#endif
+    return val;
 }
 
-static inline void aty_st_8(volatile unsigned int regindex, u8 val,
+static inline void aty_st_8(volatile int regindex, u8 val,
 			    const struct fb_info_aty *info)
 {
+    /* Hack for bloc 1, should be cleanly optimized by compiler */
+    if (regindex >= 0x400)
+    	regindex -= 0x800;
+
     *(volatile u8 *)(info->ati_regbase+regindex) = val;
+#if defined(__powerpc__)
+    eieio();
+#endif
+}
+
+static void aty_st_lcd(int index, u32 val, const struct fb_info_aty *info)
+{
+    unsigned long temp;
+    
+    /* write addr byte */
+    temp = aty_ld_le32(LCD_INDEX, info);
+    aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
+    /* write the register value */
+    aty_st_le32(LCD_DATA, val, info);
 }
 
+static u32 aty_ld_lcd(int index, const struct fb_info_aty *info)
+{
+    unsigned long temp;
+    
+    /* write addr byte */
+    temp = aty_ld_le32(LCD_INDEX, info);
+    aty_st_le32(LCD_INDEX, (temp & ~LCD_INDEX_MASK) | index, info);
+    /* read the register value */
+    return aty_ld_le32(LCD_DATA, info);
+}
 
     /*
      *  Generic Mach64 routines
@@ -566,6 +616,16 @@
 			  BUS_FIFO_ERR_ACK, info);
 }
 
+static void reset_GTC_3D_engine(const struct fb_info_aty *info)
+{
+	aty_st_le32(SCALE_3D_CNTL, 0xc0, info);
+	mdelay(GTC_3D_RESET_DELAY);
+	aty_st_le32(SETUP_CNTL, 0x00, info);
+	mdelay(GTC_3D_RESET_DELAY);
+	aty_st_le32(SCALE_3D_CNTL, 0x00, info);
+	mdelay(GTC_3D_RESET_DELAY);
+}
+
 static void init_engine(const struct atyfb_par *par, struct fb_info_aty *info)
 {
     u32 pitch_value;
@@ -579,8 +639,16 @@
 	pitch_value = pitch_value * 3;
     }
 
+    /* On GTC (RagePro), we need to reset the 3D engine first */
+    if (Gx == LB_CHIP_ID || Gx == LD_CHIP_ID || Gx == LI_CHIP_ID ||
+    	Gx == LP_CHIP_ID || Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
+    	Gx == GI_CHIP_ID || Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID ||
+    	Gx == LM_CHIP_ID || Gx == LN_CHIP_ID)
+    	reset_GTC_3D_engine(info);
+
     /* Reset engine, enable, and clear any engine errors */
     reset_engine(info);
+
     /* Ensure that vga page pointers are set to zero - the upper */
     /* page pointers are set to 1 to handle overflows in the */
     /* lower page */
@@ -683,9 +751,7 @@
     aty_st_8(DAC_W_INDEX, offset & 0xff, info);
     /* left addr byte */
     aty_st_8(DAC_DATA, (offset >> 8) & 0xff, info);
-    eieio();
     aty_st_8(DAC_MASK, val, info);
-    eieio();
     aty_st_8(DAC_CNTL, 0, info);
 }
 
@@ -693,10 +759,8 @@
 {
     /* write addr byte */
     aty_st_8(CLOCK_CNTL + 1, (offset << 2) | PLL_WR_EN, info);
-    eieio();
     /* write the register value */
     aty_st_8(CLOCK_CNTL + 2, val, info);
-    eieio();
     aty_st_8(CLOCK_CNTL + 1, (offset << 2) & ~PLL_WR_EN, info);
 }
 
@@ -706,10 +770,8 @@
 
     /* write addr byte */
     aty_st_8(CLOCK_CNTL + 1, (offset << 2), info);
-    eieio();
     /* read the register value */
     res = aty_ld_8(CLOCK_CNTL + 2, info);
-    eieio();
     return res;
 }
 
@@ -1772,6 +1834,9 @@
 	} else if ((Gx == VT_CHIP_ID) || (Gx == VU_CHIP_ID)) {
 	    aty_st_le32(DAC_CNTL, 0x87010184, info);
 	    aty_st_le32(BUS_CNTL, 0x680000f9, info);
+	} else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
+	    aty_st_le32(DAC_CNTL, 0x80010102, info);
+	    aty_st_le32(BUS_CNTL, 0x7b33a040, info);
 	} else {
 	    /* GT */
 	    aty_st_le32(DAC_CNTL, 0x86010102, info);
@@ -1788,7 +1853,7 @@
 	init_engine(par, info);
 
 #ifdef CONFIG_FB_COMPAT_XPMAC
-    if (console_fb_info == &info->fb_info) {
+    if (!console_fb_info || console_fb_info == &info->fb_info) {
 	struct fb_var_screeninfo var;
 	int vmode, cmode;
 	display_info.height = ((par->crtc.v_tot_disp>>16) & 0x7ff)+1;
@@ -2406,7 +2471,6 @@
 			tmp |= 0x2;
 		aty_st_8(DAC_CNTL, tmp, info);
 		aty_st_8(DAC_MASK, 0xff, info);
-		eieio();
 		scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
 			(info->current_par.crtc.bpp == 16)) ? 3 : 0;
 		info->aty_cmap_regs->rindex = i << scale;
@@ -2549,11 +2613,19 @@
 	    } else if (Gx == GB_CHIP_ID || Gx == GD_CHIP_ID ||
 		       Gx == GI_CHIP_ID || Gx == GP_CHIP_ID ||
 		       Gx == GQ_CHIP_ID || Gx == LB_CHIP_ID ||
-		       Gx == LD_CHIP_ID || Gx == LG_CHIP_ID ||
+		       Gx == LD_CHIP_ID ||
 		       Gx == LI_CHIP_ID || Gx == LP_CHIP_ID) {
 		/* RAGE PRO or LT PRO */
 		pll = 230;
 		mclk = 100;
+	    } else if (Gx == LG_CHIP_ID) {
+		/* Rage LT */
+		pll = 230;
+		mclk = 63;
+	    } else if ((Gx == LN_CHIP_ID) || (Gx == LM_CHIP_ID)) {
+	    	/* Rage mobility M1 */
+	    	pll = 230;
+	    	mclk = 50;
 	    } else {
 		/* other RAGE */
 		pll = 135;
@@ -2706,24 +2778,43 @@
 	}
 
 #if defined(CONFIG_PPC)
+    if (Gx == LI_CHIP_ID && machine_is_compatible("PowerBook1,1")) {
+	/* these bits let the 101 powerbook wake up from sleep -- paulus */
+	aty_st_lcd(LCD_POWER_MANAGEMENT, aty_ld_lcd(LCD_POWER_MANAGEMENT, info)
+		| (USE_F32KHZ | TRISTATE_MEM_EN), info);
+    }
+
     if (default_vmode == VMODE_NVRAM) {
+#if 0 /* This is not really supported */
 	default_vmode = nvram_read_byte(NV_VMODE);
 	if (default_vmode <= 0 || default_vmode > VMODE_MAX)
+#endif
 	    default_vmode = VMODE_CHOOSE;
     }
+    /*
+     * The default video mode is 1024x768 @ 75Hz, as that
+     * works on iMacs as well as the G3 powerbooks. - paulus
+     */
     if (default_vmode == VMODE_CHOOSE) {
 	if (Gx == LG_CHIP_ID)
 	    /* G3 PowerBook with 1024x768 LCD */
 	    default_vmode = VMODE_1024_768_60;
-	else {
-	    sense = read_aty_sense(info);
-	    default_vmode = mac_map_monitor_sense(sense);
-	}
+	else if (Gx == LN_CHIP_ID)
+	    /* iBook with 800x600 LCD */
+	    default_vmode = VMODE_800_600_60;
+	else
+	    default_vmode = VMODE_1024_768_75;
+	/* 'twould be nice to get this going - paulus */
+	sense = read_aty_sense(info);
+	printk(KERN_INFO "atyfb: monitor sense=%x, maps to mode %d\n",
+	       sense, mac_map_monitor_sense(sense));
     }
     if (default_vmode <= 0 || default_vmode > VMODE_MAX)
-	default_vmode = VMODE_640_480_60;
+	default_vmode = VMODE_1024_768_75;
+#if 0
     if (default_cmode == CMODE_NVRAM)
 	default_cmode = nvram_read_byte(NV_CMODE);
+#endif
     if (default_cmode < CMODE_8 || default_cmode > CMODE_32)
 	default_cmode = CMODE_8;
     if (mac_vmode_to_var(default_vmode, default_cmode, &var))
@@ -3476,11 +3567,10 @@
     if (Gx == GT_CHIP_ID || Gx == GU_CHIP_ID || Gx == GV_CHIP_ID ||
 	Gx == GW_CHIP_ID || Gx == GZ_CHIP_ID || Gx == LG_CHIP_ID ||
 	Gx == GB_CHIP_ID || Gx == GD_CHIP_ID || Gx == GI_CHIP_ID ||
-	Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID)
+	Gx == GP_CHIP_ID || Gx == GQ_CHIP_ID || Gx == LI_CHIP_ID)
 	i |= 0x2;	/*DAC_CNTL|0x2 turns off the extra brightness for gt*/
     aty_st_8(DAC_CNTL, i, info);
     aty_st_8(DAC_MASK, 0xff, info);
-    eieio();
     scale = ((Gx != GX_CHIP_ID) && (Gx != CX_CHIP_ID) &&
 	     (info->current_par.crtc.bpp == 16)) ? 3 : 0;
     info->aty_cmap_regs->windex = regno << scale;
@@ -3930,6 +4020,124 @@
 #endif
 
 #ifdef CONFIG_PMAC_PBOOK
+
+/* Power management routines. Those are used for PowerBook sleep.
+ *
+ * It appears that Rage LT and Rage LT Pro have different power
+ * management registers. There's is some confusion about which
+ * chipID is a Rage LT or LT pro :(
+ */
+static int
+aty_power_mgmt_LT(int sleep, struct fb_info_aty *info)
+{
+ 	unsigned int pm;
+	int timeout;
+	
+	pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+	pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
+	aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+	pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+	
+	timeout = 200000;
+	if (sleep) {
+		/* Sleep */
+		pm &= ~PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm &= ~(PWR_BLON | AUTO_PWR_UP);
+		pm |= SUSPEND_NOW;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		do {
+			pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+			udelay(10);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
+	} else {
+		/* Wakeup */
+		pm &= ~PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm |=  (PWR_BLON | AUTO_PWR_UP);
+		pm &= ~SUSPEND_NOW;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_le32(POWER_MANAGEMENT_LG, pm, info);
+		do {
+			pm = aty_ld_le32(POWER_MANAGEMENT_LG, info);
+			udelay(10);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != 0);
+	}
+	mdelay(500);
+
+	return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
+}
+
+static int
+aty_power_mgmt_LTPro(int sleep, struct fb_info_aty *info)
+{
+ 	unsigned int pm;
+	int timeout;
+	
+	pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+	pm = (pm & ~PWR_MGT_MODE_MASK) | PWR_MGT_MODE_REG;
+	aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+	pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+
+	timeout = 200;
+	if (sleep) {
+		/* Sleep */
+		pm &= ~PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm &= ~(PWR_BLON | AUTO_PWR_UP);
+		pm |= SUSPEND_NOW;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		do {
+			pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+			udelay(1000);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
+	} else {
+		/* Wakeup */
+		pm &= ~PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm &= ~SUSPEND_NOW;
+		pm |= (PWR_BLON | AUTO_PWR_UP);
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);
+		udelay(10);
+		pm |= PWR_MGT_ON;
+		aty_st_lcd(LCD_POWER_MANAGEMENT, pm, info);
+		do {
+			pm = aty_ld_lcd(LCD_POWER_MANAGEMENT, info);			
+			udelay(1000);
+			if ((--timeout) == 0)
+				break;
+		} while ((pm & PWR_MGT_STATUS_MASK) != 0);
+	}
+
+	return timeout ? PBOOK_SLEEP_OK : PBOOK_SLEEP_REFUSE;
+}
+
 /*
  * Save the contents of the frame buffer when we go to sleep,
  * and restore it when we wake up again.
@@ -3938,7 +4146,9 @@
 aty_sleep_notify(struct pmu_sleep_notifier *self, int when)
 {
 	struct fb_info_aty *info;
- 	unsigned int pm;
+ 	int result;
+
+	result = PBOOK_SLEEP_OK;
 
 	for (info = first_display; info != NULL; info = info->next) {
 		struct fb_fix_screeninfo fix;
@@ -3950,6 +4160,8 @@
 		switch (when) {
 		case PBOOK_SLEEP_REQUEST:
 			info->save_framebuffer = vmalloc(nb);
+			if (info->save_framebuffer == NULL)
+				return PBOOK_SLEEP_REFUSE;
 			break;
 		case PBOOK_SLEEP_REJECT:
 			if (info->save_framebuffer) {
@@ -3966,80 +4178,38 @@
 
 			/* Backup fb content */	
 			if (info->save_framebuffer)
-				memcpy(info->save_framebuffer,
+				memcpy_fromio(info->save_framebuffer,
 				       (void *)info->frame_buffer, nb);
 
 			/* Blank display and LCD */
 			atyfbcon_blank(VESA_POWERDOWN+1, (struct fb_info *)info);
 
-			/* Set chip to "suspend" mode. Note: There's a HW bug
-			   in the chip which prevents proper resync on wakeup
-			   with automatic power management, we handle suspend
-			   manually using the following (weird) sequence
-			   described by ATI.
-			   Note2:
-			   We could enable this for all Rage LT Pro chip ids */
-			if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID)
-			    || (Gx == LP_CHIP_ID)) {
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				pm &= ~PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm &= ~(PWR_BLON | AUTO_PWR_UP);
-				pm |= SUSPEND_NOW;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm |= PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				do {
-					pm = aty_ld_le32(POWER_MANAGEMENT, info);
-					/* Fix a problem with revision 4c50 of the chip */
-					if (Gx == LP_CHIP_ID)
-						break;
-				} while ((pm & PWR_MGT_STATUS_MASK) != PWR_MGT_STATUS_SUSPEND);
-				mdelay(500);
-			}
+			/* Set chip to "suspend" mode */
+			if (Gx == LG_CHIP_ID)
+				result = aty_power_mgmt_LT(1, info);
+			else
+				result = aty_power_mgmt_LTPro(1, info);
 			break;
 		case PBOOK_WAKE:
 			/* Wakeup chip */
-			if ((Gx == LG_CHIP_ID) || (Gx == LT_CHIP_ID) || (Gx == LP_CHIP_ID)) {
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				pm &= ~PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm |=  (PWR_BLON | AUTO_PWR_UP);
-				pm &= ~SUSPEND_NOW;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				pm = aty_ld_le32(POWER_MANAGEMENT, info);
-				mdelay(1);
-				pm |= PWR_MGT_ON;
-				aty_st_le32(POWER_MANAGEMENT, pm, info);
-				do {
-					pm = aty_ld_le32(POWER_MANAGEMENT, info);
-					/* Fix a problem with revision 4c50 of the chip */
-					if (Gx == LP_CHIP_ID)
-						break;
-				} while ((pm & PWR_MGT_STATUS_MASK) != 0);
-				mdelay(500);
-			}
+			if (Gx == LG_CHIP_ID)
+				result = aty_power_mgmt_LT(0, info);
+			else
+				result = aty_power_mgmt_LTPro(0, info);
 
 			/* Restore fb content */			
 			if (info->save_framebuffer) {
-				memcpy((void *)info->frame_buffer,
+				memcpy_toio((void *)info->frame_buffer,
 				       info->save_framebuffer, nb);
 				vfree(info->save_framebuffer);
 				info->save_framebuffer = 0;
 			}
-
-			/* Restore display */			
+			/* Restore display */
 			atyfb_set_par(&info->current_par, info);
 			atyfbcon_blank(0, (struct fb_info *)info);
 			break;
 		}
 	}
-	return PBOOK_SLEEP_OK;
+	return result;
 }
 #endif /* CONFIG_PMAC_PBOOK */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/chipsfb.c linux.17p18/drivers/video/chipsfb.c
--- linux.vanilla/drivers/video/chipsfb.c	Fri Apr 21 12:46:38 2000
+++ linux.17p18/drivers/video/chipsfb.c	Tue Aug  1 07:59:59 2000
@@ -728,6 +728,8 @@
 		switch (when) {
 		case PBOOK_SLEEP_REQUEST:
 			p->save_framebuffer = vmalloc(nb);
+			if (p->save_framebuffer == NULL)
+				return PBOOK_SLEEP_REFUSE;
 			break;
 		case PBOOK_SLEEP_REJECT:
 			if (p->save_framebuffer) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/controlfb.c linux.17p18/drivers/video/controlfb.c
--- linux.vanilla/drivers/video/controlfb.c	Fri Apr 21 12:46:38 2000
+++ linux.17p18/drivers/video/controlfb.c	Tue Aug  1 07:59:59 2000
@@ -531,18 +531,26 @@
 
 	p->sense = read_control_sense(p);
 	printk(KERN_INFO "Monitor sense value = 0x%x, ", p->sense);
+	
 	/* Try to pick a video mode out of NVRAM if we have one. */
-	par->vmode = nvram_read_byte(NV_VMODE);
-	if(par->vmode <= 0 || par->vmode > VMODE_MAX || !control_reg_init[par->vmode - 1])
-		par->vmode = VMODE_CHOOSE;
-	if(par->vmode == VMODE_CHOOSE)
-		par->vmode = mac_map_monitor_sense(p->sense);
-	if(!control_reg_init[par->vmode - 1])
-		par->vmode = VMODE_640_480_60;
+	if (default_vmode == VMODE_NVRAM) {
+		par->vmode = nvram_read_byte(NV_VMODE);
+		if(par->vmode <= 0 || par->vmode > VMODE_MAX || !control_reg_init[par->vmode - 1])
+			par->vmode = VMODE_CHOOSE;
+		if(par->vmode == VMODE_CHOOSE)
+			par->vmode = mac_map_monitor_sense(p->sense);
+		if(!control_reg_init[par->vmode - 1])
+			par->vmode = VMODE_640_480_60;
+	} else
+		par->vmode=default_vmode;
+
+	if (default_cmode == CMODE_NVRAM){
+		par->cmode = nvram_read_byte(NV_CMODE);
+		if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
+			par->cmode = CMODE_8;}
+	else
+		par->cmode=default_cmode;
 
-	par->cmode = nvram_read_byte(NV_CMODE);
-	if(par->cmode < CMODE_8 || par->cmode > CMODE_32)
-		par->cmode = CMODE_8;
 	/*
 	 * Reduce the pixel size if we don't have enough VRAM.
 	 */
@@ -780,14 +788,10 @@
      *  bitfields, horizontal timing, vertical timing.
      */
 	/* swiped by jonh from atyfb.c */
-	if (xres <= 512 && yres <= 384)
-		par->vmode = VMODE_512_384_60;		/* 512x384, 60Hz */
-	else if (xres <= 640 && yres <= 480)
+	if (xres <= 640 && yres <= 480)
 		par->vmode = VMODE_640_480_67;		/* 640x480, 67Hz */
 	else if (xres <= 640 && yres <= 870)
 		par->vmode = VMODE_640_870_75P;		/* 640x870, 75Hz (portrait) */
-	else if (xres <= 768 && yres <= 576)
-		par->vmode = VMODE_768_576_50I;		/* 768x576, 50Hz (PAL full frame) */
 	else if (xres <= 800 && yres <= 600)
 		par->vmode = VMODE_800_600_75;		/* 800x600, 75Hz */
 	else if (xres <= 832 && yres <= 624)
@@ -1176,8 +1180,8 @@
 		}
 		if (!strncmp(this_opt, "vmode:", 6)) {
 			int vmode = simple_strtoul(this_opt+6, NULL, 0);
-		if (vmode > 0 && vmode <= VMODE_MAX)
-			default_vmode = vmode;
+			if (vmode > 0 && vmode <= VMODE_MAX)
+				default_vmode = vmode;
 		} else if (!strncmp(this_opt, "cmode:", 6)) {
 			int depth = simple_strtoul(this_opt+6, NULL, 0);
 			switch (depth) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/fbcon.c linux.17p18/drivers/video/fbcon.c
--- linux.vanilla/drivers/video/fbcon.c	Fri Apr 21 12:46:38 2000
+++ linux.17p18/drivers/video/fbcon.c	Tue Aug  1 07:59:59 2000
@@ -526,7 +526,7 @@
     	q = (unsigned short *)(conp->vc_origin + conp->vc_size_row * old_rows);
     	step = logo_lines * old_cols;
     	for (r = q - logo_lines * old_cols; r < q; r++)
-    	    if (*r != conp->vc_video_erase_char)
+    	    if (scr_readw(r) != conp->vc_video_erase_char)
     	    	break;
 	if (r != q && nr_rows >= old_rows + logo_lines) {
     	    save = kmalloc(logo_lines * nr_cols * 2, GFP_KERNEL);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/fbmem.c linux.17p18/drivers/video/fbmem.c
--- linux.vanilla/drivers/video/fbmem.c	Fri Apr 21 12:46:39 2000
+++ linux.17p18/drivers/video/fbmem.c	Tue Aug  1 07:59:59 2000
@@ -68,6 +68,8 @@
 extern void offb_setup(char *options, int *ints);
 extern void atyfb_init(void);
 extern void atyfb_setup(char *options, int *ints);
+extern void aty128fb_init(void);
+extern void aty128fb_setup(char *options, int *ints);
 extern void igafb_init(void);
 extern void igafb_setup(char *options, int *ints);
 extern void imsttfb_init(void);
@@ -92,6 +94,8 @@
 extern void sbusfb_setup(char *options, int *ints);
 extern void valkyriefb_init(void);
 extern void valkyriefb_setup(char *options, int *ints);
+extern void control_init(void);
+extern void control_setup(char *options, int *ints);
 extern void g364fb_init(void);
 extern void fm2fb_init(void);
 extern void fm2fb_setup(char *options, int *ints);
@@ -143,6 +147,9 @@
 #ifdef CONFIG_FB_ATY
 	{ "atyfb", atyfb_init, atyfb_setup },
 #endif
+#ifdef CONFIG_FB_ATY128
+	{ "aty128fb", aty128fb_init, aty128fb_setup },
+#endif
 #ifdef CONFIG_FB_IGA
         { "igafb", igafb_init, igafb_setup },
 #endif
@@ -179,6 +186,9 @@
 #ifdef CONFIG_FB_VALKYRIE
 	{ "valkyriefb", valkyriefb_init, valkyriefb_setup },
 #endif
+#ifdef CONFIG_FB_CONTROL
+	{ "controlfb", control_init, control_setup },
+#endif
 #ifdef CONFIG_FB_G364
 	{ "g364", g364fb_init, NULL },
 #endif
@@ -260,19 +270,27 @@
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
-	char *base_addr;
-	ssize_t copy_size;
 
 	if (! fb || ! info->disp)
 		return -ENODEV;
 
 	fb->fb_get_fix(&fix,PROC_CONSOLE(info), info);
-	base_addr=info->disp->screen_base;
-	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
-	if (copy_to_user(buf, base_addr+p, copy_size))
-	    return -EFAULT;
-	*ppos += copy_size;
-	return copy_size;
+	if (p >= fix.smem_len)
+	    return 0;
+	if (count >= fix.smem_len)
+	    count = fix.smem_len;
+	if (count + p > fix.smem_len)
+		count = fix.smem_len - p;
+	if (count) {
+	    char *base_addr;
+
+	    base_addr = info->disp->screen_base;
+	    count -= copy_to_user(buf, base_addr+p, count);
+	    if (!count)
+		return -EFAULT;
+	    *ppos += count;
+	}
+	return count;
 }
 
 static ssize_t
@@ -284,19 +302,32 @@
 	struct fb_info *info = registered_fb[fbidx];
 	struct fb_ops *fb = info->fbops;
 	struct fb_fix_screeninfo fix;
-	char *base_addr;
-	ssize_t copy_size;
+	int err;
 
 	if (! fb || ! info->disp)
 		return -ENODEV;
 
 	fb->fb_get_fix(&fix, PROC_CONSOLE(info), info);
-	base_addr=info->disp->screen_base;
-	copy_size=(count + p <= fix.smem_len ? count : fix.smem_len - p);
-	if (copy_from_user(base_addr+p, buf, copy_size))
-	    return -EFAULT;
-	file->f_pos += copy_size;
-	return copy_size;
+	if (p > fix.smem_len)
+	    return -ENOSPC;
+	if (count >= fix.smem_len)
+	    count = fix.smem_len;
+	err = 0;
+	if (count + p > fix.smem_len) {
+	    count = fix.smem_len - p;
+	    err = -ENOSPC;
+	}
+	if (count) {
+	    char *base_addr;
+
+	    base_addr = info->disp->screen_base;
+	    count -= copy_from_user(base_addr+p, buf, count);
+	    *ppos += count;
+	    err = -EFAULT;
+	}
+	if (count)
+		return count;
+	return err;
 }
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/igafb.c linux.17p18/drivers/video/igafb.c
--- linux.vanilla/drivers/video/igafb.c	Fri Apr 21 12:46:39 2000
+++ linux.17p18/drivers/video/igafb.c	Tue Aug  1 08:13:46 2000
@@ -367,7 +367,7 @@
 	pci_outb(info, green, DAC_DATA);
 	pci_outb(info, blue,  DAC_DATA);
 
-	if (regno << 16)
+	if (regno < 16) {
 		switch (default_var.bits_per_pixel) {
 #ifdef FBCON_HAS_CFB16
 		case 16:
@@ -383,11 +383,14 @@
 #endif
 #ifdef FBCON_HAS_CFB32
 		case 32:
+			{ int i;
 			i = (regno << 8) | regno;
 			info->fbcon_cmap.cfb32[regno] = (i << 16) | i;
+			}
 			break;
 #endif
 		}
+	}
 	return 0;
 }
 
@@ -508,19 +511,19 @@
         case 15:
         case 16:
                 sw = &fbcon_cfb16;
-		display->dispsw_data = fbcon_cmap.cfb16;
+		display->dispsw_data = info->fbcon_cmap.cfb16;
                 break;
 #endif
 #ifdef FBCON_HAS_CFB24
 	case 24:
 		sw = &fbcon_cfb24;
-		display->dispsw_data = fbcon_cmap.cfb24;
+		display->dispsw_data = info->fbcon_cmap.cfb24;
 		break;
 #endif
 #ifdef FBCON_HAS_CFB32
         case 32:
                 sw = &fbcon_cfb32;
-		display->dispsw_data = fbcon_cmap.cfb32;
+		display->dispsw_data = info->fbcon_cmap.cfb32;
                 break;
 #endif
         default:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/macmodes.c linux.17p18/drivers/video/macmodes.c
--- linux.vanilla/drivers/video/macmodes.c	Fri Apr 21 12:46:39 2000
+++ linux.17p18/drivers/video/macmodes.c	Tue Aug  1 07:59:59 2000
@@ -367,8 +367,10 @@
 	    continue;
 	if (var->pixclock > mode->pixclock)
 	    continue;
+#if 0
 	if ((var->vmode & FB_VMODE_MASK) != mode->vmode)
 	    continue;
+#endif
 	*vmode = mode->number;
 	return 0;
     }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/matroxfb.c linux.17p18/drivers/video/matroxfb.c
--- linux.vanilla/drivers/video/matroxfb.c	Fri Apr 21 12:46:39 2000
+++ linux.17p18/drivers/video/matroxfb.c	Tue Aug  1 07:59:59 2000
@@ -4693,7 +4693,12 @@
 	}
 	display->var = *var;
 	/* cmap */
+#ifdef __alpha__
+	display->screen_base = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg
+		+ dense_mem(vaddr_va(ACCESS_FBINFO(video.vbase)));
+#else
 	display->screen_base = vaddr_va(ACCESS_FBINFO(video.vbase)) + ydstorg;
+#endif
 	display->visual = visual;
 	display->ypanstep = 1;
 	display->ywrapstep = 0;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/offb.c linux.17p18/drivers/video/offb.c
--- linux.vanilla/drivers/video/offb.c	Fri Apr 21 12:46:39 2000
+++ linux.17p18/drivers/video/offb.c	Tue Aug  1 07:59:59 2000
@@ -42,6 +42,15 @@
 
 static int currcon = 0;
 
+/* Supported palette hacks */
+enum {
+	cmap_unknown,
+	cmap_m64,	/* ATI Mach64 */
+	cmap_r128,	/* ATI Rage128 */
+	cmap_M3A,	/* ATI Rage Mobility M3 Head A */
+	cmap_M3B	/* ATI Rage Mobility M3 Head B */
+};
+
 struct fb_info_offb {
     struct fb_info info;
     struct fb_fix_screeninfo fix;
@@ -50,6 +59,7 @@
     struct { u_char red, green, blue, pad; } palette[256];
     volatile unsigned char *cmap_adr;
     volatile unsigned char *cmap_data;
+    int cmap_type;
     union {
 #ifdef FBCON_HAS_CFB16
 	u16 cfb16[16];
@@ -106,7 +116,8 @@
 static int offb_init_driver(struct device_node *);
 static void offb_init_nodriver(struct device_node *);
 static void offb_init_fb(const char *name, const char *full_name, int width,
-		      int height, int depth, int pitch, unsigned long address);
+		      int height, int depth, int pitch, unsigned long address,
+		      struct device_node *dp);
 
     /*
      *  Interface to the low level console driver
@@ -293,6 +304,9 @@
 #ifdef CONFIG_FB_ATY
 extern void atyfb_of_init(struct device_node *dp);
 #endif /* CONFIG_FB_ATY */
+#if defined(CONFIG_FB_ATY128)
+extern void aty128fb_of_init(struct device_node *dp);
+#endif /* CONFIG_FB_ATY128 */
 #ifdef CONFIG_FB_S3TRIO
 extern void s3triofb_init_of(struct device_node *dp);
 #endif /* CONFIG_FB_S3TRIO */
@@ -362,6 +376,20 @@
 	    }
 
 	    /*
+	     * The M3 on the Pismo powerbook has no addresses
+	     * on the display nodes, they are on their parent.
+	     */
+	    if (dp->n_addrs == 0 && device_is_compatible(dp, "ATY,RageM3p")) {
+		int na;
+		unsigned int *ap = (unsigned int *)
+		    get_property(dp, "AAPL,address", &na);
+		if (ap != 0)
+		    for (na /= sizeof(unsigned int); na > 0; --na, ++ap)
+			if (*ap <= addr && addr < *ap + 0x1000000)
+			    goto foundit;
+	    }
+
+	    /*
 	     * See if the display address is in one of the address
 	     * ranges for this display.
 	     */
@@ -386,7 +414,7 @@
 			 boot_infos->dispDeviceRect[2],
 			 boot_infos->dispDeviceRect[3],
 			 boot_infos->dispDeviceDepth,
-			 boot_infos->dispDeviceRowBytes, addr);
+			 boot_infos->dispDeviceRowBytes, addr, 0);
 	}
     }
 
@@ -409,6 +437,15 @@
 
 __initfunc(static int offb_init_driver(struct device_node *dp))
 {
+#ifdef CONFIG_FB_ATY128
+    if (!strncmp(dp->name, "ATY,Rage128", 11) ||
+    	!strncmp(dp->name, "ATY,RageM3pA", 12)) {
+	aty128fb_of_init(dp);
+	return 1;
+    }
+    if (!strncmp(dp->name, "ATY,RageM3pB", 12))
+    	return 0;
+#endif /* CONFIG_FB_ATY128*/
 #ifdef CONFIG_FB_ATY
     if (!strncmp(dp->name, "ATY", 3)) {
 	atyfb_of_init(dp);
@@ -477,9 +514,11 @@
 	&& len == sizeof(int))
 	height = *pp;
     if ((pp = (int *)get_property(dp, "linebytes", &len)) != NULL
-	&& len == sizeof(int))
+	&& len == sizeof(int)) {
 	pitch = *pp;
-    else
+	if (pitch == 1)
+	    pitch = 0x1000;
+    } else
 	pitch = width;
     if ((up = (unsigned *)get_property(dp, "address", &len)) != NULL
 	&& len == sizeof(unsigned))
@@ -500,13 +539,14 @@
 	    address += 0x1000;
     }
     offb_init_fb(dp->name, dp->full_name, width, height, depth,
-		 pitch, address);
+		 pitch, address, dp);
     
 }
 
 __initfunc(static void offb_init_fb(const char *name, const char *full_name,
 				    int width, int height, int depth,
-				    int pitch, unsigned long address))
+				    int pitch, unsigned long address,
+				    struct device_node *dp))
 {
     int i;
     struct fb_fix_screeninfo *fix;
@@ -543,13 +583,27 @@
     fix->type = FB_TYPE_PACKED_PIXELS;
     fix->type_aux = 0;
 
+    info->cmap_type = cmap_unknown;
     if (depth == 8)
     {
     	/* XXX kludge for ati */
-    	if (strncmp(name, "ATY,", 4) == 0) {
+	if (dp && !strncmp(name, "ATY,Rage128", 11)) {
+		unsigned long regbase = dp->addrs[2].address;
+		info->cmap_adr = ioremap(regbase, 0x1FFF);
+		info->cmap_type = cmap_r128;
+	} else if (dp && !strncmp(name, "ATY,RageM3pA", 12)) {
+		unsigned long regbase = dp->parent->addrs[2].address;
+		info->cmap_adr = ioremap(regbase, 0x1FFF);
+		info->cmap_type = cmap_M3A;
+	} else if (dp && !strncmp(name, "ATY,RageM3pB", 12)) {
+		unsigned long regbase = dp->parent->addrs[2].address;
+		info->cmap_adr = ioremap(regbase, 0x1FFF);
+		info->cmap_type = cmap_M3B;
+	} else if (!strncmp(name, "ATY,", 4)) {
 		unsigned long base = address & 0xff000000UL;
 		info->cmap_adr = ioremap(base + 0x7ff000, 0x1000) + 0xcc0;
 		info->cmap_data = info->cmap_adr + 1;
+		info->cmap_type = cmap_m64;
 	}
         fix->visual = info->cmap_adr ? FB_VISUAL_PSEUDOCOLOR
 				     : FB_VISUAL_STATIC_PSEUDOCOLOR;
@@ -706,7 +760,7 @@
 	display_info.cmap_data_address = 0;
 	display_info.disp_reg_address = 0;
 	/* XXX kludge for ati */
-	if (strncmp(name, "ATY,", 4) == 0) {
+	if (info->cmap_type == cmap_m64) {
 	    unsigned long base = address & 0xff000000UL;
 	    display_info.disp_reg_address = base + 0x7ffc00;
 	    display_info.cmap_adr_address = base + 0x7ffcc0;
@@ -767,12 +821,33 @@
 	return;
 
     if (blank)
-	for (i = 0; i < 256; i++) {
-	    *info2->cmap_adr = i;
-	    mach_eieio();
-	    for (j = 0; j < 3; j++) {
-		*info2->cmap_data = 0;
-		mach_eieio();
+        for (i = 0; i < 256; i++) {
+	    switch(info2->cmap_type) {
+	    case cmap_m64:
+	        *info2->cmap_adr = i;
+	  	mach_eieio();
+	  	for (j = 0; j < 3; j++) {
+		    *info2->cmap_data = 0;
+		    mach_eieio();
+	    	}
+	    	break;
+	    case cmap_M3A:
+	        /* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+	    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+	    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+	    case cmap_r128:
+	    	/* Set palette index & data */
+    	        out_8(info2->cmap_adr + 0xb0, i);
+	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+	    	break;
+	    case cmap_M3B:
+	        /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+	    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+	    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+	    	/* Set palette index & data */
+	    	out_8(info2->cmap_adr + 0xb0, i);
+	    	out_le32((unsigned *)(info2->cmap_adr + 0xb4), 0);
+	    	break;
 	    }
 	}
     else
@@ -823,14 +898,37 @@
     info2->palette[regno].green = green;
     info2->palette[regno].blue = blue;
 
-    *info2->cmap_adr = regno;/* On some chipsets, add << 3 in 15 bits */
-    mach_eieio();
-    *info2->cmap_data = red;
-    mach_eieio();
-    *info2->cmap_data = green;
-    mach_eieio();
-    *info2->cmap_data = blue;
-    mach_eieio();
+    switch(info2->cmap_type) {
+    case cmap_m64:
+        *info2->cmap_adr = regno;
+	mach_eieio();
+	*info2->cmap_data = red;
+	mach_eieio();
+	*info2->cmap_data = green;
+	mach_eieio();
+	*info2->cmap_data = blue;
+	mach_eieio();
+	break;
+    case cmap_M3A:
+	/* Clear PALETTE_ACCESS_CNTL in DAC_CNTL */
+	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+		in_le32((unsigned *)(info2->cmap_adr + 0x58)) & ~0x20);
+    case cmap_r128:
+	/* Set palette index & data */
+	out_8(info2->cmap_adr + 0xb0, regno);
+	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+		(red << 16 | green << 8 | blue));
+	break;
+    case cmap_M3B:
+        /* Set PALETTE_ACCESS_CNTL in DAC_CNTL */
+    	out_le32((unsigned *)(info2->cmap_adr + 0x58),
+    		in_le32((unsigned *)(info2->cmap_adr + 0x58)) | 0x20);
+    	/* Set palette index & data */
+    	out_8(info2->cmap_adr + 0xb0, regno);
+  	out_le32((unsigned *)(info2->cmap_adr + 0xb4),
+    		(red << 16 | green << 8 | blue));
+    	break;
+    }
 
     if (regno < 16)
 	switch (info2->var.bits_per_pixel) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/pm2fb.c linux.17p18/drivers/video/pm2fb.c
--- linux.vanilla/drivers/video/pm2fb.c	Fri Apr 21 12:46:40 2000
+++ linux.17p18/drivers/video/pm2fb.c	Tue Aug  1 07:59:59 2000
@@ -1272,7 +1272,13 @@
 }
 
 static struct display_switch pm2_cfb8 = {
-	fbcon_cfb8_setup, pm2fb_pp_bmove, pm2fb_clear8,
+	fbcon_cfb8_setup, pm2fb_pp_bmove,
+#ifdef __alpha__
+	/* No idea why, but pm2fb_clear8 does not always work on Alpha. */
+	fbcon_cfb8_clear,
+#else
+	pm2fb_clear8,
+#endif
 	fbcon_cfb8_putc, fbcon_cfb8_putcs, fbcon_cfb8_revc,
 	pm2fb_cursor, pm2fb_set_font,
 	pm2fb_clear_margins8,
@@ -1769,7 +1775,11 @@
 
 	save_flags(flags);
 	cli();
+#ifdef __alpha__
+	disp->screen_base=i->regions.v_fb + dense_mem(i->regions.v_fb);
+#else
 	disp->screen_base=i->regions.v_fb;
+#endif
 	switch (depth=((struct pm2fb_par* )par)->depth) {
 #ifdef FBCON_HAS_CFB8
 		case 8:
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/drivers/video/vfb.c linux.17p18/drivers/video/vfb.c
--- linux.vanilla/drivers/video/vfb.c	Fri Apr 21 12:46:40 2000
+++ linux.17p18/drivers/video/vfb.c	Wed Aug 16 21:46:35 2000
@@ -494,7 +494,7 @@
 {
     u_long length;
     
-    length = (xres_virtual+bpp-1)/bpp;
+    length = xres_virtual*bpp;
     length = (length+31)&-32;
     length >>= 3;
     return(length);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/affs/file.c linux.17p18/fs/affs/file.c
--- linux.vanilla/fs/affs/file.c	Fri Apr 21 12:46:40 2000
+++ linux.17p18/fs/affs/file.c	Tue Aug  1 07:59:06 2000
@@ -221,6 +221,8 @@
 
 	for (index = 0; index < 4; index++) {
 		kc = &inode->u.affs_i.i_ec->kc[index];
+		if (kc->kc_last == -1)		/* don't look in cache if invalid */
+			continue;
 		if (*ext == kc->kc_this_seq) {
 			return kc->kc_this_key;
 		} else if (*ext == kc->kc_this_seq + 1) {
@@ -893,7 +895,7 @@
 	/* Invalidate cache */
 	if (inode->u.affs_i.i_ec) {
 		inode->u.affs_i.i_ec->max_ext = 0;
-		for (key = 0; key < 3; key++) {
+		for (key = 0; key < 4; key++) {
 			inode->u.affs_i.i_ec->kc[key].kc_next_key = 0;
 			inode->u.affs_i.i_ec->kc[key].kc_last     = -1;
 		}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/buffer.c linux.17p18/fs/buffer.c
--- linux.vanilla/fs/buffer.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/fs/buffer.c	Tue Aug  1 07:59:22 2000
@@ -27,6 +27,10 @@
 /* invalidate_buffers/set_blocksize/sync_dev race conditions and
    fs corruption fixes, 1999, Andrea Arcangeli <andrea@suse.de> */
 
+/* Wait for dirty buffers to sync in sync_page_buffers.
+ * 2000, Marcelo Tosatti <marcelo@conectiva.com.br>
+ */
+
 #include <linux/malloc.h>
 #include <linux/locks.h>
 #include <linux/errno.h>
@@ -1464,6 +1468,30 @@
 #define BUFFER_BUSY_BITS	((1<<BH_Dirty) | (1<<BH_Lock) | (1<<BH_Protected))
 #define buffer_busy(bh)		((bh)->b_count || ((bh)->b_state & BUFFER_BUSY_BITS))
 
+static int sync_page_buffers(struct buffer_head *bh, int wait)
+{
+	struct buffer_head * tmp = bh;
+
+	do {
+		struct buffer_head *p = tmp;
+		tmp = tmp->b_this_page;
+		if (buffer_locked(p)) {
+			if (wait)
+				__wait_on_buffer(p);
+		} else if (buffer_dirty(p))
+			ll_rw_block(WRITE, 1, &p);
+	} while (tmp != bh);
+
+	do {
+		struct buffer_head *p = tmp;
+		tmp = tmp->b_this_page;
+		if (buffer_busy(p))
+			return 1;
+	} while (tmp != bh);
+
+	return 0;
+}
+
 /*
  * try_to_free_buffers() checks if all the buffers on this particular page
  * are unused, and free's the page if so.
@@ -1471,22 +1499,19 @@
  * Wake up bdflush() if this fails - if we're running low on memory due
  * to dirty buffers, we need to flush them out as quickly as possible.
  */
-int try_to_free_buffers(struct page * page_map)
+int try_to_free_buffers(struct page * page_map, int wait)
 {
 	struct buffer_head * tmp, * bh = page_map->buffers;
+	int too_many;
 
 	tmp = bh;
 	do {
-		struct buffer_head * p = tmp;
-
+		if (buffer_busy(tmp))
+			goto busy;
 		tmp = tmp->b_this_page;
-		if (!buffer_busy(p))
-			continue;
-
-		wakeup_bdflush(0);
-		return 0;
 	} while (tmp != bh);
 
+ succeed:
 	tmp = bh;
 	do {
 		struct buffer_head * p = tmp;
@@ -1504,6 +1529,28 @@
 	page_map->buffers = NULL;
 	__free_page(page_map);
 	return 1;
+
+ busy:
+	too_many = (nr_buffers * bdf_prm.b_un.nfract/100);
+
+	if (!sync_page_buffers(bh, wait)) {
+
+		/* If a high percentage of the buffers are dirty, 
+		 * wake kflushd 
+		 */
+		if (nr_buffers_type[BUF_DIRTY] > too_many)
+			wakeup_bdflush(0);
+			
+		/*
+		 * We can jump after the busy check because
+		 * we rely on the kernel lock.
+		 */
+		goto succeed;
+	}
+
+	if(nr_buffers_type[BUF_DIRTY] > too_many)
+		wakeup_bdflush(0);
+	return 0;
 }
 
 /* ================== Debugging =================== */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/cache.c linux.17p18/fs/coda/cache.c
--- linux.vanilla/fs/coda/cache.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/cache.c	Wed Aug  9 22:23:26 2000
@@ -24,82 +24,49 @@
 #include <linux/coda_fs_i.h>
 #include <linux/coda_cache.h>
 
-static void coda_ccinsert(struct coda_cache *el, struct super_block *sb);
-static void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cii);
-static void coda_ccremove(struct coda_cache *el);
-static void coda_cnremove(struct coda_cache *el);
-static void coda_cache_create(struct inode *inode, int mask);
-static struct coda_cache * coda_cache_find(struct inode *inode);
-
-
-/* insert a acl-cache entry in sb list */
-static void coda_ccinsert(struct coda_cache *el, struct super_block *sb)
+/* create a new acl cache entry and enlist it */
+static struct coda_cache *coda_cache_create(struct inode *inode)
 {
-	struct coda_sb_info *sbi = coda_sbp(sb);
+	struct coda_inode_info *cii = ITOC(inode);
+	struct coda_sb_info *sbi = coda_sbp(inode->i_sb);
+	struct coda_cache *cc = NULL;
 	ENTRY;
-	/* third test verifies cc was initialized before adding it 
-	   to the sblist. Probably superfluous */
-	if ( !sbi || !el || !list_empty(&el->cc_cclist) ) {
-		printk("coda_ccinsert: NULL sbi or el->cc_cclist not empty!\n");
-		return ;
-	}
 
-	list_add(&el->cc_cclist, &sbi->sbi_cchead);
-}
+	if ( !sbi || !cii ) {
+		printk("coda_cache_create: NULL sbi or cii!\n");
+		return NULL;
+	}
 
-/* insert a acl-cache entry in the inode list */
-static void coda_cninsert(struct coda_cache *el, struct coda_inode_info *cii)
-{
-	ENTRY;
-	if ( !cii ||  !el || ! list_empty(&el->cc_cnlist)) {
-		printk("coda_cninsert: NULL cii or el->cc_cnlist not empty!\n");
-		return ;
+	CODA_ALLOC(cc, struct coda_cache *, sizeof(struct coda_cache));
+	if ( !cc ) {
+		printk("Out of memory in coda_cache_create!\n");
+		return NULL;
 	}
-	list_add(&el->cc_cnlist, &cii->c_cnhead);
-}
 
-/* remove a cache entry from the superblock list */
-static void coda_ccremove(struct coda_cache *el)
-{
-	ENTRY;
-        if ( ! list_empty(&el->cc_cclist) )
-	        list_del(&el->cc_cclist);
-	else
-		printk("coda_ccremove: loose cc entry!");
-}
+	coda_load_creds(&cc->cc_cred);
+	cc->cc_mask = 0;
 
-/* remove a cache entry from the inode's list */
-static void coda_cnremove(struct coda_cache *el)
-{
-	ENTRY;
-	if ( ! list_empty(&el->cc_cnlist) )
-		list_del(&el->cc_cnlist);
-	else
-		printk("coda_cnremove: loose cn entry!");
+	INIT_LIST_HEAD(&cc->cc_cclist);
+	INIT_LIST_HEAD(&cc->cc_cnlist);
+	list_add(&cc->cc_cclist, &sbi->sbi_cchead);
+	list_add(&cc->cc_cnlist, &cii->c_cnhead);
+
+	return cc;
 }
 
-/* create a new cache entry and enlist it */
-static void coda_cache_create(struct inode *inode, int mask)
+/* destroy an acl cache entry */
+static void coda_cache_destroy(struct coda_cache *el)
 {
-	struct coda_inode_info *cii = ITOC(inode);
-	struct super_block *sb = inode->i_sb;
-	struct coda_cache *cc = NULL;
 	ENTRY;
 
-	CODA_ALLOC(cc, struct coda_cache *, sizeof(*cc));
-
-	if ( !cc ) {
-		printk("Out of memory in coda_cache_enter!\n");
+	if (list_empty(&el->cc_cclist) || list_empty(&el->cc_cnlist)) {
+		printk("coda_cache_destroy: loose entry!");
 		return;
 	}
 
-	INIT_LIST_HEAD(&cc->cc_cclist);
-	INIT_LIST_HEAD(&cc->cc_cnlist);
-
-	coda_load_creds(&cc->cc_cred);
-	cc->cc_mask = mask;
-	coda_cninsert(cc, cii);
-	coda_ccinsert(cc, sb);
+	list_del(&el->cc_cclist);
+	list_del(&el->cc_cnlist);
+	CODA_FREE(el, sizeof(struct coda_cache));
 }
 
 /* see if there is a match for the current 
@@ -107,11 +74,11 @@
 static struct coda_cache * coda_cache_find(struct inode *inode)
 {
 	struct coda_inode_info *cii = ITOC(inode);
-	struct list_head *lh, *le;
+	struct list_head *le;
 	struct coda_cache *cc = NULL;
 	
-	le = lh = &cii->c_cnhead;
-	while( (le = le->next ) != lh )  {
+	for(le = cii->c_cnhead.next; le != &cii->c_cnhead; le = le->next)
+	{
 		/* compare name and creds */
 		cc = list_entry(le, struct coda_cache, cc_cnlist);
 		if ( !coda_cred_ok(&cc->cc_cred) )
@@ -119,7 +86,7 @@
 		CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino );
 		return cc; /* cache hit */
 	}
-		return NULL;
+	return NULL;
 }
 
 /* create or extend an acl cache hit */
@@ -129,11 +96,11 @@
 
 	cc = coda_cache_find(inode);
 
-	if ( cc ) {
+	if (!cc)
+		coda_cache_create(inode);
+
+	if (cc)
 		cc->cc_mask |= mask;
-	} else {
-		coda_cache_create(inode, mask);
-	}
 }
 
 /* remove all cached acl matches from an inode */
@@ -154,9 +121,7 @@
 	while ( le != &cii->c_cnhead ) {
 		cc = list_entry(le, struct coda_cache, cc_cnlist);
 		le = le->next;
-		coda_cnremove(cc);
-		coda_ccremove(cc);
-		CODA_FREE(cc, sizeof(*cc));
+		coda_cache_destroy(cc);
 	}
 }
 
@@ -172,16 +137,11 @@
 		return;
 	}
 	
-	if ( list_empty(&sbi->sbi_cchead) )
-		return;
-
 	le = sbi->sbi_cchead.next;
 	while ( le != &sbi->sbi_cchead ) {
 		cc = list_entry(le, struct coda_cache, cc_cclist);
 		le = le->next;
-		coda_cnremove(cc);
-		coda_ccremove(cc);
-		CODA_FREE(cc, sizeof(*cc));
+		coda_cache_destroy(cc);
 	}
 }
 
@@ -197,18 +157,12 @@
 		return;
 	}
 	
-	if (list_empty(&sbi->sbi_cchead))
-		return;
-
 	le = sbi->sbi_cchead.next;
 	while ( le != &sbi->sbi_cchead ) {
 		cc = list_entry(le, struct coda_cache, cc_cclist);
 		le = le->next;
-		if ( coda_cred_eq(&cc->cc_cred, cred)) {
-			coda_cnremove(cc);
-			coda_ccremove(cc);
-			CODA_FREE(cc, sizeof(*cc));
-		}
+		if (coda_cred_eq(&cc->cc_cred, cred))
+			coda_cache_destroy(cc);
 	}
 }
 
@@ -218,11 +172,11 @@
 int coda_cache_check(struct inode *inode, int mask)
 {
 	struct coda_inode_info *cii = ITOC(inode);
-	struct list_head *lh, *le;
+	struct list_head *le;
 	struct coda_cache *cc = NULL;
 	
-	le = lh = &cii->c_cnhead;
-	while( (le = le->next ) != lh )  {
+	for(le = cii->c_cnhead.next; le != &cii->c_cnhead; le = le->next)
+	{
 		/* compare name and creds */
 		cc = list_entry(le, struct coda_cache, cc_cnlist);
 		if ( (cc->cc_mask & mask) != mask ) 
@@ -232,8 +186,8 @@
 		CDEBUG(D_CACHE, "HIT for ino %ld\n", inode->i_ino );
 		return 1; /* cache hit */
 	}
-		CDEBUG(D_CACHE, "MISS for ino %ld\n", inode->i_ino );
-		return 0;
+	CDEBUG(D_CACHE, "MISS for ino %ld\n", inode->i_ino );
+	return 0;
 }
 
 
@@ -294,10 +248,10 @@
 	struct list_head *child;
 	struct dentry *de;
 
-	child = parent->d_subdirs.next;
-	while ( child != &parent->d_subdirs ) {
+	for(child = parent->d_subdirs.next; child != &parent->d_subdirs;
+	    child = child->next)
+	{
 		de = list_entry(child, struct dentry, d_child);
-		child = child->next;
 		/* don't know what to do with negative dentries */
 		if ( ! de->d_inode ) 
 			continue;
@@ -315,7 +269,7 @@
 	struct dentry *alias_de;
 
 	ENTRY;
-	if ( !inode ) 
+	if ( !inode || !S_ISDIR(inode->i_mode)) 
 		return; 
 
 	if (list_empty(&inode->i_dentry))
@@ -338,14 +292,7 @@
 /* this will not zap the inode away */
 void coda_flag_inode(struct inode *inode, int flag)
 {
-	struct coda_inode_info *cii;
-
-	if ( !inode ) {
-		CDEBUG(D_CACHE, " no inode!\n");
-		return;
-	}
-
-	cii = ITOC(inode);
+	struct coda_inode_info *cii = ITOC(inode);
 	cii->c_flags |= flag;
 }		
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/cnode.c linux.17p18/fs/coda/cnode.c
--- linux.vanilla/fs/coda/cnode.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/cnode.c	Wed Aug  9 22:23:26 2000
@@ -3,6 +3,7 @@
    */
 
 #include <linux/types.h>
+#include <linux/string.h>
 #include <linux/time.h>
 
 #include <linux/coda.h>
@@ -96,6 +97,8 @@
 	cnp = ITOC(*inode);
 	/* see if we've got it already */
 	if  ( cnp->c_magic != 0 && coda_fideq(fid, &cnp->c_fid)) {
+		/* replace the attributes, type might have changed */
+		coda_fill_inode(*inode, &attr);
 		return 0;
 	}
 
@@ -117,19 +120,26 @@
        INIT_LIST_HEAD(&(cnp->c_volrootlist));
 
 	/* fill in the inode attributes */
-	if ( coda_f2i(fid) != ino ) {
-	        if ( !coda_fid_is_weird(fid) ) 
-		        printk("Coda: unknown weird fid: ino %ld, fid %s."
-			       "Tell Peter.\n", (long)ino, coda_f2s(&cnp->c_fid));
-		list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
-		CDEBUG(D_UPCALL, "Added %ld ,%s to volroothead\n",
-		       (long)ino, coda_f2s(&cnp->c_fid));
+        coda_fill_inode(*inode, &attr);
+
+	if ( coda_f2i(fid) == ino )
+		goto out;
+
+	/* check if we expected this weird fid */
+	if ( !coda_fid_is_weird(fid) ) {
+		printk("Coda: unknown weird fid: ino %ld, fid %s."
+				"Tell Peter.\n", (long)ino, coda_f2s(&cnp->c_fid));
+		goto out;
 	}
 
-        coda_fill_inode(*inode, &attr);
-	CDEBUG(D_DOWNCALL, "Done making inode: ino %ld,  count %d with %s\n",
-	        (*inode)->i_ino, (*inode)->i_count, 
-	       coda_f2s(&cnp->c_fid));
+	/* add the inode to a global list so we can find it back later */
+	list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
+	CDEBUG(D_UPCALL, "Added %ld ,%s to volroothead\n",
+	       (long)ino, coda_f2s(&cnp->c_fid));
+
+out:
+	CDEBUG(D_DOWNCALL, "Done making inode: ino %ld, count %d with %s\n",
+	        (*inode)->i_ino, (*inode)->i_count, coda_f2s(&cnp->c_fid));
 
         EXIT;
         return 0;
@@ -150,7 +160,8 @@
 	cnp->c_fid = *newfid;
 
 	list_del(&cnp->c_volrootlist);
-	if ( !coda_fid_is_weird(newfid) ) 
+	INIT_LIST_HEAD(&cnp->c_volrootlist);
+	if ( coda_fid_is_weird(newfid) ) 
 		list_add(&cnp->c_volrootlist, &sbi->sbi_volroothead);
 
 	return;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/dir.c linux.17p18/fs/coda/dir.c
--- linux.vanilla/fs/coda/dir.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/dir.c	Wed Aug  9 22:23:26 2000
@@ -37,8 +37,8 @@
 			const char *symname);
 static int coda_mkdir(struct inode *dir_inode, struct dentry *entry, int mode);
 static int coda_rmdir(struct inode *dir_inode, struct dentry *entry);
-static int coda_rename(struct inode *old_inode, struct dentry *old_dentry, 
-                       struct inode *new_inode, struct dentry *new_dentry);
+static int coda_rename(struct inode *old_dir, struct dentry *old_dentry, 
+                       struct inode *new_dir, struct dentry *new_dentry);
 
 /* dir file-ops */
 static int coda_readdir(struct file *file, void *dirent, filldir_t filldir);
@@ -52,7 +52,6 @@
 			      filldir_t filldir);
 int coda_fsync(struct file *, struct dentry *dentry);
 
-int coda_crossvol_rename = 0;
 int coda_hasmknod = 0;
 
 struct dentry_operations coda_dentry_operations =
@@ -111,9 +110,9 @@
 {
         struct coda_inode_info *dircnp;
 	struct inode *res_inode = NULL;
-	struct ViceFid resfid;
+	struct ViceFid resfid = {0,0,0};
 	int dropme = 0; /* to indicate entry should not be cached */
-	int type;
+	int type = 0;
 	int error = 0;
 	const char *name = entry->d_name.name;
 	size_t length = entry->d_name.len;
@@ -137,6 +136,7 @@
 		CDEBUG(D_SPECIAL, 
 		       "Lookup on CTL object; dir ino %ld, count %d\n", 
 		       dir->i_ino, dir->i_count);
+		dropme = 1;
                 goto exit;
         }
 
@@ -151,9 +151,14 @@
 			       coda_f2s(&resfid));
 			dropme = 1;
 		}
+
 	    	error = coda_cnode_make(&res_inode, &resfid, dir->i_sb);
-		if (error)
-			return ERR_PTR(error);
+		if (error) return ERR_PTR(error);
+
+		/* make sure we drop unexpected non-hashable fids */
+		if (coda_f2i(&resfid) != res_inode->i_ino &&
+		    !coda_fid_is_weird(&resfid))
+			dropme = 1;
 	} else if (error != -ENOENT) {
 	        CDEBUG(D_INODE, "error for %s(%*s)%d\n",
 		       coda_f2s(&dircnp->c_fid), (int)length, name, error);
@@ -168,7 +173,7 @@
 	d_add(entry, res_inode);
 	if ( dropme ) {
 		d_drop(entry);
-		ITOC(res_inode)->c_flags |= C_VATTR;
+		coda_flag_inode(res_inode, C_VATTR);
 	}
         EXIT;
         return NULL;
@@ -184,9 +189,8 @@
 	coda_vfs_stat.permission++;
 	coda_permission_stat.count++;
 
-        if ( mask == 0 ) {
+        if ( mask == 0 )
                 return 0;
-        }
 
 	if ( coda_access_cache == 1 ) {
 		if ( coda_cache_check(inode, mask) ) {
@@ -203,17 +207,29 @@
         CDEBUG(D_INODE, "fid: %s, ino: %ld (mask: %o) error: %d\n", 
 	       coda_f2s(&(cp->c_fid)), inode->i_ino, mask, error);
 
-	if ( error == 0 ) {
+	if (!error)
 		coda_cache_enter(inode, mask);
-	}
 
         return error; 
 }
 
-
+static inline void coda_dir_changed(struct inode *dir, int link)
+{
+#ifdef REQUERY_VENUS_FOR_MTIME
+	/* invalidate the directory cnode's attributes to refetch the
+	 * attributes from venus next time the inode is referenced */
+	coda_flag_inode(dir, C_VATTR);
+#else
+	/* optimistically we can also act as if our nose bleeds. The
+	 * granularity of the mtime is coarse anyways so we might actually be
+	 * right most of the time. Note: we only do this for directories. */
+	dir->i_mtime = CURRENT_TIME;
+#endif
+	if (link)
+		dir->i_nlink += link;
+}
 
 /* creation routines: create, mknod, mkdir, link, symlink */
-
 static int coda_create(struct inode *dir, struct dentry *de, int mode)
 {
         int error=0;
@@ -252,10 +268,10 @@
 	}
 
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags |= C_VATTR;
+	coda_dir_changed(dir, 0);
 	d_instantiate(de, result);
         return 0;
-}			     
+}
 
 static int coda_mknod(struct inode *dir, struct dentry *de, int mode, int rdev)
 {
@@ -297,7 +313,7 @@
 	}
 
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags |= C_VATTR;
+	coda_dir_changed(dir, 0);
 	d_instantiate(de, result);
         return 0;
 }			     
@@ -344,8 +360,7 @@
 	}
 	
 	/* invalidate the directory cnode's attributes */
-	dircnp->c_flags |= C_VATTR;
-	dir->i_nlink++;
+	coda_dir_changed(dir, 1);
 	d_instantiate(de, inode);
         return 0;
 }
@@ -375,16 +390,17 @@
         error = venus_link(dir_inode->i_sb,&(cnp->c_fid), &(dir_cnp->c_fid), 
 			   (const char *)name, len);
 
-	if (  ! error ) { 
-		dir_cnp->c_flags |= C_VATTR;
-		++inode->i_count;
-		d_instantiate(de, inode);
-		inode->i_nlink++;
-	} else  {
+	if (error) { 
 		d_drop(de);
-		return error;
+		goto out;	
 	}
 
+	coda_dir_changed(dir_inode, 0);
+	inode->i_count++;
+	d_instantiate(de, inode);
+	inode->i_nlink++;
+
+out:
         CDEBUG(D_INODE, "link result %d\n",error);
 	EXIT;
         return(error);
@@ -421,9 +437,8 @@
 			      symname, symlen);
 
 	/* mtime is no good anymore */
-	if ( !error ) {
-		dir_cnp->c_flags |= C_VATTR;
-	}
+	if ( !error )
+		coda_dir_changed(dir_inode, 0);
 
         CDEBUG(D_INODE, "in symlink result %d\n",error);
         EXIT;
@@ -451,7 +466,7 @@
         }
 
         /* cache management: mtime has changed, ask Venus */
-	dircnp->c_flags |= C_VATTR;
+	coda_dir_changed(dir, 0);
 	de->d_inode->i_nlink--;
 	d_delete(de);
 
@@ -479,8 +494,9 @@
                 return error;
         }
 
-	if (de->d_inode->i_nlink)
-		de->d_inode->i_nlink --;
+	coda_dir_changed(dir, -1);
+	de->d_inode->i_nlink--;
+	d_delete(de);
 
         return 0;
 }
@@ -493,7 +509,6 @@
         const char *new_name = new_dentry->d_name.name;
 	int old_length = old_dentry->d_name.len;
 	int new_length = new_dentry->d_name.len;
-	struct inode *new_inode = new_dentry->d_inode;
         struct coda_inode_info *new_cnp, *old_cnp;
         int error;
 
@@ -508,28 +523,29 @@
 	       old_name, old_length, (long)strlen(old_name), new_name, new_length, 
 	       (long)strlen(new_name),old_dentry->d_count, new_dentry->d_count);
 
-	/* the C library will do unlink/create etc */
-	if ( coda_crossvol_rename == 0 && 
-	     old_cnp->c_fid.Volume != new_cnp->c_fid.Volume )
-		return -EXDEV;
-
         error = venus_rename(old_dir->i_sb, &(old_cnp->c_fid), 
 			     &(new_cnp->c_fid), old_length, new_length, 
 			     (const char *) old_name, (const char *)new_name);
 
-        if ( error ) {
-                CDEBUG(D_INODE, "returned error %d\n", error);
-                return error;
+        if ( !error ) {
+		if ( new_dentry->d_inode ) {
+			if ( S_ISDIR(new_dentry->d_inode->i_mode) ) {
+				old_dir->i_nlink--;
+				new_dir->i_nlink++;
+			}
+			coda_flag_inode(new_dentry->d_inode, C_VATTR);
+		}
+
+		/* coda_flag_inode(old_dir, C_VATTR); */
+		/* coda_flag_inode(new_dir, C_VATTR); */
+		old_dir->i_mtime = new_dir->i_mtime = CURRENT_TIME;
         }
 
-	coda_flag_inode(new_inode, C_VATTR);
-	coda_flag_inode(old_dir, C_VATTR);
-	coda_flag_inode(new_dir, C_VATTR);
 
 	CDEBUG(D_INODE, "result %d\n", error); 
 
 	EXIT;
-	return 0;
+	return error;
 }
 
 
@@ -589,7 +605,6 @@
 
         cnp = ITOC(i);
 
-
 	error = venus_open(i->i_sb, &(cnp->c_fid), coda_flags, &ino, &dev); 
 	if (error) {
 	        CDEBUG(D_FILE, "venus: dev %d, inode %ld, out->result %d\n",
@@ -617,7 +632,7 @@
 		cnp->c_ovp = NULL;
 	}
 	cnp->c_ovp = cont_inode; 
-        cnp->c_ocount++;
+	cnp->c_contcount++;
 
         CDEBUG(D_FILE, "result %d, coda i->i_count is %d for ino %ld\n", 
 	       error, i->i_count, i->i_ino);
@@ -642,24 +657,16 @@
 	cred = (struct coda_cred *)f->private_data;
 
         cnp =ITOC(i);
-        CHECK_CNODE(cnp);
         CDEBUG(D_FILE,  
-	       "RELEASE coda (ino %ld, ct %d) cache (ino %ld, ct %d)\n",
-               i->i_ino, i->i_count, (cnp->c_ovp ? cnp->c_ovp->i_ino : 0),
+	       "RELEASE coda (ino %ld, ct %d, ref %d) cache (ino %ld, ct %d)\n",
+               i->i_ino, i->i_count, cnp->c_contcount,
+	       (cnp->c_ovp ? cnp->c_ovp->i_ino : 0),
                (cnp->c_ovp ? cnp->c_ovp->i_count : -99));
 
-
-        /* even when c_ocount=0 we cannot put c_ovp to
-         * NULL since the file may be mmapped.
-	 * See code in inode.c (coda_put_inode) for
-	 * further handling of close.
-	 */
-
-        --cnp->c_ocount;
-
-        if (flags & (O_WRONLY | O_RDWR)) {
-                --cnp->c_owrite;
-        }
+	if (--cnp->c_contcount == 0) {
+		iput(cnp->c_ovp);
+		cnp->c_ovp = NULL;
+	}
 
 	error = venus_release(i->i_sb, &(cnp->c_fid), cflags, cred);
 
@@ -780,7 +787,6 @@
 /* called when a cache lookup succeeds */
 static int coda_dentry_revalidate(struct dentry *de, int flags)
 {
-	int valid = 1;
 	struct inode *inode = de->d_inode;
 	struct coda_inode_info *cii;
 	ENTRY;
@@ -788,14 +794,14 @@
 	if (!inode)
 		return 1;
 
-	cii = ITOC(de->d_inode);
 	if (coda_isroot(inode))
 		return 1;
 	if (is_bad_inode(inode))
 		return 0;
 
+	cii = ITOC(de->d_inode);
 	if (! (cii->c_flags & (C_PURGE | C_FLUSH)) )
-		return valid;
+		return 1;
 
 	shrink_dcache_parent(de);
 
@@ -825,9 +831,9 @@
 	int flags;
 
 	if (!dentry->d_inode) 
-		return ;
+		return;
 
-	flags =  (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
+	flags = (ITOC(dentry->d_inode)->c_flags) & C_PURGE;
 	if (is_bad_inode(dentry->d_inode) || flags) {
 		CDEBUG(D_DOWNCALL, "bad inode, unhashing %s/%s, %ld\n", 
 		       dentry->d_parent->d_name.name, dentry->d_name.name,
@@ -862,19 +868,10 @@
 	if ( cii->c_flags == 0 )
 		return 0;
 
-	/* Venus closed the device .... */
-	if ( cii->c_flags & C_DYING ) { 
-		make_bad_inode(inode);
-		return -EIO;
-	}
-
-	
 	if (cii->c_flags & (C_VATTR | C_PURGE | C_FLUSH)) {
 		error = venus_getattr(inode->i_sb, &(cii->c_fid), &attr);
-		if ( error ) { 
-			make_bad_inode(inode);
+		if ( error )
 			return -EIO;
-		}
 
 		/* this inode may be lost if:
 		   - it's ino changed 
@@ -885,17 +882,15 @@
 		old_ino = inode->i_ino;
 		coda_vattr_to_iattr(inode, &attr);
 
-
 		if ((old_mode & S_IFMT) != (inode->i_mode & S_IFMT)) {
 			printk("Coda: inode %ld, fid %s changed type!\n",
 			       inode->i_ino, coda_f2s(&(cii->c_fid)));
 		}
 
 		/* the following can happen when a local fid is replaced 
-		   with a global one, here we lose and declar the inode bad */
+		   with a global one, here we lose and declare the inode bad */
 		if (inode->i_ino != old_ino) {
 			make_bad_inode(inode);
-			inode->i_mode = old_mode;
 			return -EIO;
 		}
 		
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/file.c linux.17p18/fs/coda/file.c
--- linux.vanilla/fs/coda/file.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/file.c	Wed Aug  9 22:23:26 2000
@@ -115,7 +115,6 @@
 
         ENTRY;
 	cii = ITOC(file->f_dentry->d_inode);
-	cii->c_mmcount++;
   
 	res =generic_file_mmap(file, vma);
 	EXIT;
@@ -136,7 +135,6 @@
 	coda_vfs_stat.file_read++;
 
         cnp = ITOC(coda_inode);
-        CHECK_CNODE(cnp);
 	
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
@@ -177,7 +175,6 @@
 	coda_vfs_stat.file_write++;
 
         cnp = ITOC(coda_inode);
-        CHECK_CNODE(cnp);
 
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
@@ -221,7 +218,6 @@
 		return -EINVAL;
 
         cnp = ITOC(coda_inode);
-        CHECK_CNODE(cnp);
 
         cont_inode = cnp->c_ovp;
         if ( cont_inode == NULL ) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/inode.c linux.17p18/fs/coda/inode.c
--- linux.vanilla/fs/coda/inode.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/inode.c	Wed Aug  9 22:23:26 2000
@@ -37,8 +37,7 @@
 static struct super_block *coda_read_super(struct super_block *, void *, int);
 static void coda_read_inode(struct inode *);
 static int  coda_notify_change(struct dentry *dentry, struct iattr *attr);
-static void coda_put_inode(struct inode *);
-static void coda_delete_inode(struct inode *);
+static void coda_clear_inode(struct inode *);
 static void coda_put_super(struct super_block *);
 static int coda_statfs(struct super_block *sb, struct statfs *buf, 
 		       int bufsiz);
@@ -48,13 +47,14 @@
 {
 	coda_read_inode,        /* read_inode */
 	NULL,                   /* write_inode */
-	coda_put_inode,	        /* put_inode */
-	coda_delete_inode,      /* delete_inode */
+	NULL,			/* put_inode */
+	NULL,			/* delete_inode */
 	coda_notify_change,	/* notify_change */
 	coda_put_super,	        /* put_super */
 	NULL,			/* write_super */
 	coda_statfs,   		/* statfs */
-	NULL			/* remount_fs */
+	NULL,			/* remount_fs */
+	coda_clear_inode	/* clear_inode */
 };
 
 static struct super_block * coda_read_super(struct super_block *sb, 
@@ -165,35 +165,22 @@
 	return;
 }
 
-static void coda_put_inode(struct inode *in) 
+static void coda_clear_inode(struct inode *inode) 
 {
-	ENTRY;
-
-        CDEBUG(D_INODE,"ino: %ld, count %d\n", in->i_ino, in->i_count);
-
-	if ( in->i_count == 1 ) 
-		in->i_nlink = 0;
-		
-}
-
-static void coda_delete_inode(struct inode *inode)
-{
-        struct coda_inode_info *cii;
+	struct coda_inode_info *cii = ITOC(inode);
         struct inode *open_inode;
 
         ENTRY;
         CDEBUG(D_SUPER, " inode->ino: %ld, count: %d\n", 
 	       inode->i_ino, inode->i_count);        
 
-        cii = ITOC(inode);
-	if ( inode->i_ino == CTL_INO || cii->c_magic != CODA_CNODE_MAGIC ) {
-	        clear_inode(inode);
-		return;
-	}
-
-
-	if ( ! list_empty(&cii->c_volrootlist) )
+	if ( inode->i_ino == CTL_INO || cii->c_magic != CODA_CNODE_MAGIC )
+		goto out;
+	
+	if ( !list_empty(&cii->c_volrootlist) ) {
 		list_del(&cii->c_volrootlist);
+		INIT_LIST_HEAD(&cii->c_volrootlist);
+	}
 
         open_inode = cii->c_ovp;
         if ( open_inode ) {
@@ -202,11 +189,12 @@
                 cii->c_ovp = NULL;
                 iput(open_inode);
         }
-	
+
 	coda_cache_clear_inode(inode);
+
 	CDEBUG(D_DOWNCALL, "clearing inode: %ld, %x\n", inode->i_ino, cii->c_flags);
+out:
 	inode->u.coda_i.c_magic = 0;
-        clear_inode(inode);
 	EXIT;
 }
 
@@ -220,7 +208,6 @@
 	ENTRY;
         memset(&vattr, 0, sizeof(vattr)); 
         cii = ITOC(inode);
-        CHECK_CNODE(cii);
 
         coda_iattr_to_vattr(iattr, &vattr);
         vattr.va_type = C_VNON; /* cannot set type */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/pioctl.c linux.17p18/fs/coda/pioctl.c
--- linux.vanilla/fs/coda/pioctl.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/pioctl.c	Wed Aug  9 22:23:26 2000
@@ -26,8 +26,6 @@
 
 /* pioctl ops */
 static int coda_ioctl_permission(struct inode *inode, int mask);
-static int coda_ioctl_open(struct inode *i, struct file *f);
-static int coda_ioctl_release(struct inode *i, struct file *f);
 static int coda_pioctl(struct inode * inode, struct file * filp, 
                        unsigned int cmd, unsigned long arg);
 
@@ -64,9 +62,9 @@
 	NULL,			/* select - default */
 	coda_pioctl,	        /* ioctl */
 	NULL,                   /* mmap */
-	coda_ioctl_open,        /* open */
+	NULL,			/* open */
 	NULL,
-	coda_ioctl_release,     /* release */
+	NULL,			/* release */
 	NULL,		        /* fsync */
 };
 
@@ -77,25 +75,6 @@
 
         return 0;
 }
-
-/* The pioctl file ops*/
-int coda_ioctl_open(struct inode *i, struct file *f)
-{
-
-        ENTRY;
-
-        CDEBUG(D_PIOCTL, "File inode number: %ld\n", 
-	       f->f_dentry->d_inode->i_ino);
-
-	EXIT;
-        return 0;
-}
-
-int coda_ioctl_release(struct inode *i, struct file *f) 
-{
-        return 0;
-}
-
 
 static int coda_pioctl(struct inode * inode, struct file * filp, 
 		       unsigned int cmd, unsigned long user_data)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/psdev.c linux.17p18/fs/coda/psdev.c
--- linux.vanilla/fs/coda/psdev.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/psdev.c	Wed Aug  9 22:23:26 2000
@@ -69,37 +69,52 @@
         struct venus_comm *vcp = &coda_upc_comm;
 	unsigned int mask = POLLOUT | POLLWRNORM;
 
-	poll_wait(file, &(vcp->vc_waitq), wait);
+	poll_wait(file, &vcp->vc_waitq, wait);
 	if (!list_empty(&vcp->vc_pending))
                 mask |= POLLIN | POLLRDNORM;
 
 	return mask;
 }
 
+static int coda_psdev_ioctl(struct inode * inode, struct file * filp,
+			    unsigned int cmd, unsigned long arg)
+{
+	unsigned int data;
+
+	switch(cmd) {
+	case CIOC_KERNEL_VERSION:
+		data = CODA_KERNEL_VERSION;
+		return put_user(data, (int *) arg);
+	default:
+		return -ENOTTY;
+	}
+
+	return 0;
+}
 
 /*
  *	Receive a message written by Venus to the psdev
  */
  
 static ssize_t coda_psdev_write(struct file *file, const char *buf, 
-				size_t count, loff_t *off)
+				size_t nbytes, loff_t *off)
 {
         struct venus_comm *vcp = &coda_upc_comm;
         struct upc_req *req = NULL;
         struct upc_req *tmp;
 	struct list_head *lh;
 	struct coda_in_hdr hdr;
+	ssize_t retval = 0, count = 0;
 	int error;
 
-
-	if ( !coda_upc_comm.vc_pid ) 
+	if ( !coda_upc_comm.vc_inuse ) 
 		return -EIO;
         /* Peek at the opcode, uniquefier */
 	if (copy_from_user(&hdr, buf, 2 * sizeof(u_long)))
 	        return -EFAULT;
 
 	CDEBUG(D_PSDEV, "(process,opc,uniq)=(%d,%ld,%ld), count %ld\n", 
-	       current->pid, hdr.opcode, hdr.unique, (long)count);
+	       current->pid, hdr.opcode, hdr.unique, (long)nbytes);
 
         if (DOWNCALL(hdr.opcode)) {
 		struct super_block *sb = NULL;
@@ -108,37 +123,42 @@
 
 		sb = coda_super_info.sbi_sb;
 		if ( !sb ) {
-			printk("coda_psdev_write: downcall, no SB!\n");
-			return count;
+			CDEBUG(D_PSDEV, "coda_psdev_write: downcall, no SB!\n");
+			count = nbytes;
+			goto out;
 		}
 		CDEBUG(D_PSDEV, "handling downcall\n");
 
-		if  ( count < sizeof(struct coda_out_hdr) ) {
+		if  ( nbytes < sizeof(struct coda_out_hdr) ) {
 		        printk("coda_downcall opc %ld uniq %ld, not enough!\n",
 			       hdr.opcode, hdr.unique);
-			return count;
+			count = nbytes;
+			goto out;
 		}
-		CODA_ALLOC(dcbuf, union outputArgs *, size);
-		if ( count > size ) {
+		if ( nbytes > size ) {
 		        printk("Coda: downcall opc %ld, uniq %ld, too much!",
 			       hdr.opcode, hdr.unique);
-		        count = size;
+		        nbytes = size;
+		}
+		CODA_ALLOC(dcbuf, union outputArgs *, nbytes);
+		if (copy_from_user(dcbuf, buf, nbytes)) {
+			CODA_FREE(dcbuf, nbytes);
+			retval = -EFAULT;
+			goto out;
 		}
-		if (copy_from_user(dcbuf, buf, count))
-		        return -EFAULT;
 
 		/* what downcall errors does Venus handle ? */
 		error = coda_downcall(hdr.opcode, dcbuf, sb);
 
+		CODA_FREE(dcbuf, nbytes);
 		if ( error) {
-		        printk("psdev_write: coda_downcall error: %d\n", 
-			       error);
-			return 0;
+		        printk("psdev_write: coda_downcall error: %d\n", error);
+			retval = error;
+			goto out;
 		}
-		CODA_FREE(dcbuf, size);
-		return count;
+		count = nbytes;
+		goto out;
         }
-
         
         /* Look for the message on the processing queue. */
 	lh  = &vcp->vc_processing;
@@ -155,28 +175,35 @@
         if (!req) {
 	        printk("psdev_write: msg (%ld, %ld) not found\n", 
 		       hdr.opcode, hdr.unique);
-		return(-ESRCH);
+		retval = -ESRCH;
+		goto out;
         }
 
         /* move data into response buffer. */
-        if (req->uc_outSize < count) {
+        if (req->uc_outSize < nbytes) {
                 printk("psdev_write: too much cnt: %d, cnt: %ld, opc: %ld, uniq: %ld.\n",
-		       req->uc_outSize, (long)count, hdr.opcode, hdr.unique);
-		count = req->uc_outSize; /* don't have more space! */
+		       req->uc_outSize, (long)nbytes, hdr.opcode, hdr.unique);
+		nbytes = req->uc_outSize; /* don't have more space! */
+	}
+        if (copy_from_user(req->uc_data, buf, nbytes)) {
+		req->uc_flags |= REQ_ABORT;
+		wake_up(&req->uc_sleep);
+	        retval = -EFAULT;
+		goto out;
 	}
-        if (copy_from_user(req->uc_data, buf, count))
-	        return -EFAULT;
 
 	/* adjust outsize. is this usefull ?? */
-        req->uc_outSize = count;	
+        req->uc_outSize = nbytes;	
         req->uc_flags |= REQ_WRITE;
+	count = nbytes;
 
 	CDEBUG(D_PSDEV, 
 	       "Found! Count %ld for (opc,uniq)=(%ld,%ld), upc_req at %p\n", 
 	        (long)count, hdr.opcode, hdr.unique, &req);
 
         wake_up(&req->uc_sleep);
-        return(count);  
+out:
+        return(count ? count : retval);  
 }
 
 /*
@@ -184,78 +211,85 @@
  */
 
 static ssize_t coda_psdev_read(struct file * file, char * buf, 
-			       size_t count, loff_t *off)
+			       size_t nbytes, loff_t *off)
 {
+	struct wait_queue wait = { current, NULL };
         struct venus_comm *vcp = &coda_upc_comm;
         struct upc_req *req;
-	int result = count ;
+	ssize_t retval = 0, count = 0;
 
-        CDEBUG(D_PSDEV, "count %ld\n", (long)count);
-        if (list_empty(&(vcp->vc_pending))) {
-              return -1;	
-        }
-    
-        req = list_entry((vcp->vc_pending.next), struct upc_req, uc_chain);
-        list_del(&(req->uc_chain));
+	if (nbytes == 0)
+		return 0;
+
+	add_wait_queue(&vcp->vc_waitq, &wait);
+	current->state = TASK_INTERRUPTIBLE;
+
+	while (list_empty(&vcp->vc_pending)) {
+		if (file->f_flags & O_NONBLOCK) {
+			retval = -EAGAIN;
+			break;
+		}
+		if (signal_pending(current)) {
+			retval = -ERESTARTSYS;
+			break;
+		}
+		schedule();
+	}
+
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&vcp->vc_waitq, &wait);
+
+	if (retval)
+		goto out;
+
+	req = list_entry(vcp->vc_pending.next, struct upc_req, uc_chain);
+	list_del(&req->uc_chain);
 
         /* Move the input args into userspace */
-        if (req->uc_inSize <= count)
-              result = req->uc_inSize;
+	count = req->uc_inSize;
+	if (nbytes < req->uc_inSize) {
+		printk ("psdev_read: Venus read %ld bytes of %d in message\n",
+			(long)nbytes, req->uc_inSize);
+		count = nbytes;
+	}
 
-        if (count < req->uc_inSize) {
-                printk ("psdev_read: Venus read %ld bytes of %d in message\n",
-			(long)count, req->uc_inSize);
-        }
+        if (copy_to_user(buf, req->uc_data, count)) {
+		retval = -EFAULT;
+		goto free_out;
+	}
 
-        if ( copy_to_user(buf, req->uc_data, result))
-	        return -EFAULT;
-        
-        /* If request was a signal, don't enqueue */
-        if (req->uc_opcode == CODA_SIGNAL) {
-                    CDEBUG(D_PSDEV, "vcread: signal msg (%d, %d)\n", 
-                              req->uc_opcode, req->uc_unique);
-              CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
-              CODA_FREE(req, sizeof(struct upc_req));
-              return count;
-        }
-    
-        req->uc_flags |= REQ_READ;
-        list_add(&(req->uc_chain), vcp->vc_processing.prev);
+        /* If request was not a signal, enqueue and don't free */
+	if (req->uc_opcode != CODA_SIGNAL) {
+		req->uc_flags |= REQ_READ;
+		list_add(&req->uc_chain, vcp->vc_processing.prev);
+		goto out;
+	}
 
-        return result;
-}
+	CDEBUG(D_PSDEV, "vcread: signal msg (%d, %d)\n", 
+			req->uc_opcode, req->uc_unique);
 
+free_out:
+	CODA_FREE(req->uc_data, sizeof(struct coda_in_hdr));
+	CODA_FREE(req, sizeof(struct upc_req));
+out:
+	return (count ? count : retval);
+}
 
 static int coda_psdev_open(struct inode * inode, struct file * file)
 {
         struct venus_comm *vcp = &coda_upc_comm;
         ENTRY;
 	
-	/* first opener: must be lento. Initialize & take its pid */
-	if ( file->f_flags == O_RDWR ) {
-		if ( vcp->vc_pid ) {
-			printk("Venus pid already set to %d!!\n", vcp->vc_pid);
-			return -1;
-		}
-		if ( vcp->vc_inuse ) {
-			printk("psdev_open: Cannot O_RDWR while open.\n");
-			return -1;
-		}
-	}
-	
-	vcp->vc_inuse++;
 	MOD_INC_USE_COUNT;
 
-
-	if ( file->f_flags == O_RDWR ) {
-		vcp->vc_pid = current->pid;
-		vcp->vc_seq = 0;
+	/* first opener, initialize */
+	if (!vcp->vc_inuse++) {
 		INIT_LIST_HEAD(&vcp->vc_pending);
 		INIT_LIST_HEAD(&vcp->vc_processing);
+		vcp->vc_seq = 0;
 	}
 
-	CDEBUG(D_PSDEV, "inuse: %d, vc_pid %d, caller %d\n",
-	       vcp->vc_inuse, vcp->vc_pid, current->pid);
+	CDEBUG(D_PSDEV, "inuse: %d\n", vcp->vc_inuse);
 
 	EXIT;
         return 0;
@@ -275,16 +309,13 @@
 		return -1;
 	}
 
-	vcp->vc_inuse--;
 	MOD_DEC_USE_COUNT;
-	CDEBUG(D_PSDEV, "inuse: %d, vc_pid %d, caller %d\n",
-	       vcp->vc_inuse, vcp->vc_pid, current->pid);
 
-	if ( vcp->vc_pid != current->pid ) {
+	CDEBUG(D_PSDEV, "psdev_release: inuse %d\n", vcp->vc_inuse);
+	if (--vcp->vc_inuse) {
 		return 0;
 	}
-        
-	vcp->vc_pid = 0;
+
         /* Wakeup clients so they can return. */
 	CDEBUG(D_PSDEV, "wake up pending clients\n");
 	lh = vcp->vc_pending.next;
@@ -305,6 +336,7 @@
 	CDEBUG(D_PSDEV, "wake up processing clients\n");
 	while ( (lh = lh->next) != &vcp->vc_processing) {
 		req = list_entry(lh, struct upc_req, uc_chain);
+		req->uc_flags |= REQ_ABORT;
 	        wake_up(&req->uc_sleep);
         }
 	CDEBUG(D_PSDEV, "Done.\n");
@@ -320,7 +352,7 @@
       coda_psdev_write,      /* write */
       NULL,		     /* coda_psdev_readdir */
       coda_psdev_poll,       /* poll */
-      NULL,                  /* ioctl */
+      coda_psdev_ioctl,      /* ioctl */
       NULL,		     /* coda_psdev_mmap */
       coda_psdev_open,       /* open */
       NULL,
@@ -361,6 +393,7 @@
 	}
 	memset(&coda_upc_comm, 0, sizeof(coda_upc_comm));
 	memset(&coda_super_info, 0, sizeof(coda_super_info));
+	coda_upc_comm.vc_waitq = NULL;
 
 	coda_sysctl_init();
 
@@ -375,7 +408,7 @@
 int init_module(void)
 {
 	int status;
-	printk(KERN_INFO "Coda Kernel/Venus communications (module), v5.0-pre1, braam@cs.cmu.edu.\n");
+	printk(KERN_INFO "Coda Kernel/Venus communications (module), v5.3.8, coda@cs.cmu.edu.\n");
 
 	status = init_coda_psdev();
 	if ( status ) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/stats.c linux.17p18/fs/coda/stats.c
--- linux.vanilla/fs/coda/stats.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/stats.c	Thu Jan  1 01:00:00 1970
@@ -1,416 +0,0 @@
-/*
- * stats.c
- * 
- * CODA operation statistics
- *
- * (c) March, 1998 Zhanyong Wan <zhanyong.wan@yale.edu>
- *
- */
-
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/sysctl.h>
-#include <linux/swapctl.h>
-#include <linux/proc_fs.h>
-#include <linux/malloc.h>
-#include <linux/stat.h>
-#include <linux/ctype.h>
-#include <asm/bitops.h>
-#include <asm/segment.h>
-#include <asm/uaccess.h>
-#include <linux/utsname.h>
-
-#include <linux/coda.h>
-#include <linux/coda_linux.h>
-#include <linux/coda_fs_i.h>
-#include <linux/coda_psdev.h>
-#include <linux/coda_cache.h>
-#include <linux/coda_proc.h>
-
-struct coda_vfs_stats		coda_vfs_stat;
-struct coda_permission_stats	coda_permission_stat;
-struct coda_cache_inv_stats	coda_cache_inv_stat;
-struct coda_upcall_stats_entry coda_upcall_stat[CODA_NCALLS];
-
-/* keep this in sync with coda.h! */
-char *coda_upcall_names[] = {
-	"totals      ",   /*  0 */
-	"noop        ",   /*  1 */
-	"root        ",   /*  2 */
-	"sync        ",   /*  3 */
-	"open        ",   /*  4 */
-	"close       ",   /*  5 */
-	"ioctl       ",   /*  6 */
-	"getattr     ",   /*  7 */
-	"setattr     ",   /*  8 */
-	"access      ",   /*  9 */
-	"lookup      ",   /* 10 */
-	"create      ",   /* 11 */
-	"remove      ",   /* 12 */
-	"link        ",   /* 13 */
-	"rename      ",   /* 14 */
-	"mkdir       ",   /* 15 */
-	"rmdir       ",   /* 16 */
-	"readdir     ",   /* 17 */
-	"symlink     ",   /* 18 */
-	"readlink    ",   /* 19 */
-	"fsync       ",   /* 20 */
-	"inactive    ",   /* 21 */
-	"vget        ",   /* 22 */
-	"signal      ",   /* 23 */
-	"replace     ",   /* 24 */
-	"flush       ",   /* 25 */
-	"purgeuser   ",   /* 26 */
-	"zapfile     ",   /* 27 */
-	"zapdir      ",   /* 28 */
-	"zapvnode    ",   /* 28 */
-	"purgefid    ",   /* 30 */
-	"open_by_path"    /* 31 */
-};
-
-
-
-
-void reset_coda_vfs_stats( void )
-{
-	memset( &coda_vfs_stat, 0, sizeof( coda_vfs_stat ) );
-}
-
-#if 0
-static void reset_upcall_entry( struct coda_upcall_stats_entry * pentry )
-{
-	pentry->count = 0;
-	pentry->time_sum = pentry->time_squared_sum = 0;
-}
-#endif
-
-void reset_coda_upcall_stats( void )
-{
-	memset( &coda_upcall_stat, 0, sizeof( coda_upcall_stat ) );
-}
-
-void reset_coda_permission_stats( void )
-{
-	memset( &coda_permission_stat, 0, sizeof( coda_permission_stat ) );
-}
-
-void reset_coda_cache_inv_stats( void )
-{
-	memset( &coda_cache_inv_stat, 0, sizeof( coda_cache_inv_stat ) );
-}
-
-
-void do_time_stats( struct coda_upcall_stats_entry * pentry, 
-		    unsigned long runtime )
-{
-	
-	unsigned long time = runtime * 1000 /HZ;	/* time in ms */
-	CDEBUG(D_SPECIAL, "time: %ld\n", time);
-
-	if ( pentry->count == 0 ) {
-		pentry->time_sum = pentry->time_squared_sum = 0;
-	}
-	
-	pentry->count++;
-	pentry->time_sum += time;
-	pentry->time_squared_sum += time*time;
-}
-
-
-
-void coda_upcall_stats(int opcode, long unsigned runtime) 
-{
-	struct coda_upcall_stats_entry * pentry;
-	
-	if ( opcode < 0 || opcode > CODA_NCALLS - 1) {
-		printk("Nasty opcode %d passed to coda_upcall_stats\n",
-		       opcode);
-		return;
-	}
-		
-	pentry = &coda_upcall_stat[opcode];
-	do_time_stats(pentry, runtime);
-
-        /* fill in the totals */
-	pentry = &coda_upcall_stat[0];
-	do_time_stats(pentry, runtime);
-
-}
-
-unsigned long get_time_average( const struct coda_upcall_stats_entry * pentry )
-{
-	return ( pentry->count == 0 ) ? 0 : pentry->time_sum / pentry->count;
-}
-
-static inline unsigned long absolute( unsigned long x )
-{
-	return x >= 0 ? x : -x;
-}
-
-static unsigned long sqr_root( unsigned long x )
-{
-	unsigned long y = x, r;
-	int n_bit = 0;
-  
-	if ( x == 0 )
-		return 0;
-	if ( x < 0)
-		x = -x;
-
-	while ( y ) {
-		y >>= 1;
-		n_bit++;
-	}
-  
-	r = 1 << (n_bit/2);
-  
-	while ( 1 ) {
-		r = (r + x/r)/2;
-		if ( r*r <= x && x < (r+1)*(r+1) )
-			break;
-	}
-  
-	return r;
-}
-
-unsigned long get_time_std_deviation( const struct coda_upcall_stats_entry * pentry )
-{
-	unsigned long time_avg;
-  
-	if ( pentry->count <= 1 )
-		return 0;
-  
-	time_avg = get_time_average( pentry );
-	return 
-	        sqr_root( (pentry->time_squared_sum / pentry->count) - 
-			    time_avg * time_avg );
-}
-
-int do_reset_coda_vfs_stats( ctl_table * table, int write, struct file * filp,
-			     void * buffer, size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_vfs_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int do_reset_coda_upcall_stats( ctl_table * table, int write, 
-				struct file * filp, void * buffer, 
-				size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_upcall_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int do_reset_coda_permission_stats( ctl_table * table, int write, 
-				    struct file * filp, void * buffer, 
-				    size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_permission_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int do_reset_coda_cache_inv_stats( ctl_table * table, int write, 
-				   struct file * filp, void * buffer, 
-				   size_t * lenp )
-{
-	if ( write ) {
-		reset_coda_cache_inv_stats();
-	}
-  
-	*lenp = 0;
-	return 0;
-}
-
-int coda_vfs_stats_get_info( char * buffer, char ** start, off_t offset,
-			     int length, int dummy )
-{
-	int len=0;
-	off_t begin;
-	struct coda_vfs_stats * ps = & coda_vfs_stat;
-  
-  /* this works as long as we are below 1024 characters! */
-	len += sprintf( buffer,
-			"Coda VFS statistics\n"
-			"===================\n\n"
-			"File Operations:\n"
-			"\tfile_read\t%9d\n"
-			"\tfile_write\t%9d\n"
-			"\tfile_mmap\t%9d\n"
-			"\topen\t\t%9d\n"
-			"\trelase\t\t%9d\n"
-			"\tfsync\t\t%9d\n\n"
-			"Dir Operations:\n"
-			"\treaddir\t\t%9d\n\n"
-			"Inode Operations\n"
-			"\tcreate\t\t%9d\n"
-			"\tlookup\t\t%9d\n"
-			"\tlink\t\t%9d\n"
-			"\tunlink\t\t%9d\n"
-			"\tsymlink\t\t%9d\n"
-			"\tmkdir\t\t%9d\n"
-			"\trmdir\t\t%9d\n"
-			"\trename\t\t%9d\n"
-			"\tpermission\t%9d\n"
-			"\treadpage\t%9d\n",
-
-			/* file operations */
-			ps->file_read,
-			ps->file_write,
-			ps->file_mmap,
-			ps->open,
-			ps->release,
-			ps->fsync,
-
-			/* dir operations */
-			ps->readdir,
-		  
-			/* inode operations */
-			ps->create,
-			ps->lookup,
-			ps->link,
-			ps->unlink,
-			ps->symlink,
-			ps->mkdir,
-			ps->rmdir,
-			ps->rename,
-			ps->permission,
-			ps->readpage );
-  
-	begin = offset;
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-
-	return len;
-}
-
-int coda_upcall_stats_get_info( char * buffer, char ** start, off_t offset,
-				int length, int dummy )
-{
-	int len=0;
-	int i;
-	off_t begin;
-	off_t pos = 0;
-	char tmpbuf[80];
-	int tmplen = 0;
-
-	ENTRY;
-	/* this works as long as we are below 1024 characters! */
-	if ( offset < 80 ) 
-		len += sprintf( buffer,"%-79s\n",	"Coda upcall statistics");
-	if ( offset < 160) 
-		len += sprintf( buffer + len,"%-79s\n",	"======================");
-	if ( offset < 240) 
-		len += sprintf( buffer + len,"%-79s\n",	"upcall\t\t    count\tavg time(ms)\tstd deviation(ms)");
-	if ( offset < 320) 
-		len += sprintf( buffer + len,"%-79s\n",	"------\t\t    -----\t------------\t-----------------");
-	pos = 320; 
-	for ( i = 0 ; i < CODA_NCALLS ; i++ ) {
-		tmplen += sprintf(tmpbuf,"%s\t%9d\t%10ld\t%10ld", 
-				  coda_upcall_names[i],
-				  coda_upcall_stat[i].count, 
-				  get_time_average(&coda_upcall_stat[i]),
-				  coda_upcall_stat[i].time_squared_sum);
-		pos += 80;
-		if ( pos < offset ) 
-			continue; 
-		len += sprintf(buffer + len, "%-79s\n", tmpbuf);
-		if ( len >= length ) 
-			break; 
-	}
-  
-	begin = len- (pos - offset);
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-	EXIT;
-	return len;
-}
-
-int coda_permission_stats_get_info( char * buffer, char ** start, off_t offset,
-				    int length, int dummy )
-{
-	int len=0;
-	off_t begin;
-	struct coda_permission_stats * ps = & coda_permission_stat;
-  
-	/* this works as long as we are below 1024 characters! */
-	len += sprintf( buffer,
-			"Coda permission statistics\n"
-			"==========================\n\n"
-			"count\t\t%9d\n"
-			"hit count\t%9d\n",
-
-			ps->count,
-			ps->hit_count );
-  
-	begin = offset;
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-
-	return len;
-}
-
-int coda_cache_inv_stats_get_info( char * buffer, char ** start, off_t offset,
-				   int length, int dummy )
-{
-	int len=0;
-	off_t begin;
-	struct coda_cache_inv_stats * ps = & coda_cache_inv_stat;
-  
-	/* this works as long as we are below 1024 characters! */
-	len += sprintf( buffer,
-			"Coda cache invalidation statistics\n"
-			"==================================\n\n"
-			"flush\t\t%9d\n"
-			"purge user\t%9d\n"
-			"zap_dir\t\t%9d\n"
-			"zap_file\t%9d\n"
-			"zap_vnode\t%9d\n"
-			"purge_fid\t%9d\n"
-			"replace\t\t%9d\n",
-			ps->flush,
-			ps->purge_user,
-			ps->zap_dir,
-			ps->zap_file,
-			ps->zap_vnode,
-			ps->purge_fid,
-			ps->replace );
-  
-	begin = offset;
-	*start = buffer + begin;
-	len -= begin;
-
-	if ( len > length )
-		len = length;
-	if ( len < 0 )
-		len = 0;
-
-	return len;
-}
-
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/coda/upcall.c linux.17p18/fs/coda/upcall.c
--- linux.vanilla/fs/coda/upcall.c	Fri Apr 21 12:46:41 2000
+++ linux.17p18/fs/coda/upcall.c	Wed Aug  9 22:23:26 2000
@@ -88,7 +88,7 @@
 		       fidp->Volume, fidp->Vnode);
 	}
 
-	if (inp)  CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         EXIT;
 	return error;
 }
@@ -110,8 +110,7 @@
 	if ( !error )
 	        *attr = outp->coda_getattr.attr;
 
-        if (inp) 
-		CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         EXIT;
         return error;
 }
@@ -132,7 +131,7 @@
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
         CDEBUG(D_SUPER, " result %d\n", error); 
-        if ( inp ) CODA_FREE(inp, insize);
+        CODA_FREE(inp, insize);
         return error;
 }
 
@@ -162,7 +161,7 @@
 	        *resfid = outp->coda_lookup.VFid;
 		*type = outp->coda_lookup.vtype;
 	}
-	if (inp) CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 		
 	return error;
 }
@@ -188,8 +187,7 @@
 
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-        if (inp) 
-		CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         return error;
 }
 
@@ -216,8 +214,7 @@
 		*dev = 0;
 	}
 
-        if (inp) 
-                CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 
 	return error;
 }	
@@ -247,8 +244,7 @@
 	*attrs = outp->coda_mkdir.attr;
 	*newfid = outp->coda_mkdir.VFid;
 
-	if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;        
 }
 
@@ -288,7 +284,7 @@
               (char *)inp + (int) inp->coda_rename.destname);
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-	if (inp) CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -321,8 +317,7 @@
 	*attrs = outp->coda_create.attr;
 	*newfid = outp->coda_create.VFid;
 
-	if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;        
 }
 
@@ -344,8 +339,7 @@
 	*((char *)inp + offset + length) = '\0';
         
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
-	if ( inp ) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -366,8 +360,7 @@
 	*((char *)inp + offset + length) = '\0';
         
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
-	if ( inp ) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -397,7 +390,7 @@
 		*(buffer + retlen) = '\0';
 	}
         
-        if (inp) CODA_FREE(inp, insize);
+        CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -427,8 +420,7 @@
         
         error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-        if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -465,8 +457,7 @@
 
 	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-        if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -485,8 +476,7 @@
         error = coda_upcall(coda_sbp(sb), sizeof(union inputArgs), 
                             &outsize, inp);
 
-	if ( inp ) 
-		CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -504,7 +494,7 @@
 
 	error = coda_upcall(coda_sbp(sb), insize, &outsize, inp);
 
-	if (inp) CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
         EXIT;
 	return error;
 }
@@ -575,8 +565,7 @@
         }
 
  exit:
-        if (inp) 
-	        CODA_FREE(inp, insize);
+	CODA_FREE(inp, insize);
 	return error;
 }
 
@@ -601,7 +590,7 @@
 		printk("coda_statfs: Venus returns: %d\n", error);
 	}
 
-        if (inp) CODA_FREE(inp, insize);
+        CODA_FREE(inp, insize);
         CDEBUG(D_INODE, " result %d\n",error);
         EXIT;
         return error;
@@ -614,7 +603,7 @@
 
 static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp)
 {
-	struct wait_queue	wait = { current, NULL };
+	struct wait_queue wait = { current, NULL };
 	struct timeval begin = { 0, 0 }, end = { 0, 0 };
 
 	vmp->uc_posttime = jiffies;
@@ -624,16 +613,20 @@
 
 	add_wait_queue(&vmp->uc_sleep, &wait);
 	for (;;) {
-		if ( coda_hard == 0 ) 
+		if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE ) 
 			current->state = TASK_INTERRUPTIBLE;
 		else
 			current->state = TASK_UNINTERRUPTIBLE;
 
+		/* venus died */
+		if ( !coda_upc_comm.vc_inuse )
+			break;
+
 		/* got a reply */
-		if ( vmp->uc_flags & REQ_WRITE )
+		if ( vmp->uc_flags & (REQ_WRITE | REQ_ABORT) )
 			break;
 
-		if ( !coda_hard && signal_pending(current) ) {
+		if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) {
 			/* if this process really wants to die, let it go */
 			if ( sigismember(&(current->signal), SIGKILL) ||
 			     sigismember(&(current->signal), SIGINT) )
@@ -644,7 +637,6 @@
 				break; 
 		}
 		schedule();
-
 	}
 	remove_wait_queue(&vmp->uc_sleep, &wait);
 	current->state = TASK_RUNNING;
@@ -689,7 +681,7 @@
 ENTRY;
 
 	vcommp = &coda_upc_comm;
-	if ( !vcommp->vc_pid ) {
+	if ( !vcommp->vc_inuse ) {
 		printk("No pseudo device in upcall comms at %p\n", vcommp);
                 return -ENXIO;
 	}
@@ -733,17 +725,12 @@
 	CDEBUG(D_UPCALL, 
 	       "..process %d woken up by Venus for req at %p, data at %p\n", 
 	       current->pid, req, req->uc_data);
-	if (vcommp->vc_pid) {      /* i.e. Venus is still alive */
+	if (vcommp->vc_inuse) {      /* i.e. Venus is still alive */
 	    /* Op went through, interrupt or not... */
 	    if (req->uc_flags & REQ_WRITE) {
 		out = (union outputArgs *)req->uc_data;
 		/* here we map positive Venus errors to kernel errors */
-		if ( out->oh.result < 0 ) {
-			printk("Tell Peter: Venus returns negative error %ld, for oc %ld!\n",
-			       out->oh.result, out->oh.opcode);
-			out->oh.result = EINTR;
-		}
-		error = -out->oh.result;
+		error = -(int)out->oh.result;
 		CDEBUG(D_UPCALL, 
 		       "upcall: (u,o,r) (%ld, %ld, %ld) out at %p\n", 
 		       out->oh.unique, out->oh.opcode, out->oh.result, out);
@@ -847,7 +834,7 @@
 
 	/* Handle invalidation requests. */
           if ( !sb || !sb->s_root || !sb->s_root->d_inode) { 
-	          printk("coda_downcall: opcode %d, no sb!\n", opcode);
+	          CDEBUG(D_DOWNCALL, "coda_downcall: opcode %d, no sb!\n", opcode);
 		  return 0; 
 	  }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/exec.c linux.17p18/fs/exec.c
--- linux.vanilla/fs/exec.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/fs/exec.c	Tue Aug  1 18:19:25 2000
@@ -561,7 +561,7 @@
 
 /* 
  * Fill the binprm structure from the inode. 
- * Check permissions, then read the first 512 bytes
+ * Check permissions, then read the first 128 bytes
  */
 int prepare_binprm(struct linux_binprm *bprm)
 {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ext2/acl.c linux.17p18/fs/ext2/acl.c
--- linux.vanilla/fs/ext2/acl.c	Fri Apr 21 12:46:42 2000
+++ linux.17p18/fs/ext2/acl.c	Tue Aug  1 07:59:06 2000
@@ -54,7 +54,7 @@
 	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
 		return 0;
 	if ((mask == S_IROTH) ||
-	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+	    (S_ISDIR(inode->i_mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
 		if (capable(CAP_DAC_READ_SEARCH))
 			return 0;
 	return -EACCES;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ext2/namei.c linux.17p18/fs/ext2/namei.c
--- linux.vanilla/fs/ext2/namei.c	Fri Apr 21 12:46:42 2000
+++ linux.17p18/fs/ext2/namei.c	Tue Aug  1 07:59:06 2000
@@ -418,6 +418,10 @@
 		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
 					      EXT2_FEATURE_INCOMPAT_FILETYPE))
 			de->file_type = EXT2_FT_REG_FILE;
+	} else if (S_ISSOCK(inode->i_mode)) {
+		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
+					      EXT2_FEATURE_INCOMPAT_FILETYPE))
+			de->file_type = EXT2_FT_SOCK;
 	} else if (S_ISCHR(inode->i_mode)) {
 		inode->i_op = &chrdev_inode_operations;
 		if (EXT2_HAS_INCOMPAT_FEATURE(dir->i_sb,
@@ -793,6 +797,8 @@
 			de->file_type = EXT2_FT_DIR;
 		else if (S_ISLNK(inode->i_mode))
 			de->file_type = EXT2_FT_SYMLINK;
+		else if (S_ISSOCK(inode->i_mode))  
+			de->file_type = EXT2_FT_SOCK;
 		else if (S_ISCHR(inode->i_mode))
 			de->file_type = EXT2_FT_CHRDEV;
 		else if (S_ISBLK(inode->i_mode))
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ext2/super.c linux.17p18/fs/ext2/super.c
--- linux.vanilla/fs/ext2/super.c	Fri Apr 21 12:46:42 2000
+++ linux.17p18/fs/ext2/super.c	Tue Aug  1 07:59:06 2000
@@ -184,7 +184,7 @@
 		else if (!strcmp (this_char, "errors")) {
 			if (!value || !*value) {
 				printk ("EXT2-fs: the errors option requires "
-					"an argument");
+					"an argument\n");
 				return 0;
 			}
 			if (!strcmp (value, "continue")) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/isofs/dir.c linux.17p18/fs/isofs/dir.c
--- linux.vanilla/fs/isofs/dir.c	Fri Apr 21 12:46:43 2000
+++ linux.17p18/fs/isofs/dir.c	Tue Aug  1 07:59:07 2000
@@ -7,6 +7,9 @@
  *
  *  Steve Beynon		       : Missing last directory entries fixed
  *  (stephen@askone.demon.co.uk)      : 21st June 1996
+ *
+ *  Go Taniguchi			: Move sector and boundarie error fixed
+ *  (go@turbolinux.co.jp)		: Jul 21 2000
  * 
  *  isofs directory handling functions
  */
@@ -160,9 +163,11 @@
 		de = (struct iso_directory_record *) (bh->b_data + offset);
 		if(first_de) inode_number = (block << bufbits) + (offset & (bufsize - 1));
 
-		de_len = *(unsigned char *) de;
+		/* Check boundaries and get length. by GO! */
+		if (offset < bufsize) de_len = *(unsigned char *) de;
 #ifdef DEBUG
-		printk("de_len = %ld\n", de_len);
+		if (offset < bufsize) printk("de_len = %ld\n", de_len);
+		else printk("Move to next sector\n");
 #endif
 	    
 
@@ -170,15 +175,15 @@
 		   CDROM sector.  If we are at the end of the directory, we
 		   kick out of the while loop. */
 
-		if ((de_len == 0) || (offset >= bufsize) ) {
+		if ((offset >= bufsize) || (de_len == 0) ) {
 			brelse(bh);
-			if (de_len == 0) {
+			if (offset >= bufsize) {	/*Check first. by GO!*/
+				offset -= bufsize;
+				filp->f_pos += offset;
+			} else {
 				filp->f_pos = ((filp->f_pos & ~(ISOFS_BLOCK_SIZE - 1))
 					       + ISOFS_BLOCK_SIZE);
 				offset = 0;
-			} else {
-				offset -= bufsize;
-				filp->f_pos += offset;
 			}
 
 			if (filp->f_pos >= inode->i_size)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/isofs/inode.c linux.17p18/fs/isofs/inode.c
--- linux.vanilla/fs/isofs/inode.c	Sun Jun 11 21:44:18 2000
+++ linux.17p18/fs/isofs/inode.c	Tue Aug  1 07:59:07 2000
@@ -915,7 +915,7 @@
 	 * If we are beyond the end of this file, don't give out any
 	 * blocks.
 	 */
-	if( b_off > inode->i_size )
+	if( b_off >= inode->i_size )
 	  {
 	    off_t	max_legal_read_offset;
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/lockd/svc.c linux.17p18/fs/lockd/svc.c
--- linux.vanilla/fs/lockd/svc.c	Fri Apr 21 12:46:43 2000
+++ linux.17p18/fs/lockd/svc.c	Tue Aug  1 07:59:07 2000
@@ -236,7 +236,10 @@
 	}
 
 	if ((error = svc_makesock(serv, IPPROTO_UDP, 0)) < 0 
-	 || (error = svc_makesock(serv, IPPROTO_TCP, 0)) < 0) {
+#ifdef CONFIG_NFSD_TCP
+	 || (error = svc_makesock(serv, IPPROTO_TCP, 0)) < 0
+#endif
+		) {
 		if (warned++ == 0) 
 			printk(KERN_WARNING
 				"lockd_up: makesock failed, error=%d\n", error);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/namei.c linux.17p18/fs/namei.c
--- linux.vanilla/fs/namei.c	Fri Apr 21 12:46:44 2000
+++ linux.17p18/fs/namei.c	Tue Aug  1 07:59:23 2000
@@ -155,7 +155,7 @@
 		return 0;
 	/* read and search access */
 	if ((mask == S_IROTH) ||
-	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+	    (S_ISDIR(inode->i_mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
 		if (capable(CAP_DAC_READ_SEARCH))
 			return 0;
 	return -EACCES;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ncpfs/ncplib_kernel.h linux.17p18/fs/ncpfs/ncplib_kernel.h
--- linux.vanilla/fs/ncpfs/ncplib_kernel.h	Sun Jun 11 21:44:19 2000
+++ linux.17p18/fs/ncpfs/ncplib_kernel.h	Wed Aug  9 22:52:47 2000
@@ -130,7 +130,7 @@
 		nc[0] = toupperif(*np, case_trans);
 		nc[1] = 0x00;
 		nls_in->char2uni(nc, &len, &uc.uni2, &uc.uni1);
-		nls_out->uni2char(0x00, uc.uni2, np, 1, &len);
+		nls_out->uni2char(uc.uni1, uc.uni2, np, 1, &len);
 		np++;
 	}
 }
@@ -154,7 +154,7 @@
 		nc[0] = *np;
 		nc[1] = 0;
 		nls_in->char2uni(nc, &len, &uc.uni2, &uc.uni1);
-		nls_out->uni2char(0x00, uc.uni2, nc, 1, &len);
+		nls_out->uni2char(uc.uni1, uc.uni2, nc, 1, &len);
 		*np = tolowerif(nc[0], case_trans);
 		np++;
 	}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/nls/nls_base.c linux.17p18/fs/nls/nls_base.c
--- linux.vanilla/fs/nls/nls_base.c	Sun Jun 11 21:44:19 2000
+++ linux.17p18/fs/nls/nls_base.c	Tue Aug  1 07:59:07 2000
@@ -514,6 +514,7 @@
 	init_nls_cp874();
 #endif
 #ifdef CONFIG_NLS_CODEPAGE_932
+	init_nls_euc_jp();
 	init_nls_cp932();
 #endif
 #ifdef CONFIG_NLS_CODEPAGE_936
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/nls/nls_cp932.c linux.17p18/fs/nls/nls_cp932.c
--- linux.vanilla/fs/nls/nls_cp932.c	Sun Jun 11 21:44:19 2000
+++ linux.17p18/fs/nls/nls_cp932.c	Tue Aug  1 07:59:08 2000
@@ -2,7 +2,9 @@
  * linux/fs/nls_cp932.c
  *
  * Charset cp932 translation tables.
- * Generated automatically from the Microsoft
+ * This translation table was generated automatically, the
+ * original table can be download from the Microsoft website.
+ * (http://www.microsoft.com/typography/unicode/unicodecp.htm)
  */
 
 #include <linux/module.h>
@@ -2889,7 +2891,7 @@
 	{0x21, 0x78}, {0x21, 0x79}, {0x21, 0x60}, {0x21, 0x61}, /* 0x48-0x4B */
 	{0x21, 0x62}, {0x21, 0x63}, {0x21, 0x64}, {0x21, 0x65}, /* 0x4C-0x4F */
 	{0x21, 0x66}, {0x21, 0x67}, {0x21, 0x68}, {0x21, 0x69}, /* 0x50-0x53 */
-	{0xFF, 0xE2}, {0xFF, 0xE4}, {0xFF, 0x07}, {0xFF, 0x02}, /* 0x54-0x57 */
+	{0x00, 0x3F}, {0xFF, 0xE4}, {0xFF, 0x07}, {0xFF, 0x02}, /* 0x54-0x57 */
 	{0x32, 0x31}, {0x21, 0x16}, {0x21, 0x21}, {0x22, 0x35}, /* 0x58-0x5B */
 	{0x7E, 0x8A}, {0x89, 0x1C}, {0x93, 0x48}, {0x92, 0x88}, /* 0x5C-0x5F */
 	{0x84, 0xDC}, {0x4F, 0xC9}, {0x70, 0xBB}, {0x66, 0x31}, /* 0x60-0x63 */
@@ -3144,21 +3146,21 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x83, 0x9F, 0x83, 0x00, 0x83, 0x00, /* 0x90-0x93 */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0x94-0x97 */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0x98-0x9B */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0x9C-0x9F */
-	0x83, 0x00, 0x83, 0x00, 0x3F, 0x3F, 0x83, 0x00, /* 0xA0-0xA3 */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0xA4-0xA7 */
-	0x83, 0x00, 0x83, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x83, 0x9F, 0x83, 0xA0, 0x83, 0xA1, /* 0x90-0x93 */
+	0x83, 0xA2, 0x83, 0xA3, 0x83, 0xA4, 0x83, 0xA5, /* 0x94-0x97 */
+	0x83, 0xA6, 0x83, 0xA7, 0x83, 0xA8, 0x83, 0xA9, /* 0x98-0x9B */
+	0x83, 0xAA, 0x83, 0xAB, 0x83, 0xAC, 0x83, 0xAD, /* 0x9C-0x9F */
+	0x83, 0xAE, 0x83, 0xAF, 0x3F, 0x3F, 0x83, 0xB0, /* 0xA0-0xA3 */
+	0x83, 0xB1, 0x83, 0xB2, 0x83, 0xB3, 0x83, 0xB4, /* 0xA4-0xA7 */
+	0x83, 0xB5, 0x83, 0xB6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0xB0-0xB3 */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0xB4-0xB7 */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0xB8-0xBB */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0xBC-0xBF */
-	0x83, 0x00, 0x83, 0x00, 0x3F, 0x3F, 0x83, 0x00, /* 0xC0-0xC3 */
-	0x83, 0x00, 0x83, 0x00, 0x83, 0x00, 0x83, 0x00, /* 0xC4-0xC7 */
-	0x83, 0x00, 0x83, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x83, 0xBF, 0x83, 0xC0, 0x83, 0xC1, /* 0xB0-0xB3 */
+	0x83, 0xC2, 0x83, 0xC3, 0x83, 0xC4, 0x83, 0xC5, /* 0xB4-0xB7 */
+	0x83, 0xC6, 0x83, 0xC7, 0x83, 0xC8, 0x83, 0xC9, /* 0xB8-0xBB */
+	0x83, 0xCA, 0x83, 0xCB, 0x83, 0xCC, 0x83, 0xCD, /* 0xBC-0xBF */
+	0x83, 0xCE, 0x83, 0xCF, 0x3F, 0x3F, 0x83, 0xD0, /* 0xC0-0xC3 */
+	0x83, 0xD1, 0x83, 0xD2, 0x83, 0xD3, 0x83, 0xD4, /* 0xC4-0xC7 */
+	0x83, 0xD5, 0x83, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
@@ -3251,13 +3253,13 @@
 	0x3F, 0x3F, 0x81, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x81, 0x65, 0x81, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x81, 0x67, 0x81, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x81, 0x00, 0x81, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x81, 0xF5, 0x81, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x81, 0x64, 0x81, 0x63, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x81, 0x00, 0x3F, 0x3F, 0x81, 0x8C, 0x81, 0x8D, /* 0x30-0x33 */
+	0x81, 0xF1, 0x3F, 0x3F, 0x81, 0x8C, 0x81, 0x8D, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xA6, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
@@ -3316,12 +3318,12 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x59, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xFA, 0x59, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xFA, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xF0, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
@@ -3335,20 +3337,20 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x00, 0x4A, 0x00, 0x4B, 0x00, 0x4C, 0x00, 0x4D, /* 0x60-0x63 */
-	0x00, 0x4E, 0x00, 0x4F, 0x00, 0x50, 0x00, 0x51, /* 0x64-0x67 */
-	0x00, 0x52, 0x00, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0xFA, 0x4A, 0xFA, 0x4B, 0xFA, 0x4C, 0xFA, 0x4D, /* 0x60-0x63 */
+	0xFA, 0x4E, 0xFA, 0x4F, 0xFA, 0x50, 0xFA, 0x51, /* 0x64-0x67 */
+	0xFA, 0x52, 0xFA, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x40, 0x00, 0x41, 0x00, 0x42, 0x00, 0x43, /* 0x70-0x73 */
-	0x00, 0x44, 0x00, 0x45, 0x00, 0x46, 0x00, 0x47, /* 0x74-0x77 */
-	0x00, 0x48, 0x00, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xEE, 0xEF, 0xEE, 0xF0, 0xEE, 0xF1, 0xEE, 0xF2, /* 0x70-0x73 */
+	0xEE, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0xEE, 0xF6, /* 0x74-0x77 */
+	0xEE, 0xF7, 0xEE, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x81, 0x00, 0x81, 0x00, 0x81, 0x00, 0x81, 0x00, /* 0x90-0x93 */
+	0x81, 0xA9, 0x81, 0xAA, 0x81, 0xA8, 0x81, 0xAB, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
@@ -3364,8 +3366,8 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x81, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xCB, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x81, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
@@ -3379,22 +3381,22 @@
 };
 
 static unsigned char u2c_22[512] = {
-	0x81, 0x00, 0x3F, 0x3F, 0x81, 0x00, 0x81, 0x00, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, /* 0x04-0x07 */
-	0x81, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, /* 0x08-0x0B */
+	0x81, 0xCD, 0x3F, 0x3F, 0x81, 0xDD, 0x81, 0xCE, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xDE, /* 0x04-0x07 */
+	0x81, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xB9, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x87, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x87, 0x95, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x81, 0x00, 0x81, 0x87, 0x87, 0x98, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x81, 0xE5, 0x81, 0x87, 0x87, 0x98, /* 0x1C-0x1F */
 	0x87, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x81, 0x61, 0x3F, 0x3F, 0x81, 0x00, /* 0x24-0x27 */
-	0x81, 0x00, 0x87, 0x9B, 0x87, 0x9C, 0x87, 0x92, /* 0x28-0x2B */
-	0x81, 0x00, 0x3F, 0x3F, 0x87, 0x93, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x81, 0x61, 0x3F, 0x3F, 0x81, 0xC8, /* 0x24-0x27 */
+	0x81, 0xC9, 0x87, 0x9B, 0x87, 0x9C, 0x87, 0x92, /* 0x28-0x2B */
+	0x81, 0xE8, 0x3F, 0x3F, 0x87, 0x93, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x81, 0x88, 0x00, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x81, 0x88, 0xFA, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x81, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x81, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
@@ -3405,15 +3407,15 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x81, 0x82, 0x87, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x85, 0x81, 0x86, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x81, 0x00, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xE1, 0x81, 0xE2, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x81, 0x00, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x81, 0x00, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xBC, 0x81, 0xBD, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xBA, 0x81, 0xBB, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
@@ -3451,7 +3453,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xDC, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
@@ -3583,25 +3585,25 @@
 };
 
 static unsigned char u2c_25[512] = {
-	0x84, 0x9F, 0x84, 0x00, 0x84, 0x00, 0x84, 0x00, /* 0x00-0x03 */
+	0x84, 0x9F, 0x84, 0xAA, 0x84, 0xA0, 0x84, 0xAB, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x0C-0x0F */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x10-0x13 */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x14-0x17 */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x18-0x1B */
-	0x84, 0x00, 0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x20-0x23 */
-	0x84, 0x00, 0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x28-0x2B */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x2C-0x2F */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x30-0x33 */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x34-0x37 */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x38-0x3B */
-	0x84, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x84, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xAC, /* 0x0C-0x0F */
+	0x84, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xAD, /* 0x10-0x13 */
+	0x84, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xAF, /* 0x14-0x17 */
+	0x84, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xAE, /* 0x18-0x1B */
+	0x84, 0xA5, 0x84, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x84, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB0, /* 0x20-0x23 */
+	0x84, 0xA7, 0x84, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x84, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB2, /* 0x28-0x2B */
+	0x84, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB6, /* 0x2C-0x2F */
+	0x84, 0xBB, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB1, /* 0x30-0x33 */
+	0x84, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB8, /* 0x34-0x37 */
+	0x84, 0xBD, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB3, /* 0x38-0x3B */
+	0x84, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB9, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xBE, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0x00, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x84, 0xB4, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
@@ -3624,14 +3626,14 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x81, 0x00, 0x81, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x81, 0xA1, 0x81, 0xA0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x81, 0x00, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xA3, 0x81, 0xA2, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x81, 0x00, 0x81, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x81, 0xA5, 0x81, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x9F, 0x81, 0x9E, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x9B, /* 0xC8-0xCB */
@@ -3643,7 +3645,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xFC, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
@@ -3677,8 +3679,8 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x00, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x81, 0x00, 0x3F, 0x3F, 0x81, 0x00, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0xF4, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x81, 0xF3, 0x3F, 0x3F, 0x81, 0xF2, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
@@ -3723,7 +3725,7 @@
 	0x3F, 0x3F, 0x81, 0x58, 0x81, 0x59, 0x81, 0x5A, /* 0x04-0x07 */
 	0x81, 0x71, 0x81, 0x72, 0x81, 0x73, 0x81, 0x74, /* 0x08-0x0B */
 	0x81, 0x75, 0x81, 0x76, 0x81, 0x77, 0x81, 0x78, /* 0x0C-0x0F */
-	0x81, 0x79, 0x81, 0x7A, 0x81, 0x00, 0x81, 0x00, /* 0x10-0x13 */
+	0x81, 0x79, 0x81, 0x7A, 0x81, 0xA7, 0x81, 0xAC, /* 0x10-0x13 */
 	0x81, 0x6B, 0x81, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x87, 0x80, 0x3F, 0x3F, 0x87, 0x81, /* 0x1C-0x1F */
@@ -3735,29 +3737,29 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x82, 0x9F, 0x82, 0x00, 0x82, 0x00, /* 0x40-0x43 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x44-0x47 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x48-0x4B */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x4C-0x4F */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x50-0x53 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x54-0x57 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x58-0x5B */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x5C-0x5F */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x60-0x63 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x64-0x67 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x68-0x6B */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x6C-0x6F */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x70-0x73 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x74-0x77 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x78-0x7B */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x7C-0x7F */
-	
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x80-0x83 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x84-0x87 */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x88-0x8B */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x8C-0x8F */
-	0x82, 0x00, 0x82, 0x00, 0x82, 0x00, 0x82, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x82, 0x9F, 0x82, 0xA0, 0x82, 0xA1, /* 0x40-0x43 */
+	0x82, 0xA2, 0x82, 0xA3, 0x82, 0xA4, 0x82, 0xA5, /* 0x44-0x47 */
+	0x82, 0xA6, 0x82, 0xA7, 0x82, 0xA8, 0x82, 0xA9, /* 0x48-0x4B */
+	0x82, 0xAA, 0x82, 0xAB, 0x82, 0xAC, 0x82, 0xAD, /* 0x4C-0x4F */
+	0x82, 0xAE, 0x82, 0xAF, 0x82, 0xB0, 0x82, 0xB1, /* 0x50-0x53 */
+	0x82, 0xB2, 0x82, 0xB3, 0x82, 0xB4, 0x82, 0xB5, /* 0x54-0x57 */
+	0x82, 0xB6, 0x82, 0xB7, 0x82, 0xB8, 0x82, 0xB9, /* 0x58-0x5B */
+	0x82, 0xBA, 0x82, 0xBB, 0x82, 0xBC, 0x82, 0xBD, /* 0x5C-0x5F */
+	0x82, 0xBE, 0x82, 0xBF, 0x82, 0xC0, 0x82, 0xC1, /* 0x60-0x63 */
+	0x82, 0xC2, 0x82, 0xC3, 0x82, 0xC4, 0x82, 0xC5, /* 0x64-0x67 */
+	0x82, 0xC6, 0x82, 0xC7, 0x82, 0xC8, 0x82, 0xC9, /* 0x68-0x6B */
+	0x82, 0xCA, 0x82, 0xCB, 0x82, 0xCC, 0x82, 0xCD, /* 0x6C-0x6F */
+	0x82, 0xCE, 0x82, 0xCF, 0x82, 0xD0, 0x82, 0xD1, /* 0x70-0x73 */
+	0x82, 0xD2, 0x82, 0xD3, 0x82, 0xD4, 0x82, 0xD5, /* 0x74-0x77 */
+	0x82, 0xD6, 0x82, 0xD7, 0x82, 0xD8, 0x82, 0xD9, /* 0x78-0x7B */
+	0x82, 0xDA, 0x82, 0xDB, 0x82, 0xDC, 0x82, 0xDD, /* 0x7C-0x7F */
+	
+	0x82, 0xDE, 0x82, 0xDF, 0x82, 0xE0, 0x82, 0xE1, /* 0x80-0x83 */
+	0x82, 0xE2, 0x82, 0xE3, 0x82, 0xE4, 0x82, 0xE5, /* 0x84-0x87 */
+	0x82, 0xE6, 0x82, 0xE7, 0x82, 0xE8, 0x82, 0xE9, /* 0x88-0x8B */
+	0x82, 0xEA, 0x82, 0xEB, 0x82, 0xEC, 0x82, 0xED, /* 0x8C-0x8F */
+	0x82, 0xEE, 0x82, 0xEF, 0x82, 0xF0, 0x82, 0xF1, /* 0x90-0x93 */
+	0x83, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x81, 0x4A, /* 0x98-0x9B */
 	0x81, 0x4B, 0x81, 0x54, 0x81, 0x55, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x83, 0x40, 0x83, 0x41, 0x83, 0x42, /* 0xA0-0xA3 */
@@ -3799,7 +3801,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x58, 0x87, 0x8B, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0xFA, 0x58, 0x87, 0x8B, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x87, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
@@ -3923,502 +3925,502 @@
 };
 
 static unsigned char u2c_4E[512] = {
-	0x88, 0x00, 0x92, 0x9A, 0x3F, 0x3F, 0x8E, 0x00, /* 0x00-0x03 */
+	0x88, 0xEA, 0x92, 0x9A, 0x3F, 0x3F, 0x8E, 0xB5, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x9C, /* 0x04-0x07 */
-	0x8F, 0x00, 0x8E, 0x4F, 0x8F, 0x00, 0x89, 0x00, /* 0x08-0x0B */
+	0x8F, 0xE4, 0x8E, 0x4F, 0x8F, 0xE3, 0x89, 0xBA, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x95, 0x73, 0x97, 0x5E, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x98, 0x00, 0x89, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x8A, 0x8E, 0x98, 0x00, 0x90, 0x00, 0x99, 0x00, /* 0x14-0x17 */
-	0x8B, 0x75, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x00, 0x68, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x98, 0xA0, 0x89, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x8A, 0x8E, 0x98, 0xA1, 0x90, 0xA2, 0x99, 0xC0, /* 0x14-0x17 */
+	0x8B, 0x75, 0x95, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xE5, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x97, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xC0, 0x3F, 0x3F, /* 0x24-0x27 */
+	0xED, 0x4C, 0x3F, 0x3F, 0x98, 0xA2, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x92, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x98, 0x00, 0x8B, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x8A, 0x00, 0x92, 0x4F, 0x3F, 0x3F, 0x8E, 0x00, /* 0x38-0x3B */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x94, 0x54, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x98, 0xA3, 0x8B, 0xF8, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xA4, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x8A, 0xDB, 0x92, 0x4F, 0x3F, 0x3F, 0x8E, 0xE5, /* 0x38-0x3B */
+	0x98, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xA6, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xA7, 0x94, 0x54, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x8B, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x56, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x93, 0x00, 0x8C, 0x00, 0x96, 0x52, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x93, 0xE1, 0x8C, 0xC1, 0x96, 0x52, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x68, 0x98, 0x00, 0x8F, 0x00, /* 0x54-0x57 */
-	0x98, 0x00, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x8B, 0x00, 0x8C, 0x00, 0x96, 0x00, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0xE5, 0x68, 0x98, 0xA8, 0x8F, 0xE6, /* 0x54-0x57 */
+	0x98, 0xA9, 0x89, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x8B, 0xE3, 0x8C, 0xEE, 0x96, 0xE7, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xA4, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x97, 0x90, 0x3F, 0x3F, 0x93, 0x00, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x97, 0x90, 0x3F, 0x3F, 0x93, 0xFB, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xA3, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x8B, 0x54, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x98, 0x00, 0x97, 0x00, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x97, 0x5C, 0x91, 0x88, 0x98, 0x00, 0x8E, 0x96, /* 0x88-0x8B */
-	0x93, 0x00, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x89, 0x5D, 0x8C, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x8C, 0x00, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x98, 0x6A, 0x98, 0x69, 0x3F, 0x3F, 0x8D, 0x00, /* 0x98-0x9B */
-	0x88, 0x9F, 0x3F, 0x3F, 0x98, 0x00, 0x98, 0x00, /* 0x9C-0x9F */
-	0x98, 0x00, 0x96, 0x53, 0x98, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x8C, 0x00, 0x88, 0x00, 0x96, 0x92, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x8B, 0x54, 0x3F, 0x3F, 0x98, 0xAA, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x98, 0xAB, 0x97, 0xB9, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x97, 0x5C, 0x91, 0x88, 0x98, 0xAD, 0x8E, 0x96, /* 0x88-0x8B */
+	0x93, 0xF1, 0x3F, 0x3F, 0x98, 0xB0, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x89, 0x5D, 0x8C, 0xDD, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x8C, 0xDC, 0x88, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x98, 0x6A, 0x98, 0x69, 0x3F, 0x3F, 0x8D, 0xB1, /* 0x98-0x9B */
+	0x88, 0x9F, 0x3F, 0x3F, 0x98, 0xB1, 0x98, 0xB2, /* 0x9C-0x9F */
+	0x98, 0xB3, 0x96, 0x53, 0x98, 0xB4, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x8C, 0xF0, 0x88, 0xE5, 0x96, 0x92, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x8B, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x9D, /* 0xA8-0xAB */
-	0x8B, 0x9E, 0x92, 0x00, 0x97, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x8B, 0x9E, 0x92, 0xE0, 0x97, 0xBA, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x98, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xB6, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xB7, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x6C, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x8F, 0x59, 0x90, 0x6D, 0x98, 0x00, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x98, 0x00, 0x3F, 0x3F, 0x98, 0x00, 0x8B, 0x77, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x89, 0x00, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x98, 0x00, 0x98, 0x00, 0x95, 0x00, /* 0xCC-0xCF */
+	0x8F, 0x59, 0x90, 0x6D, 0x98, 0xBC, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x98, 0xBA, 0x3F, 0x3F, 0x98, 0xBB, 0x8B, 0x77, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xA1, 0x89, 0xEE, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x98, 0xB9, 0x98, 0xB8, 0x95, 0xA7, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x8E, 0x65, 0x8E, 0x64, 0x91, 0x00, 0x98, 0x00, /* 0xD4-0xD7 */
-	0x95, 0x74, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x81, 0x57, 0x98, 0x00, 0x98, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x69, 0x3F, 0x3F, 0x91, 0x00, /* 0xE0-0xE3 */
-	0x97, 0x00, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x98, 0x00, 0x89, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x8B, 0x00, 0x3F, 0x3F, 0x92, 0x87, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x8F, 0x98, 0x00, /* 0xF4-0xF7 */
+	0x8E, 0x65, 0x8E, 0x64, 0x91, 0xBC, 0x98, 0xBD, /* 0xD4-0xD7 */
+	0x95, 0x74, 0x90, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x81, 0x57, 0x98, 0xBE, 0x98, 0xC0, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0xED, 0x4D, 0x3F, 0x3F, 0x91, 0xE3, /* 0xE0-0xE3 */
+	0x97, 0xDF, 0x88, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x98, 0xBF, 0x89, 0xBC, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x8B, 0xC2, 0x3F, 0x3F, 0x92, 0x87, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x8F, 0x98, 0xC1, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x43, /* 0xF8-0xFB */
-	0x00, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xED, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_4F[512] = {
-	0x00, 0x6B, 0x8A, 0x00, 0x3F, 0x3F, 0x00, 0x6C, /* 0x00-0x03 */
+	0xED, 0x4F, 0x8A, 0xE9, 0x3F, 0x3F, 0xED, 0x50, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x98, 0x00, 0x88, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x8C, 0x00, 0x8A, 0x00, 0x95, 0x9A, /* 0x0C-0x0F */
-	0x94, 0x00, 0x8B, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x98, 0xC2, 0x88, 0xC9, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x8C, 0xDE, 0x8A, 0xEA, 0x95, 0x9A, /* 0x0C-0x0F */
+	0x94, 0xB0, 0x8B, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x98, 0x00, 0x93, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xEF, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x98, 0xE5, 0x93, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x8C, /* 0x2C-0x2F */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x94, 0x00, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x90, 0x4C, 0x00, 0x6D, 0x8E, 0x66, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x8E, 0x97, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x41, 0x98, 0x00, /* 0x44-0x47 */
+	0x98, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x94, 0xBA, 0x3F, 0x3F, 0x97, 0xE0, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x90, 0x4C, 0xED, 0x51, 0x8E, 0x66, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x8E, 0x97, 0x89, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xCF, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x41, 0x98, 0xC8, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x88, 0x00, 0x92, 0x00, 0x8F, 0x5A, /* 0x4C-0x4F */
-	0x8D, 0x00, 0x97, 0x43, 0x3F, 0x3F, 0x91, 0x00, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x89, 0x00, 0x00, 0x6E, 0x98, 0x00, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x97, 0x5D, 0x98, 0x00, 0x98, 0x00, /* 0x58-0x5B */
-	0x8D, 0x00, 0x98, 0x00, 0x9B, 0x43, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x88, 0xCA, 0x92, 0xE1, 0x8F, 0x5A, /* 0x4C-0x4F */
+	0x8D, 0xB2, 0x97, 0x43, 0x3F, 0x3F, 0x91, 0xCC, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x89, 0xBD, 0xED, 0x52, 0x98, 0xC7, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x97, 0x5D, 0x98, 0xC3, 0x98, 0xC5, /* 0x58-0x5B */
+	0x8D, 0xEC, 0x98, 0xC6, 0x9B, 0x43, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, /* 0x6C-0x6F */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x95, 0x00, 0x98, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, /* 0x78-0x7B */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x67, /* 0x7C-0x7F */
-	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x98, 0x00, 0x3F, 0x3F, 0x00, 0x70, 0x97, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x8E, 0x98, 0x3F, 0x3F, 0x98, 0x00, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x98, 0x00, 0x00, 0x6F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x72, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x98, 0x00, 0x3F, 0x3F, 0x00, 0x71, 0x8B, 0x9F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x8B, 0x00, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x98, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xD1, /* 0x6C-0x6F */
+	0x98, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xC0, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x95, 0xB9, 0x98, 0xC9, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xCD, /* 0x78-0x7B */
+	0x8C, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x67, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xA4, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xD2, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x98, 0xCA, 0x3F, 0x3F, 0xED, 0x54, 0x97, 0xE1, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x8E, 0x98, 0x3F, 0x3F, 0x98, 0xCB, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x98, 0xD0, 0xED, 0x53, 0x3F, 0x3F, /* 0x90-0x93 */
+	0xED, 0x56, 0x3F, 0x3F, 0x98, 0xD3, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x98, 0xCC, 0x3F, 0x3F, 0xED, 0x55, 0x8B, 0x9F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x88, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x8B, 0xA0, 0x89, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x44, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x96, 0x99, 0x95, 0x8E, 0x8C, 0x00, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x96, 0x99, 0x95, 0x8E, 0x8C, 0xF2, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x90, 0x4E, 0x97, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x90, 0x4E, 0x97, 0xB5, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x57, 0x91, 0x00, /* 0xC0-0xC3 */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x00, 0x61, 0x8F, 0x72, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x73, 0x98, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x98, 0x00, 0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0xD4-0xD7 */
-	0x98, 0x00, 0x3F, 0x3F, 0x98, 0x00, 0x98, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x98, 0x00, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xD6, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x57, 0x91, 0xA3, /* 0xC0-0xC3 */
+	0x89, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0xED, 0x45, 0x8F, 0x72, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xED, 0x57, 0x98, 0xD7, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x98, 0xDC, 0x98, 0xDA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x98, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xAD, /* 0xD4-0xD7 */
+	0x98, 0xD8, 0x3F, 0x3F, 0x98, 0xDB, 0x98, 0xD9, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x95, 0xDB, 0x3F, 0x3F, 0x98, 0xD6, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x90, 0x4D, 0x3F, 0x3F, 0x96, 0x93, /* 0xE0-0xE3 */
-	0x98, 0x00, 0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x98, 0xDD, 0x98, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x43, 0x98, 0x00, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x43, 0x98, 0xEB, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x6F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x95, 0x55, 0x98, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x95, 0x00, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x00, 0x76, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x95, 0x55, 0x98, 0xE6, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x95, 0xEE, 0x3F, 0x3F, 0x89, 0xB4, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xEA, 0xED, 0x5A, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_50[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x98, 0x00, 0x98, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x91, 0x71, 0x3F, 0x3F, 0x8C, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x94, 0x7B, 0x3F, 0x3F, 0x00, 0x00, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x98, 0x00, 0x93, 0x7C, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x98, 0x00, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x98, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x77, 0x8E, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x98, 0x00, 0x00, 0x75, 0x95, 0x00, /* 0x20-0x23 */
-	0x92, 0x6C, 0x98, 0x00, 0x8C, 0x91, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x98, 0x00, 0x98, 0x00, 0x98, 0x00, 0x97, 0x00, /* 0x28-0x2B */
-	0x98, 0x00, 0x98, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x98, 0xE4, 0x98, 0xED, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x91, 0x71, 0x3F, 0x3F, 0x8C, 0xC2, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x94, 0x7B, 0x3F, 0x3F, 0xE0, 0xC5, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x98, 0xEC, 0x93, 0x7C, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x98, 0xE1, 0x3F, 0x3F, 0x8C, 0xF4, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x8C, 0xF3, 0x98, 0xDF, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x5B, 0x8E, 0xD8, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x98, 0xE7, 0xED, 0x59, 0x95, 0xED, /* 0x20-0x23 */
+	0x92, 0x6C, 0x98, 0xE3, 0x8C, 0x91, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x98, 0xE0, 0x98, 0xE8, 0x98, 0xE2, 0x97, 0xCF, /* 0x28-0x2B */
+	0x98, 0xE9, 0x98, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xE4, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x8C, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x00, 0x74, 0x3F, 0x3F, 0x00, 0x7A, 0x98, 0x00, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x78, 0x98, 0x00, /* 0x44-0x47 */
-	0x98, 0x00, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x4C-0x4F */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x98, 0x00, 0x98, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0xED, 0x58, 0x3F, 0x3F, 0xED, 0x5E, 0x98, 0xEE, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x5C, 0x98, 0xEF, /* 0x44-0x47 */
+	0x98, 0xF3, 0x88, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xCE, /* 0x4C-0x4F */
+	0x98, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x98, 0xF1, 0x98, 0xF5, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xF4, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x92, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x8C, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x79, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x91, 0x00, 0x92, 0x00, 0x8B, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x98, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0xED, 0x5D, 0x3F, 0x3F, 0x8E, 0xC3, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x91, 0xA4, 0x92, 0xE3, 0x8B, 0xF4, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x98, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x8B, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x98, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x98, 0xFA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x96, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x8C, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x8E, 0x50, 0x94, 0x00, 0x98, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xED, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x8E, 0x50, 0x94, 0xF5, 0x98, 0xF9, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x8D, 0x00, 0x97, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, 0x99, 0x42, /* 0xB0-0xB3 */
-	0x98, 0x00, 0x8D, 0x00, 0x3F, 0x3F, 0x8F, 0x9D, /* 0xB4-0xB7 */
+	0x8D, 0xC3, 0x97, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xFC, 0x99, 0x42, /* 0xB0-0xB3 */
+	0x98, 0xFB, 0x8D, 0xC2, 0x3F, 0x3F, 0x8F, 0x9D, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x58, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x43, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x8B, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x99, 0x40, 0x99, 0x41, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x91, 0x9C, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x93, 0xAD, 0x3F, 0x3F, 0x91, 0x9C, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x8B, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x96, 0x6C, 0x99, 0x44, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x7D, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xED, 0x61, 0x3F, 0x3F, 0x97, 0xBB, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x45, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x48, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x99, 0x46, 0x3F, 0x3F, 0x91, 0x6D, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x99, 0x47, 0x99, 0x49, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x7C, 0x99, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x99, 0x4A, 0x3F, 0x3F, 0x95, 0x00, /* 0xF8-0xFB */
+	0xED, 0x60, 0x99, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x99, 0x4A, 0x3F, 0x3F, 0x95, 0xC6, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_51[512] = {
 	0x8B, 0x56, 0x99, 0x4D, 0x99, 0x4E, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x89, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x99, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xF2, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x99, 0x51, 0x99, 0x50, 0x99, 0x4F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x98, 0x00, 0x3F, 0x3F, 0x99, 0x52, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x98, 0xD4, 0x3F, 0x3F, 0x99, 0x52, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x9E, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x99, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x44, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xD7, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x55, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x54, 0x99, 0x57, /* 0x38-0x3B */
 	0x99, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x58, /* 0x3C-0x3F */
-	0x99, 0x59, 0x88, 0x00, 0x3F, 0x3F, 0x8C, 0x00, /* 0x40-0x43 */
-	0x8C, 0x5A, 0x8F, 0x5B, 0x92, 0x9B, 0x8B, 0x00, /* 0x44-0x47 */
-	0x90, 0x00, 0x8C, 0x00, 0x00, 0x7E, 0x8D, 0x8E, /* 0x48-0x4B */
-	0x99, 0x5B, 0x96, 0x00, 0x93, 0x65, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x99, 0x59, 0x88, 0xF2, 0x3F, 0x3F, 0x8C, 0xB3, /* 0x40-0x43 */
+	0x8C, 0x5A, 0x8F, 0x5B, 0x92, 0x9B, 0x8B, 0xA2, /* 0x44-0x47 */
+	0x90, 0xE6, 0x8C, 0xF5, 0xED, 0x62, 0x8D, 0x8E, /* 0x48-0x4B */
+	0x99, 0x5B, 0x96, 0xC6, 0x93, 0x65, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x8E, 0x99, 0x3F, 0x3F, 0x99, 0x5A, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x99, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x7D, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x8A, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x5D, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x80, 0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x91, 0x53, 0x99, 0x5F, 0x99, 0x60, 0x94, 0x00, /* 0x68-0x6B */
-	0x8C, 0x00, 0x98, 0x5A, 0x99, 0x61, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x95, 0x00, 0x91, 0x00, 0x8B, 0x00, /* 0x74-0x77 */
+	0xED, 0x63, 0x93, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x91, 0x53, 0x99, 0x5F, 0x99, 0x60, 0x94, 0xAA, /* 0x68-0x6B */
+	0x8C, 0xF6, 0x98, 0x5A, 0x99, 0x61, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x8B, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x95, 0xBA, 0x91, 0xB4, 0x8B, 0xEF, /* 0x74-0x77 */
 	0x93, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x8C, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x99, 0x62, 0x3F, 0x3F, 0x99, 0x63, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x93, 0x00, 0x89, 0x7E, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x99, 0x66, 0x8D, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x99, 0x65, 0x8D, 0x00, 0x3F, 0x3F, 0x99, 0x67, /* 0x8C-0x8F */
-	0x00, 0x00, 0x99, 0x68, 0x96, 0x60, 0x99, 0x69, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x99, 0x6A, 0x99, 0x6B, 0x8F, 0x00, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x00, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x8A, 0x00, 0x3F, 0x3F, 0x99, 0x6E, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x99, 0x6C, 0x96, 0x00, 0x99, 0x6D, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x93, 0xE0, 0x89, 0x7E, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x99, 0x66, 0x8D, 0xFB, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x99, 0x65, 0x8D, 0xC4, 0x3F, 0x3F, 0x99, 0x67, /* 0x8C-0x8F */
+	0xE3, 0xEC, 0x99, 0x68, 0x96, 0x60, 0x99, 0x69, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x99, 0x6A, 0x99, 0x6B, 0x8F, 0xE7, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x8E, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xED, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x8A, 0xA5, 0x3F, 0x3F, 0x99, 0x6E, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x99, 0x6C, 0x96, 0xBB, 0x99, 0x6D, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x95, 0x79, 0x99, 0x6F, 0x99, 0x70, 0x99, 0x71, /* 0xA8-0xAB */
 	0x93, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x99, 0x75, 0x99, 0x73, 0x99, 0x74, 0x99, 0x72, /* 0xB0-0xB3 */
-	0x8D, 0x00, 0x99, 0x76, 0x96, 0x00, 0x97, 0x00, /* 0xB4-0xB7 */
+	0x8D, 0xE1, 0x99, 0x76, 0x96, 0xE8, 0x97, 0xE2, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x99, 0x77, 0x00, 0x82, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x99, 0x77, 0xED, 0x65, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x90, 0x00, 0x99, 0x78, 0x8F, 0x79, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x90, 0xA6, 0x99, 0x78, 0x8F, 0x79, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x99, 0x79, 0x3F, 0x3F, 0x92, 0x9C, /* 0xC8-0xCB */
-	0x97, 0x00, 0x93, 0x80, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x97, 0xBD, 0x93, 0x80, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xC3, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x7A, /* 0xD8-0xDB */
-	0x00, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xEA, 0xA3, 0x8B, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x99, 0x7B, 0x96, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x88, 0x91, 0x00, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x99, 0x7D, 0x93, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x00, 0x83, 0x99, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x88, 0x91, 0xFA, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x99, 0x7D, 0x93, 0xE2, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0xED, 0x66, 0x99, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x99, 0x80, 0x8A, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x99, 0x81, 0x8B, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x93, 0x00, 0x89, 0x9A, 0x8F, 0x6F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x99, 0x81, 0x8B, 0xA5, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x93, 0xCA, 0x89, 0x9A, 0x8F, 0x6F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x94, 0x9F, 0x99, 0x82, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_52[512] = {
 	0x93, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x6E, /* 0x00-0x03 */
-	0x99, 0x83, 0x3F, 0x3F, 0x95, 0x00, 0x90, 0x00, /* 0x04-0x07 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x8A, 0x00, 0x99, 0x84, /* 0x08-0x0B */
+	0x99, 0x83, 0x3F, 0x3F, 0x95, 0xAA, 0x90, 0xD8, /* 0x04-0x07 */
+	0x8A, 0xA0, 0x3F, 0x3F, 0x8A, 0xA7, 0x99, 0x84, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x86, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x8C, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x99, 0x85, 0x00, 0x84, 0x3F, 0x3F, 0x97, 0x00, /* 0x14-0x17 */
+	0x99, 0x85, 0xED, 0x67, 0x3F, 0x3F, 0x97, 0xF1, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x8F, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x94, 0x00, 0x95, 0x00, 0x3F, 0x3F, 0x99, 0x87, /* 0x24-0x27 */
+	0x94, 0xBB, 0x95, 0xCA, 0x3F, 0x3F, 0x99, 0x87, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x97, 0x98, 0x99, 0x88, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x89, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x93, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x8A, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x8D, 0x00, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xA7, 0x8D, 0xFC, /* 0x34-0x37 */
 	0x8C, 0x94, 0x99, 0x8B, 0x8E, 0x68, 0x8D, 0x8F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x40-0x43 */
-	0x99, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x99, 0x8E, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xE4, /* 0x40-0x43 */
+	0x99, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xA5, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xED, 0x99, 0x8E, /* 0x48-0x4B */
 	0x99, 0x8F, 0x91, 0x4F, 0x3F, 0x3F, 0x99, 0x8C, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x99, 0x91, 0x3F, 0x3F, 0x96, 0x55, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x84, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x90, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x95, /* 0x60-0x63 */
-	0x8D, 0x00, 0x94, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x8D, 0xDC, 0x94, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x99, 0x94, 0x99, 0x92, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x9B, /* 0x6C-0x6F */
-	0x8F, 0x00, 0x99, 0x9B, 0x8A, 0x84, 0x99, 0x95, /* 0x70-0x73 */
+	0x8F, 0xE8, 0x99, 0x9B, 0x8A, 0x84, 0x99, 0x95, /* 0x70-0x73 */
 	0x99, 0x93, 0x91, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x99, 0x97, 0x3F, 0x3F, 0x99, 0x96, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x63, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x80, /* 0x84-0x87 */
-	0x99, 0x9C, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x99, 0x9C, 0x97, 0xAB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x99, 0x98, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x99, 0x9D, 0x99, 0x9A, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x99, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0x98-0x9B */
-	0x00, 0x85, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x9C-0x9F */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x86, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xCD, /* 0x98-0x9B */
+	0xED, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xF7, /* 0x9C-0x9F */
+	0x89, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xF2, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x69, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x8F, 0x95, 0x93, 0x77, 0x8D, 0x85, /* 0xA8-0xAB */
-	0x99, 0x00, 0x99, 0x00, 0x3F, 0x3F, 0x00, 0x77, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x98, 0x4A, 0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x99, 0x00, 0x3F, 0x3F, 0x8A, 0x4E, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x87, 0x99, 0x00, 0x3F, 0x3F, 0x96, 0x75, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x97, 0x45, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x99, 0x00, /* 0xD4-0xD7 */
-	0x8A, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x00, 0x88, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x8F, 0x9F, 0x99, 0x00, 0x95, 0x00, /* 0xDC-0xDF */
-	0x99, 0x00, 0x3F, 0x3F, 0x90, 0x00, 0x99, 0x00, /* 0xE0-0xE3 */
-	0x8B, 0x00, 0x3F, 0x3F, 0x99, 0x00, 0x8A, 0x00, /* 0xE4-0xE7 */
+	0x99, 0xA0, 0x99, 0xA1, 0x3F, 0x3F, 0xEE, 0x5B, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x97, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x98, 0x4A, 0x99, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x8C, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x99, 0xA2, 0x3F, 0x3F, 0x8A, 0x4E, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0xED, 0x6A, 0x99, 0xA4, 0x3F, 0x3F, 0x96, 0x75, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x92, 0xBA, 0x3F, 0x3F, 0x97, 0x45, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x95, 0xD7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x99, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xD3, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x93, 0xAE, 0x3F, 0x3F, 0x99, 0xA6, /* 0xD4-0xD7 */
+	0x8A, 0xA8, 0x96, 0xB1, 0x3F, 0x3F, 0xED, 0x6B, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x8F, 0x9F, 0x99, 0xA7, 0x95, 0xE5, /* 0xDC-0xDF */
+	0x99, 0xAB, 0x3F, 0x3F, 0x90, 0xA8, 0x99, 0xA8, /* 0xE0-0xE3 */
+	0x8B, 0xCE, 0x3F, 0x3F, 0x99, 0xA9, 0x8A, 0xA9, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x4D, 0x99, 0x00, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x99, 0x00, 0x99, 0x00, 0x8E, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x96, 0x00, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x4D, 0x99, 0xAC, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x99, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x99, 0xAE, 0x99, 0xAF, 0x8E, 0xD9, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xF9, 0x96, 0xDC, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_53[512] = {
-	0x00, 0x89, 0x96, 0x00, 0x93, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x95, 0x00, 0x99, 0x00, 0x00, 0x8A, /* 0x04-0x07 */
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x99, 0x00, /* 0x0C-0x0F */
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x99, 0x00, 0x89, 0x00, 0x96, 0x6B, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x8D, 0x00, 0x99, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
+	0xED, 0x6C, 0x96, 0xE6, 0x93, 0xF5, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x95, 0xEF, 0x99, 0xB0, 0xED, 0x6D, /* 0x04-0x07 */
+	0x99, 0xB1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x99, 0xB3, 0x3F, 0x3F, 0x99, 0xB5, /* 0x0C-0x0F */
+	0x99, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x99, 0xB6, 0x89, 0xBB, 0x96, 0x6B, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x8D, 0xFA, 0x99, 0xB7, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x91, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x8F, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x99, 0x00, /* 0x20-0x23 */
-	0x00, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x99, 0x00, /* 0x30-0x33 */
+	0x8F, 0xA0, 0x8B, 0xA7, 0x3F, 0x3F, 0x99, 0xB8, /* 0x20-0x23 */
+	0xED, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xD9, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xB9, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x99, 0xBA, 0x3F, 0x3F, 0x99, 0xBB, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x99, 0x00, 0x95, 0x43, 0x8B, 0x00, 0x88, 0x00, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0x3C-0x3F */
-	0x99, 0x00, 0x8F, 0x5C, 0x3F, 0x3F, 0x90, 0x00, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x99, 0x00, 0x99, 0x00, 0x8F, 0x00, /* 0x44-0x47 */
-	0x8C, 0x00, 0x99, 0x00, 0x94, 0x00, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x94, 0x00, 0x91, 0x00, 0x91, 0x00, /* 0x50-0x53 */
-	0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0x54-0x57 */
+	0x99, 0xBC, 0x95, 0x43, 0x8B, 0xE6, 0x88, 0xE3, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xBD, /* 0x3C-0x3F */
+	0x99, 0xBD, 0x8F, 0x5C, 0x3F, 0x3F, 0x90, 0xE7, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x99, 0xBF, 0x99, 0xBE, 0x8F, 0xA1, /* 0x44-0x47 */
+	0x8C, 0xDF, 0x99, 0xC1, 0x94, 0xBC, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x99, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x94, 0xDA, 0x91, 0xB2, 0x91, 0xEC, /* 0x50-0x53 */
+	0x8B, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xEC, /* 0x54-0x57 */
 	0x92, 0x50, 0x3F, 0x3F, 0x94, 0x8E, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x96, 0x6D, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x96, 0x6D, 0x3F, 0x3F, 0x99, 0xC4, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x90, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x54, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x89, 0x4B, /* 0x6C-0x6F */
-	0x88, 0x00, 0x8A, 0x00, 0x00, 0x8C, 0x91, 0x00, /* 0x70-0x73 */
-	0x8B, 0x70, 0x97, 0x91, 0x3F, 0x3F, 0x99, 0x00, /* 0x74-0x77 */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x99, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xC6, 0x89, 0x4B, /* 0x6C-0x6F */
+	0x88, 0xF3, 0x8A, 0xEB, 0xED, 0x6F, 0x91, 0xA6, /* 0x70-0x73 */
+	0x8B, 0x70, 0x97, 0x91, 0x3F, 0x3F, 0x99, 0xC9, /* 0x74-0x77 */
+	0x89, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xC8, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xA8, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xCA, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x96, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8D, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x97, 0x00, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x9C-0x9F */
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x99, 0x00, 0x99, 0x00, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x70, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xCB, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x97, 0xD0, 0x3F, 0x3F, 0x8C, 0xFA, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xB4, /* 0x9C-0x9F */
+	0x99, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x99, 0xCE, 0x99, 0xCD, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x90, 0x7E, 0x89, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x89, 0x7D, 0x99, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x99, 0x00, 0x3F, 0x3F, 0x00, 0x8E, 0x8C, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x89, 0x7D, 0x99, 0xCF, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x99, 0xD0, 0x3F, 0x3F, 0xED, 0x71, 0x8C, 0xB5, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xD1, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x8E, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x51, 0x99, 0x00, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x51, 0x99, 0xD2, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x96, 0x94, 0x8D, 0x00, 0x8B, 0x79, 0x97, 0x46, /* 0xC8-0xCB */
-	0x91, 0x6F, 0x94, 0x00, 0x8E, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x96, 0x94, 0x8D, 0xB3, 0x8B, 0x79, 0x97, 0x46, /* 0xC8-0xCB */
+	0x91, 0x6F, 0x94, 0xBD, 0x8E, 0xFB, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x8F, 0x66, 0x3F, 0x3F, 0x8E, 0x00, 0x8E, 0x00, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x8F, 0x96, 0x3F, 0x3F, 0x94, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x00, 0x8F, 0x3F, 0x3F, 0x99, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x89, 0x62, 0x91, 0x70, 0x8C, 0x00, /* 0xE0-0xE3 */
-	0x8C, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x99, 0x00, 0x92, 0x40, 0x91, 0x00, 0x8B, 0x00, /* 0xE8-0xEB */
-	0x8F, 0x00, 0x99, 0x00, 0x99, 0x00, 0x89, 0x00, /* 0xEC-0xEF */
-	0x91, 0x00, 0x8E, 0x00, 0x8E, 0x6A, 0x89, 0x45, /* 0xF0-0xF3 */
+	0x8F, 0x66, 0x3F, 0x3F, 0x8E, 0xE6, 0x8E, 0xF3, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x8F, 0x96, 0x3F, 0x3F, 0x94, 0xBE, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xED, 0x72, 0x3F, 0x3F, 0x99, 0xD5, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x89, 0x62, 0x91, 0x70, 0x8C, 0xFB, /* 0xE0-0xE3 */
+	0x8C, 0xC3, 0x8B, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x99, 0xD9, 0x92, 0x40, 0x91, 0xFC, 0x8B, 0xA9, /* 0xE8-0xEB */
+	0x8F, 0xA2, 0x99, 0xDA, 0x99, 0xD8, 0x89, 0xC2, /* 0xEC-0xEF */
+	0x91, 0xE4, 0x8E, 0xB6, 0x8E, 0x6A, 0x89, 0x45, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x90, 0x8D, 0x86, /* 0xF4-0xF7 */
-	0x8E, 0x69, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x8E, 0x69, 0x3F, 0x3F, 0x99, 0xDB, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_54[512] = {
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x8B, 0x68, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x99, 0xDC, 0x3F, 0x3F, 0x8B, 0x68, /* 0x00-0x03 */
 	0x8A, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x8D, 0x87, 0x8B, 0x67, 0x92, 0x00, 0x89, 0x44, /* 0x08-0x0B */
-	0x93, 0x00, 0x96, 0x00, 0x8D, 0x40, 0x97, 0x99, /* 0x0C-0x0F */
-	0x93, 0x66, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x8D, 0x87, 0x8B, 0x67, 0x92, 0xDD, 0x89, 0x44, /* 0x08-0x0B */
+	0x93, 0xAF, 0x96, 0xBC, 0x8D, 0x40, 0x97, 0x99, /* 0x0C-0x0F */
+	0x93, 0x66, 0x8C, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x4E, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x8B, 0x00, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x99, 0xE5, 0x3F, 0x3F, 0x8B, 0xE1, /* 0x1C-0x1F */
 	0x96, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x8A, 0x00, /* 0x28-0x2B */
-	0x99, 0x00, 0x99, 0x00, 0x99, 0x00, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xDB, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x99, 0xE4, 0x3F, 0x3F, 0x8A, 0xDC, /* 0x28-0x2B */
+	0x99, 0xDF, 0x99, 0xE0, 0x99, 0xE2, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x8B, 0x7A, 0x90, 0x81, 0x3F, 0x3F, 0x95, 0x00, /* 0x38-0x3B */
-	0x99, 0x00, 0x99, 0x00, 0x8C, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x99, 0x00, 0x3F, 0x3F, 0x98, 0x43, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x92, 0x00, 0x8C, 0x00, 0x8D, 0x90, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xE3, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x8B, 0x7A, 0x90, 0x81, 0x3F, 0x3F, 0x95, 0xAB, /* 0x38-0x3B */
+	0x99, 0xE1, 0x99, 0xDD, 0x8C, 0xE1, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x99, 0xDE, 0x3F, 0x3F, 0x98, 0x43, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xF0, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x92, 0xE6, 0x8C, 0xE0, 0x8D, 0x90, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xE6, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x93, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xEA, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x8E, 0x00, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x8E, 0xFC, 0x3F, 0x3F, 0x8E, 0xF4, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x99, 0x00, 0x99, 0x00, 0x3F, 0x3F, 0x96, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x99, 0x00, 0x99, 0x00, 0x99, 0x00, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, /* 0x78-0x7B */
-	0x8C, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
-	
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x99, 0x00, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x92, 0x8D, 0x00, /* 0x88-0x8B */
-	0x98, 0x61, 0x3F, 0x3F, 0x99, 0x00, 0x99, 0x00, /* 0x8C-0x8F */
-	0x99, 0x00, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x99, 0xED, 0x99, 0xEB, 0x3F, 0x3F, 0x96, 0xA1, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x99, 0xE8, 0x99, 0xF1, 0x99, 0xEC, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xEF, /* 0x78-0x7B */
+	0x8C, 0xC4, 0x96, 0xBD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0x99, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x99, 0xF2, 0x3F, 0x3F, 0x99, 0xF4, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x75, 0x8D, 0xEE, /* 0x88-0x8B */
+	0x98, 0x61, 0x3F, 0x3F, 0x99, 0xE9, 0x99, 0xE7, /* 0x8C-0x8F */
+	0x99, 0xF3, 0x3F, 0x3F, 0x99, 0xEE, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x00, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x9A, 0x42, 0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x99, 0x00, 0x00, 0x93, 0x3F, 0x3F, 0x9A, 0x40, /* 0xA8-0xAB */
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x5D, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x8A, 0x50, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x9A, 0x44, 0x88, 0x00, 0x9A, 0x43, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x88, 0x00, 0x95, 0x69, 0x9A, 0x41, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x99, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x00, /* 0xC4-0xC7 */
-	0x99, 0x00, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0xED, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xF6, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x9A, 0x42, 0x99, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x99, 0xFC, 0xED, 0x76, 0x3F, 0x3F, 0x9A, 0x40, /* 0xA8-0xAB */
+	0x99, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x5D, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xE7, 0x8A, 0x50, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x99, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x9A, 0x44, 0x88, 0xF4, 0x9A, 0x43, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x88, 0xA3, 0x95, 0x69, 0x9A, 0x41, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x99, 0xFA, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0xF5, /* 0xC4-0xC7 */
+	0x99, 0xFB, 0x8D, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x9A, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x88, 0x00, 0x9A, 0x4E, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x88, 0xF5, 0x9A, 0x4E, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x9A, 0x46, 0x9A, 0x47, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x8F, 0x00, 0x96, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x8F, 0xA3, 0x96, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x9A, 0x4C, 0x9A, 0x4B, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x4E, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x4D, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x9A, 0x4A, 0x3F, 0x3F, 0x00, 0x94, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x9A, 0x4A, 0x3F, 0x3F, 0xED, 0x77, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_55[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x89, 0x53, 0x3F, 0x3F, 0x8D, 0x00, 0x90, 0x4F, /* 0x04-0x07 */
+	0x89, 0x53, 0x3F, 0x3F, 0x8D, 0xB4, 0x90, 0x4F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x48, /* 0x0C-0x0F */
 	0x93, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x9A, 0x49, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x9A, 0x49, 0x3F, 0x3F, 0x88, 0xA0, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x53, 0x97, 0x42, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x9A, 0x59, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x8F, 0xA5, 0x3F, 0x3F, 0x9A, 0x59, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x9A, 0x58, 0x9A, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xC1, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x9A, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x91, 0x00, 0x9A, 0x55, 0x8F, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x91, 0xED, 0x9A, 0x55, 0x8F, 0xA4, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x9A, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0x4C-0x4F */
+	0x9A, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xE2, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x5B, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x56, 0x9A, 0x57, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
@@ -4433,23 +4435,23 @@
 	0x9A, 0x65, 0x3F, 0x3F, 0x9A, 0x61, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x9A, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x66, /* 0x80-0x83 */
-	0x91, 0x50, 0x3F, 0x3F, 0x00, 0x95, 0x9A, 0x68, /* 0x84-0x87 */
+	0x91, 0x50, 0x3F, 0x3F, 0xED, 0x78, 0x9A, 0x68, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x8D, 0x41, 0x9A, 0x5E, 0x92, 0x9D, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x9A, 0x62, 0x9A, 0x5B, 0x8A, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x8A, 0x00, 0x8A, 0x85, 0x9A, 0x63, 0x9A, 0x5F, /* 0x9C-0x9F */
+	0x9A, 0x62, 0x9A, 0x5B, 0x8A, 0xAB, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x8A, 0xEC, 0x8A, 0x85, 0x9A, 0x63, 0x9A, 0x5F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x96, /* 0xA4-0xA7 */
 	0x9A, 0x69, 0x9A, 0x67, 0x91, 0x72, 0x8B, 0x69, /* 0xA8-0xAB */
-	0x8B, 0x00, 0x3F, 0x3F, 0x9A, 0x64, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x8B, 0xAA, 0x3F, 0x3F, 0x9A, 0x64, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x8B, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x63, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x9A, 0x6D, 0x9A, 0x6B, 0x3F, 0x3F, 0x9A, 0x00, /* 0xC4-0xC7 */
+	0x9A, 0x6D, 0x9A, 0x6B, 0x3F, 0x3F, 0x9A, 0xA5, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
@@ -4469,17 +4471,17 @@
 static unsigned char u2c_56[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x51, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x89, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x9A, 0x71, 0x3F, 0x3F, 0x9A, 0x73, 0x8F, 0x00, /* 0x14-0x17 */
+	0x9A, 0x71, 0x3F, 0x3F, 0x9A, 0x73, 0x8F, 0xA6, /* 0x14-0x17 */
 	0x89, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x76, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x89, 0xDC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x82, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x8F, 0x00, 0x9A, 0x7D, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x8F, 0xFA, 0x9A, 0x7D, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x9A, 0x7B, 0x3F, 0x3F, 0x9A, 0x7C, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x9A, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
@@ -4493,11 +4495,11 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x9A, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x9A, 0x84, 0x9A, 0x80, /* 0x68-0x6B */
+	0x8A, 0xED, 0x3F, 0x3F, 0x9A, 0x84, 0x9A, 0x80, /* 0x68-0x6B */
 	0x9A, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x93, 0x00, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x95, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x93, 0xD3, 0x3F, 0x3F, 0x94, 0xB6, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x9A, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
@@ -4522,246 +4524,246 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x95, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x9A, 0x96, 0x3F, 0x3F, 0x9A, 0x97, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x98, /* 0xD4-0xD7 */
-	0x99, 0x64, 0x3F, 0x3F, 0x8E, 0x00, 0x8E, 0x6C, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x63, /* 0xE0-0xE3 */
+	0x99, 0x64, 0x3F, 0x3F, 0x8E, 0xFA, 0x8E, 0x6C, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xF1, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x88, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x63, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x99, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x8D, 0x00, 0x3F, 0x3F, 0x88, 0x00, 0x90, 0x7D, /* 0xF0-0xF3 */
+	0x8D, 0xA2, 0x3F, 0x3F, 0x88, 0xCD, 0x90, 0x7D, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x9A, 0x9A, 0x8C, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x9A, 0x9A, 0x8C, 0xC5, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x8D, 0x91, 0x3F, 0x3F, 0x9A, 0x9C, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_57[512] = {
-	0x9A, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x00-0x03 */
+	0x9A, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xDE, /* 0x00-0x03 */
 	0x9A, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x9A, 0x9F, 0x9A, 0x9E, 0x3F, 0x3F, 0x9A, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x8C, 0x97, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x80, 0x9A, 0x00, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x79, /* 0x1C-0x1F */
+	0x9A, 0x9F, 0x9A, 0x9E, 0x3F, 0x3F, 0x9A, 0xA0, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x9A, 0xA1, 0x3F, 0x3F, 0x8C, 0x97, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x80, 0x9A, 0xA2, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xA4, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x9A, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x9A, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x79, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x88, 0x00, /* 0x24-0x27 */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xA7, 0x88, 0xB3, /* 0x24-0x27 */
+	0x8D, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x8C, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x92, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0x34-0x37 */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xA8, /* 0x34-0x37 */
+	0x9A, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xAB, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x9A, 0x00, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x44-0x47 */
+	0x9A, 0xAC, 0x3F, 0x3F, 0x8D, 0xE2, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xCF, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x56, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x9A, 0x00, /* 0x4C-0x4F */
-	0x8D, 0x00, 0x8D, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xAA, 0x9A, 0xAD, /* 0x4C-0x4F */
+	0x8D, 0xBF, 0x8D, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0xED, 0x79, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x8D, 0x00, 0x00, 0x97, 0x92, 0x52, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x92, 0x00, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x9A, 0xB1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x8D, 0xA3, 0xED, 0x7A, 0x92, 0x52, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x9A, 0xAE, 0x92, 0xD8, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xB2, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x82, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x9A, 0x00, 0x9A, 0x00, 0x3F, 0x3F, 0x8C, 0x5E, /* 0x88-0x8B */
+	0x9A, 0xB0, 0x9A, 0xB3, 0x3F, 0x3F, 0x8C, 0x5E, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xB4, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x9A, 0x00, 0x3F, 0x3F, 0x8D, 0x43, 0x8A, 0x5F, /* 0xA0-0xA3 */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x00, 0x98, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0xB0-0xB3 */
+	0x9A, 0xB5, 0x3F, 0x3F, 0x8D, 0x43, 0x8A, 0x5F, /* 0xA0-0xA3 */
+	0x9A, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xB8, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0xED, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x9A, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xB6, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x00, 0x9A, /* 0xC4-0xC7 */
-	0x00, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x84, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x9A, 0x00, /* 0xD0-0xD3 */
-	0x9A, 0x00, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x9A, 0xAF, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xBA, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xBB, 0xED, 0x7D, /* 0xC4-0xC7 */
+	0xED, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x84, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xE9, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xBD, 0x9A, 0xBE, /* 0xD0-0xD3 */
+	0x9A, 0xBC, 0x3F, 0x3F, 0x9A, 0xC0, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x94, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xDC-0xDF */
-	0x95, 0x75, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0xE0-0xE3 */
+	0x94, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xE6, /* 0xDC-0xDF */
+	0x95, 0x75, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xC1, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x94, 0x7C, 0x8A, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x8F, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xB7, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x94, 0x7C, 0x8A, 0xEE, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x8D, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_58[512] = {
-	0x96, 0x78, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x8C, 0x98, 0x91, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x9A, 0x00, /* 0x08-0x0B */
+	0x96, 0x78, 0x3F, 0x3F, 0x93, 0xB0, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x8C, 0x98, 0x91, 0xCD, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xBF, 0x9A, 0xC2, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9F, /* 0x2C-0x2F */
-	0x89, 0x81, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x8F, 0x00, 0x93, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x95, 0x00, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x91, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x9A, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x9A, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x9A, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x92, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xAC, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x9F, /* 0x2C-0x2F */
+	0x89, 0x81, 0x95, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x8F, 0xEA, 0x93, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xE4, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x9A, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x95, 0xBB, 0x97, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x9A, 0x00, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xF2, 0x9A, 0xC8, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x91, 0x59, 0x9A, 0x00, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x91, 0x59, 0x9A, 0xCB, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x93, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x68, /* 0x54-0x57 */
-	0x93, 0x84, 0x94, 0x00, 0x92, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x93, 0x84, 0x94, 0xB7, 0x92, 0xCB, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xC7, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xC7, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x89, 0x96, 0x3F, 0x3F, 0x93, 0x55, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x9A, 0x00, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x9A, 0xC9, 0x3F, 0x3F, 0x9A, 0xC5, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x90, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x9A, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x6D, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xAB, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x9A, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xE6, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x9D, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x92, 0x00, 0x3F, 0x3F, 0x00, 0x9D, 0x9A, 0x00, /* 0x9C-0x9F */
+	0x92, 0xC4, 0x3F, 0x3F, 0xED, 0x81, 0x9A, 0xD0, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x96, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9E, 0x95, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x9A, 0x00, 0x9A, 0x00, 0x9A, 0x00, 0x9A, 0x00, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x92, 0x64, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x9A, 0x00, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x8D, 0x88, 0x3F, 0x3F, 0x9A, 0x00, /* 0xD4-0xD7 */
-	0x9A, 0x00, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x9A, 0x00, 0x3F, 0x3F, 0x9A, 0x00, 0x9A, 0x00, /* 0xDC-0xDF */
+	0x96, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xD1, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xD6, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x82, 0x95, 0xAD, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x9A, 0xD5, 0x9A, 0xCF, 0x9A, 0xD2, 0x9A, 0xD4, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xA4, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x95, 0xC7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x9A, 0xD7, 0x3F, 0x3F, 0x92, 0x64, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xF3, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x8F, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x9A, 0xD9, 0x3F, 0x3F, 0x9A, 0xD8, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x8D, 0x88, 0x3F, 0x3F, 0x9A, 0xDA, /* 0xD4-0xD7 */
+	0x9A, 0xDC, 0x9A, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x9A, 0xDE, 0x3F, 0x3F, 0x9A, 0xD3, 0x9A, 0xE0, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x9A, 0x00, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x9A, 0xDF, 0x9A, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x6D, /* 0xE8-0xEB */
-	0x90, 0x70, 0x3F, 0x3F, 0x91, 0x73, 0x9A, 0x00, /* 0xEC-0xEF */
-	0x90, 0x00, 0x88, 0x00, 0x94, 0x84, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x9A, 0x00, 0x9A, 0x00, /* 0xF8-0xFB */
-	0x9A, 0x00, 0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x90, 0x70, 0x3F, 0x3F, 0x91, 0x73, 0x9A, 0xE1, /* 0xEC-0xEF */
+	0x90, 0xBA, 0x88, 0xEB, 0x94, 0x84, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xD9, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x9A, 0xE3, 0x9A, 0xE2, 0x9A, 0xE4, /* 0xF8-0xFB */
+	0x9A, 0xE5, 0x9A, 0xE6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_59[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xE7, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x95, 0x00, 0x9A, 0x00, 0x00, 0x9F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0x0C-0x0F */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x95, 0xCF, 0x9A, 0xE8, 0xED, 0x83, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xC4, /* 0x0C-0x0F */
+	0x9A, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x97, 0x5B, 0x8A, 0x4F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x99, 0x00, 0x8F, 0x67, 0x91, 0x00, 0x9A, 0x00, /* 0x18-0x1B */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, 0x91, 0x00, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x93, 0x56, 0x91, 0x00, 0x95, 0x76, /* 0x28-0x2B */
-	0x9A, 0x00, 0x9A, 0x00, 0x89, 0x9B, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x8E, 0x00, 0x9A, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0x34-0x37 */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x99, 0xC7, 0x8F, 0x67, 0x91, 0xBD, 0x9A, 0xEA, /* 0x18-0x1B */
+	0x96, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xB2, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x9A, 0xEC, 0x3F, 0x3F, 0x91, 0xE5, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x93, 0x56, 0x91, 0xBE, 0x95, 0x76, /* 0x28-0x2B */
+	0x9A, 0xED, 0x9A, 0xEE, 0x89, 0x9B, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x8E, 0xB8, 0x9A, 0xEF, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xCE, /* 0x34-0x37 */
+	0x9A, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xF1, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x89, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0x44-0x47 */
-	0x93, 0x00, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x91, 0x74, /* 0x4C-0x4F */
-	0x9A, 0x00, 0x8C, 0x5F, 0x3F, 0x3F, 0x00, 0x00, /* 0x50-0x53 */
-	0x96, 0x7A, 0x9A, 0x00, 0x3F, 0x3F, 0x93, 0x85, /* 0x54-0x57 */
-	0x9A, 0x00, 0x3F, 0x3F, 0x9A, 0x00, 0x00, 0x00, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x9A, 0x00, 0x3F, 0x3F, 0x9A, 0x00, 0x00, 0x00, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x89, 0x9C, 0x3F, 0x3F, 0x9A, 0x00, /* 0x64-0x67 */
-	0x8F, 0x00, 0x9A, 0x00, 0x92, 0x44, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x9A, 0x00, 0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x89, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xEF, /* 0x44-0x47 */
+	0x93, 0xDE, 0x95, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xF5, 0x91, 0x74, /* 0x4C-0x4F */
+	0x9A, 0xF4, 0x8C, 0x5F, 0x3F, 0x3F, 0xED, 0x84, /* 0x50-0x53 */
+	0x96, 0x7A, 0x9A, 0xF3, 0x3F, 0x3F, 0x93, 0x85, /* 0x54-0x57 */
+	0x9A, 0xF7, 0x3F, 0x3F, 0x9A, 0xF6, 0xED, 0x85, /* 0x58-0x5B */
+	0x3F, 0x3F, 0xED, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x9A, 0xF9, 0x3F, 0x3F, 0x9A, 0xF8, 0xED, 0x87, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x89, 0x9C, 0x3F, 0x3F, 0x9A, 0xFA, /* 0x64-0x67 */
+	0x8F, 0xA7, 0x9A, 0xFC, 0x92, 0x44, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x9A, 0xFB, 0x3F, 0x3F, 0x95, 0xB1, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x97, /* 0x70-0x73 */
 	0x93, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x9B, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x8D, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x9B, 0x41, 0x94, 0x40, 0x94, 0x00, /* 0x80-0x83 */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x9B, 0x41, 0x94, 0x40, 0x94, 0xDC, /* 0x80-0x83 */
+	0x96, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x44, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x9B, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x57, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x64, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x9B, 0x00, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x96, 0xAD, 0x3F, 0x3F, 0x9B, 0xAA, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x9B, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x45, /* 0xA0-0xA3 */
-	0x00, 0x00, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0xED, 0x88, 0x91, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x96, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x93, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x46, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x96, 0x85, 0x00, 0x00, 0x8D, 0x00, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x96, 0x85, 0xED, 0x89, 0x8D, 0xC8, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xA8, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x47, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x8E, 0x6F, 0x3F, 0x3F, 0x8E, 0x6E, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x88, 0x00, 0x8C, 0x00, 0x3F, 0x3F, 0x90, 0x00, /* 0xD0-0xD3 */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x88, 0xB7, 0x8C, 0xC6, 0x3F, 0x3F, 0x90, 0xA9, /* 0xD0-0xD3 */
+	0x88, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x9B, 0x4B, 0x9B, 0x4C, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x9B, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x89, 0x57, 0x8A, 0x00, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x9B, 0x48, 0x3F, 0x3F, 0x96, 0x00, 0x95, 0x50, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x89, 0x57, 0x8A, 0xAD, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x9B, 0x48, 0x3F, 0x3F, 0x96, 0xC3, 0x95, 0x50, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xA6, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xF7, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x70, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_5A[512] = {
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x88, 0x00, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x88, 0xD0, 0x3F, 0x3F, 0x88, 0xA1, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x9B, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x9B, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x96, 0x00, 0x3F, 0x3F, 0x9B, 0x52, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x96, 0xBA, 0x3F, 0x3F, 0x9B, 0x52, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x9B, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x4E, /* 0x1C-0x1F */
 	0x90, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x9B, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x95, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xE2, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x9B, 0x56, 0x9B, 0x57, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x8F, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x9B, 0x53, 0x98, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x6B, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x9B, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xA5, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x58, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x77, 0x3F, 0x3F, /* 0x64-0x67 */
@@ -4770,7 +4772,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xB9, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
@@ -4788,9 +4790,9 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x9B, 0x5B, 0x9B, 0x5F, 0x9B, 0x5C, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x89, 0x00, 0x9B, 0x5E, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x89, 0xC5, 0x9B, 0x5E, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x9B, 0x5D, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x8E, 0xB9, 0x3F, 0x3F, 0x9B, 0x5D, /* 0xC8-0xCB */
 	0x8C, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x9B, 0x6B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x64, 0x9B, 0x61, /* 0xD4-0xD7 */
@@ -4809,16 +4811,16 @@
 static unsigned char u2c_5B[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x9B, 0x68, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x8A, 0xF0, 0x3F, 0x3F, 0x9B, 0x68, /* 0x08-0x0B */
 	0x9B, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x69, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xEC, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x6C, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x92, 0xDA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x89, 0x64, 0x3F, 0x3F, 0x9B, 0x6A, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x6D, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
@@ -4828,319 +4830,319 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x8E, 0x71, 0x9B, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x8D, 0x45, 0x9B, 0x73, 0x00, 0x00, 0x8E, 0x9A, /* 0x54-0x57 */
-	0x91, 0x00, 0x3F, 0x3F, 0x9B, 0x74, 0x9B, 0x75, /* 0x58-0x5B */
-	0x8E, 0x79, 0x8D, 0x46, 0x3F, 0x3F, 0x96, 0x00, /* 0x5C-0x5F */
+	0x8D, 0x45, 0x9B, 0x73, 0xED, 0x8A, 0x8E, 0x9A, /* 0x54-0x57 */
+	0x91, 0xB6, 0x3F, 0x3F, 0x9B, 0x74, 0x9B, 0x75, /* 0x58-0x5B */
+	0x8E, 0x79, 0x8D, 0x46, 0x3F, 0x3F, 0x96, 0xD0, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x47, /* 0x60-0x63 */
-	0x8C, 0x00, 0x9B, 0x76, 0x8A, 0x77, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x9B, 0x77, 0x3F, 0x3F, 0x91, 0x00, /* 0x68-0x6B */
+	0x8C, 0xC7, 0x9B, 0x76, 0x8A, 0x77, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x9B, 0x77, 0x3F, 0x3F, 0x91, 0xB7, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x9B, 0x78, 0x9B, 0x00, 0x3F, 0x3F, 0x9B, 0x79, /* 0x70-0x73 */
+	0x9B, 0x78, 0x9B, 0xA1, 0x3F, 0x3F, 0x9B, 0x79, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x9B, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x9B, 0x7B, 0x3F, 0x3F, 0x9B, 0x7D, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x9B, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x80, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x89, 0x46, /* 0x84-0x87 */
-	0x8E, 0x00, 0x88, 0x00, 0x3F, 0x3F, 0x91, 0x76, /* 0x88-0x8B */
-	0x8A, 0x00, 0x8E, 0x00, 0x3F, 0x3F, 0x8D, 0x47, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x91, 0xEE, 0x3F, 0x3F, 0x89, 0x46, /* 0x84-0x87 */
+	0x8E, 0xE7, 0x88, 0xC0, 0x3F, 0x3F, 0x91, 0x76, /* 0x88-0x8B */
+	0x8A, 0xAE, 0x8E, 0xB3, 0x3F, 0x3F, 0x8D, 0x47, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x93, 0x86, 0x3F, 0x3F, 0x8F, 0x40, /* 0x94-0x97 */
-	0x8A, 0x00, 0x92, 0x88, 0x92, 0x00, 0x88, 0x00, /* 0x98-0x9B */
-	0x8B, 0x58, 0x95, 0x00, 0x3F, 0x3F, 0x8E, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x71, 0x90, 0x00, /* 0xA0-0xA3 */
-	0x8E, 0x00, 0x97, 0x47, 0x9B, 0x81, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x8A, 0xAF, 0x92, 0x88, 0x92, 0xE8, 0x88, 0xB6, /* 0x98-0x9B */
+	0x8B, 0x58, 0x95, 0xF3, 0x3F, 0x3F, 0x8E, 0xC0, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x71, 0x90, 0xE9, /* 0xA0-0xA3 */
+	0x8E, 0xBA, 0x97, 0x47, 0x9B, 0x81, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x7B, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x51, /* 0xB0-0xB3 */
-	0x89, 0x83, 0x8F, 0x00, 0x89, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x8D, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x51, /* 0xB0-0xB3 */
+	0x89, 0x83, 0x8F, 0xAA, 0x89, 0xC6, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x9B, 0x82, 0x97, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x68, /* 0xBC-0xBF */
-	0x00, 0x00, 0x3F, 0x3F, 0x8E, 0x00, 0x9B, 0x83, /* 0xC0-0xC3 */
-	0x8A, 0x00, 0x93, 0x00, 0x96, 0x00, 0x9B, 0x84, /* 0xC4-0xC7 */
+	0xED, 0x8B, 0x3F, 0x3F, 0x8E, 0xE2, 0x9B, 0x83, /* 0xC0-0xC3 */
+	0x8A, 0xF1, 0x93, 0xD0, 0x96, 0xA7, 0x9B, 0x84, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x9B, 0x85, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x95, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x9B, 0x87, 0x3F, 0x3F, 0x8A, 0x00, 0x8B, 0x00, /* 0xD0-0xD3 */
+	0x9B, 0x87, 0x3F, 0x3F, 0x8A, 0xA6, 0x8B, 0xF5, /* 0xD0-0xD3 */
 	0x9B, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0xD8-0xDB */
+	0xED, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xB0, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x90, 0x51, 0x9B, 0x8B, 0x8E, 0x40, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x89, 0x00, 0x9B, 0x8A, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x89, 0xC7, 0x9B, 0x8A, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x9B, 0x88, 0x9B, 0x8C, 0x9B, 0x89, 0x94, 0x4A, /* 0xE4-0xE7 */
-	0x9E, 0x00, 0x90, 0x52, 0x3F, 0x3F, 0x9B, 0x8D, /* 0xE8-0xEB */
-	0x00, 0x00, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x9E, 0xCB, 0x90, 0x52, 0x3F, 0x3F, 0x9B, 0x8D, /* 0xE8-0xEB */
+	0xED, 0x8E, 0x3F, 0x3F, 0x97, 0xBE, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x9B, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x90, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x92, 0x9E, 0x9B, 0x8F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x90, 0x00, 0x3F, 0x3F, 0x8E, 0x9B, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x8E, 0x00, /* 0xFC-0xFF */
+	0x90, 0xA1, 0x3F, 0x3F, 0x8E, 0x9B, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xCE, 0x8E, 0xF5, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_5C[512] = {
-	0x3F, 0x3F, 0x95, 0x95, 0x90, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x8E, 0x00, 0x9B, 0x91, 0x8F, 0x00, 0x9B, 0x92, /* 0x04-0x07 */
-	0x9B, 0x93, 0x88, 0x00, 0x91, 0x00, 0x90, 0x71, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x9B, 0x94, 0x93, 0x00, 0x8F, 0x00, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x9B, 0x95, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x95, 0x95, 0x90, 0xEA, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x8E, 0xCB, 0x9B, 0x91, 0x8F, 0xAB, 0x9B, 0x92, /* 0x04-0x07 */
+	0x9B, 0x93, 0x88, 0xD1, 0x91, 0xB8, 0x90, 0x71, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x9B, 0x94, 0x93, 0xB1, 0x8F, 0xAC, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x8F, 0xAD, 0x3F, 0x3F, 0x9B, 0x95, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xEB, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xAE, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x8F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x9B, 0x96, 0x3F, 0x3F, 0x9B, 0x97, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x96, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x9B, 0x98, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x8B, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x8F, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x9B, 0x99, 0x9B, 0x9A, 0x8E, 0x00, 0x90, 0x4B, /* 0x38-0x3B */
-	0x93, 0x00, 0x90, 0x73, 0x94, 0x00, 0x94, 0x41, /* 0x3C-0x3F */
-	0x8B, 0x00, 0x9B, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x9B, 0x99, 0x9B, 0x9A, 0x8E, 0xDA, 0x90, 0x4B, /* 0x38-0x3B */
+	0x93, 0xF2, 0x90, 0x73, 0x94, 0xF6, 0x94, 0x41, /* 0x3C-0x3F */
+	0x8B, 0xC7, 0x9B, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x8B, 0x8F, 0x9B, 0x9C, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x8B, 0x00, 0x3F, 0x3F, 0x93, 0x00, 0x89, 0x00, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x8E, 0x72, 0x9B, 0x9D, 0x9B, 0x00, /* 0x4C-0x4F */
-	0x9B, 0x9F, 0x8B, 0x00, 0x3F, 0x3F, 0x9B, 0x9E, /* 0x50-0x53 */
+	0x8B, 0xFC, 0x3F, 0x3F, 0x93, 0xCD, 0x89, 0xAE, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x8E, 0x72, 0x9B, 0x9D, 0x9B, 0xA0, /* 0x4C-0x4F */
+	0x9B, 0x9F, 0x8B, 0xFB, 0x3F, 0x3F, 0x9B, 0x9E, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x93, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x93, 0x6A, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xAE, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x93, 0x6A, 0x8E, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x91, 0x77, 0x97, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x9B, 0x00, 0x3F, 0x3F, 0x9B, 0x00, 0x93, 0x00, /* 0x6C-0x6F */
+	0x9B, 0xA2, 0x3F, 0x3F, 0x9B, 0xA3, 0x93, 0xD4, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x8E, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xA5, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x9B, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x8A, 0x00, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x9B, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x8A, 0xF2, 0x9B, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x9B, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x91, 0x5A, 0x8A, 0x00, 0x3F, 0x3F, 0x9B, 0x00, /* 0xA8-0xAB */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x8A, 0x78, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x9B, 0x00, /* 0xB4-0xB7 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x9B, 0x00, /* 0xB8-0xBB */
-	0x9B, 0x00, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x89, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x90, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x91, 0x5A, 0x8A, 0xE2, 0x3F, 0x3F, 0x9B, 0xAB, /* 0xA8-0xAB */
+	0x96, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x91, 0xD0, 0x3F, 0x3F, 0x8A, 0x78, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xAD, 0x9B, 0xAF, /* 0xB4-0xB7 */
+	0x8A, 0xDD, 0x3F, 0x3F, 0xED, 0x91, 0x9B, 0xAC, /* 0xB8-0xBB */
+	0x9B, 0xAE, 0x3F, 0x3F, 0x9B, 0xB1, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x9B, 0x00, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x9B, 0xB0, 0x3F, 0x3F, 0x9B, 0xB2, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x9B, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x93, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x93, 0xBB, 0x8B, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x89, 0x00, 0x9B, 0x00, 0x9B, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x95, 0x00, /* 0xEC-0xEF */
-	0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x93, 0x87, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x8F, 0x73, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x89, 0xE3, 0x9B, 0xB4, 0x9B, 0xB9, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x9B, 0xB7, 0x3F, 0x3F, 0x95, 0xF5, /* 0xEC-0xEF */
+	0x95, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0xED, 0x92, 0x93, 0x87, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xB6, 0x8F, 0x73, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x9B, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_5D[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x92, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x9B, 0x00, 0x9B, 0x00, 0x8A, 0x52, 0x9B, 0x00, /* 0x14-0x17 */
-	0x9B, 0x00, 0x9B, 0x00, 0x9B, 0x00, 0x9B, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xBA, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xE8, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x9B, 0xC0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x9B, 0xC1, 0x9B, 0xBB, 0x8A, 0x52, 0x9B, 0xBC, /* 0x14-0x17 */
+	0x9B, 0xC5, 0x9B, 0xC4, 0x9B, 0xC3, 0x9B, 0xBF, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xBE, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xC2, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x93, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x95, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x96, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x48-0x4B */
-	0x9B, 0x00, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x97, 0x92, 0x3F, 0x3F, 0x9B, 0x00, 0x00, 0x00, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xC9, /* 0x48-0x4B */
+	0x9B, 0xC6, 0x3F, 0x3F, 0x9B, 0xC8, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x97, 0x92, 0x3F, 0x3F, 0x9B, 0xC7, 0xED, 0x94, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x9B, 0xBD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x90, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x9B, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x8D, 0x00, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x9B, 0xCA, 0xED, 0x97, 0x3F, 0x3F, 0x8D, 0xB5, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xCB, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xCC, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xCF, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x9B, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xCD, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x88, /* 0x88-0x8B */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x9B, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x9B, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x9B, 0xD1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xD0, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x9B, 0x00, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x9B, 0xD2, 0x3F, 0x3F, 0x9B, 0xD3, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0xB4-0xB7 */
-	0x00, 0x00, 0x00, 0x00, 0x97, 0x00, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x9B, 0x00, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xD6, /* 0xB4-0xB7 */
+	0xED, 0x98, 0xED, 0x99, 0x97, 0xE4, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x9B, 0xD7, 0x9B, 0xD4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x8A, 0x00, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x00, 0x00, 0x3F, 0x3F, 0x9B, 0x00, 0x9B, 0x00, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x90, 0x00, 0x8F, 0x42, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x9B, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x8A, 0xDE, 0x9B, 0xD9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0xED, 0x9A, 0x3F, 0x3F, 0x9B, 0xDB, 0x9B, 0xDA, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xDC, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xDD, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x90, 0xEC, 0x8F, 0x42, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x8F, 0x84, 0x3F, 0x3F, 0x91, 0x83, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x8D, 0x48, 0x8D, 0x00, 0x8D, 0x49, /* 0xE4-0xE7 */
-	0x8B, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x8C, 0x00, 0x9B, 0x00, 0x96, 0x00, /* 0xF0-0xF3 */
-	0x94, 0x62, 0x9B, 0x00, 0x3F, 0x3F, 0x8D, 0x4A, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x92, 0x46, 0x8B, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x8D, 0x48, 0x8D, 0xB6, 0x8D, 0x49, /* 0xE4-0xE7 */
+	0x8B, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xDE, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xB7, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x8C, 0xC8, 0x9B, 0xDF, 0x96, 0xA4, /* 0xF0-0xF3 */
+	0x94, 0x62, 0x9B, 0xE0, 0x3F, 0x3F, 0x8D, 0x4A, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xAA, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x92, 0x46, 0x8B, 0xD0, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_5E[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x73, 0x95, 0x7A, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x08-0x0B */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xBF, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xE1, /* 0x08-0x0B */
+	0x8A, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x9B, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x9F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x9B, 0x00, 0x9B, 0x00, 0x9B, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x9B, 0xE3, 0x9B, 0xE2, 0x9B, 0xE5, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x92, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x90, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x74, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x91, 0x00, /* 0x2C-0x2F */
-	0x8B, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, 0x9B, 0x00, /* 0x34-0x37 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x90, 0xC8, 0x3F, 0x3F, 0x91, 0xD1, /* 0x2C-0x2F */
+	0x8B, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xA0, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xE6, 0x9B, 0xE7, /* 0x34-0x37 */
+	0x8F, 0xED, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x96, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x40-0x43 */
-	0x9B, 0x00, 0x95, 0x9D, 0x3F, 0x3F, 0x9B, 0x00, /* 0x44-0x47 */
+	0x9B, 0xEA, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xE9, /* 0x40-0x43 */
+	0x9B, 0xE8, 0x95, 0x9D, 0x3F, 0x3F, 0x9B, 0xF1, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x96, 0x79, 0x3F, 0x3F, 0x9B, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x96, 0x79, 0x3F, 0x3F, 0x9B, 0xEB, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x9B, 0x00, 0x96, 0x8B, 0x3F, 0x3F, 0x9B, 0x00, /* 0x54-0x57 */
+	0x9B, 0xED, 0x96, 0x8B, 0x3F, 0x3F, 0x9B, 0xEC, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x94, 0x00, 0x9B, 0x00, 0x95, 0x00, /* 0x60-0x63 */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xEE, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x94, 0xA6, 0x9B, 0xEF, 0x95, 0xBC, /* 0x60-0x63 */
+	0x9B, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x95, 0x00, /* 0x70-0x73 */
-	0x94, 0x4E, 0x9B, 0x00, 0x9B, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x8D, 0x4B, 0x8A, 0x00, 0x9B, 0x00, 0x8C, 0x00, /* 0x78-0x7B */
-	0x97, 0x63, 0x97, 0x48, 0x8A, 0x00, 0x9B, 0x00, /* 0x7C-0x7F */
-	
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x8D, 0x4C, /* 0x80-0x83 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xB1, 0x95, 0xBD, /* 0x70-0x73 */
+	0x94, 0x4E, 0x9B, 0xF2, 0x9B, 0xF3, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x8D, 0x4B, 0x8A, 0xB2, 0x9B, 0xF4, 0x8C, 0xB6, /* 0x78-0x7B */
+	0x97, 0x63, 0x97, 0x48, 0x8A, 0xF4, 0x9B, 0xF6, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x92, 0xA1, 0x3F, 0x3F, 0x8D, 0x4C, /* 0x80-0x83 */
+	0x8F, 0xAF, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xDD, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xB0, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x98, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x92, 0x00, 0x95, 0x00, 0x93, 0x58, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x92, 0xEA, 0x95, 0xF7, 0x93, 0x58, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x4D, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x95, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x78, 0x8D, 0x00, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x9B, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x78, 0x8D, 0xC0, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xC9, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x92, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x88, 0x00, 0x8F, 0x8E, 0x8D, 0x4E, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x88, 0xC1, 0x8F, 0x8E, 0x8D, 0x4E, /* 0xB4-0xB7 */
 	0x97, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x9B, 0x00, 0x9B, 0x00, 0x94, 0x70, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x9B, 0xF8, 0x9B, 0xF9, 0x94, 0x70, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x9B, 0x00, 0x97, 0x00, 0x98, 0x4C, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0x00, /* 0xCC-0xCF */
-	0x9B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x66, /* 0xD0-0xD3 */
+	0x9B, 0xFA, 0x97, 0xF5, 0x98, 0x4C, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9B, 0xFC, /* 0xCC-0xCF */
+	0x9B, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x66, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x40, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x43, 0x9C, 0x44, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x9C, 0x42, 0x3F, 0x3F, 0x95, 0x5F, /* 0xDC-0xDF */
-	0x8F, 0x00, 0x9C, 0x46, 0x9C, 0x45, 0x9C, 0x41, /* 0xE0-0xE3 */
+	0x8F, 0xB1, 0x9C, 0x46, 0x9C, 0x45, 0x9C, 0x41, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x9C, 0x47, 0x9C, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x9C, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x9C, 0x4C, 0x9C, 0x4A, 0x3F, 0x3F, 0x9C, 0x4B, /* 0xF0-0xF3 */
-	0x9C, 0x4D, 0x3F, 0x3F, 0x89, 0x84, 0x92, 0x00, /* 0xF4-0xF7 */
-	0x9C, 0x4E, 0x3F, 0x3F, 0x8C, 0x9A, 0x89, 0x00, /* 0xF8-0xFB */
-	0x94, 0x55, 0x3F, 0x3F, 0x9C, 0x4F, 0x93, 0x00, /* 0xFC-0xFF */
+	0x9C, 0x4D, 0x3F, 0x3F, 0x89, 0x84, 0x92, 0xEC, /* 0xF4-0xF7 */
+	0x9C, 0x4E, 0x3F, 0x3F, 0x8C, 0x9A, 0x89, 0xF4, /* 0xF8-0xFB */
+	0x94, 0x55, 0x3F, 0x3F, 0x9C, 0x4F, 0x93, 0xF9, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_5F[512] = {
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x9C, 0x50, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x95, 0xD9, 0x3F, 0x3F, 0x9C, 0x50, /* 0x00-0x03 */
 	0x98, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x9C, 0x51, 0x95, 0x00, 0x9C, 0x54, /* 0x08-0x0B */
-	0x98, 0x9F, 0x98, 0x00, 0x3F, 0x3F, 0x8E, 0x00, /* 0x0C-0x0F */
-	0x93, 0x00, 0x9C, 0x55, 0x3F, 0x3F, 0x8B, 0x7C, /* 0x10-0x13 */
-	0x92, 0x00, 0x88, 0x00, 0x9C, 0x56, 0x95, 0x00, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x9C, 0x51, 0x95, 0xBE, 0x9C, 0x54, /* 0x08-0x0B */
+	0x98, 0x9F, 0x98, 0xAF, 0x3F, 0x3F, 0x8E, 0xAE, /* 0x0C-0x0F */
+	0x93, 0xF3, 0x9C, 0x55, 0x3F, 0x3F, 0x8B, 0x7C, /* 0x10-0x13 */
+	0x92, 0xA2, 0x88, 0xF8, 0x9C, 0x56, 0x95, 0xA4, /* 0x14-0x17 */
 	0x8D, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x6F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x96, 0x00, 0x8C, 0x00, 0x8C, 0x00, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xED, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xED, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x96, 0xED, 0x8C, 0xB7, 0x8C, 0xCA, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x9C, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x9C, 0x58, 0x3F, 0x3F, 0x9C, 0x5E, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x00, 0x00, 0x92, 0x00, 0x3F, 0x3F, 0x8B, 0x00, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x8E, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xED, 0x9C, 0x92, 0xA3, 0x3F, 0x3F, 0x8B, 0xAD, /* 0x34-0x37 */
 	0x9C, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x95, 0x4A, 0x3F, 0x3F, 0x92, 0x65, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x9C, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x9C, 0x5B, 0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0xED, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x9C, 0x5B, 0x3F, 0x3F, 0x8B, 0xAE, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x9C, 0x5C, 0x3F, 0x3F, 0x9C, 0x5D, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x9C, 0x5F, 0x3F, 0x3F, 0x93, 0x96, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x60, 0x9C, 0x61, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x9C, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x9C, 0x53, 0x9C, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x9C, 0x63, 0x8C, 0x60, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x46, 0x00, 0x00, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x8D, 0x00, 0x95, 0x56, 0x92, 0x00, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x46, 0xED, 0x9D, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x8D, 0xCA, 0x95, 0x56, 0x92, 0xA4, /* 0x68-0x6B */
 	0x95, 0x6A, 0x9C, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x8F, 0x00, 0x89, 0x65, 0x3F, 0x3F, 0x9C, 0x65, /* 0x70-0x73 */
+	0x8F, 0xB2, 0x89, 0x65, 0x3F, 0x3F, 0x9C, 0x65, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x66, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x69, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x96, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x94, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x69, /* 0x7C-0x7F */
 	
-	0x89, 0x9D, 0x90, 0x00, 0x9C, 0x68, 0x9C, 0x67, /* 0x80-0x83 */
-	0x8C, 0x61, 0x91, 0x00, 0x3F, 0x3F, 0x9C, 0x6D, /* 0x84-0x87 */
-	0x9C, 0x6B, 0x3F, 0x3F, 0x9C, 0x6A, 0x97, 0x00, /* 0x88-0x8B */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x89, 0x9D, 0x90, 0xAA, 0x9C, 0x68, 0x9C, 0x67, /* 0x80-0x83 */
+	0x8C, 0x61, 0x91, 0xD2, 0x3F, 0x3F, 0x9C, 0x6D, /* 0x84-0x87 */
+	0x9C, 0x6B, 0x3F, 0x3F, 0x9C, 0x6A, 0x97, 0xA5, /* 0x88-0x8B */
+	0x8C, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x8F, 0x99, 0x9C, 0x6C, 0x93, 0x6B, 0x8F, 0x5D, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xBE, /* 0x94-0x97 */
 	0x9C, 0x70, 0x9C, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x6E, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x9C, 0x71, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x9C, 0x71, 0x8C, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x9C, 0x72, 0x95, 0x9C, 0x8F, 0x7A, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x9C, 0x73, 0x94, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xB0-0xB3 */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x9C, 0x73, 0x94, 0xF7, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xBF, /* 0xB0-0xB3 */
+	0x92, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x9E, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x93, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x9C, 0x74, 0x8B, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x53, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x95, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x8A, 0x00, 0x94, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x8A, 0xF5, 0x94, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x75, 0x8E, 0x75, /* 0xD4-0xD7 */
 	0x96, 0x59, 0x96, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x89, 0x9E, 0x9C, 0x7A, 0x00, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x89, 0x9E, 0x9C, 0x7A, 0xED, 0x9F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x92, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x9C, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xF5, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x9C, 0x00, 0x9C, 0x79, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x9C, 0xAB, 0x9C, 0x79, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x94, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x9C, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x76, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x8D, 0x9A, 0x3F, 0x3F, 0x9C, 0x7C, /* 0xFC-0xFF */
@@ -5154,191 +5156,191 @@
 	0x9C, 0x81, 0x3F, 0x3F, 0x93, 0x7B, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x9C, 0x86, 0x95, 0x7C, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x9C, 0x80, 0x3F, 0x3F, 0x9C, 0x85, /* 0x18-0x1B */
-	0x97, 0x00, 0x8E, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x91, 0x00, 0x9C, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x8B, 0x7D, 0x9C, 0x88, 0x90, 0x00, /* 0x24-0x27 */
-	0x89, 0x85, 0x9C, 0x82, 0x89, 0x00, 0x9C, 0x87, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x2C-0x2F */
+	0x97, 0xE5, 0x8E, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x91, 0xD3, 0x9C, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x8B, 0x7D, 0x9C, 0x88, 0x90, 0xAB, /* 0x24-0x27 */
+	0x89, 0x85, 0x9C, 0x82, 0x89, 0xF6, 0x9C, 0x87, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xAF, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x9C, 0x84, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x8A, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x9C, 0x8C, 0x9C, 0x96, 0x9C, 0x94, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x91, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x90, 0x97, 0x00, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x90, 0x97, 0xF6, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x9C, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x8B, 0x00, 0x3F, 0x3F, 0x8D, 0x50, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x8B, 0xB0, 0x3F, 0x3F, 0x8D, 0x50, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x8F, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x9C, 0x99, 0x9C, 0x8B, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x9C, 0x8F, /* 0x5C-0x5F */
-	0x9C, 0x7E, 0x3F, 0x3F, 0x89, 0x00, 0x9C, 0x93, /* 0x60-0x63 */
+	0x3F, 0x3F, 0xED, 0xA0, 0x3F, 0x3F, 0x9C, 0x8F, /* 0x5C-0x5F */
+	0x9C, 0x7E, 0x3F, 0x3F, 0x89, 0xF8, 0x9C, 0x93, /* 0x60-0x63 */
 	0x9C, 0x95, 0x92, 0x70, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x8D, 0x00, 0x89, 0x00, 0x9C, 0x8D, 0x9C, 0x98, /* 0x68-0x6B */
-	0x9C, 0x97, 0x8B, 0x00, 0x3F, 0x3F, 0x91, 0x00, /* 0x6C-0x6F */
+	0x8D, 0xA6, 0x89, 0xB6, 0x9C, 0x8D, 0x9C, 0x98, /* 0x68-0x6B */
+	0x9C, 0x97, 0x8B, 0xB1, 0x3F, 0x3F, 0x91, 0xA7, /* 0x6C-0x6F */
 	0x8A, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x8C, 0x62, 0x3F, 0x3F, 0x9C, 0x8E, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x9C, 0x9A, 0x3F, 0x3F, 0x9C, 0x9D, /* 0x80-0x83 */
-	0x9C, 0x9F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x00, 0x00, 0x9C, 0x00, /* 0x88-0x8B */
-	0x92, 0x00, 0x9C, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x89, 0x00, 0x3F, 0x3F, 0x9C, 0x00, 0x9C, 0x00, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x9E, 0x9C, 0x00, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x9C-0x9F */
-	0x97, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x78, 0x9C, 0x00, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x94, 0x59, 0x88, 0x00, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x9C, 0x9F, 0xED, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x8E, 0xBB, 0xED, 0xA2, 0x9C, 0xA5, /* 0x88-0x8B */
+	0x92, 0xEE, 0x9C, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xA3, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x89, 0xF7, 0x3F, 0x3F, 0x9C, 0xA1, 0x9C, 0xA2, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x9E, 0x9C, 0xA0, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xE5, /* 0x9C-0x9F */
+	0x97, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xB3, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x78, 0x9C, 0xA4, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x94, 0x59, 0x88, 0xAB, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x9C, 0x7B, /* 0xB0-0xB3 */
-	0x9C, 0x00, 0x9C, 0x00, 0x96, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x93, 0x89, 0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xDF, 0x9C, 0x7B, /* 0xB0-0xB3 */
+	0x9C, 0xAA, 0x9C, 0xAE, 0x96, 0xE3, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x9C, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x93, 0x89, 0x9C, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x8F, 0x00, 0x9C, 0x00, 0x93, 0x00, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x8F, 0xEE, 0x9C, 0xAD, 0x93, 0xD5, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x98, 0x66, 0x3F, 0x3F, 0x9C, 0x00, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x8D, 0x9B, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x90, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x88, 0x00, /* 0xDC-0xDF */
-	0x9C, 0x00, 0x9C, 0x00, 0x3F, 0x3F, 0x91, 0x79, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x98, 0x66, 0x3F, 0x3F, 0x9C, 0xA9, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xED, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x9C, 0xAF, 0x3F, 0x3F, 0x8D, 0x9B, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x90, 0xC9, 0x3F, 0x3F, 0xED, 0xA3, 0x88, 0xD2, /* 0xDC-0xDF */
+	0x9C, 0xA8, 0x9C, 0xA6, 0x3F, 0x3F, 0x91, 0x79, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x9C, /* 0xE4-0xE7 */
 	0x8E, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x91, 0x00, 0x9C, 0x00, 0x00, 0x00, 0x91, 0x7A, /* 0xF0-0xF3 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x9C, 0x00, 0x9C, 0x00, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x9C, 0x00, 0x9C, 0x00, /* 0xF8-0xFB */
+	0x91, 0xC4, 0x9C, 0xBB, 0xED, 0xA6, 0x91, 0x7A, /* 0xF0-0xF3 */
+	0x9C, 0xB6, 0x3F, 0x3F, 0x9C, 0xB3, 0x9C, 0xB4, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x8E, 0xE4, 0x9C, 0xB7, 0x9C, 0xBA, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_61[512] = {
-	0x9C, 0x00, 0x8F, 0x44, 0x3F, 0x3F, 0x9C, 0x00, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x96, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x9C, 0x00, 0x9C, 0x00, 0x88, 0x00, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x88, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0x1C-0x1F */
-	0x00, 0x00, 0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0x24-0x27 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x34-0x37 */
+	0x9C, 0xB5, 0x8F, 0x44, 0x3F, 0x3F, 0x9C, 0xB8, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xB2, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x96, 0xFA, 0x96, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x9C, 0xBC, 0x9C, 0xBD, 0x88, 0xD3, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xED, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x9C, 0xB1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xF0, 0x88, 0xA4, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xB4, /* 0x1C-0x1F */
+	0xED, 0xA5, 0x9C, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xC1, /* 0x24-0x27 */
+	0x9C, 0xC0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x9C, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xED, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x9C, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xA8, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0x44-0x47 */
-	0x8E, 0x9C, 0x3F, 0x3F, 0x9C, 0x00, 0x91, 0x00, /* 0x48-0x4B */
-	0x8D, 0x51, 0x9C, 0x00, 0x90, 0x54, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, 0x9C, 0x00, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x9D, 0x8A, 0x00, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, 0x8C, 0x64, /* 0x64-0x67 */
-	0x8A, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x9C, 0x00, /* 0x6C-0x6F */
-	0x88, 0x00, 0x9C, 0x00, 0x3F, 0x3F, 0x9C, 0x00, /* 0x70-0x73 */
-	0x9C, 0x00, 0x9C, 0x00, 0x8C, 0x63, 0x9C, 0x00, /* 0x74-0x77 */
+	0x9C, 0xC4, 0x9C, 0xC7, 0x9C, 0xBF, 0x9C, 0xC3, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xC8, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x9C, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xBE, /* 0x44-0x47 */
+	0x8E, 0x9C, 0x3F, 0x3F, 0x9C, 0xC2, 0x91, 0xD4, /* 0x48-0x4B */
+	0x8D, 0x51, 0x9C, 0xB0, 0x90, 0x54, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xD6, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x95, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x9C, 0xCC, 0x9C, 0xCD, 0x9C, 0xCE, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x9C, 0xD5, 0x3F, 0x3F, 0x9C, 0xD4, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x9D, 0x8A, 0xB5, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x9C, 0xD2, 0x3F, 0x3F, 0x8C, 0x64, /* 0x64-0x67 */
+	0x8A, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xCF, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xB6, 0x9C, 0xD1, /* 0x6C-0x6F */
+	0x88, 0xD4, 0x9C, 0xD3, 0x3F, 0x3F, 0x9C, 0xCA, /* 0x70-0x73 */
+	0x9C, 0xD0, 0x9C, 0xD7, 0x8C, 0x63, 0x9C, 0xCB, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x7C, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x4A, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xDA, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xDE, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x9E, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x97, 0x00, 0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x00, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x97, 0xF7, 0x9C, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x9C, 0xDC, 0x3F, 0x3F, 0x9C, 0xD9, 0x3F, 0x3F, /* 0x94-0x97 */
+	0xED, 0xAA, 0x9C, 0xD8, 0x9C, 0xDD, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x8C, 0x65, 0x3F, 0x3F, 0x9C, 0x00, /* 0xA8-0xAB */
-	0x9C, 0x00, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x95, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xB2, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x8C, 0x65, 0x3F, 0x3F, 0x9C, 0xE0, /* 0xA8-0xAB */
+	0x9C, 0xDB, 0x3F, 0x3F, 0x9C, 0xE1, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x9B, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x8D, 0x00, /* 0xC4-0xC7 */
-	0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, /* 0xC8-0xCB */
-	0x9C, 0x00, 0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xAF, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xE9, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xB6, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xE7, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xE8, 0x8D, 0xA7, /* 0xC4-0xC7 */
+	0x9C, 0xE6, 0x9C, 0xE4, 0x9C, 0xE3, 0x9C, 0xEA, /* 0xC8-0xCB */
+	0x9C, 0xE2, 0x9C, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x89, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xEE, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9C, 0xED, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x9C, 0x00, 0x9C, 0x00, /* 0xF4-0xF7 */
-	0x8C, 0x9C, 0x3F, 0x3F, 0x9C, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, 0x9C, 0x00, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xA6, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x9C, 0xF1, 0x3F, 0x3F, 0x9C, 0xEF, 0x9C, 0xE5, /* 0xF4-0xF7 */
+	0x8C, 0x9C, 0x3F, 0x3F, 0x9C, 0xF0, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x9C, 0xF4, 0x9C, 0xF3, 0x9C, 0xF5, 0x9C, 0xF2, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_62[512] = {
-	0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x9C, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x9C, 0x00, 0x9C, 0x00, 0x95, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x9C, 0x00, 0x9C, 0x00, 0x8F, 0x5E, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x90, 0x00, 0x89, 0x00, 0x89, 0x00, 0x00, 0x00, /* 0x10-0x13 */
-	0x9C, 0x00, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x9C, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x00, 0x00, 0x9D, 0x40, 0x8C, 0x81, /* 0x1C-0x1F */
+	0x9C, 0xF7, 0x9C, 0xF8, 0x95, 0xE8, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x9C, 0xFA, 0x9C, 0xF9, 0x8F, 0x5E, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x90, 0xAC, 0x89, 0xE4, 0x89, 0xFA, 0xED, 0xAB, /* 0x10-0x13 */
+	0x9C, 0xFB, 0x3F, 0x3F, 0x88, 0xBD, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xCA, 0x9C, 0xFC, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE6, 0xC1, 0x9D, 0x40, 0x8C, 0x81, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x9D, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xED, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x42, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x43, 0x8B, 0x59, /* 0x2C-0x2F */
 	0x9D, 0x44, 0x3F, 0x3F, 0x9D, 0x45, 0x9D, 0x46, /* 0x30-0x33 */
-	0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0x38-0x3B */
+	0x91, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x8C, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xDF, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x5B, /* 0x3C-0x3F */
 	0x8F, 0x8A, 0x9D, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0x44-0x47 */
-	0x00, 0x00, 0x94, 0x00, 0x3F, 0x3F, 0x8E, 0x00, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x8D, 0x00, 0x9D, 0x48, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x4B, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xEE, /* 0x44-0x47 */
+	0xE7, 0xBB, 0x94, 0xE0, 0x3F, 0x3F, 0x8E, 0xE8, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x8D, 0xCB, 0x9D, 0x48, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xC5, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x95, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x91, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x4B, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x49, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x9D, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x4A, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x9D, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xAF, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x88, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x7D, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x9D, 0x4E, 0x3F, 0x3F, 0x9D, 0x51, 0x8F, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x94, 0xE1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x9D, 0x4E, 0x3F, 0x3F, 0x9D, 0x51, 0x8F, 0xB3, /* 0x7C-0x7F */
 	
 	0x8B, 0x5A, 0x3F, 0x3F, 0x9D, 0x4F, 0x9D, 0x56, /* 0x80-0x83 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x8F, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x9D, 0x50, 0x94, 0x63, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x97, 0x7D, 0x9D, 0x52, 0x9D, 0x53, /* 0x90-0x93 */
 	0x9D, 0x57, 0x93, 0x8A, 0x9D, 0x54, 0x8D, 0x52, /* 0x94-0x97 */
-	0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x65, /* 0x98-0x9B */
-	0x94, 0x00, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x90, 0xDC, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x65, /* 0x98-0x9B */
+	0x94, 0xB2, 0x3F, 0x3F, 0x91, 0xF0, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0xA8-0xAB */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xAC, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xE2, /* 0xA8-0xAB */
+	0x9D, 0xAB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x95, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x92, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x96, 0x95, 0x3F, 0x3F, 0x9D, 0x5A, /* 0xB8-0xBB */
 	0x89, 0x9F, 0x92, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x63, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x92, 0x53, 0x9D, 0x5D, 0x9D, 0x64, /* 0xC4-0xC7 */
 	0x9D, 0x5F, 0x9D, 0x66, 0x9D, 0x62, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x9D, 0x61, 0x94, 0x8F, 0x3F, 0x3F, 0x9D, 0x5B, /* 0xCC-0xCF */
-	0x89, 0x00, 0x9D, 0x59, 0x8B, 0x91, 0x91, 0x00, /* 0xD0-0xD3 */
+	0x89, 0xFB, 0x9D, 0x59, 0x8B, 0x91, 0x91, 0xF1, /* 0xD0-0xD3 */
 	0x9D, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x58, /* 0xD4-0xD7 */
-	0x8D, 0x53, 0x90, 0x00, 0x3F, 0x3F, 0x8F, 0x00, /* 0xD8-0xDB */
+	0x8D, 0x53, 0x90, 0xD9, 0x3F, 0x3F, 0x8F, 0xB5, /* 0xD8-0xDB */
 	0x9D, 0x60, 0x94, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x8B, 0x92, 0x8A, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
@@ -5353,67 +5355,67 @@
 static unsigned char u2c_63[512] = {
 	0x3F, 0x3F, 0x8E, 0x9D, 0x9D, 0x6B, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x77, /* 0x04-0x07 */
-	0x9D, 0x6C, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x9D, 0x6C, 0x88, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x9D, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x92, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x8B, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xB2, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x6A, /* 0x24-0x27 */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, /* 0x28-0x2B */
+	0x88, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xC1, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x55, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x94, 0x00, 0x9D, 0x70, 0x91, 0x7D, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xF0, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x94, 0xD2, 0x9D, 0x70, 0x91, 0x7D, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x91, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x8E, 0x4A, 0x9D, 0x71, 0x3F, 0x3F, 0x9D, 0x73, /* 0x4C-0x4F */
 	0x9D, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x92, 0x00, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x95, 0xDF, 0x3F, 0x3F, 0x92, 0xBB, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x91, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x64-0x67 */
-	0x8E, 0x00, 0x9D, 0x80, 0x3F, 0x3F, 0x9D, 0x7E, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xF9, /* 0x64-0x67 */
+	0x8E, 0xCC, 0x9D, 0x80, 0x3F, 0x3F, 0x9D, 0x7E, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x98, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x9E, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x78, 0x8F, 0x00, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, 0x94, 0x50, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x78, 0x8F, 0xB7, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xE6, 0x94, 0x50, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x9D, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x7C, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x8E, 0x00, 0x9D, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x8F, 0x00, 0x3F, 0x3F, 0x9D, 0x75, 0x9D, 0x7A, /* 0x8C-0x8F */
+	0x8E, 0xF6, 0x9D, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x8F, 0xB6, 0x3F, 0x3F, 0x9D, 0x75, 0x9D, 0x7A, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x72, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x74, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x8C, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x7C, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x7C, /* 0x9C-0x9F */
-	0x97, 0x00, 0x8D, 0x00, 0x92, 0x54, 0x9D, 0x79, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x8D, 0x54, /* 0xA4-0xA7 */
+	0x97, 0xA9, 0x8D, 0xCC, 0x92, 0x54, 0x9D, 0x79, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x90, 0xDA, 0x3F, 0x3F, 0x8D, 0x54, /* 0xA4-0xA7 */
 	0x90, 0x84, 0x89, 0x86, 0x91, 0x5B, 0x9D, 0x77, /* 0xA8-0xAB */
 	0x8B, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x66, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x92, 0x00, 0x9D, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x92, 0xCD, 0x9D, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x7E, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x81, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x9D, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0xC0-0xC3 */
+	0x9D, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xB5, /* 0xC0-0xC3 */
 	0x9D, 0x89, 0x3F, 0x3F, 0x9D, 0x84, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x9D, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x60, /* 0xCC-0xCF */
-	0x92, 0x00, 0x3F, 0x3F, 0x9D, 0x87, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x92, 0xF1, 0x3F, 0x3F, 0x9D, 0x87, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x4B, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x67, 0x8A, 0x00, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x67, 0x8A, 0xB7, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x9D, 0x85, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x88, 0xAC, 0x3F, 0x3F, 0x9D, 0x85, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x9D, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xF6, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x89, 0x87, 0x00, 0x00, 0x9D, 0x88, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x89, 0x87, 0xED, 0xAD, 0x9D, 0x88, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x68, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
@@ -5422,7 +5424,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x8C, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x9D, 0x93, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x91, 0xB9, 0x3F, 0x3F, 0x9D, 0x93, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x8D, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x8A, 0x9D, 0x91, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
@@ -5430,12 +5432,12 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x8E, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x9D, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x94, 0x00, 0x93, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x94, 0xC0, 0x93, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x9D, 0x8B, 0x3F, 0x3F, 0x9D, 0x8F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x67, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xEF, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xDB, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x97, 0x3F, 0x3F, /* 0x4C-0x4F */
@@ -5443,13 +5445,13 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x93, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xED, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x94, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x96, 0x80, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x95, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x96, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x96, 0x00, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x96, 0xCC, 0x3F, 0x3F, 0x90, 0xA0, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x82, /* 0x80-0x83 */
@@ -5459,154 +5461,154 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x54, 0x9D, 0x9A, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x9D, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x51, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x00, 0x00, 0x93, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0xED, 0xAF, 0x93, 0xB3, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x93, 0x50, 0x9D, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x9D, 0x9C, 0x3F, 0x3F, 0x95, 0x8F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x94, 0x64, 0x8E, 0x42, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x90, 0x00, 0x3F, 0x3F, 0x96, 0x6F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x90, 0xEF, 0x3F, 0x3F, 0x96, 0x6F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x8A, 0x68, 0x3F, 0x3F, 0x9D, 0x00, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x8A, 0x68, 0x3F, 0x3F, 0x9D, 0xA3, /* 0xB8-0xBB */
 	0x9D, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x97, 0x69, 0x9D, 0x00, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x9D, 0x00, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x97, 0x69, 0x9D, 0xA5, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x9D, 0xA1, 0x3F, 0x3F, 0x9D, 0xA2, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x91, 0x80, 0x00, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x91, 0x80, 0xED, 0xB0, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xA0, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x9D, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x9D, 0x9F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x9D, 0xA4, 0x3F, 0x3F, 0x9D, 0x9F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x9D, 0x00, 0x9D, 0x00, 0x93, 0x46, 0x9D, 0x00, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x43, 0x9D, 0x00, /* 0xE4-0xE7 */
+	0x9D, 0xA9, 0x9D, 0xAA, 0x93, 0x46, 0x9D, 0xAC, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x43, 0x9D, 0xA7, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x8B, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x9D, 0x00, 0x9D, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x9D, 0x00, 0x8F, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x8B, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xAD, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x9D, 0xA6, 0x9D, 0xB1, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x9D, 0xB0, 0x3F, 0x3F, 0x9D, 0xAF, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xB2, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x9D, 0xB4, 0x8F, 0xEF, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_65[512] = {
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x9D, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x9D, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x9D, 0x00, 0x9D, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, /* 0x20-0x23 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x98, 0x9D, 0x00, /* 0x28-0x2B */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x78, /* 0x2C-0x2F */
+	0x9D, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x9D, 0xB6, 0x9D, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xB9, /* 0x20-0x23 */
+	0x9D, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x98, 0x9D, 0xBA, /* 0x28-0x2B */
+	0x9D, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x78, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x9D, 0x00, 0x9D, 0x00, 0x9D, 0x00, 0x9D, 0x00, /* 0x34-0x37 */
-	0x9D, 0x00, 0x89, 0x00, 0x3F, 0x3F, 0x8D, 0x55, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x90, 0x00, /* 0x3C-0x3F */
+	0x9D, 0xBB, 0x9D, 0xBC, 0x9D, 0xBE, 0x9D, 0xBD, /* 0x34-0x37 */
+	0x9D, 0xBF, 0x89, 0xFC, 0x3F, 0x3F, 0x8D, 0x55, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xFA, 0x90, 0xAD, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x9D, 0x00, 0x00, 0x00, 0x95, 0x71, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x8C, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x9D, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x9D, 0xC4, 0xED, 0xB1, 0x95, 0x71, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x8B, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x9D, 0x00, 0x9D, 0x00, 0x94, 0x73, /* 0x54-0x57 */
-	0x9D, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x9D, 0x00, 0x9D, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x8E, 0x55, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x9D, 0xC3, 0x9D, 0xC2, 0x94, 0x73, /* 0x54-0x57 */
+	0x9D, 0xC5, 0x8B, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x9D, 0xC7, 0x9D, 0xC6, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xB8, 0x8E, 0x55, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xD6, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x8C, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x90, 0x94, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x90, 0x00, 0x93, 0x47, 0x3F, 0x3F, 0x95, 0x7E, /* 0x74-0x77 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x90, 0x94, 0x3F, 0x3F, 0x9D, 0xC8, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x90, 0xAE, 0x93, 0x47, 0x3F, 0x3F, 0x95, 0x7E, /* 0x74-0x77 */
+	0x9D, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x9D, 0x00, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x84-0x87 */
-	0x9B, 0x7C, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x95, 0x6B, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x94, 0x00, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xCA, 0x9D, 0xCB, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xB6, /* 0x84-0x87 */
+	0x9B, 0x7C, 0x90, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x95, 0x6B, 0x3F, 0x3F, 0x8D, 0xD6, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x94, 0xE3, 0x94, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x6C, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x9D, 0x00, /* 0x98-0x9B */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x8B, 0x00, 0x90, 0x00, 0x3F, 0x3F, 0x95, 0x80, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x97, 0xBF, 0x3F, 0x3F, 0x9D, 0xCD, /* 0x98-0x9B */
+	0x8E, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xCE, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x88, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x8B, 0xD2, 0x90, 0xCB, 0x3F, 0x3F, 0x95, 0x80, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xCF, /* 0xA8-0xAB */
 	0x8E, 0x61, 0x92, 0x66, 0x3F, 0x3F, 0x8E, 0x7A, /* 0xAC-0xAF */
 	0x90, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xD0, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x95, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x89, 0x97, 0x8E, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x9D, 0x00, /* 0xC0-0xC3 */
-	0x9D, 0x00, 0x97, 0x00, 0x9D, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0xC8-0xCB */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x9D, 0x00, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x9D, 0xD3, 0x3F, 0x3F, 0x9D, 0xD1, /* 0xC0-0xC3 */
+	0x9D, 0xD4, 0x97, 0xB7, 0x9D, 0xD2, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xF9, /* 0xC8-0xCB */
+	0x9D, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xB0, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xD6, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xF8, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x9D, 0xD8, 0x3F, 0x3F, 0x9D, 0xD7, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x9D, 0x00, 0x9D, 0x00, 0x8A, 0x00, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x93, 0x00, 0x92, 0x55, 0x8B, 0x8C, /* 0xE4-0xE7 */
+	0x9D, 0xD9, 0x9D, 0xDA, 0x8A, 0xF9, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x93, 0xFA, 0x92, 0x55, 0x8B, 0x8C, /* 0xE4-0xE7 */
 	0x8E, 0x7C, 0x91, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x8F, 0x7B, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x8F, 0x7B, 0x88, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x9D, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x9D, 0x00, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xA0, 0x9D, 0xDF, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_66[512] = {
-	0x00, 0x00, 0x3F, 0x3F, 0x8D, 0x56, 0x9D, 0x00, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x8F, 0x00, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x00, 0x9D, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x8F, 0x00, 0x3F, 0x3F, 0x96, 0x00, 0x8D, 0x00, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0x10-0x13 */
-	0x90, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0xED, 0xB2, 0x3F, 0x3F, 0x8D, 0x56, 0x9D, 0xDE, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xA9, 0x8F, 0xB8, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xED, 0xB5, 0x9D, 0xDD, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x8F, 0xB9, 0x3F, 0x3F, 0x96, 0xBE, 0x8D, 0xA8, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xD5, /* 0x10-0x13 */
+	0x90, 0xCC, 0xED, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x9D, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x90, 0x00, /* 0x1C-0x1F */
+	0x9D, 0xE4, 0x3F, 0x3F, 0xED, 0xB7, 0x90, 0xAF, /* 0x1C-0x1F */
 	0x89, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x00, 0x8F, 0x74, 0x3F, 0x3F, 0x96, 0x86, /* 0x24-0x27 */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x8F, 0x00, 0x00, 0x00, 0x90, 0x00, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x63, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x9D, 0x00, 0x9D, 0x00, 0x9D, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x38-0x3B */
+	0xED, 0xB8, 0x8F, 0x74, 0x3F, 0x3F, 0x96, 0x86, /* 0x24-0x27 */
+	0x8D, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x8F, 0xBA, 0xED, 0xB6, 0x90, 0xA5, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0xED, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x9D, 0xE3, 0x9D, 0xE1, 0x9D, 0xE2, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xB4, /* 0x38-0x3B */
 	0x92, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x45, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x9D, 0x00, 0x8E, 0x9E, 0x8D, 0x57, /* 0x40-0x43 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x90, 0x57, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x9D, 0xE8, 0x8E, 0x9E, 0x8D, 0x57, /* 0x40-0x43 */
+	0x9D, 0xE6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x9D, 0xE7, 0x3F, 0x3F, 0x90, 0x57, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xE5, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x4E, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x9D, 0x00, 0x9D, 0x00, 0x9D, 0x00, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x9D, 0x00, 0x00, 0x00, 0x8A, 0x41, 0x9D, 0x00, /* 0x64-0x67 */
-	0x9D, 0x00, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xBA, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xED, 0xBB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x9D, 0xEA, 0x9D, 0xE9, 0x9D, 0xEE, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xEF, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x9D, 0xEB, 0xED, 0xB9, 0x8A, 0x41, 0x9D, 0xEC, /* 0x64-0x67 */
+	0x9D, 0xED, 0x94, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x81, 0x8C, 0x69, /* 0x6C-0x6F */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x70-0x73 */
-	0x90, 0x00, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x9D, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xBD, /* 0x70-0x73 */
+	0x90, 0xB0, 0x3F, 0x3F, 0x8F, 0xBB, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x71, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x9D, 0x00, /* 0x80-0x83 */
-	0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0x84-0x87 */
-	0x9D, 0x00, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x8B, 0xC5, 0x3F, 0x3F, 0x9D, 0xF1, /* 0x80-0x83 */
+	0x9D, 0xF5, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xC9, /* 0x84-0x87 */
+	0x9D, 0xF2, 0x9D, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xF3, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x8F, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x67, 0x88, 0x00, /* 0x94-0x97 */
-	0x9D, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x00, 0x00, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x67, 0x88, 0xC3, /* 0x94-0x97 */
+	0x9D, 0xF6, 0xED, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x9D, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xED, 0xBF, 0x3F, 0x3F, 0x92, 0xA8, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xEF, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x62, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xE9, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xC0, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x96, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x9E, 0x41, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x9D, 0x00, 0x3F, 0x3F, 0x9D, 0x00, 0x00, 0x00, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x9E, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x9E, 0x41, 0x9D, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x9D, 0xFC, 0x3F, 0x3F, 0x9D, 0xFB, 0xED, 0xC1, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x9D, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x9E, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xDC, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x9D, 0xFA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x42, 0x3F, 0x3F, /* 0xD4-0xD7 */
@@ -5616,87 +5618,87 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x46, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x9E, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x9E, 0x48, 0x3F, 0x3F, 0x8B, 0x00, 0x89, 0x67, /* 0xF0-0xF3 */
+	0x9E, 0x48, 0x3F, 0x3F, 0x8B, 0xC8, 0x89, 0x67, /* 0xF0-0xF3 */
 	0x8D, 0x58, 0x9E, 0x49, 0x3F, 0x3F, 0x9E, 0x4A, /* 0xF4-0xF7 */
-	0x8F, 0x91, 0x91, 0x82, 0x00, 0x00, 0x00, 0x66, /* 0xF8-0xFB */
-	0x99, 0x00, 0x91, 0x5D, 0x91, 0x5C, 0x91, 0x00, /* 0xFC-0xFF */
+	0x8F, 0x91, 0x91, 0x82, 0xED, 0xC2, 0xED, 0x4A, /* 0xF8-0xFB */
+	0x99, 0xD6, 0x91, 0x5D, 0x91, 0x5C, 0x91, 0xD6, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_67[512] = {
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x00, /* 0x00-0x03 */
+	0x8D, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0xF0, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x8C, 0x8E, 0x97, 0x4C, 0x3F, 0x3F, 0x95, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x95, 0x9E, 0x00, 0x00, 0x9E, 0x4B, /* 0x0C-0x0F */
+	0x8C, 0x8E, 0x97, 0x4C, 0x3F, 0x3F, 0x95, 0xFC, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x95, 0x9E, 0xED, 0xC3, 0x9E, 0x4B, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x8D, 0x00, 0x92, 0x00, 0x9E, 0x4C, 0x98, 0x4E, /* 0x14-0x17 */
+	0x8D, 0xF1, 0x92, 0xBD, 0x9E, 0x4C, 0x98, 0x4E, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x5D, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x92, 0x00, 0x9E, 0x4D, 0x8A, 0x00, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x92, 0xA9, 0x9E, 0x4D, 0x8A, 0xFA, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x4E, 0x9E, 0x4F, /* 0x24-0x27 */
-	0x96, 0x00, 0x3F, 0x3F, 0x96, 0x00, 0x96, 0x96, /* 0x28-0x2B */
+	0x96, 0xD8, 0x3F, 0x3F, 0x96, 0xA2, 0x96, 0x96, /* 0x28-0x2B */
 	0x96, 0x7B, 0x8E, 0x44, 0x9E, 0x51, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x8E, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x96, 0x70, 0x3F, 0x3F, 0x9E, 0x53, 0x9E, 0x56, /* 0x34-0x37 */
-	0x9E, 0x55, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x9E, 0x55, 0x3F, 0x3F, 0x8A, 0xF7, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x8B, 0x80, 0x3F, 0x3F, 0x9E, 0x52, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x9E, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x57, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x90, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x9B, 0x88, 0x00, /* 0x4C-0x4F */
-	0x8D, 0x00, 0x91, 0x00, 0x3F, 0x3F, 0x8E, 0x00, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x9B, 0x88, 0xC7, /* 0x4C-0x4F */
+	0x8D, 0xDE, 0x91, 0xBA, 0x3F, 0x3F, 0x8E, 0xDB, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xF1, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x9E, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x93, 0x6D, 0x3F, 0x3F, 0x9E, 0x58, 0x91, 0x00, /* 0x5C-0x5F */
-	0x9E, 0x59, 0x8F, 0x00, 0x96, 0x00, 0x9E, 0x5B, /* 0x60-0x63 */
-	0x9E, 0x5C, 0x97, 0x88, 0x00, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x93, 0x6D, 0x3F, 0x3F, 0x9E, 0x58, 0x91, 0xA9, /* 0x5C-0x5F */
+	0x9E, 0x59, 0x8F, 0xF0, 0x96, 0xDB, 0x9E, 0x5B, /* 0x60-0x63 */
+	0x9E, 0x5C, 0x97, 0x88, 0xED, 0xC5, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x61, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x8D, 0x59, 0x3F, 0x3F, 0x94, 0x74, /* 0x6C-0x6F */
-	0x9E, 0x5E, 0x93, 0x8C, 0x9D, 0x00, 0x9D, 0x00, /* 0x70-0x73 */
+	0x9E, 0x5E, 0x93, 0x8C, 0x9D, 0xDC, 0x9D, 0xE0, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x8B, 0x6E, 0x3F, 0x3F, 0x94, 0x66, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x9E, 0x60, 0x3F, 0x3F, 0x8F, 0x00, 0x94, 0x00, /* 0x7C-0x7F */
+	0x9E, 0x60, 0x3F, 0x3F, 0x8F, 0xBC, 0x94, 0xC2, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x9E, 0x66, 0x3F, 0x3F, 0x94, 0x00, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x9E, 0x66, 0x3F, 0x3F, 0x94, 0xF8, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x9E, 0x5D, 0x3F, 0x3F, 0x9E, 0x63, /* 0x88-0x8B */
 	0x9E, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x96, 0x8D, 0x3F, 0x3F, 0x97, 0x00, /* 0x94-0x97 */
+	0x90, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x96, 0x8D, 0x3F, 0x3F, 0x97, 0xD1, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x87, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x89, 0x00, 0x8E, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x89, 0xCA, 0x8E, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x98, 0x67, 0x9E, 0x65, 0x90, 0x95, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x64, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x9E, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xCD, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x6B, /* 0xB0-0xB3 */
-	0x9E, 0x69, 0x3F, 0x3F, 0x89, 0x00, 0x9E, 0x67, /* 0xB4-0xB7 */
-	0x9E, 0x6D, 0x9E, 0x73, 0x3F, 0x3F, 0x00, 0x00, /* 0xB8-0xBB */
+	0x9E, 0x69, 0x3F, 0x3F, 0x89, 0xCB, 0x9E, 0x67, /* 0xB4-0xB7 */
+	0x9E, 0x6D, 0x9E, 0x73, 0x3F, 0x3F, 0xED, 0xC6, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x00, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x95, 0x00, 0x3F, 0x3F, 0x9E, 0x75, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0xED, 0xC8, 0x91, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x95, 0xBF, 0x3F, 0x3F, 0x9E, 0x75, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x41, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x74, 0x94, 0x90, /* 0xCC-0xCF */
-	0x96, 0x5E, 0x8A, 0x00, 0x3F, 0x3F, 0x90, 0x00, /* 0xD0-0xD3 */
+	0x96, 0x5E, 0x8A, 0xB9, 0x3F, 0x3F, 0x90, 0xF5, /* 0xD0-0xD3 */
 	0x8F, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x92, 0x00, 0x3F, 0x3F, 0x97, 0x4D, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x92, 0xD1, 0x3F, 0x3F, 0x97, 0x4D, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x9E, 0x70, 0x9E, 0x6F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x71, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x9E, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x76, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x9E, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x9E, 0x6A, 0x3F, 0x3F, 0x9E, 0x72, 0x9E, 0x68, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x92, 0x8C, 0x3F, 0x3F, 0x96, 0x00, /* 0xF0-0xF3 */
-	0x8E, 0x00, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x92, 0x8C, 0x3F, 0x3F, 0x96, 0xF6, /* 0xF0-0xF3 */
+	0x8E, 0xC4, 0x8D, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xB8, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x8F, 0x8A, 0x60, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_68[512] = {
-	0x3F, 0x3F, 0x00, 0x00, 0x92, 0x00, 0x93, 0x00, /* 0x00-0x03 */
+	0x3F, 0x3F, 0xED, 0xC9, 0x92, 0xCC, 0x93, 0xC8, /* 0x00-0x03 */
 	0x89, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x8C, 0x49, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xF0, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xB2, 0x8C, 0x49, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x78, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x8D, 0x5A, 0x8A, 0x9C, 0x3F, 0x3F, /* 0x20-0x23 */
@@ -5704,171 +5706,171 @@
 	0x3F, 0x3F, 0x9E, 0x7A, 0x8A, 0x94, 0x9E, 0x81, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x7D, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x8A, 0x6A, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x8A, 0x69, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x90, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x8A, 0x6A, 0x8D, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x8A, 0x69, 0x8D, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x9E, 0x7B, 0x8C, 0x85, 0x8C, 0x6A, 0x93, 0x8D, /* 0x40-0x43 */
-	0x00, 0x00, 0x3F, 0x3F, 0x9E, 0x79, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xED, 0xCA, 0x3F, 0x3F, 0x9E, 0x79, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x88, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x9E, 0x7C, 0x9E, 0x7E, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x8B, 0x00, 0x8C, 0x4B, 0x00, 0x00, 0x8A, 0x00, /* 0x50-0x53 */
+	0x8B, 0xCB, 0x8C, 0x4B, 0xED, 0xC7, 0x8A, 0xBA, /* 0x50-0x53 */
 	0x8B, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x9E, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x8D, 0x00, 0x96, 0x91, 0x3F, 0x3F, 0x8E, 0x56, /* 0x5C-0x5F */
+	0x8D, 0xF7, 0x96, 0x91, 0x3F, 0x3F, 0x8E, 0x56, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x83, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x4F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x9E, 0x8F, 0x3F, 0x3F, 0x89, 0x00, 0x9E, 0x84, /* 0x74-0x77 */
+	0x9E, 0x8F, 0x3F, 0x3F, 0x89, 0xB1, 0x9E, 0x84, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x95, 0x9E, 0x85, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x9E, 0x8C, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x97, 0xC0, 0x3F, 0x3F, 0x9E, 0x8C, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x94, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x9E, 0x94, 0x3F, 0x3F, 0x9E, 0x87, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xB2, /* 0x90-0x93 */
 	0x9E, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x5B, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x8B, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x9E, 0x8A, 0x3F, 0x3F, 0x9E, 0x86, /* 0x9C-0x9F */
-	0x9E, 0x91, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x00, 0x8C, 0x00, /* 0xA4-0xA7 */
+	0x9E, 0x91, 0x3F, 0x3F, 0x8F, 0xBD, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0xEB, 0x8C, 0xE6, /* 0xA4-0xA7 */
 	0x97, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x9E, 0x88, 0x3F, 0x3F, 0x92, 0x00, /* 0xAC-0xAF */
-	0x8A, 0x42, 0x8D, 0x00, 0x3F, 0x3F, 0x9E, 0x80, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x9E, 0x88, 0x3F, 0x3F, 0x92, 0xF2, /* 0xAC-0xAF */
+	0x8A, 0x42, 0x8D, 0xAB, 0x3F, 0x3F, 0x9E, 0x80, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x9E, 0x90, 0x8A, 0x81, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x9E, 0x8E, 0x9E, 0x92, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x93, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x00, 0x64, 0x96, 0x00, 0x9E, 0x97, 0x8A, 0x00, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x9E, 0x9E, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
+	0x8A, 0xFC, 0x3F, 0x3F, 0x9E, 0xB0, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0xED, 0x48, 0x96, 0xC7, 0x9E, 0x97, 0x8A, 0xFB, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x9E, 0x9E, 0x3F, 0x3F, 0xED, 0xCB, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x5F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x9E, 0x9F, 0x9E, 0x00, 0x3F, 0x3F, 0x9E, 0x00, /* 0xD4-0xD7 */
+	0x9E, 0x9F, 0x9E, 0xA1, 0x3F, 0x3F, 0x9E, 0xA5, /* 0xD4-0xD7 */
 	0x9E, 0x99, 0x3F, 0x3F, 0x92, 0x49, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x8F, /* 0xDC-0xDF */
-	0x9E, 0x00, 0x9E, 0x9C, 0x3F, 0x3F, 0x9E, 0x00, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, /* 0xE4-0xE7 */
+	0x9E, 0xA9, 0x9E, 0x9C, 0x3F, 0x3F, 0x9E, 0xA6, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xA0, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x58, 0x9E, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x58, 0x9E, 0xAA, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xB1, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x9E, 0x00, 0x8A, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x9E, 0xA8, 0x8A, 0xBB, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_69[512] = {
 	0x98, 0x6F, 0x9E, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x9E, 0x00, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x9E, 0x98, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0x08-0x0B */
-	0x9E, 0x9D, 0x90, 0x41, 0x92, 0x00, 0x9E, 0x93, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x9E, 0xA4, 0x88, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x9E, 0x98, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xB8, /* 0x08-0x0B */
+	0x9E, 0x9D, 0x90, 0x41, 0x92, 0xC5, 0x9E, 0x93, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xA3, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x90, 0x9A, 0x9E, 0x00, 0x8A, 0x91, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x90, 0x9A, 0x9E, 0xAD, 0x8A, 0x91, /* 0x18-0x1B */
 	0x8C, 0x9F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x9A, 0x9E, 0x00, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x9B, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x9E, 0xAF, 0x9E, 0x9A, 0x9E, 0xAE, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x9E, 0xA7, 0x9E, 0x9B, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x9E, 0xAB, 0x3F, 0x3F, 0x9E, 0xAC, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x93, 0x00, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x92, 0x00, /* 0x3C-0x3F */
+	0x9E, 0xBD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x93, 0xCC, 0x3F, 0x3F, 0x9E, 0xA2, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x9E, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x9E, 0xBB, 0x3F, 0x3F, 0x92, 0xD6, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x6B, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x96, /* 0x50-0x53 */
-	0x9E, 0x00, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x9E, 0x00, 0x91, 0x5E, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x9E, 0x00, 0x9E, 0x00, 0x9E, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x93, 0x00, 0x9E, 0x00, 0x93, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x9E, 0xB6, 0x91, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x9E, 0xBC, 0x91, 0x5E, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x9E, 0xB3, 0x9E, 0xC0, 0x9E, 0xBF, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x93, 0xED, 0x9E, 0xBE, 0x93, 0xE8, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x00, 0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x00, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x8B, 0x00, 0x9E, 0x00, 0x8F, 0x7C, /* 0x6C-0x6F */
+	0xED, 0xCD, 0x3F, 0x3F, 0x9E, 0xC2, 0x9E, 0xB5, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x8B, 0xC6, 0x9E, 0xB8, 0x8F, 0x7C, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x80, /* 0x70-0x73 */
-	0x9E, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x9E, 0x00, /* 0x74-0x77 */
-	0x9E, 0x00, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x98, 0x4F, 0x8A, 0x79, 0x9E, 0x00, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x9E, 0xBA, 0x8B, 0xC9, 0x3F, 0x3F, 0x9E, 0xB2, /* 0x74-0x77 */
+	0x9E, 0xB4, 0x9E, 0xB1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x98, 0x4F, 0x8A, 0x79, 0x9E, 0xB7, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x9E, 0x00, 0x8A, 0x54, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x9E, 0xC1, 0x8A, 0x54, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xE5, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x7C, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x98, 0x50, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x59, /* 0x98-0x9B */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x9E, 0xD2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x98, 0x50, 0x9E, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0xED, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x59, /* 0x98-0x9B */
+	0x9E, 0xD4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x9E, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xD0, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x00, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x9E, 0x00, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x8D, 0x5C, /* 0xC8-0xCB */
-	0x92, 0x00, 0x91, 0x84, 0x9E, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xC4, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x9E, 0xE1, 0x9E, 0xC3, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x9E, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xCE, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xC9, 0x9E, 0xC6, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x9E, 0xC7, 0x3F, 0x3F, 0x9E, 0xCF, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0xA0, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xCC, 0x8D, 0x5C, /* 0xC8-0xCB */
+	0x92, 0xC6, 0x91, 0x84, 0x9E, 0xCA, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x9E, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xC8, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x97, 0x6C, 0x96, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, /* 0xE4-0xE7 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x9E, 0xCD, 0x9E, 0xD7, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xD0, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xDF, /* 0xE4-0xE7 */
+	0x9E, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xE5, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x9E, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xDE, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x92, 0x00, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x91, 0x85, 0x3F, 0x3F, 0x9E, 0x00, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x9E, 0xDD, 0x3F, 0x3F, 0x92, 0xCE, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x91, 0x85, 0x3F, 0x3F, 0x9E, 0xDB, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_6A[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x94, 0x00, /* 0x08-0x0B */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x00, /* 0x10-0x13 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x94, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x95, 0x57, 0x3F, 0x3F, 0x9E, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x8F, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x96, 0x00, 0x9E, 0x00, 0x9E, 0x00, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xD9, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x9E, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xE6, 0x94, 0xF3, /* 0x08-0x0B */
+	0x9E, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xE7, 0x9E, 0xEA, /* 0x10-0x13 */
+	0x9E, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x94, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x95, 0x57, 0x3F, 0x3F, 0x9E, 0xDA, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xE2, 0x8F, 0xBE, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x96, 0xCD, 0x9E, 0xF6, 0x9E, 0xE9, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x89, 0x00, 0x8A, 0x7E, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x8F, 0x00, 0x9E, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x9E, 0x00, 0x8E, 0x00, 0x8A, 0x92, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x8C, 0xA0, 0x89, 0xA1, 0x8A, 0x7E, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xD1, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xED, 0xD1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x8F, 0xBF, 0x9E, 0xEE, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x9E, 0xF5, 0x8E, 0xF7, 0x8A, 0x92, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x92, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x9E, 0x00, /* 0x44-0x47 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x48-0x4B */
+	0x9E, 0xEB, 0x3F, 0x3F, 0xED, 0xD3, 0x9E, 0xF0, /* 0x44-0x47 */
+	0x9E, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xB4, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x8B, 0x6B, 0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x8B, 0x6B, 0x9E, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x40, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x93, 0x00, 0x9E, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x93, 0xC9, 0x9E, 0xF1, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xF3, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xD2, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x00, 0x00, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xED, 0xED, 0xD4, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x8A, 0x80, /* 0x7C-0x7F */
+	0x9E, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xD5, 0x8A, 0x80, /* 0x7C-0x7F */
 	
 	0x92, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x9E, 0xFA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x9E, 0x00, 0x8C, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x9E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x9E, 0xF8, 0x8C, 0xE7, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x9E, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x40, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x9E, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x9E, 0x00, 0x3F, 0x3F, 0x9E, 0x00, 0x9E, 0x00, /* 0xA0-0xA3 */
+	0x9E, 0xF9, 0x3F, 0x3F, 0x9E, 0xFB, 0x9E, 0xFC, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x4B, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x9F, 0x47, 0x3F, 0x3F, 0x9E, 0x8D, 0x3F, 0x3F, /* 0xAC-0xAF */
@@ -5876,17 +5878,17 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x9F, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x42, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x9E, 0x00, 0x9F, 0x44, 0x9F, 0x43, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x9E, 0xE8, 0x9F, 0x44, 0x9F, 0x43, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x9F, 0x49, 0x3F, 0x3F, 0x98, 0x45, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x4C, 0x8B, 0x00, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x4C, 0x8B, 0xF9, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x48, 0x9F, 0x4A, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x94, 0x00, 0x3F, 0x3F, 0x9F, 0x4D, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xD6, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xED, 0xD7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x94, 0xA5, 0x3F, 0x3F, 0x9F, 0x4D, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
@@ -5897,40 +5899,40 @@
 static unsigned char u2c_6B[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x97, 0x93, 0x9F, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9E, 0xDC, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x52, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x53, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x89, 0x54, 0x3F, 0x3F, 0x9F, 0x55, /* 0x1C-0x1F */
-	0x8C, 0x87, 0x8E, 0x9F, 0x3F, 0x3F, 0x8B, 0x00, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0x24-0x27 */
+	0x8C, 0x87, 0x8E, 0x9F, 0x3F, 0x3F, 0x8B, 0xD3, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xA2, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x7E, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x57, /* 0x34-0x37 */
 	0x9F, 0x56, 0x9F, 0x59, 0x8B, 0x5C, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x8B, 0x00, 0x8A, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x8B, 0xD4, 0x8A, 0xBC, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x5C, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x5B, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x9F, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x89, 0x00, 0x3F, 0x3F, 0x92, 0x56, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x9F, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0x50-0x53 */
+	0x89, 0xCC, 0x3F, 0x3F, 0x92, 0x56, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x9F, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xBD, /* 0x50-0x53 */
 	0x9F, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x9F, 0x5F, 0x3F, 0x3F, 0x9F, 0x61, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x62, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x9F, 0x63, 0x8E, 0x7E, 0x90, 0x00, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x9F, 0x63, 0x8E, 0x7E, 0x90, 0xB3, /* 0x60-0x63 */
 	0x8D, 0x9F, 0x3F, 0x3F, 0x95, 0x90, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x95, 0x00, 0x98, 0x63, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x95, 0xE0, 0x98, 0x63, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x95, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, /* 0x70-0x73 */
-	0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xCE, /* 0x70-0x73 */
+	0x97, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x9F, 0x64, 0x9F, 0x65, 0x3F, 0x3F, 0x8E, 0x80, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x66, /* 0x7C-0x7F */
 	
 	0x9F, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x69, /* 0x80-0x83 */
 	0x9F, 0x68, 0x3F, 0x3F, 0x96, 0x77, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x8F, 0x7D, 0x8E, 0x00, 0x8E, 0x63, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x8F, 0x7D, 0x8E, 0xEA, 0x8E, 0x63, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x9F, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x9F, 0x6C, 0x90, 0x42, 0x3F, 0x3F, /* 0x94-0x97 */
@@ -5941,16 +5943,16 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x6F, 0x9F, 0x70, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x71, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x9F, 0x73, 0x9F, 0x72, 0x9F, 0x74, /* 0xB0-0xB3 */
-	0x89, 0x00, 0x92, 0x69, 0x3F, 0x3F, 0x9F, 0x75, /* 0xB4-0xB7 */
+	0x89, 0xA3, 0x92, 0x69, 0x3F, 0x3F, 0x9F, 0x75, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x45, 0x8A, 0x6B, /* 0xB8-0xBB */
 	0x9F, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x61, /* 0xBC-0xBF */
-	0x9A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x9A, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x8B, 0x42, 0x9F, 0x77, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x78, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x95, 0x00, 0x96, 0x88, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, 0x9F, 0x79, /* 0xD0-0xD3 */
-	0x94, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x95, 0xEA, 0x96, 0x88, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xC5, 0x9F, 0x79, /* 0xD0-0xD3 */
+	0x94, 0xE4, 0x3F, 0x3F, 0xED, 0xD8, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x94, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xD1, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x7A, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
@@ -5967,7 +5969,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x9F, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x81, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x9F, 0x82, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x96, 0xAF, 0x3F, 0x3F, 0x9F, 0x82, /* 0x10-0x13 */
 	0x9F, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x43, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x84, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
@@ -5978,53 +5980,53 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x90, 0x85, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x58, /* 0x34-0x37 */
 	0x89, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x00, 0x00, /* 0x3C-0x3F */
-	0x92, 0x00, 0x8F, 0x60, 0x8B, 0x81, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xC3, 0xED, 0xD9, /* 0x3C-0x3F */
+	0x92, 0xF3, 0x8F, 0x60, 0x8B, 0x81, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x9F, 0x88, 0x3F, 0x3F, 0x8A, 0x00, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xC4, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x8E, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x9F, 0x88, 0x3F, 0x3F, 0x8A, 0xBE, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x98, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x00, 0x00, 0x93, 0x00, 0x9F, 0x87, 0x8D, 0x5D, /* 0x5C-0x5F */
+	0xED, 0xDA, 0x93, 0xF0, 0x9F, 0x87, 0x8D, 0x5D, /* 0x5C-0x5F */
 	0x92, 0x72, 0x3F, 0x3F, 0x9F, 0x89, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x9F, 0x91, 0x3F, 0x3F, 0x9F, 0x8A, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x6C-0x6F */
-	0x91, 0x00, 0x3F, 0x3F, 0x8B, 0x82, 0x9F, 0x92, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xDC, /* 0x6C-0x6F */
+	0x91, 0xBF, 0x3F, 0x3F, 0x8B, 0x82, 0x9F, 0x92, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x88, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x8B, 0x44, 0x9F, 0x90, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x9F, 0x8E, 0x9F, 0x8B, 0x97, 0x80, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x93, 0x00, 0x9F, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xDB, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x92, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x93, 0xD7, 0x9F, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x9F, 0x94, 0x3F, 0x3F, 0x9F, 0x93, 0x8C, 0x42, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x8D, 0x00, 0x9F, 0x8D, 0x9F, 0x8F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xAB, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x8D, 0xB9, 0x9F, 0x8D, 0x9F, 0x8F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x96, 0x76, 0x91, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x96, 0x76, 0x91, 0xF2, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x97, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x9C, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x9F, 0x9D, 0x3F, 0x3F, 0x89, 0x00, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x9F, 0x9D, 0x3F, 0x3F, 0x89, 0xCD, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x95, 0x00, 0x96, 0x00, 0x9F, 0x9F, 0x8E, 0x00, /* 0xB8-0xBB */
-	0x8F, 0x00, 0x9F, 0x98, 0x9F, 0x9E, 0x89, 0x88, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x95, 0xA6, 0x96, 0xFB, 0x9F, 0x9F, 0x8E, 0xA1, /* 0xB8-0xBB */
+	0x8F, 0xC0, 0x9F, 0x98, 0x9F, 0x9E, 0x89, 0x88, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x8B, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x9F, 0x95, 0x9F, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x90, 0x00, 0x94, 0x91, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x90, 0xF2, 0x94, 0x91, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x94, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x97, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x96, 0x40, 0x3F, 0x3F, 0x9F, 0x99, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x00, 0x00, 0x9F, 0x00, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x9F, 0xA2, 0xED, 0xDD, 0x9F, 0xA0, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x9F, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x96, 0x41, 0x94, 0x67, 0x8B, 0x83, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x93, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x92, 0x8D, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0xEC-0xEF */
-	0x91, 0x00, 0x9F, 0x96, 0x3F, 0x3F, 0x89, 0x6A, /* 0xF0-0xF3 */
+	0x92, 0x8D, 0x3F, 0x3F, 0x9F, 0xA3, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xA1, /* 0xEC-0xEF */
+	0x91, 0xD7, 0x9F, 0x96, 0x3F, 0x3F, 0x89, 0x6A, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
@@ -6032,763 +6034,763 @@
 
 static unsigned char u2c_6D[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0xED, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x6D, /* 0x08-0x0B */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x97, 0x8C, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, 0x9F, 0x00, /* 0x1C-0x1F */
+	0x9F, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xAD, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xF4, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x9F, 0xAA, 0x3F, 0x3F, 0x97, 0x8C, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xB4, 0x9F, 0xA4, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x89, 0x6B, 0x8D, 0x5E, 0x9F, 0x00, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x92, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x89, 0x6B, 0x8D, 0x5E, 0x9F, 0xA7, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x46, 0x9F, 0x00, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x9F, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x88, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x9F, 0x00, 0x94, 0x68, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x8F, 0x00, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x46, 0x9F, 0xAC, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x9F, 0xAB, 0x9F, 0xA6, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x9F, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x88, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x9F, 0xA8, 0x94, 0x68, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x97, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x8F, 0xF2, 0x90, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x9F, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x9F, 0xB4, 0x9F, 0xB2, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x95, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0x60-0x63 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x89, 0x59, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xAF, /* 0x60-0x63 */
+	0x9F, 0xB1, 0x3F, 0x3F, 0x89, 0x59, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x8D, 0x5F, 0x98, 0x51, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x8A, 0x5C, 0x3F, 0x3F, 0x95, 0x82, 0x00, 0x00, /* 0x6C-0x6F */
+	0x8A, 0x5C, 0x3F, 0x3F, 0x95, 0x82, 0xED, 0xE0, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x97, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x43, /* 0x74-0x77 */
-	0x90, 0x5A, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x90, 0x5A, 0x9F, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x84-0x87 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x97, 0x4F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x00, 0x40, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x93, 0x93, /* 0x98-0x9B */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x9F, 0xB8, 0x3F, 0x3F, 0xED, 0xDF, /* 0x84-0x87 */
+	0x8F, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x97, 0x4F, 0x3F, 0x3F, 0x9F, 0xB5, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xB0, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x9F, 0xB6, 0xED, 0xE1, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x97, 0xDC, 0x3F, 0x3F, 0x93, 0x93, /* 0x98-0x9B */
+	0x93, 0xC0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x00, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x55, /* 0xAC-0xAF */
+	0xED, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x55, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x74, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x9F, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x9F, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x97, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x97, 0x84, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x9F, 0x00, 0x9F, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0xC8-0xCB */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x42, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x8F, 0x69, 0x9F, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x93, 0x91, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x9F, 0xC6, 0x9F, 0xC0, 0x9F, 0xBD, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xD2, /* 0xC8-0xCB */
+	0x9F, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xE3, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x8F, 0x69, 0x9F, 0xC5, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x9F, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x93, 0x91, 0x9F, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xC2, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x92, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x9F, 0x00, 0x88, 0x00, /* 0xE8-0xEB */
-	0x9F, 0x00, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x90, 0x5B, 0x00, 0x44, 0x8F, 0x7E, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x8D, 0x00, /* 0xF4-0xF7 */
-	0x00, 0x43, 0x9F, 0x00, 0x9F, 0x00, 0x93, 0x59, /* 0xF8-0xFB */
-	0x00, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x9F, 0xC9, 0x3F, 0x3F, 0x9F, 0xBE, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x9F, 0xC4, 0x3F, 0x3F, 0x9F, 0xCB, 0x88, 0xFA, /* 0xE8-0xEB */
+	0x9F, 0xC1, 0x3F, 0x3F, 0x9F, 0xCC, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x90, 0x5B, 0xED, 0xE5, 0x8F, 0x7E, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x95, 0xA3, 0x3F, 0x3F, 0x8D, 0xAC, /* 0xF4-0xF7 */
+	0xED, 0xE4, 0x9F, 0xB9, 0x9F, 0xC7, 0x93, 0x59, /* 0xF8-0xFB */
+	0xED, 0xE6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_6E[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x8A, 0x89, /* 0x04-0x07 */
-	0x8D, 0x00, 0x8F, 0x00, 0x9F, 0x00, 0x8F, 0x61, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x90, 0xB4, 0x3F, 0x3F, 0x8A, 0x89, /* 0x04-0x07 */
+	0x8D, 0xCF, 0x8F, 0xC2, 0x9F, 0xBB, 0x8F, 0x61, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x6B, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x8F, 0x8D, 0x8C, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x9F, 0x00, /* 0x1C-0x1F */
-	0x8B, 0x94, 0x93, 0x6E, 0x3F, 0x3F, 0x9F, 0x00, /* 0x20-0x23 */
-	0x9F, 0x00, 0x88, 0x00, 0x89, 0x51, 0x00, 0x48, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x9F, 0x00, /* 0x28-0x2B */
-	0x91, 0x00, 0x9F, 0x00, 0x9F, 0x00, 0x8D, 0x60, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x9F, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x9F, 0xD0, 0x8F, 0x8D, 0x8C, 0xB8, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x9F, 0xDF, 0x3F, 0x3F, 0x9F, 0xD9, /* 0x1C-0x1F */
+	0x8B, 0x94, 0x93, 0x6E, 0x3F, 0x3F, 0x9F, 0xD4, /* 0x20-0x23 */
+	0x9F, 0xDD, 0x88, 0xAD, 0x89, 0x51, 0xED, 0xE9, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x89, 0xB7, 0x3F, 0x3F, 0x9F, 0xD6, /* 0x28-0x2B */
+	0x91, 0xAA, 0x9F, 0xCD, 0x9F, 0xCF, 0x8D, 0x60, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x9F, 0x00, 0x00, 0x46, 0x9F, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x00, 0x49, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0x40-0x43 */
+	0x9F, 0xE0, 0xED, 0xE7, 0x9F, 0xDB, 0x3F, 0x3F, /* 0x38-0x3B */
+	0xED, 0xEA, 0x3F, 0x3F, 0x9F, 0xD3, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xDA, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x9F, 0x00, 0x9F, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xA9, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x9F, 0xD8, 0x9F, 0xDC, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x58, /* 0x58-0x5B */
-	0x00, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xCE, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x8F, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x58, /* 0x58-0x5B */
+	0xED, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xD2, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x4E, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x93, 0x92, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xD5, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xCE, 0x93, 0x92, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xD1, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xD7, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x70, 0x8E, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x70, 0x8E, 0xBC, /* 0x7C-0x7F */
 	
-	0x96, 0x9E, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x96, 0x9E, 0x3F, 0x3F, 0x9F, 0xE1, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0x8C-0x8F */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x94, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xED, /* 0x8C-0x8F */
+	0x8C, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x80, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x97, 0x00, 0x8D, 0x61, 0x3F, 0x3F, 0x9F, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x6E, 0x9F, 0x00, /* 0xB4-0xB7 */
+	0x9F, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x97, 0xAD, 0x8D, 0x61, 0x3F, 0x3F, 0x9F, 0xF0, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xEC, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x9F, 0xEE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xE2, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xE8, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xEA, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x6E, 0x9F, 0xE5, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x4D, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x00, 0x4A, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x9F, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x8E, 0x00, /* 0xC8-0xCB */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x8A, 0x8A, 0x3F, 0x3F, 0x9F, 0x00, /* 0xD0-0xD3 */
-	0x9F, 0x00, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x9F, 0xE7, 0x3F, 0x3F, 0xED, 0xEB, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xEF, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x9F, 0xE9, 0x96, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x9F, 0xE4, 0x3F, 0x3F, 0x8E, 0xA0, /* 0xC8-0xCB */
+	0x9F, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x8A, 0x8A, 0x3F, 0x3F, 0x9F, 0xE6, /* 0xD0-0xD3 */
+	0x9F, 0xEB, 0x9F, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x91, 0x00, 0x91, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x91, 0xEA, 0x91, 0xD8, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x93, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x42, /* 0xF4-0xF7 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x00, 0x9F, 0x00, /* 0xFC-0xFF */
+	0x9F, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xFA, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xF8, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x93, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x42, /* 0xF4-0xF7 */
+	0x9F, 0xF5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0xF6, 0x9F, 0xDE, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_6F[512] = {
 	0x3F, 0x3F, 0x8B, 0x99, 0x95, 0x59, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xBD, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x8D, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x52, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x00, 0x41, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x9F, 0xF2, 0x3F, 0x3F, 0xE0, 0x41, /* 0x10-0x13 */
 	0x89, 0x89, 0x91, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x94, 0x99, 0x3F, 0x3F, 0x8A, 0x00, 0x97, 0x00, /* 0x20-0x23 */
+	0x94, 0x99, 0x3F, 0x3F, 0x8A, 0xBF, 0x97, 0xF8, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x9F, /* 0x28-0x2B */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x9F, 0x00, 0x9F, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x92, 0xD0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x9F, 0xF9, 0x9F, 0xFB, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x91, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x40, 0x9F, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x40, 0x9F, 0xF7, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x9F, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x8A, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x8C, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x49, /* 0x58-0x5B */
-	0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x83, /* 0x5C-0x5F */
+	0xE0, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x49, /* 0x58-0x5B */
+	0x90, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x83, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x8F, 0x81, 0x3F, 0x3F, 0x00, 0x52, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x8F, 0x81, 0x3F, 0x3F, 0xE0, 0x52, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x00, 0x4B, 0x92, 0x00, 0x00, 0x48, /* 0x6C-0x6F */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x6B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x00, 0x45, 0x3F, 0x3F, 0x00, 0x44, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
-	
-	0x00, 0x47, 0x00, 0x46, 0x00, 0x4C, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x90, 0x9F, 0x3F, 0x3F, 0x00, 0x43, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xE0, 0x4B, 0x92, 0xAA, 0xE0, 0x48, /* 0x6C-0x6F */
+	0x92, 0xD7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE0, 0x6B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0xE0, 0x45, 0x3F, 0x3F, 0xE0, 0x44, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE0, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0xE0, 0x47, 0xE0, 0x46, 0xE0, 0x4C, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x90, 0x9F, 0x3F, 0x3F, 0xE0, 0x43, 0x3F, 0x3F, /* 0x84-0x87 */
+	0xED, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x4F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xE0, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xC0, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x00, 0x55, 0x3F, 0x3F, 0x00, 0x54, /* 0xA0-0xA3 */
-	0x00, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x59, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0xE0, 0x55, 0x3F, 0x3F, 0xE0, 0x54, /* 0xA0-0xA3 */
+	0xE0, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x59, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x93, 0x62, 0x3F, 0x3F, 0x00, 0x53, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x00, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x93, 0x62, 0x3F, 0x3F, 0xE0, 0x53, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0xED, 0xED, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE0, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x8C, 0x83, 0x91, 0x00, 0x00, 0x51, 0x94, 0x5A, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x58, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x8C, 0x83, 0x91, 0xF7, 0xE0, 0x51, 0x94, 0x5A, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x58, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x5D, 0x00, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x61, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5A, /* 0xDC-0xDF */
+	0xE0, 0x5D, 0xE0, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE0, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x61, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x5A, /* 0xDC-0xDF */
 	0x8D, 0x8A, 0x94, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x9F, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x94, /* 0xE8-0xEB */
-	0x00, 0x5C, 0x3F, 0x3F, 0x00, 0x60, 0x91, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x5F, 0x3F, 0x3F, 0x00, 0x4A, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x00, 0x4D, 0x00, 0x89, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x64, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x68, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xE0, 0x5C, 0x3F, 0x3F, 0xE0, 0x60, 0x91, 0xF3, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xE0, 0x5F, 0x3F, 0x3F, 0xE0, 0x4A, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0xED, 0xEE, 0xE8, 0x89, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x64, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x68, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_70[512] = {
-	0x3F, 0x3F, 0x00, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x4E, 0x3F, 0x3F, 0x00, 0x4F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x62, 0x3F, 0x3F, 0x00, 0x63, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x67, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE0, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0xED, 0xEF, 0x3F, 0x3F, 0xED, 0xF0, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE0, 0x62, 0x3F, 0x3F, 0xE0, 0x63, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x67, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xE0, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x95, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x00, 0x6D, 0x3F, 0x3F, 0x00, 0x6A, 0x00, 0x69, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x00, 0x6C, 0x93, 0x00, 0x00, 0x6E, /* 0x1C-0x1F */
+	0xE0, 0x6D, 0x3F, 0x3F, 0xE0, 0x6A, 0xE0, 0x69, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE0, 0x6C, 0x93, 0xD2, 0xE0, 0x6E, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x95, 0x91, 0x00, /* 0x24-0x27 */
-	0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x6F, 0x3F, 0x3F, 0x00, 0x71, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x95, 0x91, 0xEB, /* 0x24-0x27 */
+	0xED, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x90, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xE0, 0x6F, 0x3F, 0x3F, 0xE0, 0x71, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x70, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x70, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x00, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x9F, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0xE0, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x93, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x73, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x73, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xCE, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x94, /* 0x6C-0x6F */
 	0x8A, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x8B, 0x84, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x8E, 0x00, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x8E, 0xDC, 0x8D, 0xD0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x00, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xED, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x98, 0x46, 0x90, 0x86, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x8A, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x75, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x75, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE0, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x52, /* 0xA8-0xAB */
-	0x00, 0x78, 0x92, 0x59, 0x00, 0x7B, 0x00, 0x76, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7A, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xF3, /* 0xA8-0xAB */
+	0xE0, 0x78, 0x92, 0x59, 0xE0, 0x7B, 0xE0, 0x76, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x7A, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x00, 0x79, 0x93, 0x5F, 0x88, 0x00, 0x00, 0x62, /* 0xB8-0xBB */
+	0xE0, 0x79, 0x93, 0x5F, 0x88, 0xD7, 0xED, 0x46, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7D, /* 0xC8-0xCB */
+	0x97, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x7D, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x47, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x80, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x00, 0x7E, 0x3F, 0x3F, 0x00, 0x7C, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0xE0, 0x80, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xE0, 0x7E, 0x3F, 0x3F, 0xE0, 0x7C, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0xE0, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x96, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x00, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0xE0, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_71[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x53, /* 0x0C-0x0F */
+	0xED, 0xF5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE0, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xF4, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x89, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x84, 0x95, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x00, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE0, 0x84, 0x95, 0xB0, 0x3F, 0x3F, /* 0x18-0x1B */
+	0xE0, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x96, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xC5, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x52, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x8F, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x56, 0x00, 0x57, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x8A, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0xF7, 0xED, 0xF8, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x97, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xE0, 0x8A, 0x3F, 0x3F, 0x90, 0xF7, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x86, 0x00, 0x8B, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE0, 0x86, 0xE0, 0x8B, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x89, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x00, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x89, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x94, 0x81, 0x00, 0x85, 0x00, 0x88, 0x8F, 0x00, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x00, 0x8C, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0xED, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x89, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x94, 0x81, 0xE0, 0x85, 0xE0, 0x88, 0x8F, 0xC6, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x94, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0xE0, 0x8C, 0x3F, 0x3F, 0x8E, 0xCF, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x90, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x00, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x87, 0x3F, 0x3F, 0x8C, 0x46, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8D, /* 0x8C-0x8F */
+	0xE0, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0xE0, 0x87, 0x3F, 0x3F, 0x8C, 0x46, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x8D, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x97, 0x6F, 0x00, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x97, 0x6F, 0xE0, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xEA, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x6E, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x00, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x00, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE0, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0xE0, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x94, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x95, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x00, 0x59, 0x3F, 0x3F, 0x94, 0x52, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0xE0, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x95, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0xED, 0xFA, 0x3F, 0x3F, 0x94, 0x52, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x93, 0x95, 0x00, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x99, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x97, 0x00, 0x3F, 0x3F, 0x00, 0x96, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x98, 0x89, 0x8D, 0x3F, 0x3F, 0x00, 0x93, /* 0xD4-0xD7 */
+	0x93, 0x95, 0xE0, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0x99, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x97, 0xD3, 0x3F, 0x3F, 0xE0, 0x96, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0xE0, 0x98, 0x89, 0x8D, 0x3F, 0x3F, 0xE0, 0x93, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x9A, 0x7A, /* 0xDC-0xDF */
-	0x00, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x91, 0x87, 0x8E, 0x57, 0x00, 0x9C, /* 0xE4-0xE7 */
+	0xE0, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x91, 0x87, 0x8E, 0x57, 0xE0, 0x9C, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x00, 0x9B, 0x90, 0x43, 0x99, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0xE0, 0x9B, 0x90, 0x43, 0x99, 0xD7, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x00, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x00, 0x9F, 0x3F, 0x3F, 0x00, 0x8E, /* 0xF8-0xFB */
-	0x00, 0x9E, 0x3F, 0x3F, 0x00, 0x5A, 0x00, 0x00, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0xE0, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xE0, 0x9F, 0x3F, 0x3F, 0xE0, 0x8E, /* 0xF8-0xFB */
+	0xE0, 0x9E, 0x3F, 0x3F, 0xED, 0xFB, 0xE0, 0xA0, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_72[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x9A, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE0, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xE0, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xA3, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x00, 0x00, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x95, 0x83, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x00, 0x00, /* 0x38-0x3B */
-	0x00, 0x00, 0x91, 0x75, 0x8E, 0x00, 0x00, 0x00, /* 0x3C-0x3F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x95, 0x00, /* 0x44-0x47 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x48-0x4B */
+	0xE0, 0xA4, 0x3F, 0x3F, 0x92, 0xDC, 0x3F, 0x3F, /* 0x28-0x2B */
+	0xE0, 0xA6, 0xE0, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xE0, 0xA7, 0x3F, 0x3F, 0xE0, 0xA8, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x8E, 0xDD, 0x95, 0x83, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xEA, 0xE0, 0xA9, /* 0x38-0x3B */
+	0xE0, 0xAA, 0x91, 0x75, 0x8E, 0xA2, 0xE0, 0xAB, /* 0x3C-0x3F */
+	0xE0, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xAD, 0x95, 0xD0, /* 0x44-0x47 */
+	0x94, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xAE, /* 0x48-0x4B */
 	0x94, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xAB, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x89, 0x00, 0x3F, 0x3F, 0x8B, 0x8D, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x96, 0x00, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x89, 0x00, 0x98, 0x53, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE0, 0xAF, 0x89, 0xE5, 0x3F, 0x3F, 0x8B, 0x8D, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x96, 0xC4, 0x3F, 0x3F, 0x96, 0xB4, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x89, 0xB2, 0x98, 0x53, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x71, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x95, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x8C, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xB5, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE0, 0xB0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x93, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x8C, 0xA1, 0xE0, 0xB1, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x8D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x84-0x87 */
+	0x8D, 0xD2, 0xE0, 0xB3, 0xE0, 0xB2, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xB4, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xB5, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xB6, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x8B, 0x5D, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA4-0xA7 */
+	0x8B, 0x5D, 0x3F, 0x3F, 0xE0, 0xB7, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xB8, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x00, 0x5B, 0x00, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5C, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x00, 0x00, /* 0xC0-0xC3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x8C, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xC6, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xED, 0xFC, 0xE0, 0xBA, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xF3, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE0, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x40, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xB6, 0xE0, 0xBB, /* 0xC0-0xC3 */
+	0xE0, 0xBD, 0x3F, 0x3F, 0xE0, 0xBC, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x8C, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xBE, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x8C, 0xCF, 0x3F, 0x3F, 0xE0, 0xBF, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xE7, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x91, 0x5F, 0x3F, 0x3F, 0x8D, 0x9D, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE0, 0xC1, 0xE0, 0xC2, 0xE0, 0xC0, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x93, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x8E, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x93, 0xC6, 0x8B, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xF4-0xF7 */
-	0x92, 0x4B, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xC4, /* 0xF4-0xF7 */
+	0x92, 0x4B, 0xE0, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x98, 0x54, 0x94, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_73[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xC7, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0x18-0x1B */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x97, 0x00, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xC9, 0xE0, 0xC6, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xD2, /* 0x18-0x1B */
+	0xE0, 0xC8, 0xE0, 0xCA, 0x3F, 0x3F, 0x97, 0xC2, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x5D, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x00, 0x92, 0x96, 0x94, 0x4C, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x00, 0x00, /* 0x2C-0x2F */
+	0xEE, 0x41, 0xE0, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE0, 0xCD, 0x92, 0x96, 0x94, 0x4C, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xA3, 0xE0, 0xCC, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x00, 0x00, 0x3F, 0x3F, 0x97, 0x50, 0x97, 0x51, /* 0x34-0x37 */
+	0xE0, 0xCB, 0x3F, 0x3F, 0x97, 0x50, 0x97, 0x51, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x89, 0x8E, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xCF, 0x89, 0x8E, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x8D, 0x96, 0x8E, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xD0, 0xE0, 0xD1, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xD3, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x62, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x68-0x6B */
+	0xE0, 0xD5, 0x3F, 0x3F, 0xE0, 0xD4, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x00, 0x3F, 0x3F, 0x8A, 0x6C, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x5F, /* 0x74-0x77 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7B */
+	0xE0, 0xD6, 0x3F, 0x3F, 0x8A, 0x6C, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE0, 0xD8, 0x3F, 0x3F, 0xEE, 0x43, /* 0x74-0x77 */
+	0xE0, 0xD7, 0x3F, 0x3F, 0xE0, 0xDA, 0xE0, 0xD9, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x89, 0x00, /* 0x88-0x8B */
+	0x8C, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xA6, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x8B, 0xCA, 0x3F, 0x3F, 0x89, 0xA4, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xE8, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x8A, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xE6, 0xE0, 0xDC, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x00, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xDE, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xEE, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0xE0, 0xDF, 0x3F, 0x3F, 0x89, 0xCF, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x00, 0x00, 0x00, 0x61, 0x8E, 0x58, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x92, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x64, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x62, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE0, 0xDB, 0xEE, 0x45, 0x8E, 0x58, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x92, 0xBF, 0xE0, 0xDD, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x48, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x46, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x63, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xE2, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x8E, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x47, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0xE0, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x5D, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x94, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x00, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x94, 0xC7, 0xE0, 0xE1, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xE0, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0xEE, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0xE0, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xBB, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_74[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x85, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x00, 0x97, 0x9D, 0x00, 0x65, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE0, 0xE4, 0x97, 0x9D, 0xEE, 0x49, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x97, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x67, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x69, 0x00, 0x68, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6A, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x97, 0x00, /* 0x30-0x33 */
-	0x8B, 0x00, 0x94, 0x00, 0x94, 0x69, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xF4, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xE0, 0xE6, 0xEE, 0x4B, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xEE, 0x4D, 0xEE, 0x4C, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x4E, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xE8, 0x97, 0xD4, /* 0x30-0x33 */
+	0x8B, 0xD5, 0x94, 0xFA, 0x94, 0x69, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xE9, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xEB, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0xE0, 0xEE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x00, 0x8C, 0x00, 0x89, 0x6C, /* 0x58-0x5B */
-	0x00, 0x00, 0x3F, 0x3F, 0x90, 0x90, 0x00, 0x00, /* 0x5C-0x5F */
-	0x97, 0x00, 0x3F, 0x3F, 0x00, 0x6B, 0x00, 0x00, /* 0x60-0x63 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x6C-0x6F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0xE0, 0xEA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE0, 0xED, 0x8C, 0xE8, 0x89, 0x6C, /* 0x58-0x5B */
+	0xE0, 0xEF, 0x3F, 0x3F, 0x90, 0x90, 0xE0, 0xEC, /* 0x5C-0x5F */
+	0x97, 0xDA, 0x3F, 0x3F, 0xEE, 0x4F, 0xE0, 0xF2, /* 0x60-0x63 */
+	0xEA, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE0, 0xF0, 0xE0, 0xF3, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xE5, /* 0x6C-0x6F */
+	0xE0, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xBA, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xF4, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xF5, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x9E, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, 0x00, 0x00, /* 0x88-0x8B */
+	0x3F, 0x3F, 0xEE, 0x50, 0x3F, 0x3F, 0xE0, 0xF6, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x6D, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xF7, 0xEE, 0x51, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xE3, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xF8, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x8A, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x8E, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xF9, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE0, 0xFA, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE0, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x89, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x00, 0x40, 0x3F, 0x3F, 0x95, 0x5A, 0x00, 0x41, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x00, 0x42, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x00, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x44, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x00, 0x46, 0x00, 0x47, 0x00, 0x45, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x72, 0x00, 0x49, /* 0xF4-0xF7 */
-	0x00, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0xE1, 0x40, 0x3F, 0x3F, 0x95, 0x5A, 0xE1, 0x41, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xA2, 0xE1, 0x42, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE1, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x44, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0xE1, 0x46, 0xE1, 0x47, 0xE1, 0x45, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x72, 0xE1, 0x49, /* 0xF4-0xF7 */
+	0xE1, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_75[512] = {
-	0x3F, 0x3F, 0x00, 0x6E, 0x3F, 0x3F, 0x00, 0x4B, /* 0x00-0x03 */
-	0x00, 0x4A, 0x00, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xEE, 0x52, 0x3F, 0x3F, 0xE1, 0x4B, /* 0x00-0x03 */
+	0xE1, 0x4A, 0xE1, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x4D, 0x00, 0x4F, 0x00, 0x4E, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x8D, 0x99, 0x3F, 0x3F, 0x00, 0x51, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x90, 0x72, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x93, 0x5B, 0x3F, 0x3F, 0x00, 0x52, 0x90, 0x00, /* 0x1C-0x1F */
+	0xE1, 0x4D, 0xE1, 0x4F, 0xE1, 0x4E, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x8D, 0x99, 0x3F, 0x3F, 0xE1, 0x51, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE1, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x8A, 0xC3, 0x3F, 0x3F, 0x90, 0x72, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x93, 0x5B, 0x3F, 0x3F, 0xE1, 0x52, 0x90, 0xB6, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x59, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x89, 0x99, 0x00, 0x53, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x97, 0x70, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x28-0x2B */
-	0x00, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x89, 0x99, 0xE1, 0x53, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x97, 0x70, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xE1, /* 0x28-0x2B */
+	0xE1, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x8C, /* 0x2C-0x2F */
 	0x93, 0x63, 0x97, 0x52, 0x8D, 0x62, 0x90, 0x5C, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x6A, /* 0x34-0x37 */
-	0x99, 0x00, 0x3F, 0x3F, 0x92, 0x00, 0x89, 0x00, /* 0x38-0x3B */
-	0x00, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x99, 0xB2, 0x3F, 0x3F, 0x92, 0xAC, 0x89, 0xE6, /* 0x38-0x3B */
+	0xE1, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x00, 0x56, 0x3F, 0x3F, 0x00, 0x5B, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x00, 0x59, 0x00, 0x58, 0x9D, 0x00, /* 0x48-0x4B */
-	0x8A, 0x45, 0x00, 0x57, 0x3F, 0x3F, 0x88, 0x00, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x97, 0x00, 0x00, 0x5C, 0x00, 0x5A, /* 0x58-0x5B */
-	0x92, 0x7B, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x94, 0x00, 0x3F, 0x3F, 0x95, 0x4C, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x5E, 0x97, 0x00, 0x8C, 0x6C, 0x00, 0x5F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x5D, 0x94, 0x00, 0x00, 0x60, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x00, 0x61, 0x3F, 0x3F, 0x00, 0x6F, /* 0x6C-0x6F */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, /* 0x70-0x73 */
-	0x00, 0x66, 0x3F, 0x3F, 0x00, 0x63, 0x93, 0x00, /* 0x74-0x77 */
-	0x00, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE1, 0x56, 0x3F, 0x3F, 0xE1, 0x5B, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE1, 0x59, 0xE1, 0x58, 0x9D, 0xC0, /* 0x48-0x4B */
+	0x8A, 0x45, 0xE1, 0x57, 0x3F, 0x3F, 0x88, 0xD8, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x94, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x94, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x97, 0xAF, 0xE1, 0x5C, 0xE1, 0x5A, /* 0x58-0x5B */
+	0x92, 0x7B, 0x90, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x94, 0xA9, 0x3F, 0x3F, 0x95, 0x4C, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE1, 0x5E, 0x97, 0xAA, 0x8C, 0x6C, 0xE1, 0x5F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE1, 0x5D, 0x94, 0xD4, 0xE1, 0x60, /* 0x68-0x6B */
+	0x3F, 0x3F, 0xE1, 0x61, 0x3F, 0x3F, 0xEE, 0x53, /* 0x6C-0x6F */
+	0x88, 0xD9, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xF4, /* 0x70-0x73 */
+	0xE1, 0x66, 0x3F, 0x3F, 0xE1, 0x63, 0x93, 0xEB, /* 0x74-0x77 */
+	0xE1, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x45, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x69, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x64, 0x00, 0x65, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x68, 0x00, 0x67, 0x95, 0x44, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x69, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x64, 0xE1, 0x65, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xE1, 0x68, 0xE1, 0x67, 0x95, 0x44, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x61, 0x91, 0x60, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x8B, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6B, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6E, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x00, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0xE1, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x6B, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE1, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x6E, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0xE1, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x75, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x00, 0x76, 0x94, 0x00, 0x00, 0x70, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x00, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x00, 0x74, 0x90, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x00, 0x75, 0x00, 0x73, 0x8E, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6F, 0x00, 0x71, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x95, 0x61, 0x3F, 0x3F, 0x8F, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x78, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x79, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x8E, 0x00, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x93, 0x97, 0x00, 0x7A, 0x3F, 0x3F, 0x92, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7C, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x9F, 0x00, 0x7B, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0xE1, 0x76, 0x94, 0xE6, 0xE1, 0x70, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0xE1, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xE1, 0x74, 0x90, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0xE1, 0x75, 0xE1, 0x73, 0x8E, 0xBE, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x6F, 0xE1, 0x71, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x95, 0x61, 0x3F, 0x3F, 0x8F, 0xC7, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x78, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xE1, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x79, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x8E, 0xA4, 0x8D, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x93, 0x97, 0xE1, 0x7A, 0x3F, 0x3F, 0x92, 0xC9, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x7C, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x9F, 0xE1, 0x7B, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x91, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x00, 0x82, 0x3F, 0x3F, 0x00, 0x84, 0x00, 0x85, /* 0xF0-0xF3 */
+	0xE1, 0x82, 0x3F, 0x3F, 0xE1, 0x84, 0xE1, 0x85, /* 0xF0-0xF3 */
 	0x92, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x83, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x80, 0x3F, 0x3F, 0x00, 0x7D, 0x00, 0x7E, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x83, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0xE1, 0x80, 0x3F, 0x3F, 0xE1, 0x7D, 0xE1, 0x7E, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_76[512] = {
-	0x3F, 0x3F, 0x00, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0xE1, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x88, 0x3F, 0x3F, 0x00, 0x86, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xE1, 0x88, 0x3F, 0x3F, 0xE1, 0x86, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE1, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x89, /* 0x1C-0x1F */
-	0x00, 0x8B, 0x00, 0x8C, 0x00, 0x8D, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8A, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x89, /* 0x1C-0x1F */
+	0xE1, 0x8B, 0xE1, 0x8C, 0xE1, 0x8D, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE1, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x8A, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x00, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x91, /* 0x38-0x3B */
+	0xE1, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xE1, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x91, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x94, 0x00, 0x92, /* 0x44-0x47 */
-	0x00, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x00, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x00, 0x97, 0x00, 0x98, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9C, /* 0x64-0x67 */
-	0x00, 0x99, 0x00, 0x9A, 0x00, 0x9B, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x00, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x9E, 0x3F, 0x3F, 0x00, 0x9F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x00, 0x00, 0x3F, 0x3F, 0x94, 0x00, 0x93, 0x6F, /* 0x78-0x7B */
-	0x00, 0x00, 0x94, 0x92, 0x95, 0x53, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xC3, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x94, 0xE1, 0x92, /* 0x44-0x47 */
+	0xE1, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x8A, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xFC, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xC8, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE1, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0xE1, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0xE1, 0x97, 0xE1, 0x98, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0x9C, /* 0x64-0x67 */
+	0xE1, 0x99, 0xE1, 0x9A, 0xE1, 0x9B, 0x3F, 0x3F, /* 0x68-0x6B */
+	0xE1, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0xE1, 0x9E, 0x3F, 0x3F, 0xE1, 0x9F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xA0, 0x3F, 0x3F, /* 0x74-0x77 */
+	0xE1, 0xA1, 0x3F, 0x3F, 0x94, 0xAD, 0x93, 0x6F, /* 0x78-0x7B */
+	0xE1, 0xA2, 0x94, 0x92, 0x95, 0x53, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x70, 0x00, 0x00, /* 0x80-0x83 */
+	0xE1, 0xA3, 0x3F, 0x3F, 0xEE, 0x54, 0xE1, 0xA4, /* 0x80-0x83 */
 	0x93, 0x49, 0x3F, 0x3F, 0x8A, 0x46, 0x8D, 0x63, /* 0x84-0x87 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x8E, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, /* 0x98-0x9B */
-	0x00, 0x71, 0x3F, 0x3F, 0x00, 0x72, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xE1, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xA6, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xA7, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x8E, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xA9, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xA8, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xE1, 0xAA, 0xE1, 0xAB, 0xEE, 0x57, /* 0x98-0x9B */
+	0xEE, 0x55, 0x3F, 0x3F, 0xEE, 0x56, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x74, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x58, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x89, /* 0xB4-0xB7 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xE7, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE1, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xE1, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x89, /* 0xB4-0xB7 */
+	0xE1, 0xAE, 0xE1, 0xAF, 0xE1, 0xB0, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x4D, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x94, 0x75, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xB1, 0x94, 0x75, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x7E, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x89, 0x6D, 0x3F, 0x3F, 0x89, 0x76, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x93, 0x90, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0xD8-0xDB */
-	0x9F, 0x58, 0x3F, 0x3F, 0x00, 0x00, 0x96, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x8A, 0x00, /* 0xE0-0xE3 */
-	0x94, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x91, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0xE1, 0xB2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xB4, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xB3, 0x93, 0x90, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xB7, /* 0xD8-0xDB */
+	0x9F, 0x58, 0x3F, 0x3F, 0xE1, 0xB5, 0x96, 0xBF, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0xE1, 0xB6, 0x3F, 0x3F, 0x8A, 0xC4, /* 0xE0-0xE3 */
+	0x94, 0xD5, 0xE1, 0xB7, 0x3F, 0x3F, 0xE1, 0xB8, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xB9, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xDA, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xD3, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x92, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x91, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xBB, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x82, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_77[512] = {
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x04-0x07 */
-	0x00, 0x00, 0x94, 0x00, 0x3F, 0x3F, 0x8A, 0x00, /* 0x08-0x0B */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x8F, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0xE1, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xBD, /* 0x04-0x07 */
+	0xE1, 0xBC, 0x94, 0xFB, 0x3F, 0x3F, 0x8A, 0xC5, /* 0x08-0x0B */
+	0x8C, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x90, 0x5E, /* 0x1C-0x1F */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xC4, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xC1, 0x90, 0x5E, /* 0x1C-0x1F */
+	0x96, 0xB0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE1, 0xC0, 0xE1, 0xC2, 0xE1, 0xC3, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE1, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x34-0x37 */
-	0x00, 0x00, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xC5, /* 0x34-0x37 */
+	0xE1, 0xC6, 0x3F, 0x3F, 0x92, 0xAD, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x8A, 0xE1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x92, 0x85, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x76, 0x00, 0x00, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x5A, 0xE1, 0xC7, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xC8, 0xE1, 0xCB, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x90, 0x87, 0x3F, 0x3F, 0x93, 0x00, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x00, 0x00, 0x96, 0x72, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x90, 0x87, 0x3F, 0x3F, 0x93, 0xC2, /* 0x60-0x63 */
+	0x3F, 0x3F, 0xE1, 0xCC, 0x96, 0x72, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xE1, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xCA, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE1, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xCE, 0xE1, 0xCD, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xD1, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xD0, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xE1, 0xD2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xD4, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xE1, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x95, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x8F, 0x75, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xB8-0xBB */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xBC-0xBF */
+	0x8F, 0x75, 0x97, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE1, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xB5, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xD6, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE1, 0xD7, 0x3F, 0x3F, 0xE1, 0xDB, /* 0xB8-0xBB */
+	0xE1, 0xD9, 0xE1, 0xDA, 0x3F, 0x3F, 0xE1, 0xD8, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xDC, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0xE1, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x96, 0x00, /* 0xD8-0xDB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x00, 0x00, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xDE, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xDF, 0x96, 0xB5, /* 0xD8-0xDB */
+	0xE1, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xEE, 0xE1, 0xE1, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x92, 0x6D, 0x3F, 0x3F, 0x94, 0x8A, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x92, 0x5A, 0x00, 0x00, 0x8B, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x8B, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x92, 0x5A, 0xE1, 0xE2, 0x8B, 0xB8, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xCE, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xE1, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_78[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xBB, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x8C, 0x00, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0xE1, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xE5, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x8C, 0xA4, 0x8D, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x00, 0x00, 0x00, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x93, 0x75, 0x8D, 0x00, 0x8B, 0x6D, /* 0x24-0x27 */
+	0xE1, 0xE7, 0xEE, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x93, 0x75, 0x8D, 0xD4, 0x8B, 0x6D, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x43, 0x3F, 0x3F, /* 0x30-0x33 */
@@ -6796,438 +6798,438 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x76, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x7B, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE1, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x79, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x5D, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x8F, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0x68-0x6B */
-	0x8D, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7B, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0xEE, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xB0, /* 0x68-0x6B */
+	0x8D, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xA5, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xA1, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE1, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x5F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE1, 0xED, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x92, 0x00, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x8C, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xEC, 0x92, 0xF4, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x00, 0x00, 0x8A, 0x56, 0x00, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x89, 0x4F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, 0x98, 0x71, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xE1, 0xEF, 0x8A, 0x56, 0xE1, 0xEA, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x94, 0xE8, 0x3F, 0x3F, 0x89, 0x4F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x8D, 0xEA, 0x3F, 0x3F, 0x98, 0x71, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xEE, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x90, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xF0, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xC9, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x90, 0xD7, 0xE1, 0xF2, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xF3, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE1, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x6D, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xC8-0xCB */
+	0xE1, 0xF9, 0x3F, 0x3F, 0xE1, 0xF8, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x8E, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0xE1, 0xFA, 0xE1, 0xF5, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xFB, 0xE1, 0xF6, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x94, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x41, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x94, 0xD6, 0xE1, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0xE1, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x41, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x40, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x40, /* 0xE4-0xE7 */
 	0x96, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xEC-0xEF */
+	0xE1, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xE9, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0xE2, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x00, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0xE2, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_79[512] = {
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x44, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x8F, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x44, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x62, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x46, 0x00, 0x45, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE2, 0x46, 0xE2, 0x45, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE2, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x49, /* 0x28-0x2B */
-	0x00, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xE6, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE1, 0xE8, 0xE2, 0x49, /* 0x28-0x2B */
+	0xE2, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xEE, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x97, 0x00, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x00, 0x4A, 0x8C, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xA6, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x97, 0xE7, 0x3F, 0x3F, 0x8E, 0xD0, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0xE2, 0x4A, 0x8C, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x5F, /* 0x44-0x47 */
 	0x8B, 0x46, 0x8E, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x97, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x50, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x4F, 0x91, 0x63, 0x00, 0x4C, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4E, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x8F, 0x6A, 0x90, 0x5F, 0x00, 0x4D, /* 0x5C-0x5F */
-	0x00, 0x4B, 0x3F, 0x3F, 0x94, 0x49, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x97, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x50, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xE2, 0x4F, 0x91, 0x63, 0xE2, 0x4C, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x4E, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x8F, 0x6A, 0x90, 0x5F, 0xE2, 0x4D, /* 0x5C-0x5F */
+	0xE2, 0x4B, 0x3F, 0x3F, 0x94, 0x49, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x8F, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x95, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x8D, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x98, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x51, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x52, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x51, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x52, /* 0x7C-0x7F */
 	
-	0x00, 0x68, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0xE2, 0x68, 0x8B, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x98, 0x5C, 0x91, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x53, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x89, 0x00, 0x92, 0x00, 0x95, 0x9F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x53, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x89, 0xD0, 0x92, 0xF5, 0x95, 0x9F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x83, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x00, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xEE, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x66, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE2, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x9A, 0x00, 0x55, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x57, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x58, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x94, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x59, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x9A, 0xE2, 0x55, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x57, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x58, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x94, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x59, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x5A, 0x00, 0x5B, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x8B, 0x00, 0x89, 0x00, 0x93, 0x00, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0xE2, 0x5A, 0xE2, 0x5B, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x8B, 0xD7, 0x89, 0xD1, 0x93, 0xC3, /* 0xBC-0xBF */
 	0x8F, 0x47, 0x8E, 0x84, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x00, 0x5C, 0x3F, 0x3F, 0x8F, 0x48, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xE2, 0x5C, 0x3F, 0x3F, 0x8F, 0x48, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x89, 0x00, 0x95, 0x62, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x89, 0xC8, 0x95, 0x62, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xE2, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x94, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x64, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x60, 0x3F, 0x3F, 0x00, 0x61, /* 0xE0-0xE3 */
-	0x94, 0x89, 0x3F, 0x3F, 0x90, 0x60, 0x00, 0x5E, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE2, 0x60, 0x3F, 0x3F, 0xE2, 0x61, /* 0xE0-0xE3 */
+	0x94, 0x89, 0x3F, 0x3F, 0x90, 0x60, 0xE2, 0x5E, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x92, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x00, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0xE2, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x8F, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xDA, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_7A[512] = {
 	0x8B, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x00, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x63, 0x90, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xE2, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xF6, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE2, 0x63, 0x90, 0xC5, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x42, /* 0x14-0x17 */
-	0x00, 0x64, 0x00, 0x65, 0x92, 0x74, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x67, /* 0x1C-0x1F */
-	0x00, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x96, 0xAB, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x42, /* 0x14-0x17 */
+	0xE2, 0x64, 0xE2, 0x65, 0x92, 0x74, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x97, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x67, /* 0x1C-0x1F */
+	0xE2, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x69, 0x88, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6C, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6A, /* 0x38-0x3B */
-	0x89, 0x00, 0x8C, 0x6D, 0x00, 0x6B, 0x8D, 0x65, /* 0x3C-0x3F */
-	0x8D, 0x92, 0x3F, 0x3F, 0x95, 0x00, 0x00, 0x6D, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xED, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0xE2, 0x69, 0x88, 0xEE, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x6C, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x6A, /* 0x38-0x3B */
+	0x89, 0xD2, 0x8C, 0x6D, 0xE2, 0x6B, 0x8D, 0x65, /* 0x3C-0x3F */
+	0x8D, 0x92, 0x3F, 0x3F, 0x95, 0xE4, 0xE2, 0x6D, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x73, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x00, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x90, 0x00, 0x89, 0x6E, 0x89, 0x00, /* 0x4C-0x4F */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6E, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE2, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x90, 0xCF, 0x89, 0x6E, 0x89, 0xB8, /* 0x4C-0x4F */
+	0x88, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x6E, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x00, 0x70, 0x00, 0x71, 0x8F, 0x00, /* 0x60-0x63 */
+	0x3F, 0x3F, 0xE2, 0x70, 0xE2, 0x71, 0x8F, 0xF5, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x72, 0x3F, 0x3F, 0x8A, 0x6E, /* 0x68-0x6B */
+	0x3F, 0x3F, 0xE2, 0x72, 0x3F, 0x3F, 0x8A, 0x6E, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE2, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x8C, 0x8A, 0x3F, 0x3F, 0x8B, 0x86, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x75, 0x8B, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x00, 0x76, 0x3F, 0x3F, 0x90, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE2, 0x75, 0x8B, 0xF3, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0xE2, 0x76, 0x3F, 0x3F, 0x90, 0xFA, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x90, 0x00, /* 0x80-0x83 */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x93, 0xCB, 0x3F, 0x3F, 0x90, 0xDE, /* 0x80-0x83 */
+	0x8D, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0xE2, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x82, 0x91, 0x8B, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x00, 0x79, 0x00, 0x7B, 0x00, 0x78, /* 0x94-0x97 */
-	0x00, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE2, 0x79, 0xE2, 0x7B, 0xE2, 0x78, /* 0x94-0x97 */
+	0xE2, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x41, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x00, 0x7C, 0x8C, 0x45, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0xE2, 0x7C, 0x8C, 0x45, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x87, 0x97, 0x71, /* 0xAC-0xAF */
-	0x00, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x80, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xE2, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x80, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x4D, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x83, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x83, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x96, /* 0xC0-0xC3 */
-	0x00, 0x82, 0x00, 0x81, 0x3F, 0x3F, 0x00, 0x85, /* 0xC4-0xC7 */
-	0x00, 0x7D, 0x3F, 0x3F, 0x00, 0x86, 0x97, 0x00, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x87, 0x3F, 0x3F, 0x00, 0x88, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x00, 0x84, 0x9A, 0x00, 0x00, 0x8A, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x8B, 0x00, 0x8C, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x97, 0x00, 0x00, 0x8D, 0x3F, 0x3F, 0x00, 0x00, /* 0xDC-0xDF */
-	0x8F, 0x00, 0x00, 0x8E, 0x00, 0x8F, 0x8F, 0x76, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x93, 0x00, 0x00, 0x90, 0x00, 0x85, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x47, 0x00, 0x87, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x00, 0x91, 0x3F, 0x3F, 0x92, 0x5B, /* 0xEC-0xEF */
-	0x00, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x99, 0x5E, 0x92, 0x7C, 0x8E, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0xFC-0xFF */
+	0xE2, 0x82, 0xE2, 0x81, 0x3F, 0x3F, 0xE2, 0x85, /* 0xC4-0xC7 */
+	0xE2, 0x7D, 0x3F, 0x3F, 0xE2, 0x86, 0x97, 0xA7, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xE2, 0x87, 0x3F, 0x3F, 0xE2, 0x88, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0xEE, 0x67, 0x9A, 0xF2, 0xE2, 0x8A, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xE2, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xE2, 0x8B, 0xE2, 0x8C, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x97, 0xB3, 0xE2, 0x8D, 0x3F, 0x3F, 0xE8, 0xED, /* 0xDC-0xDF */
+	0x8F, 0xCD, 0xE2, 0x8E, 0xE2, 0x8F, 0x8F, 0x76, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x93, 0xB6, 0xE2, 0x90, 0xEE, 0x68, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x47, 0xEE, 0x6A, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0xE2, 0x91, 0x3F, 0x3F, 0x92, 0x5B, /* 0xEC-0xEF */
+	0xE2, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xA3, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x99, 0x5E, 0x92, 0x7C, 0x8E, 0xB1, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xC6, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_7B[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x93, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x96, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x8B, 0x88, 0x3F, 0x3F, 0x00, 0x95, 0x00, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x94, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x93, 0x3F, 0x3F, /* 0x00-0x03 */
+	0xE2, 0xA0, 0x3F, 0x3F, 0xE2, 0x96, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x8B, 0x88, 0x3F, 0x3F, 0xE2, 0x95, 0xE2, 0xA2, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x94, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x8F, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x00, 0x98, 0x00, 0x99, 0x3F, 0x3F, 0x93, 0x4A, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9A, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0xE2, 0x98, 0xE2, 0x99, 0x3F, 0x3F, 0x93, 0x4A, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x9A, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x8A, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x90, 0x79, 0x95, 0x84, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x00, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x97, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x9B, 0x00, 0x9D, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0xE2, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x91, 0xE6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x97, /* 0x30-0x33 */
+	0x3F, 0x3F, 0xE2, 0x9B, 0xE2, 0x9D, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x8D, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x00, 0x95, 0x4D, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x94, 0x00, 0x93, 0x99, 0x3F, 0x3F, 0x8B, 0x00, /* 0x48-0x4B */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x94, 0x00, /* 0x4C-0x4F */
-	0x00, 0x9E, 0x92, 0x7D, 0x93, 0x9B, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x93, 0x9A, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE2, 0xA4, 0x95, 0x4D, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x94, 0xA4, 0x93, 0x99, 0x3F, 0x3F, 0x8B, 0xD8, /* 0x48-0x4B */
+	0xE2, 0xA3, 0xE2, 0xA1, 0x3F, 0x3F, 0x94, 0xB3, /* 0x4C-0x4F */
+	0xE2, 0x9E, 0x92, 0x7D, 0x93, 0x9B, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x93, 0x9A, 0x3F, 0x3F, 0x8D, 0xF4, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0xE2, 0xB6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE2, 0xA6, 0x3F, 0x3F, 0xE2, 0xA8, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE2, 0xAB, 0x3F, 0x3F, 0xE2, 0xAC, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0xE2, 0xA9, 0xE2, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE2, 0xA7, 0xE2, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0x9F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x89, 0x00, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x94, 0x93, 0x96, 0x00, 0x3F, 0x3F, 0x8E, 0x5A, /* 0x94-0x97 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xCD, 0x89, 0xD3, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xB3, /* 0x88-0x8B */
+	0x3F, 0x3F, 0xE2, 0xB0, 0x3F, 0x3F, 0xE2, 0xB5, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xB4, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x94, 0x93, 0x96, 0xA5, 0x3F, 0x3F, 0x8E, 0x5A, /* 0x94-0x97 */
+	0xE2, 0xAE, 0xE2, 0xB7, 0xE2, 0xB2, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xE2, 0xB1, 0xE2, 0xAD, 0xEE, 0x6B, 0xE2, 0xAF, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x8A, 0xC7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x5C, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x90, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x94, 0xA0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xE2, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x94, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x90, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x94, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x95, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x92, 0x7A, 0x3F, 0x3F, 0x00, 0x00, /* 0xC8-0xCB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
+	0x90, 0xDF, 0xE2, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x94, 0xCD, 0x3F, 0x3F, 0xE2, 0xBD, 0x95, 0xD1, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x92, 0x7A, 0x3F, 0x3F, 0xE2, 0xB8, /* 0xC8-0xCB */
+	0xE2, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xBB, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x93, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0xE2, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x8E, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x93, 0xC4, 0xE2, 0xC3, 0xE2, 0xC2, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE2, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x98, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xC8, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xCC, 0xE2, 0xC9, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_7C[512] = {
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x04-0x07 */
+	0xE2, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xC6, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, /* 0x10-0x13 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xE2, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xE2, 0xC0, 0x99, 0xD3, 0xE2, 0xC7, /* 0x10-0x13 */
+	0xE2, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xCA, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xD0, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x8A, 0xC8, 0x3F, 0x3F, 0xE2, 0xCD, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xCE, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xCF, 0xE2, 0xD2, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x34-0x37 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x00, 0x00, 0x97, 0x00, 0x95, 0x00, /* 0x3C-0x3F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xD1, /* 0x34-0x37 */
+	0x94, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xE2, 0xD3, 0x97, 0xFA, 0x95, 0xEB, /* 0x3C-0x3F */
+	0xE2, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xD5, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x00, 0x90, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x4C-0x4F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x5C-0x5F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xE2, 0xD4, 0x90, 0xD0, 0x3F, 0x3F, 0xE2, 0xD7, /* 0x4C-0x4F */
+	0xE2, 0xD9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0xE2, 0xD6, 0x3F, 0x3F, 0xE2, 0xDD, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE2, 0xDA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xDB, /* 0x5C-0x5F */
+	0xE2, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE2, 0xDC, 0xE2, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0xE2, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xC4, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE2, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xE0, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x8B, 0x00, 0x8C, 0x48, 0x00, 0x00, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x8B, 0xCC, 0x8C, 0x48, 0xE2, 0xE1, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x90, 0x88, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x00, 0x00, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x95, 0xB2, 0x3F, 0x3F, 0x90, 0x88, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x96, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0xE2, 0xE2, 0x3F, 0x3F, 0x97, 0xB1, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x94, 0x94, 0x3F, 0x3F, 0x91, 0x65, /* 0x94-0x97 */
 	0x94, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x6C, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x00, 0x00, 0x8A, 0x9F, 0x3F, 0x3F, 0x8F, 0x00, /* 0xA4-0xA7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x00, 0x90, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xBE, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0xE2, 0xE7, 0xE2, 0xE5, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0xE2, 0xE3, 0x8A, 0x9F, 0x3F, 0x3F, 0x8F, 0xCF, /* 0xA4-0xA7 */
+	0xE2, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xE6, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0xE2, 0xE4, 0xE2, 0xEC, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xE2, 0xEB, 0xE2, 0xEA, 0xE2, 0xE9, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE2, 0xED, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE2, 0xEE, 0x90, 0xB8, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0xE2, 0xEF, 0x3F, 0x3F, 0xE2, 0xF1, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0xE2, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xD0, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x57, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xF3, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x9C, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x00, 0x3F, 0x3F, 0x95, 0x00, 0x91, 0x8C, /* 0xDC-0xDF */
-	0x8D, 0x66, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x8E, 0x85, 0x3F, 0x3F, 0x00, 0x00, 0x8C, 0x6E, /* 0xF8-0xFB */
+	0xE2, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xE2, 0xF4, 0x3F, 0x3F, 0x95, 0xB3, 0x91, 0x8C, /* 0xDC-0xDF */
+	0x8D, 0x66, 0x3F, 0x3F, 0xE2, 0xF5, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xC6, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xF7, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xF8, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0xE2, 0xF9, 0x3F, 0x3F, 0xE2, 0xFA, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x8E, 0x85, 0x3F, 0x3F, 0xE2, 0xFB, 0x8C, 0x6E, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x8A, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_7D[512] = {
-	0x8B, 0x49, 0x3F, 0x3F, 0x00, 0x40, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x96, 0x00, 0x8D, 0x67, 0x00, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x43, 0x96, 0x00, /* 0x08-0x0B */
+	0x8B, 0x49, 0x3F, 0x3F, 0xE3, 0x40, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x96, 0xF1, 0x8D, 0x67, 0xE2, 0xFC, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x43, 0x96, 0xE4, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x94, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x95, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x8F, 0x83, 0x00, 0x42, 0x3F, 0x3F, 0x8E, 0x00, /* 0x14-0x17 */
-	0x8D, 0x68, 0x8E, 0x86, 0x8B, 0x89, 0x95, 0x00, /* 0x18-0x1B */
-	0x00, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x91, 0x66, 0x96, 0x61, 0x8D, 0x00, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x8F, 0x83, 0xE3, 0x42, 0x3F, 0x3F, 0x8E, 0xD1, /* 0x14-0x17 */
+	0x8D, 0x68, 0x8E, 0x86, 0x8B, 0x89, 0x95, 0xB4, /* 0x18-0x1B */
+	0xE3, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x91, 0x66, 0x96, 0x61, 0x8D, 0xF5, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x87, /* 0x28-0x2B */
-	0x92, 0x00, 0x3F, 0x3F, 0x00, 0x46, 0x97, 0x00, /* 0x2C-0x2F */
-	0x8D, 0x00, 0x3F, 0x3F, 0x00, 0x47, 0x90, 0x61, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x8F, 0x00, 0x8D, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x48, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x49, 0x8C, 0x00, /* 0x40-0x43 */
-	0x91, 0x67, 0x00, 0x44, 0x00, 0x4A, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x45, /* 0x48-0x4B */
-	0x8C, 0x6F, 0x3F, 0x3F, 0x00, 0x4D, 0x00, 0x51, /* 0x4C-0x4F */
+	0x92, 0xDB, 0x3F, 0x3F, 0xE3, 0x46, 0x97, 0xDD, /* 0x2C-0x2F */
+	0x8D, 0xD7, 0x3F, 0x3F, 0xE3, 0x47, 0x90, 0x61, /* 0x30-0x33 */
+	0x3F, 0x3F, 0xE3, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x8F, 0xD0, 0x8D, 0xAE, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x48, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x49, 0x8C, 0xBC, /* 0x40-0x43 */
+	0x91, 0x67, 0xE3, 0x44, 0xE3, 0x4A, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xEE, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x45, /* 0x48-0x4B */
+	0x8C, 0x6F, 0x3F, 0x3F, 0xE3, 0x4D, 0xE3, 0x51, /* 0x4C-0x4F */
 	0x8C, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4C, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x55, /* 0x58-0x5B */
-	0x00, 0x8B, 0x3F, 0x3F, 0x8D, 0x69, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x97, 0x8D, 0x88, 0x00, 0x00, 0x52, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x4C, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x55, /* 0x58-0x5B */
+	0xEE, 0x6E, 0x3F, 0x3F, 0x8D, 0x69, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x97, 0x8D, 0x88, 0xBA, 0xE3, 0x52, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x8B, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x50, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x93, 0x9D, 0x00, 0x4E, 0x00, 0x4B, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x8A, 0x47, 0x90, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x00, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0xE3, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x50, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x93, 0x9D, 0xE3, 0x4E, 0xE3, 0x4B, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x8A, 0x47, 0x90, 0xE2, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x8C, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0xE3, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x56, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x53, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xE3, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x56, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x53, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x8C, 0x70, 0x91, 0x00, 0x00, 0x58, /* 0x98-0x9B */
-	0x91, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x65, /* 0x9C-0x9F */
-	0x00, 0x8D, 0x3F, 0x3F, 0x00, 0x61, 0x00, 0x5B, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x8C, 0x70, 0x91, 0xB1, 0xE3, 0x58, /* 0x98-0x9B */
+	0x91, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x65, /* 0x9C-0x9F */
+	0xEE, 0x70, 0x3F, 0x3F, 0xE3, 0x61, 0xE3, 0x5B, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5F, /* 0xA8-0xAB */
-	0x8E, 0x00, 0x88, 0x00, 0x00, 0x5A, 0x00, 0x62, /* 0xAC-0xAF */
-	0x00, 0x66, 0x8D, 0x6A, 0x96, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x92, 0x00, 0x00, 0x5C, 0x3F, 0x3F, 0x00, 0x8C, /* 0xB4-0xB7 */
-	0x00, 0x64, 0x3F, 0x3F, 0x00, 0x59, 0x92, 0x5D, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x5E, 0x88, 0x00, 0x96, 0x00, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x5F, /* 0xA8-0xAB */
+	0x8E, 0xF8, 0x88, 0xDB, 0xE3, 0x5A, 0xE3, 0x62, /* 0xAC-0xAF */
+	0xE3, 0x66, 0x8D, 0x6A, 0x96, 0xD4, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x92, 0xD4, 0xE3, 0x5C, 0x3F, 0x3F, 0xEE, 0x6F, /* 0xB4-0xB7 */
+	0xE3, 0x64, 0x3F, 0x3F, 0xE3, 0x59, 0x92, 0x5D, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE3, 0x5E, 0x88, 0xBB, 0x96, 0xC8, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5D, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x94, 0x00, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x5D, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xD9, 0x94, 0xEA, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x8D, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x97, 0x00, 0x8F, 0x8F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x8E, 0x00, 0x8E, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x67, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x63, 0x00, 0x68, 0x00, 0x6A, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x92, 0x00, 0x00, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x00, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x95, 0x00, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6B, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x97, 0xCE, 0x8F, 0x8F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xE3, 0x8E, 0xEE, 0x71, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE3, 0x67, 0x3F, 0x3F, 0x90, 0xFC, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xE3, 0x63, 0xE3, 0x68, 0xE3, 0x6A, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x92, 0xF7, 0xE3, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE3, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x95, 0xD2, 0x8A, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x96, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xDC, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x6C, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x97, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x6B, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_7E[512] = {
 	0x3F, 0x3F, 0x89, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x93, 0x00, 0x00, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x75, 0x00, 0x6F, 0x00, 0x76, /* 0x08-0x0B */
+	0x93, 0xEA, 0xE3, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE3, 0x75, 0xE3, 0x6F, 0xE3, 0x76, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x72, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x72, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x9B, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x00, 0x74, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x71, 0x00, 0x77, 0x00, 0x70, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xC8, 0xE3, 0x74, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xE3, 0x71, 0xE3, 0x77, 0xE3, 0x70, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x63, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x44, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x6B, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x73, 0x00, 0x80, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x7B, 0x3F, 0x3F, 0x00, 0x7E, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x00, 0x7C, 0x00, 0x81, 0x00, 0x7A, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x00, 0x60, 0x90, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x00, 0x7D, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x78, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE3, 0x73, 0xE3, 0x80, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0xE3, 0x7B, 0x3F, 0x3F, 0xE3, 0x7E, /* 0x34-0x37 */
+	0x3F, 0x3F, 0xE3, 0x7C, 0xE3, 0x81, 0xE3, 0x7A, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xE3, 0x60, 0x90, 0xD1, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x94, 0xC9, 0x3F, 0x3F, 0xE3, 0x7D, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x78, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x40, 0x8C, 0x71, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x8F, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x90, 0x44, 0x91, 0x55, 0x00, 0x84, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x86, 0x00, 0x87, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x00, 0x83, 0x00, 0x85, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x72, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x90, 0x44, 0x91, 0x55, 0xE3, 0x84, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE3, 0x86, 0xE3, 0x87, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0xE3, 0x83, 0xE3, 0x85, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x79, 0x00, 0x82, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x8A, 0x00, 0x89, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x79, 0xE3, 0x82, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE3, 0x8A, 0xE3, 0x89, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x96, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x8C, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x88, 0x3F, 0x3F, 0x00, 0x8C, /* 0x78-0x7B */
-	0x00, 0x8B, 0x00, 0x8F, 0x3F, 0x3F, 0x00, 0x91, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE3, 0x88, 0x3F, 0x3F, 0xE3, 0x8C, /* 0x78-0x7B */
+	0xE3, 0x8B, 0xE3, 0x8F, 0x3F, 0x3F, 0xE3, 0x91, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x5B, 0x00, 0x8D, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x5B, 0xE3, 0x8D, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x92, 0x00, 0x93, 0x00, 0x5C, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x00, 0x94, 0x3F, 0x3F, 0x00, 0x9A, 0x93, 0x5A, /* 0x8C-0x8F */
-	0x00, 0x96, 0x3F, 0x3F, 0x00, 0x95, 0x00, 0x97, /* 0x90-0x93 */
-	0x00, 0x98, 0x3F, 0x3F, 0x00, 0x99, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9B, /* 0x98-0x9B */
-	0x00, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xE3, 0x92, 0xE3, 0x93, 0xED, 0x40, 0x3F, 0x3F, /* 0x88-0x8B */
+	0xE3, 0x94, 0x3F, 0x3F, 0xE3, 0x9A, 0x93, 0x5A, /* 0x8C-0x8F */
+	0xE3, 0x96, 0x3F, 0x3F, 0xE3, 0x95, 0xE3, 0x97, /* 0x90-0x93 */
+	0xE3, 0x98, 0x3F, 0x3F, 0xE3, 0x99, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0x9B, /* 0x98-0x9B */
+	0xE3, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
@@ -7268,849 +7270,849 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x00, 0x9D, 0x3F, 0x3F, 0x00, 0x9E, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xCA, 0x3F, 0x3F, /* 0x34-0x37 */
+	0xE3, 0x9D, 0x3F, 0x3F, 0xE3, 0x9E, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x9F, 0x3F, 0x3F, 0x00, 0x90, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE3, 0x9F, 0x3F, 0x3F, 0xEE, 0x73, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x5C-0x5F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x64-0x67 */
-	0x00, 0x00, 0x00, 0x00, 0x8D, 0x00, 0x8C, 0x72, /* 0x68-0x6B */
+	0xE3, 0xA0, 0xE3, 0xA1, 0xE3, 0xA2, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xE3, 0xA3, 0xE3, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0xE3, 0xA6, 0xE3, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE3, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xA8, /* 0x5C-0x5F */
+	0xE3, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xAC, /* 0x64-0x67 */
+	0xE3, 0xAA, 0xE3, 0xAB, 0x8D, 0xDF, 0x8C, 0x72, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x75, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x94, 0x00, 0x3F, 0x3F, 0x8F, 0x90, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x94, 0x6C, 0x3F, 0x3F, 0x94, 0x00, /* 0x74-0x77 */
-	0x00, 0x00, 0x9C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x94, 0xB1, 0x3F, 0x3F, 0x8F, 0x90, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x94, 0x6C, 0x3F, 0x3F, 0x94, 0xEB, /* 0x74-0x77 */
+	0xE3, 0xAD, 0x9C, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x97, 0x85, 0x00, 0x00, 0x00, 0x00, /* 0x84-0x87 */
-	0x00, 0x00, 0x3F, 0x3F, 0x97, 0x72, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x00, 0x00, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xAE, 0xE3, 0xB0, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x97, 0x85, 0xE3, 0xAF, 0xE3, 0xB2, /* 0x84-0x87 */
+	0xE3, 0xB1, 0x3F, 0x3F, 0x97, 0x72, 0x3F, 0x3F, /* 0x88-0x8B */
+	0xE3, 0xB3, 0x3F, 0x3F, 0x94, 0xFC, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x00, 0x91, 0x3F, 0x3F, 0x00, 0x00, /* 0xA0-0xA3 */
+	0xE3, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xB7, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE3, 0xB6, 0xE3, 0xB5, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0xEE, 0x74, 0x3F, 0x3F, 0xE3, 0xB8, /* 0xA0-0xA3 */
 	0x8C, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x91, 0x41, 0x8B, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xBC, 0xE3, 0xB9, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xBA, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xBD, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xE3, 0xBE, 0xE3, 0xBB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x89, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x89, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0xE3, 0xC0, 0xE3, 0xC1, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xC2, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x97, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x4B, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE3, 0xC4, 0xE3, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x90, 0x89, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x8A, 0x00, /* 0xE8-0xEB */
+	0x90, 0x89, 0xE3, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xC6, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE3, 0xC7, 0x3F, 0x3F, 0x8A, 0xE3, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xF0-0xF3 */
+	0x8A, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xC8, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x96, 0x7C, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0xE3, 0xC9, 0x3F, 0x3F, 0x96, 0x7C, /* 0xF8-0xFB */
 	0x97, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_80[512] = {
 	0x97, 0x73, 0x98, 0x56, 0x3F, 0x3F, 0x8D, 0x6C, /* 0x00-0x03 */
-	0x00, 0x00, 0x8E, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x08-0x0B */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x91, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x8D, 0x6B, 0x3F, 0x3F, 0x96, 0x00, /* 0x14-0x17 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE3, 0xCC, 0x8E, 0xD2, 0xE3, 0xCB, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xCD, /* 0x08-0x0B */
+	0x8E, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x91, 0xCF, 0x3F, 0x3F, 0xE3, 0xCE, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x8D, 0x6B, 0x3F, 0x3F, 0x96, 0xD5, /* 0x14-0x17 */
+	0xE3, 0xCF, 0xE3, 0xD0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0xE3, 0xD1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xE3, 0xD2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0xE3, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x92, 0x5E, 0x3F, 0x3F, 0x00, 0x00, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xA8, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xEB, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xD5, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x92, 0x5E, 0x3F, 0x3F, 0xE3, 0xD4, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xD7, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xD6, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x00, 0x00, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x91, 0x8F, 0x00, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xD8, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xB9, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE3, 0xD9, 0x3F, 0x3F, 0xE3, 0xDA, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xB7, 0xE3, 0xDB, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x91, 0x8F, 0xE3, 0xDC, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0x6C-0x6F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x73 */
-	0x92, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x90, 0x45, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x00, 0x00, 0x98, 0x57, 0x00, 0x00, /* 0x7C-0x7F */
+	0xE3, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xFC, /* 0x6C-0x6F */
+	0xE3, 0xE0, 0x3F, 0x3F, 0xE3, 0xDF, 0xE3, 0xDE, /* 0x70-0x73 */
+	0x92, 0xAE, 0x3F, 0x3F, 0xE3, 0xE1, 0x90, 0x45, /* 0x74-0x77 */
+	0x3F, 0x3F, 0xE3, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0xE3, 0xE3, 0x98, 0x57, 0xE3, 0xE4, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x94, 0x00, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x98, 0x5D, /* 0x88-0x8B */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x95, 0x49, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x8C, 0x00, 0x8E, 0x88, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x96, 0x62, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x8D, 0x6D, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x8D, 0x6E, 0x88, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xE3, 0xE5, 0xE3, 0xE7, 0xE3, 0xE6, 0x94, 0xA3, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x93, 0xF7, 0x3F, 0x3F, 0x98, 0x5D, /* 0x88-0x8B */
+	0x94, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xE9, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xD1, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x95, 0x49, 0x3F, 0x3F, 0xE3, 0xEA, 0xE3, 0xE8, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x8A, 0xCC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x8C, 0xD2, 0x8E, 0x88, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x94, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x8C, 0xA8, 0x96, 0x62, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0xE3, 0xED, 0xE3, 0xEB, 0x3F, 0x3F, 0x8D, 0x6D, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x8D, 0x6E, 0x88, 0xE7, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x8D, 0xE6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x78, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xC0-0xC3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x92, 0x5F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xDD, /* 0xC0-0xC3 */
+	0xE3, 0xF2, 0x3F, 0x3F, 0x92, 0x5F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x94, 0x77, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x94, 0x77, 0x3F, 0x3F, 0x91, 0xD9, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x00, 0x00, 0x96, 0x45, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x88, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x45, 0x94, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xF4, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xE3, 0xF0, 0xE3, 0xF3, 0xE3, 0xEE, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xE3, 0xF1, 0x96, 0x45, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x8C, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x88, 0xFB, 0xE3, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xF6, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xE3, 0xF7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x93, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x8B, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0xE4, 0x45, 0x94, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_81[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x89, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x8B, 0x00, 0x90, 0x00, 0x98, 0x65, /* 0x04-0x07 */
-	0x96, 0x00, 0x00, 0x00, 0x90, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x8B, 0xBA, 0x90, 0xC6, 0x98, 0x65, /* 0x04-0x07 */
+	0x96, 0xAC, 0xE3, 0xF5, 0x90, 0xD2, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x72, 0x00, 0x00, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x72, 0xE3, 0xF8, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xFA, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0xE3, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xFB, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x92, 0x45, 0x3F, 0x3F, 0x94, 0x5D, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x42, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x92, 0xAF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x42, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x41, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x41, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE3, 0xFC, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x74, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x95, 0x85, 0x00, 0x44, 0x3F, 0x3F, 0x00, 0x43, /* 0x50-0x53 */
+	0x95, 0x85, 0xE4, 0x44, 0x3F, 0x3F, 0xE4, 0x43, /* 0x50-0x53 */
 	0x8D, 0x6F, 0x98, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x54, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x54, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x00, 0x48, 0x00, 0x49, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x47, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x8D, 0x98, 0x00, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x92, 0x00, 0x95, 0x00, 0x91, 0x42, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE4, 0x48, 0xE4, 0x49, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xEE, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x47, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x8D, 0x98, 0xE4, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE4, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x92, 0xB0, 0x95, 0xA0, 0x91, 0x42, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xDA, /* 0x7C-0x7F */
 	
-	0x00, 0x4E, 0x3F, 0x3F, 0x00, 0x4F, 0x00, 0x4B, /* 0x80-0x83 */
+	0xE4, 0x4E, 0x3F, 0x3F, 0xE4, 0x4F, 0xE4, 0x4B, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x4C, 0x3F, 0x3F, 0x00, 0x4D, 0x3F, 0x3F, /* 0x88-0x8B */
+	0xE4, 0x4C, 0x3F, 0x3F, 0xE4, 0x4D, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x70, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x55, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x00, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x55, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xE4, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x86, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x96, 0x8C, 0x95, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x53, /* 0xA0-0xA3 */
-	0x00, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x96, 0x63, 0x00, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0xE4, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x53, /* 0xA0-0xA3 */
+	0xE4, 0x52, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x96, 0x63, 0xE4, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x00, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x56, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x00, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x00, 0x5A, 0x3F, 0x3F, 0x00, 0x5E, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x5B, 0x00, 0x59, 0x94, 0x5E, /* 0xBC-0xBF */
-	0x00, 0x5C, 0x3F, 0x3F, 0x00, 0x5D, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x00, 0x64, 0x00, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x00, 0x61, 0x3F, 0x3F, 0x91, 0x9F, /* 0xD0-0xD3 */
+	0xE4, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x56, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0xE4, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xE4, 0x5A, 0x3F, 0x3F, 0xE4, 0x5E, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE4, 0x5B, 0xE4, 0x59, 0x94, 0x5E, /* 0xBC-0xBF */
+	0xE4, 0x5C, 0x3F, 0x3F, 0xE4, 0x5D, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xB0, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0xE4, 0x64, 0xE4, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xE4, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0xE4, 0x61, 0x3F, 0x3F, 0x91, 0x9F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x63, 0x00, 0x62, 0x00, 0x65, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x66, /* 0xDC-0xDF */
-	0x00, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x62, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x00, 0x68, /* 0xE4-0xE7 */
-	0x97, 0x00, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0xE4, 0x63, 0xE4, 0x62, 0xE4, 0x65, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x66, /* 0xDC-0xDF */
+	0xE4, 0x67, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x62, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x89, 0xE7, 0x3F, 0x3F, 0xE4, 0x68, /* 0xE4-0xE7 */
+	0x97, 0xD5, 0x3F, 0x3F, 0x8E, 0xA9, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x8F, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x8A, /* 0xF0-0xF3 */
 	0x92, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x69, 0x00, 0x6A, /* 0xF8-0xFB */
-	0x89, 0x50, 0x3F, 0x3F, 0x00, 0x6B, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x69, 0xE4, 0x6A, /* 0xF8-0xFB */
+	0x89, 0x50, 0x3F, 0x3F, 0xE4, 0x6B, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_82[512] = {
-	0x3F, 0x3F, 0x00, 0x6C, 0x00, 0x6D, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x6E, 0x3F, 0x3F, 0x00, 0x6F, /* 0x04-0x07 */
-	0x8B, 0x00, 0x9D, 0x00, 0x00, 0x70, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x90, 0x00, 0x00, 0x71, 0x8E, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x00, 0x72, 0x3F, 0x3F, 0x98, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x73, 0x95, 0x00, /* 0x14-0x17 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x43, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE4, 0x6C, 0xE4, 0x6D, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0xE4, 0x6E, 0x3F, 0x3F, 0xE4, 0x6F, /* 0x04-0x07 */
+	0x8B, 0xBB, 0x9D, 0xA8, 0xE4, 0x70, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x90, 0xE3, 0xE4, 0x71, 0x8E, 0xC9, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xE4, 0x72, 0x3F, 0x3F, 0x98, 0xAE, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x73, 0x95, 0xDC, /* 0x14-0x17 */
+	0x8A, 0xDA, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x43, /* 0x18-0x1B */
 	0x8F, 0x77, 0x3F, 0x3F, 0x95, 0x91, 0x8F, 0x4D, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x74, 0x8D, 0x71, 0x00, 0x75, /* 0x28-0x2B */
-	0x94, 0x00, 0x3F, 0x3F, 0x00, 0x84, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x77, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x91, 0x00, 0x94, 0x95, 0x8C, 0x00, /* 0x34-0x37 */
-	0x00, 0x76, 0x91, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xE4, 0x74, 0x8D, 0x71, 0xE4, 0x75, /* 0x28-0x2B */
+	0x94, 0xCA, 0x3F, 0x3F, 0xE4, 0x84, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x77, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x91, 0xC7, 0x94, 0x95, 0x8C, 0xBD, /* 0x34-0x37 */
+	0xE4, 0x76, 0x91, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x00, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x44-0x47 */
+	0xE4, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xF8, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x7A, 0x00, 0x79, 0x00, 0x7C, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x00, 0x7B, 0x3F, 0x3F, 0x00, 0x7D, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x80, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x7E, 0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x81, 0x3F, 0x3F, 0x00, 0x82, 0x00, 0x83, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x00, 0x97, 0x00, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x00, 0x85, 0x90, 0x46, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x90, 0x00, 0x86, /* 0x74-0x77 */
-	0x00, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x88, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0xE4, 0x7A, 0xE4, 0x79, 0xE4, 0x7C, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0xE4, 0x7B, 0x3F, 0x3F, 0xE4, 0x7D, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x80, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE4, 0x7E, 0x3F, 0x3F, 0x8A, 0xCD, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xE4, 0x81, 0x3F, 0x3F, 0xE4, 0x82, 0xE4, 0x83, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0xAF, 0x97, 0xC7, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0xE4, 0x85, 0x90, 0x46, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x90, 0xE4, 0x86, /* 0x74-0x77 */
+	0xE4, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x88, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x00, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8A, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xF0, /* 0x88-0x8B */
+	0x3F, 0x3F, 0xE4, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x8A, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x95, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x00, 0x8C, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x8E, 0xC5, 0x3F, 0x3F, 0xE4, 0x8C, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x8A, 0x48, 0x88, 0x00, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8B, /* 0xA8-0xAB */
-	0x00, 0x8E, 0x94, 0x6D, 0x3F, 0x3F, 0x90, 0x63, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x96, 0x46, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x8A, 0x48, 0x88, 0xB0, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x8B, /* 0xA8-0xAB */
+	0xE4, 0x8E, 0x94, 0x6D, 0x3F, 0x3F, 0x90, 0x63, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x89, 0xD4, 0x3F, 0x3F, 0x96, 0x46, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x8C, 0x7C, 0x8B, 0x00, 0x3F, 0x3F, 0x00, 0x8D, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x8C, 0x7C, 0x8B, 0xDA, 0x3F, 0x3F, 0xE4, 0x8D, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x89, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x8A, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x89, 0x91, 0x00, 0x92, 0x97, 0x00, /* 0xD0-0xD3 */
-	0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x63, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x9E, 0x3F, 0x3F, 0x89, 0x00, /* 0xD8-0xDB */
-	0x00, 0x9C, 0x3F, 0x3F, 0x00, 0x9A, 0x00, 0x91, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x8F, 0x3F, 0x3F, 0x00, 0x90, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x8E, 0x00, 0x8B, 0x00, 0x92, 0x97, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x89, 0x91, 0xE4, 0x92, 0x97, 0xE8, /* 0xD0-0xD3 */
+	0x91, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x63, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xE4, 0x9E, 0x3F, 0x3F, 0x89, 0xD5, /* 0xD8-0xDB */
+	0xE4, 0x9C, 0x3F, 0x3F, 0xE4, 0x9A, 0xE4, 0x91, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0xE4, 0x8F, 0x3F, 0x3F, 0xE4, 0x90, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x8E, 0xE1, 0x8B, 0xEA, 0x92, 0x97, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xCF, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x89, 0x70, 0x3F, 0x3F, 0x00, 0x94, /* 0xF0-0xF3 */
-	0x00, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x00, 0x99, 0x00, 0x95, 0x00, 0x98, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x89, 0x70, 0x3F, 0x3F, 0xE4, 0x94, /* 0xF0-0xF3 */
+	0xE4, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xE4, 0x99, 0xE4, 0x95, 0xE4, 0x98, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_83[512] = {
-	0x3F, 0x3F, 0x00, 0x93, 0x96, 0x00, 0x00, 0x97, /* 0x00-0x03 */
-	0x89, 0x00, 0x8A, 0x9D, 0x00, 0x9B, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xEE, 0x76, 0x96, 0xCE, 0xE4, 0x97, /* 0x00-0x03 */
+	0x89, 0xD6, 0x8A, 0x9D, 0xE4, 0x9B, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE4, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x73, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x14-0x17 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xA1, 0xE4, 0xAA, /* 0x14-0x17 */
+	0xE4, 0xAB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x88, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xB2, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x00, 0x00, 0x00, 0x9F, 0x92, 0x83, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x91, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x88, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xA9, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xA8, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0xE4, 0xA3, 0xE4, 0xA2, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xE4, 0xA0, 0xE4, 0x9F, 0x92, 0x83, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x91, 0xF9, 0xE4, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xE4, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0xE4, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x91, 0x90, 0x8C, 0x74, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x60, /* 0x4C-0x4F */
-	0x00, 0x00, 0x3F, 0x3F, 0x8D, 0x72, 0x3F, 0x3F, /* 0x50-0x53 */
+	0xE4, 0xA6, 0x3F, 0x3F, 0x8D, 0x72, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x91, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x94, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x77, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x89, 0x00, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0x78-0x7B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x95, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xB8, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE4, 0xB9, 0x3F, 0x3F, 0x89, 0xD7, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xAC, /* 0x78-0x7B */
+	0xE4, 0xB6, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x78, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x96, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, 0x00, 0x00, /* 0x9C-0x9F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0xE4, 0xAC, 0x3F, 0x3F, 0xE4, 0xB4, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xE4, 0xBB, 0xE4, 0xB5, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xB3, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0x96, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xB1, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xAD, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xCE, 0xE4, 0xAF, /* 0x9C-0x9F */
+	0xE4, 0xBA, 0x3F, 0x3F, 0xE4, 0xB0, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x94, 0x9C, /* 0xA8-0xAB */
+	0xE4, 0xBC, 0x3F, 0x3F, 0xE4, 0xAE, 0x94, 0x9C, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x97, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE4, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x90, 0x9B, 0x3F, 0x3F, 0x00, 0x96, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0xE4, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0xE4, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x90, 0x9B, 0x3F, 0x3F, 0xEE, 0x79, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x65, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x8B, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x8D, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x70, /* 0xDC-0xDF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x8B, 0xDB, 0x3F, 0x3F, 0xE4, 0xC0, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xD9, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xD2, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE4, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x8D, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x70, /* 0xDC-0xDF */
+	0xE4, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0xEC-0xEF */
-	0x8C, 0x00, 0x95, 0x48, 0x00, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x97, 0x00, 0x00, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x95, 0xEC, 0x3F, 0x3F, 0xE4, 0xBF, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xD8, /* 0xEC-0xEF */
+	0x8C, 0xD4, 0x95, 0x48, 0xE4, 0xC9, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0xE4, 0xBD, 0x3F, 0x3F, 0xEE, 0x7A, 0xE4, 0xC6, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xD0, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0xE4, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_84[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x00-0x03 */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x08-0x0B */
-	0x96, 0x47, 0x00, 0x00, 0x88, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xC2, /* 0x00-0x03 */
+	0x93, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xC7, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xC4, /* 0x08-0x0B */
+	0x96, 0x47, 0xE4, 0xCA, 0x88, 0xDE, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xBE, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE4, 0xCC, 0x3F, 0x3F, 0xE4, 0xCB, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x94, 0x8B, 0x00, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x94, 0x8B, 0xE4, 0xD2, 0x3F, 0x3F, /* 0x28-0x2B */
+	0xE4, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x8A, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x00, 0x00, 0x97, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0xE4, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0xE4, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0xE4, 0xD3, 0x97, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x98, 0x97, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xDC, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xEE, 0x7B, 0x97, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xA8, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x98, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x8B, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x95, 0x92, 0x00, 0x00, 0x93, 0x9F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x68-0x6B */
-	0x91, 0x92, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x95, 0x92, 0xE4, 0xE2, 0x93, 0x9F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xAF, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE4, 0xDB, 0x3F, 0x3F, 0xE4, 0xD7, /* 0x68-0x6B */
+	0x91, 0x92, 0xE4, 0xD1, 0xE4, 0xD9, 0xE4, 0xDE, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x94, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x00, 0x95, 0x98, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x88, 0xA8, 0x3F, 0x3F, 0xE4, 0xD6, /* 0x74-0x77 */
+	0x3F, 0x3F, 0xE4, 0xDF, 0x95, 0x98, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x00, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xDA, 0x3F, 0x3F, /* 0x80-0x83 */
+	0xE4, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0xD3, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x8F, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x95, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x8E, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x96, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x95, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xE5, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0xE4, 0xEE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xE4, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x97, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x00, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x8F, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xB8-0xBB */
-	0x91, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x92, 0x7E, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x97, 0x75, 0x00, 0x00, 0x8A, 0x57, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x00, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xEE, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x8F, 0xF6, 0xE4, 0xE3, 0x3F, 0x3F, 0xE4, 0xE8, /* 0xB8-0xBB */
+	0x91, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xE4, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0xE4, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x92, 0x7E, 0x3F, 0x3F, 0xE4, 0xEC, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x97, 0x75, 0xE4, 0xE1, 0x8A, 0x57, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xE4, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0xE4, 0xEA, 0x96, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xED, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xE4, 0xE6, 0xE4, 0xE9, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xED, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x96, 0x48, 0x3F, 0x3F, 0x98, 0x40, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0xE4, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xFC-0xFF */
+	0xE4, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xF0, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_85[512] = {
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x8E, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xCF, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x96, 0x00, /* 0x10-0x13 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x14-0x17 */
-	0x00, 0x00, 0x3F, 0x3F, 0x89, 0x55, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x95, 0xCC, 0x3F, 0x3F, 0x96, 0xA0, /* 0x10-0x13 */
+	0xE4, 0xF7, 0xE4, 0xF6, 0x3F, 0x3F, 0xE4, 0xF2, /* 0x14-0x17 */
+	0xE4, 0xF3, 0x3F, 0x3F, 0x89, 0x55, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xF5, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xE4, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xD3, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x00, 0x00, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xE4, 0xF4, 0x88, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x91, 0xA0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x00, 0x00, 0x00, 0x40, 0x3F, 0x3F, 0x94, 0x00, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x95, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0xE4, 0xF9, 0xE5, 0x40, 0x3F, 0x3F, 0x94, 0xD7, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x00, 0x8F, 0x00, 0x8E, 0x00, 0x00, 0x42, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9A, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x43, 0x3F, 0x3F, 0x95, 0x99, /* 0x54-0x57 */
-	0x00, 0x00, 0x00, 0x9B, 0x00, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
+	0xE4, 0xFC, 0x8F, 0xD4, 0x8E, 0xC7, 0xE5, 0x42, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xBC, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x7D, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xE5, 0x43, 0x3F, 0x3F, 0x95, 0x99, /* 0x54-0x57 */
+	0xE4, 0xFB, 0xEE, 0x7E, 0xE4, 0xD4, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE4, 0xFA, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x98, 0x6E, 0x93, 0x00, 0x95, 0x93, 0x00, 0x9C, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x00, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x98, 0x6E, 0x93, 0xA0, 0x95, 0x93, 0xEE, 0x80, /* 0x68-0x6B */
+	0x3F, 0x3F, 0xE5, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x50, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x50, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x51, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x51, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x00, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x94, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4E, /* 0x84-0x87 */
-	0x00, 0x46, 0x3F, 0x3F, 0x00, 0x48, 0x3F, 0x3F, /* 0x88-0x8B */
+	0xE5, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x94, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x4E, /* 0x84-0x87 */
+	0xE5, 0x46, 0x3F, 0x3F, 0xE5, 0x48, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x00, 0x52, 0x00, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x92, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x00, 0x4C, /* 0x98-0x9B */
-	0x00, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xE5, 0x52, 0xE5, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0xE5, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x92, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x93, 0xE3, 0x3F, 0x3F, 0xE5, 0x4C, /* 0x98-0x9B */
+	0xE5, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x00, 0x45, 0x3F, 0x3F, 0x91, 0x45, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x00, 0x49, 0x8E, 0x46, 0x90, 0x64, 0x8C, 0x4F, /* 0xA8-0xAB */
-	0x96, 0x00, 0x3F, 0x3F, 0x96, 0x00, 0x8F, 0x92, /* 0xAC-0xAF */
-	0x00, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xE5, 0x45, 0x3F, 0x3F, 0x91, 0x45, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0xE5, 0x49, 0x8E, 0x46, 0x90, 0x64, 0x8C, 0x4F, /* 0xA8-0xAB */
+	0x96, 0xF2, 0x3F, 0x3F, 0x96, 0xF7, 0x8F, 0x92, /* 0xAC-0xAF */
+	0xEE, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x56, 0x00, 0x54, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE5, 0x56, 0xE5, 0x54, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x98, 0x6D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x00, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x97, 0x95, 0x3F, 0x3F, 0x00, 0x55, /* 0xCC-0xCF */
-	0x00, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xE5, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x97, 0x95, 0x3F, 0x3F, 0xE5, 0x55, /* 0xCC-0xCF */
+	0xE5, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xE5, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x5B, 0x00, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xE5, 0x5B, 0xE5, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x93, 0x00, 0x00, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x94, 0x00, 0x00, 0x4D, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x93, 0xA1, 0xE5, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x94, 0xCB, 0xE5, 0x4D, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x93, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x00, 0x5C, 0x00, 0x61, 0x91, 0x94, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x60, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0xE5, 0x5C, 0xE5, 0x61, 0x91, 0x94, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x60, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_86[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x41, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x62, 0x91, 0x68, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5D, 0x00, 0x5F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x41, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x62, 0x91, 0x68, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x5D, 0xE5, 0x5F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5E, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x5E, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x9F, 0x50, 0x9F, 0x41, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x64, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x64, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x63, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x63, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x97, 0x96, 0x3F, 0x3F, 0x00, 0x00, /* 0x2C-0x2F */
-	0x00, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x97, 0x96, 0x3F, 0x3F, 0xE1, 0xBA, /* 0x2C-0x2F */
+	0xE5, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x66, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x66, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x00, 0x67, 0x8C, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0xE5, 0x67, 0x8C, 0xD5, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x8B, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x00, 0x69, 0x99, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE5, 0x69, 0x99, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x95, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x97, 0x00, 0x3F, 0x3F, 0x8B, 0x00, 0x00, 0x6A, /* 0x5C-0x5F */
+	0x97, 0xB8, 0x3F, 0x3F, 0x8B, 0xF1, 0xE5, 0x6A, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6B, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x6B, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x8E, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE5, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x88, 0x00, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x93, 0xF8, 0x3F, 0x3F, 0x88, 0xB8, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x00, 0x71, /* 0x88-0x8B */
-	0x00, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6D, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xE1, 0xE5, 0x71, /* 0x88-0x8B */
+	0xE5, 0x72, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x6D, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x8E, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6E, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x6E, /* 0xA0-0xA3 */
 	0x94, 0x61, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x7A, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x74, /* 0xAC-0xAF */
-	0x00, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x73, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE5, 0x6F, 0xE5, 0x70, 0xE5, 0x7A, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x74, /* 0xAC-0xAF */
+	0xE5, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x73, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x00, 0x75, 0x3F, 0x3F, 0x00, 0x76, 0x8E, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x00, 0x78, 0x3F, 0x3F, 0x92, 0x60, /* 0xC8-0xCB */
+	0xE5, 0x75, 0x3F, 0x3F, 0xE5, 0x76, 0x8E, 0xD6, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0xE5, 0x78, 0x3F, 0x3F, 0x92, 0x60, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x8C, 0x75, 0x8A, 0x61, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x8A, 0x5E, 0x3F, 0x3F, 0x00, 0x81, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7C, 0x00, 0x80, /* 0xDC-0xDF */
+	0xE5, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x8A, 0x5E, 0x3F, 0x3F, 0xE5, 0x81, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x7C, 0xE5, 0x80, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x00, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x00, 0x7E, 0x95, 0x67, 0x94, 0x00, 0x00, 0x82, /* 0xEC-0xEF */
+	0x94, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE5, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0xE5, 0x7E, 0x95, 0x67, 0x94, 0xD8, 0xE5, 0x82, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x91, 0x00, 0x00, 0x8C, 0x3F, 0x3F, 0x00, 0x88, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x91, 0xFB, 0xE5, 0x8C, 0x3F, 0x3F, 0xE5, 0x88, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xE9, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_87[512] = {
-	0x00, 0x86, 0x3F, 0x3F, 0x96, 0x49, 0x00, 0x87, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x84, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x00, 0x85, 0x00, 0x8A, 0x00, 0x8D, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x89, 0x00, 0x83, 0x3F, 0x3F, /* 0x10-0x13 */
+	0xE5, 0x86, 0x3F, 0x3F, 0x96, 0x49, 0xE5, 0x87, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x84, 0x3F, 0x3F, /* 0x04-0x07 */
+	0xE5, 0x85, 0xE5, 0x8A, 0xE5, 0x8D, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE5, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xE5, 0x89, 0xE5, 0x83, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x92, 0x77, 0x3F, 0x3F, 0x00, 0x94, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x92, 0x77, 0x3F, 0x3F, 0xE5, 0x94, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x96, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x00, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0xE5, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE5, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x00, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x90, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x91, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8F, /* 0x3C-0x3F */
+	0xE5, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x90, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x91, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x8F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x98, 0x58, /* 0x48-0x4B */
-	0x00, 0x98, 0x3F, 0x3F, 0x00, 0x99, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x90, 0x49, 0x3F, 0x3F, 0x00, 0x9B, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x96, /* 0x5C-0x5F */
-	0x00, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x9C, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9D, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x90, 0xE4, 0x3F, 0x3F, 0x98, 0x58, /* 0x48-0x4B */
+	0xE5, 0x98, 0x3F, 0x3F, 0xE5, 0x99, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x9F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x90, 0x49, 0x3F, 0x3F, 0xE5, 0x9B, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE5, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x96, /* 0x5C-0x5F */
+	0xE5, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xA0, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xDA, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xE5, 0x9C, 0x3F, 0x3F, 0xE5, 0xA1, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0x9D, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x9A, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x00, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE5, 0x9A, 0x3F, 0x3F, 0x92, 0xB1, 0x3F, 0x3F, /* 0x74-0x77 */
+	0xE5, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x88, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xA5, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x97, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xA4, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xA3, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x86, 0x00, 0x00, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xAC, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xA6, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xAE, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x86, 0xE5, 0xB1, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE5, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0xE5, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0xE5, 0xAD, 0x3F, 0x3F, 0xE5, 0xB0, 0xE5, 0xAF, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xA7, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0xE5, 0xAA, 0x3F, 0x3F, 0xE5, 0xBB, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE5, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xB2, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xB3, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xB8, 0xE5, 0xB9, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x8A, 0x49, 0x3F, 0x3F, 0x8B, 0x61, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xB7, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_88[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE5, 0xA2, 0x3F, 0x3F, 0xEE, 0x85, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xE5, 0xB6, 0xE5, 0xBA, 0xE5, 0xB5, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xE5, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE5, 0xBE, 0xE5, 0xBD, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE5, 0xC0, 0xE5, 0xBF, 0xE5, 0x79, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xC4, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xE5, 0xC1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xC2, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0xE5, 0xC3, 0x3F, 0x3F, 0xE5, 0xC5, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x8C, 0x8C, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x00, 0x00, 0x3F, 0x3F, 0x8F, 0x4F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x8C, 0x8C, 0x3F, 0x3F, 0xE5, 0xC7, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xE5, 0xC6, 0x3F, 0x3F, 0x8F, 0x4F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x8D, 0x73, 0x9F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x8F, 0x70, /* 0x50-0x53 */
+	0x8D, 0x73, 0x9F, 0xA5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xC8, 0x8F, 0x70, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x58, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x89, 0x71, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x8F, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x8D, 0x74, 0x00, 0x00, 0x88, 0x00, /* 0x60-0x63 */
+	0x3F, 0x3F, 0xE5, 0xC9, 0x3F, 0x3F, 0x89, 0x71, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x8F, 0xD5, 0xE5, 0xCA, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x8D, 0x74, 0xE5, 0xCB, 0x88, 0xDF, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x95, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x68-0x6B */
+	0x95, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xCC, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x90, 0x8A, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x92, 0x8F, /* 0x74-0x77 */
+	0x90, 0x8A, 0x3F, 0x3F, 0xE5, 0xD3, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE5, 0xD0, 0x3F, 0x3F, 0x92, 0x8F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x8B, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE5, 0xD1, 0xE5, 0xCE, 0x8B, 0xDC, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0xE5, 0xCD, 0xE5, 0xD4, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x8C, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x00, 0x00, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x8C, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x88, 0x00, /* 0xB4-0xB7 */
+	0x8C, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xDC, /* 0x88-0x8B */
+	0x3F, 0x3F, 0xE5, 0xDA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xD6, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xB3, 0xE5, 0xD5, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xE5, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xCF, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xD9, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0xE5, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xED, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xD7, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE5, 0xDC, 0xE5, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x8C, 0xD1, 0xE5, 0xD2, 0x3F, 0x3F, 0x88, 0xBF, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x8D, 0x00, 0x97, 0x00, 0x00, 0x00, /* 0xC0-0xC3 */
-	0x00, 0x00, 0x91, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xDD, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x8D, 0xD9, 0x97, 0xF4, 0xE5, 0xDF, /* 0xC0-0xC3 */
+	0xE5, 0xE0, 0x91, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xA0, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x00, 0x97, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x95, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x8D, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE5, 0xE1, 0x97, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE5, 0xE2, 0xE5, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x95, 0xE2, 0xE5, 0xE4, 0x3F, 0x3F, 0x8D, 0xBE, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x97, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0xE5, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x8F, 0x00, /* 0xF0-0xF3 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x97, 0x87, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x00, 0x90, 0x00, 0x90, 0x9E, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xEA, 0x8F, 0xD6, /* 0xF0-0xF3 */
+	0xE5, 0xE8, 0xEE, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x97, 0x87, 0xE5, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0xE5, 0xE7, 0x90, 0xBB, 0x90, 0x9E, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_89[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x8A, 0x8C, 0x3F, 0x3F, 0x96, 0x4A, 0x00, 0x00, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xE6, 0x3F, 0x3F, /* 0x00-0x03 */
+	0xE5, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xA1, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xED, 0x3F, 0x3F, /* 0x08-0x0B */
+	0xE5, 0xEC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x8A, 0x8C, 0x3F, 0x3F, 0x96, 0x4A, 0xE5, 0xEE, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x00, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0xED, 0x41, 0xE5, 0xFA, 0xE5, 0xF0, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2B */
+	0x3F, 0x3F, 0xE5, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xF2, 0xE5, 0xF3, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xF7, 0x3F, 0x3F, /* 0x34-0x37 */
+	0xE5, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xF6, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x40-0x43 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE5, 0xF4, 0x3F, 0x3F, 0xE5, 0xEF, /* 0x40-0x43 */
+	0xE5, 0xF5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xE5, 0xF9, 0xE8, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xA6, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x8B, 0x00, /* 0x5C-0x5F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x41, 0x3F, 0x3F, 0x00, 0x40, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x43, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x00, 0x42, 0x3F, 0x3F, 0x00, 0x44, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE5, 0xFC, 0x8B, 0xDD, /* 0x5C-0x5F */
+	0xE5, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE6, 0x41, 0x3F, 0x3F, 0xE6, 0x40, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x43, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0xE6, 0x42, 0x3F, 0x3F, 0xE6, 0x44, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x50, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x46, /* 0x74-0x77 */
+	0xE6, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x46, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x47, 0x90, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x47, 0x90, 0xBC, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x97, 0x76, 0x3F, 0x3F, 0x00, 0x48, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x94, 0x65, /* 0x84-0x87 */
-	0x00, 0x49, 0x3F, 0x3F, 0x00, 0x4A, 0x8C, 0x00, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x97, 0x76, 0x3F, 0x3F, 0xE6, 0x48, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xA2, 0x94, 0x65, /* 0x84-0x87 */
+	0xE6, 0x49, 0x3F, 0x3F, 0xE6, 0x4A, 0x8C, 0xA9, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x4B, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4B, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x4B, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x8B, 0x94, 0x60, /* 0x94-0x97 */
-	0x00, 0x4C, 0x3F, 0x3F, 0x8A, 0x6F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xE6, 0x4C, 0x3F, 0x3F, 0x8A, 0x6F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x00, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4F, 0x97, 0x97, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x00, 0x4E, 0x90, 0x65, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x51, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x52, 0x8A, 0x00, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x53, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x00, 0x54, 0x3F, 0x3F, 0x00, 0x55, /* 0xBC-0xBF */
-	0x00, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0xE6, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x4F, 0x97, 0x97, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0xE6, 0x4E, 0x90, 0x65, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0xE6, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x51, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x52, 0x8A, 0xCF, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x53, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE6, 0x54, 0x3F, 0x3F, 0xE6, 0x55, /* 0xBC-0xBF */
+	0xE6, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x70, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x57, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x58, 0x00, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x47, 0x00, 0x5A, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x57, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xE6, 0x58, 0xE6, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xF0, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x47, 0xE6, 0x5A, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x00, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0xE6, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0xE6, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_8A[512] = {
-	0x8C, 0x00, 0x3F, 0x3F, 0x92, 0x00, 0x00, 0x5D, /* 0x00-0x03 */
+	0x8C, 0xBE, 0x3F, 0x3F, 0x92, 0xF9, 0xE6, 0x5D, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x8C, 0x76, 0x3F, 0x3F, 0x90, 0x75, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x60, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x00, 0x5F, 0x3F, 0x3F, 0x00, 0x00, 0x8C, 0x50, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5E, 0x91, 0x00, /* 0x14-0x17 */
-	0x8B, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x61, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x00, 0x62, 0x3F, 0x3F, 0x8F, 0x00, /* 0x1C-0x1F */
+	0xE6, 0x60, 0x3F, 0x3F, 0x93, 0xA2, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xE6, 0x5F, 0x3F, 0x3F, 0xEE, 0x87, 0x8C, 0x50, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x5E, 0x91, 0xF5, /* 0x14-0x17 */
+	0x8B, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x61, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE6, 0x62, 0x3F, 0x3F, 0x8F, 0xD7, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x8D, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x00, 0x63, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE6, 0x63, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x4B, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x8B, 0x96, 0x3F, 0x3F, 0x96, 0x00, /* 0x30-0x33 */
-	0x91, 0x69, 0x3F, 0x3F, 0x00, 0x64, 0x00, 0x00, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x90, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x8B, 0x96, 0x3F, 0x3F, 0x96, 0xF3, /* 0x30-0x33 */
+	0x91, 0x69, 0x3F, 0x3F, 0xE6, 0x64, 0xEE, 0x88, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x66, 0x92, 0x90, /* 0x38-0x3B */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x68, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x8F, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0xE6, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x68, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xE6, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x8D, 0x00, 0x91, 0x00, 0x00, 0x67, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x8F, 0x00, 0x95, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x66, /* 0x58-0x5B */
+	0x8D, 0xBC, 0x91, 0xC0, 0xE6, 0x67, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x8F, 0xD9, 0x95, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x66, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x8C, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x89, 0x72, 0x3F, 0x3F, 0x00, 0x6D, 0x8C, 0x77, /* 0x60-0x63 */
+	0x89, 0x72, 0x3F, 0x3F, 0xE6, 0x6D, 0x8C, 0x77, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x8E, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x8E, 0x8D, 0x3F, 0x3F, 0x98, 0x6C, /* 0x68-0x6B */
-	0x00, 0x6C, 0x00, 0x6B, 0x91, 0x46, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x8B, 0x6C, 0x98, 0x62, 0x8A, 0x59, 0x8F, 0x00, /* 0x70-0x73 */
+	0xE6, 0x6C, 0xE6, 0x6B, 0x91, 0x46, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x8B, 0x6C, 0x98, 0x62, 0x8A, 0x59, 0x8F, 0xDA, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xEE, 0x89, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE6, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x00, 0x70, 0x00, 0x6E, 0x3F, 0x3F, 0x8C, 0x00, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x6F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0xE6, 0x70, 0xE6, 0x6E, 0x3F, 0x3F, 0x8C, 0xD6, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x97, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x8E, 0x8F, 0x94, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x00, 0x73, 0x3F, 0x3F, 0x90, 0x00, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xE6, 0x73, 0x3F, 0x3F, 0x90, 0xBE, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x92, 0x61, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x97, 0x55, 0x3F, 0x3F, 0x00, 0x76, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x90, 0x00, 0x00, 0x72, 0x3F, 0x3F, 0x00, 0x77, /* 0xA0-0xA3 */
-	0x8C, 0x00, 0x00, 0x74, 0x00, 0x75, 0x00, 0x00, /* 0xA4-0xA7 */
-	0x00, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x90, 0x00, 0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x92, 0x4E, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x8B, 0x62, 0x3F, 0x3F, 0x00, 0x00, 0x92, 0x00, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7A, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x00, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x6B, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0xC8-0xCB */
-	0x8A, 0x00, 0x00, 0x79, 0x3F, 0x3F, 0x90, 0x7A, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x97, 0x55, 0x3F, 0x3F, 0xE6, 0x76, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xEA, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x90, 0xBD, 0xE6, 0x72, 0x3F, 0x3F, 0xE6, 0x77, /* 0xA0-0xA3 */
+	0x8C, 0xEB, 0xE6, 0x74, 0xE6, 0x75, 0xEE, 0x8A, /* 0xA4-0xA7 */
+	0xE6, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x90, 0xE0, 0x93, 0xC7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x92, 0x4E, 0x3F, 0x3F, 0x89, 0xDB, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x94, 0xEE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x8B, 0x62, 0x3F, 0x3F, 0xEE, 0x8B, 0x92, 0xB2, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x7A, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0xE6, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x6B, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xBF, /* 0xC8-0xCB */
+	0x8A, 0xD0, 0xE6, 0x79, 0x3F, 0x3F, 0x90, 0x7A, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xC8, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x5F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7B, 0x00, 0x87, /* 0xD8-0xDB */
-	0x92, 0x00, 0x3F, 0x3F, 0x00, 0x86, 0x00, 0x00, /* 0xDC-0xDF */
-	0x00, 0x83, 0x00, 0x8B, 0x00, 0x84, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x00, 0x80, 0x3F, 0x3F, 0x92, 0x00, 0x00, 0x7E, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7C, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x7B, 0xE6, 0x87, /* 0xD8-0xDB */
+	0x92, 0xB3, 0x3F, 0x3F, 0xE6, 0x86, 0xEE, 0x8C, /* 0xDC-0xDF */
+	0xE6, 0x83, 0xE6, 0x8B, 0xE6, 0x84, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE6, 0x80, 0x3F, 0x3F, 0x92, 0xFA, 0xE6, 0x7E, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x7C, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x97, 0x40, 0x8E, 0x90, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x81, 0x3F, 0x3F, 0x00, 0x7D, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x85, /* 0xF4-0xF7 */
-	0x8F, 0x94, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0xE6, 0x81, 0x3F, 0x3F, 0xE6, 0x7D, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x8E, 0xE6, 0x85, /* 0xF4-0xF7 */
+	0x8F, 0x94, 0x3F, 0x3F, 0x8C, 0xBF, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xF8, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_8B[512] = {
-	0x96, 0x64, 0x89, 0x79, 0x88, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x89, /* 0x04-0x07 */
+	0x96, 0x64, 0x89, 0x79, 0x88, 0xE0, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x93, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x89, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x88, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x00, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x00, 0x82, 0x3F, 0x3F, 0x00, 0x8C, 0x00, 0x8E, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x00, 0x8A, 0x8D, 0x75, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x00, 0x8F, 0x97, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x92, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x00, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x93, /* 0x28-0x2B */
+	0xE6, 0x88, 0x3F, 0x3F, 0x93, 0xE4, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xE6, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0xE6, 0x82, 0x3F, 0x3F, 0xE6, 0x8C, 0xE6, 0x8E, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x8C, 0xAA, 0xE6, 0x8A, 0x8D, 0x75, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x8E, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0xE6, 0x8F, 0x97, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x92, 0x3F, 0x3F, /* 0x24-0x27 */
+	0xE6, 0x95, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x93, /* 0x28-0x2B */
 	0x95, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x90, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x90, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x94, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x8B, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x94, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0xE6, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x00, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x97, 0x3F, 0x3F, 0x00, 0x99, 0x00, 0x98, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9B, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x8E, 0x00, 0x3F, 0x3F, 0x00, 0x9D, 0x00, 0x9C, /* 0x58-0x5B */
-	0x95, 0x88, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0xE6, 0x9A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xE6, 0x97, 0x3F, 0x3F, 0xE6, 0x99, 0xE6, 0x98, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x8F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x9B, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x8E, 0xAF, 0x3F, 0x3F, 0xE6, 0x9D, 0xE6, 0x9C, /* 0x58-0x5B */
+	0x95, 0x88, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x9F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x78, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9E, /* 0x68-0x6B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x6C-0x6F */
-	0x8B, 0x63, 0x00, 0x00, 0x8F, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x9E, /* 0x68-0x6B */
+	0xE6, 0xA0, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xA1, /* 0x6C-0x6F */
+	0x8B, 0x63, 0xE3, 0xBF, 0x8F, 0xF7, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE6, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xEC, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE6, 0xA3, 0x3F, 0x3F, 0xEE, 0x90, /* 0x7C-0x7F */
 	
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x5D, /* 0x80-0x83 */
+	0xE6, 0xA4, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x5D, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x8F, 0x51, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x9D, 0xCC, 0x3F, 0x3F, /* 0x88-0x8B */
+	0xE6, 0xA5, 0x3F, 0x3F, 0xE6, 0xA6, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x8F, 0x51, 0x3F, 0x3F, 0xE6, 0xA7, 0xE6, 0xA8, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xA9, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xE6, 0xAA, 0xE6, 0xAB, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
@@ -8153,66 +8155,66 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x4A, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x00, 0x3F, 0x3F, 0x96, 0x4C, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xAC, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xAE, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0xE6, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xA4, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xE6, 0xAF, 0x3F, 0x3F, 0x96, 0x4C, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xE6, 0xB0, 0x3F, 0x3F, 0xE6, 0xB1, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xE6, 0xB2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xE6, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xD8, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x8F, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x8F, 0xDB, 0xE6, 0xB4, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x8B, 0x98, 0x00, /* 0x68-0x6B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x8B, 0x98, 0xAC, /* 0x68-0x6B */
+	0xE6, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x00, 0x00, 0x95, 0x5E, 0x00, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0xE6, 0xB6, 0x95, 0x5E, 0xE6, 0xB7, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE6, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x96, 0x65, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xB8, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0xE6, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xE6, 0xB9, 0xE6, 0xBB, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x96, 0x65, 0xE6, 0xBC, 0xE6, 0xBD, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x8A, 0x4C, 0x92, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x95, 0x89, 0x8D, 0x00, 0x8D, 0x76, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0xE6, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0xE6, 0xC0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x8A, 0x4C, 0x92, 0xE5, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x95, 0x89, 0x8D, 0xE0, 0x8D, 0x76, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x6E, /* 0xA4-0xA7 */
-	0x89, 0x00, 0x94, 0x00, 0x00, 0x00, 0x8A, 0x00, /* 0xA8-0xAB */
-	0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x99, /* 0xAC-0xAF */
-	0x96, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xB0-0xB3 */
-	0x8B, 0x4D, 0x3F, 0x3F, 0x00, 0x00, 0x94, 0x83, /* 0xB4-0xB7 */
-	0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0xB8-0xBB */
-	0x93, 0x5C, 0x00, 0x00, 0x3F, 0x3F, 0x96, 0x66, /* 0xBC-0xBF */
-	0x89, 0x00, 0x00, 0x00, 0x98, 0x47, 0x92, 0x00, /* 0xC0-0xC3 */
+	0x89, 0xDD, 0x94, 0xCC, 0xE6, 0xC3, 0x8A, 0xD1, /* 0xA8-0xAB */
+	0x90, 0xD3, 0xE6, 0xC2, 0xE6, 0xC7, 0x92, 0x99, /* 0xAC-0xAF */
+	0x96, 0xE1, 0x3F, 0x3F, 0xE6, 0xC5, 0xE6, 0xC6, /* 0xB0-0xB3 */
+	0x8B, 0x4D, 0x3F, 0x3F, 0xE6, 0xC8, 0x94, 0x83, /* 0xB4-0xB7 */
+	0x91, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xEF, /* 0xB8-0xBB */
+	0x93, 0x5C, 0xE6, 0xC4, 0x3F, 0x3F, 0x96, 0x66, /* 0xBC-0xBF */
+	0x89, 0xEA, 0xE6, 0xCA, 0x98, 0x47, 0x92, 0xC0, /* 0xC0-0xC3 */
 	0x98, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x91, /* 0xC4-0xC7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x00, 0x00, 0x91, 0x47, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x95, 0x6F, /* 0xD0-0xD3 */
+	0xE6, 0xC9, 0x3F, 0x3F, 0x91, 0xAF, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0xE6, 0xDA, 0x91, 0x47, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x93, 0xF6, 0x3F, 0x3F, 0x95, 0x6F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x8E, 0x5E, /* 0xD8-0xDB */
-	0x8E, 0x92, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x94, 0x85, 0x3F, 0x3F, 0x8C, 0x00, 0x00, 0x00, /* 0xE0-0xE3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x95, 0x8A, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xCD, 0x8E, 0x5E, /* 0xD8-0xDB */
+	0x8E, 0x92, 0x3F, 0x3F, 0x8F, 0xDC, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x94, 0x85, 0x3F, 0x3F, 0x8C, 0xAB, 0xE6, 0xCC, /* 0xE0-0xE3 */
+	0xE6, 0xCB, 0x3F, 0x3F, 0x95, 0x8A, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xBF, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x93, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
-	0x8D, 0x77, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xEE, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0xEE, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xCF, 0xE6, 0xD0, /* 0xF8-0xFB */
+	0x8D, 0x77, 0xE6, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_8D[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x04-0x07 */
-	0x91, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x8A, 0x00, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x0C-0x0F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x13 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
+	0xE6, 0xD1, 0xE6, 0xD2, 0x3F, 0x3F, 0xE6, 0xD4, /* 0x04-0x07 */
+	0x91, 0xA1, 0x3F, 0x3F, 0xE6, 0xD3, 0x8A, 0xE4, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE6, 0xD6, 0x3F, 0x3F, 0xE6, 0xD5, /* 0x0C-0x0F */
+	0xE6, 0xD7, 0x3F, 0x3F, 0xEE, 0x93, 0xE6, 0xD9, /* 0x10-0x13 */
+	0xE6, 0xDB, 0x3F, 0x3F, 0xE6, 0xDC, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
@@ -8232,143 +8234,143 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x90, 0x00, 0x3F, 0x3F, 0x8E, 0x00, 0x00, 0x00, /* 0x64-0x67 */
+	0x90, 0xD4, 0x3F, 0x3F, 0x8E, 0xCD, 0xE6, 0xDD, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x71, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x91, 0x96, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x70-0x73 */
-	0x95, 0x8B, 0x3F, 0x3F, 0x00, 0x00, 0x8B, 0x4E, /* 0x74-0x77 */
+	0x3F, 0x3F, 0xE6, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x91, 0x96, 0xE6, 0xDF, 0x3F, 0x3F, 0xE6, 0xE0, /* 0x70-0x73 */
+	0x95, 0x8B, 0x3F, 0x3F, 0xEE, 0x94, 0x8B, 0x4E, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xE6, 0xE1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x92, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x7A, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE6, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xEF, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x90, 0x96, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xAB, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xE5, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xE4, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xE3, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xC8-0xCB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xEB, /* 0xC8-0xCB */
+	0xE6, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xE6, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x8B, 0x97, 0x3F, 0x3F, 0x00, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xE8, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xE7, 0xE6, 0xEA, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x8B, 0x97, 0x3F, 0x3F, 0xE6, 0xEE, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x90, 0xD5, 0x3F, 0x3F, 0xE6, 0xEF, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x8C, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xE8-0xEB */
+	0x8C, 0xD7, 0x3F, 0x3F, 0xE6, 0xEC, 0xE6, 0xED, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x48, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xB5, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x91, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xFC-0xFF */
+	0xE6, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xF3, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_8E[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x00, 0x00, 0x00, 0x00, 0x97, 0x78, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0x0C-0x0F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0xE6, 0xF1, 0xE6, 0xF2, 0x97, 0x78, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xA5, /* 0x0C-0x0F */
+	0xE6, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xE6, 0xF4, 0xE6, 0xF5, 0xE6, 0xF7, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x48, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x48, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0xE6, 0xFA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xE6, 0xFB, 0xE6, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x40, /* 0x44-0x47 */
-	0x00, 0x44, 0x00, 0x41, 0x00, 0x00, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x00, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x00, /* 0x5C-0x5F */
-	0x00, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x49, /* 0x60-0x63 */
-	0x00, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xF8, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x92, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x40, /* 0x44-0x47 */
+	0xE7, 0x44, 0xE7, 0x41, 0xE6, 0xFC, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xE7, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xE7, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xE7, 0x4A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE7, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0xD6, /* 0x5C-0x5F */
+	0xE7, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x49, /* 0x60-0x63 */
+	0xE7, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4C, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x8F, 0x52, 0x3F, 0x3F, 0x00, 0x4B, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x4C, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x8F, 0x52, 0x3F, 0x3F, 0xE7, 0x4B, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0xE7, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x00, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x00, 0x51, 0x00, 0x50, 0x3F, 0x3F, 0x00, 0x4F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x53, 0x00, 0x52, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x00, 0x55, 0x3F, 0x3F, 0x00, 0x54, /* 0x90-0x93 */
-	0x00, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x00, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0xE7, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0xE7, 0x51, 0xE7, 0x50, 0x3F, 0x3F, 0xE7, 0x4F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x53, 0xE7, 0x52, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x96, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xE7, 0x55, 0x3F, 0x3F, 0xE7, 0x54, /* 0x90-0x93 */
+	0xE7, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xE7, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x00, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0xE7, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x58, 0x90, 0x67, /* 0xA8-0xAB */
-	0x00, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0xAC-0xAF */
-	0x00, 0x5B, 0x00, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x58, 0x90, 0x67, /* 0xA8-0xAB */
+	0xE7, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xEB, /* 0xAC-0xAF */
+	0xE7, 0x5B, 0xE7, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5E, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x5E, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x00, 0x5F, 0x00, 0x5C, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x00, 0x60, 0x3F, 0x3F, 0x8E, 0x00, 0x00, 0x61, /* 0xC8-0xCB */
-	0x8B, 0x4F, 0x8C, 0x52, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xE7, 0x5F, 0xE7, 0x5C, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0xE7, 0x60, 0x3F, 0x3F, 0x8E, 0xD4, 0xE7, 0x61, /* 0xC8-0xCB */
+	0x8B, 0x4F, 0x8C, 0x52, 0x3F, 0x3F, 0xEE, 0x96, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xAC, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x62, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x5D, 0x00, 0x63, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x62, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xEE, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x5D, 0xE7, 0x63, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x66, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x66, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x65, /* 0xF8-0xFB */
-	0x00, 0x64, 0x8C, 0x79, 0x00, 0x67, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x8E, 0xB2, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x65, /* 0xF8-0xFB */
+	0xE7, 0x64, 0x8C, 0x79, 0xE7, 0x67, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_8F[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x72, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x8D, 0x00, 0x00, 0x68, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6B, 0x00, 0x6D, /* 0x10-0x13 */
-	0x95, 0x00, 0x00, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, 0x00, 0x70, /* 0x18-0x1B */
-	0x00, 0x6E, 0x8B, 0x50, 0x3F, 0x3F, 0x00, 0x6F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xE7, 0x69, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x8D, 0xDA, 0xE7, 0x68, 0x3F, 0x3F, /* 0x08-0x0B */
+	0xE7, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x6B, 0xE7, 0x6D, /* 0x10-0x13 */
+	0x95, 0xE3, 0xE7, 0x6A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xE7, 0x6C, 0x3F, 0x3F, 0xE7, 0x70, /* 0x18-0x1B */
+	0xE7, 0x6E, 0x8B, 0x50, 0x3F, 0x3F, 0xE7, 0x6F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x72, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x94, 0x79, 0x97, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x72, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x94, 0x79, 0x97, 0xD6, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x53, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x73, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x73, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x97, 0x41, 0x00, 0x75, 0x3F, 0x3F, 0x00, 0x74, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x78, 0x97, 0x60, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x77, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x8A, 0x8D, 0x00, 0x76, 0x00, 0x7B, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x00, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x00, 0x79, 0x93, 0x51, 0x00, 0x7C, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x97, 0x41, 0xE7, 0x75, 0x3F, 0x3F, 0xE7, 0x74, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x78, 0x97, 0x60, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x77, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x8A, 0x8D, 0xE7, 0x76, 0xE7, 0x7B, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE7, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xE7, 0x79, 0x93, 0x51, 0xE7, 0x7C, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7D, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x7D, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x00, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x8C, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x8C, 0x44, 0x00, 0x80, 0x00, 0x81, /* 0x60-0x63 */
-	0x00, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xE7, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x8C, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x8C, 0x44, 0xE7, 0x80, 0xE7, 0x81, /* 0x60-0x63 */
+	0xE7, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
@@ -8383,340 +8385,340 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x68, /* 0x98-0x9B */
-	0x00, 0x83, 0x3F, 0x3F, 0x8E, 0x00, 0x00, 0x84, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x85, /* 0xA0-0xA3 */
+	0xE7, 0x83, 0x3F, 0x3F, 0x8E, 0xAB, 0xE7, 0x84, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x85, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x99, 0x9F, /* 0xA4-0xA7 */
 	0x99, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x00, 0x86, 0x00, 0x90, 0x00, 0x87, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xE7, 0x86, 0xE3, 0x90, 0xE7, 0x87, /* 0xAC-0xAF */
 	0x92, 0x43, 0x90, 0x4A, 0x94, 0x5F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x88, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, 0x92, 0x00, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x88, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xD3, 0x92, 0xD2, /* 0xB8-0xBB */
 	0x8D, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x48, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x49, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x96, 0x98, 0x90, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x7D, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x89, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x8B, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x95, 0xD4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x89, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8B, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x00, 0x8A, 0x89, 0x00, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x93, 0x00, 0x00, 0x8C, 0x94, 0x97, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x93, 0x52, 0x3F, 0x3F, 0x00, 0x8D, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x8B, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0xE7, 0x8A, 0x89, 0xDE, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x93, 0xF4, 0xE7, 0x8C, 0x94, 0x97, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x93, 0x52, 0x3F, 0x3F, 0xE7, 0x8D, /* 0xEC-0xEF */
 	0x8F, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0xF4-0xF7 */
-	0x00, 0x9E, 0x00, 0x91, 0x00, 0x92, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xE7, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xC0, /* 0xF4-0xF7 */
+	0xE7, 0x9E, 0xE7, 0x91, 0xE7, 0x92, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x92, 0xC7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_90[512] = {
-	0x91, 0x00, 0x91, 0x97, 0x3F, 0x3F, 0x93, 0x00, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x90, 0x8B, 0x74, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x99, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x96, 0x00, 0x00, 0x93, 0x00, /* 0x0C-0x0F */
-	0x92, 0x80, 0x00, 0x93, 0x3F, 0x3F, 0x92, 0x00, /* 0x10-0x13 */
-	0x93, 0x72, 0x00, 0x94, 0x00, 0x98, 0x90, 0x80, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x94, 0x87, 0x92, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x90, 0x00, 0x00, 0x97, 0x91, 0x00, /* 0x1C-0x1F */
-	0x91, 0x00, 0x00, 0x95, 0x88, 0x00, 0x98, 0x41, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9A, /* 0x24-0x27 */
+	0x91, 0xDE, 0x91, 0x97, 0x3F, 0x3F, 0x93, 0xA6, /* 0x00-0x03 */
+	0x3F, 0x3F, 0xE7, 0x90, 0x8B, 0x74, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x99, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE7, 0x96, 0xE7, 0xA3, 0x93, 0xA7, /* 0x0C-0x0F */
+	0x92, 0x80, 0xE7, 0x93, 0x3F, 0x3F, 0x92, 0xFC, /* 0x10-0x13 */
+	0x93, 0x72, 0xE7, 0x94, 0xE7, 0x98, 0x90, 0x80, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x94, 0x87, 0x92, 0xCA, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x90, 0xC0, 0xE7, 0x97, 0x91, 0xAC, /* 0x1C-0x1F */
+	0x91, 0xA2, 0xE7, 0x95, 0x88, 0xA7, 0x98, 0x41, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x9A, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xDF, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x8F, 0x54, 0x90, 0x69, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x9C, 0x00, 0x9B, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x88, 0x00, 0x00, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x95, 0x4E, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x93, 0x00, 0x90, 0x8B, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x92, 0x78, 0x3F, 0x3F, 0x8B, 0x00, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x00, 0x00, 0x97, 0x56, 0x89, 0x5E, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x95, 0x00, 0x89, 0x00, 0x00, 0x9F, /* 0x4C-0x4F */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0x00, /* 0x50-0x53 */
-	0x92, 0x42, 0x88, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x91, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x89, 0x93, 0x91, 0x6B, 0x3F, 0x3F, 0x8C, 0x00, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x97, 0x79, 0x3F, 0x3F, 0x00, 0x00, /* 0x64-0x67 */
-	0x00, 0x00, 0x93, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x91, 0x98, 0x8E, 0x00, 0x00, 0x00, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x8F, 0x85, 0x00, 0x00, 0x91, 0x4A, /* 0x74-0x77 */
-	0x91, 0x49, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x97, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x94, 0x00, /* 0x7C-0x7F */
-	
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, /* 0x80-0x83 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8E, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xE7, 0x9C, 0xE7, 0x9B, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x88, 0xED, 0xE7, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x95, 0x4E, 0x3F, 0x3F, 0xE7, 0xA5, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x93, 0xD9, 0x90, 0x8B, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x92, 0x78, 0x3F, 0x3F, 0x8B, 0xF6, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE7, 0xA4, 0x97, 0x56, 0x89, 0x5E, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x95, 0xD5, 0x89, 0xDF, 0xE7, 0x9F, /* 0x4C-0x4F */
+	0xE7, 0xA0, 0xE7, 0xA1, 0xE7, 0xA2, 0x93, 0xB9, /* 0x50-0x53 */
+	0x92, 0x42, 0x88, 0xE1, 0xE7, 0xA6, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE7, 0xA7, 0xEA, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x91, 0xBB, 0x3F, 0x3F, 0xE7, 0xA8, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x89, 0x93, 0x91, 0x6B, 0x3F, 0x3F, 0x8C, 0xAD, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x97, 0x79, 0x3F, 0x3F, 0xEE, 0x99, /* 0x64-0x67 */
+	0xE7, 0xA9, 0x93, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x91, 0x98, 0x8E, 0xD5, 0xE7, 0xAA, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xAD, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x8F, 0x85, 0xE7, 0xAB, 0x91, 0x4A, /* 0x74-0x77 */
+	0x91, 0x49, 0x3F, 0x3F, 0x88, 0xE2, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x97, 0xC9, 0xE7, 0xAF, 0x3F, 0x3F, 0x94, 0xF0, /* 0x7C-0x7F */
+	
+	0xE7, 0xB1, 0xE7, 0xB0, 0xE7, 0xAE, 0xE2, 0x84, /* 0x80-0x83 */
+	0x8A, 0xD2, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0x8E, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xE7, 0xB3, 0xE7, 0xB2, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xB4, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x97, 0x57, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xDF, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x4D, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xE7, 0xB5, 0x3F, 0x3F, 0x8E, 0xD7, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xB6, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xE7, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0xE7, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x93, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x88, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x78, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x59, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x8C, 0x53, 0x00, 0x00, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xBC, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x9A, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x8C, 0x53, 0xE7, 0xB9, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE7, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x95, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x8A, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x97, 0x58, 0x3F, 0x3F, 0x8B, 0x00, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x97, 0x58, 0x3F, 0x3F, 0x8B, 0xBD, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x93, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_91[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xBD, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xBE, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xEE, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xE7, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0x9D, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x93, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xE7, 0xC1, 0x3F, 0x3F, 0xE7, 0xC0, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x93, 0x00, 0x00, 0x00, 0x8F, 0x55, /* 0x48-0x4B */
-	0x8E, 0x00, 0x94, 0x7A, 0x92, 0x91, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x90, 0x8C, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x93, 0xD1, 0xE7, 0xC2, 0x8F, 0x55, /* 0x48-0x4B */
+	0x8E, 0xDE, 0x94, 0x7A, 0x92, 0x91, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xF0, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x90, 0x8C, 0x3F, 0x3F, 0xE7, 0xC3, 0x3F, 0x3F, /* 0x54-0x57 */
+	0xE7, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x7C, 0x00, 0x00, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x00, 0x97, 0x8F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x7C, 0xE7, 0xC5, /* 0x60-0x63 */
+	0x3F, 0x3F, 0xE7, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE7, 0xC7, 0x97, 0x8F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x8F, 0x56, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xC9, 0xE7, 0xC8, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x8D, 0x79, 0x3F, 0x3F, 0x8D, 0x93, /* 0x74-0x77 */
 	0x8E, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xCC, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x86, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x8C, 0x00, 0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xE7, 0xCB, 0x3F, 0x3F, 0xE7, 0xCA, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x91, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x8C, 0xED, 0x3F, 0x3F, 0x90, 0xC1, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xAE, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x8F, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xCD, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x8F, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xD0, 0xE7, 0xCE, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xCF, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0xE7, 0xD2, 0xE7, 0xD1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x8F, 0xF8, 0x3F, 0x3F, 0xE7, 0xD3, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x8D, 0x00, /* 0xC4-0xC7 */
-	0x8E, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xC8-0xCB */
-	0x97, 0x00, 0x8F, 0x64, 0x96, 0x00, 0x97, 0x00, /* 0xCC-0xCF */
-	0x00, 0x00, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xD4-0xD7 */
-	0x93, 0x42, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0xD8-0xDB */
-	0x8A, 0x98, 0x90, 0x6A, 0x00, 0x00, 0x00, 0x00, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x92, 0x00, /* 0xE0-0xE3 */
-	0x00, 0x00, 0x00, 0x00, 0x96, 0x74, 0x8B, 0x00, /* 0xE4-0xE7 */
+	0xE7, 0xD4, 0xE7, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xCE, 0x8D, 0xD1, /* 0xC4-0xC7 */
+	0x8E, 0xDF, 0xE7, 0xD6, 0x3F, 0x3F, 0xE7, 0xD7, /* 0xC8-0xCB */
+	0x97, 0xA2, 0x8F, 0x64, 0x96, 0xEC, 0x97, 0xCA, /* 0xCC-0xCF */
+	0xE7, 0xD8, 0x8B, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xD9, 0xEE, 0x9F, /* 0xD4-0xD7 */
+	0x93, 0x42, 0x3F, 0x3F, 0xEE, 0x9E, 0xE7, 0xDC, /* 0xD8-0xDB */
+	0x8A, 0x98, 0x90, 0x6A, 0xEE, 0xA0, 0xE7, 0xDA, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0xE7, 0xDB, 0x3F, 0x3F, 0x92, 0xDE, /* 0xE0-0xE3 */
+	0xEE, 0xA3, 0xEE, 0xA4, 0x96, 0x74, 0x8B, 0xFA, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xEE, 0xA1, 0xEE, 0xA2, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xE7, 0xDE, 0xE7, 0xDF, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xFC-0xFF */
+	0xE7, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xE1, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_92[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x93, 0x00, 0x8A, 0x62, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xA5, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xA7, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x93, 0xDD, 0x8A, 0x62, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xEE, 0xA6, 0xE7, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0xE7, 0xE2, 0xE7, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xE0, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0xE8, 0x6E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0xE7, 0xE3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x3C-0x3F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x93, 0x53, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x89, 0x94, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x00, 0x3F, 0x3F, 0x8F, 0x00, 0x00, 0x00, /* 0x64-0x67 */
+	0x97, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xD8, /* 0x34-0x37 */
+	0x3F, 0x3F, 0xEE, 0xAE, 0xEE, 0xA8, 0x3F, 0x3F, /* 0x38-0x3B */
+	0xEE, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xED, /* 0x3C-0x3F */
+	0xEE, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x93, 0x53, 0xE7, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xE7, 0xEB, 0xE7, 0xE9, 0x3F, 0x3F, 0xE7, 0xEE, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xAB, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xE7, 0xEF, 0xEE, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xE7, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xEE, 0xAC, 0xE7, 0xF4, 0x89, 0x94, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xE6, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xAB, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE7, 0xEA, 0x3F, 0x3F, 0x8F, 0xDE, 0xEE, 0xAF, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x8D, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x74-0x77 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xB1, /* 0x74-0x77 */
+	0xEE, 0xB2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x67, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x65, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x5F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x8B, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x65, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x93, 0xBA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0xED, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x91, 0x4C, 0x3F, 0x3F, 0x00, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x96, 0x00, 0x3F, 0x3F, 0x92, 0x00, 0x00, 0x00, /* 0x98-0x9B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x91, 0x4C, 0x3F, 0x3F, 0xE7, 0xF2, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xE7, 0xEC, 0xE7, 0xF1, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x96, 0xC1, 0x3F, 0x3F, 0x92, 0xB6, 0xE7, 0xF3, /* 0x98-0x9B */
+	0xE7, 0xF0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xB0, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x91, 0x4B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xF7, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE7, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
-	0x00, 0x00, 0x3F, 0x3F, 0x96, 0x4E, 0x00, 0x00, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xF5, /* 0xCC-0xCF */
+	0xEE, 0xB6, 0x3F, 0x3F, 0x96, 0x4E, 0xEE, 0xBA, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0xEE, 0xB8, 0x3F, 0x3F, 0xEE, 0xB4, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xEE, 0xB5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x8F, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x95, 0x00, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0xEE, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x8F, 0x9B, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xB3, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE7, 0xF8, 0x95, 0xDD, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x89, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x65, 0x92, 0x92, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x8B, 0x98, 0x00, 0x65, 0x00, 0x00, 0x00, 0x00, /* 0xF8-0xFB */
-	0x8D, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xFC-0xFF */
+	0x8B, 0x98, 0xED, 0x49, 0xE7, 0xFA, 0xEE, 0xBD, /* 0xF8-0xFB */
+	0x8D, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xC0, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_93[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xC2, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x4B, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE7, 0xF9, /* 0x0C-0x0F */
 	0x90, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x90, 0x8E, 0x00, 0x40, 0x00, 0x42, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x8F, 0x00, 0x00, 0x00, 0x00, 0x41, 0x00, 0x43, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x00, 0x00, 0x8B, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x95, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, /* 0x28-0x2B */
-	0x98, 0x42, 0x3F, 0x3F, 0x00, 0x00, 0x8D, 0x00, /* 0x2C-0x2F */
+	0x90, 0x8E, 0xE8, 0x40, 0xE8, 0x42, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xEE, 0xC1, 0xEE, 0xBF, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x8F, 0xF9, 0xEE, 0xBC, 0xE8, 0x41, 0xE8, 0x43, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xEE, 0xBB, 0x8B, 0xD1, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x95, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xE0, /* 0x28-0x2B */
+	0x98, 0x42, 0x3F, 0x3F, 0xE7, 0xFC, 0x8D, 0xF6, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x5E, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x44, 0x00, 0x46, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xE8, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x44, 0xE8, 0x46, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x00, /* 0x48-0x4B */
+	0xE7, 0xFB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xED, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0xE7, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x93, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x92, 0x00, 0x3F, 0x3F, 0x00, 0x4B, 0x00, 0x00, /* 0x54-0x57 */
+	0x92, 0xD5, 0x3F, 0x3F, 0xE8, 0x4B, 0xEE, 0xC4, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x62, /* 0x58-0x5B */
-	0x00, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x00, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE8, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0xE8, 0x48, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x8C, 0x4C, 0x3F, 0x3F, 0x00, 0x4A, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x8C, 0x4C, 0x3F, 0x3F, 0xE8, 0x4A, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0xEE, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x8C, 0xAE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x49, 0x3F, 0x3F, 0x8F, 0x00, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0xE8, 0x49, 0x3F, 0x3F, 0x8F, 0xDF, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x8A, 0x99, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x00, 0x4F, 0x3F, 0x3F, 0x8D, 0x00, 0x91, 0x99, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xE8, 0x4F, 0x3F, 0x3F, 0x8D, 0xBD, 0x91, 0x99, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xC8, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x5A, /* 0xA4-0xA7 */
+	0xEE, 0xC5, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x5A, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x00, 0x4D, 0x00, 0x4E, 0x92, 0x00, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x00, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xE8, 0x4D, 0xE8, 0x4E, 0x92, 0xC1, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE8, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0xE8, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x56, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x00, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x56, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xC6, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0xE8, 0x59, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x00, 0x58, 0x93, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x51, 0x00, 0x52, /* 0xD4-0xD7 */
-	0x00, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x00, 0x57, 0x00, 0x00, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x00, 0x5A, 0x00, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x00, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0xE8, 0x58, 0x93, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x51, 0xE8, 0x52, /* 0xD4-0xD7 */
+	0xE8, 0x55, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xE8, 0x57, 0xEE, 0xC7, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x8B, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0xE8, 0x5A, 0xE8, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0xE8, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0xEE, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_94[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5E, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x5E, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x5F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x00, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5D, /* 0x10-0x13 */
-	0x00, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x8F, 0x00, 0x93, 0x00, 0x00, 0x5B, 0x3F, 0x3F, /* 0x18-0x1B */
+	0xE8, 0x60, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x5D, /* 0x10-0x13 */
+	0xE8, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x8F, 0xE0, 0x93, 0xA8, 0xE8, 0x5B, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xE8, 0x64, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x62, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x62, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x00, 0x63, 0x00, 0x61, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x91, 0x00, 0x3F, 0x3F, 0x00, 0x65, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xEE, 0xC9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0xE8, 0x63, 0xE8, 0x61, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x91, 0xF6, 0x3F, 0x3F, 0xE8, 0x65, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x00, 0x68, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0xE8, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xE8, 0x68, 0xEE, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xEE, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x8A, 0x00, 0x00, 0x67, 0x96, 0x00, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x8A, 0xD3, 0xE8, 0x67, 0x96, 0xF8, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x73, 0x00, 0x69, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x00, 0x6A, 0x3F, 0x3F, 0x00, 0x6B, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x73, 0xE8, 0x69, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x6C, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0xE8, 0x6A, 0x3F, 0x3F, 0xE8, 0x6B, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6D, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x6D, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x00, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x00, 0x70, 0x3F, 0x3F, 0x00, 0x71, /* 0x74-0x77 */
+	0xE8, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE8, 0x70, 0x3F, 0x3F, 0xE8, 0x71, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x74, 0x00, 0x72, 0x00, 0x75, 0x00, 0x77, /* 0x7C-0x7F */
+	0xE8, 0x74, 0xE8, 0x72, 0xE8, 0x75, 0xE8, 0x77, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x00, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0xE8, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
@@ -8780,36 +8782,36 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x00, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0xB7, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x96, 0x00, 0x3F, 0x3F, 0x00, 0x78, 0x91, 0x4D, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x79, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x95, 0x00, 0x00, 0x7A, 0x8A, 0x4A, /* 0x88-0x8B */
+	0x96, 0xE5, 0x3F, 0x3F, 0xE8, 0x78, 0x91, 0x4D, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x79, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x95, 0xC2, 0xE8, 0x7A, 0x8A, 0x4A, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x5B, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x8A, 0x00, 0x00, 0x00, 0x8A, 0x00, /* 0x90-0x93 */
-	0x00, 0x7B, 0x3F, 0x3F, 0x00, 0x7C, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x00, 0x7D, 0x00, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x8A, 0xD5, 0xEE, 0xCC, 0x8A, 0xD4, /* 0x90-0x93 */
+	0xE8, 0x7B, 0x3F, 0x3F, 0xE8, 0x7C, 0x3F, 0x3F, /* 0x94-0x97 */
+	0xE8, 0x7D, 0xE8, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x00, 0x80, 0x3F, 0x3F, 0x8A, 0x00, 0x8A, 0x74, /* 0xA0-0xA3 */
-	0x8D, 0x7D, 0x94, 0x00, 0x3F, 0x3F, 0x00, 0x82, /* 0xA4-0xA7 */
-	0x00, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x00, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE8, 0x80, 0x3F, 0x3F, 0x8A, 0xD6, 0x8A, 0x74, /* 0xA0-0xA3 */
+	0x8D, 0x7D, 0x94, 0xB4, 0x3F, 0x3F, 0xE8, 0x82, /* 0xA4-0xA7 */
+	0xE8, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0xE8, 0x83, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x7B, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x86, 0x3F, 0x3F, 0x00, 0x85, /* 0xB8-0xBB */
-	0x00, 0x84, 0x3F, 0x3F, 0x00, 0x87, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8A, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x88, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x00, 0x8C, 0x00, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0xE8, 0x86, 0x3F, 0x3F, 0xE8, 0x85, /* 0xB8-0xBB */
+	0xE8, 0x84, 0x3F, 0x3F, 0xE8, 0x87, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x8A, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xC5, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x88, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0xE8, 0x8C, 0xE8, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x8E, 0x00, 0x8D, 0x00, 0x8F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x91, 0x00, 0x93, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x00, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0xE8, 0x8E, 0xE8, 0x8D, 0xE8, 0x8F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x93, 0xAC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xE8, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0xE8, 0x91, 0xE8, 0x93, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0xE8, 0x92, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
@@ -8827,164 +8829,164 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x95, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xE8, 0x94, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x00, 0x95, 0x3F, 0x3F, 0x8D, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x96, 0x00, 0x97, /* 0x2C-0x2F */
+	0xE8, 0x95, 0x3F, 0x3F, 0x8D, 0xE3, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x96, 0xE8, 0x97, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x68, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x6A, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, /* 0x3C-0x3F */
-	0x91, 0x00, 0x3F, 0x3F, 0x00, 0x98, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xA2, /* 0x3C-0x3F */
+	0x91, 0xC9, 0x3F, 0x3F, 0xE8, 0x98, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x95, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9B, /* 0x48-0x4B */
-	0x00, 0x99, 0x8D, 0x7E, 0x3F, 0x3F, 0x00, 0x9A, /* 0x4C-0x4F */
-	0x8C, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0x9B, /* 0x48-0x4B */
+	0xE8, 0x99, 0x8D, 0x7E, 0x3F, 0x3F, 0xE8, 0x9A, /* 0x4C-0x4F */
+	0x8C, 0xC0, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x00, /* 0x58-0x5B */
-	0x00, 0x9D, 0x00, 0x9F, 0x00, 0x9E, 0x00, 0x00, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0xC3, /* 0x58-0x5B */
+	0xE8, 0x9D, 0xE8, 0x9F, 0xE8, 0x9E, 0xE8, 0xA0, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x40, 0x90, 0x77, /* 0x60-0x63 */
-	0x8F, 0x9C, 0x8A, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x8F, 0x9C, 0x8A, 0xD7, 0xE8, 0xA1, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x86, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x89, 0x41, 0x3F, 0x3F, 0x00, 0x00, 0x92, 0x00, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x97, 0x00, 0x93, 0x00, 0x00, 0x9C, /* 0x74-0x77 */
-	0x97, 0x00, 0x3F, 0x3F, 0x8C, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE8, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x89, 0x41, 0x3F, 0x3F, 0xE8, 0xA2, 0x92, 0xC2, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x97, 0xCB, 0x93, 0xA9, 0xE8, 0x9C, /* 0x74-0x77 */
+	0x97, 0xA4, 0x3F, 0x3F, 0x8C, 0xAF, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x97, 0x7A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x8B, 0x00, 0x97, 0x00, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x8C, 0x47, 0x3F, 0x3F, 0x91, 0x00, 0x00, 0x40, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x00, 0x00, 0x8A, 0x4B, 0x90, 0x8F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x8B, 0xF7, 0x97, 0xB2, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x8C, 0x47, 0x3F, 0x3F, 0x91, 0xE0, 0xE4, 0x40, /* 0x88-0x8B */
+	0x3F, 0x3F, 0xE8, 0xA4, 0x8A, 0x4B, 0x90, 0x8F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x8A, 0x75, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x94-0x97 */
-	0x00, 0x00, 0x8C, 0x84, 0x3F, 0x3F, 0x8D, 0x00, /* 0x98-0x9B */
-	0x8F, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x89, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA4-0xA7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xAC-0xAF */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x97, 0x00, /* 0xB4-0xB7 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x90, 0x00, /* 0xB8-0xBB */
-	0x94, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x90, 0x9D, 0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x97, 0x59, 0x89, 0x00, 0x8F, 0x57, 0x8C, 0x00, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xC8-0xCB */
-	0x8E, 0x93, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x8A, 0x75, 0xE8, 0xA6, 0x3F, 0x3F, 0xE8, 0xA7, /* 0x94-0x97 */
+	0xE8, 0xA5, 0x8C, 0x84, 0x3F, 0x3F, 0x8D, 0xDB, /* 0x98-0x9B */
+	0x8F, 0xE1, 0xEE, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x89, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xD7, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xA9, /* 0xA4-0xA7 */
+	0xE7, 0xAC, 0x3F, 0x3F, 0xE8, 0xA8, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xD0, /* 0xAC-0xAF */
+	0xE8, 0xAC, 0xE8, 0xAA, 0xE8, 0xAB, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xE8, 0xAD, 0x3F, 0x3F, 0xE8, 0xAE, 0x97, 0xEA, /* 0xB4-0xB7 */
+	0xE8, 0xAF, 0xE8, 0xB0, 0x3F, 0x3F, 0x90, 0xC7, /* 0xB8-0xBB */
+	0x94, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x90, 0x9D, 0x8A, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x97, 0x59, 0x89, 0xEB, 0x8F, 0x57, 0x8C, 0xD9, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0xE8, 0xB3, 0x3F, 0x3F, 0xE8, 0xB2, /* 0xC8-0xCB */
+	0x8E, 0x93, 0xE8, 0xB4, 0xE8, 0xB1, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x8E, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x99, 0x00, 0x3F, 0x3F, 0x90, 0x97, /* 0xD8-0xDB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x93, 0x00, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0xE8, 0xB8, 0xE5, 0xAB, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x99, 0xD4, 0x3F, 0x3F, 0x90, 0x97, /* 0xD8-0xDB */
+	0xE8, 0xB6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xA3, 0x93, 0xEF, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x89, 0x4A, 0x3F, 0x3F, 0x90, 0x00, 0x8E, 0x00, /* 0xE8-0xEB */
+	0x89, 0x4A, 0x3F, 0x3F, 0x90, 0xE1, 0x8E, 0xB4, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x95, 0x00, 0x3F, 0x3F, 0x89, 0x5F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x97, 0x8B, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x93, 0x64, /* 0xF8-0xFB */
+	0x95, 0xB5, 0x3F, 0x3F, 0x89, 0x5F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xEB, 0x97, 0x8B, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xE8, 0xB9, 0x3F, 0x3F, 0x93, 0x64, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_97[512] = {
-	0x8E, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x90, 0x6B, /* 0x04-0x07 */
-	0x00, 0x00, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x91, 0x9A, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x8E, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0xE8, 0xBA, 0x3F, 0x3F, 0xE8, 0xBB, 0x90, 0x6B, /* 0x04-0x07 */
+	0xE8, 0xBC, 0x3F, 0x3F, 0x97, 0xEC, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xE8, 0xB7, 0xE8, 0xBE, 0xE8, 0xC0, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0xE8, 0xBF, 0x3F, 0x3F, 0xE8, 0xBD, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xC1, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xE8, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x91, 0x9A, 0x3F, 0x3F, 0x89, 0xE0, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x00, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
+	0xE8, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0xB6, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xC4, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x98, 0x49, 0x00, 0x00, /* 0x30-0x33 */
+	0xE8, 0xC5, 0x3F, 0x3F, 0x98, 0x49, 0xEE, 0xD1, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x9E, 0x50, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x40-0x43 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x00, 0x00, 0x90, 0x00, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x00, 0x96, 0x00, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x90, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x00, 0x00, 0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x00, 0x00, 0x00, 0x72, 0x96, 0x00, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x00, 0x00, 0x8A, 0x76, 0x3F, 0x3F, 0x00, 0x00, /* 0x68-0x6B */
+	0x9E, 0x50, 0xE8, 0xC6, 0x3F, 0x3F, 0xEE, 0xD2, /* 0x38-0x3B */
+	0x3F, 0x3F, 0xE8, 0xC7, 0xE8, 0xC8, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xCC, 0xEE, 0xD3, /* 0x40-0x43 */
+	0xE8, 0xC9, 0x3F, 0x3F, 0xE8, 0xCA, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xE8, 0xCB, 0xE8, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0xEE, 0xD4, 0x3F, 0x3F, 0xEE, 0xD5, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0xEE, 0xD6, 0x90, 0xC2, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xEE, 0xD7, 0x96, 0xF5, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x90, 0xC3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0xE8, 0xCE, 0x3F, 0x3F, 0x94, 0xF1, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0xE8, 0xCF, 0xEA, 0x72, 0x96, 0xCA, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE8, 0xD0, 0x3F, 0x3F, 0xE8, 0xD1, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xE8, 0xD2, 0x8A, 0x76, 0x3F, 0x3F, 0xE8, 0xD4, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x90, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xE8, 0xD5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x8C, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	0x3F, 0x3F, 0xE8, 0xD6, 0xE8, 0xDA, 0x3F, 0x3F, /* 0x78-0x7B */
+	0xE8, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x8A, 0x93, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x8C-0x8F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xE8, 0xD9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x8A, 0x93, 0xE8, 0xD7, 0xE8, 0xDB, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xDC, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x88, 0xC6, 0x3F, 0x3F, 0xE8, 0xDD, /* 0x8C-0x8F */
+	0xE8, 0xDE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x8F, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x8B, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x91, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x95, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xB0-0xB3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x8F, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xE8, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x8B, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xE2, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xE1, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0xE8, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0x91, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x95, 0xDA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xE3, /* 0xB0-0xB3 */
+	0xE8, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xE5, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xE6, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0xE8, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xE8, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0x00, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8A, 0xD8, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xE8, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x00, 0x00, 0x94, 0x42, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x89, 0x00, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xE8, 0xEA, 0x94, 0x42, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xEC, 0x89, 0xB9, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0xE8, 0xEF, 0xE8, 0xEE, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x43, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, /* 0xFC-0xFF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xBF, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_98[512] = {
-	0x3F, 0x3F, 0x95, 0x00, 0x92, 0x00, 0x8D, 0x00, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x95, 0xC5, 0x92, 0xB8, 0x8D, 0xA0, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x8D, 0x80, 0x8F, 0x87, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x90, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x0C-0x0F */
-	0x97, 0x61, 0x8A, 0x00, 0x94, 0x00, 0x93, 0x00, /* 0x10-0x13 */
+	0xE8, 0xF1, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xF0, /* 0x0C-0x0F */
+	0x97, 0x61, 0x8A, 0xE6, 0x94, 0xD0, 0x93, 0xDA, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x9C, /* 0x14-0x17 */
-	0x97, 0x00, 0x3F, 0x3F, 0x8C, 0x7A, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x97, 0xCC, 0x3F, 0x3F, 0x8C, 0x7A, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE8, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE8, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x96, 0x6A, 0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x96, 0x6A, 0x93, 0xAA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x89, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x34-0x37 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x70, /* 0x38-0x3B */
-	0x97, 0x8A, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x89, 0x6F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xF5, /* 0x34-0x37 */
+	0xE8, 0xF2, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x70, /* 0x38-0x3B */
+	0x97, 0x8A, 0xE8, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x48-0x4B */
-	0x91, 0x00, 0x8A, 0x7A, 0x8A, 0x7B, 0x00, 0x00, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xF7, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xF9, /* 0x48-0x4B */
+	0x91, 0xE8, 0x8A, 0x7A, 0x8A, 0x7B, 0xE8, 0xF8, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x8A, 0x00, 0x8C, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x54-0x57 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x5E, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x8A, 0xE7, 0x8C, 0xB0, 0x3F, 0x3F, 0xEE, 0xD8, /* 0x54-0x57 */
+	0x8A, 0xE8, 0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x5E, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xDE, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x8C, 0x00, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x68-0x6B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x6C-0x6F */
-	0x00, 0x00, 0x00, 0x40, 0x3F, 0x3F, 0x00, 0x42, /* 0x70-0x73 */
-	0x00, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0xEE, 0xD9, 0x3F, 0x3F, 0x8C, 0xDA, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xFA, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE8, 0xFB, /* 0x6C-0x6F */
+	0xE8, 0xFC, 0xE9, 0x40, 0x3F, 0x3F, 0xE9, 0x42, /* 0x70-0x73 */
+	0xE9, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
@@ -8998,53 +9000,53 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x95, 0x97, 0x3F, 0x3F, 0x00, 0x43, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x44, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x00, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x46, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x95, 0x97, 0x3F, 0x3F, 0xE9, 0x43, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x44, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xE9, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x46, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x48, /* 0xC0-0xC3 */
-	0x00, 0x47, 0x3F, 0x3F, 0x00, 0x49, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x48, /* 0xC0-0xC3 */
+	0xE9, 0x47, 0x3F, 0x3F, 0xE9, 0x49, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, /* 0xD8-0xDB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x48, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xF2, /* 0xD8-0xDB */
+	0xE3, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, 0x90, 0x48, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x51, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x00, 0x4A, 0x3F, 0x3F, 0x00, 0x4B, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x99, 0x00, 0x9F, 0x5A, 0x94, 0x00, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xE9, 0x4A, 0x3F, 0x3F, 0xE9, 0x4B, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x99, 0xAA, 0x9F, 0x5A, 0x94, 0xD1, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xF9, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x88, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x8E, 0x94, 0x96, 0x4F, 0x8F, 0x00, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0x8E, 0x94, 0x96, 0x4F, 0x8F, 0xFC, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_99[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4C, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x00, 0x4D, 0x97, 0x7B, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x4C, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x96, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE9, 0x4D, 0x97, 0x7B, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x89, 0x61, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x8E, 0x60, 0x3F, 0x3F, 0x00, 0x4E, 0x89, 0x00, /* 0x10-0x13 */
-	0x00, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x00, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x00, 0x52, 0x00, 0x53, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x00, 0x55, 0x00, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x24-0x27 */
-	0x8A, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x00, 0x56, 0x3F, 0x3F, 0x00, 0x57, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x8E, 0x60, 0x3F, 0x3F, 0xE9, 0x4E, 0x89, 0xEC, /* 0x10-0x13 */
+	0xE9, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0xE9, 0x50, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE9, 0x52, 0xE9, 0x53, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0xE9, 0x55, 0xE9, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE9, 0x54, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xDC, /* 0x24-0x27 */
+	0x8A, 0xD9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0xE9, 0x56, 0x3F, 0x3F, 0xE9, 0x57, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x00, 0x58, 0x00, 0x59, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5A, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x00, 0x5B, 0x3F, 0x3F, 0x00, 0x5E, /* 0x48-0x4B */
-	0x00, 0x61, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x00, 0x5D, 0x00, 0x5F, 0x00, 0x60, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x62, 0x3F, 0x3F, 0x8B, 0x00, /* 0x54-0x57 */
+	0x3F, 0x3F, 0xE9, 0x58, 0xE9, 0x59, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x5A, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0xE9, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0xE9, 0x5B, 0x3F, 0x3F, 0xE9, 0x5E, /* 0x48-0x4B */
+	0xE9, 0x61, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xE9, 0x5D, 0xE9, 0x5F, 0xE9, 0x60, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xE9, 0x62, 0x3F, 0x3F, 0x8B, 0xC0, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
@@ -9061,63 +9063,63 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0x00, 0x00, 0x63, /* 0x94-0x97 */
-	0x00, 0x64, 0x8D, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8E, 0xF1, 0xE9, 0x63, /* 0x94-0x97 */
+	0xE9, 0x64, 0x8D, 0x81, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xDE, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x00, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0xE9, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x8A, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x94, 0x6E, 0x00, 0x66, 0x00, 0x67, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x94, 0x6E, 0xE9, 0x66, 0xE9, 0x67, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x92, 0x79, /* 0xB0-0xB3 */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x93, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x00, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0xE9, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x94, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x91, 0x00, 0x89, 0x77, 0x8B, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x8B, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x91, 0xCA, 0x89, 0x77, 0x8B, 0xEC, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x8B, 0xED, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x92, 0x93, 0x00, 0x6D, 0x8B, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x6A, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x00, 0x6B, 0x3F, 0x3F, 0x00, 0x69, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x77, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x92, 0x93, 0xE9, 0x6D, 0x8B, 0xEE, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x89, 0xED, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE9, 0x6C, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x6A, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xE9, 0x6B, 0x3F, 0x3F, 0xE9, 0x69, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x77, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x00, 0x6E, 0x00, 0x6F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x70, 0x00, 0x71, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0xE9, 0x6E, 0xE9, 0x6F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xE9, 0x70, 0xE9, 0x71, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x00, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x72, /* 0xF8-0xFB */
+	0xE9, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x72, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8F, 0x78, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_9A[512] = {
-	0x3F, 0x3F, 0x00, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x00, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xE9, 0x74, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0xE9, 0x76, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x52, 0x00, 0x75, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x9B, 0x8C, 0x00, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x52, 0xE9, 0x75, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x9B, 0x8C, 0xB1, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xE9, 0x78, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x91, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x79, /* 0x28-0x2B */
+	0x91, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x79, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x93, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7A, /* 0x34-0x37 */
+	0x93, 0xAB, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x7A, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x80, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x00, 0x7D, 0x3F, 0x3F, 0x00, 0x7C, 0x00, 0x7E, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x00, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x80, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0xE9, 0x7D, 0x3F, 0x3F, 0xE9, 0x7C, 0xE9, 0x7E, /* 0x40-0x43 */
+	0x3F, 0x3F, 0xE9, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x00, 0x82, 0x00, 0x00, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0xE9, 0x82, 0xEE, 0xDF, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x00, 0x81, 0x3F, 0x3F, 0x00, 0x84, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0x00, 0x00, 0x83, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x85, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x86, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x88, 0x00, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x00, 0x89, 0x00, 0x8B, 0x00, 0x8A, /* 0x68-0x6B */
+	0x3F, 0x3F, 0xE9, 0x81, 0x3F, 0x3F, 0xE9, 0x84, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x8B, 0xC1, 0xE9, 0x83, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x85, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x86, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xE9, 0x88, 0xE9, 0x87, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0xE9, 0x89, 0xE9, 0x8B, 0xE9, 0x8A, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
@@ -9135,129 +9137,129 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x8D, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x00, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x00, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0xE9, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0xE9, 0x8D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x8A, 0x5B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x00, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0xE9, 0x8E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0xE9, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x90, 0x91, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x90, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x00, 0x91, 0x3F, 0x3F, 0x00, 0x92, /* 0xD0-0xD3 */
-	0x00, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x8D, 0x82, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x40, 0x3F, 0x3F, 0x00, 0x94, 0x00, 0x95, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x96, 0x00, 0x97, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x98, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0x00, 0x00, 0x9A, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x95, 0x45, 0x00, 0x9B, 0x00, 0x99, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0x00, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9E, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x90, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0xE9, 0x91, 0x3F, 0x3F, 0xE9, 0x92, /* 0xD0-0xD3 */
+	0xE9, 0x93, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x8D, 0x82, 0xEE, 0xE0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xEE, 0xE1, 0x3F, 0x3F, 0xE9, 0x94, 0xE9, 0x95, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x96, 0xE9, 0x97, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x98, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x94, 0xAF, 0xE9, 0x9A, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x95, 0x45, 0xE9, 0x9B, 0xE9, 0x99, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xE9, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0xE9, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x9E, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0x9F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_9B[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xA0, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0x24-0x27 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x9F, 0x54, 0x00, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xE9, 0xA1, 0x3F, 0x3F, 0xE9, 0xA2, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xA3, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xA4, 0xE9, 0xA5, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xE9, 0xA6, 0x3F, 0x3F, 0xE9, 0xA7, /* 0x24-0x27 */
+	0xE9, 0xA8, 0xE9, 0xA9, 0xE9, 0xAA, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xAB, 0xE9, 0xAC, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x9F, 0x54, 0xE9, 0xAD, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE2, 0xF6, /* 0x38-0x3B */
 	0x8B, 0x53, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x8A, 0x40, 0x8D, 0x00, 0x00, 0x00, /* 0x40-0x43 */
-	0x00, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x8A, 0x40, 0x8D, 0xB0, 0xE9, 0xAF, /* 0x40-0x43 */
+	0xE9, 0xAE, 0x96, 0xA3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0xE9, 0xB1, 0xE9, 0xB2, 0xE9, 0xB0, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0xE9, 0xB3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x96, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x00, 0x00, 0x3F, 0x3F, 0x8B, 0x9B, 0x3F, 0x3F, /* 0x58-0x5B */
+	0xE9, 0xB4, 0x3F, 0x3F, 0x8B, 0x9B, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x44, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x42, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x00, 0x00, 0x00, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xE3, 0x3F, 0x3F, /* 0x70-0x73 */
+	0xE9, 0xB5, 0xEE, 0xE2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xB7, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0x00, 0x00, 0x43, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x88, 0xBC, 0xEE, 0xE4, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xE9, 0xB8, 0x95, 0xA9, 0xE9, 0xB6, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xB9, 0xE9, 0xBA, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x9C-0x9F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xBB, /* 0x9C-0x9F */
+	0xE9, 0xBC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x00, 0x00, 0x3F, 0x3F, 0x96, 0x8E, 0x8E, 0x4C, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x8D, 0x00, 0x91, 0x4E, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x00, 0x44, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x00, 0x45, /* 0xB8-0xBB */
+	0xE9, 0xBD, 0x3F, 0x3F, 0x96, 0x8E, 0x8E, 0x4C, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x8D, 0xF8, 0x91, 0x4E, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xEE, 0xE5, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xE9, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0xE9, 0xC1, 0x3F, 0x3F, 0xEE, 0xE6, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x8C, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x8E, 0x49, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0x00, /* 0xD8-0xDB */
+	0xE9, 0xBF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xC2, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x8C, 0xEF, 0xE9, 0xC0, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xC3, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0xE9, 0xC4, 0xE9, 0xC5, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0xE9, 0xC9, 0x3F, 0x3F, 0x8E, 0x49, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x91, 0xE2, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0xE0-0xE3 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0xE9, 0xCA, 0xE9, 0xC7, 0xE9, 0xC6, /* 0xE0-0xE3 */
+	0xE9, 0xC8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x8C, 0x7E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x3F, 0x3F, 0x88, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0xE9, 0xCE, 0xE9, 0xCD, 0xE9, 0xCC, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x88, 0xB1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_9C[512] = {
-	0x00, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x00, 0x00, 0x8A, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x98, 0x6B, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x13 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x18-0x1B */
+	0xEE, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0xE9, 0xD8, 0x3F, 0x3F, 0xE9, 0xD4, 0x3F, 0x3F, /* 0x04-0x07 */
+	0xE9, 0xD5, 0xE9, 0xD1, 0xE9, 0xD7, 0x3F, 0x3F, /* 0x08-0x0B */
+	0xE9, 0xD3, 0x8A, 0x82, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x98, 0x6B, 0x3F, 0x3F, 0xE9, 0xD6, 0xE9, 0xD2, /* 0x10-0x13 */
+	0xE9, 0xD0, 0xE9, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xDA, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xE9, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xE9, 0xDC, 0xE9, 0xDB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x95, 0x68, 0x00, 0x00, 0x88, 0x00, /* 0x2C-0x2F */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x95, 0x68, 0xE9, 0xD9, 0x88, 0xF1, /* 0x2C-0x2F */
+	0xE9, 0xDE, 0x3F, 0x3F, 0xE9, 0xE0, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x8A, 0x8F, 0x00, 0x00, 0x89, 0x56, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x8A, 0x8F, 0xE9, 0xCB, 0x89, 0x56, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xE2, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xE1, 0xE9, 0xDF, /* 0x44-0x47 */
 	0x92, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x90, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0x00, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x97, 0xD8, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xE3, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x64-0x67 */
+	0xE9, 0xE4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xE5, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xE6, 0x3F, 0x3F, /* 0x74-0x77 */
+	0xE9, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
@@ -9285,81 +9287,81 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x92, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xE4-0xE7 */
-	0x3F, 0x3F, 0x94, 0x00, 0x3F, 0x3F, 0x00, 0x00, /* 0xE8-0xEB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x50, /* 0xF0-0xF3 */
-	0x96, 0x00, 0x3F, 0x3F, 0x93, 0x00, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x92, 0xB9, 0x3F, 0x3F, 0xE9, 0xE8, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x94, 0xB5, 0x3F, 0x3F, 0xE9, 0xED, /* 0xE8-0xEB */
+	0xE9, 0xE9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0xE9, 0xEA, 0x3F, 0x3F, 0x3F, 0x3F, 0x96, 0x50, /* 0xF0-0xF3 */
+	0x96, 0xC2, 0x3F, 0x3F, 0x93, 0xCE, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_9D[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x93, 0x00, /* 0x04-0x07 */
-	0x00, 0x00, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x00, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xEE, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xEF, 0x93, 0xBC, /* 0x04-0x07 */
+	0xE9, 0xEC, 0xE9, 0xEB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0xA8, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xF7, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE9, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x89, 0x95, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x8A, 0x9B, 0x3F, 0x3F, 0x00, 0x00, 0x8E, 0x00, /* 0x28-0x2B */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xF4, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xF3, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xF1, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x8A, 0x9B, 0x3F, 0x3F, 0xE9, 0xF0, 0x8E, 0xB0, /* 0x28-0x2B */
+	0x89, 0xA7, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8D, 0x83, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
-	0x00, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xFA, 0xE9, 0xF9, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0xE9, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xE9, 0xF5, 0x3F, 0x3F, 0xE9, 0xFB, 0x3F, 0x3F, /* 0x44-0x47 */
+	0xE9, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
-	0x00, 0x44, 0x00, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0xEA, 0x44, 0xEA, 0x43, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
-	0x3F, 0x3F, 0x00, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x89, 0x4C, 0x00, 0x40, 0x00, 0x41, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x8D, 0x94, 0x96, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x00, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x48, /* 0x68-0x6B */
-	0x96, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4A, /* 0x6C-0x6F */
-	0x00, 0x47, 0x3F, 0x3F, 0x00, 0x46, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0xEA, 0x45, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x89, 0x4C, 0xEA, 0x40, 0xEA, 0x41, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x8D, 0x94, 0x96, 0xB7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xEA, 0x42, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEE, 0xE9, /* 0x68-0x6B */
+	0x96, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x4A, /* 0x6C-0x6F */
+	0xEE, 0xE8, 0x3F, 0x3F, 0xEA, 0x46, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4B, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x4B, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x48, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x00, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x48, /* 0x84-0x87 */
+	0x3F, 0x3F, 0xEA, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x7B, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4C, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x4C, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x00, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x00, 0x4E, 0x3F, 0x3F, 0x00, 0x49, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x4F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x92, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x00, 0x53, 0x3F, 0x3F, 0x00, 0x54, 0x00, 0x52, /* 0xB8-0xBB */
+	0xEA, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0xEA, 0x4E, 0x3F, 0x3F, 0xEA, 0x49, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xE9, 0xF2, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x4F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x92, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0xEA, 0x53, 0x3F, 0x3F, 0xEA, 0x54, 0xEA, 0x52, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x00, 0x51, 0x00, 0x57, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x00, 0x50, 0x3F, 0x3F, 0x00, 0x55, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0xEA, 0x51, 0xEA, 0x57, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0xEA, 0x50, 0x3F, 0x3F, 0xEA, 0x55, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x56, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x59, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x56, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x59, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x00, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xEA, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x5B, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x5B, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x00, 0x5C, 0x3F, 0x3F, 0x00, 0x5D, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0xEA, 0x5C, 0x3F, 0x3F, 0xEA, 0x5D, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x98, 0x68, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
-	0x00, 0x5A, 0x91, 0x00, 0x8D, 0x00, 0x3F, 0x3F, /* 0xF8-0xFB */
-	0x3F, 0x3F, 0x00, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xEA, 0x5A, 0x91, 0xE9, 0x8D, 0xEB, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0xEA, 0x5E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_9E[512] = {
@@ -9369,8 +9371,8 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x00, 0x4A, 0x00, 0x5F, 0x00, 0x60, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x61, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0xEE, 0xEB, 0xEA, 0x5F, 0xEA, 0x60, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x61, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
@@ -9392,87 +9394,155 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x00, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x8C, 0x00, 0x00, 0x63, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
-	0x3F, 0x3F, 0x00, 0x64, 0x3F, 0x3F, 0x8E, 0x00, /* 0x7C-0x7F */
-	
-	0x3F, 0x3F, 0x00, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x00, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x67, /* 0x88-0x8B */
-	0x00, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x00, 0x6B, 0x00, 0x69, 0x98, 0x5B, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x00, 0x6A, 0x3F, 0x3F, 0x97, 0x00, /* 0x94-0x97 */
+	0x3F, 0x3F, 0xEA, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x8C, 0xB2, 0xEA, 0x63, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0xEA, 0x64, 0x3F, 0x3F, 0x8E, 0xAD, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0xEA, 0x65, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0xEA, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x67, /* 0x88-0x8B */
+	0xEA, 0x68, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xEA, 0x6B, 0xEA, 0x69, 0x98, 0x5B, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xEA, 0x6A, 0x3F, 0x3F, 0x97, 0xED, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x00, 0x6C, 0x3F, 0x3F, 0x97, 0x00, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0xEA, 0x6C, 0x3F, 0x3F, 0x97, 0xD9, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x00, 0x6D, 0x94, 0x9E, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x00, 0x6E, 0x00, 0x70, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x00, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0xEA, 0x6D, 0x94, 0x9E, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0xEA, 0x6E, 0xEA, 0x70, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0xEA, 0x71, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x00, 0x6F, 0x8D, 0x8D, 0x96, 0x00, 0x96, 0x83, /* 0xB8-0xBB */
-	0x9B, 0x00, 0x3F, 0x3F, 0x9F, 0x80, 0x96, 0x9B, /* 0xBC-0xBF */
+	0xEA, 0x6F, 0x8D, 0x8D, 0x96, 0xCB, 0x96, 0x83, /* 0xB8-0xBB */
+	0x9B, 0xF5, 0x3F, 0x3F, 0x9F, 0x80, 0x96, 0x9B, /* 0xBC-0xBF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x89, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x89, 0xA9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x00, 0x73, 0x8B, 0x6F, 0x00, 0x74, 0x00, 0x75, /* 0xCC-0xCF */
-	0x00, 0x76, 0x00, 0x4B, 0x8D, 0x95, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x00, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x00, 0x00, 0x96, 0x00, 0x3F, 0x3F, 0x91, 0x00, /* 0xD8-0xDB */
-	0x00, 0x78, 0x00, 0x7A, 0x00, 0x79, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x00, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x00, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
-	0x00, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x7E, /* 0xEC-0xEF */
+	0xEA, 0x73, 0x8B, 0x6F, 0xEA, 0x74, 0xEA, 0x75, /* 0xCC-0xCF */
+	0xEA, 0x76, 0xEE, 0xEC, 0x8D, 0x95, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0xEA, 0x77, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0xE0, 0xD2, 0x96, 0xD9, 0x3F, 0x3F, 0x91, 0xE1, /* 0xD8-0xDB */
+	0xEA, 0x78, 0xEA, 0x7A, 0xEA, 0x79, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xEA, 0x7B, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0xEA, 0x7C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0xEA, 0x7D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x7E, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
-	0x00, 0x80, 0x3F, 0x3F, 0x00, 0x81, 0x00, 0x82, /* 0xF4-0xF7 */
-	0x3F, 0x3F, 0x00, 0x83, 0x3F, 0x3F, 0x00, 0x84, /* 0xF8-0xFB */
-	0x00, 0x85, 0x00, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+	0xEA, 0x80, 0x3F, 0x3F, 0xEA, 0x81, 0xEA, 0x82, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xEA, 0x83, 0x3F, 0x3F, 0xEA, 0x84, /* 0xF8-0xFB */
+	0xEA, 0x85, 0xEA, 0x86, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
 static unsigned char u2c_9F[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x87, /* 0x04-0x07 */
-	0x00, 0x88, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x87, /* 0x04-0x07 */
+	0xEA, 0x88, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x93, 0x43, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0x00, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x00, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x8C, 0xDB, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xEA, 0x8A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x91, 0x6C, 0x00, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x91, 0x6C, 0xEA, 0x8B, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x00, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xEA, 0x8C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x95, 0x40, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8D, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x8D, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x8E, 0xE2, 0x56, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xE6, 0xD8, 0xE8, 0xEB, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x8F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0xEA, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x92, /* 0x5C-0x5F */
+	0xEA, 0x93, 0xEA, 0x94, 0x97, 0xEE, 0xEA, 0x91, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x95, 0xEA, 0x96, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x98, 0x3F, 0x3F, /* 0x68-0x6B */
+	0xEA, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x9A, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEA, 0x9B, 0xEA, 0x99, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x97, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0xEA, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0xEA, 0x9D, 0xE2, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0xEA, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+};
+
+static unsigned char u2c_DC[512] = {
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8E, 0x00, 0x56, /* 0x48-0x4B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, /* 0x4C-0x4F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x8F, 0x3F, 0x3F, /* 0x50-0x53 */
-	0x00, 0x90, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x92, /* 0x5C-0x5F */
-	0x00, 0x93, 0x00, 0x94, 0x97, 0x00, 0x00, 0x91, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x95, 0x00, 0x96, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x98, 0x3F, 0x3F, /* 0x68-0x6B */
-	0x00, 0x97, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9A, 0x3F, 0x3F, /* 0x70-0x73 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x9B, 0x00, 0x99, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x97, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x00, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x00, 0x9D, 0x00, 0x73, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x00, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
@@ -9509,7 +9579,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0xED, 0xC4, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
@@ -9555,7 +9625,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x00, 0x00, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xEE, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
@@ -9570,15 +9640,15 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x00, 0x90, 0x00, 0x9B, /* 0x0C-0x0F */
-	0x00, 0x9C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x10-0x13 */
-	0x00, 0x00, 0x00, 0x58, 0x00, 0x5E, 0x00, 0x75, /* 0x14-0x17 */
-	0x00, 0x7D, 0x00, 0x7E, 0x00, 0x80, 0x00, 0x82, /* 0x18-0x1B */
-	0x00, 0x86, 0x00, 0x89, 0x00, 0x92, 0x00, 0x9D, /* 0x1C-0x1F */
-	0x00, 0x9F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x20-0x23 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x24-0x27 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x28-0x2B */
-	0x00, 0x00, 0x00, 0x49, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xED, 0x73, 0xED, 0x7E, /* 0x0C-0x0F */
+	0xED, 0x80, 0xED, 0x95, 0xED, 0xBC, 0xED, 0xCC, /* 0x10-0x13 */
+	0xED, 0xCE, 0xED, 0xF9, 0xEE, 0x42, 0xEE, 0x59, /* 0x14-0x17 */
+	0xEE, 0x61, 0xEE, 0x62, 0xEE, 0x63, 0xEE, 0x65, /* 0x18-0x1B */
+	0xEE, 0x69, 0xEE, 0x6C, 0xEE, 0x75, 0xEE, 0x81, /* 0x1C-0x1F */
+	0xEE, 0x83, 0xEE, 0x84, 0xEE, 0x8D, 0xEE, 0x95, /* 0x20-0x23 */
+	0xEE, 0x97, 0xEE, 0x98, 0xEE, 0x9B, 0xEE, 0xB7, /* 0x24-0x27 */
+	0xEE, 0xBE, 0xEE, 0xCE, 0xEE, 0xDA, 0xEE, 0xDB, /* 0x28-0x2B */
+	0xEE, 0xDD, 0xEE, 0xEA, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
@@ -9635,8 +9705,8 @@
 };
 
 static unsigned char u2c_FF[512] = {
-	0x3F, 0x3F, 0x81, 0x49, 0x00, 0x57, 0x81, 0x94, /* 0x00-0x03 */
-	0x81, 0x90, 0x81, 0x93, 0x81, 0x95, 0x00, 0x56, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x81, 0x49, 0xEE, 0xFC, 0x81, 0x94, /* 0x00-0x03 */
+	0x81, 0x90, 0x81, 0x93, 0x81, 0x95, 0xEE, 0xFB, /* 0x04-0x07 */
 	0x81, 0x69, 0x81, 0x6A, 0x81, 0x96, 0x81, 0x7B, /* 0x08-0x0B */
 	0x81, 0x43, 0x81, 0x7C, 0x81, 0x44, 0x81, 0x5E, /* 0x0C-0x0F */
 	0x82, 0x4F, 0x82, 0x50, 0x82, 0x51, 0x82, 0x52, /* 0x10-0x13 */
@@ -9659,23 +9729,23 @@
 	0x82, 0x94, 0x82, 0x95, 0x82, 0x96, 0x82, 0x97, /* 0x54-0x57 */
 	0x82, 0x98, 0x82, 0x99, 0x82, 0x9A, 0x81, 0x6F, /* 0x58-0x5B */
 	0x81, 0x62, 0x81, 0x70, 0x81, 0x60, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x60-0x63 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x64-0x67 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x68-0x6B */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x6C-0x6F */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x70-0x73 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x74-0x77 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x78-0x7B */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x7C-0x7F */
-	
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x80-0x83 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x84-0x87 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x88-0x8B */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x8C-0x8F */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x90-0x93 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x94-0x97 */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x98-0x9B */
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x00, 0xA1, 0x00, 0xA2, 0x00, 0xA3, /* 0x60-0x63 */
+	0x00, 0xA4, 0x00, 0xA5, 0x00, 0xA6, 0x00, 0xA7, /* 0x64-0x67 */
+	0x00, 0xA8, 0x00, 0xA9, 0x00, 0xAA, 0x00, 0xAB, /* 0x68-0x6B */
+	0x00, 0xAC, 0x00, 0xAD, 0x00, 0xAE, 0x00, 0xAF, /* 0x6C-0x6F */
+	0x00, 0xB0, 0x00, 0xB1, 0x00, 0xB2, 0x00, 0xB3, /* 0x70-0x73 */
+	0x00, 0xB4, 0x00, 0xB5, 0x00, 0xB6, 0x00, 0xB7, /* 0x74-0x77 */
+	0x00, 0xB8, 0x00, 0xB9, 0x00, 0xBA, 0x00, 0xBB, /* 0x78-0x7B */
+	0x00, 0xBC, 0x00, 0xBD, 0x00, 0xBE, 0x00, 0xBF, /* 0x7C-0x7F */
+	
+	0x00, 0xC0, 0x00, 0xC1, 0x00, 0xC2, 0x00, 0xC3, /* 0x80-0x83 */
+	0x00, 0xC4, 0x00, 0xC5, 0x00, 0xC6, 0x00, 0xC7, /* 0x84-0x87 */
+	0x00, 0xC8, 0x00, 0xC9, 0x00, 0xCA, 0x00, 0xCB, /* 0x88-0x8B */
+	0x00, 0xCC, 0x00, 0xCD, 0x00, 0xCE, 0x00, 0xCF, /* 0x8C-0x8F */
+	0x00, 0xD0, 0x00, 0xD1, 0x00, 0xD2, 0x00, 0xD3, /* 0x90-0x93 */
+	0x00, 0xD4, 0x00, 0xD5, 0x00, 0xD6, 0x00, 0xD7, /* 0x94-0x97 */
+	0x00, 0xD8, 0x00, 0xD9, 0x00, 0xDA, 0x00, 0xDB, /* 0x98-0x9B */
+	0x00, 0xDC, 0x00, 0xDD, 0x00, 0xDE, 0x00, 0xDF, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
@@ -9692,8 +9762,8 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
-	0x81, 0x91, 0x81, 0x92, 0x00, 0x54, 0x81, 0x50, /* 0xE0-0xE3 */
-	0x00, 0x55, 0x81, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x81, 0x91, 0x81, 0x92, 0xEE, 0xF9, 0x81, 0x50, /* 0xE0-0xE3 */
+	0xEE, 0xFA, 0x81, 0x8F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
@@ -9730,7 +9800,7 @@
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   u2c_DC, NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
@@ -9742,12 +9812,11 @@
 
 	if (boundlen <= 0)
 		return;
-	if (ch == 0xFF && 0x60 < cl && cl < 0xA0){
+	if (ch == 0xFF && 0x61 <= cl && cl <= 0x9F){
 		out[0] = cl + 0x40;
 		*outlen = 1;
 		return;
 	}
-
 	uni2charset = page_uni2charset[ch];
 	*outlen = 0;
 	if (uni2charset){
@@ -9771,13 +9840,12 @@
 
 	ch = rawstring[0];
 	cl = rawstring[1];
-	if (0xA0 < ch && ch < 0xE0){
-		*uni1 = 0xFF;
-		*uni2 = ch - 0x40;
+	if (0xA1 <= ch && ch <= 0xDF){
+		*uni1 = ch - 0x40;
+		*uni2 = 0xFF;
 		*offset = 1;
 		return;
 	}
-
 	charset2uni = page_charset2uni[ch];
 	if (charset2uni && cl){
 		*uni1 = charset2uni[cl].uni2;
@@ -9810,20 +9878,99 @@
 	NULL
 };
 
+static struct nls_table alias_table = {
+	"sjis",
+	uni2char,
+	char2uni,
+	inc_use_count,
+	dec_use_count,
+	NULL
+};
+
+static void uni2char_euc_jp(unsigned char ch, unsigned char cl, unsigned char * out, int boundlen, int *outlen)
+{
+	if (boundlen <= 0)
+		return;
+	if (ch == 0xFF && 0x61 <= cl && cl <= 0x9F){
+		if (boundlen <= 1)
+			return;
+		out[0] = 0x8E; /* EUCHANKAKU */
+		out[1] = cl + 0x40;
+		*outlen = 2;
+		return;
+	}
+	uni2char(ch, cl, out, boundlen, outlen);
+	if (*outlen == 2) {
+		/* translate SJIS into EUC-JP */ 
+		out[0] = (out[0]^0xA0)*2 + 0x5F;
+		if (out[1] > 0x9E)
+			out[0]++;
+
+		if (out[1] < 0x7F)
+			out[1] = out[1] + 0x61;
+		else if (out[1] < 0x9F)
+			out[1] = out[1] + 0x60;
+		else
+			out[1] = out[1] + 0x02;
+	}
+}
+
+static void char2uni_euc_jp(unsigned char *rawstring, int *offset, unsigned char *uni1, unsigned char *uni2)
+{
+	unsigned char sjis_temp[2];
+
+	if (rawstring[0] == 0x8E) {
+		if (0xA1 <= rawstring[1] && rawstring[1] <= 0xDF){
+			*uni1 = rawstring[1] - 0x40;
+			*uni2 = 0xFF;
+			*offset = 2;
+			return;
+		}
+	}
+	/* translate EUC-JP into SJIS */
+	sjis_temp[0] = ((rawstring[0]-0x5f)/2) ^ 0xA0;
+	if (!(rawstring[0]&1))
+		sjis_temp[1] = rawstring[1] - 0x02;
+	else if (rawstring[1] < 0xE0)
+		sjis_temp[1] = rawstring[1] - 0x61;
+	else
+		sjis_temp[1] = rawstring[1] - 0x60;
+
+	char2uni(sjis_temp, offset, uni1, uni2);
+}
+
+static struct nls_table euc_jp_table = {
+	"euc-jp",
+	uni2char_euc_jp,
+	char2uni_euc_jp,
+	inc_use_count,
+	dec_use_count,
+	NULL
+};
+
+int __init init_nls_euc_jp(void)
+{
+	return register_nls(&euc_jp_table);
+}
+
 int __init init_nls_cp932(void)
 {
+	register_nls(&alias_table);
 	return register_nls(&table);
 }
 
 #ifdef MODULE
 int init_module(void)
 {
+	init_nls_euc_jp();
 	return init_nls_cp932();
 }
 
 
 void cleanup_module(void)
 {
+	unregister_nls(&euc_jp_table);
+	unregister_nls(&alias_table);
 	unregister_nls(&table);
 	return;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/nls/nls_cp936.c linux.17p18/fs/nls/nls_cp936.c
--- linux.vanilla/fs/nls/nls_cp936.c	Sun Jun 11 21:44:20 2000
+++ linux.17p18/fs/nls/nls_cp936.c	Tue Aug  1 07:59:08 2000
@@ -2,7 +2,9 @@
  * linux/fs/nls_cp936.c
  *
  * Charset cp936 translation tables.
- * Generated automatically from the Microsoft
+ * This translation table was generated automatically, the
+ * original table can be download from the Microsoft website.
+ * (http://www.microsoft.com/typography/unicode/unicodecp.htm)
  */
 
 #include <linux/module.h>
@@ -42,7 +44,7 @@
 	{0x4E, 0x74}, {0x4E, 0x75}, {0x4E, 0x76}, {0x4E, 0x77}, /* 0x6C-0x6F */
 	{0x4E, 0x78}, {0x4E, 0x79}, {0x4E, 0x7A}, {0x4E, 0x7B}, /* 0x70-0x73 */
 	{0x4E, 0x7C}, {0x4E, 0x7D}, {0x4E, 0x7F}, {0x4E, 0x80}, /* 0x74-0x77 */
-	{0x4E, 0x81}, {0x4E, 0x82}, {0x4E, 0x83}, {0x4E, 0x84}, /* 0x78-0x7B */
+	{0x4E, 0x81}, {0xF9, 0x1B}, {0x4E, 0x83}, {0x4E, 0x84}, /* 0x78-0x7B */
 	{0x4E, 0x85}, {0x4E, 0x87}, {0x4E, 0x8A}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x4E, 0x90}, {0x4E, 0x96}, {0x4E, 0x97}, {0x4E, 0x99}, /* 0x80-0x83 */
@@ -72,7 +74,7 @@
 	{0x4F, 0x6E}, {0x4F, 0x71}, {0x4F, 0x72}, {0x4F, 0x75}, /* 0xE0-0xE3 */
 	{0x4F, 0x77}, {0x4F, 0x78}, {0x4F, 0x79}, {0x4F, 0x7A}, /* 0xE4-0xE7 */
 	{0x4F, 0x7D}, {0x4F, 0x80}, {0x4F, 0x81}, {0x4F, 0x82}, /* 0xE8-0xEB */
-	{0x4F, 0x85}, {0x4F, 0x86}, {0x4F, 0x87}, {0x4F, 0x8A}, /* 0xEC-0xEF */
+	{0x4F, 0x85}, {0xF9, 0x2D}, {0x4F, 0x87}, {0x4F, 0x8A}, /* 0xEC-0xEF */
 	{0x4F, 0x8C}, {0x4F, 0x8E}, {0x4F, 0x90}, {0x4F, 0x92}, /* 0xF0-0xF3 */
 	{0x4F, 0x93}, {0x4F, 0x95}, {0x4F, 0x96}, {0x4F, 0x98}, /* 0xF4-0xF7 */
 	{0x4F, 0x99}, {0x4F, 0x9A}, {0x4F, 0x9C}, {0x4F, 0x9E}, /* 0xF8-0xFB */
@@ -117,7 +119,7 @@
 	{0x50, 0x13}, {0x50, 0x15}, {0x50, 0x16}, {0x50, 0x17}, /* 0x84-0x87 */
 	{0x50, 0x1B}, {0x50, 0x1D}, {0x50, 0x1E}, {0x50, 0x20}, /* 0x88-0x8B */
 	{0x50, 0x22}, {0x50, 0x23}, {0x50, 0x24}, {0x50, 0x27}, /* 0x8C-0x8F */
-	{0x50, 0x2B}, {0x50, 0x2F}, {0x50, 0x30}, {0x50, 0x31}, /* 0x90-0x93 */
+	{0xF9, 0xD4}, {0x50, 0x2F}, {0x50, 0x30}, {0x50, 0x31}, /* 0x90-0x93 */
 	{0x50, 0x32}, {0x50, 0x33}, {0x50, 0x34}, {0x50, 0x35}, /* 0x94-0x97 */
 	{0x50, 0x36}, {0x50, 0x37}, {0x50, 0x38}, {0x50, 0x39}, /* 0x98-0x9B */
 	{0x50, 0x3B}, {0x50, 0x3D}, {0x50, 0x3F}, {0x50, 0x40}, /* 0x9C-0x9F */
@@ -199,7 +201,7 @@
 	{0x51, 0x57}, {0x51, 0x58}, {0x51, 0x59}, {0x51, 0x5B}, /* 0xBC-0xBF */
 	{0x51, 0x5D}, {0x51, 0x5E}, {0x51, 0x5F}, {0x51, 0x60}, /* 0xC0-0xC3 */
 	{0x51, 0x61}, {0x51, 0x63}, {0x51, 0x64}, {0x51, 0x66}, /* 0xC4-0xC7 */
-	{0x51, 0x67}, {0x51, 0x69}, {0x51, 0x6A}, {0x51, 0x6F}, /* 0xC8-0xCB */
+	{0x51, 0x67}, {0xF9, 0x78}, {0x51, 0x6A}, {0x51, 0x6F}, /* 0xC8-0xCB */
 	{0x51, 0x72}, {0x51, 0x7A}, {0x51, 0x7E}, {0x51, 0x7F}, /* 0xCC-0xCF */
 	{0x51, 0x83}, {0x51, 0x84}, {0x51, 0x86}, {0x51, 0x87}, /* 0xD0-0xD3 */
 	{0x51, 0x8A}, {0x51, 0x8B}, {0x51, 0x8E}, {0x51, 0x8F}, /* 0xD4-0xD7 */
@@ -232,8 +234,8 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x51, 0xD8}, {0x51, 0xD9}, {0x51, 0xDA}, {0x51, 0xDC}, /* 0x40-0x43 */
-	{0x51, 0xDE}, {0x51, 0xDF}, {0x51, 0xE2}, {0x51, 0xE3}, /* 0x44-0x47 */
+	{0x51, 0xD8}, {0x51, 0xD9}, {0x51, 0xDA}, {0xF9, 0x54}, /* 0x40-0x43 */
+	{0xFA, 0x15}, {0x51, 0xDF}, {0x51, 0xE2}, {0x51, 0xE3}, /* 0x44-0x47 */
 	{0x51, 0xE5}, {0x51, 0xE6}, {0x51, 0xE7}, {0x51, 0xE8}, /* 0x48-0x4B */
 	{0x51, 0xE9}, {0x51, 0xEA}, {0x51, 0xEC}, {0x51, 0xEE}, /* 0x4C-0x4F */
 	{0x51, 0xF1}, {0x51, 0xF2}, {0x51, 0xF4}, {0x51, 0xF7}, /* 0x50-0x53 */
@@ -257,7 +259,7 @@
 	{0x52, 0x76}, {0x52, 0x77}, {0x52, 0x78}, {0x52, 0x79}, /* 0x94-0x97 */
 	{0x52, 0x7A}, {0x52, 0x7B}, {0x52, 0x7C}, {0x52, 0x7E}, /* 0x98-0x9B */
 	{0x52, 0x80}, {0x52, 0x83}, {0x52, 0x84}, {0x52, 0x85}, /* 0x9C-0x9F */
-	{0x52, 0x86}, {0x52, 0x87}, {0x52, 0x89}, {0x52, 0x8A}, /* 0xA0-0xA3 */
+	{0x52, 0x86}, {0x52, 0x87}, {0xF9, 0xC7}, {0x52, 0x8A}, /* 0xA0-0xA3 */
 	{0x52, 0x8B}, {0x52, 0x8C}, {0x52, 0x8D}, {0x52, 0x8E}, /* 0xA4-0xA7 */
 	{0x52, 0x8F}, {0x52, 0x91}, {0x52, 0x92}, {0x52, 0x94}, /* 0xA8-0xAB */
 	{0x52, 0x95}, {0x52, 0x96}, {0x52, 0x97}, {0x52, 0x98}, /* 0xAC-0xAF */
@@ -271,12 +273,12 @@
 	{0x52, 0xCC}, {0x52, 0xCD}, {0x52, 0xCE}, {0x52, 0xCF}, /* 0xCC-0xCF */
 	{0x52, 0xD1}, {0x52, 0xD3}, {0x52, 0xD4}, {0x52, 0xD5}, /* 0xD0-0xD3 */
 	{0x52, 0xD7}, {0x52, 0xD9}, {0x52, 0xDA}, {0x52, 0xDB}, /* 0xD4-0xD7 */
-	{0x52, 0xDC}, {0x52, 0xDD}, {0x52, 0xDE}, {0x52, 0xE0}, /* 0xD8-0xDB */
+	{0x52, 0xDC}, {0x52, 0xDD}, {0xF9, 0x2F}, {0x52, 0xE0}, /* 0xD8-0xDB */
 	{0x52, 0xE1}, {0x52, 0xE2}, {0x52, 0xE3}, {0x52, 0xE5}, /* 0xDC-0xDF */
 	{0x52, 0xE6}, {0x52, 0xE7}, {0x52, 0xE8}, {0x52, 0xE9}, /* 0xE0-0xE3 */
 	{0x52, 0xEA}, {0x52, 0xEB}, {0x52, 0xEC}, {0x52, 0xED}, /* 0xE4-0xE7 */
 	{0x52, 0xEE}, {0x52, 0xEF}, {0x52, 0xF1}, {0x52, 0xF2}, /* 0xE8-0xEB */
-	{0x52, 0xF3}, {0x52, 0xF4}, {0x52, 0xF5}, {0x52, 0xF6}, /* 0xEC-0xEF */
+	{0x52, 0xF3}, {0x52, 0xF4}, {0xF9, 0x7F}, {0x52, 0xF6}, /* 0xEC-0xEF */
 	{0x52, 0xF7}, {0x52, 0xF8}, {0x52, 0xFB}, {0x52, 0xFC}, /* 0xF0-0xF3 */
 	{0x52, 0xFD}, {0x53, 0x01}, {0x53, 0x02}, {0x53, 0x03}, /* 0xF4-0xF7 */
 	{0x53, 0x04}, {0x53, 0x07}, {0x53, 0x09}, {0x53, 0x0A}, /* 0xF8-0xFB */
@@ -325,7 +327,7 @@
 	{0x53, 0xB0}, {0x53, 0xB1}, {0x53, 0xB2}, {0x53, 0xB3}, /* 0x94-0x97 */
 	{0x53, 0xB4}, {0x53, 0xB5}, {0x53, 0xB7}, {0x53, 0xB8}, /* 0x98-0x9B */
 	{0x53, 0xB9}, {0x53, 0xBA}, {0x53, 0xBC}, {0x53, 0xBD}, /* 0x9C-0x9F */
-	{0x53, 0xBE}, {0x53, 0xC0}, {0x53, 0xC3}, {0x53, 0xC4}, /* 0xA0-0xA3 */
+	{0x53, 0xBE}, {0x53, 0xC0}, {0xF9, 0x6B}, {0x53, 0xC4}, /* 0xA0-0xA3 */
 	{0x53, 0xC5}, {0x53, 0xC6}, {0x53, 0xC7}, {0x53, 0xCE}, /* 0xA4-0xA7 */
 	{0x53, 0xCF}, {0x53, 0xD0}, {0x53, 0xD2}, {0x53, 0xD3}, /* 0xA8-0xAB */
 	{0x53, 0xD5}, {0x53, 0xDA}, {0x53, 0xDC}, {0x53, 0xDD}, /* 0xAC-0xAF */
@@ -336,7 +338,7 @@
 	{0x54, 0x1A}, {0x54, 0x1C}, {0x54, 0x22}, {0x54, 0x24}, /* 0xC0-0xC3 */
 	{0x54, 0x25}, {0x54, 0x2A}, {0x54, 0x30}, {0x54, 0x33}, /* 0xC4-0xC7 */
 	{0x54, 0x36}, {0x54, 0x37}, {0x54, 0x3A}, {0x54, 0x3D}, /* 0xC8-0xCB */
-	{0x54, 0x3F}, {0x54, 0x41}, {0x54, 0x42}, {0x54, 0x44}, /* 0xCC-0xCF */
+	{0x54, 0x3F}, {0x54, 0x41}, {0xF9, 0x80}, {0x54, 0x44}, /* 0xCC-0xCF */
 	{0x54, 0x45}, {0x54, 0x47}, {0x54, 0x49}, {0x54, 0x4C}, /* 0xD0-0xD3 */
 	{0x54, 0x4D}, {0x54, 0x4E}, {0x54, 0x4F}, {0x54, 0x51}, /* 0xD4-0xD7 */
 	{0x54, 0x5A}, {0x54, 0x5D}, {0x54, 0x5E}, {0x54, 0x5F}, /* 0xD8-0xDB */
@@ -577,7 +579,7 @@
 	{0x58, 0x47}, {0x58, 0x48}, {0x58, 0x49}, {0x58, 0x4A}, /* 0x48-0x4B */
 	{0x58, 0x4B}, {0x58, 0x4E}, {0x58, 0x4F}, {0x58, 0x50}, /* 0x4C-0x4F */
 	{0x58, 0x52}, {0x58, 0x53}, {0x58, 0x55}, {0x58, 0x56}, /* 0x50-0x53 */
-	{0x58, 0x57}, {0x58, 0x59}, {0x58, 0x5A}, {0x58, 0x5B}, /* 0x54-0x57 */
+	{0x58, 0x57}, {0x58, 0x59}, {0xFA, 0x10}, {0x58, 0x5B}, /* 0x54-0x57 */
 	{0x58, 0x5C}, {0x58, 0x5D}, {0x58, 0x5F}, {0x58, 0x60}, /* 0x58-0x5B */
 	{0x58, 0x61}, {0x58, 0x62}, {0x58, 0x63}, {0x58, 0x64}, /* 0x5C-0x5F */
 	{0x58, 0x66}, {0x58, 0x67}, {0x58, 0x68}, {0x58, 0x69}, /* 0x60-0x63 */
@@ -604,9 +606,9 @@
 	{0x58, 0xC8}, {0x58, 0xC9}, {0x58, 0xCA}, {0x58, 0xCB}, /* 0xB0-0xB3 */
 	{0x58, 0xCC}, {0x58, 0xCD}, {0x58, 0xCE}, {0x58, 0xCF}, /* 0xB4-0xB7 */
 	{0x58, 0xD0}, {0x58, 0xD2}, {0x58, 0xD3}, {0x58, 0xD4}, /* 0xB8-0xBB */
-	{0x58, 0xD6}, {0x58, 0xD7}, {0x58, 0xD8}, {0x58, 0xD9}, /* 0xBC-0xBF */
+	{0x58, 0xD6}, {0x58, 0xD7}, {0xF9, 0x4A}, {0x58, 0xD9}, /* 0xBC-0xBF */
 	{0x58, 0xDA}, {0x58, 0xDB}, {0x58, 0xDC}, {0x58, 0xDD}, /* 0xC0-0xC3 */
-	{0x58, 0xDE}, {0x58, 0xDF}, {0x58, 0xE0}, {0x58, 0xE1}, /* 0xC4-0xC7 */
+	{0x58, 0xDE}, {0xF9, 0x42}, {0x58, 0xE0}, {0x58, 0xE1}, /* 0xC4-0xC7 */
 	{0x58, 0xE2}, {0x58, 0xE3}, {0x58, 0xE5}, {0x58, 0xE6}, /* 0xC8-0xCB */
 	{0x58, 0xE7}, {0x58, 0xE8}, {0x58, 0xE9}, {0x58, 0xEA}, /* 0xCC-0xCF */
 	{0x58, 0xED}, {0x58, 0xEF}, {0x58, 0xF1}, {0x58, 0xF2}, /* 0xD0-0xD3 */
@@ -796,7 +798,7 @@
 	{0x5B, 0xD1}, {0x5B, 0xD4}, {0x5B, 0xD5}, {0x5B, 0xD6}, /* 0x80-0x83 */
 	{0x5B, 0xD7}, {0x5B, 0xD8}, {0x5B, 0xD9}, {0x5B, 0xDA}, /* 0x84-0x87 */
 	{0x5B, 0xDB}, {0x5B, 0xDC}, {0x5B, 0xE0}, {0x5B, 0xE2}, /* 0x88-0x8B */
-	{0x5B, 0xE3}, {0x5B, 0xE6}, {0x5B, 0xE7}, {0x5B, 0xE9}, /* 0x8C-0x8F */
+	{0x5B, 0xE3}, {0x5B, 0xE6}, {0xF9, 0xAA}, {0x5B, 0xE9}, /* 0x8C-0x8F */
 	{0x5B, 0xEA}, {0x5B, 0xEB}, {0x5B, 0xEC}, {0x5B, 0xED}, /* 0x90-0x93 */
 	{0x5B, 0xEF}, {0x5B, 0xF1}, {0x5B, 0xF2}, {0x5B, 0xF3}, /* 0x94-0x97 */
 	{0x5B, 0xF4}, {0x5B, 0xF5}, {0x5B, 0xF6}, {0x5B, 0xF7}, /* 0x98-0x9B */
@@ -813,7 +815,7 @@
 	{0x5C, 0x47}, {0x5C, 0x4C}, {0x5C, 0x4D}, {0x5C, 0x52}, /* 0xC4-0xC7 */
 	{0x5C, 0x53}, {0x5C, 0x54}, {0x5C, 0x56}, {0x5C, 0x57}, /* 0xC8-0xCB */
 	{0x5C, 0x58}, {0x5C, 0x5A}, {0x5C, 0x5B}, {0x5C, 0x5C}, /* 0xCC-0xCF */
-	{0x5C, 0x5D}, {0x5C, 0x5F}, {0x5C, 0x62}, {0x5C, 0x64}, /* 0xD0-0xD3 */
+	{0x5C, 0x5D}, {0x5C, 0x5F}, {0xF9, 0x4B}, {0x5C, 0x64}, /* 0xD0-0xD3 */
 	{0x5C, 0x67}, {0x5C, 0x68}, {0x5C, 0x69}, {0x5C, 0x6A}, /* 0xD4-0xD7 */
 	{0x5C, 0x6B}, {0x5C, 0x6C}, {0x5C, 0x6D}, {0x5C, 0x70}, /* 0xD8-0xDB */
 	{0x5C, 0x72}, {0x5C, 0x73}, {0x5C, 0x74}, {0x5C, 0x75}, /* 0xDC-0xDF */
@@ -865,7 +867,7 @@
 	{0x5D, 0x09}, {0x5D, 0x0A}, {0x5D, 0x0B}, {0x5D, 0x0C}, /* 0x84-0x87 */
 	{0x5D, 0x0D}, {0x5D, 0x0F}, {0x5D, 0x10}, {0x5D, 0x11}, /* 0x88-0x8B */
 	{0x5D, 0x12}, {0x5D, 0x13}, {0x5D, 0x15}, {0x5D, 0x17}, /* 0x8C-0x8F */
-	{0x5D, 0x18}, {0x5D, 0x19}, {0x5D, 0x1A}, {0x5D, 0x1C}, /* 0x90-0x93 */
+	{0x5D, 0x18}, {0xF9, 0xD5}, {0x5D, 0x1A}, {0x5D, 0x1C}, /* 0x90-0x93 */
 	{0x5D, 0x1D}, {0x5D, 0x1F}, {0x5D, 0x20}, {0x5D, 0x21}, /* 0x94-0x97 */
 	{0x5D, 0x22}, {0x5D, 0x23}, {0x5D, 0x25}, {0x5D, 0x28}, /* 0x98-0x9B */
 	{0x5D, 0x2A}, {0x5D, 0x2B}, {0x5D, 0x2C}, {0x5D, 0x2F}, /* 0x9C-0x9F */
@@ -875,7 +877,7 @@
 	{0x5D, 0x3F}, {0x5D, 0x40}, {0x5D, 0x41}, {0x5D, 0x42}, /* 0xAC-0xAF */
 	{0x5D, 0x43}, {0x5D, 0x44}, {0x5D, 0x45}, {0x5D, 0x46}, /* 0xB0-0xB3 */
 	{0x5D, 0x48}, {0x5D, 0x49}, {0x5D, 0x4D}, {0x5D, 0x4E}, /* 0xB4-0xB7 */
-	{0x5D, 0x4F}, {0x5D, 0x50}, {0x5D, 0x51}, {0x5D, 0x52}, /* 0xB8-0xBB */
+	{0x5D, 0x4F}, {0xF9, 0x21}, {0x5D, 0x51}, {0x5D, 0x52}, /* 0xB8-0xBB */
 	{0x5D, 0x53}, {0x5D, 0x54}, {0x5D, 0x55}, {0x5D, 0x56}, /* 0xBC-0xBF */
 	{0x5D, 0x57}, {0x5D, 0x59}, {0x5D, 0x5A}, {0x5D, 0x5C}, /* 0xC0-0xC3 */
 	{0x5D, 0x5E}, {0x5D, 0x5F}, {0x5D, 0x60}, {0x5D, 0x61}, /* 0xC4-0xC7 */
@@ -918,7 +920,7 @@
 	{0x5D, 0xAD}, {0x5D, 0xAE}, {0x5D, 0xAF}, {0x5D, 0xB0}, /* 0x4C-0x4F */
 	{0x5D, 0xB1}, {0x5D, 0xB2}, {0x5D, 0xB3}, {0x5D, 0xB4}, /* 0x50-0x53 */
 	{0x5D, 0xB5}, {0x5D, 0xB6}, {0x5D, 0xB8}, {0x5D, 0xB9}, /* 0x54-0x57 */
-	{0x5D, 0xBA}, {0x5D, 0xBB}, {0x5D, 0xBC}, {0x5D, 0xBD}, /* 0x58-0x5B */
+	{0xF9, 0xAB}, {0x5D, 0xBB}, {0x5D, 0xBC}, {0x5D, 0xBD}, /* 0x58-0x5B */
 	{0x5D, 0xBE}, {0x5D, 0xBF}, {0x5D, 0xC0}, {0x5D, 0xC1}, /* 0x5C-0x5F */
 	{0x5D, 0xC2}, {0x5D, 0xC3}, {0x5D, 0xC4}, {0x5D, 0xC6}, /* 0x60-0x63 */
 	{0x5D, 0xC7}, {0x5D, 0xC8}, {0x5D, 0xC9}, {0x5D, 0xCA}, /* 0x64-0x67 */
@@ -987,7 +989,7 @@
 	{0x5E, 0xDD}, {0x5E, 0xDE}, {0x5E, 0xDF}, {0x5E, 0xE0}, /* 0x50-0x53 */
 	{0x5E, 0xE1}, {0x5E, 0xE2}, {0x5E, 0xE3}, {0x5E, 0xE4}, /* 0x54-0x57 */
 	{0x5E, 0xE5}, {0x5E, 0xE6}, {0x5E, 0xE7}, {0x5E, 0xE9}, /* 0x58-0x5B */
-	{0x5E, 0xEB}, {0x5E, 0xEC}, {0x5E, 0xED}, {0x5E, 0xEE}, /* 0x5C-0x5F */
+	{0x5E, 0xEB}, {0xF9, 0x82}, {0x5E, 0xED}, {0x5E, 0xEE}, /* 0x5C-0x5F */
 	{0x5E, 0xEF}, {0x5E, 0xF0}, {0x5E, 0xF1}, {0x5E, 0xF2}, /* 0x60-0x63 */
 	{0x5E, 0xF3}, {0x5E, 0xF5}, {0x5E, 0xF8}, {0x5E, 0xF9}, /* 0x64-0x67 */
 	{0x5E, 0xFB}, {0x5E, 0xFC}, {0x5E, 0xFD}, {0x5F, 0x05}, /* 0x68-0x6B */
@@ -1016,7 +1018,7 @@
 	{0x5F, 0x96}, {0x5F, 0x9A}, {0x5F, 0x9B}, {0x5F, 0x9D}, /* 0xC0-0xC3 */
 	{0x5F, 0x9E}, {0x5F, 0x9F}, {0x5F, 0xA0}, {0x5F, 0xA2}, /* 0xC4-0xC7 */
 	{0x5F, 0xA3}, {0x5F, 0xA4}, {0x5F, 0xA5}, {0x5F, 0xA6}, /* 0xC8-0xCB */
-	{0x5F, 0xA7}, {0x5F, 0xA9}, {0x5F, 0xAB}, {0x5F, 0xAC}, /* 0xCC-0xCF */
+	{0x5F, 0xA7}, {0xF9, 0x66}, {0x5F, 0xAB}, {0x5F, 0xAC}, /* 0xCC-0xCF */
 	{0x5F, 0xAF}, {0x5F, 0xB0}, {0x5F, 0xB1}, {0x5F, 0xB2}, /* 0xD0-0xD3 */
 	{0x5F, 0xB3}, {0x5F, 0xB4}, {0x5F, 0xB6}, {0x5F, 0xB8}, /* 0xD4-0xD7 */
 	{0x5F, 0xB9}, {0x5F, 0xBA}, {0x5F, 0xBB}, {0x5F, 0xBE}, /* 0xD8-0xDB */
@@ -1079,7 +1081,7 @@
 	{0x60, 0xC9}, {0x60, 0xCC}, {0x60, 0xCD}, {0x60, 0xCE}, /* 0xAC-0xAF */
 	{0x60, 0xCF}, {0x60, 0xD0}, {0x60, 0xD2}, {0x60, 0xD3}, /* 0xB0-0xB3 */
 	{0x60, 0xD4}, {0x60, 0xD6}, {0x60, 0xD7}, {0x60, 0xD9}, /* 0xB4-0xB7 */
-	{0x60, 0xDB}, {0x60, 0xDE}, {0x60, 0xE1}, {0x60, 0xE2}, /* 0xB8-0xBB */
+	{0x60, 0xDB}, {0x60, 0xDE}, {0xF9, 0xB9}, {0x60, 0xE2}, /* 0xB8-0xBB */
 	{0x60, 0xE3}, {0x60, 0xE4}, {0x60, 0xE5}, {0x60, 0xEA}, /* 0xBC-0xBF */
 	{0x60, 0xF1}, {0x60, 0xF2}, {0x60, 0xF5}, {0x60, 0xF7}, /* 0xC0-0xC3 */
 	{0x60, 0xF8}, {0x60, 0xFB}, {0x60, 0xFC}, {0x60, 0xFD}, /* 0xC4-0xC7 */
@@ -1096,7 +1098,7 @@
 	{0x61, 0x37}, {0x61, 0x38}, {0x61, 0x39}, {0x61, 0x3A}, /* 0xF0-0xF3 */
 	{0x61, 0x3B}, {0x61, 0x3C}, {0x61, 0x3D}, {0x61, 0x3E}, /* 0xF4-0xF7 */
 	{0x61, 0x40}, {0x61, 0x41}, {0x61, 0x42}, {0x61, 0x43}, /* 0xF8-0xFB */
-	{0x61, 0x44}, {0x61, 0x45}, {0x61, 0x46}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0xF9, 0xD9}, {0x61, 0x45}, {0x61, 0x46}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_91[256] = {
@@ -1130,7 +1132,7 @@
 	{0x61, 0x80}, {0x61, 0x81}, {0x61, 0x82}, {0x61, 0x83}, /* 0x6C-0x6F */
 	{0x61, 0x84}, {0x61, 0x85}, {0x61, 0x86}, {0x61, 0x87}, /* 0x70-0x73 */
 	{0x61, 0x88}, {0x61, 0x89}, {0x61, 0x8A}, {0x61, 0x8C}, /* 0x74-0x77 */
-	{0x61, 0x8D}, {0x61, 0x8F}, {0x61, 0x90}, {0x61, 0x91}, /* 0x78-0x7B */
+	{0x61, 0x8D}, {0x61, 0x8F}, {0xF9, 0x8F}, {0x61, 0x91}, /* 0x78-0x7B */
 	{0x61, 0x92}, {0x61, 0x93}, {0x61, 0x95}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x61, 0x96}, {0x61, 0x97}, {0x61, 0x98}, {0x61, 0x99}, /* 0x80-0x83 */
@@ -1153,9 +1155,9 @@
 	{0x61, 0xE9}, {0x61, 0xEA}, {0x61, 0xEB}, {0x61, 0xEC}, /* 0xC4-0xC7 */
 	{0x61, 0xED}, {0x61, 0xEE}, {0x61, 0xEF}, {0x61, 0xF0}, /* 0xC8-0xCB */
 	{0x61, 0xF1}, {0x61, 0xF2}, {0x61, 0xF3}, {0x61, 0xF4}, /* 0xCC-0xCF */
-	{0x61, 0xF6}, {0x61, 0xF7}, {0x61, 0xF8}, {0x61, 0xF9}, /* 0xD0-0xD3 */
+	{0xF9, 0x0D}, {0x61, 0xF7}, {0x61, 0xF8}, {0x61, 0xF9}, /* 0xD0-0xD3 */
 	{0x61, 0xFA}, {0x61, 0xFB}, {0x61, 0xFC}, {0x61, 0xFD}, /* 0xD4-0xD7 */
-	{0x61, 0xFE}, {0x62, 0x00}, {0x62, 0x01}, {0x62, 0x02}, /* 0xD8-0xDB */
+	{0x61, 0xFE}, {0xF9, 0x90}, {0x62, 0x01}, {0x62, 0x02}, /* 0xD8-0xDB */
 	{0x62, 0x03}, {0x62, 0x04}, {0x62, 0x05}, {0x62, 0x07}, /* 0xDC-0xDF */
 	{0x62, 0x09}, {0x62, 0x13}, {0x62, 0x14}, {0x62, 0x19}, /* 0xE0-0xE3 */
 	{0x62, 0x1C}, {0x62, 0x1D}, {0x62, 0x1E}, {0x62, 0x20}, /* 0xE4-0xE7 */
@@ -1201,7 +1203,7 @@
 	{0x62, 0xB6}, {0x62, 0xB7}, {0x62, 0xB8}, {0x62, 0xBA}, /* 0x78-0x7B */
 	{0x62, 0xBE}, {0x62, 0xC0}, {0x62, 0xC1}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
-	{0x62, 0xC3}, {0x62, 0xCB}, {0x62, 0xCF}, {0x62, 0xD1}, /* 0x80-0x83 */
+	{0x62, 0xC3}, {0x62, 0xCB}, {0xF9, 0x5B}, {0x62, 0xD1}, /* 0x80-0x83 */
 	{0x62, 0xD5}, {0x62, 0xDD}, {0x62, 0xDE}, {0x62, 0xE0}, /* 0x84-0x87 */
 	{0x62, 0xE1}, {0x62, 0xE4}, {0x62, 0xEA}, {0x62, 0xEB}, /* 0x88-0x8B */
 	{0x62, 0xF0}, {0x62, 0xF2}, {0x62, 0xF5}, {0x62, 0xF8}, /* 0x8C-0x8F */
@@ -1289,14 +1291,14 @@
 	{0x64, 0x83}, {0x64, 0x86}, {0x64, 0x88}, {0x64, 0x89}, /* 0xC4-0xC7 */
 	{0x64, 0x8A}, {0x64, 0x8B}, {0x64, 0x8C}, {0x64, 0x8D}, /* 0xC8-0xCB */
 	{0x64, 0x8E}, {0x64, 0x8F}, {0x64, 0x90}, {0x64, 0x93}, /* 0xCC-0xCF */
-	{0x64, 0x94}, {0x64, 0x97}, {0x64, 0x98}, {0x64, 0x9A}, /* 0xD0-0xD3 */
+	{0x64, 0x94}, {0x64, 0x97}, {0x64, 0x98}, {0xF9, 0x91}, /* 0xD0-0xD3 */
 	{0x64, 0x9B}, {0x64, 0x9C}, {0x64, 0x9D}, {0x64, 0x9F}, /* 0xD4-0xD7 */
 	{0x64, 0xA0}, {0x64, 0xA1}, {0x64, 0xA2}, {0x64, 0xA3}, /* 0xD8-0xDB */
 	{0x64, 0xA5}, {0x64, 0xA6}, {0x64, 0xA7}, {0x64, 0xA8}, /* 0xDC-0xDF */
 	{0x64, 0xAA}, {0x64, 0xAB}, {0x64, 0xAF}, {0x64, 0xB1}, /* 0xE0-0xE3 */
 	{0x64, 0xB2}, {0x64, 0xB3}, {0x64, 0xB4}, {0x64, 0xB6}, /* 0xE4-0xE7 */
 	{0x64, 0xB9}, {0x64, 0xBB}, {0x64, 0xBD}, {0x64, 0xBE}, /* 0xE8-0xEB */
-	{0x64, 0xBF}, {0x64, 0xC1}, {0x64, 0xC3}, {0x64, 0xC4}, /* 0xEC-0xEF */
+	{0x64, 0xBF}, {0x64, 0xC1}, {0x64, 0xC3}, {0xF9, 0x30}, /* 0xEC-0xEF */
 	{0x64, 0xC6}, {0x64, 0xC7}, {0x64, 0xC8}, {0x64, 0xC9}, /* 0xF0-0xF3 */
 	{0x64, 0xCA}, {0x64, 0xCB}, {0x64, 0xCC}, {0x64, 0xCF}, /* 0xF4-0xF7 */
 	{0x64, 0xD1}, {0x64, 0xD3}, {0x64, 0xD4}, {0x64, 0xD5}, /* 0xF8-0xFB */
@@ -1350,7 +1352,7 @@
 	{0x65, 0x64}, {0x65, 0x65}, {0x65, 0x67}, {0x65, 0x68}, /* 0xA8-0xAB */
 	{0x65, 0x69}, {0x65, 0x6A}, {0x65, 0x6D}, {0x65, 0x6E}, /* 0xAC-0xAF */
 	{0x65, 0x6F}, {0x65, 0x71}, {0x65, 0x73}, {0x65, 0x75}, /* 0xB0-0xB3 */
-	{0x65, 0x76}, {0x65, 0x78}, {0x65, 0x79}, {0x65, 0x7A}, /* 0xB4-0xB7 */
+	{0x65, 0x76}, {0xF9, 0x69}, {0x65, 0x79}, {0x65, 0x7A}, /* 0xB4-0xB7 */
 	{0x65, 0x7B}, {0x65, 0x7C}, {0x65, 0x7D}, {0x65, 0x7E}, /* 0xB8-0xBB */
 	{0x65, 0x7F}, {0x65, 0x80}, {0x65, 0x81}, {0x65, 0x82}, /* 0xBC-0xBF */
 	{0x65, 0x83}, {0x65, 0x84}, {0x65, 0x85}, {0x65, 0x86}, /* 0xC0-0xC3 */
@@ -1412,7 +1414,7 @@
 	{0x66, 0x72}, {0x66, 0x73}, {0x66, 0x75}, {0x66, 0x78}, /* 0x90-0x93 */
 	{0x66, 0x79}, {0x66, 0x7B}, {0x66, 0x7C}, {0x66, 0x7D}, /* 0x94-0x97 */
 	{0x66, 0x7F}, {0x66, 0x80}, {0x66, 0x81}, {0x66, 0x83}, /* 0x98-0x9B */
-	{0x66, 0x85}, {0x66, 0x86}, {0x66, 0x88}, {0x66, 0x89}, /* 0x9C-0x9F */
+	{0x66, 0x85}, {0x66, 0x86}, {0xF9, 0xC5}, {0x66, 0x89}, /* 0x9C-0x9F */
 	{0x66, 0x8A}, {0x66, 0x8B}, {0x66, 0x8D}, {0x66, 0x8E}, /* 0xA0-0xA3 */
 	{0x66, 0x8F}, {0x66, 0x90}, {0x66, 0x92}, {0x66, 0x93}, /* 0xA4-0xA7 */
 	{0x66, 0x94}, {0x66, 0x95}, {0x66, 0x98}, {0x66, 0x99}, /* 0xA8-0xAB */
@@ -1425,7 +1427,7 @@
 	{0x66, 0xB7}, {0x66, 0xB8}, {0x66, 0xBA}, {0x66, 0xBB}, /* 0xC4-0xC7 */
 	{0x66, 0xBC}, {0x66, 0xBD}, {0x66, 0xBF}, {0x66, 0xC0}, /* 0xC8-0xCB */
 	{0x66, 0xC1}, {0x66, 0xC2}, {0x66, 0xC3}, {0x66, 0xC4}, /* 0xCC-0xCF */
-	{0x66, 0xC5}, {0x66, 0xC6}, {0x66, 0xC7}, {0x66, 0xC8}, /* 0xD0-0xD3 */
+	{0x66, 0xC5}, {0xF9, 0x8B}, {0x66, 0xC7}, {0x66, 0xC8}, /* 0xD0-0xD3 */
 	{0x66, 0xC9}, {0x66, 0xCA}, {0x66, 0xCB}, {0x66, 0xCC}, /* 0xD4-0xD7 */
 	{0x66, 0xCD}, {0x66, 0xCE}, {0x66, 0xCF}, {0x66, 0xD0}, /* 0xD8-0xDB */
 	{0x66, 0xD1}, {0x66, 0xD2}, {0x66, 0xD3}, {0x66, 0xD4}, /* 0xDC-0xDF */
@@ -1473,7 +1475,7 @@
 	{0x67, 0x67}, {0x67, 0x6B}, {0x67, 0x6C}, {0x67, 0x6E}, /* 0x78-0x7B */
 	{0x67, 0x71}, {0x67, 0x74}, {0x67, 0x76}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
-	{0x67, 0x78}, {0x67, 0x79}, {0x67, 0x7A}, {0x67, 0x7B}, /* 0x80-0x83 */
+	{0x67, 0x78}, {0x67, 0x79}, {0x67, 0x7A}, {0xF9, 0xC8}, /* 0x80-0x83 */
 	{0x67, 0x7D}, {0x67, 0x80}, {0x67, 0x82}, {0x67, 0x83}, /* 0x84-0x87 */
 	{0x67, 0x85}, {0x67, 0x86}, {0x67, 0x88}, {0x67, 0x8A}, /* 0x88-0x8B */
 	{0x67, 0x8C}, {0x67, 0x8D}, {0x67, 0x8E}, {0x67, 0x8F}, /* 0x8C-0x8F */
@@ -1622,11 +1624,11 @@
 	{0x69, 0xF0}, {0x69, 0xF1}, {0x69, 0xF3}, {0x69, 0xF4}, /* 0xA8-0xAB */
 	{0x69, 0xF5}, {0x69, 0xF6}, {0x69, 0xF7}, {0x69, 0xF8}, /* 0xAC-0xAF */
 	{0x69, 0xF9}, {0x69, 0xFA}, {0x69, 0xFB}, {0x69, 0xFC}, /* 0xB0-0xB3 */
-	{0x69, 0xFE}, {0x6A, 0x00}, {0x6A, 0x01}, {0x6A, 0x02}, /* 0xB4-0xB7 */
+	{0x69, 0xFE}, {0x6A, 0x00}, {0x6A, 0x01}, {0xF9, 0xBF}, /* 0xB4-0xB7 */
 	{0x6A, 0x03}, {0x6A, 0x04}, {0x6A, 0x05}, {0x6A, 0x06}, /* 0xB8-0xBB */
 	{0x6A, 0x07}, {0x6A, 0x08}, {0x6A, 0x09}, {0x6A, 0x0B}, /* 0xBC-0xBF */
 	{0x6A, 0x0C}, {0x6A, 0x0D}, {0x6A, 0x0E}, {0x6A, 0x0F}, /* 0xC0-0xC3 */
-	{0x6A, 0x10}, {0x6A, 0x11}, {0x6A, 0x12}, {0x6A, 0x13}, /* 0xC4-0xC7 */
+	{0x6A, 0x10}, {0x6A, 0x11}, {0x6A, 0x12}, {0xF9, 0x4C}, /* 0xC4-0xC7 */
 	{0x6A, 0x14}, {0x6A, 0x15}, {0x6A, 0x16}, {0x6A, 0x19}, /* 0xC8-0xCB */
 	{0x6A, 0x1A}, {0x6A, 0x1B}, {0x6A, 0x1C}, {0x6A, 0x1D}, /* 0xCC-0xCF */
 	{0x6A, 0x1E}, {0x6A, 0x20}, {0x6A, 0x22}, {0x6A, 0x23}, /* 0xD0-0xD3 */
@@ -1687,7 +1689,7 @@
 	{0x6A, 0xC6}, {0x6A, 0xC7}, {0x6A, 0xC8}, {0x6A, 0xC9}, /* 0x9C-0x9F */
 	{0x6A, 0xCA}, {0x6A, 0xCB}, {0x6A, 0xCC}, {0x6A, 0xCD}, /* 0xA0-0xA3 */
 	{0x6A, 0xCE}, {0x6A, 0xCF}, {0x6A, 0xD0}, {0x6A, 0xD1}, /* 0xA4-0xA7 */
-	{0x6A, 0xD2}, {0x6A, 0xD3}, {0x6A, 0xD4}, {0x6A, 0xD5}, /* 0xA8-0xAB */
+	{0x6A, 0xD2}, {0xF9, 0x31}, {0x6A, 0xD4}, {0x6A, 0xD5}, /* 0xA8-0xAB */
 	{0x6A, 0xD6}, {0x6A, 0xD7}, {0x6A, 0xD8}, {0x6A, 0xD9}, /* 0xAC-0xAF */
 	{0x6A, 0xDA}, {0x6A, 0xDB}, {0x6A, 0xDC}, {0x6A, 0xDD}, /* 0xB0-0xB3 */
 	{0x6A, 0xDE}, {0x6A, 0xDF}, {0x6A, 0xE0}, {0x6A, 0xE1}, /* 0xB4-0xB7 */
@@ -1699,7 +1701,7 @@
 	{0x6A, 0xF6}, {0x6A, 0xF7}, {0x6A, 0xF8}, {0x6A, 0xF9}, /* 0xCC-0xCF */
 	{0x6A, 0xFA}, {0x6A, 0xFB}, {0x6A, 0xFC}, {0x6A, 0xFD}, /* 0xD0-0xD3 */
 	{0x6A, 0xFE}, {0x6A, 0xFF}, {0x6B, 0x00}, {0x6B, 0x01}, /* 0xD4-0xD7 */
-	{0x6B, 0x02}, {0x6B, 0x03}, {0x6B, 0x04}, {0x6B, 0x05}, /* 0xD8-0xDB */
+	{0x6B, 0x02}, {0x6B, 0x03}, {0xF9, 0x1D}, {0x6B, 0x05}, /* 0xD8-0xDB */
 	{0x6B, 0x06}, {0x6B, 0x07}, {0x6B, 0x08}, {0x6B, 0x09}, /* 0xDC-0xDF */
 	{0x6B, 0x0A}, {0x6B, 0x0B}, {0x6B, 0x0C}, {0x6B, 0x0D}, /* 0xE0-0xE3 */
 	{0x6B, 0x0E}, {0x6B, 0x0F}, {0x6B, 0x10}, {0x6B, 0x11}, /* 0xE4-0xE7 */
@@ -1741,7 +1743,7 @@
 	{0x6B, 0x68}, {0x6B, 0x69}, {0x6B, 0x6B}, {0x6B, 0x6C}, /* 0x68-0x6B */
 	{0x6B, 0x6D}, {0x6B, 0x6E}, {0x6B, 0x6F}, {0x6B, 0x70}, /* 0x6C-0x6F */
 	{0x6B, 0x71}, {0x6B, 0x72}, {0x6B, 0x73}, {0x6B, 0x74}, /* 0x70-0x73 */
-	{0x6B, 0x75}, {0x6B, 0x76}, {0x6B, 0x77}, {0x6B, 0x78}, /* 0x74-0x77 */
+	{0x6B, 0x75}, {0x6B, 0x76}, {0xF9, 0x8C}, {0x6B, 0x78}, /* 0x74-0x77 */
 	{0x6B, 0x7A}, {0x6B, 0x7D}, {0x6B, 0x7E}, {0x6B, 0x7F}, /* 0x78-0x7B */
 	{0x6B, 0x80}, {0x6B, 0x85}, {0x6B, 0x88}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
@@ -1751,9 +1753,9 @@
 	{0x6B, 0x9E}, {0x6B, 0x9F}, {0x6B, 0xA0}, {0x6B, 0xA2}, /* 0x8C-0x8F */
 	{0x6B, 0xA3}, {0x6B, 0xA4}, {0x6B, 0xA5}, {0x6B, 0xA6}, /* 0x90-0x93 */
 	{0x6B, 0xA7}, {0x6B, 0xA8}, {0x6B, 0xA9}, {0x6B, 0xAB}, /* 0x94-0x97 */
-	{0x6B, 0xAC}, {0x6B, 0xAD}, {0x6B, 0xAE}, {0x6B, 0xAF}, /* 0x98-0x9B */
+	{0x6B, 0xAC}, {0x6B, 0xAD}, {0xF9, 0xA5}, {0x6B, 0xAF}, /* 0x98-0x9B */
 	{0x6B, 0xB0}, {0x6B, 0xB1}, {0x6B, 0xB2}, {0x6B, 0xB6}, /* 0x9C-0x9F */
-	{0x6B, 0xB8}, {0x6B, 0xB9}, {0x6B, 0xBA}, {0x6B, 0xBB}, /* 0xA0-0xA3 */
+	{0x6B, 0xB8}, {0x6B, 0xB9}, {0xF9, 0x70}, {0x6B, 0xBB}, /* 0xA0-0xA3 */
 	{0x6B, 0xBC}, {0x6B, 0xBD}, {0x6B, 0xBE}, {0x6B, 0xC0}, /* 0xA4-0xA7 */
 	{0x6B, 0xC3}, {0x6B, 0xC4}, {0x6B, 0xC6}, {0x6B, 0xC7}, /* 0xA8-0xAB */
 	{0x6B, 0xC8}, {0x6B, 0xC9}, {0x6B, 0xCA}, {0x6B, 0xCC}, /* 0xAC-0xAF */
@@ -1866,9 +1868,9 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x6D, 0xCD}, {0x6D, 0xCE}, {0x6D, 0xCF}, {0x6D, 0xD0}, /* 0x40-0x43 */
 	{0x6D, 0xD2}, {0x6D, 0xD3}, {0x6D, 0xD4}, {0x6D, 0xD5}, /* 0x44-0x47 */
-	{0x6D, 0xD7}, {0x6D, 0xDA}, {0x6D, 0xDB}, {0x6D, 0xDC}, /* 0x48-0x4B */
+	{0x6D, 0xD7}, {0xF9, 0x4D}, {0x6D, 0xDB}, {0x6D, 0xDC}, /* 0x48-0x4B */
 	{0x6D, 0xDF}, {0x6D, 0xE2}, {0x6D, 0xE3}, {0x6D, 0xE5}, /* 0x4C-0x4F */
-	{0x6D, 0xE7}, {0x6D, 0xE8}, {0x6D, 0xE9}, {0x6D, 0xEA}, /* 0x50-0x53 */
+	{0x6D, 0xE7}, {0x6D, 0xE8}, {0x6D, 0xE9}, {0xF9, 0xD6}, /* 0x50-0x53 */
 	{0x6D, 0xED}, {0x6D, 0xEF}, {0x6D, 0xF0}, {0x6D, 0xF2}, /* 0x54-0x57 */
 	{0x6D, 0xF4}, {0x6D, 0xF5}, {0x6D, 0xF6}, {0x6D, 0xF8}, /* 0x58-0x5B */
 	{0x6D, 0xFA}, {0x6D, 0xFD}, {0x6D, 0xFE}, {0x6D, 0xFF}, /* 0x5C-0x5F */
@@ -1942,7 +1944,7 @@
 	{0x6F, 0x12}, {0x6F, 0x16}, {0x6F, 0x17}, {0x6F, 0x18}, /* 0x5C-0x5F */
 	{0x6F, 0x19}, {0x6F, 0x1A}, {0x6F, 0x1B}, {0x6F, 0x1C}, /* 0x60-0x63 */
 	{0x6F, 0x1D}, {0x6F, 0x1E}, {0x6F, 0x1F}, {0x6F, 0x21}, /* 0x64-0x67 */
-	{0x6F, 0x22}, {0x6F, 0x23}, {0x6F, 0x25}, {0x6F, 0x26}, /* 0x68-0x6B */
+	{0x6F, 0x22}, {0xF9, 0x92}, {0x6F, 0x25}, {0x6F, 0x26}, /* 0x68-0x6B */
 	{0x6F, 0x27}, {0x6F, 0x28}, {0x6F, 0x2C}, {0x6F, 0x2E}, /* 0x6C-0x6F */
 	{0x6F, 0x30}, {0x6F, 0x32}, {0x6F, 0x34}, {0x6F, 0x35}, /* 0x70-0x73 */
 	{0x6F, 0x37}, {0x6F, 0x38}, {0x6F, 0x39}, {0x6F, 0x3A}, /* 0x74-0x77 */
@@ -2001,11 +2003,11 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x6F, 0xE6}, {0x6F, 0xE7}, {0x6F, 0xE8}, {0x6F, 0xE9}, /* 0x40-0x43 */
-	{0x6F, 0xEA}, {0x6F, 0xEB}, {0x6F, 0xEC}, {0x6F, 0xED}, /* 0x44-0x47 */
+	{0x6F, 0xEA}, {0xF9, 0x22}, {0x6F, 0xEC}, {0x6F, 0xED}, /* 0x44-0x47 */
 	{0x6F, 0xF0}, {0x6F, 0xF1}, {0x6F, 0xF2}, {0x6F, 0xF3}, /* 0x48-0x4B */
 	{0x6F, 0xF4}, {0x6F, 0xF5}, {0x6F, 0xF6}, {0x6F, 0xF7}, /* 0x4C-0x4F */
 	{0x6F, 0xF8}, {0x6F, 0xF9}, {0x6F, 0xFA}, {0x6F, 0xFB}, /* 0x50-0x53 */
-	{0x6F, 0xFC}, {0x6F, 0xFD}, {0x6F, 0xFE}, {0x6F, 0xFF}, /* 0x54-0x57 */
+	{0x6F, 0xFC}, {0x6F, 0xFD}, {0xF9, 0x84}, {0x6F, 0xFF}, /* 0x54-0x57 */
 	{0x70, 0x00}, {0x70, 0x01}, {0x70, 0x02}, {0x70, 0x03}, /* 0x58-0x5B */
 	{0x70, 0x04}, {0x70, 0x05}, {0x70, 0x06}, {0x70, 0x07}, /* 0x5C-0x5F */
 	{0x70, 0x08}, {0x70, 0x09}, {0x70, 0x0A}, {0x70, 0x0B}, /* 0x60-0x63 */
@@ -2089,7 +2091,7 @@
 	{0x71, 0x3A}, {0x71, 0x3B}, {0x71, 0x3C}, {0x71, 0x3D}, /* 0x84-0x87 */
 	{0x71, 0x3E}, {0x71, 0x3F}, {0x71, 0x40}, {0x71, 0x41}, /* 0x88-0x8B */
 	{0x71, 0x42}, {0x71, 0x43}, {0x71, 0x44}, {0x71, 0x46}, /* 0x8C-0x8F */
-	{0x71, 0x47}, {0x71, 0x48}, {0x71, 0x49}, {0x71, 0x4B}, /* 0x90-0x93 */
+	{0x71, 0x47}, {0x71, 0x48}, {0xF9, 0x93}, {0x71, 0x4B}, /* 0x90-0x93 */
 	{0x71, 0x4D}, {0x71, 0x4F}, {0x71, 0x50}, {0x71, 0x51}, /* 0x94-0x97 */
 	{0x71, 0x52}, {0x71, 0x53}, {0x71, 0x54}, {0x71, 0x55}, /* 0x98-0x9B */
 	{0x71, 0x56}, {0x71, 0x57}, {0x71, 0x58}, {0x71, 0x59}, /* 0x9C-0x9F */
@@ -2115,7 +2117,7 @@
 	{0x71, 0xBF}, {0x71, 0xC0}, {0x71, 0xC1}, {0x71, 0xC2}, /* 0xEC-0xEF */
 	{0x71, 0xC4}, {0x71, 0xC5}, {0x71, 0xC6}, {0x71, 0xC7}, /* 0xF0-0xF3 */
 	{0x71, 0xC8}, {0x71, 0xC9}, {0x71, 0xCA}, {0x71, 0xCB}, /* 0xF4-0xF7 */
-	{0x71, 0xCC}, {0x71, 0xCD}, {0x71, 0xCF}, {0x71, 0xD0}, /* 0xF8-0xFB */
+	{0x71, 0xCC}, {0x71, 0xCD}, {0x71, 0xCF}, {0xF9, 0xEE}, /* 0xF8-0xFB */
 	{0x71, 0xD1}, {0x71, 0xD2}, {0x71, 0xD3}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -2149,11 +2151,11 @@
 	{0x72, 0x03}, {0x72, 0x04}, {0x72, 0x05}, {0x72, 0x07}, /* 0x68-0x6B */
 	{0x72, 0x08}, {0x72, 0x09}, {0x72, 0x0A}, {0x72, 0x0B}, /* 0x6C-0x6F */
 	{0x72, 0x0C}, {0x72, 0x0D}, {0x72, 0x0E}, {0x72, 0x0F}, /* 0x70-0x73 */
-	{0x72, 0x10}, {0x72, 0x11}, {0x72, 0x12}, {0x72, 0x13}, /* 0x74-0x77 */
+	{0xF9, 0x32}, {0x72, 0x11}, {0x72, 0x12}, {0x72, 0x13}, /* 0x74-0x77 */
 	{0x72, 0x14}, {0x72, 0x15}, {0x72, 0x16}, {0x72, 0x17}, /* 0x78-0x7B */
 	{0x72, 0x18}, {0x72, 0x19}, {0x72, 0x1A}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
-	{0x72, 0x1B}, {0x72, 0x1C}, {0x72, 0x1E}, {0x72, 0x1F}, /* 0x80-0x83 */
+	{0xF9, 0x1E}, {0x72, 0x1C}, {0x72, 0x1E}, {0x72, 0x1F}, /* 0x80-0x83 */
 	{0x72, 0x20}, {0x72, 0x21}, {0x72, 0x22}, {0x72, 0x23}, /* 0x84-0x87 */
 	{0x72, 0x24}, {0x72, 0x25}, {0x72, 0x26}, {0x72, 0x27}, /* 0x88-0x8B */
 	{0x72, 0x29}, {0x72, 0x2B}, {0x72, 0x2D}, {0x72, 0x2E}, /* 0x8C-0x8F */
@@ -2180,7 +2182,7 @@
 	{0x72, 0xA9}, {0x72, 0xAA}, {0x72, 0xAB}, {0x72, 0xAE}, /* 0xE0-0xE3 */
 	{0x72, 0xB1}, {0x72, 0xB2}, {0x72, 0xB3}, {0x72, 0xB5}, /* 0xE4-0xE7 */
 	{0x72, 0xBA}, {0x72, 0xBB}, {0x72, 0xBC}, {0x72, 0xBD}, /* 0xE8-0xEB */
-	{0x72, 0xBE}, {0x72, 0xBF}, {0x72, 0xC0}, {0x72, 0xC5}, /* 0xEC-0xEF */
+	{0x72, 0xBE}, {0x72, 0xBF}, {0xF9, 0xFA}, {0x72, 0xC5}, /* 0xEC-0xEF */
 	{0x72, 0xC6}, {0x72, 0xC7}, {0x72, 0xC9}, {0x72, 0xCA}, /* 0xF0-0xF3 */
 	{0x72, 0xCB}, {0x72, 0xCC}, {0x72, 0xCF}, {0x72, 0xD1}, /* 0xF4-0xF7 */
 	{0x72, 0xD3}, {0x72, 0xD4}, {0x72, 0xD5}, {0x72, 0xD6}, /* 0xF8-0xFB */
@@ -2245,7 +2247,7 @@
 	{0x22, 0x61}, {0x22, 0x4C}, {0x22, 0x48}, {0x22, 0x3D}, /* 0xD4-0xD7 */
 	{0x22, 0x1D}, {0x22, 0x60}, {0x22, 0x6E}, {0x22, 0x6F}, /* 0xD8-0xDB */
 	{0x22, 0x64}, {0x22, 0x65}, {0x22, 0x1E}, {0x22, 0x35}, /* 0xDC-0xDF */
-	{0x22, 0x34}, {0x26, 0x42}, {0x26, 0x40}, {0x00, 0xB0}, /* 0xE0-0xE3 */
+	{0x22, 0x34}, {0x26, 0x42}, {0x26, 0x40}, {0x22, 0x18}, /* 0xE0-0xE3 */
 	{0x20, 0x32}, {0x20, 0x33}, {0x21, 0x03}, {0xFF, 0x04}, /* 0xE4-0xE7 */
 	{0x00, 0xA4}, {0xFF, 0xE0}, {0xFF, 0xE1}, {0x20, 0x30}, /* 0xE8-0xEB */
 	{0x00, 0xA7}, {0x21, 0x16}, {0x26, 0x06}, {0x26, 0x05}, /* 0xEC-0xEF */
@@ -2884,7 +2886,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x73, 0x72}, {0x73, 0x73}, {0x73, 0x74}, {0x73, 0x75}, /* 0x40-0x43 */
+	{0x73, 0x72}, {0x73, 0x73}, {0x73, 0x74}, {0xF9, 0xA7}, /* 0x40-0x43 */
 	{0x73, 0x76}, {0x73, 0x77}, {0x73, 0x78}, {0x73, 0x79}, /* 0x44-0x47 */
 	{0x73, 0x7A}, {0x73, 0x7B}, {0x73, 0x7C}, {0x73, 0x7D}, /* 0x48-0x4B */
 	{0x73, 0x7F}, {0x73, 0x80}, {0x73, 0x81}, {0x73, 0x82}, /* 0x4C-0x4F */
@@ -2973,7 +2975,7 @@
 	{0x74, 0x52}, {0x74, 0x53}, {0x74, 0x54}, {0x74, 0x56}, /* 0x84-0x87 */
 	{0x74, 0x58}, {0x74, 0x5D}, {0x74, 0x60}, {0x74, 0x61}, /* 0x88-0x8B */
 	{0x74, 0x62}, {0x74, 0x63}, {0x74, 0x64}, {0x74, 0x65}, /* 0x8C-0x8F */
-	{0x74, 0x66}, {0x74, 0x67}, {0x74, 0x68}, {0x74, 0x69}, /* 0x90-0x93 */
+	{0x74, 0x66}, {0x74, 0x67}, {0x74, 0x68}, {0xF9, 0xAE}, /* 0x90-0x93 */
 	{0x74, 0x6A}, {0x74, 0x6B}, {0x74, 0x6C}, {0x74, 0x6E}, /* 0x94-0x97 */
 	{0x74, 0x6F}, {0x74, 0x71}, {0x74, 0x72}, {0x74, 0x73}, /* 0x98-0x9B */
 	{0x74, 0x74}, {0x74, 0x75}, {0x74, 0x78}, {0x74, 0x79}, /* 0x9C-0x9F */
@@ -3022,10 +3024,10 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x74, 0x7B}, {0x74, 0x7C}, {0x74, 0x7D}, {0x74, 0x7F}, /* 0x40-0x43 */
 	{0x74, 0x82}, {0x74, 0x84}, {0x74, 0x85}, {0x74, 0x86}, /* 0x44-0x47 */
-	{0x74, 0x88}, {0x74, 0x89}, {0x74, 0x8A}, {0x74, 0x8C}, /* 0x48-0x4B */
+	{0x74, 0x88}, {0xF9, 0x94}, {0x74, 0x8A}, {0x74, 0x8C}, /* 0x48-0x4B */
 	{0x74, 0x8D}, {0x74, 0x8F}, {0x74, 0x91}, {0x74, 0x92}, /* 0x4C-0x4F */
 	{0x74, 0x93}, {0x74, 0x94}, {0x74, 0x95}, {0x74, 0x96}, /* 0x50-0x53 */
-	{0x74, 0x97}, {0x74, 0x98}, {0x74, 0x99}, {0x74, 0x9A}, /* 0x54-0x57 */
+	{0x74, 0x97}, {0xF9, 0xEF}, {0x74, 0x99}, {0x74, 0x9A}, /* 0x54-0x57 */
 	{0x74, 0x9B}, {0x74, 0x9D}, {0x74, 0x9F}, {0x74, 0xA0}, /* 0x58-0x5B */
 	{0x74, 0xA1}, {0x74, 0xA2}, {0x74, 0xA3}, {0x74, 0xA4}, /* 0x5C-0x5F */
 	{0x74, 0xA5}, {0x74, 0xA6}, {0x74, 0xAA}, {0x74, 0xAB}, /* 0x60-0x63 */
@@ -3109,7 +3111,7 @@
 	{0x75, 0x61}, {0x75, 0x62}, {0x75, 0x63}, {0x75, 0x64}, /* 0x84-0x87 */
 	{0x75, 0x67}, {0x75, 0x68}, {0x75, 0x69}, {0x75, 0x6B}, /* 0x88-0x8B */
 	{0x75, 0x6C}, {0x75, 0x6D}, {0x75, 0x6E}, {0x75, 0x6F}, /* 0x8C-0x8F */
-	{0x75, 0x70}, {0x75, 0x71}, {0x75, 0x73}, {0x75, 0x75}, /* 0x90-0x93 */
+	{0xF9, 0x62}, {0x75, 0x71}, {0x75, 0x73}, {0x75, 0x75}, /* 0x90-0x93 */
 	{0x75, 0x76}, {0x75, 0x77}, {0x75, 0x7A}, {0x75, 0x7B}, /* 0x94-0x97 */
 	{0x75, 0x7C}, {0x75, 0x7D}, {0x75, 0x7E}, {0x75, 0x80}, /* 0x98-0x9B */
 	{0x75, 0x81}, {0x75, 0x82}, {0x75, 0x84}, {0x75, 0x85}, /* 0x9C-0x9F */
@@ -3180,7 +3182,7 @@
 	{0x76, 0x23}, {0x76, 0x27}, {0x76, 0x28}, {0x76, 0x2C}, /* 0x90-0x93 */
 	{0x76, 0x2E}, {0x76, 0x2F}, {0x76, 0x31}, {0x76, 0x32}, /* 0x94-0x97 */
 	{0x76, 0x36}, {0x76, 0x37}, {0x76, 0x39}, {0x76, 0x3A}, /* 0x98-0x9B */
-	{0x76, 0x3B}, {0x76, 0x3D}, {0x76, 0x41}, {0x76, 0x42}, /* 0x9C-0x9F */
+	{0x76, 0x3B}, {0x76, 0x3D}, {0x76, 0x41}, {0xF9, 0xC1}, /* 0x9C-0x9F */
 	{0x76, 0x44}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA0-0xA3 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA4-0xA7 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA8-0xAB */
@@ -3231,7 +3233,7 @@
 	{0x76, 0x59}, {0x76, 0x5A}, {0x76, 0x5B}, {0x76, 0x5D}, /* 0x50-0x53 */
 	{0x76, 0x5F}, {0x76, 0x60}, {0x76, 0x61}, {0x76, 0x62}, /* 0x54-0x57 */
 	{0x76, 0x64}, {0x76, 0x65}, {0x76, 0x66}, {0x76, 0x67}, /* 0x58-0x5B */
-	{0x76, 0x68}, {0x76, 0x69}, {0x76, 0x6A}, {0x76, 0x6C}, /* 0x5C-0x5F */
+	{0x76, 0x68}, {0xF9, 0x0E}, {0x76, 0x6A}, {0x76, 0x6C}, /* 0x5C-0x5F */
 	{0x76, 0x6D}, {0x76, 0x6E}, {0x76, 0x70}, {0x76, 0x71}, /* 0x60-0x63 */
 	{0x76, 0x72}, {0x76, 0x73}, {0x76, 0x74}, {0x76, 0x75}, /* 0x64-0x67 */
 	{0x76, 0x76}, {0x76, 0x77}, {0x76, 0x79}, {0x76, 0x7A}, /* 0x68-0x6B */
@@ -3296,7 +3298,7 @@
 	{0x76, 0xCC}, {0x76, 0xD3}, {0x76, 0xD5}, {0x76, 0xD9}, /* 0x44-0x47 */
 	{0x76, 0xDA}, {0x76, 0xDC}, {0x76, 0xDD}, {0x76, 0xDE}, /* 0x48-0x4B */
 	{0x76, 0xE0}, {0x76, 0xE1}, {0x76, 0xE2}, {0x76, 0xE3}, /* 0x4C-0x4F */
-	{0x76, 0xE4}, {0x76, 0xE6}, {0x76, 0xE7}, {0x76, 0xE8}, /* 0x50-0x53 */
+	{0x76, 0xE4}, {0x76, 0xE6}, {0xF9, 0x33}, {0x76, 0xE8}, /* 0x50-0x53 */
 	{0x76, 0xE9}, {0x76, 0xEA}, {0x76, 0xEB}, {0x76, 0xEC}, /* 0x54-0x57 */
 	{0x76, 0xED}, {0x76, 0xF0}, {0x76, 0xF3}, {0x76, 0xF5}, /* 0x58-0x5B */
 	{0x76, 0xF6}, {0x76, 0xF7}, {0x76, 0xFA}, {0x76, 0xFB}, /* 0x5C-0x5F */
@@ -3319,9 +3321,9 @@
 	{0x77, 0x56}, {0x77, 0x57}, {0x77, 0x58}, {0x77, 0x59}, /* 0x9C-0x9F */
 	{0x77, 0x5C}, {0x85, 0x84}, {0x96, 0xF9}, {0x4F, 0xDD}, /* 0xA0-0xA3 */
 	{0x58, 0x21}, {0x99, 0x71}, {0x5B, 0x9D}, {0x62, 0xB1}, /* 0xA4-0xA7 */
-	{0x62, 0xA5}, {0x66, 0xB4}, {0x8C, 0x79}, {0x9C, 0x8D}, /* 0xA8-0xAB */
+	{0x62, 0xA5}, {0xFA, 0x06}, {0x8C, 0x79}, {0x9C, 0x8D}, /* 0xA8-0xAB */
 	{0x72, 0x06}, {0x67, 0x6F}, {0x78, 0x91}, {0x60, 0xB2}, /* 0xAC-0xAF */
-	{0x53, 0x51}, {0x53, 0x17}, {0x8F, 0x88}, {0x80, 0xCC}, /* 0xB0-0xB3 */
+	{0x53, 0x51}, {0xF9, 0x63}, {0x8F, 0x88}, {0x80, 0xCC}, /* 0xB0-0xB3 */
 	{0x8D, 0x1D}, {0x94, 0xA1}, {0x50, 0x0D}, {0x72, 0xC8}, /* 0xB4-0xB7 */
 	{0x59, 0x07}, {0x60, 0xEB}, {0x71, 0x19}, {0x88, 0xAB}, /* 0xB8-0xBB */
 	{0x59, 0x54}, {0x82, 0xEF}, {0x67, 0x2C}, {0x7B, 0x28}, /* 0xBC-0xBF */
@@ -3333,7 +3335,7 @@
 	{0x75, 0xF9}, {0x95, 0xED}, {0x65, 0x5D}, {0x5F, 0x0A}, /* 0xD4-0xD7 */
 	{0x5F, 0xC5}, {0x8F, 0x9F}, {0x58, 0xC1}, {0x81, 0xC2}, /* 0xD8-0xDB */
 	{0x90, 0x7F}, {0x96, 0x5B}, {0x97, 0xAD}, {0x8F, 0xB9}, /* 0xDC-0xDF */
-	{0x7F, 0x16}, {0x8D, 0x2C}, {0x62, 0x41}, {0x4F, 0xBF}, /* 0xE0-0xE3 */
+	{0x7F, 0x16}, {0x8D, 0x2C}, {0x62, 0x41}, {0xF9, 0x65}, /* 0xE0-0xE3 */
 	{0x53, 0xD8}, {0x53, 0x5E}, {0x8F, 0xA8}, {0x8F, 0xA9}, /* 0xE4-0xE7 */
 	{0x8F, 0xAB}, {0x90, 0x4D}, {0x68, 0x07}, {0x5F, 0x6A}, /* 0xE8-0xEB */
 	{0x81, 0x98}, {0x88, 0x68}, {0x9C, 0xD6}, {0x61, 0x8B}, /* 0xEC-0xEF */
@@ -3391,7 +3393,7 @@
 	{0x94, 0xC2}, {0x7B, 0x94}, {0x4F, 0x2F}, {0x5E, 0x1B}, /* 0xAC-0xAF */
 	{0x82, 0x36}, {0x81, 0x16}, {0x81, 0x8A}, {0x6E, 0x24}, /* 0xB0-0xB3 */
 	{0x6C, 0xCA}, {0x9A, 0x73}, {0x63, 0x55}, {0x53, 0x5C}, /* 0xB4-0xB7 */
-	{0x54, 0xFA}, {0x88, 0x65}, {0x57, 0xE0}, {0x4E, 0x0D}, /* 0xB8-0xBB */
+	{0x54, 0xFA}, {0x88, 0x65}, {0x57, 0xE0}, {0xF9, 0x67}, /* 0xB8-0xBB */
 	{0x5E, 0x03}, {0x6B, 0x65}, {0x7C, 0x3F}, {0x90, 0xE8}, /* 0xBC-0xBF */
 	{0x60, 0x16}, {0x64, 0xE6}, {0x73, 0x1C}, {0x88, 0xC1}, /* 0xC0-0xC3 */
 	{0x67, 0x50}, {0x62, 0x4D}, {0x8D, 0x22}, {0x77, 0x6C}, /* 0xC4-0xC7 */
@@ -3403,7 +3405,7 @@
 	{0x66, 0xF9}, {0x83, 0x49}, {0x53, 0x95}, {0x7B, 0x56}, /* 0xDC-0xDF */
 	{0x4F, 0xA7}, {0x51, 0x8C}, {0x6D, 0x4B}, {0x5C, 0x42}, /* 0xE0-0xE3 */
 	{0x8E, 0x6D}, {0x63, 0xD2}, {0x53, 0xC9}, {0x83, 0x2C}, /* 0xE4-0xE7 */
-	{0x83, 0x36}, {0x67, 0xE5}, {0x78, 0xB4}, {0x64, 0x3D}, /* 0xE8-0xEB */
+	{0xF9, 0xFE}, {0x67, 0xE5}, {0x78, 0xB4}, {0x64, 0x3D}, /* 0xE8-0xEB */
 	{0x5B, 0xDF}, {0x5C, 0x94}, {0x5D, 0xEE}, {0x8B, 0xE7}, /* 0xEC-0xEF */
 	{0x62, 0xC6}, {0x67, 0xF4}, {0x8C, 0x7A}, {0x64, 0x00}, /* 0xF0-0xF3 */
 	{0x63, 0xBA}, {0x87, 0x49}, {0x99, 0x8B}, {0x8C, 0x17}, /* 0xF4-0xF7 */
@@ -3460,7 +3462,7 @@
 	{0x56, 0x32}, {0x6F, 0x6E}, {0x5D, 0xE2}, {0x54, 0x35}, /* 0xB0-0xB3 */
 	{0x70, 0x92}, {0x8F, 0x66}, {0x62, 0x6F}, {0x64, 0xA4}, /* 0xB4-0xB7 */
 	{0x63, 0xA3}, {0x5F, 0x7B}, {0x6F, 0x88}, {0x90, 0xF4}, /* 0xB8-0xBB */
-	{0x81, 0xE3}, {0x8F, 0xB0}, {0x5C, 0x18}, {0x66, 0x68}, /* 0xBC-0xBF */
+	{0x81, 0xE3}, {0xF9, 0x71}, {0x5C, 0x18}, {0x66, 0x68}, /* 0xBC-0xBF */
 	{0x5F, 0xF1}, {0x6C, 0x89}, {0x96, 0x48}, {0x8D, 0x81}, /* 0xC0-0xC3 */
 	{0x88, 0x6C}, {0x64, 0x91}, {0x79, 0xF0}, {0x57, 0xCE}, /* 0xC4-0xC7 */
 	{0x6A, 0x59}, {0x62, 0x10}, {0x54, 0x48}, {0x4E, 0x58}, /* 0xC8-0xCB */
@@ -3517,14 +3519,14 @@
 	{0x78, 0xE9}, {0x78, 0xEA}, {0x78, 0xEB}, {0x78, 0xED}, /* 0x84-0x87 */
 	{0x78, 0xEE}, {0x78, 0xEF}, {0x78, 0xF0}, {0x78, 0xF1}, /* 0x88-0x8B */
 	{0x78, 0xF3}, {0x78, 0xF5}, {0x78, 0xF6}, {0x78, 0xF8}, /* 0x8C-0x8F */
-	{0x78, 0xF9}, {0x78, 0xFB}, {0x78, 0xFC}, {0x78, 0xFD}, /* 0x90-0x93 */
+	{0x78, 0xF9}, {0xF9, 0x64}, {0x78, 0xFC}, {0x78, 0xFD}, /* 0x90-0x93 */
 	{0x78, 0xFE}, {0x78, 0xFF}, {0x79, 0x00}, {0x79, 0x02}, /* 0x94-0x97 */
 	{0x79, 0x03}, {0x79, 0x04}, {0x79, 0x06}, {0x79, 0x07}, /* 0x98-0x9B */
 	{0x79, 0x08}, {0x79, 0x09}, {0x79, 0x0A}, {0x79, 0x0B}, /* 0x9C-0x9F */
 	{0x79, 0x0C}, {0x78, 0x40}, {0x50, 0xA8}, {0x77, 0xD7}, /* 0xA0-0xA3 */
 	{0x64, 0x10}, {0x89, 0xE6}, {0x59, 0x04}, {0x63, 0xE3}, /* 0xA4-0xA7 */
 	{0x5D, 0xDD}, {0x7A, 0x7F}, {0x69, 0x3D}, {0x4F, 0x20}, /* 0xA8-0xAB */
-	{0x82, 0x39}, {0x55, 0x98}, {0x4E, 0x32}, {0x75, 0xAE}, /* 0xAC-0xAF */
+	{0x82, 0x39}, {0x55, 0x98}, {0xF9, 0x05}, {0x75, 0xAE}, /* 0xAC-0xAF */
 	{0x7A, 0x97}, {0x5E, 0x62}, {0x5E, 0x8A}, {0x95, 0xEF}, /* 0xB0-0xB3 */
 	{0x52, 0x1B}, {0x54, 0x39}, {0x70, 0x8A}, {0x63, 0x76}, /* 0xB4-0xB7 */
 	{0x95, 0x24}, {0x57, 0x82}, {0x66, 0x25}, {0x69, 0x3F}, /* 0xB8-0xBB */
@@ -3532,7 +3534,7 @@
 	{0x88, 0x22}, {0x62, 0x33}, {0x7E, 0xF0}, {0x75, 0xB5}, /* 0xC0-0xC3 */
 	{0x83, 0x28}, {0x78, 0xC1}, {0x96, 0xCC}, {0x8F, 0x9E}, /* 0xC4-0xC7 */
 	{0x61, 0x48}, {0x74, 0xF7}, {0x8B, 0xCD}, {0x6B, 0x64}, /* 0xC8-0xCB */
-	{0x52, 0x3A}, {0x8D, 0x50}, {0x6B, 0x21}, {0x80, 0x6A}, /* 0xCC-0xCF */
+	{0xF9, 0xFF}, {0x8D, 0x50}, {0x6B, 0x21}, {0x80, 0x6A}, /* 0xCC-0xCF */
 	{0x84, 0x71}, {0x56, 0xF1}, {0x53, 0x06}, {0x4E, 0xCE}, /* 0xD0-0xD3 */
 	{0x4E, 0x1B}, {0x51, 0xD1}, {0x7C, 0x97}, {0x91, 0x8B}, /* 0xD4-0xD7 */
 	{0x7C, 0x07}, {0x4F, 0xC3}, {0x8E, 0x7F}, {0x7B, 0xE1}, /* 0xD8-0xDB */
@@ -3570,7 +3572,7 @@
 	{0x79, 0x1A}, {0x79, 0x1B}, {0x79, 0x1C}, {0x79, 0x1D}, /* 0x4C-0x4F */
 	{0x79, 0x1F}, {0x79, 0x20}, {0x79, 0x21}, {0x79, 0x22}, /* 0x50-0x53 */
 	{0x79, 0x23}, {0x79, 0x25}, {0x79, 0x26}, {0x79, 0x27}, /* 0x54-0x57 */
-	{0x79, 0x28}, {0x79, 0x29}, {0x79, 0x2A}, {0x79, 0x2B}, /* 0x58-0x5B */
+	{0x79, 0x28}, {0x79, 0x29}, {0xF9, 0x85}, {0x79, 0x2B}, /* 0x58-0x5B */
 	{0x79, 0x2C}, {0x79, 0x2D}, {0x79, 0x2E}, {0x79, 0x2F}, /* 0x5C-0x5F */
 	{0x79, 0x30}, {0x79, 0x31}, {0x79, 0x32}, {0x79, 0x33}, /* 0x60-0x63 */
 	{0x79, 0x35}, {0x79, 0x36}, {0x79, 0x37}, {0x79, 0x38}, /* 0x64-0x67 */
@@ -3585,12 +3587,12 @@
 	{0x79, 0x6B}, {0x79, 0x6C}, {0x79, 0x6E}, {0x79, 0x70}, /* 0x84-0x87 */
 	{0x79, 0x71}, {0x79, 0x72}, {0x79, 0x73}, {0x79, 0x74}, /* 0x88-0x8B */
 	{0x79, 0x75}, {0x79, 0x76}, {0x79, 0x79}, {0x79, 0x7B}, /* 0x8C-0x8F */
-	{0x79, 0x7C}, {0x79, 0x7D}, {0x79, 0x7E}, {0x79, 0x7F}, /* 0x90-0x93 */
+	{0x79, 0x7C}, {0x79, 0x7D}, {0x79, 0x7E}, {0xF9, 0x3C}, /* 0x90-0x93 */
 	{0x79, 0x82}, {0x79, 0x83}, {0x79, 0x86}, {0x79, 0x87}, /* 0x94-0x97 */
 	{0x79, 0x88}, {0x79, 0x89}, {0x79, 0x8B}, {0x79, 0x8C}, /* 0x98-0x9B */
 	{0x79, 0x8D}, {0x79, 0x8E}, {0x79, 0x90}, {0x79, 0x91}, /* 0x9C-0x9F */
 	{0x79, 0x92}, {0x60, 0x20}, {0x80, 0x3D}, {0x62, 0xC5}, /* 0xA0-0xA3 */
-	{0x4E, 0x39}, {0x53, 0x55}, {0x90, 0xF8}, {0x63, 0xB8}, /* 0xA4-0xA7 */
+	{0xF9, 0x5E}, {0x53, 0x55}, {0x90, 0xF8}, {0x63, 0xB8}, /* 0xA4-0xA7 */
 	{0x80, 0xC6}, {0x65, 0xE6}, {0x6C, 0x2E}, {0x4F, 0x46}, /* 0xA8-0xAB */
 	{0x60, 0xEE}, {0x6D, 0xE1}, {0x8B, 0xDE}, {0x5F, 0x39}, /* 0xAC-0xAF */
 	{0x86, 0xCB}, {0x5F, 0x53}, {0x63, 0x21}, {0x51, 0x5A}, /* 0xB0-0xB3 */
@@ -3638,7 +3640,7 @@
 	{0x79, 0xA0}, {0x79, 0xA1}, {0x79, 0xA2}, {0x79, 0xA3}, /* 0x4C-0x4F */
 	{0x79, 0xA4}, {0x79, 0xA5}, {0x79, 0xA6}, {0x79, 0xA8}, /* 0x50-0x53 */
 	{0x79, 0xA9}, {0x79, 0xAA}, {0x79, 0xAB}, {0x79, 0xAC}, /* 0x54-0x57 */
-	{0x79, 0xAD}, {0x79, 0xAE}, {0x79, 0xAF}, {0x79, 0xB0}, /* 0x58-0x5B */
+	{0x79, 0xAD}, {0xF9, 0xB6}, {0x79, 0xAF}, {0x79, 0xB0}, /* 0x58-0x5B */
 	{0x79, 0xB1}, {0x79, 0xB2}, {0x79, 0xB4}, {0x79, 0xB5}, /* 0x5C-0x5F */
 	{0x79, 0xB6}, {0x79, 0xB7}, {0x79, 0xB8}, {0x79, 0xBC}, /* 0x60-0x63 */
 	{0x79, 0xBF}, {0x79, 0xC2}, {0x79, 0xC4}, {0x79, 0xC5}, /* 0x64-0x67 */
@@ -3657,17 +3659,17 @@
 	{0x7A, 0x0A}, {0x7A, 0x0C}, {0x7A, 0x0F}, {0x7A, 0x10}, /* 0x94-0x97 */
 	{0x7A, 0x11}, {0x7A, 0x12}, {0x7A, 0x13}, {0x7A, 0x15}, /* 0x98-0x9B */
 	{0x7A, 0x16}, {0x7A, 0x18}, {0x7A, 0x19}, {0x7A, 0x1B}, /* 0x9C-0x9F */
-	{0x7A, 0x1C}, {0x4E, 0x01}, {0x76, 0xEF}, {0x53, 0xEE}, /* 0xA0-0xA3 */
+	{0xF9, 0x56}, {0x4E, 0x01}, {0x76, 0xEF}, {0x53, 0xEE}, /* 0xA0-0xA3 */
 	{0x94, 0x89}, {0x98, 0x76}, {0x9F, 0x0E}, {0x95, 0x2D}, /* 0xA4-0xA7 */
 	{0x5B, 0x9A}, {0x8B, 0xA2}, {0x4E, 0x22}, {0x4E, 0x1C}, /* 0xA8-0xAB */
 	{0x51, 0xAC}, {0x84, 0x63}, {0x61, 0xC2}, {0x52, 0xA8}, /* 0xAC-0xAF */
 	{0x68, 0x0B}, {0x4F, 0x97}, {0x60, 0x6B}, {0x51, 0xBB}, /* 0xB0-0xB3 */
-	{0x6D, 0x1E}, {0x51, 0x5C}, {0x62, 0x96}, {0x65, 0x97}, /* 0xB4-0xB7 */
+	{0xFA, 0x05}, {0x51, 0x5C}, {0x62, 0x96}, {0x65, 0x97}, /* 0xB4-0xB7 */
 	{0x96, 0x61}, {0x8C, 0x46}, {0x90, 0x17}, {0x75, 0xD8}, /* 0xB8-0xBB */
-	{0x90, 0xFD}, {0x77, 0x63}, {0x6B, 0xD2}, {0x72, 0x8A}, /* 0xBC-0xBF */
+	{0xFA, 0x26}, {0x77, 0x63}, {0x6B, 0xD2}, {0x72, 0x8A}, /* 0xBC-0xBF */
 	{0x72, 0xEC}, {0x8B, 0xFB}, {0x58, 0x35}, {0x77, 0x79}, /* 0xC0-0xC3 */
 	{0x8D, 0x4C}, {0x67, 0x5C}, {0x95, 0x40}, {0x80, 0x9A}, /* 0xC4-0xC7 */
-	{0x5E, 0xA6}, {0x6E, 0x21}, {0x59, 0x92}, {0x7A, 0xEF}, /* 0xC8-0xCB */
+	{0xFA, 0x01}, {0x6E, 0x21}, {0x59, 0x92}, {0x7A, 0xEF}, /* 0xC8-0xCB */
 	{0x77, 0xED}, {0x95, 0x3B}, {0x6B, 0xB5}, {0x65, 0xAD}, /* 0xCC-0xCF */
 	{0x7F, 0x0E}, {0x58, 0x06}, {0x51, 0x51}, {0x96, 0x1F}, /* 0xD0-0xD3 */
 	{0x5B, 0xF9}, {0x58, 0xA9}, {0x54, 0x28}, {0x8E, 0x72}, /* 0xD4-0xD7 */
@@ -3793,7 +3795,7 @@
 	{0x7B, 0x16}, {0x7B, 0x17}, {0x7B, 0x18}, {0x7B, 0x1A}, /* 0x94-0x97 */
 	{0x7B, 0x1C}, {0x7B, 0x1D}, {0x7B, 0x1F}, {0x7B, 0x21}, /* 0x98-0x9B */
 	{0x7B, 0x22}, {0x7B, 0x23}, {0x7B, 0x27}, {0x7B, 0x29}, /* 0x9C-0x9F */
-	{0x7B, 0x2D}, {0x6D, 0x6E}, {0x6D, 0xAA}, {0x79, 0x8F}, /* 0xA0-0xA3 */
+	{0x7B, 0x2D}, {0x6D, 0x6E}, {0x6D, 0xAA}, {0xFA, 0x1B}, /* 0xA0-0xA3 */
 	{0x88, 0xB1}, {0x5F, 0x17}, {0x75, 0x2B}, {0x62, 0x9A}, /* 0xA4-0xA7 */
 	{0x8F, 0x85}, {0x4F, 0xEF}, {0x91, 0xDC}, {0x65, 0xA7}, /* 0xA8-0xAB */
 	{0x81, 0x2F}, {0x81, 0x51}, {0x5E, 0x9C}, {0x81, 0x50}, /* 0xAC-0xAF */
@@ -3816,7 +3818,7 @@
 	{0x84, 0x5B}, {0x68, 0x3C}, {0x86, 0xE4}, {0x96, 0x01}, /* 0xF0-0xF3 */
 	{0x96, 0x94}, {0x94, 0xEC}, {0x4E, 0x2A}, {0x54, 0x04}, /* 0xF4-0xF7 */
 	{0x7E, 0xD9}, {0x68, 0x39}, {0x8D, 0xDF}, {0x80, 0x15}, /* 0xF8-0xFB */
-	{0x66, 0xF4}, {0x5E, 0x9A}, {0x7F, 0xB9}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0xF9, 0x01}, {0x5E, 0x9A}, {0x7F, 0xB9}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_B9[256] = {
@@ -3928,7 +3930,7 @@
 	{0x7C, 0x2E}, {0x7C, 0x2F}, {0x7C, 0x30}, {0x7C, 0x31}, /* 0x90-0x93 */
 	{0x7C, 0x32}, {0x7C, 0x33}, {0x7C, 0x34}, {0x7C, 0x35}, /* 0x94-0x97 */
 	{0x7C, 0x36}, {0x7C, 0x37}, {0x7C, 0x39}, {0x7C, 0x3A}, /* 0x98-0x9B */
-	{0x7C, 0x3B}, {0x7C, 0x3C}, {0x7C, 0x3D}, {0x7C, 0x3E}, /* 0x9C-0x9F */
+	{0x7C, 0x3B}, {0x7C, 0x3C}, {0x7C, 0x3D}, {0xF9, 0xA6}, /* 0x9C-0x9F */
 	{0x7C, 0x42}, {0x9A, 0xB8}, {0x5B, 0x69}, {0x6D, 0x77}, /* 0xA0-0xA3 */
 	{0x6C, 0x26}, {0x4E, 0xA5}, {0x5B, 0xB3}, {0x9A, 0x87}, /* 0xA4-0xA7 */
 	{0x91, 0x63}, {0x61, 0xA8}, {0x90, 0xAF}, {0x97, 0xE9}, /* 0xA8-0xAB */
@@ -3979,7 +3981,7 @@
 	{0x7C, 0x54}, {0x7C, 0x55}, {0x7C, 0x56}, {0x7C, 0x57}, /* 0x50-0x53 */
 	{0x7C, 0x58}, {0x7C, 0x59}, {0x7C, 0x5A}, {0x7C, 0x5B}, /* 0x54-0x57 */
 	{0x7C, 0x5C}, {0x7C, 0x5D}, {0x7C, 0x5E}, {0x7C, 0x5F}, /* 0x58-0x5B */
-	{0x7C, 0x60}, {0x7C, 0x61}, {0x7C, 0x62}, {0x7C, 0x63}, /* 0x5C-0x5F */
+	{0xF9, 0x44}, {0x7C, 0x61}, {0x7C, 0x62}, {0x7C, 0x63}, /* 0x5C-0x5F */
 	{0x7C, 0x64}, {0x7C, 0x65}, {0x7C, 0x66}, {0x7C, 0x67}, /* 0x60-0x63 */
 	{0x7C, 0x68}, {0x7C, 0x69}, {0x7C, 0x6A}, {0x7C, 0x6B}, /* 0x64-0x67 */
 	{0x7C, 0x6C}, {0x7C, 0x6D}, {0x7C, 0x6E}, {0x7C, 0x6F}, /* 0x68-0x6B */
@@ -4000,7 +4002,7 @@
 	{0x7C, 0xBB}, {0x5F, 0x27}, {0x86, 0x4E}, {0x55, 0x2C}, /* 0xA0-0xA3 */
 	{0x62, 0xA4}, {0x4E, 0x92}, {0x6C, 0xAA}, {0x62, 0x37}, /* 0xA4-0xA7 */
 	{0x82, 0xB1}, {0x54, 0xD7}, {0x53, 0x4E}, {0x73, 0x3E}, /* 0xA8-0xAB */
-	{0x6E, 0xD1}, {0x75, 0x3B}, {0x52, 0x12}, {0x53, 0x16}, /* 0xAC-0xAF */
+	{0xF9, 0x04}, {0x75, 0x3B}, {0x52, 0x12}, {0x53, 0x16}, /* 0xAC-0xAF */
 	{0x8B, 0xDD}, {0x69, 0xD0}, {0x5F, 0x8A}, {0x60, 0x00}, /* 0xB0-0xB3 */
 	{0x6D, 0xEE}, {0x57, 0x4F}, {0x6B, 0x22}, {0x73, 0xAF}, /* 0xB4-0xB7 */
 	{0x68, 0x53}, {0x8F, 0xD8}, {0x7F, 0x13}, {0x63, 0x62}, /* 0xB8-0xBB */
@@ -4046,7 +4048,7 @@
 	{0x7C, 0xD2}, {0x7C, 0xD3}, {0x7C, 0xD4}, {0x7C, 0xD8}, /* 0x4C-0x4F */
 	{0x7C, 0xDA}, {0x7C, 0xDB}, {0x7C, 0xDD}, {0x7C, 0xDE}, /* 0x50-0x53 */
 	{0x7C, 0xE1}, {0x7C, 0xE2}, {0x7C, 0xE3}, {0x7C, 0xE4}, /* 0x54-0x57 */
-	{0x7C, 0xE5}, {0x7C, 0xE6}, {0x7C, 0xE7}, {0x7C, 0xE9}, /* 0x58-0x5B */
+	{0x7C, 0xE5}, {0x7C, 0xE6}, {0xF9, 0x7B}, {0x7C, 0xE9}, /* 0x58-0x5B */
 	{0x7C, 0xEA}, {0x7C, 0xEB}, {0x7C, 0xEC}, {0x7C, 0xED}, /* 0x5C-0x5F */
 	{0x7C, 0xEE}, {0x7C, 0xF0}, {0x7C, 0xF1}, {0x7C, 0xF2}, /* 0x60-0x63 */
 	{0x7C, 0xF3}, {0x7C, 0xF4}, {0x7C, 0xF5}, {0x7C, 0xF6}, /* 0x64-0x67 */
@@ -4055,7 +4057,7 @@
 	{0x7D, 0x01}, {0x7D, 0x02}, {0x7D, 0x03}, {0x7D, 0x04}, /* 0x70-0x73 */
 	{0x7D, 0x05}, {0x7D, 0x06}, {0x7D, 0x07}, {0x7D, 0x08}, /* 0x74-0x77 */
 	{0x7D, 0x09}, {0x7D, 0x0B}, {0x7D, 0x0C}, {0x7D, 0x0D}, /* 0x78-0x7B */
-	{0x7D, 0x0E}, {0x7D, 0x0F}, {0x7D, 0x10}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x7D, 0x0E}, {0x7D, 0x0F}, {0xF9, 0xCF}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x7D, 0x11}, {0x7D, 0x12}, {0x7D, 0x13}, {0x7D, 0x14}, /* 0x80-0x83 */
 	{0x7D, 0x15}, {0x7D, 0x16}, {0x7D, 0x17}, {0x7D, 0x18}, /* 0x84-0x87 */
@@ -4138,7 +4140,7 @@
 	{0x5E, 0xFA}, {0x50, 0xF5}, {0x59, 0xDC}, {0x5C, 0x06}, /* 0xA8-0xAB */
 	{0x6D, 0x46}, {0x6C, 0x5F}, {0x75, 0x86}, {0x84, 0x8B}, /* 0xAC-0xAF */
 	{0x68, 0x68}, {0x59, 0x56}, {0x8B, 0xB2}, {0x53, 0x20}, /* 0xB0-0xB3 */
-	{0x91, 0x71}, {0x96, 0x4D}, {0x85, 0x49}, {0x69, 0x12}, /* 0xB4-0xB7 */
+	{0x91, 0x71}, {0xFA, 0x09}, {0x85, 0x49}, {0x69, 0x12}, /* 0xB4-0xB7 */
 	{0x79, 0x01}, {0x71, 0x26}, {0x80, 0xF6}, {0x4E, 0xA4}, /* 0xB8-0xBB */
 	{0x90, 0xCA}, {0x6D, 0x47}, {0x9A, 0x84}, {0x5A, 0x07}, /* 0xBC-0xBF */
 	{0x56, 0xBC}, {0x64, 0x05}, {0x94, 0xF0}, {0x77, 0xEB}, /* 0xC0-0xC3 */
@@ -4153,7 +4155,7 @@
 	{0x62, 0x12}, {0x85, 0xC9}, {0x82, 0xA5}, {0x75, 0x4C}, /* 0xE4-0xE7 */
 	{0x50, 0x1F}, {0x4E, 0xCB}, {0x75, 0xA5}, {0x8B, 0xEB}, /* 0xE8-0xEB */
 	{0x5C, 0x4A}, {0x5D, 0xFE}, {0x7B, 0x4B}, {0x65, 0xA4}, /* 0xEC-0xEF */
-	{0x91, 0xD1}, {0x4E, 0xCA}, {0x6D, 0x25}, {0x89, 0x5F}, /* 0xF0-0xF3 */
+	{0xF9, 0x0A}, {0x4E, 0xCA}, {0x6D, 0x25}, {0x89, 0x5F}, /* 0xF0-0xF3 */
 	{0x7D, 0x27}, {0x95, 0x26}, {0x4E, 0xC5}, {0x8C, 0x28}, /* 0xF4-0xF7 */
 	{0x8F, 0xDB}, {0x97, 0x73}, {0x66, 0x4B}, {0x79, 0x81}, /* 0xF8-0xFB */
 	{0x8F, 0xD1}, {0x70, 0xEC}, {0x6D, 0x78}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -4177,14 +4179,14 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x7D, 0x99}, {0x7D, 0x9A}, {0x7D, 0x9B}, {0x7D, 0x9C}, /* 0x40-0x43 */
-	{0x7D, 0x9D}, {0x7D, 0x9E}, {0x7D, 0x9F}, {0x7D, 0xA0}, /* 0x44-0x47 */
+	{0x7D, 0x9D}, {0x7D, 0x9E}, {0x7D, 0x9F}, {0xF9, 0x3D}, /* 0x44-0x47 */
 	{0x7D, 0xA1}, {0x7D, 0xA2}, {0x7D, 0xA3}, {0x7D, 0xA4}, /* 0x48-0x4B */
 	{0x7D, 0xA5}, {0x7D, 0xA7}, {0x7D, 0xA8}, {0x7D, 0xA9}, /* 0x4C-0x4F */
 	{0x7D, 0xAA}, {0x7D, 0xAB}, {0x7D, 0xAC}, {0x7D, 0xAD}, /* 0x50-0x53 */
 	{0x7D, 0xAF}, {0x7D, 0xB0}, {0x7D, 0xB1}, {0x7D, 0xB2}, /* 0x54-0x57 */
 	{0x7D, 0xB3}, {0x7D, 0xB4}, {0x7D, 0xB5}, {0x7D, 0xB6}, /* 0x58-0x5B */
 	{0x7D, 0xB7}, {0x7D, 0xB8}, {0x7D, 0xB9}, {0x7D, 0xBA}, /* 0x5C-0x5F */
-	{0x7D, 0xBB}, {0x7D, 0xBC}, {0x7D, 0xBD}, {0x7D, 0xBE}, /* 0x60-0x63 */
+	{0x7D, 0xBB}, {0x7D, 0xBC}, {0x7D, 0xBD}, {0xF9, 0x57}, /* 0x60-0x63 */
 	{0x7D, 0xBF}, {0x7D, 0xC0}, {0x7D, 0xC1}, {0x7D, 0xC2}, /* 0x64-0x67 */
 	{0x7D, 0xC3}, {0x7D, 0xC4}, {0x7D, 0xC5}, {0x7D, 0xC6}, /* 0x68-0x6B */
 	{0x7D, 0xC7}, {0x7D, 0xC8}, {0x7D, 0xC9}, {0x7D, 0xCA}, /* 0x6C-0x6F */
@@ -4199,15 +4201,15 @@
 	{0x7D, 0xE6}, {0x7D, 0xE7}, {0x7D, 0xE8}, {0x7D, 0xE9}, /* 0x8C-0x8F */
 	{0x7D, 0xEA}, {0x7D, 0xEB}, {0x7D, 0xEC}, {0x7D, 0xED}, /* 0x90-0x93 */
 	{0x7D, 0xEE}, {0x7D, 0xEF}, {0x7D, 0xF0}, {0x7D, 0xF1}, /* 0x94-0x97 */
-	{0x7D, 0xF2}, {0x7D, 0xF3}, {0x7D, 0xF4}, {0x7D, 0xF5}, /* 0x98-0x9B */
+	{0x7D, 0xF2}, {0x7D, 0xF3}, {0xF9, 0x96}, {0x7D, 0xF5}, /* 0x98-0x9B */
 	{0x7D, 0xF6}, {0x7D, 0xF7}, {0x7D, 0xF8}, {0x7D, 0xF9}, /* 0x9C-0x9F */
 	{0x7D, 0xFA}, {0x5C, 0x3D}, {0x52, 0xB2}, {0x83, 0x46}, /* 0xA0-0xA3 */
 	{0x51, 0x62}, {0x83, 0x0E}, {0x77, 0x5B}, {0x66, 0x76}, /* 0xA4-0xA7 */
-	{0x9C, 0xB8}, {0x4E, 0xAC}, {0x60, 0xCA}, {0x7C, 0xBE}, /* 0xA8-0xAB */
+	{0x9C, 0xB8}, {0x4E, 0xAC}, {0x60, 0xCA}, {0xFA, 0x1D}, /* 0xA8-0xAB */
 	{0x7C, 0xB3}, {0x7E, 0xCF}, {0x4E, 0x95}, {0x8B, 0x66}, /* 0xAC-0xAF */
 	{0x66, 0x6F}, {0x98, 0x88}, {0x97, 0x59}, {0x58, 0x83}, /* 0xB0-0xB3 */
 	{0x65, 0x6C}, {0x95, 0x5C}, {0x5F, 0x84}, {0x75, 0xC9}, /* 0xB4-0xB7 */
-	{0x97, 0x56}, {0x7A, 0xDF}, {0x7A, 0xDE}, {0x51, 0xC0}, /* 0xB8-0xBB */
+	{0xFA, 0x1C}, {0x7A, 0xDF}, {0x7A, 0xDE}, {0x51, 0xC0}, /* 0xB8-0xBB */
 	{0x70, 0xAF}, {0x7A, 0x98}, {0x63, 0xEA}, {0x7A, 0x76}, /* 0xBC-0xBF */
 	{0x7E, 0xA0}, {0x73, 0x96}, {0x97, 0xED}, {0x4E, 0x45}, /* 0xC0-0xC3 */
 	{0x70, 0x78}, {0x4E, 0x5D}, {0x91, 0x52}, {0x53, 0xA9}, /* 0xC4-0xC7 */
@@ -4218,7 +4220,7 @@
 	{0x77, 0xE9}, {0x4E, 0x3E}, {0x6C, 0xAE}, {0x80, 0x5A}, /* 0xD8-0xDB */
 	{0x62, 0xD2}, {0x63, 0x6E}, {0x5D, 0xE8}, {0x51, 0x77}, /* 0xDC-0xDF */
 	{0x8D, 0xDD}, {0x8E, 0x1E}, {0x95, 0x2F}, {0x4F, 0xF1}, /* 0xE0-0xE3 */
-	{0x53, 0xE5}, {0x60, 0xE7}, {0x70, 0xAC}, {0x52, 0x67}, /* 0xE4-0xE7 */
+	{0xF9, 0x06}, {0x60, 0xE7}, {0x70, 0xAC}, {0x52, 0x67}, /* 0xE4-0xE7 */
 	{0x63, 0x50}, {0x9E, 0x43}, {0x5A, 0x1F}, {0x50, 0x26}, /* 0xE8-0xEB */
 	{0x77, 0x37}, {0x53, 0x77}, {0x7E, 0xE2}, {0x64, 0x85}, /* 0xEC-0xEF */
 	{0x65, 0x2B}, {0x62, 0x89}, {0x63, 0x98}, {0x50, 0x14}, /* 0xF0-0xF3 */
@@ -4259,7 +4261,7 @@
 	{0x7E, 0x2B}, {0x7E, 0x2C}, {0x7E, 0x2D}, {0x7E, 0x2E}, /* 0x70-0x73 */
 	{0x7E, 0x2F}, {0x7E, 0x30}, {0x7E, 0x31}, {0x7E, 0x32}, /* 0x74-0x77 */
 	{0x7E, 0x33}, {0x7E, 0x34}, {0x7E, 0x35}, {0x7E, 0x36}, /* 0x78-0x7B */
-	{0x7E, 0x37}, {0x7E, 0x38}, {0x7E, 0x39}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0xF9, 0x50}, {0x7E, 0x38}, {0x7E, 0x39}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x7E, 0x3A}, {0x7E, 0x3C}, {0x7E, 0x3D}, {0x7E, 0x3E}, /* 0x80-0x83 */
 	{0x7E, 0x3F}, {0x7E, 0x40}, {0x7E, 0x42}, {0x7E, 0x43}, /* 0x84-0x87 */
@@ -4339,28 +4341,28 @@
 	{0x7F, 0x4D}, {0x7F, 0x4E}, {0x7F, 0x4F}, {0x7F, 0x52}, /* 0x9C-0x9F */
 	{0x7F, 0x53}, {0x99, 0x88}, {0x61, 0x27}, {0x6E, 0x83}, /* 0xA0-0xA3 */
 	{0x57, 0x64}, {0x66, 0x06}, {0x63, 0x46}, {0x56, 0xF0}, /* 0xA4-0xA7 */
-	{0x62, 0xEC}, {0x62, 0x69}, {0x5E, 0xD3}, {0x96, 0x14}, /* 0xA8-0xAB */
-	{0x57, 0x83}, {0x62, 0xC9}, {0x55, 0x87}, {0x87, 0x21}, /* 0xAC-0xAF */
+	{0x62, 0xEC}, {0x62, 0x69}, {0xFA, 0x0B}, {0x96, 0x14}, /* 0xA8-0xAB */
+	{0x57, 0x83}, {0xF9, 0x25}, {0xF9, 0x0B}, {0x87, 0x21}, /* 0xAC-0xAF */
 	{0x81, 0x4A}, {0x8F, 0xA3}, {0x55, 0x66}, {0x83, 0xB1}, /* 0xB0-0xB3 */
 	{0x67, 0x65}, {0x8D, 0x56}, {0x84, 0xDD}, {0x5A, 0x6A}, /* 0xB4-0xB7 */
 	{0x68, 0x0F}, {0x62, 0xE6}, {0x7B, 0xEE}, {0x96, 0x11}, /* 0xB8-0xBB */
 	{0x51, 0x70}, {0x6F, 0x9C}, {0x8C, 0x30}, {0x63, 0xFD}, /* 0xBC-0xBF */
 	{0x89, 0xC8}, {0x61, 0xD2}, {0x7F, 0x06}, {0x70, 0xC2}, /* 0xC0-0xC3 */
-	{0x6E, 0xE5}, {0x74, 0x05}, {0x69, 0x94}, {0x72, 0xFC}, /* 0xC4-0xC7 */
-	{0x5E, 0xCA}, {0x90, 0xCE}, {0x67, 0x17}, {0x6D, 0x6A}, /* 0xC8-0xCB */
-	{0x63, 0x5E}, {0x52, 0xB3}, {0x72, 0x62}, {0x80, 0x01}, /* 0xCC-0xCF */
-	{0x4F, 0x6C}, {0x59, 0xE5}, {0x91, 0x6A}, {0x70, 0xD9}, /* 0xD0-0xD3 */
-	{0x6D, 0x9D}, {0x52, 0xD2}, {0x4E, 0x50}, {0x96, 0xF7}, /* 0xD4-0xD7 */
-	{0x95, 0x6D}, {0x85, 0x7E}, {0x78, 0xCA}, {0x7D, 0x2F}, /* 0xD8-0xDB */
-	{0x51, 0x21}, {0x57, 0x92}, {0x64, 0xC2}, {0x80, 0x8B}, /* 0xDC-0xDF */
+	{0x6E, 0xE5}, {0x74, 0x05}, {0x69, 0x94}, {0xF9, 0x2B}, /* 0xC4-0xC7 */
+	{0xF9, 0x28}, {0x90, 0xCE}, {0xF9, 0x29}, {0xF9, 0x2A}, /* 0xC8-0xCB */
+	{0x63, 0x5E}, {0x52, 0xB3}, {0xF9, 0x46}, {0xF9, 0x34}, /* 0xCC-0xCF */
+	{0x4F, 0x6C}, {0x59, 0xE5}, {0xF9, 0x19}, {0xF9, 0x16}, /* 0xD0-0xD3 */
+	{0x6D, 0x9D}, {0xF9, 0x52}, {0x4E, 0x50}, {0xF9, 0x49}, /* 0xD4-0xD7 */
+	{0x95, 0x6D}, {0x85, 0x7E}, {0xF9, 0x47}, {0xF9, 0x4F}, /* 0xD8-0xDB */
+	{0x51, 0x21}, {0x57, 0x92}, {0x64, 0xC2}, {0xF9, 0x53}, /* 0xDC-0xDF */
 	{0x7C, 0x7B}, {0x6C, 0xEA}, {0x68, 0xF1}, {0x69, 0x5E}, /* 0xE0-0xE3 */
-	{0x51, 0xB7}, {0x53, 0x98}, {0x68, 0xA8}, {0x72, 0x81}, /* 0xE4-0xE7 */
-	{0x9E, 0xCE}, {0x7B, 0xF1}, {0x72, 0xF8}, {0x79, 0xBB}, /* 0xE8-0xEB */
-	{0x6F, 0x13}, {0x74, 0x06}, {0x67, 0x4E}, {0x91, 0xCC}, /* 0xEC-0xEF */
+	{0xF9, 0x2E}, {0x53, 0x98}, {0xF9, 0xE2}, {0x72, 0x81}, /* 0xE4-0xE7 */
+	{0xF9, 0x89}, {0x7B, 0xF1}, {0x72, 0xF8}, {0x79, 0xBB}, /* 0xE8-0xEB */
+	{0x6F, 0x13}, {0xF9, 0xE4}, {0xF9, 0xE1}, {0xF9, 0xE9}, /* 0xEC-0xEF */
 	{0x9C, 0xA4}, {0x79, 0x3C}, {0x83, 0x89}, {0x83, 0x54}, /* 0xF0-0xF3 */
-	{0x54, 0x0F}, {0x68, 0x17}, {0x4E, 0x3D}, {0x53, 0x89}, /* 0xF4-0xF7 */
-	{0x52, 0xB1}, {0x78, 0x3E}, {0x53, 0x86}, {0x52, 0x29}, /* 0xF8-0xFB */
-	{0x50, 0x88}, {0x4F, 0x8B}, {0x4F, 0xD0}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0xF9, 0xDE}, {0xF9, 0xDA}, {0x4E, 0x3D}, {0x53, 0x89}, /* 0xF4-0xF7 */
+	{0x52, 0xB1}, {0x78, 0x3E}, {0x53, 0x86}, {0xF9, 0xDD}, /* 0xF8-0xFB */
+	{0x50, 0x88}, {0xF9, 0xB5}, {0x4F, 0xD0}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_C1[256] = {
@@ -4387,7 +4389,7 @@
 	{0x7F, 0x70}, {0x7F, 0x73}, {0x7F, 0x75}, {0x7F, 0x76}, /* 0x50-0x53 */
 	{0x7F, 0x77}, {0x7F, 0x78}, {0x7F, 0x7A}, {0x7F, 0x7B}, /* 0x54-0x57 */
 	{0x7F, 0x7C}, {0x7F, 0x7D}, {0x7F, 0x7F}, {0x7F, 0x80}, /* 0x58-0x5B */
-	{0x7F, 0x82}, {0x7F, 0x83}, {0x7F, 0x84}, {0x7F, 0x85}, /* 0x5C-0x5F */
+	{0x7F, 0x82}, {0x7F, 0x83}, {0x7F, 0x84}, {0xF9, 0x0F}, /* 0x5C-0x5F */
 	{0x7F, 0x86}, {0x7F, 0x87}, {0x7F, 0x88}, {0x7F, 0x89}, /* 0x60-0x63 */
 	{0x7F, 0x8B}, {0x7F, 0x8D}, {0x7F, 0x8F}, {0x7F, 0x90}, /* 0x64-0x67 */
 	{0x7F, 0x91}, {0x7F, 0x92}, {0x7F, 0x93}, {0x7F, 0x95}, /* 0x68-0x6B */
@@ -4405,29 +4407,29 @@
 	{0x7F, 0xD1}, {0x7F, 0xD2}, {0x7F, 0xD3}, {0x7F, 0xD6}, /* 0x94-0x97 */
 	{0x7F, 0xD7}, {0x7F, 0xD9}, {0x7F, 0xDA}, {0x7F, 0xDB}, /* 0x98-0x9B */
 	{0x7F, 0xDC}, {0x7F, 0xDD}, {0x7F, 0xDE}, {0x7F, 0xE2}, /* 0x9C-0x9F */
-	{0x7F, 0xE3}, {0x75, 0xE2}, {0x7A, 0xCB}, {0x7C, 0x92}, /* 0xA0-0xA3 */
-	{0x6C, 0xA5}, {0x96, 0xB6}, {0x52, 0x9B}, {0x74, 0x83}, /* 0xA4-0xA7 */
+	{0x7F, 0xE3}, {0xF9, 0xE5}, {0xF9, 0xF7}, {0xF9, 0xF9}, /* 0xA0-0xA3 */
+	{0x6C, 0xA5}, {0x96, 0xB6}, {0xF9, 0x8A}, {0x74, 0x83}, /* 0xA4-0xA7 */
 	{0x54, 0xE9}, {0x4F, 0xE9}, {0x80, 0x54}, {0x83, 0xB2}, /* 0xA8-0xAB */
-	{0x8F, 0xDE}, {0x95, 0x70}, {0x5E, 0xC9}, {0x60, 0x1C}, /* 0xAC-0xAF */
+	{0x8F, 0xDE}, {0x95, 0x70}, {0xF9, 0xA2}, {0xF9, 0xAC}, /* 0xAC-0xAF */
 	{0x6D, 0x9F}, {0x5E, 0x18}, {0x65, 0x5B}, {0x81, 0x38}, /* 0xB0-0xB3 */
 	{0x94, 0xFE}, {0x60, 0x4B}, {0x70, 0xBC}, {0x7E, 0xC3}, /* 0xB4-0xB7 */
-	{0x7C, 0xAE}, {0x51, 0xC9}, {0x68, 0x81}, {0x7C, 0xB1}, /* 0xB8-0xBB */
-	{0x82, 0x6F}, {0x4E, 0x24}, {0x8F, 0x86}, {0x91, 0xCF}, /* 0xBC-0xBF */
-	{0x66, 0x7E}, {0x4E, 0xAE}, {0x8C, 0x05}, {0x64, 0xA9}, /* 0xC0-0xC3 */
-	{0x80, 0x4A}, {0x50, 0xDA}, {0x75, 0x97}, {0x71, 0xCE}, /* 0xC4-0xC7 */
-	{0x5B, 0xE5}, {0x8F, 0xBD}, {0x6F, 0x66}, {0x4E, 0x86}, /* 0xC8-0xCB */
-	{0x64, 0x82}, {0x95, 0x63}, {0x5E, 0xD6}, {0x65, 0x99}, /* 0xCC-0xCF */
-	{0x52, 0x17}, {0x88, 0xC2}, {0x70, 0xC8}, {0x52, 0xA3}, /* 0xD0-0xD3 */
-	{0x73, 0x0E}, {0x74, 0x33}, {0x67, 0x97}, {0x78, 0xF7}, /* 0xD4-0xD7 */
+	{0x7C, 0xAE}, {0x51, 0xC9}, {0xF9, 0x7A}, {0x7C, 0xB1}, /* 0xB8-0xBB */
+	{0xF9, 0x7C}, {0x4E, 0x24}, {0x8F, 0x86}, {0xF9, 0x7E}, /* 0xBC-0xBF */
+	{0x66, 0x7E}, {0xF9, 0x77}, {0x8C, 0x05}, {0x64, 0xA9}, /* 0xC0-0xC3 */
+	{0x80, 0x4A}, {0xF9, 0xBB}, {0x75, 0x97}, {0xF9, 0xC0}, /* 0xC4-0xC7 */
+	{0x5B, 0xE5}, {0x8F, 0xBD}, {0x6F, 0x66}, {0xF9, 0xBA}, /* 0xC8-0xCB */
+	{0x64, 0x82}, {0x95, 0x63}, {0x5E, 0xD6}, {0xF9, 0xBE}, /* 0xCC-0xCF */
+	{0xF9, 0x9C}, {0xF9, 0xA0}, {0xF9, 0x9F}, {0xF9, 0x9D}, /* 0xD0-0xD3 */
+	{0x73, 0x0E}, {0x74, 0x33}, {0xF9, 0xF4}, {0x78, 0xF7}, /* 0xD4-0xD7 */
 	{0x97, 0x16}, {0x4E, 0x34}, {0x90, 0xBB}, {0x9C, 0xDE}, /* 0xD8-0xDB */
-	{0x6D, 0xCB}, {0x51, 0xDB}, {0x8D, 0x41}, {0x54, 0x1D}, /* 0xDC-0xDF */
-	{0x62, 0xCE}, {0x73, 0xB2}, {0x83, 0xF1}, {0x96, 0xF6}, /* 0xE0-0xE3 */
-	{0x9F, 0x84}, {0x94, 0xC3}, {0x4F, 0x36}, {0x7F, 0x9A}, /* 0xE4-0xE7 */
-	{0x51, 0xCC}, {0x70, 0x75}, {0x96, 0x75}, {0x5C, 0xAD}, /* 0xE8-0xEB */
-	{0x98, 0x86}, {0x53, 0xE6}, {0x4E, 0xE4}, {0x6E, 0x9C}, /* 0xEC-0xEF */
-	{0x74, 0x09}, {0x69, 0xB4}, {0x78, 0x6B}, {0x99, 0x8F}, /* 0xF0-0xF3 */
-	{0x75, 0x59}, {0x52, 0x18}, {0x76, 0x24}, {0x6D, 0x41}, /* 0xF4-0xF7 */
-	{0x67, 0xF3}, {0x51, 0x6D}, {0x9F, 0x99}, {0x80, 0x4B}, /* 0xF8-0xFB */
+	{0xF9, 0xF5}, {0x51, 0xDB}, {0x8D, 0x41}, {0xF9, 0xED}, /* 0xDC-0xDF */
+	{0x62, 0xCE}, {0xF9, 0xAD}, {0xF9, 0x58}, {0xF9, 0xB2}, /* 0xE0-0xE3 */
+	{0x9F, 0x84}, {0x94, 0xC3}, {0x4F, 0x36}, {0xF9, 0xAF}, /* 0xE4-0xE7 */
+	{0xF9, 0x55}, {0x70, 0x75}, {0xF9, 0x59}, {0x5C, 0xAD}, /* 0xE8-0xEB */
+	{0x98, 0x86}, {0x53, 0xE6}, {0xF9, 0xA8}, {0xF9, 0xCB}, /* 0xEC-0xEF */
+	{0xF9, 0xCC}, {0x69, 0xB4}, {0xF9, 0xCE}, {0x99, 0x8F}, /* 0xF0-0xF3 */
+	{0xF9, 0xCD}, {0x52, 0x18}, {0x76, 0x24}, {0xF9, 0xCA}, /* 0xF4-0xF7 */
+	{0xF9, 0xC9}, {0xF9, 0xD1}, {0x9F, 0x99}, {0x80, 0x4B}, /* 0xF8-0xFB */
 	{0x54, 0x99}, {0x7B, 0x3C}, {0x7A, 0xBF}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -4469,28 +4471,28 @@
 	{0x80, 0x5E}, {0x80, 0x5F}, {0x80, 0x60}, {0x80, 0x61}, /* 0x84-0x87 */
 	{0x80, 0x62}, {0x80, 0x63}, {0x80, 0x64}, {0x80, 0x65}, /* 0x88-0x8B */
 	{0x80, 0x66}, {0x80, 0x67}, {0x80, 0x68}, {0x80, 0x6B}, /* 0x8C-0x8F */
-	{0x80, 0x6C}, {0x80, 0x6D}, {0x80, 0x6E}, {0x80, 0x6F}, /* 0x90-0x93 */
+	{0x80, 0x6C}, {0x80, 0x6D}, {0x80, 0x6E}, {0xF9, 0x97}, /* 0x90-0x93 */
 	{0x80, 0x70}, {0x80, 0x72}, {0x80, 0x73}, {0x80, 0x74}, /* 0x94-0x97 */
 	{0x80, 0x75}, {0x80, 0x76}, {0x80, 0x77}, {0x80, 0x78}, /* 0x98-0x9B */
 	{0x80, 0x79}, {0x80, 0x7A}, {0x80, 0x7B}, {0x80, 0x7C}, /* 0x9C-0x9F */
-	{0x80, 0x7D}, {0x96, 0x86}, {0x57, 0x84}, {0x62, 0xE2}, /* 0xA0-0xA3 */
+	{0x80, 0x7D}, {0xF9, 0xDC}, {0x57, 0x84}, {0x62, 0xE2}, /* 0xA0-0xA3 */
 	{0x96, 0x47}, {0x69, 0x7C}, {0x5A, 0x04}, {0x64, 0x02}, /* 0xA4-0xA7 */
-	{0x7B, 0xD3}, {0x6F, 0x0F}, {0x96, 0x4B}, {0x82, 0xA6}, /* 0xA8-0xAB */
+	{0x7B, 0xD3}, {0xF9, 0x4E}, {0xF9, 0x51}, {0x82, 0xA6}, /* 0xA8-0xAB */
 	{0x53, 0x62}, {0x98, 0x85}, {0x5E, 0x90}, {0x70, 0x89}, /* 0xAC-0xAF */
 	{0x63, 0xB3}, {0x53, 0x64}, {0x86, 0x4F}, {0x9C, 0x81}, /* 0xB0-0xB3 */
-	{0x9E, 0x93}, {0x78, 0x8C}, {0x97, 0x32}, {0x8D, 0xEF}, /* 0xB4-0xB7 */
-	{0x8D, 0x42}, {0x9E, 0x7F}, {0x6F, 0x5E}, {0x79, 0x84}, /* 0xB8-0xBB */
-	{0x5F, 0x55}, {0x96, 0x46}, {0x62, 0x2E}, {0x9A, 0x74}, /* 0xBC-0xBF */
-	{0x54, 0x15}, {0x94, 0xDD}, {0x4F, 0xA3}, {0x65, 0xC5}, /* 0xC0-0xC3 */
-	{0x5C, 0x65}, {0x5C, 0x61}, {0x7F, 0x15}, {0x86, 0x51}, /* 0xC4-0xC7 */
-	{0x6C, 0x2F}, {0x5F, 0x8B}, {0x73, 0x87}, {0x6E, 0xE4}, /* 0xC8-0xCB */
+	{0x9E, 0x93}, {0xF9, 0x3B}, {0xF9, 0x38}, {0xF9, 0x37}, /* 0xB4-0xB7 */
+	{0x8D, 0x42}, {0xF9, 0x40}, {0x6F, 0x5E}, {0x79, 0x84}, /* 0xB8-0xBB */
+	{0x5F, 0x55}, {0x96, 0x46}, {0xF9, 0xD2}, {0x9A, 0x74}, /* 0xBC-0xBF */
+	{0x54, 0x15}, {0x94, 0xDD}, {0x4F, 0xA3}, {0xF9, 0x83}, /* 0xC0-0xC3 */
+	{0xF9, 0xDF}, {0x5C, 0x61}, {0x7F, 0x15}, {0x86, 0x51}, /* 0xC4-0xC7 */
+	{0x6C, 0x2F}, {0xF9, 0xD8}, {0xF9, 0xDB}, {0x6E, 0xE4}, /* 0xC8-0xCB */
 	{0x7E, 0xFF}, {0x5C, 0xE6}, {0x63, 0x1B}, {0x5B, 0x6A}, /* 0xCC-0xCF */
-	{0x6E, 0xE6}, {0x53, 0x75}, {0x4E, 0x71}, {0x63, 0xA0}, /* 0xD0-0xD3 */
-	{0x75, 0x65}, {0x62, 0xA1}, {0x8F, 0x6E}, {0x4F, 0x26}, /* 0xD4-0xD7 */
+	{0x6E, 0xE6}, {0xF9, 0x1C}, {0x4E, 0x71}, {0xF9, 0x75}, /* 0xD0-0xD3 */
+	{0xF9, 0x76}, {0x62, 0xA1}, {0x8F, 0x6E}, {0x4F, 0x26}, /* 0xD4-0xD7 */
 	{0x4E, 0xD1}, {0x6C, 0xA6}, {0x7E, 0xB6}, {0x8B, 0xBA}, /* 0xD8-0xDB */
-	{0x84, 0x1D}, {0x87, 0xBA}, {0x7F, 0x57}, {0x90, 0x3B}, /* 0xDC-0xDF */
-	{0x95, 0x23}, {0x7B, 0xA9}, {0x9A, 0xA1}, {0x88, 0xF8}, /* 0xE0-0xE3 */
-	{0x84, 0x3D}, {0x6D, 0x1B}, {0x9A, 0x86}, {0x7E, 0xDC}, /* 0xE4-0xE7 */
+	{0x84, 0x1D}, {0xF9, 0x11}, {0x7F, 0x57}, {0x90, 0x3B}, /* 0xDC-0xDF */
+	{0x95, 0x23}, {0x7B, 0xA9}, {0x9A, 0xA1}, {0xF9, 0x12}, /* 0xE0-0xE3 */
+	{0xF9, 0x18}, {0xF9, 0x15}, {0x9A, 0x86}, {0x7E, 0xDC}, /* 0xE4-0xE7 */
 	{0x59, 0x88}, {0x9E, 0xBB}, {0x73, 0x9B}, {0x78, 0x01}, /* 0xE8-0xEB */
 	{0x86, 0x82}, {0x9A, 0x6C}, {0x9A, 0x82}, {0x56, 0x1B}, /* 0xEC-0xEF */
 	{0x54, 0x17}, {0x57, 0xCB}, {0x4E, 0x70}, {0x9E, 0xA6}, /* 0xF0-0xF3 */
@@ -4516,7 +4518,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x80, 0x7E}, {0x80, 0x81}, {0x80, 0x82}, {0x80, 0x85}, /* 0x40-0x43 */
+	{0xF9, 0x45}, {0x80, 0x81}, {0x80, 0x82}, {0x80, 0x85}, /* 0x40-0x43 */
 	{0x80, 0x88}, {0x80, 0x8A}, {0x80, 0x8D}, {0x80, 0x8E}, /* 0x44-0x47 */
 	{0x80, 0x8F}, {0x80, 0x90}, {0x80, 0x91}, {0x80, 0x92}, /* 0x48-0x4B */
 	{0x80, 0x94}, {0x80, 0x95}, {0x80, 0x97}, {0x80, 0x99}, /* 0x4C-0x4F */
@@ -4555,7 +4557,7 @@
 	{0x95, 0x30}, {0x73, 0x1B}, {0x68, 0xA6}, {0x5B, 0x5F}, /* 0xCC-0xCF */
 	{0x77, 0x2F}, {0x91, 0x9A}, {0x97, 0x61}, {0x7C, 0xDC}, /* 0xD0-0xD3 */
 	{0x8F, 0xF7}, {0x8C, 0x1C}, {0x5F, 0x25}, {0x7C, 0x73}, /* 0xD4-0xD7 */
-	{0x79, 0xD8}, {0x89, 0xC5}, {0x6C, 0xCC}, {0x87, 0x1C}, /* 0xD8-0xDB */
+	{0x79, 0xD8}, {0x89, 0xC5}, {0xF9, 0x68}, {0x87, 0x1C}, /* 0xD8-0xDB */
 	{0x5B, 0xC6}, {0x5E, 0x42}, {0x68, 0xC9}, {0x77, 0x20}, /* 0xDC-0xDF */
 	{0x7E, 0xF5}, {0x51, 0x95}, {0x51, 0x4D}, {0x52, 0xC9}, /* 0xE0-0xE3 */
 	{0x5A, 0x29}, {0x7F, 0x05}, {0x97, 0x62}, {0x82, 0xD7}, /* 0xE4-0xE7 */
@@ -4620,16 +4622,16 @@
 	{0x77, 0x66}, {0x72, 0x67}, {0x7A, 0x46}, {0x62, 0xFF}, /* 0xC0-0xC3 */
 	{0x54, 0xEA}, {0x54, 0x50}, {0x94, 0xA0}, {0x90, 0xA3}, /* 0xC4-0xC7 */
 	{0x5A, 0x1C}, {0x7E, 0xB3}, {0x6C, 0x16}, {0x4E, 0x43}, /* 0xC8-0xCB */
-	{0x59, 0x76}, {0x80, 0x10}, {0x59, 0x48}, {0x53, 0x57}, /* 0xCC-0xCF */
+	{0x59, 0x76}, {0x80, 0x10}, {0xF9, 0x0C}, {0x53, 0x57}, /* 0xCC-0xCF */
 	{0x75, 0x37}, {0x96, 0xBE}, {0x56, 0xCA}, {0x63, 0x20}, /* 0xD0-0xD3 */
 	{0x81, 0x11}, {0x60, 0x7C}, {0x95, 0xF9}, {0x6D, 0xD6}, /* 0xD4-0xD7 */
 	{0x54, 0x62}, {0x99, 0x81}, {0x51, 0x85}, {0x5A, 0xE9}, /* 0xD8-0xDB */
 	{0x80, 0xFD}, {0x59, 0xAE}, {0x97, 0x13}, {0x50, 0x2A}, /* 0xDC-0xDF */
-	{0x6C, 0xE5}, {0x5C, 0x3C}, {0x62, 0xDF}, {0x4F, 0x60}, /* 0xE0-0xE3 */
-	{0x53, 0x3F}, {0x81, 0x7B}, {0x90, 0x06}, {0x6E, 0xBA}, /* 0xE4-0xE7 */
-	{0x85, 0x2B}, {0x62, 0xC8}, {0x5E, 0x74}, {0x78, 0xBE}, /* 0xE8-0xEB */
-	{0x64, 0xB5}, {0x63, 0x7B}, {0x5F, 0xF5}, {0x5A, 0x18}, /* 0xEC-0xEF */
-	{0x91, 0x7F}, {0x9E, 0x1F}, {0x5C, 0x3F}, {0x63, 0x4F}, /* 0xF0-0xF3 */
+	{0xF9, 0xE3}, {0x5C, 0x3C}, {0x62, 0xDF}, {0x4F, 0x60}, /* 0xE0-0xE3 */
+	{0xF9, 0xEB}, {0x81, 0x7B}, {0x90, 0x06}, {0xF9, 0xEC}, /* 0xE4-0xE7 */
+	{0x85, 0x2B}, {0x62, 0xC8}, {0xF9, 0x8E}, {0x78, 0xBE}, /* 0xE8-0xEB */
+	{0x64, 0xB5}, {0xF9, 0xA4}, {0xF9, 0xA3}, {0x5A, 0x18}, /* 0xEC-0xEF */
+	{0x91, 0x7F}, {0x9E, 0x1F}, {0xF9, 0xBD}, {0x63, 0x4F}, /* 0xF0-0xF3 */
 	{0x80, 0x42}, {0x5B, 0x7D}, {0x55, 0x6E}, {0x95, 0x4A}, /* 0xF4-0xF7 */
 	{0x95, 0x4D}, {0x6D, 0x85}, {0x60, 0xA8}, {0x67, 0xE0}, /* 0xF8-0xFB */
 	{0x72, 0xDE}, {0x51, 0xDD}, {0x5B, 0x81}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -4653,10 +4655,10 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x81, 0xD4}, {0x81, 0xD5}, {0x81, 0xD6}, {0x81, 0xD7}, /* 0x40-0x43 */
-	{0x81, 0xD8}, {0x81, 0xD9}, {0x81, 0xDA}, {0x81, 0xDB}, /* 0x44-0x47 */
+	{0xF9, 0x26}, {0x81, 0xD9}, {0x81, 0xDA}, {0x81, 0xDB}, /* 0x44-0x47 */
 	{0x81, 0xDC}, {0x81, 0xDD}, {0x81, 0xDE}, {0x81, 0xDF}, /* 0x48-0x4B */
 	{0x81, 0xE0}, {0x81, 0xE1}, {0x81, 0xE2}, {0x81, 0xE4}, /* 0x4C-0x4F */
-	{0x81, 0xE5}, {0x81, 0xE6}, {0x81, 0xE8}, {0x81, 0xE9}, /* 0x50-0x53 */
+	{0x81, 0xE5}, {0x81, 0xE6}, {0xF9, 0xF6}, {0x81, 0xE9}, /* 0x50-0x53 */
 	{0x81, 0xEB}, {0x81, 0xEE}, {0x81, 0xEF}, {0x81, 0xF0}, /* 0x54-0x57 */
 	{0x81, 0xF1}, {0x81, 0xF2}, {0x81, 0xF5}, {0x81, 0xF6}, /* 0x58-0x5B */
 	{0x81, 0xF7}, {0x81, 0xF8}, {0x81, 0xF9}, {0x81, 0xFA}, /* 0x5C-0x5F */
@@ -4679,8 +4681,8 @@
 	{0x82, 0x64}, {0x82, 0x65}, {0x82, 0x66}, {0x82, 0x67}, /* 0x9C-0x9F */
 	{0x82, 0x69}, {0x62, 0xE7}, {0x6C, 0xDE}, {0x72, 0x5B}, /* 0xA0-0xA3 */
 	{0x62, 0x6D}, {0x94, 0xAE}, {0x7E, 0xBD}, {0x81, 0x13}, /* 0xA4-0xA7 */
-	{0x6D, 0x53}, {0x51, 0x9C}, {0x5F, 0x04}, {0x59, 0x74}, /* 0xA8-0xAB */
-	{0x52, 0xAA}, {0x60, 0x12}, {0x59, 0x73}, {0x66, 0x96}, /* 0xAC-0xAF */
+	{0x6D, 0x53}, {0x51, 0x9C}, {0xF9, 0x43}, {0x59, 0x74}, /* 0xA8-0xAB */
+	{0x52, 0xAA}, {0xF9, 0x60}, {0xF9, 0x81}, {0x66, 0x96}, /* 0xAC-0xAF */
 	{0x86, 0x50}, {0x75, 0x9F}, {0x63, 0x2A}, {0x61, 0xE6}, /* 0xB0-0xB3 */
 	{0x7C, 0xEF}, {0x8B, 0xFA}, {0x54, 0xE6}, {0x6B, 0x27}, /* 0xB4-0xB7 */
 	{0x9E, 0x25}, {0x6B, 0xB4}, {0x85, 0xD5}, {0x54, 0x55}, /* 0xB8-0xBB */
@@ -4766,7 +4768,7 @@
 	{0x75, 0x66}, {0x5D, 0x0E}, {0x81, 0x10}, {0x9F, 0x50}, /* 0xE8-0xEB */
 	{0x65, 0xD7}, {0x79, 0x48}, {0x79, 0x41}, {0x9A, 0x91}, /* 0xEC-0xEF */
 	{0x8D, 0x77}, {0x5C, 0x82}, {0x4E, 0x5E}, {0x4F, 0x01}, /* 0xF0-0xF3 */
-	{0x54, 0x2F}, {0x59, 0x51}, {0x78, 0x0C}, {0x56, 0x68}, /* 0xF4-0xF7 */
+	{0x54, 0x2F}, {0xF9, 0x09}, {0x78, 0x0C}, {0x56, 0x68}, /* 0xF4-0xF7 */
 	{0x6C, 0x14}, {0x8F, 0xC4}, {0x5F, 0x03}, {0x6C, 0x7D}, /* 0xF8-0xFB */
 	{0x6C, 0xE3}, {0x8B, 0xAB}, {0x63, 0x90}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -4807,7 +4809,7 @@
 	
 	{0x83, 0xAF}, {0x83, 0xB5}, {0x83, 0xBB}, {0x83, 0xBE}, /* 0x80-0x83 */
 	{0x83, 0xBF}, {0x83, 0xC2}, {0x83, 0xC3}, {0x83, 0xC4}, /* 0x84-0x87 */
-	{0x83, 0xC6}, {0x83, 0xC8}, {0x83, 0xC9}, {0x83, 0xCB}, /* 0x88-0x8B */
+	{0x83, 0xC6}, {0x83, 0xC8}, {0xF9, 0x3E}, {0x83, 0xCB}, /* 0x88-0x8B */
 	{0x83, 0xCD}, {0x83, 0xCE}, {0x83, 0xD0}, {0x83, 0xD1}, /* 0x8C-0x8F */
 	{0x83, 0xD2}, {0x83, 0xD3}, {0x83, 0xD5}, {0x83, 0xD7}, /* 0x90-0x93 */
 	{0x83, 0xD9}, {0x83, 0xDA}, {0x83, 0xDB}, {0x83, 0xDE}, /* 0x94-0x97 */
@@ -4825,12 +4827,12 @@
 	{0x60, 0x84}, {0x68, 0x65}, {0x77, 0xA7}, {0x4E, 0x54}, /* 0xC4-0xC7 */
 	{0x4F, 0xA8}, {0x5D, 0xE7}, {0x97, 0x98}, {0x64, 0xAC}, /* 0xC8-0xCB */
 	{0x7F, 0xD8}, {0x5C, 0xED}, {0x4F, 0xCF}, {0x7A, 0x8D}, /* 0xCC-0xCF */
-	{0x52, 0x07}, {0x83, 0x04}, {0x4E, 0x14}, {0x60, 0x2F}, /* 0xD0-0xD3 */
+	{0xFA, 0x00}, {0x83, 0x04}, {0x4E, 0x14}, {0x60, 0x2F}, /* 0xD0-0xD3 */
 	{0x7A, 0x83}, {0x94, 0xA6}, {0x4F, 0xB5}, {0x4E, 0xB2}, /* 0xD4-0xD7 */
 	{0x79, 0xE6}, {0x74, 0x34}, {0x52, 0xE4}, {0x82, 0xB9}, /* 0xD8-0xDB */
 	{0x64, 0xD2}, {0x79, 0xBD}, {0x5B, 0xDD}, {0x6C, 0x81}, /* 0xDC-0xDF */
 	{0x97, 0x52}, {0x8F, 0x7B}, {0x6C, 0x22}, {0x50, 0x3E}, /* 0xE0-0xE3 */
-	{0x53, 0x7F}, {0x6E, 0x05}, {0x64, 0xCE}, {0x66, 0x74}, /* 0xE4-0xE7 */
+	{0x53, 0x7F}, {0x6E, 0x05}, {0x64, 0xCE}, {0xFA, 0x12}, /* 0xE4-0xE7 */
 	{0x6C, 0x30}, {0x60, 0xC5}, {0x98, 0x77}, {0x8B, 0xF7}, /* 0xE8-0xEB */
 	{0x5E, 0x86}, {0x74, 0x3C}, {0x7A, 0x77}, {0x79, 0xCB}, /* 0xEC-0xEF */
 	{0x4E, 0x18}, {0x90, 0xB1}, {0x74, 0x03}, {0x6C, 0x42}, /* 0xF0-0xF3 */
@@ -4871,7 +4873,7 @@
 	{0x84, 0x37}, {0x84, 0x39}, {0x84, 0x3A}, {0x84, 0x3B}, /* 0x70-0x73 */
 	{0x84, 0x3E}, {0x84, 0x3F}, {0x84, 0x40}, {0x84, 0x41}, /* 0x74-0x77 */
 	{0x84, 0x42}, {0x84, 0x43}, {0x84, 0x44}, {0x84, 0x45}, /* 0x78-0x7B */
-	{0x84, 0x47}, {0x84, 0x48}, {0x84, 0x49}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x84, 0x47}, {0x84, 0x48}, {0xF9, 0x6E}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x84, 0x4A}, {0x84, 0x4B}, {0x84, 0x4C}, {0x84, 0x4D}, /* 0x80-0x83 */
 	{0x84, 0x4E}, {0x84, 0x4F}, {0x84, 0x50}, {0x84, 0x52}, /* 0x84-0x87 */
@@ -4900,10 +4902,10 @@
 	{0x63, 0xC9}, {0x67, 0xD4}, {0x80, 0x89}, {0x83, 0x39}, /* 0xE0-0xE3 */
 	{0x88, 0x15}, {0x51, 0x12}, {0x5B, 0x7A}, {0x59, 0x82}, /* 0xE4-0xE7 */
 	{0x8F, 0xB1}, {0x4E, 0x73}, {0x6C, 0x5D}, {0x51, 0x65}, /* 0xE8-0xEB */
-	{0x89, 0x25}, {0x8F, 0x6F}, {0x96, 0x2E}, {0x85, 0x4A}, /* 0xEC-0xEF */
+	{0x89, 0x25}, {0x8F, 0x6F}, {0xF9, 0xC6}, {0x85, 0x4A}, /* 0xEC-0xEF */
 	{0x74, 0x5E}, {0x95, 0x10}, {0x95, 0xF0}, {0x6D, 0xA6}, /* 0xF0-0xF3 */
-	{0x82, 0xE5}, {0x5F, 0x31}, {0x64, 0x92}, {0x6D, 0x12}, /* 0xF4-0xF7 */
-	{0x84, 0x28}, {0x81, 0x6E}, {0x9C, 0xC3}, {0x58, 0x5E}, /* 0xF8-0xFB */
+	{0xF9, 0x74}, {0x5F, 0x31}, {0x64, 0x92}, {0x6D, 0x12}, /* 0xF4-0xF7 */
+	{0x84, 0x28}, {0x81, 0x6E}, {0x9C, 0xC3}, {0xF9, 0x6C}, /* 0xF8-0xFB */
 	{0x8D, 0x5B}, {0x4E, 0x09}, {0x53, 0xC1}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -4944,7 +4946,7 @@
 	{0x84, 0xD8}, {0x84, 0xD9}, {0x84, 0xDA}, {0x84, 0xDB}, /* 0x80-0x83 */
 	{0x84, 0xDC}, {0x84, 0xDE}, {0x84, 0xE1}, {0x84, 0xE2}, /* 0x84-0x87 */
 	{0x84, 0xE4}, {0x84, 0xE7}, {0x84, 0xE8}, {0x84, 0xE9}, /* 0x88-0x8B */
-	{0x84, 0xEA}, {0x84, 0xEB}, {0x84, 0xED}, {0x84, 0xEE}, /* 0x8C-0x8F */
+	{0x84, 0xEA}, {0x84, 0xEB}, {0x84, 0xED}, {0xF9, 0x99}, /* 0x8C-0x8F */
 	{0x84, 0xEF}, {0x84, 0xF1}, {0x84, 0xF2}, {0x84, 0xF3}, /* 0x90-0x93 */
 	{0x84, 0xF4}, {0x84, 0xF5}, {0x84, 0xF6}, {0x84, 0xF7}, /* 0x94-0x97 */
 	{0x84, 0xF8}, {0x84, 0xF9}, {0x84, 0xFA}, {0x84, 0xFB}, /* 0x98-0x9B */
@@ -4969,7 +4971,7 @@
 	{0x5C, 0x04}, {0x61, 0x51}, {0x6D, 0x89}, {0x79, 0x3E}, /* 0xE4-0xE7 */
 	{0x8B, 0xBE}, {0x78, 0x37}, {0x75, 0x33}, {0x54, 0x7B}, /* 0xE8-0xEB */
 	{0x4F, 0x38}, {0x8E, 0xAB}, {0x6D, 0xF1}, {0x5A, 0x20}, /* 0xEC-0xEF */
-	{0x7E, 0xC5}, {0x79, 0x5E}, {0x6C, 0x88}, {0x5B, 0xA1}, /* 0xF0-0xF3 */
+	{0x7E, 0xC5}, {0xFA, 0x19}, {0xF9, 0x72}, {0x5B, 0xA1}, /* 0xF0-0xF3 */
 	{0x5A, 0x76}, {0x75, 0x1A}, {0x80, 0xBE}, {0x61, 0x4E}, /* 0xF4-0xF7 */
 	{0x6E, 0x17}, {0x58, 0xF0}, {0x75, 0x1F}, {0x75, 0x25}, /* 0xF8-0xFB */
 	{0x72, 0x72}, {0x53, 0x47}, {0x7E, 0xF3}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -5017,11 +5019,11 @@
 	{0x85, 0x6F}, {0x85, 0x70}, {0x85, 0x71}, {0x85, 0x73}, /* 0x94-0x97 */
 	{0x85, 0x75}, {0x85, 0x76}, {0x85, 0x77}, {0x85, 0x78}, /* 0x98-0x9B */
 	{0x85, 0x7C}, {0x85, 0x7D}, {0x85, 0x7F}, {0x85, 0x80}, /* 0x9C-0x9F */
-	{0x85, 0x81}, {0x77, 0x01}, {0x76, 0xDB}, {0x52, 0x69}, /* 0xA0-0xA3 */
+	{0x85, 0x81}, {0xF9, 0x6D}, {0x76, 0xDB}, {0x52, 0x69}, /* 0xA0-0xA3 */
 	{0x80, 0xDC}, {0x57, 0x23}, {0x5E, 0x08}, {0x59, 0x31}, /* 0xA4-0xA7 */
 	{0x72, 0xEE}, {0x65, 0xBD}, {0x6E, 0x7F}, {0x8B, 0xD7}, /* 0xA8-0xAB */
 	{0x5C, 0x38}, {0x86, 0x71}, {0x53, 0x41}, {0x77, 0xF3}, /* 0xAC-0xAF */
-	{0x62, 0xFE}, {0x65, 0xF6}, {0x4E, 0xC0}, {0x98, 0xDF}, /* 0xB0-0xB3 */
+	{0xF9, 0x73}, {0x65, 0xF6}, {0xF9, 0xFD}, {0x98, 0xDF}, /* 0xB0-0xB3 */
 	{0x86, 0x80}, {0x5B, 0x9E}, {0x8B, 0xC6}, {0x53, 0xF2}, /* 0xB4-0xB7 */
 	{0x77, 0xE2}, {0x4F, 0x7F}, {0x5C, 0x4E}, {0x9A, 0x76}, /* 0xB8-0xBB */
 	{0x59, 0xCB}, {0x5F, 0x0F}, {0x79, 0x3A}, {0x58, 0xEB}, /* 0xBC-0xBF */
@@ -5074,7 +5076,7 @@
 	{0x85, 0xBC}, {0x85, 0xBD}, {0x85, 0xBE}, {0x85, 0xBF}, /* 0x6C-0x6F */
 	{0x85, 0xC0}, {0x85, 0xC2}, {0x85, 0xC3}, {0x85, 0xC4}, /* 0x70-0x73 */
 	{0x85, 0xC5}, {0x85, 0xC6}, {0x85, 0xC7}, {0x85, 0xC8}, /* 0x74-0x77 */
-	{0x85, 0xCA}, {0x85, 0xCB}, {0x85, 0xCC}, {0x85, 0xCD}, /* 0x78-0x7B */
+	{0x85, 0xCA}, {0x85, 0xCB}, {0x85, 0xCC}, {0xF9, 0x23}, /* 0x78-0x7B */
 	{0x85, 0xCE}, {0x85, 0xD1}, {0x85, 0xD2}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x85, 0xD4}, {0x85, 0xD6}, {0x85, 0xD7}, {0x85, 0xD8}, /* 0x80-0x83 */
@@ -5106,7 +5108,7 @@
 	{0x9A, 0xD3}, {0x78, 0x8E}, {0x5C, 0x81}, {0x7A, 0x57}, /* 0xE8-0xEB */
 	{0x90, 0x42}, {0x96, 0xA7}, {0x79, 0x5F}, {0x5B, 0x59}, /* 0xEC-0xEF */
 	{0x63, 0x5F}, {0x7B, 0x0B}, {0x84, 0xD1}, {0x68, 0xAD}, /* 0xF0-0xF3 */
-	{0x55, 0x06}, {0x7F, 0x29}, {0x74, 0x10}, {0x7D, 0x22}, /* 0xF4-0xF7 */
+	{0x55, 0x06}, {0x7F, 0x29}, {0x74, 0x10}, {0xF9, 0x6A}, /* 0xF4-0xF7 */
 	{0x95, 0x01}, {0x62, 0x40}, {0x58, 0x4C}, {0x4E, 0xD6}, /* 0xF8-0xFB */
 	{0x5B, 0x83}, {0x59, 0x79}, {0x58, 0x54}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -5128,9 +5130,9 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x85, 0xF9}, {0x85, 0xFA}, {0x85, 0xFC}, {0x85, 0xFD}, /* 0x40-0x43 */
+	{0x85, 0xF9}, {0xF9, 0xF0}, {0x85, 0xFC}, {0x85, 0xFD}, /* 0x40-0x43 */
 	{0x85, 0xFE}, {0x86, 0x00}, {0x86, 0x01}, {0x86, 0x02}, /* 0x44-0x47 */
-	{0x86, 0x03}, {0x86, 0x04}, {0x86, 0x06}, {0x86, 0x07}, /* 0x48-0x4B */
+	{0x86, 0x03}, {0x86, 0x04}, {0xF9, 0x35}, {0x86, 0x07}, /* 0x48-0x4B */
 	{0x86, 0x08}, {0x86, 0x09}, {0x86, 0x0A}, {0x86, 0x0B}, /* 0x4C-0x4F */
 	{0x86, 0x0C}, {0x86, 0x0D}, {0x86, 0x0E}, {0x86, 0x0F}, /* 0x50-0x53 */
 	{0x86, 0x10}, {0x86, 0x12}, {0x86, 0x13}, {0x86, 0x14}, /* 0x54-0x57 */
@@ -5139,18 +5141,18 @@
 	{0x86, 0x1E}, {0x86, 0x1F}, {0x86, 0x20}, {0x86, 0x21}, /* 0x60-0x63 */
 	{0x86, 0x22}, {0x86, 0x23}, {0x86, 0x24}, {0x86, 0x25}, /* 0x64-0x67 */
 	{0x86, 0x26}, {0x86, 0x28}, {0x86, 0x2A}, {0x86, 0x2B}, /* 0x68-0x6B */
-	{0x86, 0x2C}, {0x86, 0x2D}, {0x86, 0x2E}, {0x86, 0x2F}, /* 0x6C-0x6F */
+	{0x86, 0x2C}, {0xF9, 0x1F}, {0x86, 0x2E}, {0x86, 0x2F}, /* 0x6C-0x6F */
 	{0x86, 0x30}, {0x86, 0x31}, {0x86, 0x32}, {0x86, 0x33}, /* 0x70-0x73 */
 	{0x86, 0x34}, {0x86, 0x35}, {0x86, 0x36}, {0x86, 0x37}, /* 0x74-0x77 */
 	{0x86, 0x39}, {0x86, 0x3A}, {0x86, 0x3B}, {0x86, 0x3D}, /* 0x78-0x7B */
-	{0x86, 0x3E}, {0x86, 0x3F}, {0x86, 0x40}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x86, 0x3E}, {0xF9, 0x10}, {0x86, 0x40}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x86, 0x41}, {0x86, 0x42}, {0x86, 0x43}, {0x86, 0x44}, /* 0x80-0x83 */
 	{0x86, 0x45}, {0x86, 0x46}, {0x86, 0x47}, {0x86, 0x48}, /* 0x84-0x87 */
 	{0x86, 0x49}, {0x86, 0x4A}, {0x86, 0x4B}, {0x86, 0x4C}, /* 0x88-0x8B */
 	{0x86, 0x52}, {0x86, 0x53}, {0x86, 0x55}, {0x86, 0x56}, /* 0x8C-0x8F */
 	{0x86, 0x57}, {0x86, 0x58}, {0x86, 0x59}, {0x86, 0x5B}, /* 0x90-0x93 */
-	{0x86, 0x5C}, {0x86, 0x5D}, {0x86, 0x5F}, {0x86, 0x60}, /* 0x94-0x97 */
+	{0xF9, 0x36}, {0x86, 0x5D}, {0x86, 0x5F}, {0x86, 0x60}, /* 0x94-0x97 */
 	{0x86, 0x61}, {0x86, 0x63}, {0x86, 0x64}, {0x86, 0x65}, /* 0x98-0x9B */
 	{0x86, 0x66}, {0x86, 0x67}, {0x86, 0x68}, {0x86, 0x69}, /* 0x9C-0x9F */
 	{0x86, 0x6A}, {0x73, 0x6D}, {0x63, 0x1E}, {0x8E, 0x4B}, /* 0xA0-0xA3 */
@@ -5162,7 +5164,7 @@
 	{0x8C, 0x08}, {0x57, 0x66}, {0x6B, 0xEF}, {0x88, 0x92}, /* 0xB8-0xBB */
 	{0x78, 0xB3}, {0x63, 0xA2}, {0x53, 0xF9}, {0x70, 0xAD}, /* 0xBC-0xBF */
 	{0x6C, 0x64}, {0x58, 0x58}, {0x64, 0x2A}, {0x58, 0x02}, /* 0xC0-0xC3 */
-	{0x68, 0xE0}, {0x81, 0x9B}, {0x55, 0x10}, {0x7C, 0xD6}, /* 0xC4-0xC7 */
+	{0x68, 0xE0}, {0x81, 0x9B}, {0x55, 0x10}, {0xFA, 0x03}, /* 0xC4-0xC7 */
 	{0x50, 0x18}, {0x8E, 0xBA}, {0x6D, 0xCC}, {0x8D, 0x9F}, /* 0xC8-0xCB */
 	{0x70, 0xEB}, {0x63, 0x8F}, {0x6D, 0x9B}, {0x6E, 0xD4}, /* 0xCC-0xCF */
 	{0x7E, 0xE6}, {0x84, 0x04}, {0x68, 0x43}, {0x90, 0x03}, /* 0xD0-0xD3 */
@@ -5235,7 +5237,7 @@
 	{0x54, 0x1E}, {0x5C, 0x6F}, {0x81, 0xC0}, {0x62, 0xD6}, /* 0xCC-0xCF */
 	{0x62, 0x58}, {0x81, 0x31}, {0x9E, 0x35}, {0x96, 0x40}, /* 0xD0-0xD3 */
 	{0x9A, 0x6E}, {0x9A, 0x7C}, {0x69, 0x2D}, {0x59, 0xA5}, /* 0xD4-0xD7 */
-	{0x62, 0xD3}, {0x55, 0x3E}, {0x63, 0x16}, {0x54, 0xC7}, /* 0xD8-0xDB */
+	{0xFA, 0x02}, {0x55, 0x3E}, {0x63, 0x16}, {0x54, 0xC7}, /* 0xD8-0xDB */
 	{0x86, 0xD9}, {0x6D, 0x3C}, {0x5A, 0x03}, {0x74, 0xE6}, /* 0xDC-0xDF */
 	{0x88, 0x9C}, {0x6B, 0x6A}, {0x59, 0x16}, {0x8C, 0x4C}, /* 0xE0-0xE3 */
 	{0x5F, 0x2F}, {0x6E, 0x7E}, {0x73, 0xA9}, {0x98, 0x7D}, /* 0xE4-0xE7 */
@@ -5356,7 +5358,7 @@
 	{0x88, 0x0D}, {0x88, 0x0E}, {0x88, 0x0F}, {0x88, 0x10}, /* 0x90-0x93 */
 	{0x88, 0x11}, {0x88, 0x12}, {0x88, 0x14}, {0x88, 0x17}, /* 0x94-0x97 */
 	{0x88, 0x18}, {0x88, 0x19}, {0x88, 0x1A}, {0x88, 0x1C}, /* 0x98-0x9B */
-	{0x88, 0x1D}, {0x88, 0x1E}, {0x88, 0x1F}, {0x88, 0x20}, /* 0x9C-0x9F */
+	{0x88, 0x1D}, {0x88, 0x1E}, {0xF9, 0x27}, {0x88, 0x20}, /* 0x9C-0x9F */
 	{0x88, 0x23}, {0x7A, 0x00}, {0x60, 0x6F}, {0x5E, 0x0C}, /* 0xA0-0xA3 */
 	{0x60, 0x89}, {0x81, 0x9D}, {0x59, 0x15}, {0x60, 0xDC}, /* 0xA4-0xA7 */
 	{0x71, 0x84}, {0x70, 0xEF}, {0x6E, 0xAA}, {0x6C, 0x50}, /* 0xA8-0xAB */
@@ -5375,7 +5377,7 @@
 	{0x5B, 0xAA}, {0x96, 0x77}, {0x96, 0x50}, {0x7E, 0xBF}, /* 0xDC-0xDF */
 	{0x76, 0xF8}, {0x53, 0xA2}, {0x95, 0x76}, {0x99, 0x99}, /* 0xE0-0xE3 */
 	{0x7B, 0xB1}, {0x89, 0x44}, {0x6E, 0x58}, {0x4E, 0x61}, /* 0xE4-0xE7 */
-	{0x7F, 0xD4}, {0x79, 0x65}, {0x8B, 0xE6}, {0x60, 0xF3}, /* 0xE8-0xEB */
+	{0x7F, 0xD4}, {0xFA, 0x1A}, {0x8B, 0xE6}, {0x60, 0xF3}, /* 0xE8-0xEB */
 	{0x54, 0xCD}, {0x4E, 0xAB}, {0x98, 0x79}, {0x5D, 0xF7}, /* 0xEC-0xEF */
 	{0x6A, 0x61}, {0x50, 0xCF}, {0x54, 0x11}, {0x8C, 0x61}, /* 0xF0-0xF3 */
 	{0x84, 0x27}, {0x78, 0x5D}, {0x97, 0x04}, {0x52, 0x4A}, /* 0xF4-0xF7 */
@@ -5437,7 +5439,7 @@
 	{0x5F, 0xC3}, {0x4F, 0xE1}, {0x88, 0x45}, {0x66, 0x1F}, /* 0xC4-0xC7 */
 	{0x81, 0x65}, {0x73, 0x29}, {0x60, 0xFA}, {0x51, 0x74}, /* 0xC8-0xCB */
 	{0x52, 0x11}, {0x57, 0x8B}, {0x5F, 0x62}, {0x90, 0xA2}, /* 0xCC-0xCF */
-	{0x88, 0x4C}, {0x91, 0x92}, {0x5E, 0x78}, {0x67, 0x4F}, /* 0xD0-0xD3 */
+	{0xFA, 0x08}, {0x91, 0x92}, {0x5E, 0x78}, {0x67, 0x4F}, /* 0xD0-0xD3 */
 	{0x60, 0x27}, {0x59, 0xD3}, {0x51, 0x44}, {0x51, 0xF6}, /* 0xD4-0xD7 */
 	{0x80, 0xF8}, {0x53, 0x08}, {0x6C, 0x79}, {0x96, 0xC4}, /* 0xD8-0xDB */
 	{0x71, 0x8A}, {0x4F, 0x11}, {0x4F, 0xEE}, {0x7F, 0x9E}, /* 0xDC-0xDF */
@@ -5477,7 +5479,7 @@
 	{0x88, 0xCD}, {0x88, 0xCF}, {0x88, 0xD0}, {0x88, 0xD1}, /* 0x58-0x5B */
 	{0x88, 0xD3}, {0x88, 0xD6}, {0x88, 0xD7}, {0x88, 0xDA}, /* 0x5C-0x5F */
 	{0x88, 0xDB}, {0x88, 0xDC}, {0x88, 0xDD}, {0x88, 0xDE}, /* 0x60-0x63 */
-	{0x88, 0xE0}, {0x88, 0xE1}, {0x88, 0xE6}, {0x88, 0xE7}, /* 0x64-0x67 */
+	{0x88, 0xE0}, {0xF9, 0xE8}, {0x88, 0xE6}, {0x88, 0xE7}, /* 0x64-0x67 */
 	{0x88, 0xE9}, {0x88, 0xEA}, {0x88, 0xEB}, {0x88, 0xEC}, /* 0x68-0x6B */
 	{0x88, 0xED}, {0x88, 0xEE}, {0x88, 0xEF}, {0x88, 0xF2}, /* 0x6C-0x6F */
 	{0x88, 0xF5}, {0x88, 0xF6}, {0x88, 0xF7}, {0x88, 0xFA}, /* 0x70-0x73 */
@@ -5503,7 +5505,7 @@
 	{0x9E, 0x2D}, {0x54, 0x40}, {0x4E, 0x2B}, {0x82, 0xBD}, /* 0xBC-0xBF */
 	{0x72, 0x59}, {0x86, 0x9C}, {0x5D, 0x16}, {0x88, 0x59}, /* 0xC0-0xC3 */
 	{0x6D, 0xAF}, {0x96, 0xC5}, {0x54, 0xD1}, {0x4E, 0x9A}, /* 0xC4-0xC7 */
-	{0x8B, 0xB6}, {0x71, 0x09}, {0x54, 0xBD}, {0x96, 0x09}, /* 0xC8-0xCB */
+	{0x8B, 0xB6}, {0x71, 0x09}, {0xF9, 0x9E}, {0x96, 0x09}, /* 0xC8-0xCB */
 	{0x70, 0xDF}, {0x6D, 0xF9}, {0x76, 0xD0}, {0x4E, 0x25}, /* 0xCC-0xCF */
 	{0x78, 0x14}, {0x87, 0x12}, {0x5C, 0xA9}, {0x5E, 0xF6}, /* 0xD0-0xD3 */
 	{0x8A, 0x00}, {0x98, 0x9C}, {0x96, 0x0E}, {0x70, 0x8E}, /* 0xD4-0xD7 */
@@ -5546,7 +5548,7 @@
 	{0x89, 0x56}, {0x89, 0x57}, {0x89, 0x58}, {0x89, 0x59}, /* 0x5C-0x5F */
 	{0x89, 0x5A}, {0x89, 0x5B}, {0x89, 0x5C}, {0x89, 0x5D}, /* 0x60-0x63 */
 	{0x89, 0x60}, {0x89, 0x61}, {0x89, 0x62}, {0x89, 0x63}, /* 0x64-0x67 */
-	{0x89, 0x64}, {0x89, 0x65}, {0x89, 0x67}, {0x89, 0x68}, /* 0x68-0x6B */
+	{0xF9, 0x24}, {0x89, 0x65}, {0x89, 0x67}, {0x89, 0x68}, /* 0x68-0x6B */
 	{0x89, 0x69}, {0x89, 0x6A}, {0x89, 0x6B}, {0x89, 0x6C}, /* 0x6C-0x6F */
 	{0x89, 0x6D}, {0x89, 0x6E}, {0x89, 0x6F}, {0x89, 0x70}, /* 0x70-0x73 */
 	{0x89, 0x71}, {0x89, 0x72}, {0x89, 0x73}, {0x89, 0x74}, /* 0x74-0x77 */
@@ -5555,7 +5557,7 @@
 	
 	{0x89, 0x7D}, {0x89, 0x7E}, {0x89, 0x80}, {0x89, 0x82}, /* 0x80-0x83 */
 	{0x89, 0x84}, {0x89, 0x85}, {0x89, 0x87}, {0x89, 0x88}, /* 0x84-0x87 */
-	{0x89, 0x89}, {0x89, 0x8A}, {0x89, 0x8B}, {0x89, 0x8C}, /* 0x88-0x8B */
+	{0x89, 0x89}, {0x89, 0x8A}, {0xFA, 0x0A}, {0x89, 0x8C}, /* 0x88-0x8B */
 	{0x89, 0x8D}, {0x89, 0x8E}, {0x89, 0x8F}, {0x89, 0x90}, /* 0x8C-0x8F */
 	{0x89, 0x91}, {0x89, 0x92}, {0x89, 0x93}, {0x89, 0x94}, /* 0x90-0x93 */
 	{0x89, 0x95}, {0x89, 0x96}, {0x89, 0x97}, {0x89, 0x98}, /* 0x94-0x97 */
@@ -5574,11 +5576,11 @@
 	{0x80, 0xF0}, {0x75, 0x91}, {0x6C, 0x82}, {0x5B, 0x9C}, /* 0xC8-0xCB */
 	{0x59, 0xE8}, {0x5F, 0x5D}, {0x69, 0x05}, {0x86, 0x81}, /* 0xCC-0xCF */
 	{0x50, 0x1A}, {0x5D, 0xF2}, {0x4E, 0x59}, {0x77, 0xE3}, /* 0xD0-0xD3 */
-	{0x4E, 0xE5}, {0x82, 0x7A}, {0x62, 0x91}, {0x66, 0x13}, /* 0xD4-0xD7 */
+	{0x4E, 0xE5}, {0x82, 0x7A}, {0x62, 0x91}, {0xF9, 0xE0}, /* 0xD4-0xD7 */
 	{0x90, 0x91}, {0x5C, 0x79}, {0x4E, 0xBF}, {0x5F, 0x79}, /* 0xD8-0xDB */
-	{0x81, 0xC6}, {0x90, 0x38}, {0x80, 0x84}, {0x75, 0xAB}, /* 0xDC-0xDF */
+	{0x81, 0xC6}, {0xFA, 0x25}, {0x80, 0x84}, {0x75, 0xAB}, /* 0xDC-0xDF */
 	{0x4E, 0xA6}, {0x88, 0xD4}, {0x61, 0x0F}, {0x6B, 0xC5}, /* 0xE0-0xE3 */
-	{0x5F, 0xC6}, {0x4E, 0x49}, {0x76, 0xCA}, {0x6E, 0xA2}, /* 0xE4-0xE7 */
+	{0x5F, 0xC6}, {0x4E, 0x49}, {0xFA, 0x17}, {0x6E, 0xA2}, /* 0xE4-0xE7 */
 	{0x8B, 0xE3}, {0x8B, 0xAE}, {0x8C, 0x0A}, {0x8B, 0xD1}, /* 0xE8-0xEB */
 	{0x5F, 0x02}, {0x7F, 0xFC}, {0x7F, 0xCC}, {0x7E, 0xCE}, /* 0xEC-0xEF */
 	{0x83, 0x35}, {0x83, 0x6B}, {0x56, 0xE0}, {0x6B, 0xB7}, /* 0xF0-0xF3 */
@@ -5649,7 +5651,7 @@
 	{0x61, 0x09}, {0x6E, 0x1D}, {0x6E, 0x14}, {0x96, 0x85}, /* 0xE4-0xE7 */
 	{0x4E, 0x88}, {0x5A, 0x31}, {0x96, 0xE8}, {0x4E, 0x0E}, /* 0xE8-0xEB */
 	{0x5C, 0x7F}, {0x79, 0xB9}, {0x5B, 0x87}, {0x8B, 0xED}, /* 0xEC-0xEF */
-	{0x7F, 0xBD}, {0x73, 0x89}, {0x57, 0xDF}, {0x82, 0x8B}, /* 0xF0-0xF3 */
+	{0xFA, 0x1E}, {0x73, 0x89}, {0x57, 0xDF}, {0x82, 0x8B}, /* 0xF0-0xF3 */
 	{0x90, 0xC1}, {0x54, 0x01}, {0x90, 0x47}, {0x55, 0xBB}, /* 0xF4-0xF7 */
 	{0x5C, 0xEA}, {0x5F, 0xA1}, {0x61, 0x08}, {0x6B, 0x32}, /* 0xF8-0xFB */
 	{0x72, 0xF1}, {0x80, 0xB2}, {0x8A, 0x89}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -5749,7 +5751,7 @@
 	{0x8A, 0x9C}, {0x8A, 0x9D}, {0x8A, 0x9E}, {0x8A, 0x9F}, /* 0x58-0x5B */
 	{0x8A, 0xA0}, {0x8A, 0xA1}, {0x8A, 0xA2}, {0x8A, 0xA3}, /* 0x5C-0x5F */
 	{0x8A, 0xA4}, {0x8A, 0xA5}, {0x8A, 0xA6}, {0x8A, 0xA7}, /* 0x60-0x63 */
-	{0x8A, 0xA8}, {0x8A, 0xA9}, {0x8A, 0xAA}, {0x8A, 0xAB}, /* 0x64-0x67 */
+	{0x8A, 0xA8}, {0x8A, 0xA9}, {0xF9, 0xA1}, {0x8A, 0xAB}, /* 0x64-0x67 */
 	{0x8A, 0xAC}, {0x8A, 0xAD}, {0x8A, 0xAE}, {0x8A, 0xAF}, /* 0x68-0x6B */
 	{0x8A, 0xB0}, {0x8A, 0xB1}, {0x8A, 0xB2}, {0x8A, 0xB3}, /* 0x6C-0x6F */
 	{0x8A, 0xB4}, {0x8A, 0xB5}, {0x8A, 0xB6}, {0x8A, 0xB7}, /* 0x70-0x73 */
@@ -5760,15 +5762,15 @@
 	{0x8A, 0xC3}, {0x8A, 0xC4}, {0x8A, 0xC5}, {0x8A, 0xC6}, /* 0x80-0x83 */
 	{0x8A, 0xC7}, {0x8A, 0xC8}, {0x8A, 0xC9}, {0x8A, 0xCA}, /* 0x84-0x87 */
 	{0x8A, 0xCB}, {0x8A, 0xCC}, {0x8A, 0xCD}, {0x8A, 0xCE}, /* 0x88-0x8B */
-	{0x8A, 0xCF}, {0x8A, 0xD0}, {0x8A, 0xD1}, {0x8A, 0xD2}, /* 0x8C-0x8F */
-	{0x8A, 0xD3}, {0x8A, 0xD4}, {0x8A, 0xD5}, {0x8A, 0xD6}, /* 0x90-0x93 */
+	{0x8A, 0xCF}, {0x8A, 0xD0}, {0x8A, 0xD1}, {0xF9, 0x7D}, /* 0x8C-0x8F */
+	{0x8A, 0xD3}, {0x8A, 0xD4}, {0x8A, 0xD5}, {0xF9, 0x41}, /* 0x90-0x93 */
 	{0x8A, 0xD7}, {0x8A, 0xD8}, {0x8A, 0xD9}, {0x8A, 0xDA}, /* 0x94-0x97 */
 	{0x8A, 0xDB}, {0x8A, 0xDC}, {0x8A, 0xDD}, {0x8A, 0xDE}, /* 0x98-0x9B */
 	{0x8A, 0xDF}, {0x8A, 0xE0}, {0x8A, 0xE1}, {0x8A, 0xE2}, /* 0x9C-0x9F */
 	{0x8A, 0xE3}, {0x94, 0xE1}, {0x95, 0xF8}, {0x77, 0x28}, /* 0xA0-0xA3 */
 	{0x68, 0x05}, {0x69, 0xA8}, {0x54, 0x8B}, {0x4E, 0x4D}, /* 0xA4-0xA7 */
 	{0x70, 0xB8}, {0x8B, 0xC8}, {0x64, 0x58}, {0x65, 0x8B}, /* 0xA8-0xAB */
-	{0x5B, 0x85}, {0x7A, 0x84}, {0x50, 0x3A}, {0x5B, 0xE8}, /* 0xAC-0xAF */
+	{0xFA, 0x04}, {0x7A, 0x84}, {0x50, 0x3A}, {0x5B, 0xE8}, /* 0xAC-0xAF */
 	{0x77, 0xBB}, {0x6B, 0xE1}, {0x8A, 0x79}, {0x7C, 0x98}, /* 0xB0-0xB3 */
 	{0x6C, 0xBE}, {0x76, 0xCF}, {0x65, 0xA9}, {0x8F, 0x97}, /* 0xB4-0xB7 */
 	{0x5D, 0x2D}, {0x5C, 0x55}, {0x86, 0x38}, {0x68, 0x08}, /* 0xB8-0xBB */
@@ -5813,8 +5815,8 @@
 	{0x8A, 0xEC}, {0x8A, 0xED}, {0x8A, 0xEE}, {0x8A, 0xEF}, /* 0x48-0x4B */
 	{0x8A, 0xF0}, {0x8A, 0xF1}, {0x8A, 0xF2}, {0x8A, 0xF3}, /* 0x4C-0x4F */
 	{0x8A, 0xF4}, {0x8A, 0xF5}, {0x8A, 0xF6}, {0x8A, 0xF7}, /* 0x50-0x53 */
-	{0x8A, 0xF8}, {0x8A, 0xF9}, {0x8A, 0xFA}, {0x8A, 0xFB}, /* 0x54-0x57 */
-	{0x8A, 0xFC}, {0x8A, 0xFD}, {0x8A, 0xFE}, {0x8A, 0xFF}, /* 0x58-0x5B */
+	{0xFA, 0x22}, {0x8A, 0xF9}, {0x8A, 0xFA}, {0x8A, 0xFB}, /* 0x54-0x57 */
+	{0x8A, 0xFC}, {0x8A, 0xFD}, {0xF9, 0x5D}, {0x8A, 0xFF}, /* 0x58-0x5B */
 	{0x8B, 0x00}, {0x8B, 0x01}, {0x8B, 0x02}, {0x8B, 0x03}, /* 0x5C-0x5F */
 	{0x8B, 0x04}, {0x8B, 0x05}, {0x8B, 0x06}, {0x8B, 0x08}, /* 0x60-0x63 */
 	{0x8B, 0x09}, {0x8B, 0x0A}, {0x8B, 0x0B}, {0x8B, 0x0C}, /* 0x64-0x67 */
@@ -5843,7 +5845,7 @@
 	{0x65, 0xE8}, {0x7E, 0xB8}, {0x5F, 0xD7}, {0x63, 0x1A}, /* 0xBC-0xBF */
 	{0x63, 0xB7}, {0x81, 0xF3}, {0x81, 0xF4}, {0x7F, 0x6E}, /* 0xC0-0xC3 */
 	{0x5E, 0x1C}, {0x5C, 0xD9}, {0x52, 0x36}, {0x66, 0x7A}, /* 0xC4-0xC7 */
-	{0x79, 0xE9}, {0x7A, 0x1A}, {0x8D, 0x28}, {0x70, 0x99}, /* 0xC8-0xCB */
+	{0x79, 0xE9}, {0x7A, 0x1A}, {0x8D, 0x28}, {0xF9, 0xFB}, /* 0xC8-0xCB */
 	{0x75, 0xD4}, {0x6E, 0xDE}, {0x6C, 0xBB}, {0x7A, 0x92}, /* 0xCC-0xCF */
 	{0x4E, 0x2D}, {0x76, 0xC5}, {0x5F, 0xE0}, {0x94, 0x9F}, /* 0xD0-0xD3 */
 	{0x88, 0x77}, {0x7E, 0xC8}, {0x79, 0xCD}, {0x80, 0xBF}, /* 0xD4-0xD7 */
@@ -5880,7 +5882,7 @@
 	{0x8B, 0x4A}, {0x8B, 0x4B}, {0x8B, 0x4C}, {0x8B, 0x4D}, /* 0x44-0x47 */
 	{0x8B, 0x4E}, {0x8B, 0x4F}, {0x8B, 0x50}, {0x8B, 0x51}, /* 0x48-0x4B */
 	{0x8B, 0x52}, {0x8B, 0x53}, {0x8B, 0x54}, {0x8B, 0x55}, /* 0x4C-0x4F */
-	{0x8B, 0x56}, {0x8B, 0x57}, {0x8B, 0x58}, {0x8B, 0x59}, /* 0x50-0x53 */
+	{0x8B, 0x56}, {0x8B, 0x57}, {0xF9, 0xFC}, {0x8B, 0x59}, /* 0x50-0x53 */
 	{0x8B, 0x5A}, {0x8B, 0x5B}, {0x8B, 0x5C}, {0x8B, 0x5D}, /* 0x54-0x57 */
 	{0x8B, 0x5E}, {0x8B, 0x5F}, {0x8B, 0x60}, {0x8B, 0x61}, /* 0x58-0x5B */
 	{0x8B, 0x62}, {0x8B, 0x63}, {0x8B, 0x64}, {0x8B, 0x65}, /* 0x5C-0x5F */
@@ -5890,7 +5892,7 @@
 	{0x8B, 0x74}, {0x8B, 0x75}, {0x8B, 0x76}, {0x8B, 0x77}, /* 0x6C-0x6F */
 	{0x8B, 0x78}, {0x8B, 0x79}, {0x8B, 0x7A}, {0x8B, 0x7B}, /* 0x70-0x73 */
 	{0x8B, 0x7C}, {0x8B, 0x7D}, {0x8B, 0x7E}, {0x8B, 0x7F}, /* 0x74-0x77 */
-	{0x8B, 0x80}, {0x8B, 0x81}, {0x8B, 0x82}, {0x8B, 0x83}, /* 0x78-0x7B */
+	{0xF9, 0x5A}, {0x8B, 0x81}, {0x8B, 0x82}, {0x8B, 0x83}, /* 0x78-0x7B */
 	{0x8B, 0x84}, {0x8B, 0x85}, {0x8B, 0x86}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x8B, 0x87}, {0x8B, 0x88}, {0x8B, 0x89}, {0x8B, 0x8A}, /* 0x80-0x83 */
@@ -5947,14 +5949,14 @@
 	{0x8C, 0x38}, {0x8C, 0x39}, {0x8C, 0x3A}, {0x8C, 0x3B}, /* 0x40-0x43 */
 	{0x8C, 0x3C}, {0x8C, 0x3D}, {0x8C, 0x3E}, {0x8C, 0x3F}, /* 0x44-0x47 */
 	{0x8C, 0x40}, {0x8C, 0x42}, {0x8C, 0x43}, {0x8C, 0x44}, /* 0x48-0x4B */
-	{0x8C, 0x45}, {0x8C, 0x48}, {0x8C, 0x4A}, {0x8C, 0x4B}, /* 0x4C-0x4F */
+	{0x8C, 0x45}, {0xF9, 0x00}, {0x8C, 0x4A}, {0x8C, 0x4B}, /* 0x4C-0x4F */
 	{0x8C, 0x4D}, {0x8C, 0x4E}, {0x8C, 0x4F}, {0x8C, 0x50}, /* 0x50-0x53 */
 	{0x8C, 0x51}, {0x8C, 0x52}, {0x8C, 0x53}, {0x8C, 0x54}, /* 0x54-0x57 */
 	{0x8C, 0x56}, {0x8C, 0x57}, {0x8C, 0x58}, {0x8C, 0x59}, /* 0x58-0x5B */
 	{0x8C, 0x5B}, {0x8C, 0x5C}, {0x8C, 0x5D}, {0x8C, 0x5E}, /* 0x5C-0x5F */
 	{0x8C, 0x5F}, {0x8C, 0x60}, {0x8C, 0x63}, {0x8C, 0x64}, /* 0x60-0x63 */
 	{0x8C, 0x65}, {0x8C, 0x66}, {0x8C, 0x67}, {0x8C, 0x68}, /* 0x64-0x67 */
-	{0x8C, 0x69}, {0x8C, 0x6C}, {0x8C, 0x6D}, {0x8C, 0x6E}, /* 0x68-0x6B */
+	{0x8C, 0x69}, {0xFA, 0x16}, {0x8C, 0x6D}, {0x8C, 0x6E}, /* 0x68-0x6B */
 	{0x8C, 0x6F}, {0x8C, 0x70}, {0x8C, 0x71}, {0x8C, 0x72}, /* 0x6C-0x6F */
 	{0x8C, 0x74}, {0x8C, 0x75}, {0x8C, 0x76}, {0x8C, 0x77}, /* 0x70-0x73 */
 	{0x8C, 0x7B}, {0x8C, 0x7C}, {0x8C, 0x7D}, {0x8C, 0x7E}, /* 0x74-0x77 */
@@ -6017,8 +6019,8 @@
 	{0x8C, 0xB6}, {0x8C, 0xB7}, {0x8C, 0xB8}, {0x8C, 0xB9}, /* 0x48-0x4B */
 	{0x8C, 0xBA}, {0x8C, 0xBB}, {0x8C, 0xBC}, {0x8C, 0xBD}, /* 0x4C-0x4F */
 	{0x8C, 0xBE}, {0x8C, 0xBF}, {0x8C, 0xC0}, {0x8C, 0xC1}, /* 0x50-0x53 */
-	{0x8C, 0xC2}, {0x8C, 0xC3}, {0x8C, 0xC4}, {0x8C, 0xC5}, /* 0x54-0x57 */
-	{0x8C, 0xC6}, {0x8C, 0xC7}, {0x8C, 0xC8}, {0x8C, 0xC9}, /* 0x58-0x5B */
+	{0xF9, 0x48}, {0x8C, 0xC3}, {0x8C, 0xC4}, {0x8C, 0xC5}, /* 0x54-0x57 */
+	{0x8C, 0xC6}, {0x8C, 0xC7}, {0xF9, 0x03}, {0x8C, 0xC9}, /* 0x58-0x5B */
 	{0x8C, 0xCA}, {0x8C, 0xCB}, {0x8C, 0xCC}, {0x8C, 0xCD}, /* 0x5C-0x5F */
 	{0x8C, 0xCE}, {0x8C, 0xCF}, {0x8C, 0xD0}, {0x8C, 0xD1}, /* 0x60-0x63 */
 	{0x8C, 0xD2}, {0x8C, 0xD3}, {0x8C, 0xD4}, {0x8C, 0xD5}, /* 0x64-0x67 */
@@ -6234,7 +6236,7 @@
 	{0x8E, 0xC0}, {0x8E, 0xC1}, {0x8E, 0xC2}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x8E, 0xC3}, {0x8E, 0xC4}, {0x8E, 0xC5}, {0x8E, 0xC6}, /* 0x80-0x83 */
-	{0x8E, 0xC7}, {0x8E, 0xC8}, {0x8E, 0xC9}, {0x8E, 0xCA}, /* 0x84-0x87 */
+	{0x8E, 0xC7}, {0x8E, 0xC8}, {0x8E, 0xC9}, {0xF9, 0x02}, /* 0x84-0x87 */
 	{0x8E, 0xCB}, {0x8E, 0xCC}, {0x8E, 0xCD}, {0x8E, 0xCF}, /* 0x88-0x8B */
 	{0x8E, 0xD0}, {0x8E, 0xD1}, {0x8E, 0xD2}, {0x8E, 0xD3}, /* 0x8C-0x8F */
 	{0x8E, 0xD4}, {0x8E, 0xD5}, {0x8E, 0xD6}, {0x8E, 0xD7}, /* 0x90-0x93 */
@@ -6301,12 +6303,12 @@
 	{0x8F, 0x1D}, {0x8F, 0x1E}, {0x8F, 0x1F}, {0x8F, 0x20}, /* 0x78-0x7B */
 	{0x8F, 0x21}, {0x8F, 0x22}, {0x8F, 0x23}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
-	{0x8F, 0x24}, {0x8F, 0x25}, {0x8F, 0x26}, {0x8F, 0x27}, /* 0x80-0x83 */
-	{0x8F, 0x28}, {0x8F, 0x29}, {0x8F, 0x2A}, {0x8F, 0x2B}, /* 0x84-0x87 */
+	{0x8F, 0x24}, {0x8F, 0x25}, {0xF9, 0x98}, {0x8F, 0x27}, /* 0x80-0x83 */
+	{0x8F, 0x28}, {0x8F, 0x29}, {0xF9, 0xD7}, {0x8F, 0x2B}, /* 0x84-0x87 */
 	{0x8F, 0x2C}, {0x8F, 0x2D}, {0x8F, 0x2E}, {0x8F, 0x2F}, /* 0x88-0x8B */
 	{0x8F, 0x30}, {0x8F, 0x31}, {0x8F, 0x32}, {0x8F, 0x33}, /* 0x8C-0x8F */
 	{0x8F, 0x34}, {0x8F, 0x35}, {0x8F, 0x36}, {0x8F, 0x37}, /* 0x90-0x93 */
-	{0x8F, 0x38}, {0x8F, 0x39}, {0x8F, 0x3A}, {0x8F, 0x3B}, /* 0x94-0x97 */
+	{0x8F, 0x38}, {0x8F, 0x39}, {0x8F, 0x3A}, {0xFA, 0x07}, /* 0x94-0x97 */
 	{0x8F, 0x3C}, {0x8F, 0x3D}, {0x8F, 0x3E}, {0x8F, 0x3F}, /* 0x98-0x9B */
 	{0x8F, 0x40}, {0x8F, 0x41}, {0x8F, 0x42}, {0x8F, 0x43}, /* 0x9C-0x9F */
 	{0x8F, 0x44}, {0x83, 0x68}, {0x83, 0x1B}, {0x83, 0x69}, /* 0xA0-0xA3 */
@@ -6359,7 +6361,7 @@
 	{0x8F, 0x55}, {0x8F, 0x56}, {0x8F, 0x57}, {0x8F, 0x58}, /* 0x50-0x53 */
 	{0x8F, 0x59}, {0x8F, 0x5A}, {0x8F, 0x5B}, {0x8F, 0x5C}, /* 0x54-0x57 */
 	{0x8F, 0x5D}, {0x8F, 0x5E}, {0x8F, 0x5F}, {0x8F, 0x60}, /* 0x58-0x5B */
-	{0x8F, 0x61}, {0x8F, 0x62}, {0x8F, 0x63}, {0x8F, 0x64}, /* 0x5C-0x5F */
+	{0x8F, 0x61}, {0xF9, 0x8D}, {0x8F, 0x63}, {0x8F, 0x64}, /* 0x5C-0x5F */
 	{0x8F, 0x65}, {0x8F, 0x6A}, {0x8F, 0x80}, {0x8F, 0x8C}, /* 0x60-0x63 */
 	{0x8F, 0x92}, {0x8F, 0x9D}, {0x8F, 0xA0}, {0x8F, 0xA1}, /* 0x64-0x67 */
 	{0x8F, 0xA2}, {0x8F, 0xA4}, {0x8F, 0xA5}, {0x8F, 0xA6}, /* 0x68-0x6B */
@@ -6378,7 +6380,7 @@
 	{0x8F, 0xFE}, {0x8F, 0xFF}, {0x90, 0x07}, {0x90, 0x08}, /* 0x98-0x9B */
 	{0x90, 0x0C}, {0x90, 0x0E}, {0x90, 0x13}, {0x90, 0x15}, /* 0x9C-0x9F */
 	{0x90, 0x18}, {0x85, 0x56}, {0x85, 0x3B}, {0x84, 0xFF}, /* 0xA0-0xA3 */
-	{0x84, 0xFC}, {0x85, 0x59}, {0x85, 0x48}, {0x85, 0x68}, /* 0xA4-0xA7 */
+	{0xF9, 0xC2}, {0x85, 0x59}, {0x85, 0x48}, {0x85, 0x68}, /* 0xA4-0xA7 */
 	{0x85, 0x64}, {0x85, 0x5E}, {0x85, 0x7A}, {0x77, 0xA2}, /* 0xA8-0xAB */
 	{0x85, 0x43}, {0x85, 0x72}, {0x85, 0x7B}, {0x85, 0xA4}, /* 0xAC-0xAF */
 	{0x85, 0xA8}, {0x85, 0x87}, {0x85, 0x8F}, {0x85, 0x79}, /* 0xB0-0xB3 */
@@ -6420,7 +6422,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x90, 0x19}, {0x90, 0x1C}, {0x90, 0x23}, {0x90, 0x24}, /* 0x40-0x43 */
+	{0x90, 0x19}, {0x90, 0x1C}, {0xF9, 0x9A}, {0x90, 0x24}, /* 0x40-0x43 */
 	{0x90, 0x25}, {0x90, 0x27}, {0x90, 0x28}, {0x90, 0x29}, /* 0x44-0x47 */
 	{0x90, 0x2A}, {0x90, 0x2B}, {0x90, 0x2C}, {0x90, 0x30}, /* 0x48-0x4B */
 	{0x90, 0x31}, {0x90, 0x32}, {0x90, 0x33}, {0x90, 0x34}, /* 0x4C-0x4F */
@@ -6435,11 +6437,11 @@
 	{0x90, 0x6C}, {0x90, 0x6F}, {0x90, 0x70}, {0x90, 0x71}, /* 0x70-0x73 */
 	{0x90, 0x72}, {0x90, 0x73}, {0x90, 0x76}, {0x90, 0x77}, /* 0x74-0x77 */
 	{0x90, 0x78}, {0x90, 0x79}, {0x90, 0x7A}, {0x90, 0x7B}, /* 0x78-0x7B */
-	{0x90, 0x7C}, {0x90, 0x7E}, {0x90, 0x81}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0xF9, 0xC3}, {0x90, 0x7E}, {0x90, 0x81}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x90, 0x84}, {0x90, 0x85}, {0x90, 0x86}, {0x90, 0x87}, /* 0x80-0x83 */
 	{0x90, 0x89}, {0x90, 0x8A}, {0x90, 0x8C}, {0x90, 0x8D}, /* 0x84-0x87 */
-	{0x90, 0x8E}, {0x90, 0x8F}, {0x90, 0x90}, {0x90, 0x92}, /* 0x88-0x8B */
+	{0x90, 0x8E}, {0xF9, 0x13}, {0x90, 0x90}, {0x90, 0x92}, /* 0x88-0x8B */
 	{0x90, 0x94}, {0x90, 0x96}, {0x90, 0x98}, {0x90, 0x9A}, /* 0x8C-0x8F */
 	{0x90, 0x9C}, {0x90, 0x9E}, {0x90, 0x9F}, {0x90, 0xA0}, /* 0x90-0x93 */
 	{0x90, 0xA4}, {0x90, 0xA5}, {0x90, 0xA7}, {0x90, 0xA8}, /* 0x94-0x97 */
@@ -6533,7 +6535,7 @@
 	{0x56, 0x64}, {0x56, 0x71}, {0x56, 0x6B}, {0x56, 0x7B}, /* 0xE4-0xE7 */
 	{0x56, 0x7C}, {0x56, 0x85}, {0x56, 0x93}, {0x56, 0xAF}, /* 0xE8-0xEB */
 	{0x56, 0xD4}, {0x56, 0xD7}, {0x56, 0xDD}, {0x56, 0xE1}, /* 0xEC-0xEF */
-	{0x56, 0xF5}, {0x56, 0xEB}, {0x56, 0xF9}, {0x56, 0xFF}, /* 0xF0-0xF3 */
+	{0x56, 0xF5}, {0x56, 0xEB}, {0xF9, 0xA9}, {0x56, 0xFF}, /* 0xF0-0xF3 */
 	{0x57, 0x04}, {0x57, 0x0A}, {0x57, 0x09}, {0x57, 0x1C}, /* 0xF4-0xF7 */
 	{0x5E, 0x0F}, {0x5E, 0x19}, {0x5E, 0x14}, {0x5E, 0x11}, /* 0xF8-0xFB */
 	{0x5E, 0x31}, {0x5E, 0x3B}, {0x5E, 0x3C}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -6644,7 +6646,7 @@
 	{0x92, 0x25}, {0x92, 0x26}, {0x92, 0x27}, {0x92, 0x28}, /* 0x80-0x83 */
 	{0x92, 0x29}, {0x92, 0x2A}, {0x92, 0x2B}, {0x92, 0x2C}, /* 0x84-0x87 */
 	{0x92, 0x2D}, {0x92, 0x2E}, {0x92, 0x2F}, {0x92, 0x30}, /* 0x88-0x8B */
-	{0x92, 0x31}, {0x92, 0x32}, {0x92, 0x33}, {0x92, 0x34}, /* 0x8C-0x8F */
+	{0x92, 0x31}, {0x92, 0x32}, {0x92, 0x33}, {0xF9, 0xB1}, /* 0x8C-0x8F */
 	{0x92, 0x35}, {0x92, 0x36}, {0x92, 0x37}, {0x92, 0x38}, /* 0x90-0x93 */
 	{0x92, 0x39}, {0x92, 0x3A}, {0x92, 0x3B}, {0x92, 0x3C}, /* 0x94-0x97 */
 	{0x92, 0x3D}, {0x92, 0x3E}, {0x92, 0x3F}, {0x92, 0x40}, /* 0x98-0x9B */
@@ -6783,7 +6785,7 @@
 	{0x92, 0xF5}, {0x92, 0xF6}, {0x92, 0xF7}, {0x92, 0xF8}, /* 0x8C-0x8F */
 	{0x92, 0xF9}, {0x92, 0xFA}, {0x92, 0xFB}, {0x92, 0xFC}, /* 0x90-0x93 */
 	{0x92, 0xFD}, {0x92, 0xFE}, {0x92, 0xFF}, {0x93, 0x00}, /* 0x94-0x97 */
-	{0x93, 0x01}, {0x93, 0x02}, {0x93, 0x03}, {0x93, 0x04}, /* 0x98-0x9B */
+	{0x93, 0x01}, {0x93, 0x02}, {0x93, 0x03}, {0xF9, 0x3F}, /* 0x98-0x9B */
 	{0x93, 0x05}, {0x93, 0x06}, {0x93, 0x07}, {0x93, 0x08}, /* 0x9C-0x9F */
 	{0x93, 0x09}, {0x6D, 0x39}, {0x6D, 0x27}, {0x6D, 0x0C}, /* 0xA0-0xA3 */
 	{0x6D, 0x43}, {0x6D, 0x48}, {0x6D, 0x07}, {0x6D, 0x04}, /* 0xA4-0xA7 */
@@ -6845,7 +6847,7 @@
 	{0x93, 0x43}, {0x93, 0x44}, {0x93, 0x45}, {0x93, 0x46}, /* 0x78-0x7B */
 	{0x93, 0x47}, {0x93, 0x48}, {0x93, 0x49}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
-	{0x93, 0x4A}, {0x93, 0x4B}, {0x93, 0x4C}, {0x93, 0x4D}, /* 0x80-0x83 */
+	{0xF9, 0x9B}, {0x93, 0x4B}, {0x93, 0x4C}, {0x93, 0x4D}, /* 0x80-0x83 */
 	{0x93, 0x4E}, {0x93, 0x4F}, {0x93, 0x50}, {0x93, 0x51}, /* 0x84-0x87 */
 	{0x93, 0x52}, {0x93, 0x53}, {0x93, 0x54}, {0x93, 0x55}, /* 0x88-0x8B */
 	{0x93, 0x56}, {0x93, 0x57}, {0x93, 0x58}, {0x93, 0x59}, /* 0x8C-0x8F */
@@ -6860,7 +6862,7 @@
 	{0x70, 0x4F}, {0x70, 0x5E}, {0x5B, 0x80}, {0x5B, 0x84}, /* 0xB0-0xB3 */
 	{0x5B, 0x95}, {0x5B, 0x93}, {0x5B, 0xA5}, {0x5B, 0xB8}, /* 0xB4-0xB7 */
 	{0x75, 0x2F}, {0x9A, 0x9E}, {0x64, 0x34}, {0x5B, 0xE4}, /* 0xB8-0xBB */
-	{0x5B, 0xEE}, {0x89, 0x30}, {0x5B, 0xF0}, {0x8E, 0x47}, /* 0xBC-0xBF */
+	{0xF9, 0xBC}, {0x89, 0x30}, {0x5B, 0xF0}, {0x8E, 0x47}, /* 0xBC-0xBF */
 	{0x8B, 0x07}, {0x8F, 0xB6}, {0x8F, 0xD3}, {0x8F, 0xD5}, /* 0xC0-0xC3 */
 	{0x8F, 0xE5}, {0x8F, 0xEE}, {0x8F, 0xE4}, {0x8F, 0xE9}, /* 0xC4-0xC7 */
 	{0x8F, 0xE6}, {0x8F, 0xF3}, {0x8F, 0xE8}, {0x90, 0x05}, /* 0xC8-0xCB */
@@ -7009,7 +7011,7 @@
 	{0x73, 0x9F}, {0x73, 0xCF}, {0x73, 0xC2}, {0x73, 0xD1}, /* 0xE4-0xE7 */
 	{0x73, 0xB7}, {0x73, 0xB3}, {0x73, 0xC0}, {0x73, 0xC9}, /* 0xE8-0xEB */
 	{0x73, 0xC8}, {0x73, 0xE5}, {0x73, 0xD9}, {0x98, 0x7C}, /* 0xEC-0xEF */
-	{0x74, 0x0A}, {0x73, 0xE9}, {0x73, 0xE7}, {0x73, 0xDE}, /* 0xF0-0xF3 */
+	{0x74, 0x0A}, {0x73, 0xE9}, {0x73, 0xE7}, {0xF9, 0x17}, /* 0xF0-0xF3 */
 	{0x73, 0xBA}, {0x73, 0xF2}, {0x74, 0x0F}, {0x74, 0x2A}, /* 0xF4-0xF7 */
 	{0x74, 0x5B}, {0x74, 0x26}, {0x74, 0x25}, {0x74, 0x28}, /* 0xF8-0xFB */
 	{0x74, 0x30}, {0x74, 0x2E}, {0x74, 0x2C}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -7117,7 +7119,7 @@
 	{0x95, 0xA4}, {0x95, 0xA5}, {0x95, 0xA6}, {0x95, 0xA7}, /* 0x78-0x7B */
 	{0x95, 0xA8}, {0x95, 0xA9}, {0x95, 0xAA}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
-	{0x95, 0xAB}, {0x95, 0xAC}, {0x95, 0xAD}, {0x95, 0xAE}, /* 0x80-0x83 */
+	{0x95, 0xAB}, {0x95, 0xAC}, {0xF9, 0x86}, {0x95, 0xAE}, /* 0x80-0x83 */
 	{0x95, 0xAF}, {0x95, 0xB0}, {0x95, 0xB1}, {0x95, 0xB2}, /* 0x84-0x87 */
 	{0x95, 0xB3}, {0x95, 0xB4}, {0x95, 0xB5}, {0x95, 0xB6}, /* 0x88-0x8B */
 	{0x95, 0xB7}, {0x95, 0xB8}, {0x95, 0xB9}, {0x95, 0xBA}, /* 0x8C-0x8F */
@@ -7189,7 +7191,7 @@
 	{0x96, 0x5D}, {0x96, 0x5E}, {0x96, 0x60}, {0x96, 0x63}, /* 0x84-0x87 */
 	{0x96, 0x65}, {0x96, 0x66}, {0x96, 0x6B}, {0x96, 0x6D}, /* 0x88-0x8B */
 	{0x96, 0x6E}, {0x96, 0x6F}, {0x96, 0x70}, {0x96, 0x71}, /* 0x8C-0x8F */
-	{0x96, 0x73}, {0x96, 0x78}, {0x96, 0x79}, {0x96, 0x7A}, /* 0x90-0x93 */
+	{0x96, 0x73}, {0xF9, 0xD3}, {0x96, 0x79}, {0x96, 0x7A}, /* 0x90-0x93 */
 	{0x96, 0x7B}, {0x96, 0x7C}, {0x96, 0x7D}, {0x96, 0x7E}, /* 0x94-0x97 */
 	{0x96, 0x7F}, {0x96, 0x80}, {0x96, 0x81}, {0x96, 0x82}, /* 0x98-0x9B */
 	{0x96, 0x83}, {0x96, 0x84}, {0x96, 0x87}, {0x96, 0x89}, /* 0x9C-0x9F */
@@ -7244,13 +7246,13 @@
 	{0x96, 0xA9}, {0x96, 0xAA}, {0x96, 0xAB}, {0x96, 0xAC}, /* 0x54-0x57 */
 	{0x96, 0xAD}, {0x96, 0xAE}, {0x96, 0xAF}, {0x96, 0xB1}, /* 0x58-0x5B */
 	{0x96, 0xB2}, {0x96, 0xB4}, {0x96, 0xB5}, {0x96, 0xB7}, /* 0x5C-0x5F */
-	{0x96, 0xB8}, {0x96, 0xBA}, {0x96, 0xBB}, {0x96, 0xBF}, /* 0x60-0x63 */
+	{0xF9, 0xB8}, {0x96, 0xBA}, {0x96, 0xBB}, {0x96, 0xBF}, /* 0x60-0x63 */
 	{0x96, 0xC2}, {0x96, 0xC3}, {0x96, 0xC8}, {0x96, 0xCA}, /* 0x64-0x67 */
 	{0x96, 0xCB}, {0x96, 0xD0}, {0x96, 0xD1}, {0x96, 0xD3}, /* 0x68-0x6B */
 	{0x96, 0xD4}, {0x96, 0xD6}, {0x96, 0xD7}, {0x96, 0xD8}, /* 0x6C-0x6F */
 	{0x96, 0xD9}, {0x96, 0xDA}, {0x96, 0xDB}, {0x96, 0xDC}, /* 0x70-0x73 */
 	{0x96, 0xDD}, {0x96, 0xDE}, {0x96, 0xDF}, {0x96, 0xE1}, /* 0x74-0x77 */
-	{0x96, 0xE2}, {0x96, 0xE3}, {0x96, 0xE4}, {0x96, 0xE5}, /* 0x78-0x7B */
+	{0xF9, 0xEA}, {0x96, 0xE3}, {0x96, 0xE4}, {0x96, 0xE5}, /* 0x78-0x7B */
 	{0x96, 0xE6}, {0x96, 0xE7}, {0x96, 0xEB}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x96, 0xEC}, {0x96, 0xED}, {0x96, 0xEE}, {0x96, 0xF0}, /* 0x80-0x83 */
@@ -7312,7 +7314,7 @@
 	{0x97, 0x3B}, {0x97, 0x3C}, {0x97, 0x3D}, {0x97, 0x3F}, /* 0x54-0x57 */
 	{0x97, 0x40}, {0x97, 0x41}, {0x97, 0x42}, {0x97, 0x43}, /* 0x58-0x5B */
 	{0x97, 0x44}, {0x97, 0x45}, {0x97, 0x46}, {0x97, 0x47}, /* 0x5C-0x5F */
-	{0x97, 0x48}, {0x97, 0x49}, {0x97, 0x4A}, {0x97, 0x4B}, /* 0x60-0x63 */
+	{0xF9, 0xB3}, {0x97, 0x49}, {0x97, 0x4A}, {0x97, 0x4B}, /* 0x60-0x63 */
 	{0x97, 0x4C}, {0x97, 0x4D}, {0x97, 0x4E}, {0x97, 0x4F}, /* 0x64-0x67 */
 	{0x97, 0x50}, {0x97, 0x51}, {0x97, 0x54}, {0x97, 0x55}, /* 0x68-0x6B */
 	{0x97, 0x57}, {0x97, 0x58}, {0x97, 0x5A}, {0x97, 0x5C}, /* 0x6C-0x6F */
@@ -7442,7 +7444,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x98, 0x0F}, {0x98, 0x10}, {0x98, 0x11}, {0x98, 0x12}, /* 0x40-0x43 */
 	{0x98, 0x13}, {0x98, 0x14}, {0x98, 0x15}, {0x98, 0x16}, /* 0x44-0x47 */
-	{0x98, 0x17}, {0x98, 0x18}, {0x98, 0x19}, {0x98, 0x1A}, /* 0x48-0x4B */
+	{0x98, 0x17}, {0xF9, 0xB4}, {0x98, 0x19}, {0x98, 0x1A}, /* 0x48-0x4B */
 	{0x98, 0x1B}, {0x98, 0x1C}, {0x98, 0x1D}, {0x98, 0x1E}, /* 0x4C-0x4F */
 	{0x98, 0x1F}, {0x98, 0x20}, {0x98, 0x21}, {0x98, 0x22}, /* 0x50-0x53 */
 	{0x98, 0x23}, {0x98, 0x24}, {0x98, 0x25}, {0x98, 0x26}, /* 0x54-0x57 */
@@ -7461,7 +7463,7 @@
 	{0x98, 0x52}, {0x98, 0x53}, {0x98, 0x54}, {0x98, 0x55}, /* 0x84-0x87 */
 	{0x98, 0x56}, {0x98, 0x57}, {0x98, 0x58}, {0x98, 0x59}, /* 0x88-0x8B */
 	{0x98, 0x5A}, {0x98, 0x5B}, {0x98, 0x5C}, {0x98, 0x5D}, /* 0x8C-0x8F */
-	{0x98, 0x5E}, {0x98, 0x5F}, {0x98, 0x60}, {0x98, 0x61}, /* 0x90-0x93 */
+	{0xF9, 0xD0}, {0x98, 0x5F}, {0x98, 0x60}, {0x98, 0x61}, /* 0x90-0x93 */
 	{0x98, 0x62}, {0x98, 0x63}, {0x98, 0x64}, {0x98, 0x65}, /* 0x94-0x97 */
 	{0x98, 0x66}, {0x98, 0x67}, {0x98, 0x68}, {0x98, 0x69}, /* 0x98-0x9B */
 	{0x98, 0x6A}, {0x98, 0x6B}, {0x98, 0x6C}, {0x98, 0x6D}, /* 0x9C-0x9F */
@@ -7472,7 +7474,7 @@
 	{0x75, 0x4E}, {0x75, 0x4B}, {0x75, 0x48}, {0x75, 0x5B}, /* 0xB0-0xB3 */
 	{0x75, 0x72}, {0x75, 0x79}, {0x75, 0x83}, {0x7F, 0x58}, /* 0xB4-0xB7 */
 	{0x7F, 0x61}, {0x7F, 0x5F}, {0x8A, 0x48}, {0x7F, 0x68}, /* 0xB8-0xBB */
-	{0x7F, 0x74}, {0x7F, 0x71}, {0x7F, 0x79}, {0x7F, 0x81}, /* 0xBC-0xBF */
+	{0x7F, 0x74}, {0x7F, 0x71}, {0xF9, 0xE6}, {0x7F, 0x81}, /* 0xBC-0xBF */
 	{0x7F, 0x7E}, {0x76, 0xCD}, {0x76, 0xE5}, {0x88, 0x32}, /* 0xC0-0xC3 */
 	{0x94, 0x85}, {0x94, 0x86}, {0x94, 0x87}, {0x94, 0x8B}, /* 0xC4-0xC7 */
 	{0x94, 0x8A}, {0x94, 0x8C}, {0x94, 0x8D}, {0x94, 0x8F}, /* 0xC8-0xCB */
@@ -7527,10 +7529,10 @@
 	
 	{0x98, 0xE5}, {0x98, 0xE6}, {0x98, 0xE9}, {0x98, 0xEA}, /* 0x80-0x83 */
 	{0x98, 0xEB}, {0x98, 0xEC}, {0x98, 0xED}, {0x98, 0xEE}, /* 0x84-0x87 */
-	{0x98, 0xEF}, {0x98, 0xF0}, {0x98, 0xF1}, {0x98, 0xF2}, /* 0x88-0x8B */
+	{0xFA, 0x2A}, {0x98, 0xF0}, {0x98, 0xF1}, {0x98, 0xF2}, /* 0x88-0x8B */
 	{0x98, 0xF3}, {0x98, 0xF4}, {0x98, 0xF5}, {0x98, 0xF6}, /* 0x8C-0x8F */
 	{0x98, 0xF7}, {0x98, 0xF8}, {0x98, 0xF9}, {0x98, 0xFA}, /* 0x90-0x93 */
-	{0x98, 0xFB}, {0x98, 0xFC}, {0x98, 0xFD}, {0x98, 0xFE}, /* 0x94-0x97 */
+	{0x98, 0xFB}, {0xFA, 0x2B}, {0x98, 0xFD}, {0x98, 0xFE}, /* 0x94-0x97 */
 	{0x98, 0xFF}, {0x99, 0x00}, {0x99, 0x01}, {0x99, 0x02}, /* 0x98-0x9B */
 	{0x99, 0x03}, {0x99, 0x04}, {0x99, 0x05}, {0x99, 0x06}, /* 0x9C-0x9F */
 	{0x99, 0x07}, {0x94, 0xE9}, {0x94, 0xEB}, {0x94, 0xEE}, /* 0xA0-0xA3 */
@@ -7583,7 +7585,7 @@
 	{0x99, 0x1A}, {0x99, 0x1B}, {0x99, 0x1C}, {0x99, 0x1D}, /* 0x50-0x53 */
 	{0x99, 0x1E}, {0x99, 0x1F}, {0x99, 0x20}, {0x99, 0x21}, /* 0x54-0x57 */
 	{0x99, 0x22}, {0x99, 0x23}, {0x99, 0x24}, {0x99, 0x25}, /* 0x58-0x5B */
-	{0x99, 0x26}, {0x99, 0x27}, {0x99, 0x28}, {0x99, 0x29}, /* 0x5C-0x5F */
+	{0x99, 0x26}, {0x99, 0x27}, {0xFA, 0x2C}, {0x99, 0x29}, /* 0x5C-0x5F */
 	{0x99, 0x2A}, {0x99, 0x2B}, {0x99, 0x2C}, {0x99, 0x2D}, /* 0x60-0x63 */
 	{0x99, 0x2F}, {0x99, 0x30}, {0x99, 0x31}, {0x99, 0x32}, /* 0x64-0x67 */
 	{0x99, 0x33}, {0x99, 0x34}, {0x99, 0x35}, {0x99, 0x36}, /* 0x68-0x6B */
@@ -7667,7 +7669,7 @@
 	{0x99, 0xE5}, {0x99, 0xE6}, {0x99, 0xE7}, {0x99, 0xE8}, /* 0x8C-0x8F */
 	{0x99, 0xE9}, {0x99, 0xEA}, {0x99, 0xEB}, {0x99, 0xEC}, /* 0x90-0x93 */
 	{0x99, 0xED}, {0x99, 0xEE}, {0x99, 0xEF}, {0x99, 0xF0}, /* 0x94-0x97 */
-	{0x99, 0xF1}, {0x99, 0xF2}, {0x99, 0xF3}, {0x99, 0xF4}, /* 0x98-0x9B */
+	{0xF9, 0x1A}, {0x99, 0xF2}, {0x99, 0xF3}, {0x99, 0xF4}, /* 0x98-0x9B */
 	{0x99, 0xF5}, {0x99, 0xF6}, {0x99, 0xF7}, {0x99, 0xF8}, /* 0x9C-0x9F */
 	{0x99, 0xF9}, {0x76, 0x1B}, {0x76, 0x3C}, {0x76, 0x22}, /* 0xA0-0xA3 */
 	{0x76, 0x20}, {0x76, 0x40}, {0x76, 0x2D}, {0x76, 0x30}, /* 0xA4-0xA7 */
@@ -7690,7 +7692,7 @@
 	{0x80, 0x14}, {0x80, 0x16}, {0x80, 0x1C}, {0x80, 0x20}, /* 0xE8-0xEB */
 	{0x80, 0x22}, {0x80, 0x25}, {0x80, 0x26}, {0x80, 0x27}, /* 0xEC-0xEF */
 	{0x80, 0x29}, {0x80, 0x28}, {0x80, 0x31}, {0x80, 0x0B}, /* 0xF0-0xF3 */
-	{0x80, 0x35}, {0x80, 0x43}, {0x80, 0x46}, {0x80, 0x4D}, /* 0xF4-0xF7 */
+	{0x80, 0x35}, {0x80, 0x43}, {0xF9, 0xB0}, {0x80, 0x4D}, /* 0xF4-0xF7 */
 	{0x80, 0x52}, {0x80, 0x69}, {0x80, 0x71}, {0x89, 0x83}, /* 0xF8-0xFB */
 	{0x98, 0x78}, {0x98, 0x80}, {0x98, 0x83}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -7784,7 +7786,7 @@
 	{0x9A, 0x5E}, {0x9A, 0x5F}, {0x9A, 0x60}, {0x9A, 0x61}, /* 0x44-0x47 */
 	{0x9A, 0x62}, {0x9A, 0x63}, {0x9A, 0x64}, {0x9A, 0x65}, /* 0x48-0x4B */
 	{0x9A, 0x66}, {0x9A, 0x67}, {0x9A, 0x68}, {0x9A, 0x69}, /* 0x4C-0x4F */
-	{0x9A, 0x6A}, {0x9A, 0x6B}, {0x9A, 0x72}, {0x9A, 0x83}, /* 0x50-0x53 */
+	{0xF9, 0x87}, {0x9A, 0x6B}, {0x9A, 0x72}, {0x9A, 0x83}, /* 0x50-0x53 */
 	{0x9A, 0x89}, {0x9A, 0x8D}, {0x9A, 0x8E}, {0x9A, 0x94}, /* 0x54-0x57 */
 	{0x9A, 0x95}, {0x9A, 0x99}, {0x9A, 0xA6}, {0x9A, 0xA9}, /* 0x58-0x5B */
 	{0x9A, 0xAA}, {0x9A, 0xAB}, {0x9A, 0xAC}, {0x9A, 0xAD}, /* 0x5C-0x5F */
@@ -7817,7 +7819,7 @@
 	{0x7A, 0xFD}, {0x7B, 0x08}, {0x7B, 0x03}, {0x7B, 0x04}, /* 0xC4-0xC7 */
 	{0x7B, 0x15}, {0x7B, 0x0A}, {0x7B, 0x2B}, {0x7B, 0x0F}, /* 0xC8-0xCB */
 	{0x7B, 0x47}, {0x7B, 0x38}, {0x7B, 0x2A}, {0x7B, 0x19}, /* 0xCC-0xCF */
-	{0x7B, 0x2E}, {0x7B, 0x31}, {0x7B, 0x20}, {0x7B, 0x25}, /* 0xD0-0xD3 */
+	{0x7B, 0x2E}, {0x7B, 0x31}, {0xF9, 0xF8}, {0x7B, 0x25}, /* 0xD0-0xD3 */
 	{0x7B, 0x24}, {0x7B, 0x33}, {0x7B, 0x3E}, {0x7B, 0x1E}, /* 0xD4-0xD7 */
 	{0x7B, 0x58}, {0x7B, 0x5A}, {0x7B, 0x45}, {0x7B, 0x75}, /* 0xD8-0xDB */
 	{0x7B, 0x4C}, {0x7B, 0x5D}, {0x7B, 0x60}, {0x7B, 0x6E}, /* 0xDC-0xDF */
@@ -7870,7 +7872,7 @@
 	{0x9B, 0x63}, {0x9B, 0x64}, {0x9B, 0x65}, {0x9B, 0x66}, /* 0x88-0x8B */
 	{0x9B, 0x67}, {0x9B, 0x68}, {0x9B, 0x69}, {0x9B, 0x6A}, /* 0x8C-0x8F */
 	{0x9B, 0x6B}, {0x9B, 0x6C}, {0x9B, 0x6D}, {0x9B, 0x6E}, /* 0x90-0x93 */
-	{0x9B, 0x6F}, {0x9B, 0x70}, {0x9B, 0x71}, {0x9B, 0x72}, /* 0x94-0x97 */
+	{0xF9, 0x39}, {0x9B, 0x70}, {0x9B, 0x71}, {0x9B, 0x72}, /* 0x94-0x97 */
 	{0x9B, 0x73}, {0x9B, 0x74}, {0x9B, 0x75}, {0x9B, 0x76}, /* 0x98-0x9B */
 	{0x9B, 0x77}, {0x9B, 0x78}, {0x9B, 0x79}, {0x9B, 0x7A}, /* 0x9C-0x9F */
 	{0x9B, 0x7B}, {0x7C, 0x1F}, {0x7C, 0x2A}, {0x7C, 0x26}, /* 0xA0-0xA3 */
@@ -7946,7 +7948,7 @@
 	{0x91, 0x72}, {0x91, 0x74}, {0x91, 0x79}, {0x91, 0x8C}, /* 0xA8-0xAB */
 	{0x91, 0x85}, {0x91, 0x90}, {0x91, 0x8D}, {0x91, 0x91}, /* 0xAC-0xAF */
 	{0x91, 0xA2}, {0x91, 0xA3}, {0x91, 0xAA}, {0x91, 0xAD}, /* 0xB0-0xB3 */
-	{0x91, 0xAE}, {0x91, 0xAF}, {0x91, 0xB5}, {0x91, 0xB4}, /* 0xB4-0xB7 */
+	{0x91, 0xAE}, {0x91, 0xAF}, {0x91, 0xB5}, {0xF9, 0xB7}, /* 0xB4-0xB7 */
 	{0x91, 0xBA}, {0x8C, 0x55}, {0x9E, 0x7E}, {0x8D, 0xB8}, /* 0xB8-0xBB */
 	{0x8D, 0xEB}, {0x8E, 0x05}, {0x8E, 0x59}, {0x8E, 0x69}, /* 0xBC-0xBF */
 	{0x8D, 0xB5}, {0x8D, 0xBF}, {0x8D, 0xBC}, {0x8D, 0xBA}, /* 0xC0-0xC3 */
@@ -8058,7 +8060,7 @@
 	{0x9C, 0x48}, {0x9C, 0x49}, {0x9C, 0x4A}, {0x9C, 0x4B}, /* 0x4C-0x4F */
 	{0x9C, 0x4C}, {0x9C, 0x4D}, {0x9C, 0x4E}, {0x9C, 0x4F}, /* 0x50-0x53 */
 	{0x9C, 0x50}, {0x9C, 0x51}, {0x9C, 0x52}, {0x9C, 0x53}, /* 0x54-0x57 */
-	{0x9C, 0x54}, {0x9C, 0x55}, {0x9C, 0x56}, {0x9C, 0x57}, /* 0x58-0x5B */
+	{0x9C, 0x54}, {0x9C, 0x55}, {0x9C, 0x56}, {0xF9, 0xF2}, /* 0x58-0x5B */
 	{0x9C, 0x58}, {0x9C, 0x59}, {0x9C, 0x5A}, {0x9C, 0x5B}, /* 0x5C-0x5F */
 	{0x9C, 0x5C}, {0x9C, 0x5D}, {0x9C, 0x5E}, {0x9C, 0x5F}, /* 0x60-0x63 */
 	{0x9C, 0x60}, {0x9C, 0x61}, {0x9C, 0x62}, {0x9C, 0x63}, /* 0x64-0x67 */
@@ -8095,7 +8097,7 @@
 	{0x9B, 0x08}, {0x9B, 0x0F}, {0x9B, 0x13}, {0x9B, 0x1F}, /* 0xDC-0xDF */
 	{0x9B, 0x23}, {0x9E, 0xBD}, {0x9E, 0xBE}, {0x7E, 0x3B}, /* 0xE0-0xE3 */
 	{0x9E, 0x82}, {0x9E, 0x87}, {0x9E, 0x88}, {0x9E, 0x8B}, /* 0xE4-0xE7 */
-	{0x9E, 0x92}, {0x93, 0xD6}, {0x9E, 0x9D}, {0x9E, 0x9F}, /* 0xE8-0xEB */
+	{0x9E, 0x92}, {0x93, 0xD6}, {0x9E, 0x9D}, {0xF9, 0xF3}, /* 0xE8-0xEB */
 	{0x9E, 0xDB}, {0x9E, 0xDC}, {0x9E, 0xDD}, {0x9E, 0xE0}, /* 0xEC-0xEF */
 	{0x9E, 0xDF}, {0x9E, 0xE2}, {0x9E, 0xE9}, {0x9E, 0xE7}, /* 0xF0-0xF3 */
 	{0x9E, 0xE5}, {0x9E, 0xEA}, {0x9E, 0xEF}, {0x9F, 0x22}, /* 0xF4-0xF7 */
@@ -8260,7 +8262,7 @@
 	{0x9D, 0xA7}, {0x9D, 0xA8}, {0x9D, 0xA9}, {0x9D, 0xAA}, /* 0x44-0x47 */
 	{0x9D, 0xAB}, {0x9D, 0xAC}, {0x9D, 0xAD}, {0x9D, 0xAE}, /* 0x48-0x4B */
 	{0x9D, 0xAF}, {0x9D, 0xB0}, {0x9D, 0xB1}, {0x9D, 0xB2}, /* 0x4C-0x4F */
-	{0x9D, 0xB3}, {0x9D, 0xB4}, {0x9D, 0xB5}, {0x9D, 0xB6}, /* 0x50-0x53 */
+	{0x9D, 0xB3}, {0xFA, 0x2D}, {0x9D, 0xB5}, {0x9D, 0xB6}, /* 0x50-0x53 */
 	{0x9D, 0xB7}, {0x9D, 0xB8}, {0x9D, 0xB9}, {0x9D, 0xBA}, /* 0x54-0x57 */
 	{0x9D, 0xBB}, {0x9D, 0xBC}, {0x9D, 0xBD}, {0x9D, 0xBE}, /* 0x58-0x5B */
 	{0x9D, 0xBF}, {0x9D, 0xC0}, {0x9D, 0xC1}, {0x9D, 0xC2}, /* 0x5C-0x5F */
@@ -8279,7 +8281,7 @@
 	{0x9D, 0xEE}, {0x9D, 0xEF}, {0x9D, 0xF0}, {0x9D, 0xF1}, /* 0x8C-0x8F */
 	{0x9D, 0xF2}, {0x9D, 0xF3}, {0x9D, 0xF4}, {0x9D, 0xF5}, /* 0x90-0x93 */
 	{0x9D, 0xF6}, {0x9D, 0xF7}, {0x9D, 0xF8}, {0x9D, 0xF9}, /* 0x94-0x97 */
-	{0x9D, 0xFA}, {0x9D, 0xFB}, {0x9D, 0xFC}, {0x9D, 0xFD}, /* 0x98-0x9B */
+	{0xF9, 0x3A}, {0x9D, 0xFB}, {0x9D, 0xFC}, {0x9D, 0xFD}, /* 0x98-0x9B */
 	{0x9D, 0xFE}, {0x9D, 0xFF}, {0x9E, 0x00}, {0x9E, 0x01}, /* 0x9C-0x9F */
 	{0x9E, 0x02}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA0-0xA3 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA4-0xA7 */
@@ -8330,7 +8332,7 @@
 	{0x9E, 0x0F}, {0x9E, 0x10}, {0x9E, 0x11}, {0x9E, 0x12}, /* 0x4C-0x4F */
 	{0x9E, 0x13}, {0x9E, 0x14}, {0x9E, 0x15}, {0x9E, 0x16}, /* 0x50-0x53 */
 	{0x9E, 0x17}, {0x9E, 0x18}, {0x9E, 0x19}, {0x9E, 0x1A}, /* 0x54-0x57 */
-	{0x9E, 0x1B}, {0x9E, 0x1C}, {0x9E, 0x1D}, {0x9E, 0x1E}, /* 0x58-0x5B */
+	{0x9E, 0x1B}, {0x9E, 0x1C}, {0x9E, 0x1D}, {0xF9, 0x20}, /* 0x58-0x5B */
 	{0x9E, 0x24}, {0x9E, 0x27}, {0x9E, 0x2E}, {0x9E, 0x30}, /* 0x5C-0x5F */
 	{0x9E, 0x34}, {0x9E, 0x3B}, {0x9E, 0x3C}, {0x9E, 0x40}, /* 0x60-0x63 */
 	{0x9E, 0x4D}, {0x9E, 0x50}, {0x9E, 0x52}, {0x9E, 0x53}, /* 0x64-0x67 */
@@ -8345,7 +8347,7 @@
 	{0x9E, 0x86}, {0x9E, 0x89}, {0x9E, 0x8A}, {0x9E, 0x8C}, /* 0x84-0x87 */
 	{0x9E, 0x8D}, {0x9E, 0x8E}, {0x9E, 0x8F}, {0x9E, 0x90}, /* 0x88-0x8B */
 	{0x9E, 0x91}, {0x9E, 0x94}, {0x9E, 0x95}, {0x9E, 0x96}, /* 0x8C-0x8F */
-	{0x9E, 0x97}, {0x9E, 0x98}, {0x9E, 0x99}, {0x9E, 0x9A}, /* 0x90-0x93 */
+	{0xF9, 0x88}, {0x9E, 0x98}, {0x9E, 0x99}, {0x9E, 0x9A}, /* 0x90-0x93 */
 	{0x9E, 0x9B}, {0x9E, 0x9C}, {0x9E, 0x9E}, {0x9E, 0xA0}, /* 0x94-0x97 */
 	{0x9E, 0xA1}, {0x9E, 0xA2}, {0x9E, 0xA3}, {0x9E, 0xA4}, /* 0x98-0x9B */
 	{0x9E, 0xA5}, {0x9E, 0xA7}, {0x9E, 0xA8}, {0x9E, 0xA9}, /* 0x9C-0x9F */
@@ -8479,10 +8481,10 @@
 	
 	{0x9F, 0x79}, {0x9F, 0x7A}, {0x9F, 0x7B}, {0x9F, 0x7C}, /* 0x80-0x83 */
 	{0x9F, 0x7D}, {0x9F, 0x7E}, {0x9F, 0x81}, {0x9F, 0x82}, /* 0x84-0x87 */
-	{0x9F, 0x8D}, {0x9F, 0x8E}, {0x9F, 0x8F}, {0x9F, 0x90}, /* 0x88-0x8B */
+	{0xF9, 0xC4}, {0x9F, 0x8E}, {0x9F, 0x8F}, {0x9F, 0x90}, /* 0x88-0x8B */
 	{0x9F, 0x91}, {0x9F, 0x92}, {0x9F, 0x93}, {0x9F, 0x94}, /* 0x8C-0x8F */
 	{0x9F, 0x95}, {0x9F, 0x96}, {0x9F, 0x97}, {0x9F, 0x98}, /* 0x90-0x93 */
-	{0x9F, 0x9C}, {0x9F, 0x9D}, {0x9F, 0x9E}, {0x9F, 0xA1}, /* 0x94-0x97 */
+	{0xF9, 0x08}, {0x9F, 0x9D}, {0x9F, 0x9E}, {0x9F, 0xA1}, /* 0x94-0x97 */
 	{0x9F, 0xA2}, {0x9F, 0xA3}, {0x9F, 0xA4}, {0x9F, 0xA5}, /* 0x98-0x9B */
 	{0xF9, 0x2C}, {0xF9, 0x79}, {0xF9, 0x95}, {0xF9, 0xE7}, /* 0x9C-0x9F */
 	{0xF9, 0xF1}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA0-0xA3 */
@@ -8615,17 +8617,17 @@
 };
 
 static unsigned char u2c_01[512] = {
-	0x3F, 0x3F, 0xA8, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0xA8, 0xA1, 0xA8, 0xA1, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA5, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA5, 0xA8, 0xA5, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA7, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA7, 0xA8, 0xA7, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA9, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA9, 0xA8, 0xA9, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
@@ -8634,14 +8636,14 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0xA8, 0xBD, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0xA8, 0xBE, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
-	0x3F, 0x3F, 0xA8, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0xA8, 0xAD, 0xA8, 0xAD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xB1, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xB1, 0xA8, 0xB1, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
@@ -8664,13 +8666,13 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0xA1, 0xCE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0xA3, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0xA8, 0xAB, 0x3F, 0x3F, 0xA8, 0xAF, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0xA8, 0xB3, 0x3F, 0x3F, 0xA8, 0xB5, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0xA8, 0xB6, 0x3F, 0x3F, 0xA8, 0xB7, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0xA8, 0xA3, 0xA8, 0xA3, 0xA8, 0xAB, /* 0xCC-0xCF */
+	0xA8, 0xAB, 0xA8, 0xAF, 0xA8, 0xAF, 0xA8, 0xB3, /* 0xD0-0xD3 */
+	0xA8, 0xB3, 0xA8, 0xB5, 0xA8, 0xB5, 0xA8, 0xB6, /* 0xD4-0xD7 */
+	0xA8, 0xB6, 0xA8, 0xB7, 0xA8, 0xB7, 0xA8, 0xB8, /* 0xD8-0xDB */
 	0xA8, 0xB8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
@@ -8902,7 +8904,7 @@
 	0xA1, 0xEB, 0x3F, 0x3F, 0xA1, 0xE4, 0xA1, 0xE5, /* 0x30-0x33 */
 	0x3F, 0x3F, 0xA8, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xF9, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA3, 0xFE, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
@@ -9029,7 +9031,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xC7, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0xA1, 0xC6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0xA8, 0x4D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xCC, 0x3F, 0x3F, /* 0x18-0x1B */
+	0xA1, 0xE3, 0x3F, 0x3F, 0xA1, 0xCC, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0xA1, 0xD8, 0xA1, 0xDE, 0xA8, 0x4E, /* 0x1C-0x1F */
 	0xA1, 0xCF, 0x3F, 0x3F, 0x3F, 0x3F, 0xA8, 0x4F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0xA1, 0xCE, 0x3F, 0x3F, 0xA1, 0xC4, /* 0x24-0x27 */
@@ -9038,7 +9040,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0xA1, 0xE0, 0xA1, 0xDF, 0xA1, 0xC3, 0xA1, 0xCB, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0xA1, 0xD7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0xA1, 0xAB, 0xA1, 0xD7, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0xA1, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
@@ -9468,10 +9470,10 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xD2, 0xBB, 0xB6, 0xFE, /* 0x90-0x93 */
+	0xC8, 0xFD, 0xCB, 0xC4, 0xC9, 0xCF, 0xD6, 0xD0, /* 0x94-0x97 */
+	0xCF, 0xC2, 0xBC, 0xD7, 0xD2, 0xD2, 0xB1, 0xFB, /* 0x98-0x9B */
+	0xB6, 0xA1, 0xCC, 0xEC, 0xB5, 0xD8, 0xC8, 0xCB, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
@@ -9509,13 +9511,13 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0xA2, 0xE5, 0xA2, 0xE6, 0xA2, 0xE7, 0xA2, 0xE8, /* 0x20-0x23 */
 	0xA2, 0xE9, 0xA2, 0xEA, 0xA2, 0xEB, 0xA2, 0xEC, /* 0x24-0x27 */
-	0xA2, 0xED, 0xA2, 0xEE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0xA9, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xA2, 0xED, 0xA2, 0xEE, 0xD4, 0xC2, 0xBB, 0xF0, /* 0x28-0x2B */
+	0xCB, 0xAE, 0xC4, 0xBE, 0xBD, 0xF0, 0xCD, 0xC1, /* 0x2C-0x2F */
+	0xC8, 0xD5, 0xA9, 0x5A, 0xD3, 0xD0, 0xC9, 0xE7, /* 0x30-0x33 */
+	0xC3, 0xFB, 0xCC, 0xD8, 0xB2, 0xC6, 0xD7, 0xA3, /* 0x34-0x37 */
+	0xC0, 0xCD, 0xB4, 0xFA, 0xBA, 0xF4, 0xD1, 0xA7, /* 0x38-0x3B */
+	0xBC, 0xE0, 0xC6, 0xF3, 0xD7, 0xCA, 0xD0, 0xAD, /* 0x3C-0x3F */
+	0xBC, 0xC0, 0xD0, 0xDD, 0xD7, 0xD4, 0xD6, 0xC1, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
@@ -9532,19 +9534,19 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA9, 0x49, /* 0xA0-0xA3 */
+	0xD2, 0xBB, 0xB6, 0xFE, 0xC8, 0xFD, 0xCB, 0xC4, /* 0x80-0x83 */
+	0xCE, 0xE5, 0xC1, 0xF9, 0xC6, 0xDF, 0xB0, 0xCB, /* 0x84-0x87 */
+	0xBE, 0xC5, 0xCA, 0xAE, 0xD4, 0xC2, 0xBB, 0xF0, /* 0x88-0x8B */
+	0xCB, 0xAE, 0xC4, 0xBE, 0xBD, 0xF0, 0xCD, 0xC1, /* 0x8C-0x8F */
+	0xC8, 0xD5, 0xD6, 0xEA, 0xD3, 0xD0, 0xC9, 0xE7, /* 0x90-0x93 */
+	0xC3, 0xFB, 0xCC, 0xD8, 0xB2, 0xC6, 0xD7, 0xA3, /* 0x94-0x97 */
+	0xC0, 0xCD, 0xC3, 0xD8, 0xC4, 0xD0, 0xC5, 0xAE, /* 0x98-0x9B */
+	0xCA, 0xCA, 0xD3, 0xC5, 0x3F, 0x3F, 0xD7, 0xA2, /* 0x9C-0x9F */
+	0xCF, 0xEE, 0xD0, 0xDD, 0xD0, 0xB4, 0xA9, 0x49, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0xD2, 0xBD, 0xD7, 0xDA, 0xD1, 0xA7, /* 0xA8-0xAB */
+	0xBC, 0xE0, 0xC6, 0xF3, 0xD7, 0xCA, 0xD0, 0xAD, /* 0xAC-0xAF */
+	0xD2, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
@@ -15210,7 +15212,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
-static unsigned char u2c_F9[512] = {
+static unsigned char u2c_DC[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
@@ -15222,7 +15224,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0xFD, 0x9C, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
@@ -15241,7 +15243,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
-	0x3F, 0x3F, 0xFD, 0x9D, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
@@ -15249,7 +15251,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0xFD, 0x9E, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
@@ -15269,28 +15271,96 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFD, 0x9F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
-	0x3F, 0x3F, 0xFD, 0xA0, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
+static unsigned char u2c_F9[512] = {
+	0xD8, 0x4D, 0xB8, 0xFC, 0xDC, 0x87, 0xD9, 0x5A, /* 0x00-0x03 */
+	0xBB, 0xAC, 0xB4, 0xAE, 0xBE, 0xE4, 0xFD, 0x94, /* 0x04-0x07 */
+	0xFD, 0x94, 0xC6, 0xF5, 0xBD, 0xF0, 0xC0, 0xAE, /* 0x08-0x0B */
+	0xC4, 0xCE, 0x91, 0xD0, 0xB0, 0x5D, 0xC1, 0x5F, /* 0x0C-0x0F */
+	0xCC, 0x7D, 0xC2, 0xDD, 0xC2, 0xE3, 0xDF, 0x89, /* 0x10-0x13 */
+	0x98, 0xB7, 0xC2, 0xE5, 0xC0, 0xD3, 0xE7, 0xF3, /* 0x14-0x17 */
+	0xC2, 0xE4, 0xC0, 0xD2, 0xF1, 0x98, 0x81, 0x79, /* 0x18-0x1B */
+	0xC2, 0xD1, 0x99, 0xDA, 0xA0, 0x80, 0xCC, 0x6D, /* 0x1C-0x1F */
+	0xFB, 0x5B, 0x8D, 0xB9, 0x9E, 0x45, 0xCB, 0x7B, /* 0x20-0x23 */
+	0xD2, 0x68, 0xC0, 0xAD, 0xC5, 0x44, 0xCF, 0x9E, /* 0x24-0x27 */
+	0xC0, 0xC8, 0xC0, 0xCA, 0xC0, 0xCB, 0xC0, 0xC7, /* 0x28-0x2B */
+	0xFD, 0x9C, 0x81, 0xED, 0xC0, 0xE4, 0x84, 0xDA, /* 0x2C-0x2F */
+	0x93, 0xEF, 0x99, 0xA9, 0xA0, 0x74, 0xB1, 0x52, /* 0x30-0x33 */
+	0xC0, 0xCF, 0xCC, 0x4A, 0xCC, 0x94, 0xC2, 0xB7, /* 0x34-0x37 */
+	0xC2, 0xB6, 0xF4, 0x94, 0xFA, 0x98, 0xC2, 0xB5, /* 0x38-0x3B */
+	0xB5, 0x93, 0xBE, 0x47, 0xC7, 0x8A, 0xE4, 0x9B, /* 0x3C-0x3F */
+	0xC2, 0xB9, 0xD5, 0x93, 0x89, 0xC5, 0xC5, 0xAA, /* 0x40-0x43 */
+	0xBB, 0x5C, 0xC3, 0x40, 0xC0, 0xCE, 0xC0, 0xDA, /* 0x44-0x47 */
+	0xD9, 0x54, 0xC0, 0xD7, 0x89, 0xBE, 0x8C, 0xD2, /* 0x48-0x4B */
+	0x98, 0xC7, 0x9C, 0x49, 0xC2, 0xA9, 0xC0, 0xDB, /* 0x4C-0x4F */
+	0xBF, 0x7C, 0xC2, 0xAA, 0xC0, 0xD5, 0xC0, 0xDF, /* 0x50-0x53 */
+	0x84, 0x43, 0xC1, 0xE8, 0xB6, 0xA0, 0xBE, 0x63, /* 0x54-0x57 */
+	0xC1, 0xE2, 0xC1, 0xEA, 0xD7, 0x78, 0x92, 0x82, /* 0x58-0x5B */
+	0x98, 0xB7, 0xD6, 0x5A, 0xB5, 0xA4, 0x8C, 0x8E, /* 0x5C-0x5F */
+	0xC5, 0xAD, 0xC2, 0xCA, 0xAE, 0x90, 0xB1, 0xB1, /* 0x60-0x63 */
+	0xB4, 0x91, 0xB1, 0xE3, 0x8F, 0xCD, 0xB2, 0xBB, /* 0x64-0x67 */
+	0xC3, 0xDA, 0x94, 0xB5, 0xCB, 0xF7, 0x85, 0xA2, /* 0x68-0x6B */
+	0xC8, 0xFB, 0xCA, 0xA1, 0xC8, 0x7E, 0xD5, 0x66, /* 0x6C-0x6F */
+	0x9A, 0xA2, 0xB3, 0xBD, 0xC9, 0xF2, 0xCA, 0xB0, /* 0x70-0x73 */
+	0xC8, 0xF4, 0xC2, 0xD3, 0xC2, 0xD4, 0xC1, 0xC1, /* 0x74-0x77 */
+	0x83, 0xC9, 0xFD, 0x9D, 0xC1, 0xBA, 0xBC, 0x5A, /* 0x78-0x7B */
+	0xC1, 0xBC, 0xD5, 0x8F, 0xC1, 0xBF, 0x84, 0xEE, /* 0x7C-0x7F */
+	
+	0x85, 0xCE, 0xC5, 0xAE, 0x8F, 0x5D, 0xC2, 0xC3, /* 0x80-0x83 */
+	0x9E, 0x56, 0xB5, 0x5A, 0xE9, 0x82, 0xF3, 0x50, /* 0x84-0x87 */
+	0xFB, 0x90, 0xC0, 0xE8, 0xC1, 0xA6, 0x95, 0xD1, /* 0x88-0x8B */
+	0x9A, 0x76, 0xDE, 0x5D, 0xC4, 0xEA, 0x91, 0x7A, /* 0x8C-0x8F */
+	0x91, 0xD9, 0x93, 0xD3, 0x9D, 0x69, 0x9F, 0x92, /* 0x90-0x93 */
+	0xAD, 0x49, 0xFD, 0x9E, 0xBE, 0x9A, 0xC2, 0x93, /* 0x94-0x97 */
+	0xDD, 0x82, 0xC9, 0x8F, 0xDF, 0x42, 0xE5, 0x80, /* 0x98-0x9B */
+	0xC1, 0xD0, 0xC1, 0xD3, 0xD1, 0xCA, 0xC1, 0xD2, /* 0x9C-0x9F */
+	0xC1, 0xD1, 0xD5, 0x66, 0xC1, 0xAE, 0xC4, 0xEE, /* 0xA0-0xA3 */
+	0xC4, 0xED, 0x9A, 0x9A, 0xBA, 0x9F, 0xAB, 0x43, /* 0xA4-0xA7 */
+	0xC1, 0xEE, 0xE0, 0xF2, 0x8C, 0x8E, 0x8E, 0x58, /* 0xA8-0xAB */
+	0xC1, 0xAF, 0xC1, 0xE1, 0xAC, 0x93, 0xC1, 0xE7, /* 0xAC-0xAF */
+	0xF1, 0xF6, 0xE2, 0x8F, 0xC1, 0xE3, 0xEC, 0x60, /* 0xB0-0xB3 */
+	0xEE, 0x49, 0xC0, 0xFD, 0xB6, 0x59, 0xF5, 0xB7, /* 0xB4-0xB7 */
+	0xEB, 0x60, 0x90, 0xBA, 0xC1, 0xCB, 0xC1, 0xC5, /* 0xB8-0xBB */
+	0xE5, 0xBC, 0xC4, 0xF2, 0xC1, 0xCF, 0x98, 0xB7, /* 0xBC-0xBF */
+	0xC1, 0xC7, 0xAF, 0x9F, 0xDE, 0xA4, 0xDF, 0x7C, /* 0xC0-0xC3 */
+	0xFD, 0x88, 0x95, 0x9E, 0xC8, 0xEE, 0x84, 0xA2, /* 0xC4-0xC7 */
+	0x96, 0x83, 0xC1, 0xF8, 0xC1, 0xF7, 0xC1, 0xEF, /* 0xC8-0xCB */
+	0xC1, 0xF0, 0xC1, 0xF4, 0xC1, 0xF2, 0xBC, 0x7E, /* 0xCC-0xCF */
+	0xEE, 0x90, 0xC1, 0xF9, 0xC2, 0xBE, 0xEA, 0x91, /* 0xD0-0xD3 */
+	0x82, 0x90, 0x8D, 0x91, 0x9C, 0x53, 0xDD, 0x86, /* 0xD4-0xD7 */
+	0xC2, 0xC9, 0x90, 0xFC, 0xC0, 0xF5, 0xC2, 0xCA, /* 0xD8-0xDB */
+	0xC2, 0xA1, 0xC0, 0xFB, 0xC0, 0xF4, 0xC2, 0xC4, /* 0xDC-0xDF */
+	0xD2, 0xD7, 0xC0, 0xEE, 0xC0, 0xE6, 0xC4, 0xE0, /* 0xE0-0xE3 */
+	0xC0, 0xED, 0xC1, 0xA1, 0xEE, 0xBE, 0xFD, 0x9F, /* 0xE4-0xE7 */
+	0xD1, 0x65, 0xC0, 0xEF, 0xEB, 0x78, 0xC4, 0xE4, /* 0xE8-0xEB */
+	0xC4, 0xE7, 0xC1, 0xDF, 0x9F, 0xFB, 0xAD, 0x55, /* 0xEC-0xEF */
+	0xCC, 0x41, 0xFD, 0xA0, 0xF7, 0x5B, 0xF7, 0xEB, /* 0xF0-0xF3 */
+	0xC1, 0xD6, 0xC1, 0xDC, 0xC5, 0x52, 0xC1, 0xA2, /* 0xF4-0xF7 */
+	0xF3, 0xD2, 0xC1, 0xA3, 0xA0, 0xEE, 0xD6, 0xCB, /* 0xF8-0xFB */
+	0xD7, 0x52, 0xCA, 0xB2, 0xB2, 0xE8, 0xB4, 0xCC, /* 0xFC-0xFF */
+};
+
 static unsigned char u2c_FA[512] = {
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0xC7, 0xD0, 0xB6, 0xC8, 0xCD, 0xD8, 0xCC, 0xC7, /* 0x00-0x03 */
+	0xD5, 0xAC, 0xB6, 0xB4, 0xB1, 0xA9, 0xDD, 0x97, /* 0x04-0x07 */
+	0xD0, 0xD0, 0xBD, 0xB5, 0xD2, 0x8A, 0xC0, 0xAA, /* 0x08-0x0B */
 	0xFE, 0x40, 0xFE, 0x41, 0xFE, 0x42, 0xFE, 0x43, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0xFE, 0x44, 0x3F, 0x3F, 0xFE, 0x45, /* 0x10-0x13 */
-	0xFE, 0x46, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0xFE, 0x47, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xFE, 0x48, /* 0x1C-0x1F */
-	0xFE, 0x49, 0xFE, 0x4A, 0x3F, 0x3F, 0xFE, 0x4B, /* 0x20-0x23 */
-	0xFE, 0x4C, 0x3F, 0x3F, 0x3F, 0x3F, 0xFE, 0x4D, /* 0x24-0x27 */
-	0xFE, 0x4E, 0xFE, 0x4F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x89, 0x56, 0xFE, 0x44, 0xC7, 0xE7, 0xFE, 0x45, /* 0x10-0x13 */
+	0xFE, 0x46, 0x84, 0x44, 0xD8, 0x69, 0xD2, 0xE6, /* 0x14-0x17 */
+	0xFE, 0x47, 0xC9, 0xF1, 0xCF, 0xE9, 0xB8, 0xA3, /* 0x18-0x1B */
+	0xBE, 0xB8, 0xBE, 0xAB, 0xD3, 0xF0, 0xFE, 0x48, /* 0x1C-0x1F */
+	0xFE, 0x49, 0xFE, 0x4A, 0xD6, 0x54, 0xFE, 0x4B, /* 0x20-0x23 */
+	0xFE, 0x4C, 0xD2, 0xDD, 0xB6, 0xBC, 0xFE, 0x4D, /* 0x24-0x27 */
+	0xFE, 0x4E, 0xFE, 0x4F, 0xEF, 0x88, 0xEF, 0x95, /* 0x28-0x2B */
+	0xF0, 0x5E, 0xFA, 0x51, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
@@ -15510,7 +15580,7 @@
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   u2c_DC, NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
@@ -15522,6 +15592,7 @@
 
 	if (boundlen <= 0)
 		return;
+
 	uni2charset = page_uni2charset[ch];
 	*outlen = 0;
 	if (uni2charset){
@@ -15545,6 +15616,7 @@
 
 	ch = rawstring[0];
 	cl = rawstring[1];
+
 	charset2uni = page_charset2uni[ch];
 	if (charset2uni && cl){
 		*uni1 = charset2uni[cl].uni2;
@@ -15577,20 +15649,34 @@
 	NULL
 };
 
+static struct nls_table alias_table = {
+	"gb2312",
+	uni2char,
+	char2uni,
+	inc_use_count,
+	dec_use_count,
+	NULL
+};
+
+
 int __init init_nls_cp936(void)
 {
+	register_nls(&alias_table);
 	return register_nls(&table);
 }
 
 #ifdef MODULE
 int init_module(void)
 {
+
 	return init_nls_cp936();
 }
 
 
 void cleanup_module(void)
 {
+
+	unregister_nls(&alias_table);
 	unregister_nls(&table);
 	return;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/nls/nls_cp949.c linux.17p18/fs/nls/nls_cp949.c
--- linux.vanilla/fs/nls/nls_cp949.c	Sun Jun 11 21:44:21 2000
+++ linux.17p18/fs/nls/nls_cp949.c	Tue Aug  1 07:59:08 2000
@@ -2,7 +2,9 @@
  * linux/fs/nls_cp949.c
  *
  * Charset cp949 translation tables.
- * Generated automatically from the Microsoft
+ * This translation table was generated automatically, the
+ * original table can be download from the Microsoft website.
+ * (http://www.microsoft.com/typography/unicode/unicodecp.htm)
  */
 
 #include <linux/module.h>
@@ -2433,20 +2435,20 @@
 	{0xCA, 0x3A}, {0xCA, 0x3B}, {0xCA, 0x3C}, {0xCA, 0x3D}, /* 0x94-0x97 */
 	{0xCA, 0x3E}, {0xCA, 0x3F}, {0xCA, 0x40}, {0xCA, 0x41}, /* 0x98-0x9B */
 	{0xCA, 0x42}, {0xCA, 0x43}, {0xCA, 0x44}, {0xCA, 0x45}, /* 0x9C-0x9F */
-	{0xCA, 0x46}, {0x31, 0x31}, {0x31, 0x32}, {0x31, 0x33}, /* 0xA0-0xA3 */
-	{0x31, 0x34}, {0x31, 0x35}, {0x31, 0x36}, {0x31, 0x37}, /* 0xA4-0xA7 */
-	{0x31, 0x38}, {0x31, 0x39}, {0x31, 0x3A}, {0x31, 0x3B}, /* 0xA8-0xAB */
-	{0x31, 0x3C}, {0x31, 0x3D}, {0x31, 0x3E}, {0x31, 0x3F}, /* 0xAC-0xAF */
-	{0x31, 0x40}, {0x31, 0x41}, {0x31, 0x42}, {0x31, 0x43}, /* 0xB0-0xB3 */
-	{0x31, 0x44}, {0x31, 0x45}, {0x31, 0x46}, {0x31, 0x47}, /* 0xB4-0xB7 */
-	{0x31, 0x48}, {0x31, 0x49}, {0x31, 0x4A}, {0x31, 0x4B}, /* 0xB8-0xBB */
-	{0x31, 0x4C}, {0x31, 0x4D}, {0x31, 0x4E}, {0x31, 0x4F}, /* 0xBC-0xBF */
-	{0x31, 0x50}, {0x31, 0x51}, {0x31, 0x52}, {0x31, 0x53}, /* 0xC0-0xC3 */
-	{0x31, 0x54}, {0x31, 0x55}, {0x31, 0x56}, {0x31, 0x57}, /* 0xC4-0xC7 */
-	{0x31, 0x58}, {0x31, 0x59}, {0x31, 0x5A}, {0x31, 0x5B}, /* 0xC8-0xCB */
-	{0x31, 0x5C}, {0x31, 0x5D}, {0x31, 0x5E}, {0x31, 0x5F}, /* 0xCC-0xCF */
-	{0x31, 0x60}, {0x31, 0x61}, {0x31, 0x62}, {0x31, 0x63}, /* 0xD0-0xD3 */
-	{0x31, 0x64}, {0x31, 0x65}, {0x31, 0x66}, {0x31, 0x67}, /* 0xD4-0xD7 */
+	{0xCA, 0x46}, {0xFF, 0xA1}, {0xFF, 0xA2}, {0xFF, 0xA3}, /* 0xA0-0xA3 */
+	{0xFF, 0xA4}, {0xFF, 0xA5}, {0xFF, 0xA6}, {0xFF, 0xA7}, /* 0xA4-0xA7 */
+	{0xFF, 0xA8}, {0xFF, 0xA9}, {0xFF, 0xAA}, {0xFF, 0xAB}, /* 0xA8-0xAB */
+	{0xFF, 0xAC}, {0xFF, 0xAD}, {0xFF, 0xAE}, {0xFF, 0xAF}, /* 0xAC-0xAF */
+	{0xFF, 0xB0}, {0xFF, 0xB1}, {0xFF, 0xB2}, {0xFF, 0xB3}, /* 0xB0-0xB3 */
+	{0xFF, 0xB4}, {0xFF, 0xB5}, {0xFF, 0xB6}, {0xFF, 0xB7}, /* 0xB4-0xB7 */
+	{0xFF, 0xB8}, {0xFF, 0xB9}, {0xFF, 0xBA}, {0xFF, 0xBB}, /* 0xB8-0xBB */
+	{0xFF, 0xBC}, {0xFF, 0xBD}, {0xFF, 0xBE}, {0xFF, 0xC2}, /* 0xBC-0xBF */
+	{0xFF, 0xC3}, {0xFF, 0xC4}, {0xFF, 0xC5}, {0xFF, 0xC6}, /* 0xC0-0xC3 */
+	{0xFF, 0xC7}, {0xFF, 0xCA}, {0xFF, 0xCB}, {0xFF, 0xCC}, /* 0xC4-0xC7 */
+	{0xFF, 0xCD}, {0xFF, 0xCE}, {0xFF, 0xCF}, {0xFF, 0xD2}, /* 0xC8-0xCB */
+	{0xFF, 0xD3}, {0xFF, 0xD4}, {0xFF, 0xD5}, {0xFF, 0xD6}, /* 0xCC-0xCF */
+	{0xFF, 0xD7}, {0xFF, 0xDA}, {0xFF, 0xDB}, {0xFF, 0xDC}, /* 0xD0-0xD3 */
+	{0xFF, 0xA0}, {0x31, 0x65}, {0x31, 0x66}, {0x31, 0x67}, /* 0xD4-0xD7 */
 	{0x31, 0x68}, {0x31, 0x69}, {0x31, 0x6A}, {0x31, 0x6B}, /* 0xD8-0xDB */
 	{0x31, 0x6C}, {0x31, 0x6D}, {0x31, 0x6E}, {0x31, 0x6F}, /* 0xDC-0xDF */
 	{0x31, 0x70}, {0x31, 0x71}, {0x31, 0x72}, {0x31, 0x73}, /* 0xE0-0xE3 */
@@ -5228,7 +5230,7 @@
 	{0x5B, 0xEC}, {0x61, 0x63}, {0x68, 0xFA}, {0x6B, 0x3E}, /* 0xB0-0xB3 */
 	{0x70, 0x4C}, {0x74, 0x2F}, {0x74, 0xD8}, {0x7B, 0xA1}, /* 0xB4-0xB7 */
 	{0x7F, 0x50}, {0x83, 0xC5}, {0x89, 0xC0}, {0x8C, 0xAB}, /* 0xB8-0xBB */
-	{0x95, 0xDC}, {0x99, 0x28}, {0x52, 0x2E}, {0x60, 0x5D}, /* 0xBC-0xBF */
+	{0x95, 0xDC}, {0xFA, 0x2C}, {0x52, 0x2E}, {0x60, 0x5D}, /* 0xBC-0xBF */
 	{0x62, 0xEC}, {0x90, 0x02}, {0x4F, 0x8A}, {0x51, 0x49}, /* 0xC0-0xC3 */
 	{0x53, 0x21}, {0x58, 0xD9}, {0x5E, 0xE3}, {0x66, 0xE0}, /* 0xC4-0xC7 */
 	{0x6D, 0x38}, {0x70, 0x9A}, {0x72, 0xC2}, {0x73, 0xD6}, /* 0xC8-0xCB */
@@ -5634,7 +5636,7 @@
 	{0x76, 0xDC}, {0x77, 0x79}, {0x79, 0xB1}, {0x7A, 0x3B}, /* 0xA8-0xAB */
 	{0x84, 0x04}, {0x89, 0xA9}, {0x8C, 0xED}, {0x8D, 0xF3}, /* 0xAC-0xAF */
 	{0x8E, 0x48}, {0x90, 0x03}, {0x90, 0x14}, {0x90, 0x53}, /* 0xB0-0xB3 */
-	{0x90, 0xFD}, {0x93, 0x4D}, {0x96, 0x76}, {0x97, 0xDC}, /* 0xB4-0xB7 */
+	{0xFA, 0x26}, {0x93, 0x4D}, {0x96, 0x76}, {0x97, 0xDC}, /* 0xB4-0xB7 */
 	{0x6B, 0xD2}, {0x70, 0x06}, {0x72, 0x58}, {0x72, 0xA2}, /* 0xB8-0xBB */
 	{0x73, 0x68}, {0x77, 0x63}, {0x79, 0xBF}, {0x7B, 0xE4}, /* 0xBC-0xBF */
 	{0x7E, 0x9B}, {0x8B, 0x80}, {0x58, 0xA9}, {0x60, 0xC7}, /* 0xC0-0xC3 */
@@ -6059,7 +6061,7 @@
 	{0x73, 0xED}, {0x75, 0x54}, {0x76, 0x22}, {0x76, 0xE4}, /* 0xEC-0xEF */
 	{0x76, 0xFC}, {0x78, 0xD0}, {0x78, 0xFB}, {0x79, 0x2C}, /* 0xF0-0xF3 */
 	{0x7D, 0x46}, {0x82, 0x2C}, {0x87, 0xE0}, {0x8F, 0xD4}, /* 0xF4-0xF7 */
-	{0x98, 0x12}, {0x98, 0xEF}, {0x52, 0xC3}, {0x62, 0xD4}, /* 0xF8-0xFB */
+	{0x98, 0x12}, {0xFA, 0x2A}, {0x52, 0xC3}, {0x62, 0xD4}, /* 0xF8-0xFB */
 	{0x64, 0xA5}, {0x6E, 0x24}, {0x6F, 0x51}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -6187,7 +6189,7 @@
 	{0x83, 0xE9}, {0x88, 0xDC}, {0x89, 0x13}, {0x8B, 0x5C}, /* 0xCC-0xCF */
 	{0x8F, 0x14}, {0x4F, 0x0F}, {0x50, 0xD5}, {0x53, 0x10}, /* 0xD0-0xD3 */
 	{0x53, 0x5C}, {0x5B, 0x93}, {0x5F, 0xA9}, {0x67, 0x0D}, /* 0xD4-0xD7 */
-	{0x79, 0x8F}, {0x81, 0x79}, {0x83, 0x2F}, {0x85, 0x14}, /* 0xD8-0xDB */
+	{0xFA, 0x1B}, {0x81, 0x79}, {0x83, 0x2F}, {0x85, 0x14}, /* 0xD8-0xDB */
 	{0x89, 0x07}, {0x89, 0x86}, {0x8F, 0x39}, {0x8F, 0x3B}, /* 0xDC-0xDF */
 	{0x99, 0xA5}, {0x9C, 0x12}, {0x67, 0x2C}, {0x4E, 0x76}, /* 0xE0-0xE3 */
 	{0x4F, 0xF8}, {0x59, 0x49}, {0x5C, 0x01}, {0x5C, 0xEF}, /* 0xE4-0xE7 */
@@ -6331,7 +6333,7 @@
 	{0x82, 0x0D}, {0x83, 0x8E}, {0x84, 0xD1}, {0x86, 0xC7}, /* 0xEC-0xEF */
 	{0x88, 0xDF}, {0x8A, 0x50}, {0x8A, 0x5E}, {0x8B, 0x1D}, /* 0xF0-0xF3 */
 	{0x8C, 0xDC}, {0x8D, 0x66}, {0x8F, 0xAD}, {0x90, 0xAA}, /* 0xF4-0xF7 */
-	{0x98, 0xFC}, {0x99, 0xDF}, {0x9E, 0x9D}, {0x52, 0x4A}, /* 0xF8-0xFB */
+	{0xFA, 0x2B}, {0x99, 0xDF}, {0x9E, 0x9D}, {0x52, 0x4A}, /* 0xF8-0xFB */
 	{0xF9, 0x69}, {0x67, 0x14}, {0xF9, 0x6A}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -6390,7 +6392,7 @@
 	{0x5E, 0x38}, {0x5E, 0x8A}, {0x5E, 0xA0}, {0x5E, 0xC2}, /* 0xC8-0xCB */
 	{0x60, 0xF3}, {0x68, 0x51}, {0x6A, 0x61}, {0x6E, 0x58}, /* 0xCC-0xCF */
 	{0x72, 0x3D}, {0x72, 0x40}, {0x72, 0xC0}, {0x76, 0xF8}, /* 0xD0-0xD3 */
-	{0x79, 0x65}, {0x7B, 0xB1}, {0x7F, 0xD4}, {0x88, 0xF3}, /* 0xD4-0xD7 */
+	{0xFA, 0x1A}, {0x7B, 0xB1}, {0x7F, 0xD4}, {0x88, 0xF3}, /* 0xD4-0xD7 */
 	{0x89, 0xF4}, {0x8A, 0x73}, {0x8C, 0x61}, {0x8C, 0xDE}, /* 0xD8-0xDB */
 	{0x97, 0x1C}, {0x58, 0x5E}, {0x74, 0xBD}, {0x8C, 0xFD}, /* 0xDC-0xDF */
 	{0x55, 0xC7}, {0xF9, 0x6C}, {0x7A, 0x61}, {0x7D, 0x22}, /* 0xE0-0xE3 */
@@ -6667,7 +6669,7 @@
 	{0x8E, 0xFE}, {0x98, 0xDF}, {0x98, 0xFE}, {0x4F, 0x38}, /* 0xDC-0xDF */
 	{0x4F, 0x81}, {0x4F, 0xE1}, {0x54, 0x7B}, {0x5A, 0x20}, /* 0xE0-0xE3 */
 	{0x5B, 0xB8}, {0x61, 0x3C}, {0x65, 0xB0}, {0x66, 0x68}, /* 0xE4-0xE7 */
-	{0x71, 0xFC}, {0x75, 0x33}, {0x79, 0x5E}, {0x7D, 0x33}, /* 0xE8-0xEB */
+	{0x71, 0xFC}, {0x75, 0x33}, {0xFA, 0x19}, {0x7D, 0x33}, /* 0xE8-0xEB */
 	{0x81, 0x4E}, {0x81, 0xE3}, {0x83, 0x98}, {0x85, 0xAA}, /* 0xEC-0xEF */
 	{0x85, 0xCE}, {0x87, 0x03}, {0x8A, 0x0A}, {0x8E, 0xAB}, /* 0xF0-0xF3 */
 	{0x8F, 0x9B}, {0xF9, 0x71}, {0x8F, 0xC5}, {0x59, 0x31}, /* 0xF4-0xF7 */
@@ -6994,7 +6996,7 @@
 	{0x9F, 0x07}, {0x5C, 0x4B}, {0x6C, 0x83}, {0x73, 0x44}, /* 0xA8-0xAB */
 	{0x73, 0x89}, {0x92, 0x3A}, {0x6E, 0xAB}, {0x74, 0x65}, /* 0xAC-0xAF */
 	{0x76, 0x1F}, {0x7A, 0x69}, {0x7E, 0x15}, {0x86, 0x0A}, /* 0xB0-0xB3 */
-	{0x51, 0x40}, {0x58, 0xC5}, {0x64, 0xC1}, {0x74, 0xEE}, /* 0xB4-0xB7 */
+	{0xFA, 0x0C}, {0x58, 0xC5}, {0x64, 0xC1}, {0x74, 0xEE}, /* 0xB4-0xB7 */
 	{0x75, 0x15}, {0x76, 0x70}, {0x7F, 0xC1}, {0x90, 0x95}, /* 0xB8-0xBB */
 	{0x96, 0xCD}, {0x99, 0x54}, {0x6E, 0x26}, {0x74, 0xE6}, /* 0xBC-0xBF */
 	{0x7A, 0xA9}, {0x7A, 0xAA}, {0x81, 0xE5}, {0x86, 0xD9}, /* 0xC0-0xC3 */
@@ -7073,7 +7075,7 @@
 	{0x5B, 0x87}, {0x5B, 0xD3}, {0x5C, 0x24}, {0x61, 0x1A}, /* 0xD4-0xD7 */
 	{0x61, 0x82}, {0x65, 0xF4}, {0x72, 0x5B}, {0x73, 0x97}, /* 0xD8-0xDB */
 	{0x74, 0x40}, {0x76, 0xC2}, {0x79, 0x50}, {0x79, 0x91}, /* 0xDC-0xDF */
-	{0x79, 0xB9}, {0x7D, 0x06}, {0x7F, 0xBD}, {0x82, 0x8B}, /* 0xE0-0xE3 */
+	{0x79, 0xB9}, {0x7D, 0x06}, {0xFA, 0x1E}, {0x82, 0x8B}, /* 0xE0-0xE3 */
 	{0x85, 0xD5}, {0x86, 0x5E}, {0x8F, 0xC2}, {0x90, 0x47}, /* 0xE4-0xE7 */
 	{0x90, 0xF5}, {0x91, 0xEA}, {0x96, 0x85}, {0x96, 0xE8}, /* 0xE8-0xEB */
 	{0x96, 0xE9}, {0x52, 0xD6}, {0x5F, 0x67}, {0x65, 0xED}, /* 0xEC-0xEF */
@@ -7272,7 +7274,7 @@
 	{0xF9, 0xE7}, {0xF9, 0xE8}, {0x8C, 0xBD}, {0x8C, 0xB3}, /* 0xC0-0xC3 */
 	{0x90, 0x87}, {0xF9, 0xE9}, {0xF9, 0xEA}, {0x98, 0xF4}, /* 0xC4-0xC7 */
 	{0x99, 0x0C}, {0xF9, 0xEB}, {0xF9, 0xEC}, {0x70, 0x37}, /* 0xC8-0xCB */
-	{0x76, 0xCA}, {0x7F, 0xCA}, {0x7F, 0xCC}, {0x7F, 0xFC}, /* 0xCC-0xCF */
+	{0xFA, 0x17}, {0x7F, 0xCA}, {0x7F, 0xCC}, {0x7F, 0xFC}, /* 0xCC-0xCF */
 	{0x8B, 0x1A}, {0x4E, 0xBA}, {0x4E, 0xC1}, {0x52, 0x03}, /* 0xD0-0xD3 */
 	{0x53, 0x70}, {0xF9, 0xED}, {0x54, 0xBD}, {0x56, 0xE0}, /* 0xD4-0xD7 */
 	{0x59, 0xFB}, {0x5B, 0xC5}, {0x5F, 0x15}, {0x5F, 0xCD}, /* 0xD8-0xDB */
@@ -7280,7 +7282,7 @@
 	{0x83, 0x35}, {0xF9, 0xF0}, {0x86, 0x93}, {0x8A, 0x8D}, /* 0xE0-0xE3 */
 	{0xF9, 0xF1}, {0x97, 0x6D}, {0x97, 0x77}, {0xF9, 0xF2}, /* 0xE4-0xE7 */
 	{0xF9, 0xF3}, {0x4E, 0x00}, {0x4F, 0x5A}, {0x4F, 0x7E}, /* 0xE8-0xEB */
-	{0x58, 0xF9}, {0x65, 0xE5}, {0x6E, 0xA2}, {0x90, 0x38}, /* 0xEC-0xEF */
+	{0x58, 0xF9}, {0x65, 0xE5}, {0x6E, 0xA2}, {0xFA, 0x25}, /* 0xEC-0xEF */
 	{0x93, 0xB0}, {0x99, 0xB9}, {0x4E, 0xFB}, {0x58, 0xEC}, /* 0xF0-0xF3 */
 	{0x59, 0x8A}, {0x59, 0xD9}, {0x60, 0x41}, {0xF9, 0xF4}, /* 0xF4-0xF7 */
 	{0xF9, 0xF5}, {0x7A, 0x14}, {0xF9, 0xF6}, {0x83, 0x4F}, /* 0xF8-0xFB */
@@ -7485,10 +7487,10 @@
 	{0x6D, 0xE8}, {0x6E, 0x1F}, {0x6E, 0x5E}, {0x70, 0x1E}, /* 0xE4-0xE7 */
 	{0x70, 0xA1}, {0x73, 0x8E}, {0x73, 0xFD}, {0x75, 0x3A}, /* 0xE8-0xEB */
 	{0x77, 0x5B}, {0x78, 0x87}, {0x79, 0x8E}, {0x7A, 0x0B}, /* 0xEC-0xEF */
-	{0x7A, 0x7D}, {0x7C, 0xBE}, {0x7D, 0x8E}, {0x82, 0x47}, /* 0xF0-0xF3 */
+	{0x7A, 0x7D}, {0xFA, 0x1D}, {0x7D, 0x8E}, {0x82, 0x47}, /* 0xF0-0xF3 */
 	{0x8A, 0x02}, {0x8A, 0xEA}, {0x8C, 0x9E}, {0x91, 0x2D}, /* 0xF4-0xF7 */
 	{0x91, 0x4A}, {0x91, 0xD8}, {0x92, 0x66}, {0x92, 0xCC}, /* 0xF8-0xFB */
-	{0x93, 0x20}, {0x97, 0x06}, {0x97, 0x56}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x93, 0x20}, {0x97, 0x06}, {0xFA, 0x1C}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_F0[256] = {
@@ -7537,7 +7539,7 @@
 	{0x52, 0x36}, {0x52, 0x91}, {0x55, 0x7C}, {0x58, 0x24}, /* 0xA4-0xA7 */
 	{0x5E, 0x1D}, {0x5F, 0x1F}, {0x60, 0x8C}, {0x63, 0xD0}, /* 0xA8-0xAB */
 	{0x68, 0xAF}, {0x6F, 0xDF}, {0x79, 0x6D}, {0x7B, 0x2C}, /* 0xAC-0xAF */
-	{0x81, 0xCD}, {0x85, 0xBA}, {0x88, 0xFD}, {0x8A, 0xF8}, /* 0xB0-0xB3 */
+	{0x81, 0xCD}, {0x85, 0xBA}, {0x88, 0xFD}, {0xFA, 0x22}, /* 0xB0-0xB3 */
 	{0x8E, 0x44}, {0x91, 0x8D}, {0x96, 0x64}, {0x96, 0x9B}, /* 0xB4-0xB7 */
 	{0x97, 0x3D}, {0x98, 0x4C}, {0x9F, 0x4A}, {0x4F, 0xCE}, /* 0xB8-0xBB */
 	{0x51, 0x46}, {0x51, 0xCB}, {0x52, 0xA9}, {0x56, 0x32}, /* 0xBC-0xBF */
@@ -7822,7 +7824,7 @@
 	{0x7C, 0x3D}, {0x7C, 0x64}, {0x8A, 0x79}, {0x8A, 0xC2}, /* 0xD8-0xDB */
 	{0x58, 0x1E}, {0x59, 0xBE}, {0x5E, 0x16}, {0x63, 0x77}, /* 0xDC-0xDF */
 	{0x72, 0x52}, {0x75, 0x8A}, {0x77, 0x6B}, {0x8A, 0xDC}, /* 0xE0-0xE3 */
-	{0x8C, 0xBC}, {0x8F, 0x12}, {0x5E, 0xF3}, {0x66, 0x74}, /* 0xE4-0xE7 */
+	{0x8C, 0xBC}, {0x8F, 0x12}, {0x5E, 0xF3}, {0xFA, 0x12}, /* 0xE4-0xE7 */
 	{0x6D, 0xF8}, {0x80, 0x7D}, {0x83, 0xC1}, {0x8A, 0xCB}, /* 0xE8-0xEB */
 	{0x97, 0x51}, {0x9B, 0xD6}, {0xFA, 0x00}, {0x52, 0x43}, /* 0xEC-0xEF */
 	{0x66, 0xFF}, {0x6D, 0x95}, {0x6E, 0xEF}, {0x7D, 0xE0}, /* 0xF0-0xF3 */
@@ -7881,7 +7883,7 @@
 	{0x91, 0xAE}, {0x4F, 0xC3}, {0x56, 0xD1}, {0x71, 0xED}, /* 0xB4-0xB7 */
 	{0x77, 0xD7}, {0x87, 0x00}, {0x89, 0xF8}, {0x5B, 0xF8}, /* 0xB8-0xBB */
 	{0x5F, 0xD6}, {0x67, 0x51}, {0x90, 0xA8}, {0x53, 0xE2}, /* 0xBC-0xBF */
-	{0x58, 0x5A}, {0x5B, 0xF5}, {0x60, 0xA4}, {0x61, 0x81}, /* 0xC0-0xC3 */
+	{0xFA, 0x10}, {0x5B, 0xF5}, {0x60, 0xA4}, {0x61, 0x81}, /* 0xC0-0xC3 */
 	{0x64, 0x60}, {0x7E, 0x3D}, {0x80, 0x70}, {0x85, 0x25}, /* 0xC4-0xC7 */
 	{0x92, 0x83}, {0x64, 0xAE}, {0x50, 0xAC}, {0x5D, 0x14}, /* 0xC8-0xCB */
 	{0x67, 0x00}, {0x58, 0x9C}, {0x62, 0xBD}, {0x63, 0xA8}, /* 0xCC-0xCF */
@@ -8156,7 +8158,7 @@
 	{0x66, 0x30}, {0x6C, 0xB3}, {0x74, 0x55}, {0x83, 0x77}, /* 0xC0-0xC3 */
 	{0x87, 0x66}, {0x8C, 0xC0}, {0x90, 0x50}, {0x97, 0x1E}, /* 0xC4-0xC7 */
 	{0x9C, 0x15}, {0x58, 0xD1}, {0x5B, 0x78}, {0x86, 0x50}, /* 0xC8-0xCB */
-	{0x8B, 0x14}, {0x9D, 0xB4}, {0x5B, 0xD2}, {0x60, 0x68}, /* 0xCC-0xCF */
+	{0x8B, 0x14}, {0xFA, 0x2D}, {0x5B, 0xD2}, {0x60, 0x68}, /* 0xCC-0xCF */
 	{0x60, 0x8D}, {0x65, 0xF1}, {0x6C, 0x57}, {0x6F, 0x22}, /* 0xD0-0xD3 */
 	{0x6F, 0xA3}, {0x70, 0x1A}, {0x7F, 0x55}, {0x7F, 0xF0}, /* 0xD4-0xD7 */
 	{0x95, 0x91}, {0x95, 0x92}, {0x96, 0x50}, {0x97, 0xD3}, /* 0xD8-0xDB */
@@ -8435,7 +8437,7 @@
 	{0x70, 0x98}, {0x75, 0xD5}, {0x54, 0x03}, {0x5C, 0x79}, /* 0xDC-0xDF */
 	{0x7D, 0x07}, {0x8A, 0x16}, {0x6B, 0x20}, {0x6B, 0x3D}, /* 0xE0-0xE3 */
 	{0x6B, 0x46}, {0x54, 0x38}, {0x60, 0x70}, {0x6D, 0x3D}, /* 0xE4-0xE7 */
-	{0x7F, 0xD5}, {0x82, 0x08}, {0x50, 0xD6}, {0x51, 0xDE}, /* 0xE8-0xEB */
+	{0x7F, 0xD5}, {0x82, 0x08}, {0x50, 0xD6}, {0xFA, 0x15}, /* 0xE8-0xEB */
 	{0x55, 0x9C}, {0x56, 0x6B}, {0x56, 0xCD}, {0x59, 0xEC}, /* 0xEC-0xEF */
 	{0x5B, 0x09}, {0x5E, 0x0C}, {0x61, 0x99}, {0x61, 0x98}, /* 0xF0-0xF3 */
 	{0x62, 0x31}, {0x66, 0x5E}, {0x66, 0xE6}, {0x71, 0x99}, /* 0xF4-0xF7 */
@@ -8483,7 +8485,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0xA9, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0xA9, 0xA2, 0xA9, 0xA2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
@@ -8750,6 +8752,74 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
+static unsigned char u2c_11[512] = {
+	0xA4, 0xA1, 0xA4, 0xA2, 0xA4, 0xA4, 0xA4, 0xA7, /* 0x00-0x03 */
+	0xA4, 0xA8, 0xA4, 0xA9, 0xA4, 0xB1, 0xA4, 0xB2, /* 0x04-0x07 */
+	0xA4, 0xB3, 0xA4, 0xB5, 0xA4, 0xB6, 0xA4, 0xB7, /* 0x08-0x0B */
+	0xA4, 0xB8, 0xA4, 0xB9, 0xA4, 0xBA, 0xA4, 0xBB, /* 0x0C-0x0F */
+	0xA4, 0xBC, 0xA4, 0xBD, 0xA4, 0xBE, 0x3F, 0x3F, /* 0x10-0x13 */
+	0xA4, 0xD5, 0xA4, 0xD6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xDD, 0x3F, 0x3F, /* 0x18-0x1B */
+	0xA4, 0xDE, 0xA4, 0xE1, 0xA4, 0xE2, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0xA4, 0xE3, 0xA4, 0xB4, 0xA4, 0xE4, 0xA4, 0xE5, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xE6, /* 0x24-0x27 */
+	0x3F, 0x3F, 0xA4, 0xE7, 0x3F, 0x3F, 0xA4, 0xE8, /* 0x28-0x2B */
+	0xA4, 0xE9, 0xA4, 0xEA, 0xA4, 0xEB, 0xA4, 0xEC, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xED, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xEE, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0xA4, 0xB5, 0xA4, 0xB6, 0xA4, 0xB5, 0xA4, 0xB6, /* 0x3C-0x3F */
+	0xA4, 0xEF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0xA4, 0xF2, 0xA4, 0xF3, 0xA4, 0xF0, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0xA4, 0xB7, 0x3F, 0x3F, 0xA4, 0xB8, 0xA4, 0xB9, /* 0x4C-0x4F */
+	0xA4, 0xB8, 0xA4, 0xB9, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0xA4, 0xBA, 0xA4, 0xBA, 0x3F, 0x3F, 0xA4, 0xF4, /* 0x54-0x57 */
+	0xA4, 0xF5, 0xA4, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xD4, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0xA4, 0xBF, 0xA4, 0xC0, 0xA4, 0xC1, /* 0x60-0x63 */
+	0xA4, 0xC2, 0xA4, 0xC3, 0xA4, 0xC4, 0xA4, 0xC5, /* 0x64-0x67 */
+	0xA4, 0xC6, 0xA4, 0xC7, 0xA4, 0xC8, 0xA4, 0xC9, /* 0x68-0x6B */
+	0xA4, 0xCA, 0xA4, 0xCB, 0xA4, 0xCC, 0xA4, 0xCD, /* 0x6C-0x6F */
+	0xA4, 0xCE, 0xA4, 0xCF, 0xA4, 0xD0, 0xA4, 0xD1, /* 0x70-0x73 */
+	0xA4, 0xD2, 0xA4, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0xA4, 0xF7, 0xA4, 0xF8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0xA4, 0xF9, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0xA4, 0xFA, 0xA4, 0xFB, 0x3F, 0x3F, /* 0x90-0x93 */
+	0xA4, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xFD, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0xA4, 0xFE, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0xA4, 0xA1, 0xA4, 0xA2, 0xA4, 0xA3, 0xA4, 0xA4, /* 0xA8-0xAB */
+	0xA4, 0xA5, 0xA4, 0xA6, 0xA4, 0xA7, 0xA4, 0xA9, /* 0xAC-0xAF */
+	0xA4, 0xAA, 0xA4, 0xAB, 0xA4, 0xAC, 0xA4, 0xAD, /* 0xB0-0xB3 */
+	0xA4, 0xAE, 0xA4, 0xAF, 0xA4, 0xB0, 0xA4, 0xB1, /* 0xB4-0xB7 */
+	0xA4, 0xB2, 0xA4, 0xB4, 0xA4, 0xB5, 0xA4, 0xB6, /* 0xB8-0xBB */
+	0xA4, 0xB7, 0xA4, 0xB8, 0xA4, 0xBA, 0xA4, 0xBB, /* 0xBC-0xBF */
+	0xA4, 0xBC, 0xA4, 0xBD, 0xA4, 0xBE, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xD6, 0xA4, 0xD7, /* 0xC4-0xC7 */
+	0xA4, 0xD8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0xA4, 0xD9, 0x3F, 0x3F, 0xA4, 0xDA, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xDB, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xDC, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0xA4, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0xA4, 0xDE, 0xA4, 0xDF, 0x3F, 0x3F, 0xA4, 0xE0, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xE8, 0xA4, 0xEA, /* 0xE4-0xE7 */
+	0xA4, 0xEC, 0x3F, 0x3F, 0xA4, 0xED, 0xA4, 0xEF, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xF0, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0xA4, 0xB7, 0xA4, 0xF2, 0xA4, 0xF3, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0xA4, 0xF4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0xA4, 0xF6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+};
+
 static unsigned char u2c_20[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
@@ -8794,7 +8864,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x00, 0x5C, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
@@ -9069,13 +9139,13 @@
 	0xA9, 0xD9, 0xA9, 0xDA, 0xA9, 0xDB, 0xA9, 0xDC, /* 0xA8-0xAB */
 	0xA9, 0xDD, 0xA9, 0xDE, 0xA9, 0xDF, 0xA9, 0xE0, /* 0xAC-0xAF */
 	0xA9, 0xE1, 0xA9, 0xE2, 0xA9, 0xE3, 0xA9, 0xE4, /* 0xB0-0xB3 */
-	0xA9, 0xE5, 0xA9, 0xE6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0xA9, 0xE5, 0xA9, 0xE6, 0xA8, 0xCD, 0xA8, 0xCE, /* 0xB4-0xB7 */
+	0xA8, 0xCF, 0xA8, 0xD0, 0xA8, 0xD1, 0xA8, 0xD2, /* 0xB8-0xBB */
+	0xA8, 0xD3, 0xA8, 0xD4, 0xA8, 0xD5, 0xA8, 0xD6, /* 0xBC-0xBF */
+	0xA8, 0xD7, 0xA8, 0xD8, 0xA8, 0xD9, 0xA8, 0xDA, /* 0xC0-0xC3 */
+	0xA8, 0xDB, 0xA8, 0xDC, 0xA8, 0xDD, 0xA8, 0xDE, /* 0xC4-0xC7 */
+	0xA8, 0xDF, 0xA8, 0xE0, 0xA8, 0xE1, 0xA8, 0xE2, /* 0xC8-0xCB */
+	0xA8, 0xE3, 0xA8, 0xE4, 0xA8, 0xE5, 0xA8, 0xE6, /* 0xCC-0xCF */
 	0xA8, 0xCD, 0xA8, 0xCE, 0xA8, 0xCF, 0xA8, 0xD0, /* 0xD0-0xD3 */
 	0xA8, 0xD1, 0xA8, 0xD2, 0xA8, 0xD3, 0xA8, 0xD4, /* 0xD4-0xD7 */
 	0xA8, 0xD5, 0xA8, 0xD6, 0xA8, 0xD7, 0xA8, 0xD8, /* 0xD8-0xDB */
@@ -9332,10 +9402,10 @@
 	0xA4, 0xF4, 0xA4, 0xF5, 0xA4, 0xF6, 0xA4, 0xF7, /* 0x84-0x87 */
 	0xA4, 0xF8, 0xA4, 0xF9, 0xA4, 0xFA, 0xA4, 0xFB, /* 0x88-0x8B */
 	0xA4, 0xFC, 0xA4, 0xFD, 0xA4, 0xFE, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xEC, 0xE9, 0xEC, 0xA3, /* 0x90-0x93 */
+	0xDF, 0xB2, 0xDE, 0xCC, 0xDF, 0xBE, 0xF1, 0xE9, /* 0x94-0x97 */
+	0xF9, 0xBB, 0xCB, 0xA3, 0xEB, 0xE0, 0xDC, 0xB0, /* 0x98-0x9B */
+	0xEF, 0xCB, 0xF4, 0xB8, 0xF2, 0xA2, 0xEC, 0xD1, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
@@ -9371,15 +9441,15 @@
 	0xA9, 0xC5, 0xA9, 0xC6, 0xA9, 0xC7, 0xA9, 0xC8, /* 0x14-0x17 */
 	0xA9, 0xC9, 0xA9, 0xCA, 0xA9, 0xCB, 0xA9, 0xCC, /* 0x18-0x1B */
 	0xA2, 0xDF, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xEC, 0xE9, 0xEC, 0xA3, 0xDF, 0xB2, 0xDE, 0xCC, /* 0x20-0x23 */
+	0xE7, 0xE9, 0xD7, 0xBF, 0xF6, 0xD2, 0xF8, 0xA2, /* 0x24-0x27 */
+	0xCE, 0xFA, 0xE4, 0xA8, 0xEA, 0xC5, 0xFB, 0xFD, /* 0x28-0x2B */
+	0xE2, 0xA9, 0xD9, 0xCA, 0xD1, 0xD1, 0xF7, 0xCF, /* 0x2C-0x2F */
+	0xEC, 0xED, 0xF1, 0xBB, 0xEA, 0xF3, 0xDE, 0xE4, /* 0x30-0x33 */
+	0xD9, 0xA3, 0xF7, 0xE5, 0xEE, 0xAF, 0xF5, 0xE6, /* 0x34-0x37 */
+	0xD6, 0xCC, 0xD3, 0xDB, 0xFB, 0xBC, 0xF9, 0xCA, /* 0x38-0x3B */
+	0xCA, 0xF8, 0xD0, 0xEA, 0xED, 0xC0, 0xFA, 0xF0, /* 0x3C-0x3F */
+	0xF0, 0xAE, 0xFD, 0xCC, 0xED, 0xBB, 0xF2, 0xB8, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
@@ -9396,19 +9466,19 @@
 	0xA8, 0xC9, 0xA8, 0xCA, 0xA8, 0xCB, 0xA8, 0xCC, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA2, 0xDE, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xEC, 0xE9, 0xEC, 0xA3, 0xDF, 0xB2, 0xDE, 0xCC, /* 0x80-0x83 */
+	0xE7, 0xE9, 0xD7, 0xBF, 0xF6, 0xD2, 0xF8, 0xA2, /* 0x84-0x87 */
+	0xCE, 0xFA, 0xE4, 0xA8, 0xEA, 0xC5, 0xFB, 0xFD, /* 0x88-0x8B */
+	0xE2, 0xA9, 0xD9, 0xCA, 0xD1, 0xD1, 0xF7, 0xCF, /* 0x8C-0x8F */
+	0xEC, 0xED, 0xF1, 0xBB, 0xEA, 0xF3, 0xDE, 0xE4, /* 0x90-0x93 */
+	0xD9, 0xA3, 0xF7, 0xE5, 0xEE, 0xAF, 0xF5, 0xE6, /* 0x94-0x97 */
+	0xD6, 0xCC, 0xDD, 0xFA, 0xD1, 0xFB, 0xD2, 0xB3, /* 0x98-0x9B */
+	0xEE, 0xEA, 0xE9, 0xD0, 0xEC, 0xD4, 0xF1, 0xBC, /* 0x9C-0x9F */
+	0xFA, 0xA3, 0xFD, 0xCC, 0xDE, 0xD0, 0xEF, 0xE1, /* 0xA0-0xA3 */
+	0xDF, 0xBE, 0xF1, 0xE9, 0xF9, 0xBB, 0xF1, 0xA7, /* 0xA4-0xA7 */
+	0xE9, 0xD3, 0xEC, 0xA2, 0xF0, 0xF3, 0xF9, 0xCA, /* 0xA8-0xAB */
+	0xCA, 0xF8, 0xD0, 0xEA, 0xED, 0xC0, 0xFA, 0xF0, /* 0xAC-0xAF */
+	0xE5, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
@@ -18066,6 +18136,74 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
+static unsigned char u2c_DC[512] = {
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+};
+
 static unsigned char u2c_F9[512] = {
 	0xCB, 0xD0, 0xCB, 0xD6, 0xCB, 0xE7, 0xCD, 0xCF, /* 0x00-0x03 */
 	0xCD, 0xE8, 0xCE, 0xAD, 0xCF, 0xFB, 0xD0, 0xA2, /* 0x04-0x07 */
@@ -18138,15 +18276,15 @@
 	0xF4, 0xEE, 0xF6, 0xF4, 0xF6, 0xF6, 0xF7, 0xB8, /* 0x00-0x03 */
 	0xF7, 0xC8, 0xF7, 0xD3, 0xF8, 0xDB, 0xF8, 0xF0, /* 0x04-0x07 */
 	0xFA, 0xA1, 0xFA, 0xA2, 0xFA, 0xE6, 0xFC, 0xA9, /* 0x08-0x0B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0xE8, 0xB4, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xF5, 0xC0, 0x3F, 0x3F, 0xF4, 0xE7, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xFD, 0xEB, 0x3F, 0x3F, 0xEC, 0xCC, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xE3, 0xEA, 0xDF, 0xD4, 0xDC, 0xD8, /* 0x18-0x1B */
+	0xEF, 0xFE, 0xEF, 0xF1, 0xE9, 0xE2, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xF0, 0xB3, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xEC, 0xEF, 0xD4, 0xB4, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xDA, 0xF9, 0xDE, 0xF8, /* 0x28-0x2B */
+	0xCE, 0xBD, 0xF9, 0xCD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
@@ -18244,22 +18382,22 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0xA4, 0xD4, 0xA4, 0xA1, 0xA4, 0xA2, 0xA4, 0xA3, /* 0xA0-0xA3 */
+	0xA4, 0xA4, 0xA4, 0xA5, 0xA4, 0xA6, 0xA4, 0xA7, /* 0xA4-0xA7 */
+	0xA4, 0xA8, 0xA4, 0xA9, 0xA4, 0xAA, 0xA4, 0xAB, /* 0xA8-0xAB */
+	0xA4, 0xAC, 0xA4, 0xAD, 0xA4, 0xAE, 0xA4, 0xAF, /* 0xAC-0xAF */
+	0xA4, 0xB0, 0xA4, 0xB1, 0xA4, 0xB2, 0xA4, 0xB3, /* 0xB0-0xB3 */
+	0xA4, 0xB4, 0xA4, 0xB5, 0xA4, 0xB6, 0xA4, 0xB7, /* 0xB4-0xB7 */
+	0xA4, 0xB8, 0xA4, 0xB9, 0xA4, 0xBA, 0xA4, 0xBB, /* 0xB8-0xBB */
+	0xA4, 0xBC, 0xA4, 0xBD, 0xA4, 0xBE, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xBF, 0xA4, 0xC0, /* 0xC0-0xC3 */
+	0xA4, 0xC1, 0xA4, 0xC2, 0xA4, 0xC3, 0xA4, 0xC4, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xC5, 0xA4, 0xC6, /* 0xC8-0xCB */
+	0xA4, 0xC7, 0xA4, 0xC8, 0xA4, 0xC9, 0xA4, 0xCA, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xCB, 0xA4, 0xCC, /* 0xD0-0xD3 */
+	0xA4, 0xCD, 0xA4, 0xCE, 0xA4, 0xCF, 0xA4, 0xD0, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0xD1, 0xA4, 0xD2, /* 0xD8-0xDB */
+	0xA4, 0xD3, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
 	0xA1, 0xCB, 0xA1, 0xCC, 0xA1, 0xFE, 0xA3, 0xFE, /* 0xE0-0xE3 */
 	0x3F, 0x3F, 0xA1, 0xCD, 0xA3, 0xDC, 0x3F, 0x3F, /* 0xE4-0xE7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
@@ -18273,7 +18411,7 @@
 static unsigned char *page_uni2charset[256] = {
 	NULL,   u2c_01, u2c_02, u2c_03, u2c_04, NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   u2c_11, NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	u2c_20, u2c_21, u2c_22, u2c_23, u2c_24, u2c_25, u2c_26, NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
@@ -18298,7 +18436,7 @@
 	u2c_C0, u2c_C1, u2c_C2, u2c_C3, u2c_C4, u2c_C5, u2c_C6, u2c_C7, 
 	u2c_C8, u2c_C9, u2c_CA, u2c_CB, u2c_CC, u2c_CD, u2c_CE, u2c_CF, 
 	u2c_D0, u2c_D1, u2c_D2, u2c_D3, u2c_D4, u2c_D5, u2c_D6, u2c_D7, 
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   u2c_DC, NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
@@ -18310,6 +18448,7 @@
 
 	if (boundlen <= 0)
 		return;
+
 	uni2charset = page_uni2charset[ch];
 	*outlen = 0;
 	if (uni2charset){
@@ -18333,6 +18472,7 @@
 
 	ch = rawstring[0];
 	cl = rawstring[1];
+
 	charset2uni = page_charset2uni[ch];
 	if (charset2uni && cl){
 		*uni1 = charset2uni[cl].uni2;
@@ -18365,20 +18505,34 @@
 	NULL
 };
 
+static struct nls_table alias_table = {
+	"euc-kr",
+	uni2char,
+	char2uni,
+	inc_use_count,
+	dec_use_count,
+	NULL
+};
+
+
 int __init init_nls_cp949(void)
 {
+	register_nls(&alias_table);
 	return register_nls(&table);
 }
 
 #ifdef MODULE
 int init_module(void)
 {
+
 	return init_nls_cp949();
 }
 
 
 void cleanup_module(void)
 {
+
+	unregister_nls(&alias_table);
 	unregister_nls(&table);
 	return;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/nls/nls_cp950.c linux.17p18/fs/nls/nls_cp950.c
--- linux.vanilla/fs/nls/nls_cp950.c	Sun Jun 11 21:44:21 2000
+++ linux.17p18/fs/nls/nls_cp950.c	Tue Aug  1 07:59:08 2000
@@ -2,7 +2,9 @@
  * linux/fs/nls_cp950.c
  *
  * Charset cp950 translation tables.
- * Generated automatically from the Microsoft
+ * This translation table was generated automatically, the
+ * original table can be download from the Microsoft website.
+ * (http://www.microsoft.com/typography/unicode/unicodecp.htm)
  */
 
 #include <linux/module.h>
@@ -31,16 +33,16 @@
 	{0x30, 0x00}, {0xFF, 0x0C}, {0x30, 0x01}, {0x30, 0x02}, /* 0x40-0x43 */
 	{0xFF, 0x0E}, {0x20, 0x27}, {0xFF, 0x1B}, {0xFF, 0x1A}, /* 0x44-0x47 */
 	{0xFF, 0x1F}, {0xFF, 0x01}, {0xFE, 0x30}, {0x20, 0x26}, /* 0x48-0x4B */
-	{0x20, 0x25}, {0xFE, 0x50}, {0xFE, 0x51}, {0xFE, 0x52}, /* 0x4C-0x4F */
+	{0x20, 0x25}, {0xFE, 0x50}, {0xFF, 0x64}, {0xFE, 0x52}, /* 0x4C-0x4F */
 	{0x00, 0xB7}, {0xFE, 0x54}, {0xFE, 0x55}, {0xFE, 0x56}, /* 0x50-0x53 */
 	{0xFE, 0x57}, {0xFF, 0x5C}, {0x20, 0x13}, {0xFE, 0x31}, /* 0x54-0x57 */
 	{0x20, 0x14}, {0xFE, 0x33}, {0x25, 0x74}, {0xFE, 0x34}, /* 0x58-0x5B */
 	{0xFE, 0x4F}, {0xFF, 0x08}, {0xFF, 0x09}, {0xFE, 0x35}, /* 0x5C-0x5F */
 	{0xFE, 0x36}, {0xFF, 0x5B}, {0xFF, 0x5D}, {0xFE, 0x37}, /* 0x60-0x63 */
-	{0xFE, 0x38}, {0x30, 0x14}, {0x30, 0x15}, {0xFE, 0x39}, /* 0x64-0x67 */
+	{0xFE, 0x38}, {0xFF, 0x3B}, {0xFF, 0x3D}, {0xFE, 0x39}, /* 0x64-0x67 */
 	{0xFE, 0x3A}, {0x30, 0x10}, {0x30, 0x11}, {0xFE, 0x3B}, /* 0x68-0x6B */
 	{0xFE, 0x3C}, {0x30, 0x0A}, {0x30, 0x0B}, {0xFE, 0x3D}, /* 0x6C-0x6F */
-	{0xFE, 0x3E}, {0x30, 0x08}, {0x30, 0x09}, {0xFE, 0x3F}, /* 0x70-0x73 */
+	{0xFE, 0x3E}, {0x30, 0x08}, {0x30, 0x09}, {0xFF, 0x3E}, /* 0x70-0x73 */
 	{0xFE, 0x40}, {0x30, 0x0C}, {0x30, 0x0D}, {0xFE, 0x41}, /* 0x74-0x77 */
 	{0xFE, 0x42}, {0x30, 0x0E}, {0x30, 0x0F}, {0xFE, 0x43}, /* 0x78-0x7B */
 	{0xFE, 0x44}, {0xFE, 0x59}, {0xFE, 0x5A}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -54,26 +56,26 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0xFE, 0x5B}, {0xFE, 0x5C}, {0xFE, 0x5D}, /* 0xA0-0xA3 */
-	{0xFE, 0x5E}, {0x20, 0x18}, {0x20, 0x19}, {0x20, 0x1C}, /* 0xA4-0xA7 */
-	{0x20, 0x1D}, {0x30, 0x1D}, {0x30, 0x1E}, {0x20, 0x35}, /* 0xA8-0xAB */
+	{0xFE, 0x5E}, {0xFF, 0x40}, {0xFF, 0x07}, {0x20, 0x1C}, /* 0xA4-0xA7 */
+	{0xFF, 0x02}, {0x30, 0x1D}, {0x30, 0x1E}, {0x20, 0x35}, /* 0xA8-0xAB */
 	{0x20, 0x32}, {0xFF, 0x03}, {0xFF, 0x06}, {0xFF, 0x0A}, /* 0xAC-0xAF */
 	{0x20, 0x3B}, {0x00, 0xA7}, {0x30, 0x03}, {0x25, 0xCB}, /* 0xB0-0xB3 */
 	{0x25, 0xCF}, {0x25, 0xB3}, {0x25, 0xB2}, {0x25, 0xCE}, /* 0xB4-0xB7 */
 	{0x26, 0x06}, {0x26, 0x05}, {0x25, 0xC7}, {0x25, 0xC6}, /* 0xB8-0xBB */
 	{0x25, 0xA1}, {0x25, 0xA0}, {0x25, 0xBD}, {0x25, 0xBC}, /* 0xBC-0xBF */
-	{0x32, 0xA3}, {0x21, 0x05}, {0x00, 0xAF}, {0xFF, 0xE3}, /* 0xC0-0xC3 */
+	{0x32, 0xA3}, {0x21, 0x05}, {0x03, 0x05}, {0xFF, 0xE3}, /* 0xC0-0xC3 */
 	{0xFF, 0x3F}, {0x02, 0xCD}, {0xFE, 0x49}, {0xFE, 0x4A}, /* 0xC4-0xC7 */
 	{0xFE, 0x4D}, {0xFE, 0x4E}, {0xFE, 0x4B}, {0xFE, 0x4C}, /* 0xC8-0xCB */
 	{0xFE, 0x5F}, {0xFE, 0x60}, {0xFE, 0x61}, {0xFF, 0x0B}, /* 0xCC-0xCF */
 	{0xFF, 0x0D}, {0x00, 0xD7}, {0x00, 0xF7}, {0x00, 0xB1}, /* 0xD0-0xD3 */
 	{0x22, 0x1A}, {0xFF, 0x1C}, {0xFF, 0x1E}, {0xFF, 0x1D}, /* 0xD4-0xD7 */
 	{0x22, 0x66}, {0x22, 0x67}, {0x22, 0x60}, {0x22, 0x1E}, /* 0xD8-0xDB */
-	{0x22, 0x52}, {0x22, 0x61}, {0xFE, 0x62}, {0xFE, 0x63}, /* 0xDC-0xDF */
+	{0x22, 0x52}, {0x22, 0x63}, {0xFE, 0x62}, {0xFE, 0x63}, /* 0xDC-0xDF */
 	{0xFE, 0x64}, {0xFE, 0x65}, {0xFE, 0x66}, {0xFF, 0x5E}, /* 0xE0-0xE3 */
 	{0x22, 0x29}, {0x22, 0x2A}, {0x22, 0xA5}, {0x22, 0x20}, /* 0xE4-0xE7 */
 	{0x22, 0x1F}, {0x22, 0xBF}, {0x33, 0xD2}, {0x33, 0xD1}, /* 0xE8-0xEB */
 	{0x22, 0x2B}, {0x22, 0x2E}, {0x22, 0x35}, {0x22, 0x34}, /* 0xEC-0xEF */
-	{0x26, 0x40}, {0x26, 0x42}, {0x22, 0x95}, {0x22, 0x99}, /* 0xF0-0xF3 */
+	{0x26, 0x40}, {0x26, 0x42}, {0x26, 0x41}, {0x26, 0x09}, /* 0xF0-0xF3 */
 	{0x21, 0x91}, {0x21, 0x93}, {0x21, 0x90}, {0x21, 0x92}, /* 0xF4-0xF7 */
 	{0x21, 0x96}, {0x21, 0x97}, {0x21, 0x99}, {0x21, 0x98}, /* 0xF8-0xFB */
 	{0x22, 0x25}, {0x22, 0x23}, {0xFF, 0x0F}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -102,7 +104,7 @@
 	{0xFE, 0x69}, {0xFE, 0x6A}, {0xFE, 0x6B}, {0x33, 0xD5}, /* 0x4C-0x4F */
 	{0x33, 0x9C}, {0x33, 0x9D}, {0x33, 0x9E}, {0x33, 0xCE}, /* 0x50-0x53 */
 	{0x33, 0xA1}, {0x33, 0x8E}, {0x33, 0x8F}, {0x33, 0xC4}, /* 0x54-0x57 */
-	{0x00, 0xB0}, {0x51, 0x59}, {0x51, 0x5B}, {0x51, 0x5E}, /* 0x58-0x5B */
+	{0x22, 0x18}, {0x51, 0x59}, {0x51, 0x5B}, {0x51, 0x5E}, /* 0x58-0x5B */
 	{0x51, 0x5D}, {0x51, 0x61}, {0x51, 0x63}, {0x55, 0xE7}, /* 0x5C-0x5F */
 	{0x74, 0xE9}, {0x7C, 0xCE}, {0x25, 0x81}, {0x25, 0x82}, /* 0x60-0x63 */
 	{0x25, 0x83}, {0x25, 0x84}, {0x25, 0x85}, {0x25, 0x86}, /* 0x64-0x67 */
@@ -122,7 +124,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x25, 0x6E}, {0x25, 0x70}, {0x25, 0x6F}, /* 0xA0-0xA3 */
-	{0x25, 0x50}, {0x25, 0x5E}, {0x25, 0x6A}, {0x25, 0x61}, /* 0xA4-0xA7 */
+	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xA4-0xA7 */
 	{0x25, 0xE2}, {0x25, 0xE3}, {0x25, 0xE5}, {0x25, 0xE4}, /* 0xA8-0xAB */
 	{0x25, 0x71}, {0x25, 0x72}, {0x25, 0x73}, {0xFF, 0x10}, /* 0xAC-0xAF */
 	{0xFF, 0x11}, {0xFF, 0x12}, {0xFF, 0x13}, {0xFF, 0x14}, /* 0xB0-0xB3 */
@@ -132,7 +134,7 @@
 	{0x21, 0x67}, {0x21, 0x68}, {0x21, 0x69}, {0x30, 0x21}, /* 0xC0-0xC3 */
 	{0x30, 0x22}, {0x30, 0x23}, {0x30, 0x24}, {0x30, 0x25}, /* 0xC4-0xC7 */
 	{0x30, 0x26}, {0x30, 0x27}, {0x30, 0x28}, {0x30, 0x29}, /* 0xC8-0xCB */
-	{0x53, 0x41}, {0x53, 0x44}, {0x53, 0x45}, {0xFF, 0x21}, /* 0xCC-0xCF */
+	{0x00, 0x3F}, {0x53, 0x44}, {0x00, 0x3F}, {0xFF, 0x21}, /* 0xCC-0xCF */
 	{0xFF, 0x22}, {0xFF, 0x23}, {0xFF, 0x24}, {0xFF, 0x25}, /* 0xD0-0xD3 */
 	{0xFF, 0x26}, {0xFF, 0x27}, {0xFF, 0x28}, {0xFF, 0x29}, /* 0xD4-0xD7 */
 	{0xFF, 0x2A}, {0xFF, 0x2B}, {0xFF, 0x2C}, {0xFF, 0x2D}, /* 0xD8-0xDB */
@@ -195,7 +197,7 @@
 	{0x31, 0x1B}, {0x31, 0x1C}, {0x31, 0x1D}, {0x31, 0x1E}, /* 0xAC-0xAF */
 	{0x31, 0x1F}, {0x31, 0x20}, {0x31, 0x21}, {0x31, 0x22}, /* 0xB0-0xB3 */
 	{0x31, 0x23}, {0x31, 0x24}, {0x31, 0x25}, {0x31, 0x26}, /* 0xB4-0xB7 */
-	{0x31, 0x27}, {0x31, 0x28}, {0x31, 0x29}, {0x02, 0xD9}, /* 0xB8-0xBB */
+	{0x31, 0x27}, {0x31, 0x28}, {0x31, 0x29}, {0x20, 0x24}, /* 0xB8-0xBB */
 	{0x02, 0xC9}, {0x02, 0xCA}, {0x02, 0xC7}, {0x02, 0xCB}, /* 0xBC-0xBF */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xC0-0xC3 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xC4-0xC7 */
@@ -233,16 +235,16 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x4E, 0x00}, {0x4E, 0x59}, {0x4E, 0x01}, {0x4E, 0x03}, /* 0x40-0x43 */
-	{0x4E, 0x43}, {0x4E, 0x5D}, {0x4E, 0x86}, {0x4E, 0x8C}, /* 0x44-0x47 */
+	{0x4E, 0x43}, {0x4E, 0x5D}, {0xF9, 0xBA}, {0x4E, 0x8C}, /* 0x44-0x47 */
 	{0x4E, 0xBA}, {0x51, 0x3F}, {0x51, 0x65}, {0x51, 0x6B}, /* 0x48-0x4B */
-	{0x51, 0xE0}, {0x52, 0x00}, {0x52, 0x01}, {0x52, 0x9B}, /* 0x4C-0x4F */
+	{0x51, 0xE0}, {0x52, 0x00}, {0x52, 0x01}, {0xF9, 0x8A}, /* 0x4C-0x4F */
 	{0x53, 0x15}, {0x53, 0x41}, {0x53, 0x5C}, {0x53, 0xC8}, /* 0x50-0x53 */
 	{0x4E, 0x09}, {0x4E, 0x0B}, {0x4E, 0x08}, {0x4E, 0x0A}, /* 0x54-0x57 */
 	{0x4E, 0x2B}, {0x4E, 0x38}, {0x51, 0xE1}, {0x4E, 0x45}, /* 0x58-0x5B */
 	{0x4E, 0x48}, {0x4E, 0x5F}, {0x4E, 0x5E}, {0x4E, 0x8E}, /* 0x5C-0x5F */
 	{0x4E, 0xA1}, {0x51, 0x40}, {0x52, 0x03}, {0x52, 0xFA}, /* 0x60-0x63 */
 	{0x53, 0x43}, {0x53, 0xC9}, {0x53, 0xE3}, {0x57, 0x1F}, /* 0x64-0x67 */
-	{0x58, 0xEB}, {0x59, 0x15}, {0x59, 0x27}, {0x59, 0x73}, /* 0x68-0x6B */
+	{0x58, 0xEB}, {0x59, 0x15}, {0x59, 0x27}, {0xF9, 0x81}, /* 0x68-0x6B */
 	{0x5B, 0x50}, {0x5B, 0x51}, {0x5B, 0x53}, {0x5B, 0xF8}, /* 0x6C-0x6F */
 	{0x5C, 0x0F}, {0x5C, 0x22}, {0x5C, 0x38}, {0x5C, 0x71}, /* 0x70-0x73 */
 	{0x5D, 0xDD}, {0x5D, 0xE5}, {0x5D, 0xF1}, {0x5D, 0xF2}, /* 0x74-0x77 */
@@ -257,15 +259,15 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x94-0x97 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
-	{0x00, 0x3F}, {0x4E, 0x11}, {0x4E, 0x10}, {0x4E, 0x0D}, /* 0xA0-0xA3 */
-	{0x4E, 0x2D}, {0x4E, 0x30}, {0x4E, 0x39}, {0x4E, 0x4B}, /* 0xA4-0xA7 */
+	{0x00, 0x3F}, {0x4E, 0x11}, {0x4E, 0x10}, {0xF9, 0x67}, /* 0xA0-0xA3 */
+	{0x4E, 0x2D}, {0x4E, 0x30}, {0xF9, 0x5E}, {0x4E, 0x4B}, /* 0xA4-0xA7 */
 	{0x5C, 0x39}, {0x4E, 0x88}, {0x4E, 0x91}, {0x4E, 0x95}, /* 0xA8-0xAB */
 	{0x4E, 0x92}, {0x4E, 0x94}, {0x4E, 0xA2}, {0x4E, 0xC1}, /* 0xAC-0xAF */
-	{0x4E, 0xC0}, {0x4E, 0xC3}, {0x4E, 0xC6}, {0x4E, 0xC7}, /* 0xB0-0xB3 */
+	{0xF9, 0xFD}, {0x4E, 0xC3}, {0x4E, 0xC6}, {0x4E, 0xC7}, /* 0xB0-0xB3 */
 	{0x4E, 0xCD}, {0x4E, 0xCA}, {0x4E, 0xCB}, {0x4E, 0xC4}, /* 0xB4-0xB7 */
-	{0x51, 0x43}, {0x51, 0x41}, {0x51, 0x67}, {0x51, 0x6D}, /* 0xB8-0xBB */
+	{0x51, 0x43}, {0x51, 0x41}, {0x51, 0x67}, {0xF9, 0xD1}, /* 0xB8-0xBB */
 	{0x51, 0x6E}, {0x51, 0x6C}, {0x51, 0x97}, {0x51, 0xF6}, /* 0xBC-0xBF */
-	{0x52, 0x06}, {0x52, 0x07}, {0x52, 0x08}, {0x52, 0xFB}, /* 0xC0-0xC3 */
+	{0x52, 0x06}, {0xFA, 0x00}, {0x52, 0x08}, {0x52, 0xFB}, /* 0xC0-0xC3 */
 	{0x52, 0xFE}, {0x52, 0xFF}, {0x53, 0x16}, {0x53, 0x39}, /* 0xC4-0xC7 */
 	{0x53, 0x48}, {0x53, 0x47}, {0x53, 0x45}, {0x53, 0x5E}, /* 0xC8-0xCB */
 	{0x53, 0x84}, {0x53, 0xCB}, {0x53, 0xCA}, {0x53, 0xCD}, /* 0xCC-0xCF */
@@ -303,18 +305,18 @@
 	{0x4E, 0x16}, {0x4E, 0x15}, {0x4E, 0x14}, {0x4E, 0x18}, /* 0x40-0x43 */
 	{0x4E, 0x3B}, {0x4E, 0x4D}, {0x4E, 0x4F}, {0x4E, 0x4E}, /* 0x44-0x47 */
 	{0x4E, 0xE5}, {0x4E, 0xD8}, {0x4E, 0xD4}, {0x4E, 0xD5}, /* 0x48-0x4B */
-	{0x4E, 0xD6}, {0x4E, 0xD7}, {0x4E, 0xE3}, {0x4E, 0xE4}, /* 0x4C-0x4F */
+	{0x4E, 0xD6}, {0x4E, 0xD7}, {0x4E, 0xE3}, {0xF9, 0xA8}, /* 0x4C-0x4F */
 	{0x4E, 0xD9}, {0x4E, 0xDE}, {0x51, 0x45}, {0x51, 0x44}, /* 0x50-0x53 */
 	{0x51, 0x89}, {0x51, 0x8A}, {0x51, 0xAC}, {0x51, 0xF9}, /* 0x54-0x57 */
 	{0x51, 0xFA}, {0x51, 0xF8}, {0x52, 0x0A}, {0x52, 0xA0}, /* 0x58-0x5B */
-	{0x52, 0x9F}, {0x53, 0x05}, {0x53, 0x06}, {0x53, 0x17}, /* 0x5C-0x5F */
+	{0x52, 0x9F}, {0x53, 0x05}, {0x53, 0x06}, {0xF9, 0x63}, /* 0x5C-0x5F */
 	{0x53, 0x1D}, {0x4E, 0xDF}, {0x53, 0x4A}, {0x53, 0x49}, /* 0x60-0x63 */
 	{0x53, 0x61}, {0x53, 0x60}, {0x53, 0x6F}, {0x53, 0x6E}, /* 0x64-0x67 */
 	{0x53, 0xBB}, {0x53, 0xEF}, {0x53, 0xE4}, {0x53, 0xF3}, /* 0x68-0x6B */
 	{0x53, 0xEC}, {0x53, 0xEE}, {0x53, 0xE9}, {0x53, 0xE8}, /* 0x6C-0x6F */
 	{0x53, 0xFC}, {0x53, 0xF8}, {0x53, 0xF5}, {0x53, 0xEB}, /* 0x70-0x73 */
 	{0x53, 0xE6}, {0x53, 0xEA}, {0x53, 0xF2}, {0x53, 0xF1}, /* 0x74-0x77 */
-	{0x53, 0xF0}, {0x53, 0xE5}, {0x53, 0xED}, {0x53, 0xFB}, /* 0x78-0x7B */
+	{0x53, 0xF0}, {0xF9, 0x06}, {0x53, 0xED}, {0x53, 0xFB}, /* 0x78-0x7B */
 	{0x56, 0xDB}, {0x56, 0xDA}, {0x59, 0x16}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
@@ -340,7 +342,7 @@
 	{0x75, 0x30}, {0x75, 0x31}, {0x75, 0x32}, {0x75, 0x33}, /* 0xD0-0xD3 */
 	{0x75, 0x8B}, {0x76, 0x7D}, {0x76, 0xAE}, {0x76, 0xBF}, /* 0xD4-0xD7 */
 	{0x76, 0xEE}, {0x77, 0xDB}, {0x77, 0xE2}, {0x77, 0xF3}, /* 0xD8-0xDB */
-	{0x79, 0x3A}, {0x79, 0xBE}, {0x7A, 0x74}, {0x7A, 0xCB}, /* 0xDC-0xDF */
+	{0x79, 0x3A}, {0x79, 0xBE}, {0x7A, 0x74}, {0xF9, 0xF7}, /* 0xDC-0xDF */
 	{0x4E, 0x1E}, {0x4E, 0x1F}, {0x4E, 0x52}, {0x4E, 0x53}, /* 0xE0-0xE3 */
 	{0x4E, 0x69}, {0x4E, 0x99}, {0x4E, 0xA4}, {0x4E, 0xA6}, /* 0xE4-0xE7 */
 	{0x4E, 0xA5}, {0x4E, 0xFF}, {0x4F, 0x09}, {0x4F, 0x19}, /* 0xE8-0xEB */
@@ -368,10 +370,10 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x51, 0x71}, {0x51, 0x8D}, {0x51, 0xB0}, {0x52, 0x17}, /* 0x40-0x43 */
+	{0x51, 0x71}, {0x51, 0x8D}, {0x51, 0xB0}, {0xF9, 0x9C}, /* 0x40-0x43 */
 	{0x52, 0x11}, {0x52, 0x12}, {0x52, 0x0E}, {0x52, 0x16}, /* 0x44-0x47 */
-	{0x52, 0xA3}, {0x53, 0x08}, {0x53, 0x21}, {0x53, 0x20}, /* 0x48-0x4B */
-	{0x53, 0x70}, {0x53, 0x71}, {0x54, 0x09}, {0x54, 0x0F}, /* 0x4C-0x4F */
+	{0xF9, 0x9D}, {0x53, 0x08}, {0x53, 0x21}, {0x53, 0x20}, /* 0x48-0x4B */
+	{0x53, 0x70}, {0x53, 0x71}, {0x54, 0x09}, {0xF9, 0xDE}, /* 0x4C-0x4F */
 	{0x54, 0x0C}, {0x54, 0x0A}, {0x54, 0x10}, {0x54, 0x01}, /* 0x50-0x53 */
 	{0x54, 0x0B}, {0x54, 0x04}, {0x54, 0x11}, {0x54, 0x0D}, /* 0x54-0x57 */
 	{0x54, 0x08}, {0x54, 0x03}, {0x54, 0x0E}, {0x54, 0x06}, /* 0x58-0x5B */
@@ -381,9 +383,9 @@
 	{0x59, 0x1A}, {0x59, 0x37}, {0x59, 0x38}, {0x59, 0x84}, /* 0x68-0x6B */
 	{0x59, 0x78}, {0x59, 0x83}, {0x59, 0x7D}, {0x59, 0x79}, /* 0x6C-0x6F */
 	{0x59, 0x82}, {0x59, 0x81}, {0x5B, 0x57}, {0x5B, 0x58}, /* 0x70-0x73 */
-	{0x5B, 0x87}, {0x5B, 0x88}, {0x5B, 0x85}, {0x5B, 0x89}, /* 0x74-0x77 */
+	{0x5B, 0x87}, {0x5B, 0x88}, {0xFA, 0x04}, {0x5B, 0x89}, /* 0x74-0x77 */
 	{0x5B, 0xFA}, {0x5C, 0x16}, {0x5C, 0x79}, {0x5D, 0xDE}, /* 0x78-0x7B */
-	{0x5E, 0x06}, {0x5E, 0x76}, {0x5E, 0x74}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x5E, 0x06}, {0x5E, 0x76}, {0xF9, 0x8E}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -405,13 +407,13 @@
 	{0x6C, 0x5B}, {0x6C, 0x4D}, {0x6C, 0x4E}, {0x70, 0x70}, /* 0xC4-0xC7 */
 	{0x72, 0x5F}, {0x72, 0x5D}, {0x76, 0x7E}, {0x7A, 0xF9}, /* 0xC8-0xCB */
 	{0x7C, 0x73}, {0x7C, 0xF8}, {0x7F, 0x36}, {0x7F, 0x8A}, /* 0xCC-0xCF */
-	{0x7F, 0xBD}, {0x80, 0x01}, {0x80, 0x03}, {0x80, 0x0C}, /* 0xD0-0xD3 */
+	{0xFA, 0x1E}, {0xF9, 0x34}, {0x80, 0x03}, {0x80, 0x0C}, /* 0xD0-0xD3 */
 	{0x80, 0x12}, {0x80, 0x33}, {0x80, 0x7F}, {0x80, 0x89}, /* 0xD4-0xD7 */
-	{0x80, 0x8B}, {0x80, 0x8C}, {0x81, 0xE3}, {0x81, 0xEA}, /* 0xD8-0xDB */
+	{0xF9, 0x53}, {0x80, 0x8C}, {0x81, 0xE3}, {0x81, 0xEA}, /* 0xD8-0xDB */
 	{0x81, 0xF3}, {0x81, 0xFC}, {0x82, 0x0C}, {0x82, 0x1B}, /* 0xDC-0xDF */
 	{0x82, 0x1F}, {0x82, 0x6E}, {0x82, 0x72}, {0x82, 0x7E}, /* 0xE0-0xE3 */
-	{0x86, 0x6B}, {0x88, 0x40}, {0x88, 0x4C}, {0x88, 0x63}, /* 0xE4-0xE7 */
-	{0x89, 0x7F}, {0x96, 0x21}, {0x4E, 0x32}, {0x4E, 0xA8}, /* 0xE8-0xEB */
+	{0x86, 0x6B}, {0x88, 0x40}, {0xFA, 0x08}, {0x88, 0x63}, /* 0xE4-0xE7 */
+	{0x89, 0x7F}, {0x96, 0x21}, {0xF9, 0x05}, {0x4E, 0xA8}, /* 0xE8-0xEB */
 	{0x4F, 0x4D}, {0x4F, 0x4F}, {0x4F, 0x47}, {0x4F, 0x57}, /* 0xEC-0xEF */
 	{0x4F, 0x5E}, {0x4F, 0x34}, {0x4F, 0x5B}, {0x4F, 0x55}, /* 0xF0-0xF3 */
 	{0x4F, 0x30}, {0x4F, 0x50}, {0x4F, 0x51}, {0x4F, 0x3D}, /* 0xF4-0xF7 */
@@ -439,13 +441,13 @@
 	{0x4F, 0x5C}, {0x4F, 0x60}, {0x4F, 0x2F}, {0x4F, 0x4E}, /* 0x40-0x43 */
 	{0x4F, 0x36}, {0x4F, 0x59}, {0x4F, 0x5D}, {0x4F, 0x48}, /* 0x44-0x47 */
 	{0x4F, 0x5A}, {0x51, 0x4C}, {0x51, 0x4B}, {0x51, 0x4D}, /* 0x48-0x4B */
-	{0x51, 0x75}, {0x51, 0xB6}, {0x51, 0xB7}, {0x52, 0x25}, /* 0x4C-0x4F */
-	{0x52, 0x24}, {0x52, 0x29}, {0x52, 0x2A}, {0x52, 0x28}, /* 0x50-0x53 */
+	{0x51, 0x75}, {0x51, 0xB6}, {0xF9, 0x2E}, {0x52, 0x25}, /* 0x4C-0x4F */
+	{0x52, 0x24}, {0xF9, 0xDD}, {0x52, 0x2A}, {0x52, 0x28}, /* 0x50-0x53 */
 	{0x52, 0xAB}, {0x52, 0xA9}, {0x52, 0xAA}, {0x52, 0xAC}, /* 0x54-0x57 */
-	{0x53, 0x23}, {0x53, 0x73}, {0x53, 0x75}, {0x54, 0x1D}, /* 0x58-0x5B */
+	{0x53, 0x23}, {0x53, 0x73}, {0xF9, 0x1C}, {0xF9, 0xED}, /* 0x58-0x5B */
 	{0x54, 0x2D}, {0x54, 0x1E}, {0x54, 0x3E}, {0x54, 0x26}, /* 0x5C-0x5F */
 	{0x54, 0x4E}, {0x54, 0x27}, {0x54, 0x46}, {0x54, 0x43}, /* 0x60-0x63 */
-	{0x54, 0x33}, {0x54, 0x48}, {0x54, 0x42}, {0x54, 0x1B}, /* 0x64-0x67 */
+	{0x54, 0x33}, {0x54, 0x48}, {0xF9, 0x80}, {0x54, 0x1B}, /* 0x64-0x67 */
 	{0x54, 0x29}, {0x54, 0x4A}, {0x54, 0x39}, {0x54, 0x3B}, /* 0x68-0x6B */
 	{0x54, 0x38}, {0x54, 0x2E}, {0x54, 0x35}, {0x54, 0x36}, /* 0x6C-0x6F */
 	{0x54, 0x20}, {0x54, 0x3C}, {0x54, 0x40}, {0x54, 0x31}, /* 0x70-0x73 */
@@ -468,10 +470,10 @@
 	{0x59, 0x8D}, {0x59, 0xA4}, {0x59, 0x93}, {0x59, 0x8A}, /* 0xB0-0xB3 */
 	{0x59, 0xA5}, {0x5B, 0x5D}, {0x5B, 0x5C}, {0x5B, 0x5A}, /* 0xB4-0xB7 */
 	{0x5B, 0x5B}, {0x5B, 0x8C}, {0x5B, 0x8B}, {0x5B, 0x8F}, /* 0xB8-0xBB */
-	{0x5C, 0x2C}, {0x5C, 0x40}, {0x5C, 0x41}, {0x5C, 0x3F}, /* 0xBC-0xBF */
+	{0x5C, 0x2C}, {0x5C, 0x40}, {0x5C, 0x41}, {0xF9, 0xBD}, /* 0xBC-0xBF */
 	{0x5C, 0x3E}, {0x5C, 0x90}, {0x5C, 0x91}, {0x5C, 0x94}, /* 0xC0-0xC3 */
 	{0x5C, 0x8C}, {0x5D, 0xEB}, {0x5E, 0x0C}, {0x5E, 0x8F}, /* 0xC4-0xC7 */
-	{0x5E, 0x87}, {0x5E, 0x8A}, {0x5E, 0xF7}, {0x5F, 0x04}, /* 0xC8-0xCB */
+	{0x5E, 0x87}, {0x5E, 0x8A}, {0x5E, 0xF7}, {0xF9, 0x43}, /* 0xC8-0xCB */
 	{0x5F, 0x1F}, {0x5F, 0x64}, {0x5F, 0x62}, {0x5F, 0x77}, /* 0xCC-0xCF */
 	{0x5F, 0x79}, {0x5F, 0xD8}, {0x5F, 0xCC}, {0x5F, 0xD7}, /* 0xD0-0xD3 */
 	{0x5F, 0xCD}, {0x5F, 0xF1}, {0x5F, 0xEB}, {0x5F, 0xF8}, /* 0xD4-0xD7 */
@@ -481,8 +483,8 @@
 	{0x62, 0x7E}, {0x62, 0x79}, {0x62, 0x73}, {0x62, 0x92}, /* 0xE4-0xE7 */
 	{0x62, 0x6F}, {0x62, 0x98}, {0x62, 0x6E}, {0x62, 0x95}, /* 0xE8-0xEB */
 	{0x62, 0x93}, {0x62, 0x91}, {0x62, 0x86}, {0x65, 0x39}, /* 0xEC-0xEF */
-	{0x65, 0x3B}, {0x65, 0x38}, {0x65, 0xF1}, {0x66, 0xF4}, /* 0xF0-0xF3 */
-	{0x67, 0x5F}, {0x67, 0x4E}, {0x67, 0x4F}, {0x67, 0x50}, /* 0xF4-0xF7 */
+	{0x65, 0x3B}, {0x65, 0x38}, {0x65, 0xF1}, {0xF9, 0x01}, /* 0xF0-0xF3 */
+	{0x67, 0x5F}, {0xF9, 0xE1}, {0x67, 0x4F}, {0x67, 0x50}, /* 0xF4-0xF7 */
 	{0x67, 0x51}, {0x67, 0x5C}, {0x67, 0x56}, {0x67, 0x5E}, /* 0xF8-0xFB */
 	{0x67, 0x49}, {0x67, 0x46}, {0x67, 0x60}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -506,20 +508,20 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x67, 0x53}, {0x67, 0x57}, {0x6B, 0x65}, {0x6B, 0xCF}, /* 0x40-0x43 */
 	{0x6C, 0x42}, {0x6C, 0x5E}, {0x6C, 0x99}, {0x6C, 0x81}, /* 0x44-0x47 */
-	{0x6C, 0x88}, {0x6C, 0x89}, {0x6C, 0x85}, {0x6C, 0x9B}, /* 0x48-0x4B */
+	{0xF9, 0x72}, {0x6C, 0x89}, {0x6C, 0x85}, {0x6C, 0x9B}, /* 0x48-0x4B */
 	{0x6C, 0x6A}, {0x6C, 0x7A}, {0x6C, 0x90}, {0x6C, 0x70}, /* 0x4C-0x4F */
 	{0x6C, 0x8C}, {0x6C, 0x68}, {0x6C, 0x96}, {0x6C, 0x92}, /* 0x50-0x53 */
 	{0x6C, 0x7D}, {0x6C, 0x83}, {0x6C, 0x72}, {0x6C, 0x7E}, /* 0x54-0x57 */
 	{0x6C, 0x74}, {0x6C, 0x86}, {0x6C, 0x76}, {0x6C, 0x8D}, /* 0x58-0x5B */
 	{0x6C, 0x94}, {0x6C, 0x98}, {0x6C, 0x82}, {0x70, 0x76}, /* 0x5C-0x5F */
-	{0x70, 0x7C}, {0x70, 0x7D}, {0x70, 0x78}, {0x72, 0x62}, /* 0x60-0x63 */
+	{0x70, 0x7C}, {0x70, 0x7D}, {0x70, 0x78}, {0xF9, 0x46}, /* 0x60-0x63 */
 	{0x72, 0x61}, {0x72, 0x60}, {0x72, 0xC4}, {0x72, 0xC2}, /* 0x64-0x67 */
 	{0x73, 0x96}, {0x75, 0x2C}, {0x75, 0x2B}, {0x75, 0x37}, /* 0x68-0x6B */
 	{0x75, 0x38}, {0x76, 0x82}, {0x76, 0xEF}, {0x77, 0xE3}, /* 0x6C-0x6F */
 	{0x79, 0xC1}, {0x79, 0xC0}, {0x79, 0xBF}, {0x7A, 0x76}, /* 0x70-0x73 */
 	{0x7C, 0xFB}, {0x7F, 0x55}, {0x80, 0x96}, {0x80, 0x93}, /* 0x74-0x77 */
 	{0x80, 0x9D}, {0x80, 0x98}, {0x80, 0x9B}, {0x80, 0x9A}, /* 0x78-0x7B */
-	{0x80, 0xB2}, {0x82, 0x6F}, {0x82, 0x92}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x80, 0xB2}, {0xF9, 0x7C}, {0x82, 0x92}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -529,25 +531,25 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x94-0x97 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
-	{0x00, 0x3F}, {0x82, 0x8B}, {0x82, 0x8D}, {0x89, 0x8B}, /* 0xA0-0xA3 */
+	{0x00, 0x3F}, {0x82, 0x8B}, {0x82, 0x8D}, {0xFA, 0x0A}, /* 0xA0-0xA3 */
 	{0x89, 0xD2}, {0x8A, 0x00}, {0x8C, 0x37}, {0x8C, 0x46}, /* 0xA4-0xA7 */
 	{0x8C, 0x55}, {0x8C, 0x9D}, {0x8D, 0x64}, {0x8D, 0x70}, /* 0xA8-0xAB */
-	{0x8D, 0xB3}, {0x8E, 0xAB}, {0x8E, 0xCA}, {0x8F, 0x9B}, /* 0xAC-0xAF */
-	{0x8F, 0xB0}, {0x8F, 0xC2}, {0x8F, 0xC6}, {0x8F, 0xC5}, /* 0xB0-0xB3 */
+	{0x8D, 0xB3}, {0x8E, 0xAB}, {0xF9, 0x02}, {0x8F, 0x9B}, /* 0xAC-0xAF */
+	{0xF9, 0x71}, {0x8F, 0xC2}, {0x8F, 0xC6}, {0x8F, 0xC5}, /* 0xB0-0xB3 */
 	{0x8F, 0xC4}, {0x5D, 0xE1}, {0x90, 0x91}, {0x90, 0xA2}, /* 0xB4-0xB7 */
 	{0x90, 0xAA}, {0x90, 0xA6}, {0x90, 0xA3}, {0x91, 0x49}, /* 0xB8-0xBB */
-	{0x91, 0xC6}, {0x91, 0xCC}, {0x96, 0x32}, {0x96, 0x2E}, /* 0xBC-0xBF */
+	{0x91, 0xC6}, {0xF9, 0xE9}, {0x96, 0x32}, {0xF9, 0xC6}, /* 0xBC-0xBF */
 	{0x96, 0x31}, {0x96, 0x2A}, {0x96, 0x2C}, {0x4E, 0x26}, /* 0xC0-0xC3 */
 	{0x4E, 0x56}, {0x4E, 0x73}, {0x4E, 0x8B}, {0x4E, 0x9B}, /* 0xC4-0xC7 */
 	{0x4E, 0x9E}, {0x4E, 0xAB}, {0x4E, 0xAC}, {0x4F, 0x6F}, /* 0xC8-0xCB */
 	{0x4F, 0x9D}, {0x4F, 0x8D}, {0x4F, 0x73}, {0x4F, 0x7F}, /* 0xCC-0xCF */
-	{0x4F, 0x6C}, {0x4F, 0x9B}, {0x4F, 0x8B}, {0x4F, 0x86}, /* 0xD0-0xD3 */
+	{0x4F, 0x6C}, {0x4F, 0x9B}, {0xF9, 0xB5}, {0xF9, 0x2D}, /* 0xD0-0xD3 */
 	{0x4F, 0x83}, {0x4F, 0x70}, {0x4F, 0x75}, {0x4F, 0x88}, /* 0xD4-0xD7 */
 	{0x4F, 0x69}, {0x4F, 0x7B}, {0x4F, 0x96}, {0x4F, 0x7E}, /* 0xD8-0xDB */
 	{0x4F, 0x8F}, {0x4F, 0x91}, {0x4F, 0x7A}, {0x51, 0x54}, /* 0xDC-0xDF */
-	{0x51, 0x52}, {0x51, 0x55}, {0x51, 0x69}, {0x51, 0x77}, /* 0xE0-0xE3 */
+	{0x51, 0x52}, {0x51, 0x55}, {0xF9, 0x78}, {0x51, 0x77}, /* 0xE0-0xE3 */
 	{0x51, 0x76}, {0x51, 0x78}, {0x51, 0xBD}, {0x51, 0xFD}, /* 0xE4-0xE7 */
-	{0x52, 0x3B}, {0x52, 0x38}, {0x52, 0x37}, {0x52, 0x3A}, /* 0xE8-0xEB */
+	{0x52, 0x3B}, {0x52, 0x38}, {0x52, 0x37}, {0xF9, 0xFF}, /* 0xE8-0xEB */
 	{0x52, 0x30}, {0x52, 0x2E}, {0x52, 0x36}, {0x52, 0x41}, /* 0xEC-0xEF */
 	{0x52, 0xBE}, {0x52, 0xBB}, {0x53, 0x52}, {0x53, 0x54}, /* 0xF0-0xF3 */
 	{0x53, 0x53}, {0x53, 0x51}, {0x53, 0x66}, {0x53, 0x77}, /* 0xF4-0xF7 */
@@ -580,7 +582,7 @@
 	{0x56, 0xFA}, {0x57, 0x83}, {0x57, 0x77}, {0x57, 0x6A}, /* 0x54-0x57 */
 	{0x57, 0x69}, {0x57, 0x61}, {0x57, 0x66}, {0x57, 0x64}, /* 0x58-0x5B */
 	{0x57, 0x7C}, {0x59, 0x1C}, {0x59, 0x49}, {0x59, 0x47}, /* 0x5C-0x5F */
-	{0x59, 0x48}, {0x59, 0x44}, {0x59, 0x54}, {0x59, 0xBE}, /* 0x60-0x63 */
+	{0xF9, 0x0C}, {0x59, 0x44}, {0x59, 0x54}, {0x59, 0xBE}, /* 0x60-0x63 */
 	{0x59, 0xBB}, {0x59, 0xD4}, {0x59, 0xB9}, {0x59, 0xAE}, /* 0x64-0x67 */
 	{0x59, 0xD1}, {0x59, 0xC6}, {0x59, 0xD0}, {0x59, 0xCD}, /* 0x68-0x6B */
 	{0x59, 0xCB}, {0x59, 0xD3}, {0x59, 0xCA}, {0x59, 0xAF}, /* 0x6C-0x6F */
@@ -605,20 +607,20 @@
 	{0x5E, 0x96}, {0x5E, 0xF6}, {0x5F, 0x26}, {0x5F, 0x27}, /* 0xB4-0xB7 */
 	{0x5F, 0x29}, {0x5F, 0x80}, {0x5F, 0x81}, {0x5F, 0x7F}, /* 0xB8-0xBB */
 	{0x5F, 0x7C}, {0x5F, 0xDD}, {0x5F, 0xE0}, {0x5F, 0xFD}, /* 0xBC-0xBF */
-	{0x5F, 0xF5}, {0x5F, 0xFF}, {0x60, 0x0F}, {0x60, 0x14}, /* 0xC0-0xC3 */
+	{0xF9, 0xA3}, {0x5F, 0xFF}, {0x60, 0x0F}, {0x60, 0x14}, /* 0xC0-0xC3 */
 	{0x60, 0x2F}, {0x60, 0x35}, {0x60, 0x16}, {0x60, 0x2A}, /* 0xC4-0xC7 */
 	{0x60, 0x15}, {0x60, 0x21}, {0x60, 0x27}, {0x60, 0x29}, /* 0xC8-0xCB */
 	{0x60, 0x2B}, {0x60, 0x1B}, {0x62, 0x16}, {0x62, 0x15}, /* 0xCC-0xCF */
 	{0x62, 0x3F}, {0x62, 0x3E}, {0x62, 0x40}, {0x62, 0x7F}, /* 0xD0-0xD3 */
-	{0x62, 0xC9}, {0x62, 0xCC}, {0x62, 0xC4}, {0x62, 0xBF}, /* 0xD4-0xD7 */
+	{0xF9, 0x25}, {0x62, 0xCC}, {0x62, 0xC4}, {0x62, 0xBF}, /* 0xD4-0xD7 */
 	{0x62, 0xC2}, {0x62, 0xB9}, {0x62, 0xD2}, {0x62, 0xDB}, /* 0xD8-0xDB */
-	{0x62, 0xAB}, {0x62, 0xD3}, {0x62, 0xD4}, {0x62, 0xCB}, /* 0xDC-0xDF */
+	{0x62, 0xAB}, {0xFA, 0x02}, {0x62, 0xD4}, {0x62, 0xCB}, /* 0xDC-0xDF */
 	{0x62, 0xC8}, {0x62, 0xA8}, {0x62, 0xBD}, {0x62, 0xBC}, /* 0xE0-0xE3 */
 	{0x62, 0xD0}, {0x62, 0xD9}, {0x62, 0xC7}, {0x62, 0xCD}, /* 0xE4-0xE7 */
 	{0x62, 0xB5}, {0x62, 0xDA}, {0x62, 0xB1}, {0x62, 0xD8}, /* 0xE8-0xEB */
 	{0x62, 0xD6}, {0x62, 0xD7}, {0x62, 0xC6}, {0x62, 0xAC}, /* 0xEC-0xEF */
 	{0x62, 0xCE}, {0x65, 0x3E}, {0x65, 0xA7}, {0x65, 0xBC}, /* 0xF0-0xF3 */
-	{0x65, 0xFA}, {0x66, 0x14}, {0x66, 0x13}, {0x66, 0x0C}, /* 0xF4-0xF7 */
+	{0x65, 0xFA}, {0x66, 0x14}, {0xF9, 0xE0}, {0x66, 0x0C}, /* 0xF4-0xF7 */
 	{0x66, 0x06}, {0x66, 0x02}, {0x66, 0x0E}, {0x66, 0x00}, /* 0xF8-0xFB */
 	{0x66, 0x0F}, {0x66, 0x15}, {0x66, 0x0A}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -643,13 +645,13 @@
 	{0x66, 0x07}, {0x67, 0x0D}, {0x67, 0x0B}, {0x67, 0x6D}, /* 0x40-0x43 */
 	{0x67, 0x8B}, {0x67, 0x95}, {0x67, 0x71}, {0x67, 0x9C}, /* 0x44-0x47 */
 	{0x67, 0x73}, {0x67, 0x77}, {0x67, 0x87}, {0x67, 0x9D}, /* 0x48-0x4B */
-	{0x67, 0x97}, {0x67, 0x6F}, {0x67, 0x70}, {0x67, 0x7F}, /* 0x4C-0x4F */
+	{0xF9, 0xF4}, {0x67, 0x6F}, {0x67, 0x70}, {0x67, 0x7F}, /* 0x4C-0x4F */
 	{0x67, 0x89}, {0x67, 0x7E}, {0x67, 0x90}, {0x67, 0x75}, /* 0x50-0x53 */
 	{0x67, 0x9A}, {0x67, 0x93}, {0x67, 0x7C}, {0x67, 0x6A}, /* 0x54-0x57 */
 	{0x67, 0x72}, {0x6B, 0x23}, {0x6B, 0x66}, {0x6B, 0x67}, /* 0x58-0x5B */
 	{0x6B, 0x7F}, {0x6C, 0x13}, {0x6C, 0x1B}, {0x6C, 0xE3}, /* 0x5C-0x5F */
-	{0x6C, 0xE8}, {0x6C, 0xF3}, {0x6C, 0xB1}, {0x6C, 0xCC}, /* 0x60-0x63 */
-	{0x6C, 0xE5}, {0x6C, 0xB3}, {0x6C, 0xBD}, {0x6C, 0xBE}, /* 0x64-0x67 */
+	{0x6C, 0xE8}, {0x6C, 0xF3}, {0x6C, 0xB1}, {0xF9, 0x68}, /* 0x60-0x63 */
+	{0xF9, 0xE3}, {0x6C, 0xB3}, {0x6C, 0xBD}, {0x6C, 0xBE}, /* 0x64-0x67 */
 	{0x6C, 0xBC}, {0x6C, 0xE2}, {0x6C, 0xAB}, {0x6C, 0xD5}, /* 0x68-0x6B */
 	{0x6C, 0xD3}, {0x6C, 0xB8}, {0x6C, 0xC4}, {0x6C, 0xB9}, /* 0x6C-0x6F */
 	{0x6C, 0xC1}, {0x6C, 0xAE}, {0x6C, 0xD7}, {0x6C, 0xC5}, /* 0x70-0x73 */
@@ -666,9 +668,9 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x70, 0x95}, {0x70, 0x8E}, {0x70, 0x92}, /* 0xA0-0xA3 */
-	{0x70, 0x8A}, {0x70, 0x99}, {0x72, 0x2C}, {0x72, 0x2D}, /* 0xA4-0xA7 */
+	{0x70, 0x8A}, {0xF9, 0xFB}, {0x72, 0x2C}, {0x72, 0x2D}, /* 0xA4-0xA7 */
 	{0x72, 0x38}, {0x72, 0x48}, {0x72, 0x67}, {0x72, 0x69}, /* 0xA8-0xAB */
-	{0x72, 0xC0}, {0x72, 0xCE}, {0x72, 0xD9}, {0x72, 0xD7}, /* 0xAC-0xAF */
+	{0xF9, 0xFA}, {0x72, 0xCE}, {0x72, 0xD9}, {0x72, 0xD7}, /* 0xAC-0xAF */
 	{0x72, 0xD0}, {0x73, 0xA9}, {0x73, 0xA8}, {0x73, 0x9F}, /* 0xB0-0xB3 */
 	{0x73, 0xAB}, {0x73, 0xA5}, {0x75, 0x3D}, {0x75, 0x9D}, /* 0xB4-0xB7 */
 	{0x75, 0x99}, {0x75, 0x9A}, {0x76, 0x84}, {0x76, 0xC2}, /* 0xB8-0xBB */
@@ -686,7 +688,7 @@
 	{0x82, 0xBE}, {0x82, 0xB7}, {0x86, 0x4E}, {0x86, 0x71}, /* 0xE8-0xEB */
 	{0x52, 0x1D}, {0x88, 0x68}, {0x8E, 0xCB}, {0x8F, 0xCE}, /* 0xEC-0xEF */
 	{0x8F, 0xD4}, {0x8F, 0xD1}, {0x90, 0xB5}, {0x90, 0xB8}, /* 0xF0-0xF3 */
-	{0x90, 0xB1}, {0x90, 0xB6}, {0x91, 0xC7}, {0x91, 0xD1}, /* 0xF4-0xF7 */
+	{0x90, 0xB1}, {0x90, 0xB6}, {0x91, 0xC7}, {0xF9, 0x0A}, /* 0xF4-0xF7 */
 	{0x95, 0x77}, {0x95, 0x80}, {0x96, 0x1C}, {0x96, 0x40}, /* 0xF8-0xFB */
 	{0x96, 0x3F}, {0x96, 0x3B}, {0x96, 0x44}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -709,8 +711,8 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x96, 0x42}, {0x96, 0xB9}, {0x96, 0xE8}, {0x97, 0x52}, /* 0x40-0x43 */
-	{0x97, 0x5E}, {0x4E, 0x9F}, {0x4E, 0xAD}, {0x4E, 0xAE}, /* 0x44-0x47 */
-	{0x4F, 0xE1}, {0x4F, 0xB5}, {0x4F, 0xAF}, {0x4F, 0xBF}, /* 0x48-0x4B */
+	{0x97, 0x5E}, {0x4E, 0x9F}, {0x4E, 0xAD}, {0xF9, 0x77}, /* 0x44-0x47 */
+	{0x4F, 0xE1}, {0x4F, 0xB5}, {0x4F, 0xAF}, {0xF9, 0x65}, /* 0x48-0x4B */
 	{0x4F, 0xE0}, {0x4F, 0xD1}, {0x4F, 0xCF}, {0x4F, 0xDD}, /* 0x4C-0x4F */
 	{0x4F, 0xC3}, {0x4F, 0xB6}, {0x4F, 0xD8}, {0x4F, 0xDF}, /* 0x50-0x53 */
 	{0x4F, 0xCA}, {0x4F, 0xD7}, {0x4F, 0xAE}, {0x4F, 0xD0}, /* 0x54-0x57 */
@@ -723,7 +725,7 @@
 	{0x53, 0x9A}, {0x53, 0xDB}, {0x54, 0xAC}, {0x54, 0xC0}, /* 0x70-0x73 */
 	{0x54, 0xA8}, {0x54, 0xCE}, {0x54, 0xC9}, {0x54, 0xB8}, /* 0x74-0x77 */
 	{0x54, 0xA6}, {0x54, 0xB3}, {0x54, 0xC7}, {0x54, 0xC2}, /* 0x78-0x7B */
-	{0x54, 0xBD}, {0x54, 0xAA}, {0x54, 0xC1}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0xF9, 0x9E}, {0x54, 0xAA}, {0x54, 0xC1}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -738,7 +740,7 @@
 	{0x54, 0xA7}, {0x54, 0xBF}, {0x56, 0xFF}, {0x57, 0x82}, /* 0xA8-0xAB */
 	{0x57, 0x8B}, {0x57, 0xA0}, {0x57, 0xA3}, {0x57, 0xA2}, /* 0xAC-0xAF */
 	{0x57, 0xCE}, {0x57, 0xAE}, {0x57, 0x93}, {0x59, 0x55}, /* 0xB0-0xB3 */
-	{0x59, 0x51}, {0x59, 0x4F}, {0x59, 0x4E}, {0x59, 0x50}, /* 0xB4-0xB7 */
+	{0xF9, 0x09}, {0x59, 0x4F}, {0x59, 0x4E}, {0x59, 0x50}, /* 0xB4-0xB7 */
 	{0x59, 0xDC}, {0x59, 0xD8}, {0x59, 0xFF}, {0x59, 0xE3}, /* 0xB8-0xBB */
 	{0x59, 0xE8}, {0x5A, 0x03}, {0x59, 0xE5}, {0x59, 0xEA}, /* 0xBC-0xBF */
 	{0x59, 0xDA}, {0x59, 0xE6}, {0x5A, 0x01}, {0x59, 0xFB}, /* 0xC0-0xC3 */
@@ -746,10 +748,10 @@
 	{0x5B, 0xA2}, {0x5B, 0xA5}, {0x5C, 0x01}, {0x5C, 0x4E}, /* 0xC8-0xCB */
 	{0x5C, 0x4F}, {0x5C, 0x4D}, {0x5C, 0x4B}, {0x5C, 0xD9}, /* 0xCC-0xCF */
 	{0x5C, 0xD2}, {0x5D, 0xF7}, {0x5E, 0x1D}, {0x5E, 0x25}, /* 0xD0-0xD3 */
-	{0x5E, 0x1F}, {0x5E, 0x7D}, {0x5E, 0xA0}, {0x5E, 0xA6}, /* 0xD4-0xD7 */
+	{0x5E, 0x1F}, {0x5E, 0x7D}, {0x5E, 0xA0}, {0xFA, 0x01}, /* 0xD4-0xD7 */
 	{0x5E, 0xFA}, {0x5F, 0x08}, {0x5F, 0x2D}, {0x5F, 0x65}, /* 0xD8-0xDB */
-	{0x5F, 0x88}, {0x5F, 0x85}, {0x5F, 0x8A}, {0x5F, 0x8B}, /* 0xDC-0xDF */
-	{0x5F, 0x87}, {0x5F, 0x8C}, {0x5F, 0x89}, {0x60, 0x12}, /* 0xE0-0xE3 */
+	{0x5F, 0x88}, {0x5F, 0x85}, {0x5F, 0x8A}, {0xF9, 0xD8}, /* 0xDC-0xDF */
+	{0x5F, 0x87}, {0x5F, 0x8C}, {0x5F, 0x89}, {0xF9, 0x60}, /* 0xE0-0xE3 */
 	{0x60, 0x1D}, {0x60, 0x20}, {0x60, 0x25}, {0x60, 0x0E}, /* 0xE4-0xE7 */
 	{0x60, 0x28}, {0x60, 0x4D}, {0x60, 0x70}, {0x60, 0x68}, /* 0xE8-0xEB */
 	{0x60, 0x62}, {0x60, 0x46}, {0x60, 0x43}, {0x60, 0x6C}, /* 0xEC-0xEF */
@@ -776,7 +778,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x62, 0xEF}, {0x62, 0xEC}, {0x62, 0xFE}, {0x62, 0xF4}, /* 0x40-0x43 */
+	{0x62, 0xEF}, {0x62, 0xEC}, {0xF9, 0x73}, {0x62, 0xF4}, /* 0x40-0x43 */
 	{0x63, 0x11}, {0x63, 0x02}, {0x65, 0x3F}, {0x65, 0x45}, /* 0x44-0x47 */
 	{0x65, 0xAB}, {0x65, 0xBD}, {0x65, 0xE2}, {0x66, 0x25}, /* 0x48-0x4B */
 	{0x66, 0x2D}, {0x66, 0x20}, {0x66, 0x27}, {0x66, 0x2F}, /* 0x4C-0x4F */
@@ -786,12 +788,12 @@
 	{0x67, 0xAF}, {0x67, 0xF5}, {0x67, 0xE9}, {0x67, 0xEF}, /* 0x5C-0x5F */
 	{0x67, 0xC4}, {0x67, 0xD1}, {0x67, 0xB4}, {0x67, 0xDA}, /* 0x60-0x63 */
 	{0x67, 0xE5}, {0x67, 0xB8}, {0x67, 0xCF}, {0x67, 0xDE}, /* 0x64-0x67 */
-	{0x67, 0xF3}, {0x67, 0xB0}, {0x67, 0xD9}, {0x67, 0xE2}, /* 0x68-0x6B */
+	{0xF9, 0xC9}, {0x67, 0xB0}, {0x67, 0xD9}, {0x67, 0xE2}, /* 0x68-0x6B */
 	{0x67, 0xDD}, {0x67, 0xD2}, {0x6B, 0x6A}, {0x6B, 0x83}, /* 0x6C-0x6F */
 	{0x6B, 0x86}, {0x6B, 0xB5}, {0x6B, 0xD2}, {0x6B, 0xD7}, /* 0x70-0x73 */
 	{0x6C, 0x1F}, {0x6C, 0xC9}, {0x6D, 0x0B}, {0x6D, 0x32}, /* 0x74-0x77 */
-	{0x6D, 0x2A}, {0x6D, 0x41}, {0x6D, 0x25}, {0x6D, 0x0C}, /* 0x78-0x7B */
-	{0x6D, 0x31}, {0x6D, 0x1E}, {0x6D, 0x17}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x6D, 0x2A}, {0xF9, 0xCA}, {0x6D, 0x25}, {0x6D, 0x0C}, /* 0x78-0x7B */
+	{0x6D, 0x31}, {0xFA, 0x05}, {0x6D, 0x17}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -802,20 +804,20 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x6D, 0x3B}, {0x6D, 0x3D}, {0x6D, 0x3E}, /* 0xA0-0xA3 */
-	{0x6D, 0x36}, {0x6D, 0x1B}, {0x6C, 0xF5}, {0x6D, 0x39}, /* 0xA4-0xA7 */
+	{0x6D, 0x36}, {0xF9, 0x15}, {0x6C, 0xF5}, {0x6D, 0x39}, /* 0xA4-0xA7 */
 	{0x6D, 0x27}, {0x6D, 0x38}, {0x6D, 0x29}, {0x6D, 0x2E}, /* 0xA8-0xAB */
 	{0x6D, 0x35}, {0x6D, 0x0E}, {0x6D, 0x2B}, {0x70, 0xAB}, /* 0xAC-0xAF */
 	{0x70, 0xBA}, {0x70, 0xB3}, {0x70, 0xAC}, {0x70, 0xAF}, /* 0xB0-0xB3 */
 	{0x70, 0xAD}, {0x70, 0xB8}, {0x70, 0xAE}, {0x70, 0xA4}, /* 0xB4-0xB7 */
 	{0x72, 0x30}, {0x72, 0x72}, {0x72, 0x6F}, {0x72, 0x74}, /* 0xB8-0xBB */
 	{0x72, 0xE9}, {0x72, 0xE0}, {0x72, 0xE1}, {0x73, 0xB7}, /* 0xBC-0xBF */
-	{0x73, 0xCA}, {0x73, 0xBB}, {0x73, 0xB2}, {0x73, 0xCD}, /* 0xC0-0xC3 */
+	{0x73, 0xCA}, {0x73, 0xBB}, {0xF9, 0xAD}, {0x73, 0xCD}, /* 0xC0-0xC3 */
 	{0x73, 0xC0}, {0x73, 0xB3}, {0x75, 0x1A}, {0x75, 0x2D}, /* 0xC4-0xC7 */
 	{0x75, 0x4F}, {0x75, 0x4C}, {0x75, 0x4E}, {0x75, 0x4B}, /* 0xC8-0xCB */
 	{0x75, 0xAB}, {0x75, 0xA4}, {0x75, 0xA5}, {0x75, 0xA2}, /* 0xCC-0xCF */
 	{0x75, 0xA3}, {0x76, 0x78}, {0x76, 0x86}, {0x76, 0x87}, /* 0xD0-0xD3 */
 	{0x76, 0x88}, {0x76, 0xC8}, {0x76, 0xC6}, {0x76, 0xC3}, /* 0xD4-0xD7 */
-	{0x76, 0xC5}, {0x77, 0x01}, {0x76, 0xF9}, {0x76, 0xF8}, /* 0xD8-0xDB */
+	{0x76, 0xC5}, {0xF9, 0x6D}, {0x76, 0xF9}, {0x76, 0xF8}, /* 0xD8-0xDB */
 	{0x77, 0x09}, {0x77, 0x0B}, {0x76, 0xFE}, {0x76, 0xFC}, /* 0xDC-0xDF */
 	{0x77, 0x07}, {0x77, 0xDC}, {0x78, 0x02}, {0x78, 0x14}, /* 0xE0-0xE3 */
 	{0x78, 0x0C}, {0x78, 0x0D}, {0x79, 0x46}, {0x79, 0x49}, /* 0xE4-0xE7 */
@@ -850,7 +852,7 @@
 	{0x80, 0xCE}, {0x80, 0xDE}, {0x80, 0xE4}, {0x80, 0xDD}, /* 0x4C-0x4F */
 	{0x81, 0xF4}, {0x82, 0x22}, {0x82, 0xE7}, {0x83, 0x03}, /* 0x50-0x53 */
 	{0x83, 0x05}, {0x82, 0xE3}, {0x82, 0xDB}, {0x82, 0xE6}, /* 0x54-0x57 */
-	{0x83, 0x04}, {0x82, 0xE5}, {0x83, 0x02}, {0x83, 0x09}, /* 0x58-0x5B */
+	{0x83, 0x04}, {0xF9, 0x74}, {0x83, 0x02}, {0x83, 0x09}, /* 0x58-0x5B */
 	{0x82, 0xD2}, {0x82, 0xD7}, {0x82, 0xF1}, {0x83, 0x01}, /* 0x5C-0x5F */
 	{0x82, 0xDC}, {0x82, 0xD4}, {0x82, 0xD1}, {0x82, 0xDE}, /* 0x60-0x63 */
 	{0x82, 0xD3}, {0x82, 0xDF}, {0x82, 0xEF}, {0x83, 0x06}, /* 0x64-0x67 */
@@ -872,8 +874,8 @@
 	{0x00, 0x3F}, {0x8F, 0xED}, {0x8F, 0xEB}, {0x8F, 0xE4}, /* 0xA0-0xA3 */
 	{0x8F, 0xE8}, {0x90, 0xCA}, {0x90, 0xCE}, {0x90, 0xC1}, /* 0xA4-0xA7 */
 	{0x90, 0xC3}, {0x91, 0x4B}, {0x91, 0x4A}, {0x91, 0xCD}, /* 0xA8-0xAB */
-	{0x95, 0x82}, {0x96, 0x50}, {0x96, 0x4B}, {0x96, 0x4C}, /* 0xAC-0xAF */
-	{0x96, 0x4D}, {0x97, 0x62}, {0x97, 0x69}, {0x97, 0xCB}, /* 0xB0-0xB3 */
+	{0x95, 0x82}, {0x96, 0x50}, {0xF9, 0x51}, {0x96, 0x4C}, /* 0xAC-0xAF */
+	{0xFA, 0x09}, {0x97, 0x62}, {0x97, 0x69}, {0x97, 0xCB}, /* 0xB0-0xB3 */
 	{0x97, 0xED}, {0x97, 0xF3}, {0x98, 0x01}, {0x98, 0xA8}, /* 0xB4-0xB7 */
 	{0x98, 0xDB}, {0x98, 0xDF}, {0x99, 0x96}, {0x99, 0x99}, /* 0xB8-0xBB */
 	{0x4E, 0x58}, {0x4E, 0xB3}, {0x50, 0x0C}, {0x50, 0x0D}, /* 0xBC-0xBF */
@@ -883,9 +885,9 @@
 	{0x50, 0x11}, {0x4F, 0xFA}, {0x50, 0x00}, {0x50, 0x14}, /* 0xCC-0xCF */
 	{0x50, 0x28}, {0x4F, 0xF1}, {0x50, 0x21}, {0x50, 0x0B}, /* 0xD0-0xD3 */
 	{0x50, 0x19}, {0x50, 0x18}, {0x4F, 0xF3}, {0x4F, 0xEE}, /* 0xD4-0xD7 */
-	{0x50, 0x2D}, {0x50, 0x2A}, {0x4F, 0xFE}, {0x50, 0x2B}, /* 0xD8-0xDB */
+	{0x50, 0x2D}, {0x50, 0x2A}, {0x4F, 0xFE}, {0xF9, 0xD4}, /* 0xD8-0xDB */
 	{0x50, 0x09}, {0x51, 0x7C}, {0x51, 0xA4}, {0x51, 0xA5}, /* 0xDC-0xDF */
-	{0x51, 0xA2}, {0x51, 0xCD}, {0x51, 0xCC}, {0x51, 0xC6}, /* 0xE0-0xE3 */
+	{0x51, 0xA2}, {0x51, 0xCD}, {0xF9, 0x55}, {0x51, 0xC6}, /* 0xE0-0xE3 */
 	{0x51, 0xCB}, {0x52, 0x56}, {0x52, 0x5C}, {0x52, 0x54}, /* 0xE4-0xE7 */
 	{0x52, 0x5B}, {0x52, 0x5D}, {0x53, 0x2A}, {0x53, 0x7F}, /* 0xE8-0xEB */
 	{0x53, 0x9F}, {0x53, 0x9D}, {0x53, 0xDF}, {0x54, 0xE8}, /* 0xEC-0xEF */
@@ -946,19 +948,19 @@
 	{0x63, 0x42}, {0x63, 0x46}, {0x63, 0x4F}, {0x63, 0x49}, /* 0xB8-0xBB */
 	{0x63, 0x3A}, {0x63, 0x50}, {0x63, 0x3D}, {0x63, 0x2A}, /* 0xBC-0xBF */
 	{0x63, 0x2B}, {0x63, 0x28}, {0x63, 0x4D}, {0x63, 0x4C}, /* 0xC0-0xC3 */
-	{0x65, 0x48}, {0x65, 0x49}, {0x65, 0x99}, {0x65, 0xC1}, /* 0xC4-0xC7 */
-	{0x65, 0xC5}, {0x66, 0x42}, {0x66, 0x49}, {0x66, 0x4F}, /* 0xC8-0xCB */
+	{0x65, 0x48}, {0x65, 0x49}, {0xF9, 0xBE}, {0x65, 0xC1}, /* 0xC4-0xC7 */
+	{0xF9, 0x83}, {0x66, 0x42}, {0x66, 0x49}, {0x66, 0x4F}, /* 0xC8-0xCB */
 	{0x66, 0x43}, {0x66, 0x52}, {0x66, 0x4C}, {0x66, 0x45}, /* 0xCC-0xCF */
 	{0x66, 0x41}, {0x66, 0xF8}, {0x67, 0x14}, {0x67, 0x15}, /* 0xD0-0xD3 */
-	{0x67, 0x17}, {0x68, 0x21}, {0x68, 0x38}, {0x68, 0x48}, /* 0xD4-0xD7 */
+	{0xF9, 0x29}, {0x68, 0x21}, {0x68, 0x38}, {0x68, 0x48}, /* 0xD4-0xD7 */
 	{0x68, 0x46}, {0x68, 0x53}, {0x68, 0x39}, {0x68, 0x42}, /* 0xD8-0xDB */
-	{0x68, 0x54}, {0x68, 0x29}, {0x68, 0xB3}, {0x68, 0x17}, /* 0xDC-0xDF */
+	{0x68, 0x54}, {0x68, 0x29}, {0x68, 0xB3}, {0xF9, 0xDA}, /* 0xDC-0xDF */
 	{0x68, 0x4C}, {0x68, 0x51}, {0x68, 0x3D}, {0x67, 0xF4}, /* 0xE0-0xE3 */
 	{0x68, 0x50}, {0x68, 0x40}, {0x68, 0x3C}, {0x68, 0x43}, /* 0xE4-0xE7 */
 	{0x68, 0x2A}, {0x68, 0x45}, {0x68, 0x13}, {0x68, 0x18}, /* 0xE8-0xEB */
 	{0x68, 0x41}, {0x6B, 0x8A}, {0x6B, 0x89}, {0x6B, 0xB7}, /* 0xEC-0xEF */
 	{0x6C, 0x23}, {0x6C, 0x27}, {0x6C, 0x28}, {0x6C, 0x26}, /* 0xF0-0xF3 */
-	{0x6C, 0x24}, {0x6C, 0xF0}, {0x6D, 0x6A}, {0x6D, 0x95}, /* 0xF4-0xF7 */
+	{0x6C, 0x24}, {0x6C, 0xF0}, {0xF9, 0x2A}, {0x6D, 0x95}, /* 0xF4-0xF7 */
 	{0x6D, 0x88}, {0x6D, 0x87}, {0x6D, 0x66}, {0x6D, 0x78}, /* 0xF8-0xFB */
 	{0x6D, 0x77}, {0x6D, 0x59}, {0x6D, 0x93}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -983,16 +985,16 @@
 	{0x6D, 0x6C}, {0x6D, 0x89}, {0x6D, 0x6E}, {0x6D, 0x5A}, /* 0x40-0x43 */
 	{0x6D, 0x74}, {0x6D, 0x69}, {0x6D, 0x8C}, {0x6D, 0x8A}, /* 0x44-0x47 */
 	{0x6D, 0x79}, {0x6D, 0x85}, {0x6D, 0x65}, {0x6D, 0x94}, /* 0x48-0x4B */
-	{0x70, 0xCA}, {0x70, 0xD8}, {0x70, 0xE4}, {0x70, 0xD9}, /* 0x4C-0x4F */
-	{0x70, 0xC8}, {0x70, 0xCF}, {0x72, 0x39}, {0x72, 0x79}, /* 0x50-0x53 */
-	{0x72, 0xFC}, {0x72, 0xF9}, {0x72, 0xFD}, {0x72, 0xF8}, /* 0x54-0x57 */
-	{0x72, 0xF7}, {0x73, 0x86}, {0x73, 0xED}, {0x74, 0x09}, /* 0x58-0x5B */
-	{0x73, 0xEE}, {0x73, 0xE0}, {0x73, 0xEA}, {0x73, 0xDE}, /* 0x5C-0x5F */
+	{0x70, 0xCA}, {0x70, 0xD8}, {0x70, 0xE4}, {0xF9, 0x16}, /* 0x4C-0x4F */
+	{0xF9, 0x9F}, {0x70, 0xCF}, {0x72, 0x39}, {0x72, 0x79}, /* 0x50-0x53 */
+	{0xF9, 0x2B}, {0x72, 0xF9}, {0x72, 0xFD}, {0x72, 0xF8}, /* 0x54-0x57 */
+	{0x72, 0xF7}, {0x73, 0x86}, {0x73, 0xED}, {0xF9, 0xCC}, /* 0x58-0x5B */
+	{0x73, 0xEE}, {0x73, 0xE0}, {0x73, 0xEA}, {0xF9, 0x17}, /* 0x5C-0x5F */
 	{0x75, 0x54}, {0x75, 0x5D}, {0x75, 0x5C}, {0x75, 0x5A}, /* 0x60-0x63 */
-	{0x75, 0x59}, {0x75, 0xBE}, {0x75, 0xC5}, {0x75, 0xC7}, /* 0x64-0x67 */
+	{0xF9, 0xCD}, {0x75, 0xBE}, {0x75, 0xC5}, {0x75, 0xC7}, /* 0x64-0x67 */
 	{0x75, 0xB2}, {0x75, 0xB3}, {0x75, 0xBD}, {0x75, 0xBC}, /* 0x68-0x6B */
 	{0x75, 0xB9}, {0x75, 0xC2}, {0x75, 0xB8}, {0x76, 0x8B}, /* 0x6C-0x6F */
-	{0x76, 0xB0}, {0x76, 0xCA}, {0x76, 0xCD}, {0x76, 0xCE}, /* 0x70-0x73 */
+	{0x76, 0xB0}, {0xFA, 0x17}, {0x76, 0xCD}, {0x76, 0xCE}, /* 0x70-0x73 */
 	{0x77, 0x29}, {0x77, 0x1F}, {0x77, 0x20}, {0x77, 0x28}, /* 0x74-0x77 */
 	{0x77, 0xE9}, {0x78, 0x30}, {0x78, 0x27}, {0x78, 0x38}, /* 0x78-0x7B */
 	{0x78, 0x1D}, {0x78, 0x34}, {0x78, 0x37}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -1007,13 +1009,13 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x78, 0x25}, {0x78, 0x2D}, {0x78, 0x20}, /* 0xA0-0xA3 */
 	{0x78, 0x1F}, {0x78, 0x32}, {0x79, 0x55}, {0x79, 0x50}, /* 0xA4-0xA7 */
-	{0x79, 0x60}, {0x79, 0x5F}, {0x79, 0x56}, {0x79, 0x5E}, /* 0xA8-0xAB */
+	{0x79, 0x60}, {0x79, 0x5F}, {0x79, 0x56}, {0xFA, 0x19}, /* 0xA8-0xAB */
 	{0x79, 0x5D}, {0x79, 0x57}, {0x79, 0x5A}, {0x79, 0xE4}, /* 0xAC-0xAF */
 	{0x79, 0xE3}, {0x79, 0xE7}, {0x79, 0xDF}, {0x79, 0xE6}, /* 0xB0-0xB3 */
 	{0x79, 0xE9}, {0x79, 0xD8}, {0x7A, 0x84}, {0x7A, 0x88}, /* 0xB4-0xB7 */
 	{0x7A, 0xD9}, {0x7B, 0x06}, {0x7B, 0x11}, {0x7C, 0x89}, /* 0xB8-0xBB */
 	{0x7D, 0x21}, {0x7D, 0x17}, {0x7D, 0x0B}, {0x7D, 0x0A}, /* 0xBC-0xBF */
-	{0x7D, 0x20}, {0x7D, 0x22}, {0x7D, 0x14}, {0x7D, 0x10}, /* 0xC0-0xC3 */
+	{0x7D, 0x20}, {0xF9, 0x6A}, {0x7D, 0x14}, {0xF9, 0xCF}, /* 0xC0-0xC3 */
 	{0x7D, 0x15}, {0x7D, 0x1A}, {0x7D, 0x1C}, {0x7D, 0x0D}, /* 0xC4-0xC7 */
 	{0x7D, 0x19}, {0x7D, 0x1B}, {0x7F, 0x3A}, {0x7F, 0x5F}, /* 0xC8-0xCB */
 	{0x7F, 0x94}, {0x7F, 0xC5}, {0x7F, 0xC1}, {0x80, 0x06}, /* 0xCC-0xCF */
@@ -1027,7 +1029,7 @@
 	{0x82, 0xBB}, {0x83, 0x2B}, {0x83, 0x52}, {0x83, 0x54}, /* 0xEC-0xEF */
 	{0x83, 0x4A}, {0x83, 0x38}, {0x83, 0x50}, {0x83, 0x49}, /* 0xF0-0xF3 */
 	{0x83, 0x35}, {0x83, 0x34}, {0x83, 0x4F}, {0x83, 0x32}, /* 0xF4-0xF7 */
-	{0x83, 0x39}, {0x83, 0x36}, {0x83, 0x17}, {0x83, 0x40}, /* 0xF8-0xFB */
+	{0x83, 0x39}, {0xF9, 0xFE}, {0x83, 0x17}, {0x83, 0x40}, /* 0xF8-0xFB */
 	{0x83, 0x31}, {0x83, 0x28}, {0x83, 0x43}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -1054,7 +1056,7 @@
 	{0x88, 0x82}, {0x88, 0x7D}, {0x88, 0x79}, {0x8A, 0x18}, /* 0x4C-0x4F */
 	{0x8A, 0x10}, {0x8A, 0x0E}, {0x8A, 0x0C}, {0x8A, 0x15}, /* 0x50-0x53 */
 	{0x8A, 0x0A}, {0x8A, 0x17}, {0x8A, 0x13}, {0x8A, 0x16}, /* 0x54-0x57 */
-	{0x8A, 0x0F}, {0x8A, 0x11}, {0x8C, 0x48}, {0x8C, 0x7A}, /* 0x58-0x5B */
+	{0x8A, 0x0F}, {0x8A, 0x11}, {0xF9, 0x00}, {0x8C, 0x7A}, /* 0x58-0x5B */
 	{0x8C, 0x79}, {0x8C, 0xA1}, {0x8C, 0xA2}, {0x8D, 0x77}, /* 0x5C-0x5F */
 	{0x8E, 0xAC}, {0x8E, 0xD2}, {0x8E, 0xD4}, {0x8E, 0xCF}, /* 0x60-0x63 */
 	{0x8F, 0xB1}, {0x90, 0x01}, {0x90, 0x06}, {0x8F, 0xF7}, /* 0x64-0x67 */
@@ -1082,10 +1084,10 @@
 	{0x50, 0x76}, {0x50, 0x4E}, {0x50, 0x55}, {0x50, 0x75}, /* 0xB8-0xBB */
 	{0x50, 0x74}, {0x50, 0x77}, {0x50, 0x4F}, {0x50, 0x0F}, /* 0xBC-0xBF */
 	{0x50, 0x6F}, {0x50, 0x6D}, {0x51, 0x5C}, {0x51, 0x95}, /* 0xC0-0xC3 */
-	{0x51, 0xF0}, {0x52, 0x6A}, {0x52, 0x6F}, {0x52, 0xD2}, /* 0xC4-0xC7 */
+	{0x51, 0xF0}, {0x52, 0x6A}, {0x52, 0x6F}, {0xF9, 0x52}, /* 0xC4-0xC7 */
 	{0x52, 0xD9}, {0x52, 0xD8}, {0x52, 0xD5}, {0x53, 0x10}, /* 0xC8-0xCB */
-	{0x53, 0x0F}, {0x53, 0x19}, {0x53, 0x3F}, {0x53, 0x40}, /* 0xCC-0xCF */
-	{0x53, 0x3E}, {0x53, 0xC3}, {0x66, 0xFC}, {0x55, 0x46}, /* 0xD0-0xD3 */
+	{0x53, 0x0F}, {0x53, 0x19}, {0xF9, 0xEB}, {0x53, 0x40}, /* 0xCC-0xCF */
+	{0x53, 0x3E}, {0xF9, 0x6B}, {0x66, 0xFC}, {0x55, 0x46}, /* 0xD0-0xD3 */
 	{0x55, 0x6A}, {0x55, 0x66}, {0x55, 0x44}, {0x55, 0x5E}, /* 0xD4-0xD7 */
 	{0x55, 0x61}, {0x55, 0x43}, {0x55, 0x4A}, {0x55, 0x31}, /* 0xD8-0xDB */
 	{0x55, 0x56}, {0x55, 0x4F}, {0x55, 0x55}, {0x55, 0x2F}, /* 0xDC-0xDF */
@@ -1122,7 +1124,7 @@
 	{0x5C, 0x09}, {0x5C, 0x08}, {0x5C, 0x07}, {0x5C, 0x60}, /* 0x4C-0x4F */
 	{0x5C, 0x5C}, {0x5C, 0x5D}, {0x5D, 0x07}, {0x5D, 0x06}, /* 0x50-0x53 */
 	{0x5D, 0x0E}, {0x5D, 0x1B}, {0x5D, 0x16}, {0x5D, 0x22}, /* 0x54-0x57 */
-	{0x5D, 0x11}, {0x5D, 0x29}, {0x5D, 0x14}, {0x5D, 0x19}, /* 0x58-0x5B */
+	{0x5D, 0x11}, {0x5D, 0x29}, {0x5D, 0x14}, {0xF9, 0xD5}, /* 0x58-0x5B */
 	{0x5D, 0x24}, {0x5D, 0x27}, {0x5D, 0x17}, {0x5D, 0xE2}, /* 0x5C-0x5F */
 	{0x5E, 0x38}, {0x5E, 0x36}, {0x5E, 0x33}, {0x5E, 0x37}, /* 0x60-0x63 */
 	{0x5E, 0xB7}, {0x5E, 0xB8}, {0x5E, 0xB6}, {0x5E, 0xB5}, /* 0x64-0x67 */
@@ -1145,26 +1147,26 @@
 	{0x60, 0xDC}, {0x60, 0xBC}, {0x60, 0xD8}, {0x60, 0xD5}, /* 0xA4-0xA7 */
 	{0x60, 0xC6}, {0x60, 0xDF}, {0x60, 0xB8}, {0x60, 0xDA}, /* 0xA8-0xAB */
 	{0x60, 0xC7}, {0x62, 0x1A}, {0x62, 0x1B}, {0x62, 0x48}, /* 0xAC-0xAF */
-	{0x63, 0xA0}, {0x63, 0xA7}, {0x63, 0x72}, {0x63, 0x96}, /* 0xB0-0xB3 */
+	{0xF9, 0x75}, {0x63, 0xA7}, {0x63, 0x72}, {0x63, 0x96}, /* 0xB0-0xB3 */
 	{0x63, 0xA2}, {0x63, 0xA5}, {0x63, 0x77}, {0x63, 0x67}, /* 0xB4-0xB7 */
 	{0x63, 0x98}, {0x63, 0xAA}, {0x63, 0x71}, {0x63, 0xA9}, /* 0xB8-0xBB */
 	{0x63, 0x89}, {0x63, 0x83}, {0x63, 0x9B}, {0x63, 0x6B}, /* 0xBC-0xBF */
 	{0x63, 0xA8}, {0x63, 0x84}, {0x63, 0x88}, {0x63, 0x99}, /* 0xC0-0xC3 */
 	{0x63, 0xA1}, {0x63, 0xAC}, {0x63, 0x92}, {0x63, 0x8F}, /* 0xC4-0xC7 */
-	{0x63, 0x80}, {0x63, 0x7B}, {0x63, 0x69}, {0x63, 0x68}, /* 0xC8-0xCB */
+	{0x63, 0x80}, {0xF9, 0xA4}, {0x63, 0x69}, {0x63, 0x68}, /* 0xC8-0xCB */
 	{0x63, 0x7A}, {0x65, 0x5D}, {0x65, 0x56}, {0x65, 0x51}, /* 0xCC-0xCF */
 	{0x65, 0x59}, {0x65, 0x57}, {0x55, 0x5F}, {0x65, 0x4F}, /* 0xD0-0xD3 */
 	{0x65, 0x58}, {0x65, 0x55}, {0x65, 0x54}, {0x65, 0x9C}, /* 0xD4-0xD7 */
 	{0x65, 0x9B}, {0x65, 0xAC}, {0x65, 0xCF}, {0x65, 0xCB}, /* 0xD8-0xDB */
 	{0x65, 0xCC}, {0x65, 0xCE}, {0x66, 0x5D}, {0x66, 0x5A}, /* 0xDC-0xDF */
 	{0x66, 0x64}, {0x66, 0x68}, {0x66, 0x66}, {0x66, 0x5E}, /* 0xE0-0xE3 */
-	{0x66, 0xF9}, {0x52, 0xD7}, {0x67, 0x1B}, {0x68, 0x81}, /* 0xE4-0xE7 */
+	{0x66, 0xF9}, {0x52, 0xD7}, {0x67, 0x1B}, {0xF9, 0x7A}, /* 0xE4-0xE7 */
 	{0x68, 0xAF}, {0x68, 0xA2}, {0x68, 0x93}, {0x68, 0xB5}, /* 0xE8-0xEB */
 	{0x68, 0x7F}, {0x68, 0x76}, {0x68, 0xB1}, {0x68, 0xA7}, /* 0xEC-0xEF */
 	{0x68, 0x97}, {0x68, 0xB0}, {0x68, 0x83}, {0x68, 0xC4}, /* 0xF0-0xF3 */
 	{0x68, 0xAD}, {0x68, 0x86}, {0x68, 0x85}, {0x68, 0x94}, /* 0xF4-0xF7 */
-	{0x68, 0x9D}, {0x68, 0xA8}, {0x68, 0x9F}, {0x68, 0xA1}, /* 0xF8-0xFB */
-	{0x68, 0x82}, {0x6B, 0x32}, {0x6B, 0xBA}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x68, 0x9D}, {0xF9, 0xE2}, {0x68, 0x9F}, {0x68, 0xA1}, /* 0xF8-0xFB */
+	{0x68, 0x82}, {0x6B, 0x32}, {0xF9, 0x70}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_B2[256] = {
@@ -1187,18 +1189,18 @@
 	{0x6B, 0xEB}, {0x6B, 0xEC}, {0x6C, 0x2B}, {0x6D, 0x8E}, /* 0x40-0x43 */
 	{0x6D, 0xBC}, {0x6D, 0xF3}, {0x6D, 0xD9}, {0x6D, 0xB2}, /* 0x44-0x47 */
 	{0x6D, 0xE1}, {0x6D, 0xCC}, {0x6D, 0xE4}, {0x6D, 0xFB}, /* 0x48-0x4B */
-	{0x6D, 0xFA}, {0x6E, 0x05}, {0x6D, 0xC7}, {0x6D, 0xCB}, /* 0x4C-0x4F */
+	{0x6D, 0xFA}, {0x6E, 0x05}, {0x6D, 0xC7}, {0xF9, 0xF5}, /* 0x4C-0x4F */
 	{0x6D, 0xAF}, {0x6D, 0xD1}, {0x6D, 0xAE}, {0x6D, 0xDE}, /* 0x50-0x53 */
 	{0x6D, 0xF9}, {0x6D, 0xB8}, {0x6D, 0xF7}, {0x6D, 0xF5}, /* 0x54-0x57 */
 	{0x6D, 0xC5}, {0x6D, 0xD2}, {0x6E, 0x1A}, {0x6D, 0xB5}, /* 0x58-0x5B */
-	{0x6D, 0xDA}, {0x6D, 0xEB}, {0x6D, 0xD8}, {0x6D, 0xEA}, /* 0x5C-0x5F */
+	{0xF9, 0x4D}, {0x6D, 0xEB}, {0x6D, 0xD8}, {0xF9, 0xD6}, /* 0x5C-0x5F */
 	{0x6D, 0xF1}, {0x6D, 0xEE}, {0x6D, 0xE8}, {0x6D, 0xC6}, /* 0x60-0x63 */
 	{0x6D, 0xC4}, {0x6D, 0xAA}, {0x6D, 0xEC}, {0x6D, 0xBF}, /* 0x64-0x67 */
 	{0x6D, 0xE6}, {0x70, 0xF9}, {0x71, 0x09}, {0x71, 0x0A}, /* 0x68-0x6B */
 	{0x70, 0xFD}, {0x70, 0xEF}, {0x72, 0x3D}, {0x72, 0x7D}, /* 0x6C-0x6F */
 	{0x72, 0x81}, {0x73, 0x1C}, {0x73, 0x1B}, {0x73, 0x16}, /* 0x70-0x73 */
-	{0x73, 0x13}, {0x73, 0x19}, {0x73, 0x87}, {0x74, 0x05}, /* 0x74-0x77 */
-	{0x74, 0x0A}, {0x74, 0x03}, {0x74, 0x06}, {0x73, 0xFE}, /* 0x78-0x7B */
+	{0x73, 0x13}, {0x73, 0x19}, {0xF9, 0xDB}, {0x74, 0x05}, /* 0x74-0x77 */
+	{0x74, 0x0A}, {0x74, 0x03}, {0xF9, 0xE4}, {0x73, 0xFE}, /* 0x78-0x7B */
 	{0x74, 0x0D}, {0x74, 0xE0}, {0x74, 0xF6}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
@@ -1210,22 +1212,22 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x74, 0xF7}, {0x75, 0x1C}, {0x75, 0x22}, /* 0xA0-0xA3 */
-	{0x75, 0x65}, {0x75, 0x66}, {0x75, 0x62}, {0x75, 0x70}, /* 0xA4-0xA7 */
+	{0xF9, 0x76}, {0x75, 0x66}, {0x75, 0x62}, {0xF9, 0x62}, /* 0xA4-0xA7 */
 	{0x75, 0x8F}, {0x75, 0xD4}, {0x75, 0xD5}, {0x75, 0xB5}, /* 0xA8-0xAB */
 	{0x75, 0xCA}, {0x75, 0xCD}, {0x76, 0x8E}, {0x76, 0xD4}, /* 0xAC-0xAF */
 	{0x76, 0xD2}, {0x76, 0xDB}, {0x77, 0x37}, {0x77, 0x3E}, /* 0xB0-0xB3 */
 	{0x77, 0x3C}, {0x77, 0x36}, {0x77, 0x38}, {0x77, 0x3A}, /* 0xB4-0xB7 */
-	{0x78, 0x6B}, {0x78, 0x43}, {0x78, 0x4E}, {0x79, 0x65}, /* 0xB8-0xBB */
+	{0xF9, 0xCE}, {0x78, 0x43}, {0x78, 0x4E}, {0xFA, 0x1A}, /* 0xB8-0xBB */
 	{0x79, 0x68}, {0x79, 0x6D}, {0x79, 0xFB}, {0x7A, 0x92}, /* 0xBC-0xBF */
-	{0x7A, 0x95}, {0x7B, 0x20}, {0x7B, 0x28}, {0x7B, 0x1B}, /* 0xC0-0xC3 */
+	{0x7A, 0x95}, {0xF9, 0xF8}, {0x7B, 0x28}, {0x7B, 0x1B}, /* 0xC0-0xC3 */
 	{0x7B, 0x2C}, {0x7B, 0x26}, {0x7B, 0x19}, {0x7B, 0x1E}, /* 0xC4-0xC7 */
-	{0x7B, 0x2E}, {0x7C, 0x92}, {0x7C, 0x97}, {0x7C, 0x95}, /* 0xC8-0xCB */
+	{0x7B, 0x2E}, {0xF9, 0xF9}, {0x7C, 0x97}, {0x7C, 0x95}, /* 0xC8-0xCB */
 	{0x7D, 0x46}, {0x7D, 0x43}, {0x7D, 0x71}, {0x7D, 0x2E}, /* 0xCC-0xCF */
 	{0x7D, 0x39}, {0x7D, 0x3C}, {0x7D, 0x40}, {0x7D, 0x30}, /* 0xD0-0xD3 */
-	{0x7D, 0x33}, {0x7D, 0x44}, {0x7D, 0x2F}, {0x7D, 0x42}, /* 0xD4-0xD7 */
+	{0x7D, 0x33}, {0x7D, 0x44}, {0xF9, 0x4F}, {0x7D, 0x42}, /* 0xD4-0xD7 */
 	{0x7D, 0x32}, {0x7D, 0x31}, {0x7F, 0x3D}, {0x7F, 0x9E}, /* 0xD8-0xDB */
-	{0x7F, 0x9A}, {0x7F, 0xCC}, {0x7F, 0xCE}, {0x7F, 0xD2}, /* 0xDC-0xDF */
-	{0x80, 0x1C}, {0x80, 0x4A}, {0x80, 0x46}, {0x81, 0x2F}, /* 0xE0-0xE3 */
+	{0xF9, 0xAF}, {0x7F, 0xCC}, {0x7F, 0xCE}, {0x7F, 0xD2}, /* 0xDC-0xDF */
+	{0x80, 0x1C}, {0x80, 0x4A}, {0xF9, 0xB0}, {0x81, 0x2F}, /* 0xE0-0xE3 */
 	{0x81, 0x16}, {0x81, 0x23}, {0x81, 0x2B}, {0x81, 0x29}, /* 0xE4-0xE7 */
 	{0x81, 0x30}, {0x81, 0x24}, {0x82, 0x02}, {0x82, 0x35}, /* 0xE8-0xEB */
 	{0x82, 0x37}, {0x82, 0x36}, {0x82, 0x39}, {0x83, 0x8E}, /* 0xEC-0xEF */
@@ -1264,7 +1266,7 @@
 	{0x8C, 0xAC}, {0x8C, 0xAB}, {0x8C, 0xA8}, {0x8C, 0xAA}, /* 0x64-0x67 */
 	{0x8C, 0xA7}, {0x8D, 0x67}, {0x8D, 0x66}, {0x8D, 0xBE}, /* 0x68-0x6B */
 	{0x8D, 0xBA}, {0x8E, 0xDB}, {0x8E, 0xDF}, {0x90, 0x19}, /* 0x6C-0x6F */
-	{0x90, 0x0D}, {0x90, 0x1A}, {0x90, 0x17}, {0x90, 0x23}, /* 0x70-0x73 */
+	{0x90, 0x0D}, {0x90, 0x1A}, {0x90, 0x17}, {0xF9, 0x9A}, /* 0x70-0x73 */
 	{0x90, 0x1F}, {0x90, 0x1D}, {0x90, 0x10}, {0x90, 0x15}, /* 0x74-0x77 */
 	{0x90, 0x1E}, {0x90, 0x20}, {0x90, 0x0F}, {0x90, 0x22}, /* 0x78-0x7B */
 	{0x90, 0x16}, {0x90, 0x1B}, {0x90, 0x14}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -1277,23 +1279,23 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x94-0x97 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
-	{0x00, 0x3F}, {0x90, 0xE8}, {0x90, 0xED}, {0x90, 0xFD}, /* 0xA0-0xA3 */
+	{0x00, 0x3F}, {0x90, 0xE8}, {0x90, 0xED}, {0xFA, 0x26}, /* 0xA0-0xA3 */
 	{0x91, 0x57}, {0x91, 0xCE}, {0x91, 0xF5}, {0x91, 0xE6}, /* 0xA4-0xA7 */
 	{0x91, 0xE3}, {0x91, 0xE7}, {0x91, 0xED}, {0x91, 0xE9}, /* 0xA8-0xAB */
-	{0x95, 0x89}, {0x96, 0x6A}, {0x96, 0x75}, {0x96, 0x73}, /* 0xAC-0xAF */
-	{0x96, 0x78}, {0x96, 0x70}, {0x96, 0x74}, {0x96, 0x76}, /* 0xB0-0xB3 */
+	{0x95, 0x89}, {0x96, 0x6A}, {0xF9, 0x59}, {0x96, 0x73}, /* 0xAC-0xAF */
+	{0xF9, 0xD3}, {0x96, 0x70}, {0x96, 0x74}, {0x96, 0x76}, /* 0xB0-0xB3 */
 	{0x96, 0x77}, {0x96, 0x6C}, {0x96, 0xC0}, {0x96, 0xEA}, /* 0xB4-0xB7 */
 	{0x96, 0xE9}, {0x7A, 0xE0}, {0x7A, 0xDF}, {0x98, 0x02}, /* 0xB8-0xBB */
 	{0x98, 0x03}, {0x9B, 0x5A}, {0x9C, 0xE5}, {0x9E, 0x75}, /* 0xBC-0xBF */
-	{0x9E, 0x7F}, {0x9E, 0xA5}, {0x9E, 0xBB}, {0x50, 0xA2}, /* 0xC0-0xC3 */
+	{0xF9, 0x40}, {0x9E, 0xA5}, {0x9E, 0xBB}, {0x50, 0xA2}, /* 0xC0-0xC3 */
 	{0x50, 0x8D}, {0x50, 0x85}, {0x50, 0x99}, {0x50, 0x91}, /* 0xC4-0xC7 */
 	{0x50, 0x80}, {0x50, 0x96}, {0x50, 0x98}, {0x50, 0x9A}, /* 0xC8-0xCB */
 	{0x67, 0x00}, {0x51, 0xF1}, {0x52, 0x72}, {0x52, 0x74}, /* 0xCC-0xCF */
-	{0x52, 0x75}, {0x52, 0x69}, {0x52, 0xDE}, {0x52, 0xDD}, /* 0xD0-0xD3 */
+	{0x52, 0x75}, {0x52, 0x69}, {0xF9, 0x2F}, {0x52, 0xDD}, /* 0xD0-0xD3 */
 	{0x52, 0xDB}, {0x53, 0x5A}, {0x53, 0xA5}, {0x55, 0x7B}, /* 0xD4-0xD7 */
 	{0x55, 0x80}, {0x55, 0xA7}, {0x55, 0x7C}, {0x55, 0x8A}, /* 0xD8-0xDB */
 	{0x55, 0x9D}, {0x55, 0x98}, {0x55, 0x82}, {0x55, 0x9C}, /* 0xDC-0xDF */
-	{0x55, 0xAA}, {0x55, 0x94}, {0x55, 0x87}, {0x55, 0x8B}, /* 0xE0-0xE3 */
+	{0x55, 0xAA}, {0x55, 0x94}, {0xF9, 0x0B}, {0x55, 0x8B}, /* 0xE0-0xE3 */
 	{0x55, 0x83}, {0x55, 0xB3}, {0x55, 0xAE}, {0x55, 0x9F}, /* 0xE4-0xE7 */
 	{0x55, 0x3E}, {0x55, 0xB2}, {0x55, 0x9A}, {0x55, 0xBB}, /* 0xE8-0xEB */
 	{0x55, 0xAC}, {0x55, 0xB1}, {0x55, 0x7E}, {0x55, 0x89}, /* 0xEC-0xEF */
@@ -1324,11 +1326,11 @@
 	{0x5A, 0x9B}, {0x5A, 0xA7}, {0x5B, 0x73}, {0x5B, 0x71}, /* 0x44-0x47 */
 	{0x5B, 0xD2}, {0x5B, 0xCC}, {0x5B, 0xD3}, {0x5B, 0xD0}, /* 0x48-0x4B */
 	{0x5C, 0x0A}, {0x5C, 0x0B}, {0x5C, 0x31}, {0x5D, 0x4C}, /* 0x4C-0x4F */
-	{0x5D, 0x50}, {0x5D, 0x34}, {0x5D, 0x47}, {0x5D, 0xFD}, /* 0x50-0x53 */
+	{0xF9, 0x21}, {0x5D, 0x34}, {0x5D, 0x47}, {0x5D, 0xFD}, /* 0x50-0x53 */
 	{0x5E, 0x45}, {0x5E, 0x3D}, {0x5E, 0x40}, {0x5E, 0x43}, /* 0x54-0x57 */
-	{0x5E, 0x7E}, {0x5E, 0xCA}, {0x5E, 0xC1}, {0x5E, 0xC2}, /* 0x58-0x5B */
-	{0x5E, 0xC4}, {0x5F, 0x3C}, {0x5F, 0x6D}, {0x5F, 0xA9}, /* 0x5C-0x5F */
-	{0x5F, 0xAA}, {0x5F, 0xA8}, {0x60, 0xD1}, {0x60, 0xE1}, /* 0x60-0x63 */
+	{0x5E, 0x7E}, {0xF9, 0x28}, {0x5E, 0xC1}, {0x5E, 0xC2}, /* 0x58-0x5B */
+	{0x5E, 0xC4}, {0x5F, 0x3C}, {0x5F, 0x6D}, {0xF9, 0x66}, /* 0x5C-0x5F */
+	{0x5F, 0xAA}, {0x5F, 0xA8}, {0x60, 0xD1}, {0xF9, 0xB9}, /* 0x60-0x63 */
 	{0x60, 0xB2}, {0x60, 0xB6}, {0x60, 0xE0}, {0x61, 0x1C}, /* 0x64-0x67 */
 	{0x61, 0x23}, {0x60, 0xFA}, {0x61, 0x15}, {0x60, 0xF0}, /* 0x68-0x6B */
 	{0x60, 0xFB}, {0x60, 0xF4}, {0x61, 0x68}, {0x60, 0xF1}, /* 0x6C-0x6F */
@@ -1351,7 +1353,7 @@
 	{0x64, 0x52}, {0x63, 0xDA}, {0x63, 0xF9}, {0x65, 0x5E}, /* 0xAC-0xAF */
 	{0x65, 0x66}, {0x65, 0x62}, {0x65, 0x63}, {0x65, 0x91}, /* 0xB0-0xB3 */
 	{0x65, 0x90}, {0x65, 0xAF}, {0x66, 0x6E}, {0x66, 0x70}, /* 0xB4-0xB7 */
-	{0x66, 0x74}, {0x66, 0x76}, {0x66, 0x6F}, {0x66, 0x91}, /* 0xB8-0xBB */
+	{0xFA, 0x12}, {0x66, 0x76}, {0x66, 0x6F}, {0x66, 0x91}, /* 0xB8-0xBB */
 	{0x66, 0x7A}, {0x66, 0x7E}, {0x66, 0x77}, {0x66, 0xFE}, /* 0xBC-0xBF */
 	{0x66, 0xFF}, {0x67, 0x1F}, {0x67, 0x1D}, {0x68, 0xFA}, /* 0xC0-0xC3 */
 	{0x68, 0xD5}, {0x68, 0xE0}, {0x68, 0xD8}, {0x68, 0xD7}, /* 0xC4-0xC7 */
@@ -1397,7 +1399,7 @@
 	{0x74, 0x2A}, {0x74, 0x33}, {0x74, 0x22}, {0x74, 0x25}, /* 0x58-0x5B */
 	{0x74, 0x35}, {0x74, 0x36}, {0x74, 0x34}, {0x74, 0x2F}, /* 0x5C-0x5F */
 	{0x74, 0x1B}, {0x74, 0x26}, {0x74, 0x28}, {0x75, 0x25}, /* 0x60-0x63 */
-	{0x75, 0x26}, {0x75, 0x6B}, {0x75, 0x6A}, {0x75, 0xE2}, /* 0x64-0x67 */
+	{0x75, 0x26}, {0x75, 0x6B}, {0x75, 0x6A}, {0xF9, 0xE5}, /* 0x64-0x67 */
 	{0x75, 0xDB}, {0x75, 0xE3}, {0x75, 0xD9}, {0x75, 0xD8}, /* 0x68-0x6B */
 	{0x75, 0xDE}, {0x75, 0xE0}, {0x76, 0x7B}, {0x76, 0x7C}, /* 0x6C-0x6F */
 	{0x76, 0x96}, {0x76, 0x93}, {0x76, 0xB4}, {0x76, 0xDC}, /* 0x70-0x73 */
@@ -1427,14 +1429,14 @@
 	{0x81, 0x53}, {0x81, 0x74}, {0x82, 0x12}, {0x82, 0x1C}, /* 0xCC-0xCF */
 	{0x83, 0xE9}, {0x84, 0x03}, {0x83, 0xF8}, {0x84, 0x0D}, /* 0xD0-0xD3 */
 	{0x83, 0xE0}, {0x83, 0xC5}, {0x84, 0x0B}, {0x83, 0xC1}, /* 0xD4-0xD7 */
-	{0x83, 0xEF}, {0x83, 0xF1}, {0x83, 0xF4}, {0x84, 0x57}, /* 0xD8-0xDB */
+	{0x83, 0xEF}, {0xF9, 0x58}, {0x83, 0xF4}, {0x84, 0x57}, /* 0xD8-0xDB */
 	{0x84, 0x0A}, {0x83, 0xF0}, {0x84, 0x0C}, {0x83, 0xCC}, /* 0xDC-0xDF */
 	{0x83, 0xFD}, {0x83, 0xF2}, {0x83, 0xCA}, {0x84, 0x38}, /* 0xE0-0xE3 */
 	{0x84, 0x0E}, {0x84, 0x04}, {0x83, 0xDC}, {0x84, 0x07}, /* 0xE4-0xE7 */
 	{0x83, 0xD4}, {0x83, 0xDF}, {0x86, 0x5B}, {0x86, 0xDF}, /* 0xE8-0xEB */
 	{0x86, 0xD9}, {0x86, 0xED}, {0x86, 0xD4}, {0x86, 0xDB}, /* 0xEC-0xEF */
 	{0x86, 0xE4}, {0x86, 0xD0}, {0x86, 0xDE}, {0x88, 0x57}, /* 0xF0-0xF3 */
-	{0x88, 0xC1}, {0x88, 0xC2}, {0x88, 0xB1}, {0x89, 0x83}, /* 0xF4-0xF7 */
+	{0x88, 0xC1}, {0xF9, 0xA0}, {0x88, 0xB1}, {0x89, 0x83}, /* 0xF4-0xF7 */
 	{0x89, 0x96}, {0x8A, 0x3B}, {0x8A, 0x60}, {0x8A, 0x55}, /* 0xF8-0xFB */
 	{0x8A, 0x5E}, {0x8A, 0x3C}, {0x8A, 0x41}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -1466,9 +1468,9 @@
 	{0x8D, 0xDA}, {0x8D, 0xD1}, {0x8D, 0xCC}, {0x8D, 0xDB}, /* 0x5C-0x5F */
 	{0x8D, 0xC6}, {0x8E, 0xFB}, {0x8E, 0xF8}, {0x8E, 0xFC}, /* 0x60-0x63 */
 	{0x8F, 0x9C}, {0x90, 0x2E}, {0x90, 0x35}, {0x90, 0x31}, /* 0x64-0x67 */
-	{0x90, 0x38}, {0x90, 0x32}, {0x90, 0x36}, {0x91, 0x02}, /* 0x68-0x6B */
+	{0xFA, 0x25}, {0x90, 0x32}, {0x90, 0x36}, {0x91, 0x02}, /* 0x68-0x6B */
 	{0x90, 0xF5}, {0x91, 0x09}, {0x90, 0xFE}, {0x91, 0x63}, /* 0x6C-0x6F */
-	{0x91, 0x65}, {0x91, 0xCF}, {0x92, 0x14}, {0x92, 0x15}, /* 0x70-0x73 */
+	{0x91, 0x65}, {0xF9, 0x7E}, {0x92, 0x14}, {0x92, 0x15}, /* 0x70-0x73 */
 	{0x92, 0x23}, {0x92, 0x09}, {0x92, 0x1E}, {0x92, 0x0D}, /* 0x74-0x77 */
 	{0x92, 0x10}, {0x92, 0x07}, {0x92, 0x11}, {0x95, 0x94}, /* 0x78-0x7B */
 	{0x95, 0x8F}, {0x95, 0x8B}, {0x95, 0x91}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -1483,13 +1485,13 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x95, 0x93}, {0x95, 0x92}, {0x95, 0x8E}, /* 0xA0-0xA3 */
 	{0x96, 0x8A}, {0x96, 0x8E}, {0x96, 0x8B}, {0x96, 0x7D}, /* 0xA4-0xA7 */
-	{0x96, 0x85}, {0x96, 0x86}, {0x96, 0x8D}, {0x96, 0x72}, /* 0xA8-0xAB */
+	{0x96, 0x85}, {0xF9, 0xDC}, {0x96, 0x8D}, {0x96, 0x72}, /* 0xA8-0xAB */
 	{0x96, 0x84}, {0x96, 0xC1}, {0x96, 0xC5}, {0x96, 0xC4}, /* 0xAC-0xAF */
 	{0x96, 0xC6}, {0x96, 0xC7}, {0x96, 0xEF}, {0x96, 0xF2}, /* 0xB0-0xB3 */
 	{0x97, 0xCC}, {0x98, 0x05}, {0x98, 0x06}, {0x98, 0x08}, /* 0xB4-0xB7 */
-	{0x98, 0xE7}, {0x98, 0xEA}, {0x98, 0xEF}, {0x98, 0xE9}, /* 0xB8-0xBB */
+	{0x98, 0xE7}, {0x98, 0xEA}, {0xFA, 0x2A}, {0x98, 0xE9}, /* 0xB8-0xBB */
 	{0x98, 0xF2}, {0x98, 0xED}, {0x99, 0xAE}, {0x99, 0xAD}, /* 0xBC-0xBF */
-	{0x9E, 0xC3}, {0x9E, 0xCD}, {0x9E, 0xD1}, {0x4E, 0x82}, /* 0xC0-0xC3 */
+	{0x9E, 0xC3}, {0x9E, 0xCD}, {0x9E, 0xD1}, {0xF9, 0x1B}, /* 0xC0-0xC3 */
 	{0x50, 0xAD}, {0x50, 0xB5}, {0x50, 0xB2}, {0x50, 0xB3}, /* 0xC4-0xC7 */
 	{0x50, 0xC5}, {0x50, 0xBE}, {0x50, 0xAC}, {0x50, 0xB7}, /* 0xC8-0xCB */
 	{0x50, 0xBB}, {0x50, 0xAF}, {0x50, 0xC7}, {0x52, 0x7F}, /* 0xCC-0xCF */
@@ -1499,8 +1501,8 @@
 	{0x55, 0xCE}, {0x55, 0xDC}, {0x55, 0xC7}, {0x55, 0xD1}, /* 0xDC-0xDF */
 	{0x55, 0xE3}, {0x55, 0xE4}, {0x55, 0xEF}, {0x55, 0xDA}, /* 0xE0-0xE3 */
 	{0x55, 0xE1}, {0x55, 0xC5}, {0x55, 0xC6}, {0x55, 0xE5}, /* 0xE4-0xE7 */
-	{0x55, 0xC9}, {0x57, 0x12}, {0x57, 0x13}, {0x58, 0x5E}, /* 0xE8-0xEB */
-	{0x58, 0x51}, {0x58, 0x58}, {0x58, 0x57}, {0x58, 0x5A}, /* 0xEC-0xEF */
+	{0x55, 0xC9}, {0x57, 0x12}, {0x57, 0x13}, {0xF9, 0x6C}, /* 0xE8-0xEB */
+	{0x58, 0x51}, {0x58, 0x58}, {0x58, 0x57}, {0xFA, 0x10}, /* 0xEC-0xEF */
 	{0x58, 0x54}, {0x58, 0x6B}, {0x58, 0x4C}, {0x58, 0x6D}, /* 0xF0-0xF3 */
 	{0x58, 0x4A}, {0x58, 0x62}, {0x58, 0x52}, {0x58, 0x4B}, /* 0xF4-0xF7 */
 	{0x59, 0x67}, {0x5A, 0xC1}, {0x5A, 0xC9}, {0x5A, 0xCC}, /* 0xF8-0xFB */
@@ -1525,19 +1527,19 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x5A, 0xB3}, {0x5A, 0xC2}, {0x5A, 0xB2}, {0x5D, 0x69}, /* 0x40-0x43 */
-	{0x5D, 0x6F}, {0x5E, 0x4C}, {0x5E, 0x79}, {0x5E, 0xC9}, /* 0x44-0x47 */
+	{0x5D, 0x6F}, {0x5E, 0x4C}, {0x5E, 0x79}, {0xF9, 0xA2}, /* 0x44-0x47 */
 	{0x5E, 0xC8}, {0x5F, 0x12}, {0x5F, 0x59}, {0x5F, 0xAC}, /* 0x48-0x4B */
 	{0x5F, 0xAE}, {0x61, 0x1A}, {0x61, 0x0F}, {0x61, 0x48}, /* 0x4C-0x4F */
 	{0x61, 0x1F}, {0x60, 0xF3}, {0x61, 0x1B}, {0x60, 0xF9}, /* 0x50-0x53 */
 	{0x61, 0x01}, {0x61, 0x08}, {0x61, 0x4E}, {0x61, 0x4C}, /* 0x54-0x57 */
-	{0x61, 0x44}, {0x61, 0x4D}, {0x61, 0x3E}, {0x61, 0x34}, /* 0x58-0x5B */
+	{0xF9, 0xD9}, {0x61, 0x4D}, {0x61, 0x3E}, {0x61, 0x34}, /* 0x58-0x5B */
 	{0x61, 0x27}, {0x61, 0x0D}, {0x61, 0x06}, {0x61, 0x37}, /* 0x5C-0x5F */
 	{0x62, 0x21}, {0x62, 0x22}, {0x64, 0x13}, {0x64, 0x3E}, /* 0x60-0x63 */
 	{0x64, 0x1E}, {0x64, 0x2A}, {0x64, 0x2D}, {0x64, 0x3D}, /* 0x64-0x67 */
 	{0x64, 0x2C}, {0x64, 0x0F}, {0x64, 0x1C}, {0x64, 0x14}, /* 0x68-0x6B */
 	{0x64, 0x0D}, {0x64, 0x36}, {0x64, 0x16}, {0x64, 0x17}, /* 0x6C-0x6F */
 	{0x64, 0x06}, {0x65, 0x6C}, {0x65, 0x9F}, {0x65, 0xB0}, /* 0x70-0x73 */
-	{0x66, 0x97}, {0x66, 0x89}, {0x66, 0x87}, {0x66, 0x88}, /* 0x74-0x77 */
+	{0x66, 0x97}, {0x66, 0x89}, {0x66, 0x87}, {0xF9, 0xC5}, /* 0x74-0x77 */
 	{0x66, 0x96}, {0x66, 0x84}, {0x66, 0x98}, {0x66, 0x8D}, /* 0x78-0x7B */
 	{0x67, 0x03}, {0x69, 0x94}, {0x69, 0x6D}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
@@ -1558,10 +1560,10 @@
 	{0x6E, 0xA2}, {0x6E, 0xAF}, {0x6E, 0xD3}, {0x6E, 0xB6}, /* 0xB8-0xBB */
 	{0x6E, 0xC2}, {0x6E, 0x90}, {0x6E, 0x9D}, {0x6E, 0xC7}, /* 0xBC-0xBF */
 	{0x6E, 0xC5}, {0x6E, 0xA5}, {0x6E, 0x98}, {0x6E, 0xBC}, /* 0xC0-0xC3 */
-	{0x6E, 0xBA}, {0x6E, 0xAB}, {0x6E, 0xD1}, {0x6E, 0x96}, /* 0xC4-0xC7 */
-	{0x6E, 0x9C}, {0x6E, 0xC4}, {0x6E, 0xD4}, {0x6E, 0xAA}, /* 0xC8-0xCB */
+	{0xF9, 0xEC}, {0x6E, 0xAB}, {0xF9, 0x04}, {0x6E, 0x96}, /* 0xC4-0xC7 */
+	{0xF9, 0xCB}, {0x6E, 0xC4}, {0x6E, 0xD4}, {0x6E, 0xAA}, /* 0xC8-0xCB */
 	{0x6E, 0xA7}, {0x6E, 0xB4}, {0x71, 0x4E}, {0x71, 0x59}, /* 0xCC-0xCF */
-	{0x71, 0x69}, {0x71, 0x64}, {0x71, 0x49}, {0x71, 0x67}, /* 0xD0-0xD3 */
+	{0x71, 0x69}, {0x71, 0x64}, {0xF9, 0x93}, {0x71, 0x67}, /* 0xD0-0xD3 */
 	{0x71, 0x5C}, {0x71, 0x6C}, {0x71, 0x66}, {0x71, 0x4C}, /* 0xD4-0xD7 */
 	{0x71, 0x65}, {0x71, 0x5E}, {0x71, 0x46}, {0x71, 0x68}, /* 0xD8-0xDB */
 	{0x71, 0x56}, {0x72, 0x3A}, {0x72, 0x52}, {0x73, 0x37}, /* 0xDC-0xDF */
@@ -1595,9 +1597,9 @@
 	{0x77, 0x79}, {0x77, 0x6A}, {0x77, 0x6C}, {0x77, 0x5C}, /* 0x40-0x43 */
 	{0x77, 0x65}, {0x77, 0x68}, {0x77, 0x62}, {0x77, 0xEE}, /* 0x44-0x47 */
 	{0x78, 0x8E}, {0x78, 0xB0}, {0x78, 0x97}, {0x78, 0x98}, /* 0x48-0x4B */
-	{0x78, 0x8C}, {0x78, 0x89}, {0x78, 0x7C}, {0x78, 0x91}, /* 0x4C-0x4F */
-	{0x78, 0x93}, {0x78, 0x7F}, {0x79, 0x7A}, {0x79, 0x7F}, /* 0x50-0x53 */
-	{0x79, 0x81}, {0x84, 0x2C}, {0x79, 0xBD}, {0x7A, 0x1C}, /* 0x54-0x57 */
+	{0xF9, 0x3B}, {0x78, 0x89}, {0x78, 0x7C}, {0x78, 0x91}, /* 0x4C-0x4F */
+	{0x78, 0x93}, {0x78, 0x7F}, {0x79, 0x7A}, {0xF9, 0x3C}, /* 0x50-0x53 */
+	{0x79, 0x81}, {0x84, 0x2C}, {0x79, 0xBD}, {0xF9, 0x56}, /* 0x54-0x57 */
 	{0x7A, 0x1A}, {0x7A, 0x20}, {0x7A, 0x14}, {0x7A, 0x1F}, /* 0x58-0x5B */
 	{0x7A, 0x1E}, {0x7A, 0x9F}, {0x7A, 0xA0}, {0x7B, 0x77}, /* 0x5C-0x5F */
 	{0x7B, 0xC0}, {0x7B, 0x60}, {0x7B, 0x6E}, {0x7B, 0x67}, /* 0x60-0x63 */
@@ -1619,26 +1621,26 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x81, 0x79}, {0x81, 0x7A}, {0x81, 0x66}, /* 0xA0-0xA3 */
 	{0x82, 0x05}, {0x82, 0x47}, {0x84, 0x82}, {0x84, 0x77}, /* 0xA4-0xA7 */
-	{0x84, 0x3D}, {0x84, 0x31}, {0x84, 0x75}, {0x84, 0x66}, /* 0xA8-0xAB */
-	{0x84, 0x6B}, {0x84, 0x49}, {0x84, 0x6C}, {0x84, 0x5B}, /* 0xAC-0xAF */
+	{0xF9, 0x18}, {0x84, 0x31}, {0x84, 0x75}, {0x84, 0x66}, /* 0xA8-0xAB */
+	{0x84, 0x6B}, {0xF9, 0x6E}, {0x84, 0x6C}, {0x84, 0x5B}, /* 0xAC-0xAF */
 	{0x84, 0x3C}, {0x84, 0x35}, {0x84, 0x61}, {0x84, 0x63}, /* 0xB0-0xB3 */
 	{0x84, 0x69}, {0x84, 0x6D}, {0x84, 0x46}, {0x86, 0x5E}, /* 0xB4-0xB7 */
-	{0x86, 0x5C}, {0x86, 0x5F}, {0x86, 0xF9}, {0x87, 0x13}, /* 0xB8-0xBB */
+	{0xF9, 0x36}, {0x86, 0x5F}, {0x86, 0xF9}, {0x87, 0x13}, /* 0xB8-0xBB */
 	{0x87, 0x08}, {0x87, 0x07}, {0x87, 0x00}, {0x86, 0xFE}, /* 0xBC-0xBF */
 	{0x86, 0xFB}, {0x87, 0x02}, {0x87, 0x03}, {0x87, 0x06}, /* 0xC0-0xC3 */
 	{0x87, 0x0A}, {0x88, 0x59}, {0x88, 0xDF}, {0x88, 0xD4}, /* 0xC4-0xC7 */
 	{0x88, 0xD9}, {0x88, 0xDC}, {0x88, 0xD8}, {0x88, 0xDD}, /* 0xC8-0xCB */
-	{0x88, 0xE1}, {0x88, 0xCA}, {0x88, 0xD5}, {0x88, 0xD2}, /* 0xCC-0xCF */
+	{0xF9, 0xE8}, {0x88, 0xCA}, {0x88, 0xD5}, {0x88, 0xD2}, /* 0xCC-0xCF */
 	{0x89, 0x9C}, {0x89, 0xE3}, {0x8A, 0x6B}, {0x8A, 0x72}, /* 0xD0-0xD3 */
 	{0x8A, 0x73}, {0x8A, 0x66}, {0x8A, 0x69}, {0x8A, 0x70}, /* 0xD4-0xD7 */
 	{0x8A, 0x87}, {0x8A, 0x7C}, {0x8A, 0x63}, {0x8A, 0xA0}, /* 0xD8-0xDB */
 	{0x8A, 0x71}, {0x8A, 0x85}, {0x8A, 0x6D}, {0x8A, 0x62}, /* 0xDC-0xDF */
 	{0x8A, 0x6E}, {0x8A, 0x6C}, {0x8A, 0x79}, {0x8A, 0x7B}, /* 0xE0-0xE3 */
 	{0x8A, 0x3E}, {0x8A, 0x68}, {0x8C, 0x62}, {0x8C, 0x8A}, /* 0xE4-0xE7 */
-	{0x8C, 0x89}, {0x8C, 0xCA}, {0x8C, 0xC7}, {0x8C, 0xC8}, /* 0xE8-0xEB */
-	{0x8C, 0xC4}, {0x8C, 0xB2}, {0x8C, 0xC3}, {0x8C, 0xC2}, /* 0xEC-0xEF */
+	{0x8C, 0x89}, {0x8C, 0xCA}, {0x8C, 0xC7}, {0xF9, 0x03}, /* 0xE8-0xEB */
+	{0x8C, 0xC4}, {0x8C, 0xB2}, {0x8C, 0xC3}, {0xF9, 0x48}, /* 0xEC-0xEF */
 	{0x8C, 0xC5}, {0x8D, 0xE1}, {0x8D, 0xDF}, {0x8D, 0xE8}, /* 0xF0-0xF3 */
-	{0x8D, 0xEF}, {0x8D, 0xF3}, {0x8D, 0xFA}, {0x8D, 0xEA}, /* 0xF4-0xF7 */
+	{0xF9, 0x37}, {0x8D, 0xF3}, {0x8D, 0xFA}, {0x8D, 0xEA}, /* 0xF4-0xF7 */
 	{0x8D, 0xE4}, {0x8D, 0xE6}, {0x8E, 0xB2}, {0x8F, 0x03}, /* 0xF8-0xFB */
 	{0x8F, 0x09}, {0x8E, 0xFE}, {0x8F, 0x0A}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -1665,17 +1667,17 @@
 	{0x90, 0x55}, {0x90, 0x50}, {0x90, 0x47}, {0x90, 0x4F}, /* 0x48-0x4B */
 	{0x90, 0x4E}, {0x90, 0x4D}, {0x90, 0x51}, {0x90, 0x3E}, /* 0x4C-0x4F */
 	{0x90, 0x41}, {0x91, 0x12}, {0x91, 0x17}, {0x91, 0x6C}, /* 0x50-0x53 */
-	{0x91, 0x6A}, {0x91, 0x69}, {0x91, 0xC9}, {0x92, 0x37}, /* 0x54-0x57 */
+	{0xF9, 0x19}, {0x91, 0x69}, {0x91, 0xC9}, {0x92, 0x37}, /* 0x54-0x57 */
 	{0x92, 0x57}, {0x92, 0x38}, {0x92, 0x3D}, {0x92, 0x40}, /* 0x58-0x5B */
 	{0x92, 0x3E}, {0x92, 0x5B}, {0x92, 0x4B}, {0x92, 0x64}, /* 0x5C-0x5F */
-	{0x92, 0x51}, {0x92, 0x34}, {0x92, 0x49}, {0x92, 0x4D}, /* 0x60-0x63 */
+	{0x92, 0x51}, {0xF9, 0xB1}, {0x92, 0x49}, {0x92, 0x4D}, /* 0x60-0x63 */
 	{0x92, 0x45}, {0x92, 0x39}, {0x92, 0x3F}, {0x92, 0x5A}, /* 0x64-0x67 */
 	{0x95, 0x98}, {0x96, 0x98}, {0x96, 0x94}, {0x96, 0x95}, /* 0x68-0x6B */
 	{0x96, 0xCD}, {0x96, 0xCB}, {0x96, 0xC9}, {0x96, 0xCA}, /* 0x6C-0x6F */
-	{0x96, 0xF7}, {0x96, 0xFB}, {0x96, 0xF9}, {0x96, 0xF6}, /* 0x70-0x73 */
-	{0x97, 0x56}, {0x97, 0x74}, {0x97, 0x76}, {0x98, 0x10}, /* 0x74-0x77 */
+	{0xF9, 0x49}, {0x96, 0xFB}, {0x96, 0xF9}, {0xF9, 0xB2}, /* 0x70-0x73 */
+	{0xFA, 0x1C}, {0x97, 0x74}, {0x97, 0x76}, {0x98, 0x10}, /* 0x74-0x77 */
 	{0x98, 0x11}, {0x98, 0x13}, {0x98, 0x0A}, {0x98, 0x12}, /* 0x78-0x7B */
-	{0x98, 0x0C}, {0x98, 0xFC}, {0x98, 0xF4}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x98, 0x0C}, {0xFA, 0x2B}, {0x98, 0xF4}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -1689,7 +1691,7 @@
 	{0x99, 0xB1}, {0x99, 0xB4}, {0x9A, 0xE1}, {0x9C, 0xE9}, /* 0xA4-0xA7 */
 	{0x9E, 0x82}, {0x9F, 0x0E}, {0x9F, 0x13}, {0x9F, 0x20}, /* 0xA8-0xAB */
 	{0x50, 0xE7}, {0x50, 0xEE}, {0x50, 0xE5}, {0x50, 0xD6}, /* 0xAC-0xAF */
-	{0x50, 0xED}, {0x50, 0xDA}, {0x50, 0xD5}, {0x50, 0xCF}, /* 0xB0-0xB3 */
+	{0x50, 0xED}, {0xF9, 0xBB}, {0x50, 0xD5}, {0x50, 0xCF}, /* 0xB0-0xB3 */
 	{0x50, 0xD1}, {0x50, 0xF1}, {0x50, 0xCE}, {0x50, 0xE9}, /* 0xB4-0xB7 */
 	{0x51, 0x62}, {0x51, 0xF3}, {0x52, 0x83}, {0x52, 0x82}, /* 0xB8-0xBB */
 	{0x53, 0x31}, {0x53, 0xAD}, {0x55, 0xFE}, {0x56, 0x00}, /* 0xBC-0xBF */
@@ -1702,12 +1704,12 @@
 	{0x58, 0xFD}, {0x59, 0x25}, {0x59, 0x22}, {0x59, 0x24}, /* 0xD8-0xDB */
 	{0x59, 0x6A}, {0x59, 0x69}, {0x5A, 0xE1}, {0x5A, 0xE6}, /* 0xDC-0xDF */
 	{0x5A, 0xE9}, {0x5A, 0xD7}, {0x5A, 0xD6}, {0x5A, 0xD8}, /* 0xE0-0xE3 */
-	{0x5A, 0xE3}, {0x5B, 0x75}, {0x5B, 0xDE}, {0x5B, 0xE7}, /* 0xE4-0xE7 */
+	{0x5A, 0xE3}, {0x5B, 0x75}, {0x5B, 0xDE}, {0xF9, 0xAA}, /* 0xE4-0xE7 */
 	{0x5B, 0xE1}, {0x5B, 0xE5}, {0x5B, 0xE6}, {0x5B, 0xE8}, /* 0xE8-0xEB */
 	{0x5B, 0xE2}, {0x5B, 0xE4}, {0x5B, 0xDF}, {0x5C, 0x0D}, /* 0xEC-0xEF */
-	{0x5C, 0x62}, {0x5D, 0x84}, {0x5D, 0x87}, {0x5E, 0x5B}, /* 0xF0-0xF3 */
+	{0xF9, 0x4B}, {0x5D, 0x84}, {0x5D, 0x87}, {0x5E, 0x5B}, /* 0xF0-0xF3 */
 	{0x5E, 0x63}, {0x5E, 0x55}, {0x5E, 0x57}, {0x5E, 0x54}, /* 0xF4-0xF7 */
-	{0x5E, 0xD3}, {0x5E, 0xD6}, {0x5F, 0x0A}, {0x5F, 0x46}, /* 0xF8-0xFB */
+	{0xFA, 0x0B}, {0x5E, 0xD6}, {0x5F, 0x0A}, {0x5F, 0x46}, /* 0xF8-0xFB */
 	{0x5F, 0x70}, {0x5F, 0xB9}, {0x61, 0x47}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -1743,7 +1745,7 @@
 	{0x6B, 0x49}, {0x6B, 0x4C}, {0x6C, 0x33}, {0x6F, 0x33}, /* 0x70-0x73 */
 	{0x6F, 0x14}, {0x6E, 0xFE}, {0x6F, 0x13}, {0x6E, 0xF4}, /* 0x74-0x77 */
 	{0x6F, 0x29}, {0x6F, 0x3E}, {0x6F, 0x20}, {0x6F, 0x2C}, /* 0x78-0x7B */
-	{0x6F, 0x0F}, {0x6F, 0x02}, {0x6F, 0x22}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0xF9, 0x4E}, {0x6F, 0x02}, {0x6F, 0x22}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -1754,7 +1756,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x6E, 0xFF}, {0x6E, 0xEF}, {0x6F, 0x06}, /* 0xA0-0xA3 */
-	{0x6F, 0x31}, {0x6F, 0x38}, {0x6F, 0x32}, {0x6F, 0x23}, /* 0xA4-0xA7 */
+	{0x6F, 0x31}, {0x6F, 0x38}, {0x6F, 0x32}, {0xF9, 0x92}, /* 0xA4-0xA7 */
 	{0x6F, 0x15}, {0x6F, 0x2B}, {0x6F, 0x2F}, {0x6F, 0x88}, /* 0xA8-0xAB */
 	{0x6F, 0x2A}, {0x6E, 0xEC}, {0x6F, 0x01}, {0x6E, 0xF2}, /* 0xAC-0xAF */
 	{0x6E, 0xCC}, {0x6E, 0xF7}, {0x71, 0x94}, {0x71, 0x99}, /* 0xB0-0xB3 */
@@ -1766,14 +1768,14 @@
 	{0x76, 0x13}, {0x76, 0xE1}, {0x76, 0xE3}, {0x77, 0x84}, /* 0xC8-0xCB */
 	{0x77, 0x7D}, {0x77, 0x7F}, {0x77, 0x61}, {0x78, 0xC1}, /* 0xCC-0xCF */
 	{0x78, 0x9F}, {0x78, 0xA7}, {0x78, 0xB3}, {0x78, 0xA9}, /* 0xD0-0xD3 */
-	{0x78, 0xA3}, {0x79, 0x8E}, {0x79, 0x8F}, {0x79, 0x8D}, /* 0xD4-0xD7 */
+	{0x78, 0xA3}, {0x79, 0x8E}, {0xFA, 0x1B}, {0x79, 0x8D}, /* 0xD4-0xD7 */
 	{0x7A, 0x2E}, {0x7A, 0x31}, {0x7A, 0xAA}, {0x7A, 0xA9}, /* 0xD8-0xDB */
 	{0x7A, 0xED}, {0x7A, 0xEF}, {0x7B, 0xA1}, {0x7B, 0x95}, /* 0xDC-0xDF */
 	{0x7B, 0x8B}, {0x7B, 0x75}, {0x7B, 0x97}, {0x7B, 0x9D}, /* 0xE0-0xE3 */
 	{0x7B, 0x94}, {0x7B, 0x8F}, {0x7B, 0xB8}, {0x7B, 0x87}, /* 0xE4-0xE7 */
-	{0x7B, 0x84}, {0x7C, 0xB9}, {0x7C, 0xBD}, {0x7C, 0xBE}, /* 0xE8-0xEB */
+	{0x7B, 0x84}, {0x7C, 0xB9}, {0x7C, 0xBD}, {0xFA, 0x1D}, /* 0xE8-0xEB */
 	{0x7D, 0xBB}, {0x7D, 0xB0}, {0x7D, 0x9C}, {0x7D, 0xBD}, /* 0xEC-0xEF */
-	{0x7D, 0xBE}, {0x7D, 0xA0}, {0x7D, 0xCA}, {0x7D, 0xB4}, /* 0xF0-0xF3 */
+	{0xF9, 0x57}, {0xF9, 0x3D}, {0x7D, 0xCA}, {0x7D, 0xB4}, /* 0xF0-0xF3 */
 	{0x7D, 0xB2}, {0x7D, 0xB1}, {0x7D, 0xBA}, {0x7D, 0xA2}, /* 0xF4-0xF7 */
 	{0x7D, 0xBF}, {0x7D, 0xB5}, {0x7D, 0xB8}, {0x7D, 0xAD}, /* 0xF8-0xFB */
 	{0x7D, 0xD2}, {0x7D, 0xC7}, {0x7D, 0xAC}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -1808,7 +1810,7 @@
 	{0x87, 0x3F}, {0x87, 0x1C}, {0x87, 0x3B}, {0x87, 0x22}, /* 0x64-0x67 */
 	{0x87, 0x25}, {0x87, 0x34}, {0x87, 0x18}, {0x87, 0x55}, /* 0x68-0x6B */
 	{0x87, 0x37}, {0x87, 0x29}, {0x88, 0xF3}, {0x89, 0x02}, /* 0x6C-0x6F */
-	{0x88, 0xF4}, {0x88, 0xF9}, {0x88, 0xF8}, {0x88, 0xFD}, /* 0x70-0x73 */
+	{0x88, 0xF4}, {0x88, 0xF9}, {0xF9, 0x12}, {0x88, 0xFD}, /* 0x70-0x73 */
 	{0x88, 0xE8}, {0x89, 0x1A}, {0x88, 0xEF}, {0x8A, 0xA6}, /* 0x74-0x77 */
 	{0x8A, 0x8C}, {0x8A, 0x9E}, {0x8A, 0xA3}, {0x8A, 0x8D}, /* 0x78-0x7B */
 	{0x8A, 0xA1}, {0x8A, 0x93}, {0x8A, 0xA4}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -1821,7 +1823,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x94-0x97 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
-	{0x00, 0x3F}, {0x8A, 0xAA}, {0x8A, 0xA5}, {0x8A, 0xA8}, /* 0xA0-0xA3 */
+	{0x00, 0x3F}, {0xF9, 0xA1}, {0x8A, 0xA5}, {0x8A, 0xA8}, /* 0xA0-0xA3 */
 	{0x8A, 0x98}, {0x8A, 0x91}, {0x8A, 0x9A}, {0x8A, 0xA7}, /* 0xA4-0xA7 */
 	{0x8C, 0x6A}, {0x8C, 0x8D}, {0x8C, 0x8C}, {0x8C, 0xD3}, /* 0xA8-0xAB */
 	{0x8C, 0xD1}, {0x8C, 0xD2}, {0x8D, 0x6B}, {0x8D, 0x99}, /* 0xAC-0xAF */
@@ -1837,14 +1839,14 @@
 	{0x95, 0xA9}, {0x95, 0xA3}, {0x95, 0xA5}, {0x95, 0xA4}, /* 0xD4-0xD7 */
 	{0x96, 0x99}, {0x96, 0x9C}, {0x96, 0x9B}, {0x96, 0xCC}, /* 0xD8-0xDB */
 	{0x96, 0xD2}, {0x97, 0x00}, {0x97, 0x7C}, {0x97, 0x85}, /* 0xDC-0xDF */
-	{0x97, 0xF6}, {0x98, 0x17}, {0x98, 0x18}, {0x98, 0xAF}, /* 0xE0-0xE3 */
+	{0x97, 0xF6}, {0x98, 0x17}, {0xF9, 0xB4}, {0x98, 0xAF}, /* 0xE0-0xE3 */
 	{0x98, 0xB1}, {0x99, 0x03}, {0x99, 0x05}, {0x99, 0x0C}, /* 0xE4-0xE7 */
 	{0x99, 0x09}, {0x99, 0xC1}, {0x9A, 0xAF}, {0x9A, 0xB0}, /* 0xE8-0xEB */
 	{0x9A, 0xE6}, {0x9B, 0x41}, {0x9B, 0x42}, {0x9C, 0xF4}, /* 0xEC-0xEF */
 	{0x9C, 0xF6}, {0x9C, 0xF3}, {0x9E, 0xBC}, {0x9F, 0x3B}, /* 0xF0-0xF3 */
 	{0x9F, 0x4A}, {0x51, 0x04}, {0x51, 0x00}, {0x50, 0xFB}, /* 0xF4-0xF7 */
 	{0x50, 0xF5}, {0x50, 0xF9}, {0x51, 0x02}, {0x51, 0x08}, /* 0xF8-0xFB */
-	{0x51, 0x09}, {0x51, 0x05}, {0x51, 0xDC}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x51, 0x09}, {0x51, 0x05}, {0xF9, 0x54}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_BC[256] = {
@@ -1864,7 +1866,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x34-0x37 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
-	{0x52, 0x87}, {0x52, 0x88}, {0x52, 0x89}, {0x52, 0x8D}, /* 0x40-0x43 */
+	{0x52, 0x87}, {0x52, 0x88}, {0xF9, 0xC7}, {0x52, 0x8D}, /* 0x40-0x43 */
 	{0x52, 0x8A}, {0x52, 0xF0}, {0x53, 0xB2}, {0x56, 0x2E}, /* 0x44-0x47 */
 	{0x56, 0x3B}, {0x56, 0x39}, {0x56, 0x32}, {0x56, 0x3F}, /* 0x48-0x4B */
 	{0x56, 0x34}, {0x56, 0x29}, {0x56, 0x53}, {0x56, 0x4E}, /* 0x4C-0x4F */
@@ -1873,8 +1875,8 @@
 	{0x58, 0xB3}, {0x58, 0x9C}, {0x58, 0xAE}, {0x58, 0xA9}, /* 0x58-0x5B */
 	{0x58, 0xA6}, {0x59, 0x6D}, {0x5B, 0x09}, {0x5A, 0xFB}, /* 0x5C-0x5F */
 	{0x5B, 0x0B}, {0x5A, 0xF5}, {0x5B, 0x0C}, {0x5B, 0x08}, /* 0x60-0x63 */
-	{0x5B, 0xEE}, {0x5B, 0xEC}, {0x5B, 0xE9}, {0x5B, 0xEB}, /* 0x64-0x67 */
-	{0x5C, 0x64}, {0x5C, 0x65}, {0x5D, 0x9D}, {0x5D, 0x94}, /* 0x68-0x6B */
+	{0xF9, 0xBC}, {0x5B, 0xEC}, {0x5B, 0xE9}, {0x5B, 0xEB}, /* 0x64-0x67 */
+	{0x5C, 0x64}, {0xF9, 0xDF}, {0x5D, 0x9D}, {0x5D, 0x94}, /* 0x68-0x6B */
 	{0x5E, 0x62}, {0x5E, 0x5F}, {0x5E, 0x61}, {0x5E, 0xE2}, /* 0x6C-0x6F */
 	{0x5E, 0xDA}, {0x5E, 0xDF}, {0x5E, 0xDD}, {0x5E, 0xE3}, /* 0x70-0x73 */
 	{0x5E, 0xE0}, {0x5F, 0x48}, {0x5F, 0x71}, {0x5F, 0xB7}, /* 0x74-0x77 */
@@ -1890,19 +1892,19 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x61, 0x7C}, {0x61, 0x70}, {0x61, 0x6B}, /* 0xA0-0xA3 */
-	{0x61, 0x7E}, {0x61, 0xA7}, {0x61, 0x90}, {0x61, 0xAB}, /* 0xA4-0xA7 */
+	{0x61, 0x7E}, {0x61, 0xA7}, {0xF9, 0x8F}, {0x61, 0xAB}, /* 0xA4-0xA7 */
 	{0x61, 0x8E}, {0x61, 0xAC}, {0x61, 0x9A}, {0x61, 0xA4}, /* 0xA8-0xAB */
-	{0x61, 0x94}, {0x61, 0xAE}, {0x62, 0x2E}, {0x64, 0x69}, /* 0xAC-0xAF */
+	{0x61, 0x94}, {0x61, 0xAE}, {0xF9, 0xD2}, {0x64, 0x69}, /* 0xAC-0xAF */
 	{0x64, 0x6F}, {0x64, 0x79}, {0x64, 0x9E}, {0x64, 0xB2}, /* 0xB0-0xB3 */
 	{0x64, 0x88}, {0x64, 0x90}, {0x64, 0xB0}, {0x64, 0xA5}, /* 0xB4-0xB7 */
 	{0x64, 0x93}, {0x64, 0x95}, {0x64, 0xA9}, {0x64, 0x92}, /* 0xB8-0xBB */
-	{0x64, 0xAE}, {0x64, 0xAD}, {0x64, 0xAB}, {0x64, 0x9A}, /* 0xBC-0xBF */
+	{0x64, 0xAE}, {0x64, 0xAD}, {0x64, 0xAB}, {0xF9, 0x91}, /* 0xBC-0xBF */
 	{0x64, 0xAC}, {0x64, 0x99}, {0x64, 0xA2}, {0x64, 0xB3}, /* 0xC0-0xC3 */
-	{0x65, 0x75}, {0x65, 0x77}, {0x65, 0x78}, {0x66, 0xAE}, /* 0xC4-0xC7 */
-	{0x66, 0xAB}, {0x66, 0xB4}, {0x66, 0xB1}, {0x6A, 0x23}, /* 0xC8-0xCB */
+	{0x65, 0x75}, {0x65, 0x77}, {0xF9, 0x69}, {0x66, 0xAE}, /* 0xC4-0xC7 */
+	{0x66, 0xAB}, {0xFA, 0x06}, {0x66, 0xB1}, {0x6A, 0x23}, /* 0xC8-0xCB */
 	{0x6A, 0x1F}, {0x69, 0xE8}, {0x6A, 0x01}, {0x6A, 0x1E}, /* 0xCC-0xCF */
-	{0x6A, 0x19}, {0x69, 0xFD}, {0x6A, 0x21}, {0x6A, 0x13}, /* 0xD0-0xD3 */
-	{0x6A, 0x0A}, {0x69, 0xF3}, {0x6A, 0x02}, {0x6A, 0x05}, /* 0xD4-0xD7 */
+	{0x6A, 0x19}, {0x69, 0xFD}, {0x6A, 0x21}, {0xF9, 0x4C}, /* 0xD0-0xD3 */
+	{0x6A, 0x0A}, {0x69, 0xF3}, {0xF9, 0xBF}, {0x6A, 0x05}, /* 0xD4-0xD7 */
 	{0x69, 0xED}, {0x6A, 0x11}, {0x6B, 0x50}, {0x6B, 0x4E}, /* 0xD8-0xDB */
 	{0x6B, 0xA4}, {0x6B, 0xC5}, {0x6B, 0xC6}, {0x6F, 0x3F}, /* 0xDC-0xDF */
 	{0x6F, 0x7C}, {0x6F, 0x84}, {0x6F, 0x51}, {0x6F, 0x66}, /* 0xE0-0xE3 */
@@ -1912,7 +1914,7 @@
 	{0x6E, 0xD5}, {0x6F, 0x6F}, {0x6F, 0x60}, {0x6F, 0x5F}, /* 0xF0-0xF3 */
 	{0x71, 0x9F}, {0x71, 0xAC}, {0x71, 0xB1}, {0x71, 0xA8}, /* 0xF4-0xF7 */
 	{0x72, 0x56}, {0x72, 0x9B}, {0x73, 0x4E}, {0x73, 0x57}, /* 0xF8-0xFB */
-	{0x74, 0x69}, {0x74, 0x8B}, {0x74, 0x83}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0xF9, 0xAE}, {0x74, 0x8B}, {0x74, 0x83}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_BD[256] = {
@@ -1937,13 +1939,13 @@
 	{0x76, 0x21}, {0x76, 0x22}, {0x76, 0x9A}, {0x76, 0xBA}, /* 0x48-0x4B */
 	{0x76, 0xE4}, {0x77, 0x8E}, {0x77, 0x87}, {0x77, 0x8C}, /* 0x4C-0x4F */
 	{0x77, 0x91}, {0x77, 0x8B}, {0x78, 0xCB}, {0x78, 0xC5}, /* 0x50-0x53 */
-	{0x78, 0xBA}, {0x78, 0xCA}, {0x78, 0xBE}, {0x78, 0xD5}, /* 0x54-0x57 */
+	{0x78, 0xBA}, {0xF9, 0x47}, {0x78, 0xBE}, {0x78, 0xD5}, /* 0x54-0x57 */
 	{0x78, 0xBC}, {0x78, 0xD0}, {0x7A, 0x3F}, {0x7A, 0x3C}, /* 0x58-0x5B */
 	{0x7A, 0x40}, {0x7A, 0x3D}, {0x7A, 0x37}, {0x7A, 0x3B}, /* 0x5C-0x5F */
 	{0x7A, 0xAF}, {0x7A, 0xAE}, {0x7B, 0xAD}, {0x7B, 0xB1}, /* 0x60-0x63 */
 	{0x7B, 0xC4}, {0x7B, 0xB4}, {0x7B, 0xC6}, {0x7B, 0xC7}, /* 0x64-0x67 */
 	{0x7B, 0xC1}, {0x7B, 0xA0}, {0x7B, 0xCC}, {0x7C, 0xCA}, /* 0x68-0x6B */
-	{0x7D, 0xE0}, {0x7D, 0xF4}, {0x7D, 0xEF}, {0x7D, 0xFB}, /* 0x6C-0x6F */
+	{0x7D, 0xE0}, {0xF9, 0x96}, {0x7D, 0xEF}, {0x7D, 0xFB}, /* 0x6C-0x6F */
 	{0x7D, 0xD8}, {0x7D, 0xEC}, {0x7D, 0xDD}, {0x7D, 0xE8}, /* 0x70-0x73 */
 	{0x7D, 0xE3}, {0x7D, 0xDA}, {0x7D, 0xDE}, {0x7D, 0xE9}, /* 0x74-0x77 */
 	{0x7D, 0x9E}, {0x7D, 0xD9}, {0x7D, 0xF2}, {0x7D, 0xF9}, /* 0x78-0x7B */
@@ -1960,7 +1962,7 @@
 	{0x00, 0x3F}, {0x7F, 0xE9}, {0x80, 0x26}, {0x81, 0x9B}, /* 0xA0-0xA3 */
 	{0x81, 0x9C}, {0x81, 0x9D}, {0x81, 0xA0}, {0x81, 0x9A}, /* 0xA4-0xA7 */
 	{0x81, 0x98}, {0x85, 0x17}, {0x85, 0x3D}, {0x85, 0x1A}, /* 0xA8-0xAB */
-	{0x84, 0xEE}, {0x85, 0x2C}, {0x85, 0x2D}, {0x85, 0x13}, /* 0xAC-0xAF */
+	{0xF9, 0x99}, {0x85, 0x2C}, {0x85, 0x2D}, {0x85, 0x13}, /* 0xAC-0xAF */
 	{0x85, 0x11}, {0x85, 0x23}, {0x85, 0x21}, {0x85, 0x14}, /* 0xB0-0xB3 */
 	{0x84, 0xEC}, {0x85, 0x25}, {0x84, 0xFF}, {0x85, 0x06}, /* 0xB4-0xB7 */
 	{0x87, 0x82}, {0x87, 0x74}, {0x87, 0x76}, {0x87, 0x60}, /* 0xB8-0xBB */
@@ -1968,19 +1970,19 @@
 	{0x87, 0x57}, {0x87, 0x4C}, {0x87, 0x53}, {0x88, 0x5B}, /* 0xC0-0xC3 */
 	{0x88, 0x5D}, {0x89, 0x10}, {0x89, 0x07}, {0x89, 0x12}, /* 0xC4-0xC7 */
 	{0x89, 0x13}, {0x89, 0x15}, {0x89, 0x0A}, {0x8A, 0xBC}, /* 0xC8-0xCB */
-	{0x8A, 0xD2}, {0x8A, 0xC7}, {0x8A, 0xC4}, {0x8A, 0x95}, /* 0xCC-0xCF */
-	{0x8A, 0xCB}, {0x8A, 0xF8}, {0x8A, 0xB2}, {0x8A, 0xC9}, /* 0xD0-0xD3 */
-	{0x8A, 0xC2}, {0x8A, 0xBF}, {0x8A, 0xB0}, {0x8A, 0xD6}, /* 0xD4-0xD7 */
+	{0xF9, 0x7D}, {0x8A, 0xC7}, {0x8A, 0xC4}, {0x8A, 0x95}, /* 0xCC-0xCF */
+	{0x8A, 0xCB}, {0xFA, 0x22}, {0x8A, 0xB2}, {0x8A, 0xC9}, /* 0xD0-0xD3 */
+	{0x8A, 0xC2}, {0x8A, 0xBF}, {0x8A, 0xB0}, {0xF9, 0x41}, /* 0xD4-0xD7 */
 	{0x8A, 0xCD}, {0x8A, 0xB6}, {0x8A, 0xB9}, {0x8A, 0xDB}, /* 0xD8-0xDB */
-	{0x8C, 0x4C}, {0x8C, 0x4E}, {0x8C, 0x6C}, {0x8C, 0xE0}, /* 0xDC-0xDF */
+	{0x8C, 0x4C}, {0x8C, 0x4E}, {0xFA, 0x16}, {0x8C, 0xE0}, /* 0xDC-0xDF */
 	{0x8C, 0xDE}, {0x8C, 0xE6}, {0x8C, 0xE4}, {0x8C, 0xEC}, /* 0xE0-0xE3 */
 	{0x8C, 0xED}, {0x8C, 0xE2}, {0x8C, 0xE3}, {0x8C, 0xDC}, /* 0xE4-0xE7 */
 	{0x8C, 0xEA}, {0x8C, 0xE1}, {0x8D, 0x6D}, {0x8D, 0x9F}, /* 0xE8-0xEB */
 	{0x8D, 0xA3}, {0x8E, 0x2B}, {0x8E, 0x10}, {0x8E, 0x1D}, /* 0xEC-0xEF */
 	{0x8E, 0x22}, {0x8E, 0x0F}, {0x8E, 0x29}, {0x8E, 0x1F}, /* 0xF0-0xF3 */
 	{0x8E, 0x21}, {0x8E, 0x1E}, {0x8E, 0xBA}, {0x8F, 0x1D}, /* 0xF4-0xF7 */
-	{0x8F, 0x1B}, {0x8F, 0x1F}, {0x8F, 0x29}, {0x8F, 0x26}, /* 0xF8-0xFB */
-	{0x8F, 0x2A}, {0x8F, 0x1C}, {0x8F, 0x1E}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x8F, 0x1B}, {0x8F, 0x1F}, {0x8F, 0x29}, {0xF9, 0x98}, /* 0xF8-0xFB */
+	{0xF9, 0xD7}, {0x8F, 0x1C}, {0x8F, 0x1E}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_BE[256] = {
@@ -2006,7 +2008,7 @@
 	{0x91, 0x8B}, {0x91, 0x83}, {0x92, 0xC5}, {0x92, 0xBB}, /* 0x4C-0x4F */
 	{0x92, 0xB7}, {0x92, 0xEA}, {0x92, 0xAC}, {0x92, 0xE4}, /* 0x50-0x53 */
 	{0x92, 0xC1}, {0x92, 0xB3}, {0x92, 0xBC}, {0x92, 0xD2}, /* 0x54-0x57 */
-	{0x92, 0xC7}, {0x92, 0xF0}, {0x92, 0xB2}, {0x95, 0xAD}, /* 0x58-0x5B */
+	{0x92, 0xC7}, {0x92, 0xF0}, {0x92, 0xB2}, {0xF9, 0x86}, /* 0x58-0x5B */
 	{0x95, 0xB1}, {0x97, 0x04}, {0x97, 0x06}, {0x97, 0x07}, /* 0x5C-0x5F */
 	{0x97, 0x09}, {0x97, 0x60}, {0x97, 0x8D}, {0x97, 0x8B}, /* 0x60-0x63 */
 	{0x97, 0x8F}, {0x98, 0x21}, {0x98, 0x2B}, {0x98, 0x1C}, /* 0x64-0x67 */
@@ -2015,7 +2017,7 @@
 	{0x99, 0xDB}, {0x99, 0xD1}, {0x99, 0xD5}, {0x99, 0xD2}, /* 0x70-0x73 */
 	{0x99, 0xD9}, {0x9A, 0xB7}, {0x9A, 0xEE}, {0x9A, 0xEF}, /* 0x74-0x77 */
 	{0x9B, 0x27}, {0x9B, 0x45}, {0x9B, 0x44}, {0x9B, 0x77}, /* 0x78-0x7B */
-	{0x9B, 0x6F}, {0x9D, 0x06}, {0x9D, 0x09}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0xF9, 0x39}, {0x9D, 0x06}, {0x9D, 0x09}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -2026,7 +2028,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x9D, 0x03}, {0x9E, 0xA9}, {0x9E, 0xBE}, /* 0xA0-0xA3 */
-	{0x9E, 0xCE}, {0x58, 0xA8}, {0x9F, 0x52}, {0x51, 0x12}, /* 0xA4-0xA7 */
+	{0xF9, 0x89}, {0x58, 0xA8}, {0x9F, 0x52}, {0x51, 0x12}, /* 0xA4-0xA7 */
 	{0x51, 0x18}, {0x51, 0x14}, {0x51, 0x10}, {0x51, 0x15}, /* 0xA8-0xAB */
 	{0x51, 0x80}, {0x51, 0xAA}, {0x51, 0xDD}, {0x52, 0x91}, /* 0xAC-0xAF */
 	{0x52, 0x93}, {0x52, 0xF3}, {0x56, 0x59}, {0x56, 0x6B}, /* 0xB0-0xB3 */
@@ -2039,15 +2041,15 @@
 	{0x61, 0x91}, {0x61, 0xA9}, {0x61, 0x8A}, {0x61, 0xCD}, /* 0xCC-0xCF */
 	{0x61, 0xB6}, {0x61, 0xBE}, {0x61, 0xCA}, {0x61, 0xC8}, /* 0xD0-0xD3 */
 	{0x62, 0x30}, {0x64, 0xC5}, {0x64, 0xC1}, {0x64, 0xCB}, /* 0xD4-0xD7 */
-	{0x64, 0xBB}, {0x64, 0xBC}, {0x64, 0xDA}, {0x64, 0xC4}, /* 0xD8-0xDB */
+	{0x64, 0xBB}, {0x64, 0xBC}, {0x64, 0xDA}, {0xF9, 0x30}, /* 0xD8-0xDB */
 	{0x64, 0xC7}, {0x64, 0xC2}, {0x64, 0xCD}, {0x64, 0xBF}, /* 0xDC-0xDF */
 	{0x64, 0xD2}, {0x64, 0xD4}, {0x64, 0xBE}, {0x65, 0x74}, /* 0xE0-0xE3 */
-	{0x66, 0xC6}, {0x66, 0xC9}, {0x66, 0xB9}, {0x66, 0xC4}, /* 0xE4-0xE7 */
+	{0xF9, 0x8B}, {0x66, 0xC9}, {0x66, 0xB9}, {0x66, 0xC4}, /* 0xE4-0xE7 */
 	{0x66, 0xC7}, {0x66, 0xB8}, {0x6A, 0x3D}, {0x6A, 0x38}, /* 0xE8-0xEB */
 	{0x6A, 0x3A}, {0x6A, 0x59}, {0x6A, 0x6B}, {0x6A, 0x58}, /* 0xEC-0xEF */
 	{0x6A, 0x39}, {0x6A, 0x44}, {0x6A, 0x62}, {0x6A, 0x61}, /* 0xF0-0xF3 */
 	{0x6A, 0x4B}, {0x6A, 0x47}, {0x6A, 0x35}, {0x6A, 0x5F}, /* 0xF4-0xF7 */
-	{0x6A, 0x48}, {0x6B, 0x59}, {0x6B, 0x77}, {0x6C, 0x05}, /* 0xF8-0xFB */
+	{0x6A, 0x48}, {0x6B, 0x59}, {0xF9, 0x8C}, {0x6C, 0x05}, /* 0xF8-0xFB */
 	{0x6F, 0xC2}, {0x6F, 0xB1}, {0x6F, 0xA1}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -2071,19 +2073,19 @@
 	{0x6F, 0xC3}, {0x6F, 0xA4}, {0x6F, 0xC1}, {0x6F, 0xA7}, /* 0x40-0x43 */
 	{0x6F, 0xB3}, {0x6F, 0xC0}, {0x6F, 0xB9}, {0x6F, 0xB6}, /* 0x44-0x47 */
 	{0x6F, 0xA6}, {0x6F, 0xA0}, {0x6F, 0xB4}, {0x71, 0xBE}, /* 0x48-0x4B */
-	{0x71, 0xC9}, {0x71, 0xD0}, {0x71, 0xD2}, {0x71, 0xC8}, /* 0x4C-0x4F */
-	{0x71, 0xD5}, {0x71, 0xB9}, {0x71, 0xCE}, {0x71, 0xD9}, /* 0x50-0x53 */
+	{0x71, 0xC9}, {0xF9, 0xEE}, {0x71, 0xD2}, {0x71, 0xC8}, /* 0x4C-0x4F */
+	{0x71, 0xD5}, {0x71, 0xB9}, {0xF9, 0xC0}, {0x71, 0xD9}, /* 0x50-0x53 */
 	{0x71, 0xDC}, {0x71, 0xC3}, {0x71, 0xC4}, {0x73, 0x68}, /* 0x54-0x57 */
-	{0x74, 0x9C}, {0x74, 0xA3}, {0x74, 0x98}, {0x74, 0x9F}, /* 0x58-0x5B */
+	{0x74, 0x9C}, {0x74, 0xA3}, {0xF9, 0xEF}, {0x74, 0x9F}, /* 0x58-0x5B */
 	{0x74, 0x9E}, {0x74, 0xE2}, {0x75, 0x0C}, {0x75, 0x0D}, /* 0x5C-0x5F */
-	{0x76, 0x34}, {0x76, 0x38}, {0x76, 0x3A}, {0x76, 0xE7}, /* 0x60-0x63 */
+	{0x76, 0x34}, {0x76, 0x38}, {0x76, 0x3A}, {0xF9, 0x33}, /* 0x60-0x63 */
 	{0x76, 0xE5}, {0x77, 0xA0}, {0x77, 0x9E}, {0x77, 0x9F}, /* 0x64-0x67 */
 	{0x77, 0xA5}, {0x78, 0xE8}, {0x78, 0xDA}, {0x78, 0xEC}, /* 0x68-0x6B */
 	{0x78, 0xE7}, {0x79, 0xA6}, {0x7A, 0x4D}, {0x7A, 0x4E}, /* 0x6C-0x6F */
 	{0x7A, 0x46}, {0x7A, 0x4C}, {0x7A, 0x4B}, {0x7A, 0xBA}, /* 0x70-0x73 */
 	{0x7B, 0xD9}, {0x7C, 0x11}, {0x7B, 0xC9}, {0x7B, 0xE4}, /* 0x74-0x77 */
 	{0x7B, 0xDB}, {0x7B, 0xE1}, {0x7B, 0xE9}, {0x7B, 0xE6}, /* 0x78-0x7B */
-	{0x7C, 0xD5}, {0x7C, 0xD6}, {0x7E, 0x0A}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x7C, 0xD5}, {0xFA, 0x03}, {0x7E, 0x0A}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -2095,7 +2097,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x7E, 0x11}, {0x7E, 0x08}, {0x7E, 0x1B}, /* 0xA0-0xA3 */
 	{0x7E, 0x23}, {0x7E, 0x1E}, {0x7E, 0x1D}, {0x7E, 0x09}, /* 0xA4-0xA7 */
-	{0x7E, 0x10}, {0x7F, 0x79}, {0x7F, 0xB2}, {0x7F, 0xF0}, /* 0xA8-0xAB */
+	{0x7E, 0x10}, {0xF9, 0xE6}, {0x7F, 0xB2}, {0x7F, 0xF0}, /* 0xA8-0xAB */
 	{0x7F, 0xF1}, {0x7F, 0xEE}, {0x80, 0x28}, {0x81, 0xB3}, /* 0xAC-0xAF */
 	{0x81, 0xA9}, {0x81, 0xA8}, {0x81, 0xFB}, {0x82, 0x08}, /* 0xB0-0xB3 */
 	{0x82, 0x58}, {0x82, 0x59}, {0x85, 0x4A}, {0x85, 0x59}, /* 0xB4-0xB7 */
@@ -2106,17 +2108,17 @@
 	{0x89, 0x25}, {0x89, 0x2B}, {0x89, 0x21}, {0x89, 0xAA}, /* 0xC8-0xCB */
 	{0x89, 0xA6}, {0x8A, 0xE6}, {0x8A, 0xFA}, {0x8A, 0xEB}, /* 0xCC-0xCF */
 	{0x8A, 0xF1}, {0x8B, 0x00}, {0x8A, 0xDC}, {0x8A, 0xE7}, /* 0xD0-0xD3 */
-	{0x8A, 0xEE}, {0x8A, 0xFE}, {0x8B, 0x01}, {0x8B, 0x02}, /* 0xD4-0xD7 */
+	{0x8A, 0xEE}, {0xF9, 0x5D}, {0x8B, 0x01}, {0x8B, 0x02}, /* 0xD4-0xD7 */
 	{0x8A, 0xF7}, {0x8A, 0xED}, {0x8A, 0xF3}, {0x8A, 0xF6}, /* 0xD8-0xDB */
 	{0x8A, 0xFC}, {0x8C, 0x6B}, {0x8C, 0x6D}, {0x8C, 0x93}, /* 0xDC-0xDF */
 	{0x8C, 0xF4}, {0x8E, 0x44}, {0x8E, 0x31}, {0x8E, 0x34}, /* 0xE0-0xE3 */
-	{0x8E, 0x42}, {0x8E, 0x39}, {0x8E, 0x35}, {0x8F, 0x3B}, /* 0xE4-0xE7 */
+	{0x8E, 0x42}, {0x8E, 0x39}, {0x8E, 0x35}, {0xFA, 0x07}, /* 0xE4-0xE7 */
 	{0x8F, 0x2F}, {0x8F, 0x38}, {0x8F, 0x33}, {0x8F, 0xA8}, /* 0xE8-0xEB */
 	{0x8F, 0xA6}, {0x90, 0x75}, {0x90, 0x74}, {0x90, 0x78}, /* 0xEC-0xEF */
-	{0x90, 0x72}, {0x90, 0x7C}, {0x90, 0x7A}, {0x91, 0x34}, /* 0xF0-0xF3 */
+	{0x90, 0x72}, {0xF9, 0xC3}, {0x90, 0x7A}, {0x91, 0x34}, /* 0xF0-0xF3 */
 	{0x91, 0x92}, {0x93, 0x20}, {0x93, 0x36}, {0x92, 0xF8}, /* 0xF4-0xF7 */
 	{0x93, 0x33}, {0x93, 0x2F}, {0x93, 0x22}, {0x92, 0xFC}, /* 0xF8-0xFB */
-	{0x93, 0x2B}, {0x93, 0x04}, {0x93, 0x1A}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x93, 0x2B}, {0xF9, 0x3F}, {0x93, 0x1A}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_C0[256] = {
@@ -2143,14 +2145,14 @@
 	{0x97, 0x0F}, {0x97, 0x5B}, {0x97, 0x5C}, {0x97, 0x66}, /* 0x50-0x53 */
 	{0x97, 0x98}, {0x98, 0x30}, {0x98, 0x38}, {0x98, 0x3B}, /* 0x54-0x57 */
 	{0x98, 0x37}, {0x98, 0x2D}, {0x98, 0x39}, {0x98, 0x24}, /* 0x58-0x5B */
-	{0x99, 0x10}, {0x99, 0x28}, {0x99, 0x1E}, {0x99, 0x1B}, /* 0x5C-0x5F */
+	{0x99, 0x10}, {0xFA, 0x2C}, {0x99, 0x1E}, {0x99, 0x1B}, /* 0x5C-0x5F */
 	{0x99, 0x21}, {0x99, 0x1A}, {0x99, 0xED}, {0x99, 0xE2}, /* 0x60-0x63 */
-	{0x99, 0xF1}, {0x9A, 0xB8}, {0x9A, 0xBC}, {0x9A, 0xFB}, /* 0x64-0x67 */
+	{0xF9, 0x1A}, {0x9A, 0xB8}, {0x9A, 0xBC}, {0x9A, 0xFB}, /* 0x64-0x67 */
 	{0x9A, 0xED}, {0x9B, 0x28}, {0x9B, 0x91}, {0x9D, 0x15}, /* 0x68-0x6B */
 	{0x9D, 0x23}, {0x9D, 0x26}, {0x9D, 0x28}, {0x9D, 0x12}, /* 0x6C-0x6F */
-	{0x9D, 0x1B}, {0x9E, 0xD8}, {0x9E, 0xD4}, {0x9F, 0x8D}, /* 0x70-0x73 */
-	{0x9F, 0x9C}, {0x51, 0x2A}, {0x51, 0x1F}, {0x51, 0x21}, /* 0x74-0x77 */
-	{0x51, 0x32}, {0x52, 0xF5}, {0x56, 0x8E}, {0x56, 0x80}, /* 0x78-0x7B */
+	{0x9D, 0x1B}, {0x9E, 0xD8}, {0x9E, 0xD4}, {0xF9, 0xC4}, /* 0x70-0x73 */
+	{0xF9, 0x08}, {0x51, 0x2A}, {0x51, 0x1F}, {0x51, 0x21}, /* 0x74-0x77 */
+	{0x51, 0x32}, {0xF9, 0x7F}, {0x56, 0x8E}, {0x56, 0x80}, /* 0x78-0x7B */
 	{0x56, 0x90}, {0x56, 0x85}, {0x56, 0x87}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
@@ -2164,7 +2166,7 @@
 	{0x00, 0x3F}, {0x56, 0x8F}, {0x58, 0xD5}, {0x58, 0xD3}, /* 0xA0-0xA3 */
 	{0x58, 0xD1}, {0x58, 0xCE}, {0x5B, 0x30}, {0x5B, 0x2A}, /* 0xA4-0xA7 */
 	{0x5B, 0x24}, {0x5B, 0x7A}, {0x5C, 0x37}, {0x5C, 0x68}, /* 0xA8-0xAB */
-	{0x5D, 0xBC}, {0x5D, 0xBA}, {0x5D, 0xBD}, {0x5D, 0xB8}, /* 0xAC-0xAF */
+	{0x5D, 0xBC}, {0xF9, 0xAB}, {0x5D, 0xBD}, {0x5D, 0xB8}, /* 0xAC-0xAF */
 	{0x5E, 0x6B}, {0x5F, 0x4C}, {0x5F, 0xBD}, {0x61, 0xC9}, /* 0xB0-0xB3 */
 	{0x61, 0xC2}, {0x61, 0xC7}, {0x61, 0xE6}, {0x61, 0xCB}, /* 0xB4-0xB7 */
 	{0x62, 0x32}, {0x62, 0x34}, {0x64, 0xCE}, {0x64, 0xCA}, /* 0xB8-0xBB */
@@ -2174,16 +2176,16 @@
 	{0x6A, 0x80}, {0x6A, 0x94}, {0x6A, 0x84}, {0x6A, 0xA2}, /* 0xC8-0xCB */
 	{0x6A, 0x9C}, {0x6A, 0xDB}, {0x6A, 0xA3}, {0x6A, 0x7E}, /* 0xCC-0xCF */
 	{0x6A, 0x97}, {0x6A, 0x90}, {0x6A, 0xA0}, {0x6B, 0x5C}, /* 0xD0-0xD3 */
-	{0x6B, 0xAE}, {0x6B, 0xDA}, {0x6C, 0x08}, {0x6F, 0xD8}, /* 0xD4-0xD7 */
+	{0xF9, 0xA5}, {0x6B, 0xDA}, {0x6C, 0x08}, {0x6F, 0xD8}, /* 0xD4-0xD7 */
 	{0x6F, 0xF1}, {0x6F, 0xDF}, {0x6F, 0xE0}, {0x6F, 0xDB}, /* 0xD8-0xDB */
-	{0x6F, 0xE4}, {0x6F, 0xEB}, {0x6F, 0xEF}, {0x6F, 0x80}, /* 0xDC-0xDF */
+	{0x6F, 0xE4}, {0xF9, 0x22}, {0x6F, 0xEF}, {0x6F, 0x80}, /* 0xDC-0xDF */
 	{0x6F, 0xEC}, {0x6F, 0xE1}, {0x6F, 0xE9}, {0x6F, 0xD5}, /* 0xE0-0xE3 */
 	{0x6F, 0xEE}, {0x6F, 0xF0}, {0x71, 0xE7}, {0x71, 0xDF}, /* 0xE4-0xE7 */
 	{0x71, 0xEE}, {0x71, 0xE6}, {0x71, 0xE5}, {0x71, 0xED}, /* 0xE8-0xEB */
 	{0x71, 0xEC}, {0x71, 0xF4}, {0x71, 0xE0}, {0x72, 0x35}, /* 0xEC-0xEF */
 	{0x72, 0x46}, {0x73, 0x70}, {0x73, 0x72}, {0x74, 0xA9}, /* 0xF0-0xF3 */
 	{0x74, 0xB0}, {0x74, 0xA6}, {0x74, 0xA8}, {0x76, 0x46}, /* 0xF4-0xF7 */
-	{0x76, 0x42}, {0x76, 0x4C}, {0x76, 0xEA}, {0x77, 0xB3}, /* 0xF8-0xFB */
+	{0xF9, 0xC1}, {0x76, 0x4C}, {0x76, 0xEA}, {0x77, 0xB3}, /* 0xF8-0xFB */
 	{0x77, 0xAA}, {0x77, 0xB0}, {0x77, 0xAC}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -2211,14 +2213,14 @@
 	{0x7C, 0x0C}, {0x7B, 0xE0}, {0x7C, 0xE0}, {0x7C, 0xDC}, /* 0x50-0x53 */
 	{0x7C, 0xDE}, {0x7C, 0xE2}, {0x7C, 0xDF}, {0x7C, 0xD9}, /* 0x54-0x57 */
 	{0x7C, 0xDD}, {0x7E, 0x2E}, {0x7E, 0x3E}, {0x7E, 0x46}, /* 0x58-0x5B */
-	{0x7E, 0x37}, {0x7E, 0x32}, {0x7E, 0x43}, {0x7E, 0x2B}, /* 0x5C-0x5F */
+	{0xF9, 0x50}, {0x7E, 0x32}, {0x7E, 0x43}, {0x7E, 0x2B}, /* 0x5C-0x5F */
 	{0x7E, 0x3D}, {0x7E, 0x31}, {0x7E, 0x45}, {0x7E, 0x41}, /* 0x60-0x63 */
 	{0x7E, 0x34}, {0x7E, 0x39}, {0x7E, 0x48}, {0x7E, 0x35}, /* 0x64-0x67 */
 	{0x7E, 0x3F}, {0x7E, 0x2F}, {0x7F, 0x44}, {0x7F, 0xF3}, /* 0x68-0x6B */
 	{0x7F, 0xFC}, {0x80, 0x71}, {0x80, 0x72}, {0x80, 0x70}, /* 0x6C-0x6F */
-	{0x80, 0x6F}, {0x80, 0x73}, {0x81, 0xC6}, {0x81, 0xC3}, /* 0x70-0x73 */
+	{0xF9, 0x97}, {0x80, 0x73}, {0x81, 0xC6}, {0x81, 0xC3}, /* 0x70-0x73 */
 	{0x81, 0xBA}, {0x81, 0xC2}, {0x81, 0xC0}, {0x81, 0xBF}, /* 0x74-0x77 */
-	{0x81, 0xBD}, {0x81, 0xC9}, {0x81, 0xBE}, {0x81, 0xE8}, /* 0x78-0x7B */
+	{0x81, 0xBD}, {0x81, 0xC9}, {0x81, 0xBE}, {0xF9, 0xF6}, /* 0x78-0x7B */
 	{0x82, 0x09}, {0x82, 0x71}, {0x85, 0xAA}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
@@ -2233,7 +2235,7 @@
 	{0x85, 0x91}, {0x85, 0x94}, {0x85, 0xAF}, {0x85, 0x9B}, /* 0xA4-0xA7 */
 	{0x85, 0x87}, {0x85, 0xA8}, {0x85, 0x8A}, {0x86, 0x67}, /* 0xA8-0xAB */
 	{0x87, 0xC0}, {0x87, 0xD1}, {0x87, 0xB3}, {0x87, 0xD2}, /* 0xAC-0xAF */
-	{0x87, 0xC6}, {0x87, 0xAB}, {0x87, 0xBB}, {0x87, 0xBA}, /* 0xB0-0xB3 */
+	{0x87, 0xC6}, {0x87, 0xAB}, {0x87, 0xBB}, {0xF9, 0x11}, /* 0xB0-0xB3 */
 	{0x87, 0xC8}, {0x87, 0xCB}, {0x89, 0x3B}, {0x89, 0x36}, /* 0xB4-0xB7 */
 	{0x89, 0x44}, {0x89, 0x38}, {0x89, 0x3D}, {0x89, 0xAC}, /* 0xB8-0xBB */
 	{0x8B, 0x0E}, {0x8B, 0x17}, {0x8B, 0x19}, {0x8B, 0x1B}, /* 0xBC-0xBF */
@@ -2246,11 +2248,11 @@
 	{0x90, 0x7D}, {0x90, 0x84}, {0x90, 0x81}, {0x90, 0x82}, /* 0xD8-0xDB */
 	{0x90, 0x80}, {0x91, 0x39}, {0x91, 0xA3}, {0x91, 0x9E}, /* 0xDC-0xDF */
 	{0x91, 0x9C}, {0x93, 0x4D}, {0x93, 0x82}, {0x93, 0x28}, /* 0xE0-0xE3 */
-	{0x93, 0x75}, {0x93, 0x4A}, {0x93, 0x65}, {0x93, 0x4B}, /* 0xE4-0xE7 */
+	{0x93, 0x75}, {0xF9, 0x9B}, {0x93, 0x65}, {0x93, 0x4B}, /* 0xE4-0xE7 */
 	{0x93, 0x18}, {0x93, 0x7E}, {0x93, 0x6C}, {0x93, 0x5B}, /* 0xE8-0xEB */
 	{0x93, 0x70}, {0x93, 0x5A}, {0x93, 0x54}, {0x95, 0xCA}, /* 0xEC-0xEF */
 	{0x95, 0xCB}, {0x95, 0xCC}, {0x95, 0xC8}, {0x95, 0xC6}, /* 0xF0-0xF3 */
-	{0x96, 0xB1}, {0x96, 0xB8}, {0x96, 0xD6}, {0x97, 0x1C}, /* 0xF4-0xF7 */
+	{0x96, 0xB1}, {0xF9, 0xB8}, {0x96, 0xD6}, {0x97, 0x1C}, /* 0xF4-0xF7 */
 	{0x97, 0x1E}, {0x97, 0xA0}, {0x97, 0xD3}, {0x98, 0x46}, /* 0xF8-0xFB */
 	{0x98, 0xB6}, {0x99, 0x35}, {0x9A, 0x01}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -2276,17 +2278,17 @@
 	{0x9B, 0xAD}, {0x9D, 0x3B}, {0x9D, 0x3F}, {0x9E, 0x8B}, /* 0x44-0x47 */
 	{0x9E, 0xCF}, {0x9E, 0xDE}, {0x9E, 0xDC}, {0x9E, 0xDD}, /* 0x48-0x4B */
 	{0x9E, 0xDB}, {0x9F, 0x3E}, {0x9F, 0x4B}, {0x53, 0xE2}, /* 0x4C-0x4F */
-	{0x56, 0x95}, {0x56, 0xAE}, {0x58, 0xD9}, {0x58, 0xD8}, /* 0x50-0x53 */
+	{0x56, 0x95}, {0x56, 0xAE}, {0x58, 0xD9}, {0xF9, 0x4A}, /* 0x50-0x53 */
 	{0x5B, 0x38}, {0x5F, 0x5D}, {0x61, 0xE3}, {0x62, 0x33}, /* 0x54-0x57 */
 	{0x64, 0xF4}, {0x64, 0xF2}, {0x64, 0xFE}, {0x65, 0x06}, /* 0x58-0x5B */
 	{0x64, 0xFA}, {0x64, 0xFB}, {0x64, 0xF7}, {0x65, 0xB7}, /* 0x5C-0x5F */
 	{0x66, 0xDC}, {0x67, 0x26}, {0x6A, 0xB3}, {0x6A, 0xAC}, /* 0x60-0x63 */
 	{0x6A, 0xC3}, {0x6A, 0xBB}, {0x6A, 0xB8}, {0x6A, 0xC2}, /* 0x64-0x67 */
 	{0x6A, 0xAE}, {0x6A, 0xAF}, {0x6B, 0x5F}, {0x6B, 0x78}, /* 0x68-0x6B */
-	{0x6B, 0xAF}, {0x70, 0x09}, {0x70, 0x0B}, {0x6F, 0xFE}, /* 0x6C-0x6F */
+	{0x6B, 0xAF}, {0x70, 0x09}, {0x70, 0x0B}, {0xF9, 0x84}, /* 0x6C-0x6F */
 	{0x70, 0x06}, {0x6F, 0xFA}, {0x70, 0x11}, {0x70, 0x0F}, /* 0x70-0x73 */
 	{0x71, 0xFB}, {0x71, 0xFC}, {0x71, 0xFE}, {0x71, 0xF8}, /* 0x74-0x77 */
-	{0x73, 0x77}, {0x73, 0x75}, {0x74, 0xA7}, {0x74, 0xBF}, /* 0x78-0x7B */
+	{0x73, 0x77}, {0xF9, 0xA7}, {0x74, 0xA7}, {0x74, 0xBF}, /* 0x78-0x7B */
 	{0x75, 0x15}, {0x76, 0x56}, {0x76, 0x58}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
@@ -2298,15 +2300,15 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x76, 0x52}, {0x77, 0xBD}, {0x77, 0xBF}, /* 0xA0-0xA3 */
-	{0x77, 0xBB}, {0x77, 0xBC}, {0x79, 0x0E}, {0x79, 0xAE}, /* 0xA4-0xA7 */
+	{0x77, 0xBB}, {0x77, 0xBC}, {0x79, 0x0E}, {0xF9, 0xB6}, /* 0xA4-0xA7 */
 	{0x7A, 0x61}, {0x7A, 0x62}, {0x7A, 0x60}, {0x7A, 0xC4}, /* 0xA8-0xAB */
 	{0x7A, 0xC5}, {0x7C, 0x2B}, {0x7C, 0x27}, {0x7C, 0x2A}, /* 0xAC-0xAF */
-	{0x7C, 0x1E}, {0x7C, 0x23}, {0x7C, 0x21}, {0x7C, 0xE7}, /* 0xB0-0xB3 */
+	{0x7C, 0x1E}, {0x7C, 0x23}, {0x7C, 0x21}, {0xF9, 0x7B}, /* 0xB0-0xB3 */
 	{0x7E, 0x54}, {0x7E, 0x55}, {0x7E, 0x5E}, {0x7E, 0x5A}, /* 0xB4-0xB7 */
 	{0x7E, 0x61}, {0x7E, 0x52}, {0x7E, 0x59}, {0x7F, 0x48}, /* 0xB8-0xBB */
 	{0x7F, 0xF9}, {0x7F, 0xFB}, {0x80, 0x77}, {0x80, 0x76}, /* 0xBC-0xBF */
 	{0x81, 0xCD}, {0x81, 0xCF}, {0x82, 0x0A}, {0x85, 0xCF}, /* 0xC0-0xC3 */
-	{0x85, 0xA9}, {0x85, 0xCD}, {0x85, 0xD0}, {0x85, 0xC9}, /* 0xC4-0xC7 */
+	{0x85, 0xA9}, {0xF9, 0x23}, {0x85, 0xD0}, {0x85, 0xC9}, /* 0xC4-0xC7 */
 	{0x85, 0xB0}, {0x85, 0xBA}, {0x85, 0xB9}, {0x85, 0xA6}, /* 0xC8-0xCB */
 	{0x87, 0xEF}, {0x87, 0xEC}, {0x87, 0xF2}, {0x87, 0xE0}, /* 0xCC-0xCF */
 	{0x89, 0x86}, {0x89, 0xB2}, {0x89, 0xF4}, {0x8B, 0x28}, /* 0xD0-0xD3 */
@@ -2318,7 +2320,7 @@
 	{0x93, 0x94}, {0x93, 0x8A}, {0x93, 0x96}, {0x93, 0xA2}, /* 0xE8-0xEB */
 	{0x93, 0xB3}, {0x93, 0xAE}, {0x93, 0xAC}, {0x93, 0xB0}, /* 0xEC-0xEF */
 	{0x93, 0x98}, {0x93, 0x9A}, {0x93, 0x97}, {0x95, 0xD4}, /* 0xF0-0xF3 */
-	{0x95, 0xD6}, {0x95, 0xD0}, {0x95, 0xD5}, {0x96, 0xE2}, /* 0xF4-0xF7 */
+	{0x95, 0xD6}, {0x95, 0xD0}, {0x95, 0xD5}, {0xF9, 0xEA}, /* 0xF4-0xF7 */
 	{0x96, 0xDC}, {0x96, 0xD9}, {0x96, 0xDB}, {0x96, 0xDE}, /* 0xF8-0xFB */
 	{0x97, 0x24}, {0x97, 0xA3}, {0x97, 0xA6}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
@@ -2348,11 +2350,11 @@
 	{0x9B, 0xCA}, {0x9B, 0xC9}, {0x9B, 0xFD}, {0x9B, 0xC8}, /* 0x54-0x57 */
 	{0x9B, 0xC0}, {0x9D, 0x51}, {0x9D, 0x5D}, {0x9D, 0x60}, /* 0x58-0x5B */
 	{0x9E, 0xE0}, {0x9F, 0x15}, {0x9F, 0x2C}, {0x51, 0x33}, /* 0x5C-0x5F */
-	{0x56, 0xA5}, {0x58, 0xDE}, {0x58, 0xDF}, {0x58, 0xE2}, /* 0x60-0x63 */
-	{0x5B, 0xF5}, {0x9F, 0x90}, {0x5E, 0xEC}, {0x61, 0xF2}, /* 0x64-0x67 */
-	{0x61, 0xF7}, {0x61, 0xF6}, {0x61, 0xF5}, {0x65, 0x00}, /* 0x68-0x6B */
+	{0x56, 0xA5}, {0x58, 0xDE}, {0xF9, 0x42}, {0x58, 0xE2}, /* 0x60-0x63 */
+	{0x5B, 0xF5}, {0x9F, 0x90}, {0xF9, 0x82}, {0x61, 0xF2}, /* 0x64-0x67 */
+	{0x61, 0xF7}, {0xF9, 0x0D}, {0x61, 0xF5}, {0x65, 0x00}, /* 0x68-0x6B */
 	{0x65, 0x0F}, {0x66, 0xE0}, {0x66, 0xDD}, {0x6A, 0xE5}, /* 0x6C-0x6F */
-	{0x6A, 0xDD}, {0x6A, 0xDA}, {0x6A, 0xD3}, {0x70, 0x1B}, /* 0x70-0x73 */
+	{0x6A, 0xDD}, {0x6A, 0xDA}, {0xF9, 0x31}, {0x70, 0x1B}, /* 0x70-0x73 */
 	{0x70, 0x1F}, {0x70, 0x28}, {0x70, 0x1A}, {0x70, 0x1D}, /* 0x74-0x77 */
 	{0x70, 0x15}, {0x70, 0x18}, {0x72, 0x06}, {0x72, 0x0D}, /* 0x78-0x7B */
 	{0x72, 0x58}, {0x72, 0xA2}, {0x73, 0x78}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -2368,16 +2370,16 @@
 	{0x00, 0x3F}, {0x73, 0x7A}, {0x74, 0xBD}, {0x74, 0xCA}, /* 0xA0-0xA3 */
 	{0x74, 0xE3}, {0x75, 0x87}, {0x75, 0x86}, {0x76, 0x5F}, /* 0xA4-0xA7 */
 	{0x76, 0x61}, {0x77, 0xC7}, {0x79, 0x19}, {0x79, 0xB1}, /* 0xA8-0xAB */
-	{0x7A, 0x6B}, {0x7A, 0x69}, {0x7C, 0x3E}, {0x7C, 0x3F}, /* 0xAC-0xAF */
+	{0x7A, 0x6B}, {0x7A, 0x69}, {0xF9, 0xA6}, {0x7C, 0x3F}, /* 0xAC-0xAF */
 	{0x7C, 0x38}, {0x7C, 0x3D}, {0x7C, 0x37}, {0x7C, 0x40}, /* 0xB0-0xB3 */
 	{0x7E, 0x6B}, {0x7E, 0x6D}, {0x7E, 0x79}, {0x7E, 0x69}, /* 0xB4-0xB7 */
-	{0x7E, 0x6A}, {0x7F, 0x85}, {0x7E, 0x73}, {0x7F, 0xB6}, /* 0xB8-0xBB */
-	{0x7F, 0xB9}, {0x7F, 0xB8}, {0x81, 0xD8}, {0x85, 0xE9}, /* 0xBC-0xBF */
+	{0x7E, 0x6A}, {0xF9, 0x0F}, {0x7E, 0x73}, {0x7F, 0xB6}, /* 0xB8-0xBB */
+	{0x7F, 0xB9}, {0x7F, 0xB8}, {0xF9, 0x26}, {0x85, 0xE9}, /* 0xBC-0xBF */
 	{0x85, 0xDD}, {0x85, 0xEA}, {0x85, 0xD5}, {0x85, 0xE4}, /* 0xC0-0xC3 */
 	{0x85, 0xE5}, {0x85, 0xF7}, {0x87, 0xFB}, {0x88, 0x05}, /* 0xC4-0xC7 */
 	{0x88, 0x0D}, {0x87, 0xF9}, {0x87, 0xFE}, {0x89, 0x60}, /* 0xC8-0xCB */
 	{0x89, 0x5F}, {0x89, 0x56}, {0x89, 0x5E}, {0x8B, 0x41}, /* 0xCC-0xCF */
-	{0x8B, 0x5C}, {0x8B, 0x58}, {0x8B, 0x49}, {0x8B, 0x5A}, /* 0xD0-0xD3 */
+	{0x8B, 0x5C}, {0xF9, 0xFC}, {0x8B, 0x49}, {0x8B, 0x5A}, /* 0xD0-0xD3 */
 	{0x8B, 0x4E}, {0x8B, 0x4F}, {0x8B, 0x46}, {0x8B, 0x59}, /* 0xD4-0xD7 */
 	{0x8D, 0x08}, {0x8D, 0x0A}, {0x8E, 0x7C}, {0x8E, 0x72}, /* 0xD8-0xDB */
 	{0x8E, 0x87}, {0x8E, 0x76}, {0x8E, 0x6C}, {0x8E, 0x7A}, /* 0xDC-0xDF */
@@ -2388,7 +2390,7 @@
 	{0x93, 0xE2}, {0x93, 0xCD}, {0x93, 0xD8}, {0x93, 0xE4}, /* 0xF0-0xF3 */
 	{0x93, 0xD7}, {0x93, 0xE8}, {0x95, 0xDC}, {0x96, 0xB4}, /* 0xF4-0xF7 */
 	{0x96, 0xE3}, {0x97, 0x2A}, {0x97, 0x27}, {0x97, 0x61}, /* 0xF8-0xFB */
-	{0x97, 0xDC}, {0x97, 0xFB}, {0x98, 0x5E}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x97, 0xDC}, {0x97, 0xFB}, {0xF9, 0xD0}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode c2u_C4[256] = {
@@ -2412,15 +2414,15 @@
 	{0x99, 0x49}, {0x9A, 0x16}, {0x9A, 0x19}, {0x9B, 0x0D}, /* 0x44-0x47 */
 	{0x9B, 0xE8}, {0x9B, 0xE7}, {0x9B, 0xD6}, {0x9B, 0xDB}, /* 0x48-0x4B */
 	{0x9D, 0x89}, {0x9D, 0x61}, {0x9D, 0x72}, {0x9D, 0x6A}, /* 0x4C-0x4F */
-	{0x9D, 0x6C}, {0x9E, 0x92}, {0x9E, 0x97}, {0x9E, 0x93}, /* 0x50-0x53 */
+	{0x9D, 0x6C}, {0x9E, 0x92}, {0xF9, 0x88}, {0x9E, 0x93}, /* 0x50-0x53 */
 	{0x9E, 0xB4}, {0x52, 0xF8}, {0x56, 0xA8}, {0x56, 0xB7}, /* 0x54-0x57 */
 	{0x56, 0xB6}, {0x56, 0xB4}, {0x56, 0xBC}, {0x58, 0xE4}, /* 0x58-0x5B */
 	{0x5B, 0x40}, {0x5B, 0x43}, {0x5B, 0x7D}, {0x5B, 0xF6}, /* 0x5C-0x5F */
 	{0x5D, 0xC9}, {0x61, 0xF8}, {0x61, 0xFA}, {0x65, 0x18}, /* 0x60-0x63 */
 	{0x65, 0x14}, {0x65, 0x19}, {0x66, 0xE6}, {0x67, 0x27}, /* 0x64-0x67 */
 	{0x6A, 0xEC}, {0x70, 0x3E}, {0x70, 0x30}, {0x70, 0x32}, /* 0x68-0x6B */
-	{0x72, 0x10}, {0x73, 0x7B}, {0x74, 0xCF}, {0x76, 0x62}, /* 0x6C-0x6F */
-	{0x76, 0x65}, {0x79, 0x26}, {0x79, 0x2A}, {0x79, 0x2C}, /* 0x70-0x73 */
+	{0xF9, 0x32}, {0x73, 0x7B}, {0x74, 0xCF}, {0x76, 0x62}, /* 0x6C-0x6F */
+	{0x76, 0x65}, {0x79, 0x26}, {0xF9, 0x85}, {0x79, 0x2C}, /* 0x70-0x73 */
 	{0x79, 0x2B}, {0x7A, 0xC7}, {0x7A, 0xF6}, {0x7C, 0x4C}, /* 0x74-0x77 */
 	{0x7C, 0x43}, {0x7C, 0x4D}, {0x7C, 0xEF}, {0x7C, 0xF0}, /* 0x78-0x7B */
 	{0x8F, 0xAE}, {0x7E, 0x7D}, {0x7E, 0x7C}, {0x00, 0x3F}, /* 0x7C-0x7F */
@@ -2435,12 +2437,12 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x7E, 0x82}, {0x7F, 0x4C}, {0x80, 0x00}, /* 0xA0-0xA3 */
 	{0x81, 0xDA}, {0x82, 0x66}, {0x85, 0xFB}, {0x85, 0xF9}, /* 0xA4-0xA7 */
-	{0x86, 0x11}, {0x85, 0xFA}, {0x86, 0x06}, {0x86, 0x0B}, /* 0xA8-0xAB */
+	{0x86, 0x11}, {0xF9, 0xF0}, {0xF9, 0x35}, {0x86, 0x0B}, /* 0xA8-0xAB */
 	{0x86, 0x07}, {0x86, 0x0A}, {0x88, 0x14}, {0x88, 0x15}, /* 0xAC-0xAF */
-	{0x89, 0x64}, {0x89, 0xBA}, {0x89, 0xF8}, {0x8B, 0x70}, /* 0xB0-0xB3 */
+	{0xF9, 0x24}, {0x89, 0xBA}, {0x89, 0xF8}, {0x8B, 0x70}, /* 0xB0-0xB3 */
 	{0x8B, 0x6C}, {0x8B, 0x66}, {0x8B, 0x6F}, {0x8B, 0x5F}, /* 0xB4-0xB7 */
 	{0x8B, 0x6B}, {0x8D, 0x0F}, {0x8D, 0x0D}, {0x8E, 0x89}, /* 0xB8-0xBB */
-	{0x8E, 0x81}, {0x8E, 0x85}, {0x8E, 0x82}, {0x91, 0xB4}, /* 0xBC-0xBF */
+	{0x8E, 0x81}, {0x8E, 0x85}, {0x8E, 0x82}, {0xF9, 0xB7}, /* 0xBC-0xBF */
 	{0x91, 0xCB}, {0x94, 0x18}, {0x94, 0x03}, {0x93, 0xFD}, /* 0xC0-0xC3 */
 	{0x95, 0xE1}, {0x97, 0x30}, {0x98, 0xC4}, {0x99, 0x52}, /* 0xC4-0xC7 */
 	{0x99, 0x51}, {0x99, 0xA8}, {0x9A, 0x2B}, {0x9A, 0x30}, /* 0xC8-0xCB */
@@ -2450,12 +2452,12 @@
 	{0x51, 0x38}, {0x56, 0xC1}, {0x56, 0xC0}, {0x56, 0xC2}, /* 0xD8-0xDB */
 	{0x59, 0x14}, {0x5C, 0x6C}, {0x5D, 0xCD}, {0x61, 0xFC}, /* 0xDC-0xDF */
 	{0x61, 0xFE}, {0x65, 0x1D}, {0x65, 0x1C}, {0x65, 0x95}, /* 0xE0-0xE3 */
-	{0x66, 0xE9}, {0x6A, 0xFB}, {0x6B, 0x04}, {0x6A, 0xFA}, /* 0xE4-0xE7 */
-	{0x6B, 0xB2}, {0x70, 0x4C}, {0x72, 0x1B}, {0x72, 0xA7}, /* 0xE8-0xEB */
-	{0x74, 0xD6}, {0x74, 0xD4}, {0x76, 0x69}, {0x77, 0xD3}, /* 0xEC-0xEF */
+	{0x66, 0xE9}, {0x6A, 0xFB}, {0xF9, 0x1D}, {0x6A, 0xFA}, /* 0xE4-0xE7 */
+	{0x6B, 0xB2}, {0x70, 0x4C}, {0xF9, 0x1E}, {0x72, 0xA7}, /* 0xE8-0xEB */
+	{0x74, 0xD6}, {0x74, 0xD4}, {0xF9, 0x0E}, {0x77, 0xD3}, /* 0xEC-0xEF */
 	{0x7C, 0x50}, {0x7E, 0x8F}, {0x7E, 0x8C}, {0x7F, 0xBC}, /* 0xF0-0xF3 */
-	{0x86, 0x17}, {0x86, 0x2D}, {0x86, 0x1A}, {0x88, 0x23}, /* 0xF4-0xF7 */
-	{0x88, 0x22}, {0x88, 0x21}, {0x88, 0x1F}, {0x89, 0x6A}, /* 0xF8-0xFB */
+	{0x86, 0x17}, {0xF9, 0x1F}, {0x86, 0x1A}, {0x88, 0x23}, /* 0xF4-0xF7 */
+	{0x88, 0x22}, {0x88, 0x21}, {0xF9, 0x27}, {0x89, 0x6A}, /* 0xF8-0xFB */
 	{0x89, 0x6C}, {0x89, 0xBD}, {0x8B, 0x74}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -2480,11 +2482,11 @@
 	{0x8E, 0x8D}, {0x8E, 0x8B}, {0x8F, 0x5F}, {0x8F, 0xAF}, /* 0x44-0x47 */
 	{0x91, 0xBA}, {0x94, 0x2E}, {0x94, 0x33}, {0x94, 0x35}, /* 0x48-0x4B */
 	{0x94, 0x3A}, {0x94, 0x38}, {0x94, 0x32}, {0x94, 0x2B}, /* 0x4C-0x4F */
-	{0x95, 0xE2}, {0x97, 0x38}, {0x97, 0x39}, {0x97, 0x32}, /* 0x50-0x53 */
+	{0x95, 0xE2}, {0x97, 0x38}, {0x97, 0x39}, {0xF9, 0x38}, /* 0x50-0x53 */
 	{0x97, 0xFF}, {0x98, 0x67}, {0x98, 0x65}, {0x99, 0x57}, /* 0x54-0x57 */
 	{0x9A, 0x45}, {0x9A, 0x43}, {0x9A, 0x40}, {0x9A, 0x3E}, /* 0x58-0x5B */
 	{0x9A, 0xCF}, {0x9B, 0x54}, {0x9B, 0x51}, {0x9C, 0x2D}, /* 0x5C-0x5F */
-	{0x9C, 0x25}, {0x9D, 0xAF}, {0x9D, 0xB4}, {0x9D, 0xC2}, /* 0x60-0x63 */
+	{0x9C, 0x25}, {0x9D, 0xAF}, {0xFA, 0x2D}, {0x9D, 0xC2}, /* 0x60-0x63 */
 	{0x9D, 0xB8}, {0x9E, 0x9D}, {0x9E, 0xEF}, {0x9F, 0x19}, /* 0x64-0x67 */
 	{0x9F, 0x5C}, {0x9F, 0x66}, {0x9F, 0x67}, {0x51, 0x3C}, /* 0x68-0x6B */
 	{0x51, 0x3B}, {0x56, 0xC8}, {0x56, 0xCA}, {0x56, 0xC9}, /* 0x6C-0x6F */
@@ -2501,9 +2503,9 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x94-0x97 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
-	{0x00, 0x3F}, {0x79, 0xB3}, {0x7C, 0x60}, {0x7C, 0x5F}, /* 0xA0-0xA3 */
-	{0x80, 0x7E}, {0x80, 0x7D}, {0x81, 0xDF}, {0x89, 0x72}, /* 0xA4-0xA7 */
-	{0x89, 0x6F}, {0x89, 0xFC}, {0x8B, 0x80}, {0x8D, 0x16}, /* 0xA8-0xAB */
+	{0x00, 0x3F}, {0x79, 0xB3}, {0xF9, 0x44}, {0x7C, 0x5F}, /* 0xA0-0xA3 */
+	{0xF9, 0x45}, {0x80, 0x7D}, {0x81, 0xDF}, {0x89, 0x72}, /* 0xA4-0xA7 */
+	{0x89, 0x6F}, {0x89, 0xFC}, {0xF9, 0x5A}, {0x8D, 0x16}, /* 0xA8-0xAB */
 	{0x8D, 0x17}, {0x8E, 0x91}, {0x8E, 0x93}, {0x8F, 0x61}, /* 0xAC-0xAF */
 	{0x91, 0x48}, {0x94, 0x44}, {0x94, 0x51}, {0x94, 0x52}, /* 0xB0-0xB3 */
 	{0x97, 0x3D}, {0x97, 0x3E}, {0x97, 0xC3}, {0x97, 0xC1}, /* 0xB4-0xB7 */
@@ -2511,16 +2513,16 @@
 	{0x9A, 0xD2}, {0x9B, 0x1A}, {0x9C, 0x49}, {0x9C, 0x31}, /* 0xBC-0xBF */
 	{0x9C, 0x3E}, {0x9C, 0x3B}, {0x9D, 0xD3}, {0x9D, 0xD7}, /* 0xC0-0xC3 */
 	{0x9F, 0x34}, {0x9F, 0x6C}, {0x9F, 0x6A}, {0x9F, 0x94}, /* 0xC4-0xC7 */
-	{0x56, 0xCC}, {0x5D, 0xD6}, {0x62, 0x00}, {0x65, 0x23}, /* 0xC8-0xCB */
+	{0x56, 0xCC}, {0x5D, 0xD6}, {0xF9, 0x90}, {0x65, 0x23}, /* 0xC8-0xCB */
 	{0x65, 0x2B}, {0x65, 0x2A}, {0x66, 0xEC}, {0x6B, 0x10}, /* 0xCC-0xCF */
 	{0x74, 0xDA}, {0x7A, 0xCA}, {0x7C, 0x64}, {0x7C, 0x63}, /* 0xD0-0xD3 */
 	{0x7C, 0x65}, {0x7E, 0x93}, {0x7E, 0x96}, {0x7E, 0x94}, /* 0xD4-0xD7 */
-	{0x81, 0xE2}, {0x86, 0x38}, {0x86, 0x3F}, {0x88, 0x31}, /* 0xD8-0xDB */
-	{0x8B, 0x8A}, {0x90, 0x90}, {0x90, 0x8F}, {0x94, 0x63}, /* 0xDC-0xDF */
+	{0x81, 0xE2}, {0x86, 0x38}, {0xF9, 0x10}, {0x88, 0x31}, /* 0xD8-0xDB */
+	{0x8B, 0x8A}, {0x90, 0x90}, {0xF9, 0x13}, {0x94, 0x63}, /* 0xDC-0xDF */
 	{0x94, 0x60}, {0x94, 0x64}, {0x97, 0x68}, {0x98, 0x6F}, /* 0xE0-0xE3 */
 	{0x99, 0x5C}, {0x9A, 0x5A}, {0x9A, 0x5B}, {0x9A, 0x57}, /* 0xE4-0xE7 */
 	{0x9A, 0xD3}, {0x9A, 0xD4}, {0x9A, 0xD1}, {0x9C, 0x54}, /* 0xE8-0xEB */
-	{0x9C, 0x57}, {0x9C, 0x56}, {0x9D, 0xE5}, {0x9E, 0x9F}, /* 0xEC-0xEF */
+	{0xF9, 0xF2}, {0x9C, 0x56}, {0x9D, 0xE5}, {0xF9, 0xF3}, /* 0xEC-0xEF */
 	{0x9E, 0xF4}, {0x56, 0xD1}, {0x58, 0xE9}, {0x65, 0x2C}, /* 0xF0-0xF3 */
 	{0x70, 0x5E}, {0x76, 0x71}, {0x76, 0x72}, {0x77, 0xD7}, /* 0xF4-0xF7 */
 	{0x7F, 0x50}, {0x7F, 0x88}, {0x88, 0x36}, {0x88, 0x39}, /* 0xF8-0xFB */
@@ -2545,9 +2547,9 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x38-0x3B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x3C-0x3F */
 	{0x8B, 0x96}, {0x82, 0x77}, {0x8D, 0x1B}, {0x91, 0xC0}, /* 0x40-0x43 */
-	{0x94, 0x6A}, {0x97, 0x42}, {0x97, 0x48}, {0x97, 0x44}, /* 0x44-0x47 */
+	{0x94, 0x6A}, {0x97, 0x42}, {0xF9, 0xB3}, {0x97, 0x44}, /* 0x44-0x47 */
 	{0x97, 0xC6}, {0x98, 0x70}, {0x9A, 0x5F}, {0x9B, 0x22}, /* 0x48-0x4B */
-	{0x9B, 0x58}, {0x9C, 0x5F}, {0x9D, 0xF9}, {0x9D, 0xFA}, /* 0x4C-0x4F */
+	{0x9B, 0x58}, {0x9C, 0x5F}, {0x9D, 0xF9}, {0xF9, 0x3A}, /* 0x4C-0x4F */
 	{0x9E, 0x7C}, {0x9E, 0x7D}, {0x9F, 0x07}, {0x9F, 0x77}, /* 0x50-0x53 */
 	{0x9F, 0x72}, {0x5E, 0xF3}, {0x6B, 0x16}, {0x70, 0x63}, /* 0x54-0x57 */
 	{0x7C, 0x6C}, {0x7C, 0x6E}, {0x88, 0x3B}, {0x89, 0xC0}, /* 0x58-0x5B */
@@ -2558,8 +2560,8 @@
 	{0x7E, 0x9C}, {0x8B, 0x9C}, {0x8E, 0xAA}, {0x91, 0xC5}, /* 0x6C-0x6F */
 	{0x94, 0x7D}, {0x94, 0x7E}, {0x94, 0x7C}, {0x9C, 0x77}, /* 0x70-0x73 */
 	{0x9C, 0x78}, {0x9E, 0xF7}, {0x8C, 0x54}, {0x94, 0x7F}, /* 0x74-0x77 */
-	{0x9E, 0x1A}, {0x72, 0x28}, {0x9A, 0x6A}, {0x9B, 0x31}, /* 0x78-0x7B */
-	{0x9E, 0x1B}, {0x9E, 0x1E}, {0x7C, 0x72}, {0x00, 0x3F}, /* 0x7C-0x7F */
+	{0x9E, 0x1A}, {0x72, 0x28}, {0xF9, 0x87}, {0x9B, 0x31}, /* 0x78-0x7B */
+	{0x9E, 0x1B}, {0xF9, 0x20}, {0x7C, 0x72}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x80-0x83 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x84-0x87 */
@@ -2793,7 +2795,7 @@
 	{0x54, 0x65}, {0x54, 0x6C}, {0x54, 0x74}, {0x54, 0x66}, /* 0xE4-0xE7 */
 	{0x54, 0x8D}, {0x54, 0x6F}, {0x54, 0x61}, {0x54, 0x60}, /* 0xE8-0xEB */
 	{0x54, 0x98}, {0x54, 0x63}, {0x54, 0x67}, {0x54, 0x64}, /* 0xEC-0xEF */
-	{0x56, 0xF7}, {0x56, 0xF9}, {0x57, 0x6F}, {0x57, 0x72}, /* 0xF0-0xF3 */
+	{0x56, 0xF7}, {0xF9, 0xA9}, {0x57, 0x6F}, {0x57, 0x72}, /* 0xF0-0xF3 */
 	{0x57, 0x6D}, {0x57, 0x6B}, {0x57, 0x71}, {0x57, 0x70}, /* 0xF4-0xF7 */
 	{0x57, 0x76}, {0x57, 0x80}, {0x57, 0x75}, {0x57, 0x7B}, /* 0xF8-0xFB */
 	{0x57, 0x73}, {0x57, 0x74}, {0x57, 0x62}, {0x00, 0x3F}, /* 0xFC-0xFF */
@@ -2845,7 +2847,7 @@
 	{0x60, 0x33}, {0x60, 0x1A}, {0x60, 0x1E}, {0x60, 0x2C}, /* 0xA4-0xA7 */
 	{0x60, 0x22}, {0x60, 0x0D}, {0x60, 0x10}, {0x60, 0x2E}, /* 0xA8-0xAB */
 	{0x60, 0x13}, {0x60, 0x11}, {0x60, 0x0C}, {0x60, 0x09}, /* 0xAC-0xAF */
-	{0x60, 0x1C}, {0x62, 0x14}, {0x62, 0x3D}, {0x62, 0xAD}, /* 0xB0-0xB3 */
+	{0xF9, 0xAC}, {0x62, 0x14}, {0x62, 0x3D}, {0x62, 0xAD}, /* 0xB0-0xB3 */
 	{0x62, 0xB4}, {0x62, 0xD1}, {0x62, 0xBE}, {0x62, 0xAA}, /* 0xB4-0xB7 */
 	{0x62, 0xB6}, {0x62, 0xCA}, {0x62, 0xAE}, {0x62, 0xB3}, /* 0xB8-0xBB */
 	{0x62, 0xAF}, {0x62, 0xBB}, {0x62, 0xA9}, {0x62, 0xB0}, /* 0xBC-0xBF */
@@ -2855,7 +2857,7 @@
 	{0x66, 0x0D}, {0x66, 0x05}, {0x65, 0xFD}, {0x66, 0x11}, /* 0xCC-0xCF */
 	{0x66, 0x10}, {0x66, 0xF6}, {0x67, 0x0A}, {0x67, 0x85}, /* 0xD0-0xD3 */
 	{0x67, 0x6C}, {0x67, 0x8E}, {0x67, 0x92}, {0x67, 0x76}, /* 0xD4-0xD7 */
-	{0x67, 0x7B}, {0x67, 0x98}, {0x67, 0x86}, {0x67, 0x84}, /* 0xD8-0xDB */
+	{0xF9, 0xC8}, {0x67, 0x98}, {0x67, 0x86}, {0x67, 0x84}, /* 0xD8-0xDB */
 	{0x67, 0x74}, {0x67, 0x8D}, {0x67, 0x8C}, {0x67, 0x7A}, /* 0xDC-0xDF */
 	{0x67, 0x9F}, {0x67, 0x91}, {0x67, 0x99}, {0x67, 0x83}, /* 0xE0-0xE3 */
 	{0x67, 0x7D}, {0x67, 0x81}, {0x67, 0x78}, {0x67, 0x79}, /* 0xE4-0xE7 */
@@ -2990,7 +2992,7 @@
 	{0x60, 0x5B}, {0x60, 0x4C}, {0x60, 0x40}, {0x60, 0x42}, /* 0xC8-0xCB */
 	{0x60, 0x5F}, {0x60, 0x24}, {0x60, 0x44}, {0x60, 0x58}, /* 0xCC-0xCF */
 	{0x60, 0x66}, {0x60, 0x6E}, {0x62, 0x42}, {0x62, 0x43}, /* 0xD0-0xD3 */
-	{0x62, 0xCF}, {0x63, 0x0D}, {0x63, 0x0B}, {0x62, 0xF5}, /* 0xD4-0xD7 */
+	{0xF9, 0x5B}, {0x63, 0x0D}, {0x63, 0x0B}, {0x62, 0xF5}, /* 0xD4-0xD7 */
 	{0x63, 0x0E}, {0x63, 0x03}, {0x62, 0xEB}, {0x62, 0xF9}, /* 0xD8-0xDB */
 	{0x63, 0x0F}, {0x63, 0x0C}, {0x62, 0xF8}, {0x62, 0xF6}, /* 0xDC-0xDF */
 	{0x63, 0x00}, {0x63, 0x13}, {0x63, 0x14}, {0x62, 0xFA}, /* 0xE0-0xE3 */
@@ -3849,7 +3851,7 @@
 	{0x83, 0xC6}, {0x83, 0xC8}, {0x83, 0xEB}, {0x83, 0xE3}, /* 0x68-0x6B */
 	{0x83, 0xBF}, {0x84, 0x01}, {0x83, 0xDD}, {0x83, 0xE5}, /* 0x6C-0x6F */
 	{0x83, 0xD8}, {0x83, 0xFF}, {0x83, 0xE1}, {0x83, 0xCB}, /* 0x70-0x73 */
-	{0x83, 0xCE}, {0x83, 0xD6}, {0x83, 0xF5}, {0x83, 0xC9}, /* 0x74-0x77 */
+	{0x83, 0xCE}, {0x83, 0xD6}, {0x83, 0xF5}, {0xF9, 0x3E}, /* 0x74-0x77 */
 	{0x84, 0x09}, {0x84, 0x0F}, {0x83, 0xDE}, {0x84, 0x11}, /* 0x78-0x7B */
 	{0x84, 0x06}, {0x83, 0xC2}, {0x83, 0xF3}, {0x00, 0x3F}, /* 0x7C-0x7F */
 	
@@ -4609,7 +4611,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x94-0x97 */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x98-0x9B */
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
-	{0x00, 0x3F}, {0x73, 0x62}, {0x74, 0x87}, {0x74, 0x89}, /* 0xA0-0xA3 */
+	{0x00, 0x3F}, {0x73, 0x62}, {0x74, 0x87}, {0xF9, 0x94}, /* 0xA0-0xA3 */
 	{0x74, 0x8A}, {0x74, 0x86}, {0x74, 0x81}, {0x74, 0x7D}, /* 0xA4-0xA7 */
 	{0x74, 0x85}, {0x74, 0x88}, {0x74, 0x7C}, {0x74, 0x79}, /* 0xA8-0xAB */
 	{0x75, 0x08}, {0x75, 0x07}, {0x75, 0x7E}, {0x76, 0x25}, /* 0xAC-0xAF */
@@ -4661,7 +4663,7 @@
 	{0x84, 0xFB}, {0x85, 0x2B}, {0x84, 0xFA}, {0x85, 0x08}, /* 0x58-0x5B */
 	{0x85, 0x0C}, {0x84, 0xF4}, {0x85, 0x2A}, {0x84, 0xF2}, /* 0x5C-0x5F */
 	{0x85, 0x15}, {0x84, 0xF7}, {0x84, 0xEB}, {0x84, 0xF3}, /* 0x60-0x63 */
-	{0x84, 0xFC}, {0x85, 0x12}, {0x84, 0xEA}, {0x84, 0xE9}, /* 0x64-0x67 */
+	{0xF9, 0xC2}, {0x85, 0x12}, {0x84, 0xEA}, {0x84, 0xE9}, /* 0x64-0x67 */
 	{0x85, 0x16}, {0x84, 0xFE}, {0x85, 0x28}, {0x85, 0x1D}, /* 0x68-0x6B */
 	{0x85, 0x2E}, {0x85, 0x02}, {0x84, 0xFD}, {0x85, 0x1E}, /* 0x6C-0x6F */
 	{0x84, 0xF6}, {0x85, 0x31}, {0x85, 0x26}, {0x84, 0xE7}, /* 0x70-0x73 */
@@ -4767,7 +4769,7 @@
 	{0x9C, 0xFB}, {0x9D, 0x08}, {0x9D, 0x05}, {0x9D, 0x04}, /* 0xEC-0xEF */
 	{0x9E, 0x83}, {0x9E, 0xD3}, {0x9F, 0x0F}, {0x9F, 0x10}, /* 0xF0-0xF3 */
 	{0x51, 0x1C}, {0x51, 0x13}, {0x51, 0x17}, {0x51, 0x1A}, /* 0xF4-0xF7 */
-	{0x51, 0x11}, {0x51, 0xDE}, {0x53, 0x34}, {0x53, 0xE1}, /* 0xF8-0xFB */
+	{0x51, 0x11}, {0xFA, 0x15}, {0x53, 0x34}, {0x53, 0xE1}, /* 0xF8-0xFB */
 	{0x56, 0x70}, {0x56, 0x60}, {0x56, 0x6E}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
@@ -5087,7 +5089,7 @@
 	{0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0x9C-0x9F */
 	{0x00, 0x3F}, {0x77, 0xB4}, {0x77, 0xB1}, {0x77, 0xA8}, /* 0xA0-0xA3 */
 	{0x77, 0xF0}, {0x78, 0xF3}, {0x78, 0xFD}, {0x79, 0x02}, /* 0xA4-0xA7 */
-	{0x78, 0xFB}, {0x78, 0xFC}, {0x78, 0xF2}, {0x79, 0x05}, /* 0xA8-0xAB */
+	{0xF9, 0x64}, {0x78, 0xFC}, {0x78, 0xF2}, {0x79, 0x05}, /* 0xA8-0xAB */
 	{0x78, 0xF9}, {0x78, 0xFE}, {0x79, 0x04}, {0x79, 0xAB}, /* 0xAC-0xAF */
 	{0x79, 0xA8}, {0x7A, 0x5C}, {0x7A, 0x5B}, {0x7A, 0x56}, /* 0xB0-0xB3 */
 	{0x7A, 0x58}, {0x7A, 0x54}, {0x7A, 0x5A}, {0x7A, 0xBE}, /* 0xB4-0xB7 */
@@ -5749,7 +5751,7 @@
 	{0x8B, 0x82}, {0x8B, 0x86}, {0x8B, 0x85}, {0x8B, 0x7F}, /* 0x58-0x5B */
 	{0x8D, 0x15}, {0x8E, 0x95}, {0x8E, 0x94}, {0x8E, 0x9A}, /* 0x5C-0x5F */
 	{0x8E, 0x92}, {0x8E, 0x90}, {0x8E, 0x96}, {0x8E, 0x97}, /* 0x60-0x63 */
-	{0x8F, 0x60}, {0x8F, 0x62}, {0x91, 0x47}, {0x94, 0x4C}, /* 0x64-0x67 */
+	{0x8F, 0x60}, {0xF9, 0x8D}, {0x91, 0x47}, {0x94, 0x4C}, /* 0x64-0x67 */
 	{0x94, 0x50}, {0x94, 0x4A}, {0x94, 0x4B}, {0x94, 0x4F}, /* 0x68-0x6B */
 	{0x94, 0x47}, {0x94, 0x45}, {0x94, 0x48}, {0x94, 0x49}, /* 0x6C-0x6F */
 	{0x94, 0x46}, {0x97, 0x3F}, {0x97, 0xE3}, {0x98, 0x6A}, /* 0x70-0x73 */
@@ -5923,8 +5925,8 @@
 	{0x25, 0x58}, {0x25, 0x67}, {0x25, 0x5B}, {0x25, 0x53}, /* 0xEC-0xEF */
 	{0x25, 0x65}, {0x25, 0x56}, {0x25, 0x5F}, {0x25, 0x6B}, /* 0xF0-0xF3 */
 	{0x25, 0x62}, {0x25, 0x59}, {0x25, 0x68}, {0x25, 0x5C}, /* 0xF4-0xF7 */
-	{0x25, 0x51}, {0x25, 0x50}, {0x25, 0x6D}, {0x25, 0x6E}, /* 0xF8-0xFB */
-	{0x25, 0x70}, {0x25, 0x6F}, {0x25, 0x93}, {0x00, 0x3F}, /* 0xFC-0xFF */
+	{0x25, 0x51}, {0x25, 0x50}, {0x00, 0x3F}, {0x00, 0x3F}, /* 0xF8-0xFB */
+	{0x00, 0x3F}, {0x00, 0x3F}, {0x25, 0x93}, {0x00, 0x3F}, /* 0xFC-0xFF */
 };
 
 static struct nls_unicode *page_charset2uni[256] = {
@@ -6032,7 +6034,7 @@
 
 static unsigned char u2c_03[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xA1, 0xC2, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
@@ -6104,17 +6106,17 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0x56, /* 0x10-0x13 */
-	0xA1, 0x58, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0xA1, 0x58, 0xA2, 0x77, 0xA1, 0xFC, 0x3F, 0x3F, /* 0x14-0x17 */
 	0xA1, 0xA5, 0xA1, 0xA6, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0xA1, 0xA7, 0xA1, 0xA8, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0xA1, 0x4C, 0xA1, 0x4B, 0xA1, 0x45, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0x45, 0x3F, 0x3F, /* 0x20-0x23 */
+	0xA3, 0xBB, 0xA1, 0x4C, 0xA1, 0x4B, 0xA1, 0x45, /* 0x24-0x27 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xAC, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xAC, 0xA1, 0xB2, /* 0x30-0x33 */
 	0x3F, 0x3F, 0xA1, 0xAB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xB0, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xC3, 0x3F, 0x3F, /* 0x3C-0x3F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
@@ -6240,8 +6242,8 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
-	0x3F, 0x3F, 0xA2, 0x41, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xD4, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0xA2, 0x41, 0xA2, 0x42, 0x3F, 0x3F, /* 0x14-0x17 */
+	0xA2, 0x58, 0x3F, 0x3F, 0xA1, 0xD4, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xDB, 0xA1, 0xE8, /* 0x1C-0x1F */
 	0xA1, 0xE7, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xFD, /* 0x20-0x23 */
 	0x3F, 0x3F, 0xA1, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
@@ -6259,7 +6261,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
-	0xA1, 0xDA, 0xA1, 0xDD, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0xA1, 0xDA, 0xA1, 0xDD, 0x3F, 0x3F, 0xA1, 0xDD, /* 0x60-0x63 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xD8, 0xA1, 0xD9, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
@@ -6302,6 +6304,74 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
+static unsigned char u2c_23[512] = {
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0x5B, /* 0x04-0x07 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+};
+
 static unsigned char u2c_25[512] = {
 	0xA2, 0x77, 0x3F, 0x3F, 0xA2, 0x78, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
@@ -6330,8 +6400,8 @@
 	0xF9, 0xE0, 0xF9, 0xEB, 0xF9, 0xF4, 0xF9, 0xE2, /* 0x60-0x63 */
 	0xF9, 0xE7, 0xF9, 0xF0, 0xF9, 0xDE, 0xF9, 0xED, /* 0x64-0x67 */
 	0xF9, 0xF6, 0xF9, 0xE4, 0xF9, 0xEA, 0xF9, 0xF3, /* 0x68-0x6B */
-	0xF9, 0xE1, 0xF9, 0xFA, 0xF9, 0xFB, 0xF9, 0xFD, /* 0x6C-0x6F */
-	0xF9, 0xFC, 0xA2, 0xAC, 0xA2, 0xAD, 0xA2, 0xAE, /* 0x70-0x73 */
+	0xF9, 0xE1, 0xA2, 0x7E, 0xA2, 0xA1, 0xA2, 0xA3, /* 0x6C-0x6F */
+	0xA2, 0xA2, 0xA2, 0xAC, 0xA2, 0xAD, 0xA2, 0xAE, /* 0x70-0x73 */
 	0xA1, 0x5A, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
@@ -6373,7 +6443,7 @@
 static unsigned char u2c_26[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0xA1, 0xB9, 0xA1, 0xB8, 0x3F, 0x3F, /* 0x04-0x07 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
+	0x3F, 0x3F, 0xA1, 0xF3, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
@@ -6387,7 +6457,7 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0xA1, 0xF0, 0x3F, 0x3F, 0xA1, 0xF1, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xA1, 0xF0, 0xA1, 0xF2, 0xA1, 0xF1, 0x3F, 0x3F, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
@@ -6446,12 +6516,12 @@
 	0xA1, 0x69, 0xA1, 0x6A, 0xA2, 0x45, 0x3F, 0x3F, /* 0x10-0x13 */
 	0xA1, 0x65, 0xA1, 0x66, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
-	0x3F, 0x3F, 0xA1, 0xA9, 0xA1, 0xAA, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0xA1, 0xE3, 0xA1, 0xA9, 0xA1, 0xAA, 0x3F, 0x3F, /* 0x1C-0x1F */
 	0x3F, 0x3F, 0xA2, 0xC3, 0xA2, 0xC4, 0xA2, 0xC5, /* 0x20-0x23 */
 	0xA2, 0xC6, 0xA2, 0xC7, 0xA2, 0xC8, 0xA2, 0xC9, /* 0x24-0x27 */
 	0xA2, 0xCA, 0xA2, 0xCB, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0xA1, 0xCA, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
@@ -6544,10 +6614,10 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xA4, 0x40, 0xA4, 0x47, /* 0x90-0x93 */
+	0xA4, 0x54, 0xA5, 0x7C, 0xA4, 0x57, 0xA4, 0xA4, /* 0x94-0x97 */
+	0xA4, 0x55, 0xA5, 0xD2, 0xA4, 0x41, 0xA4, 0xFE, /* 0x98-0x9B */
+	0xA4, 0x42, 0xA4, 0xD1, 0xA6, 0x61, 0xA4, 0x48, /* 0x9C-0x9F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
@@ -6583,15 +6653,15 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x1C-0x1F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x20-0x23 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x24-0x27 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x28-0x2B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0xA4, 0x40, 0xA4, 0x47, 0xA4, 0x54, 0xA5, 0x7C, /* 0x20-0x23 */
+	0xA4, 0xAD, 0xA4, 0xBB, 0xA4, 0x43, 0xA4, 0x4B, /* 0x24-0x27 */
+	0xA4, 0x45, 0xA4, 0x51, 0xA4, 0xEB, 0xA4, 0xF5, /* 0x28-0x2B */
+	0xA4, 0xF4, 0xA4, 0xEC, 0xAA, 0xF7, 0xA4, 0x67, /* 0x2C-0x2F */
+	0xA4, 0xE9, 0xAE, 0xE8, 0xA6, 0xB3, 0xAA, 0xC0, /* 0x30-0x33 */
+	0xA6, 0x57, 0xAF, 0x53, 0xB0, 0x5D, 0xAF, 0xAC, /* 0x34-0x37 */
+	0xB3, 0xD2, 0xA5, 0x4E, 0xA9, 0x49, 0xBE, 0xC7, /* 0x38-0x3B */
+	0xBA, 0xCA, 0xA5, 0xF8, 0xB8, 0xEA, 0xA8, 0xF3, /* 0x3C-0x3F */
+	0xB2, 0xBD, 0xA5, 0xF0, 0xA6, 0xDB, 0xA6, 0xDC, /* 0x40-0x43 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
@@ -6608,19 +6678,19 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
 	
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xC0, /* 0xA0-0xA3 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0xA4, 0x40, 0xA4, 0x47, 0xA4, 0x54, 0xA5, 0x7C, /* 0x80-0x83 */
+	0xA4, 0xAD, 0xA4, 0xBB, 0xA4, 0x43, 0xA4, 0x4B, /* 0x84-0x87 */
+	0xA4, 0x45, 0xA4, 0x51, 0xA4, 0xEB, 0xA4, 0xF5, /* 0x88-0x8B */
+	0xA4, 0xF4, 0xA4, 0xEC, 0xAA, 0xF7, 0xA4, 0x67, /* 0x8C-0x8F */
+	0xA4, 0xE9, 0xAE, 0xE8, 0xA6, 0xB3, 0xAA, 0xC0, /* 0x90-0x93 */
+	0xA6, 0x57, 0xAF, 0x53, 0xB0, 0x5D, 0xAF, 0xAC, /* 0x94-0x97 */
+	0xB3, 0xD2, 0xAF, 0xB5, 0xA8, 0x6B, 0xA4, 0x6B, /* 0x98-0x9B */
+	0xBE, 0x41, 0xC0, 0x75, 0xA6, 0x4C, 0xAA, 0x60, /* 0x9C-0x9F */
+	0xB6, 0xB5, 0xA5, 0xF0, 0xBC, 0x67, 0xA1, 0xC0, /* 0xA0-0xA3 */
+	0xA4, 0x57, 0xA4, 0xA4, 0xA4, 0x55, 0xA5, 0xAA, /* 0xA4-0xA7 */
+	0xA5, 0x6B, 0xC2, 0xE5, 0xA9, 0x76, 0xBE, 0xC7, /* 0xA8-0xAB */
+	0xBA, 0xCA, 0xA5, 0xF8, 0xB8, 0xEA, 0xA8, 0xF3, /* 0xAC-0xAF */
+	0xA9, 0x5D, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
@@ -12286,11 +12356,11 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
-static unsigned char u2c_FA[512] = {
+static unsigned char u2c_DC[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x08-0x0B */
-	0xC9, 0x4A, 0xDD, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x10-0x13 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x14-0x17 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x18-0x1B */
@@ -12354,6 +12424,142 @@
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
 };
 
+static unsigned char u2c_F9[512] = {
+	0xB0, 0x5A, 0xA7, 0xF3, 0xA8, 0xAE, 0xB8, 0xEB, /* 0x00-0x03 */
+	0xB7, 0xC6, 0xA6, 0xEA, 0xA5, 0x79, 0xC0, 0x74, /* 0x04-0x07 */
+	0xC0, 0x74, 0xAB, 0xB4, 0xAA, 0xF7, 0xB3, 0xE2, /* 0x08-0x0B */
+	0xA9, 0x60, 0xC3, 0x69, 0xC4, 0xEE, 0xC3, 0xB9, /* 0x0C-0x0F */
+	0xC5, 0xDA, 0xC1, 0xB3, 0xBB, 0x72, 0xC5, 0xDE, /* 0x10-0x13 */
+	0xBC, 0xD6, 0xAC, 0xA5, 0xAF, 0x4F, 0xAF, 0x5F, /* 0x14-0x17 */
+	0xB8, 0xA8, 0xB9, 0x54, 0xC0, 0x64, 0xB6, 0xC3, /* 0x18-0x1B */
+	0xA7, 0x5A, 0xC4, 0xE6, 0xC4, 0xEA, 0xC4, 0xF5, /* 0x1C-0x1F */
+	0xC6, 0x7D, 0xB4, 0x50, 0xC0, 0xDD, 0xC2, 0xC5, /* 0x20-0x23 */
+	0xC4, 0xB0, 0xA9, 0xD4, 0xC3, 0xBE, 0xC4, 0xFA, /* 0x24-0x27 */
+	0xB4, 0x59, 0xAE, 0xD4, 0xAE, 0xF6, 0xAF, 0x54, /* 0x28-0x2B */
+	0x3F, 0x3F, 0xA8, 0xD3, 0xA7, 0x4E, 0xB3, 0xD2, /* 0x2C-0x2F */
+	0xBE, 0xDB, 0xC3, 0x72, 0xC4, 0x6C, 0xBF, 0x63, /* 0x30-0x33 */
+	0xA6, 0xD1, 0xC4, 0xAA, 0xB8, 0xB8, 0xB8, 0xF4, /* 0x34-0x37 */
+	0xC5, 0x53, 0xBE, 0x7C, 0xC6, 0x4F, 0xB8, 0x4C, /* 0x38-0x3B */
+	0xB8, 0x53, 0xBA, 0xF1, 0xDB, 0x77, 0xBF, 0xFD, /* 0x3C-0x3F */
+	0xB3, 0xC0, 0xBD, 0xD7, 0xC3, 0x62, 0xA7, 0xCB, /* 0x40-0x43 */
+	0xC5, 0xA2, 0xC5, 0xA4, 0xA8, 0x63, 0xBD, 0x55, /* 0x44-0x47 */
+	0xB8, 0xEF, 0xB9, 0x70, 0xC2, 0x53, 0xB9, 0xF0, /* 0x48-0x4B */
+	0xBC, 0xD3, 0xB2, 0x5C, 0xBA, 0x7C, 0xB2, 0xD6, /* 0x4C-0x4F */
+	0xC1, 0x5C, 0xAD, 0xAE, 0xB0, 0xC7, 0xA6, 0xD8, /* 0x50-0x53 */
+	0xBB, 0xFE, 0xAD, 0xE2, 0xB8, 0x57, 0xBA, 0xF0, /* 0x54-0x57 */
+	0xB5, 0xD9, 0xB3, 0xAE, 0xC5, 0xAA, 0xCE, 0xD4, /* 0x58-0x5B */
+	0xBC, 0xD6, 0xBF, 0xD5, 0xA4, 0xA6, 0xB9, 0xE7, /* 0x5C-0x5F */
+	0xAB, 0xE3, 0xB2, 0x76, 0xB2, 0xA7, 0xA5, 0x5F, /* 0x60-0x63 */
+	0xED, 0xA8, 0xAB, 0x4B, 0xB4, 0x5F, 0xA4, 0xA3, /* 0x64-0x67 */
+	0xAA, 0x63, 0xBC, 0xC6, 0xAF, 0xC1, 0xB0, 0xD1, /* 0x68-0x6B */
+	0xB6, 0xEB, 0xAC, 0xD9, 0xB8, 0xAD, 0xBB, 0xA1, /* 0x6C-0x6F */
+	0xB1, 0xFE, 0xA8, 0xB0, 0xA8, 0x48, 0xAC, 0x42, /* 0x70-0x73 */
+	0xAD, 0x59, 0xB1, 0xB0, 0xB2, 0xA4, 0xAB, 0x47, /* 0x74-0x77 */
+	0xA8, 0xE2, 0x3F, 0x3F, 0xB1, 0xE7, 0xC2, 0xB3, /* 0x78-0x7B */
+	0xA8, 0x7D, 0xBD, 0xCC, 0xB6, 0x71, 0xC0, 0x79, /* 0x7C-0x7F */
+	
+	0xA7, 0x66, 0xA4, 0x6B, 0xC3, 0x66, 0xAE, 0xC8, /* 0x80-0x83 */
+	0xC2, 0x6F, 0xC4, 0x72, 0xBE, 0x5B, 0xC6, 0x7A, /* 0x84-0x87 */
+	0xC4, 0x52, 0xBE, 0xA4, 0xA4, 0x4F, 0xBE, 0xE4, /* 0x88-0x8B */
+	0xBE, 0xFA, 0xF7, 0x65, 0xA6, 0x7E, 0xBC, 0xA6, /* 0x8C-0x8F */
+	0xC5, 0xCA, 0xBC, 0xBF, 0xBA, 0xA7, 0xB7, 0xD2, /* 0x90-0x93 */
+	0xE6, 0xA3, 0x3F, 0x3F, 0xBD, 0x6D, 0xC1, 0x70, /* 0x94-0x97 */
+	0xBD, 0xFB, 0xBD, 0xAC, 0xB3, 0x73, 0xC1, 0xE5, /* 0x98-0x9B */
+	0xA6, 0x43, 0xA6, 0x48, 0xAB, 0x7C, 0xAF, 0x50, /* 0x9C-0x9F */
+	0xB5, 0xF5, 0xBB, 0xA1, 0xB7, 0x47, 0xA9, 0xC0, /* 0xA0-0xA3 */
+	0xB1, 0xC9, 0xC0, 0xD4, 0xC3, 0xAE, 0xC2, 0x79, /* 0xA4-0xA7 */
+	0xA5, 0x4F, 0xCB, 0xF1, 0xB9, 0xE7, 0xC0, 0xAD, /* 0xA8-0xAB */
+	0xCC, 0xB0, 0xAC, 0xC2, 0xBC, 0xFC, 0xB2, 0xDC, /* 0xAC-0xAF */
+	0xB2, 0xE2, 0xB9, 0x61, 0xB9, 0x73, 0xC6, 0x46, /* 0xB0-0xB3 */
+	0xBB, 0xE2, 0xA8, 0xD2, 0xC2, 0xA7, 0xC4, 0xBF, /* 0xB4-0xB7 */
+	0xC1, 0xF5, 0xB4, 0x63, 0xA4, 0x46, 0xB9, 0xB1, /* 0xB8-0xBB */
+	0xBC, 0x64, 0xA7, 0xBF, 0xAE, 0xC6, 0xBC, 0xD6, /* 0xBC-0xBF */
+	0xBF, 0x52, 0xC0, 0xF8, 0xE7, 0x64, 0xBF, 0xF1, /* 0xC0-0xC3 */
+	0xC0, 0x73, 0xB7, 0x77, 0xA8, 0xBF, 0xBC, 0x42, /* 0xC4-0xC7 */
+	0xCC, 0xD8, 0xAC, 0x68, 0xAC, 0x79, 0xB7, 0xC8, /* 0xC8-0xCB */
+	0xAF, 0x5B, 0xAF, 0x64, 0xB2, 0xB8, 0xAF, 0xC3, /* 0xCC-0xCF */
+	0xC3, 0xFE, 0xA4, 0xBB, 0xBC, 0xAE, 0xB3, 0xB0, /* 0xD0-0xD3 */
+	0xAD, 0xDB, 0xB1, 0x5B, 0xB2, 0x5F, 0xBD, 0xFC, /* 0xD4-0xD7 */
+	0xAB, 0xDF, 0xB7, 0x58, 0xAE, 0xDF, 0xB2, 0x76, /* 0xD8-0xDB */
+	0xB6, 0xA9, 0xA7, 0x51, 0xA6, 0x4F, 0xBC, 0x69, /* 0xDC-0xDF */
+	0xA9, 0xF6, 0xA7, 0xF5, 0xB1, 0xF9, 0xAA, 0x64, /* 0xE0-0xE3 */
+	0xB2, 0x7A, 0xB5, 0x67, 0xBF, 0xA9, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0xB8, 0xCC, 0xA8, 0xBD, 0xC2, 0xF7, 0xB0, 0xCE, /* 0xE8-0xEB */
+	0xB7, 0xC4, 0xA7, 0x5B, 0xBF, 0x4D, 0xBF, 0x5A, /* 0xEC-0xEF */
+	0xC4, 0xA9, 0x3F, 0x3F, 0xC5, 0xEC, 0xC5, 0xEF, /* 0xF0-0xF3 */
+	0xAA, 0x4C, 0xB2, 0x4F, 0xC1, 0x7B, 0xA5, 0xDF, /* 0xF4-0xF7 */
+	0xB2, 0xC1, 0xB2, 0xC9, 0xAA, 0xAC, 0xAA, 0xA5, /* 0xF8-0xFB */
+	0xC3, 0xD1, 0xA4, 0xB0, 0xAF, 0xF9, 0xA8, 0xEB, /* 0xFC-0xFF */
+};
+
+static unsigned char u2c_FA[512] = {
+	0xA4, 0xC1, 0xAB, 0xD7, 0xA9, 0xDD, 0xBF, 0x7D, /* 0x00-0x03 */
+	0xA6, 0x76, 0xAC, 0x7D, 0xBC, 0xC9, 0xBF, 0xE7, /* 0x04-0x07 */
+	0xA6, 0xE6, 0xAD, 0xB0, 0xA8, 0xA3, 0xB9, 0xF8, /* 0x08-0x0B */
+	0xC9, 0x4A, 0xDD, 0xFC, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x0C-0x0F */
+	0xB6, 0xEF, 0x3F, 0x3F, 0xB4, 0xB8, 0x3F, 0x3F, /* 0x10-0x13 */
+	0x3F, 0x3F, 0xE8, 0xF9, 0xBD, 0xDE, 0xAF, 0x71, /* 0x14-0x17 */
+	0x3F, 0x3F, 0xAF, 0xAB, 0xB2, 0xBB, 0xBA, 0xD6, /* 0x18-0x1B */
+	0xB9, 0x74, 0xBA, 0xEB, 0xA6, 0xD0, 0x3F, 0x3F, /* 0x1C-0x1F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xBD, 0xD1, 0x3F, 0x3F, /* 0x20-0x23 */
+	0x3F, 0x3F, 0xB6, 0x68, 0xB3, 0xA3, 0x3F, 0x3F, /* 0x24-0x27 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0xB6, 0xBA, 0xB9, 0x7D, /* 0x28-0x2B */
+	0xC0, 0x5D, 0xC5, 0x62, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x2C-0x2F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x30-0x33 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x34-0x37 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x38-0x3B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x3C-0x3F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x40-0x43 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x44-0x47 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x48-0x4B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x4C-0x4F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x50-0x53 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x54-0x57 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x58-0x5B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x5C-0x5F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x74-0x77 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x78-0x7B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x7C-0x7F */
+	
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x80-0x83 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x84-0x87 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x88-0x8B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x8C-0x8F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x90-0x93 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x94-0x97 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x98-0x9B */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x9C-0x9F */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA0-0xA3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA4-0xA7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xA8-0xAB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xAC-0xAF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB0-0xB3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB4-0xB7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xB8-0xBB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xBC-0xBF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC0-0xC3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC4-0xC7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xC8-0xCB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xCC-0xCF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD0-0xD3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD4-0xD7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xD8-0xDB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xDC-0xDF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE0-0xE3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE4-0xE7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xE8-0xEB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xEC-0xEF */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF0-0xF3 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF4-0xF7 */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xF8-0xFB */
+	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0xFC-0xFF */
+};
+
 static unsigned char u2c_FE[512] = {
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x00-0x03 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x04-0x07 */
@@ -12423,8 +12629,8 @@
 };
 
 static unsigned char u2c_FF[512] = {
-	0x3F, 0x3F, 0xA1, 0x49, 0x3F, 0x3F, 0xA1, 0xAD, /* 0x00-0x03 */
-	0xA2, 0x43, 0xA2, 0x48, 0xA1, 0xAE, 0x3F, 0x3F, /* 0x04-0x07 */
+	0x3F, 0x3F, 0xA1, 0x49, 0xA1, 0xA8, 0xA1, 0xAD, /* 0x00-0x03 */
+	0xA2, 0x43, 0xA2, 0x48, 0xA1, 0xAE, 0xA1, 0xA6, /* 0x04-0x07 */
 	0xA1, 0x5D, 0xA1, 0x5E, 0xA1, 0xAF, 0xA1, 0xCF, /* 0x08-0x0B */
 	0xA1, 0x41, 0xA1, 0xD0, 0xA1, 0x44, 0xA1, 0xFE, /* 0x0C-0x0F */
 	0xA2, 0xAF, 0xA2, 0xB0, 0xA2, 0xB1, 0xA2, 0xB2, /* 0x10-0x13 */
@@ -12437,9 +12643,9 @@
 	0xA2, 0xDA, 0xA2, 0xDB, 0xA2, 0xDC, 0xA2, 0xDD, /* 0x2C-0x2F */
 	0xA2, 0xDE, 0xA2, 0xDF, 0xA2, 0xE0, 0xA2, 0xE1, /* 0x30-0x33 */
 	0xA2, 0xE2, 0xA2, 0xE3, 0xA2, 0xE4, 0xA2, 0xE5, /* 0x34-0x37 */
-	0xA2, 0xE6, 0xA2, 0xE7, 0xA2, 0xE8, 0x3F, 0x3F, /* 0x38-0x3B */
-	0xA2, 0x40, 0x3F, 0x3F, 0x3F, 0x3F, 0xA1, 0xC4, /* 0x3C-0x3F */
-	0x3F, 0x3F, 0xA2, 0xE9, 0xA2, 0xEA, 0xA2, 0xEB, /* 0x40-0x43 */
+	0xA2, 0xE6, 0xA2, 0xE7, 0xA2, 0xE8, 0xA1, 0x65, /* 0x38-0x3B */
+	0xA2, 0x40, 0xA1, 0x66, 0xA1, 0x73, 0xA1, 0xC4, /* 0x3C-0x3F */
+	0xA1, 0xA5, 0xA2, 0xE9, 0xA2, 0xEA, 0xA2, 0xEB, /* 0x40-0x43 */
 	0xA2, 0xEC, 0xA2, 0xED, 0xA2, 0xEE, 0xA2, 0xEF, /* 0x44-0x47 */
 	0xA2, 0xF0, 0xA2, 0xF1, 0xA2, 0xF2, 0xA2, 0xF3, /* 0x48-0x4B */
 	0xA2, 0xF4, 0xA2, 0xF5, 0xA2, 0xF6, 0xA2, 0xF7, /* 0x4C-0x4F */
@@ -12448,7 +12654,7 @@
 	0xA3, 0x41, 0xA3, 0x42, 0xA3, 0x43, 0xA1, 0x61, /* 0x58-0x5B */
 	0xA1, 0x55, 0xA1, 0x62, 0xA1, 0xE3, 0x3F, 0x3F, /* 0x5C-0x5F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x60-0x63 */
-	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
+	0xA1, 0x4E, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x64-0x67 */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x68-0x6B */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x6C-0x6F */
 	0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, 0x3F, /* 0x70-0x73 */
@@ -12495,7 +12701,7 @@
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	u2c_20, u2c_21, u2c_22, NULL,   NULL,   u2c_25, u2c_26, NULL,   
+	u2c_20, u2c_21, u2c_22, u2c_23, NULL,   u2c_25, u2c_26, NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	u2c_30, u2c_31, u2c_32, u2c_33, NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
@@ -12518,11 +12724,11 @@
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
+	NULL,   NULL,   NULL,   NULL,   u2c_DC, NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
 	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   NULL,   
-	NULL,   NULL,   u2c_FA, NULL,   NULL,   NULL,   u2c_FE, u2c_FF, };
+	NULL,   u2c_F9, u2c_FA, NULL,   NULL,   NULL,   u2c_FE, u2c_FF, };
 
 static void uni2char(unsigned char ch, unsigned char cl, unsigned char *out, int boundlen, int *outlen)
 {
@@ -12530,6 +12736,7 @@
 
 	if (boundlen <= 0)
 		return;
+
 	uni2charset = page_uni2charset[ch];
 	*outlen = 0;
 	if (uni2charset){
@@ -12553,6 +12760,7 @@
 
 	ch = rawstring[0];
 	cl = rawstring[1];
+
 	charset2uni = page_charset2uni[ch];
 	if (charset2uni && cl){
 		*uni1 = charset2uni[cl].uni2;
@@ -12585,20 +12793,34 @@
 	NULL
 };
 
+static struct nls_table alias_table = {
+	"big5",
+	uni2char,
+	char2uni,
+	inc_use_count,
+	dec_use_count,
+	NULL
+};
+
+
 int __init init_nls_cp950(void)
 {
+	register_nls(&alias_table);
 	return register_nls(&table);
 }
 
 #ifdef MODULE
 int init_module(void)
 {
+
 	return init_nls_cp950();
 }
 
 
 void cleanup_module(void)
 {
+
+	unregister_nls(&alias_table);
 	unregister_nls(&table);
 	return;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ntfs/Makefile linux.17p18/fs/ntfs/Makefile
--- linux.vanilla/fs/ntfs/Makefile	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/ntfs/Makefile	Tue Aug  1 07:59:08 2000
@@ -3,7 +3,7 @@
 O_TARGET := ntfs.o
 O_OBJS   := fs.o sysctl.o support.o util.o inode.o dir.o super.o attr.o
 M_OBJS   := $(O_TARGET)
-EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"990411\"
+EXTRA_CFLAGS = -DNTFS_IN_LINUX_KERNEL -DNTFS_VERSION=\"000607\"
 
 include $(TOPDIR)/Rules.make
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ntfs/fs.c linux.17p18/fs/ntfs/fs.c
--- linux.vanilla/fs/ntfs/fs.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/ntfs/fs.c	Tue Aug  1 07:59:08 2000
@@ -5,6 +5,7 @@
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996 Richard Russon
  *  Copyright (C) 1996-1997 Régis Duchesne
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 #ifdef HAVE_CONFIG_H
@@ -79,7 +80,7 @@
 	io.param=buf;
 	io.size=count;
 	error=ntfs_read_attr(ino,ino->vol->at_data,NULL,*off,&io);
-	if(error)return -error;
+	if(error && !io.size)return -error;
 	
 	*off+=io.size;
 	return io.size;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ntfs/inode.c linux.17p18/fs/ntfs/inode.c
--- linux.vanilla/fs/ntfs/inode.c	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/ntfs/inode.c	Tue Aug  1 07:59:08 2000
@@ -6,6 +6,7 @@
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1998 Joseph Malicki
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 #include "ntfstypes.h"
@@ -551,11 +552,11 @@
 		dest->size=chunk;
 		error=ntfs_getput_clusters(ino->vol,s_cluster,
 					   offset-s_vcn*clustersize,dest);
-		if(error)/* FIXME: maybe return failure */
+		if(error)
 		{
 			ntfs_error("Read error\n");
 			dest->size=copied;
-			return 0;
+			return error;
 		}
 		l-=chunk;
 		copied+=chunk;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ntfs/struct.h linux.17p18/fs/ntfs/struct.h
--- linux.vanilla/fs/ntfs/struct.h	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/ntfs/struct.h	Tue Aug  1 07:59:19 2000
@@ -3,6 +3,7 @@
  * Structure definitions
  *
  *  Copyright (C) 1997 Régis Duchesne
+ *  Copyright (C) 2000 Anton Altaparmakov
  */
 
 /* Necessary forward definition */
@@ -42,7 +43,10 @@
 	ntfs_u32 at_standard_information;
 	ntfs_u32 at_attribute_list;
 	ntfs_u32 at_file_name;
+	ntfs_u32 at_volume_version;
 	ntfs_u32 at_security_descriptor;
+	ntfs_u32 at_volume_name;
+	ntfs_u32 at_volume_information;
 	ntfs_u32 at_data;
 	ntfs_u32 at_index_root;
 	ntfs_u32 at_index_allocation;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ntfs/super.c linux.17p18/fs/ntfs/super.c
--- linux.vanilla/fs/ntfs/super.c	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/ntfs/super.c	Tue Aug  1 07:59:19 2000
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995-1997, 1999 Martin von Löwis
  *  Copyright (C) 1996-1997 Régis Duchesne
  *  Copyright (C) 1999 Steve Dodd
+ *  Copyright (C) 2000 Anton Altparmakov
  */
 
 #include "ntfstypes.h"
@@ -62,7 +63,10 @@
 	vol->at_standard_information=0x10;
 	vol->at_attribute_list=0x20;
 	vol->at_file_name=0x30;
+	vol->at_volume_version=0x40;
 	vol->at_security_descriptor=0x50;
+	vol->at_volume_name=0x60;
+	vol->at_volume_information=0x70;
 	vol->at_data=0x80;
 	vol->at_index_root=0x90;
 	vol->at_index_allocation=0xA0;
@@ -141,8 +145,18 @@
 	}else if(ntfs_ua_strncmp(name,"$FILE_NAME",64)==0){
 		vol->at_file_name=type;
 		check_type=0x30;
+	}else if(ntfs_ua_strncmp(name,"$VOLUME_VERSION",64)==0){
+		vol->at_volume_version=type;
+		check_type=0x40;
 	}else if(ntfs_ua_strncmp(name,"$SECURITY_DESCRIPTOR",64)==0){
-		vol->at_file_name=type;
+		vol->at_security_descriptor=type;
+		check_type=0x50;
+	}else if(ntfs_ua_strncmp(name,"$VOLUME_NAME",64)==0){
+		vol->at_volume_name=type;
+		check_type=0x60;
+	}else if(ntfs_ua_strncmp(name,"$VOLUME_INFORMATION",64)==0){
+		vol->at_volume_information=type;
+		check_type=0x70;
 	}else if(ntfs_ua_strncmp(name,"$DATA",64)==0){
 		vol->at_data=type;
 		check_type=0x80;
@@ -158,6 +172,7 @@
 	}else if(ntfs_ua_strncmp(name,"$SYMBOLIC_LINK",64)==0 ||
 		 ntfs_ua_strncmp(name,"$REPARSE_POINT",64)==0){
 		vol->at_symlink=type;
+		check_type=0xC0;
 	}
 	if(check_type && check_type!=type){
 		ntfs_error("Unexpected type %x for %x\n",type,check_type);
@@ -196,10 +211,31 @@
 	return error;
 }
 
+/* ntfs_get_version will determine the NTFS version of the 
+   volume and will return the version in a BCD format, with
+   the MSB being the major version number and the LSB the
+   minor one. Otherwise return <0 on error. 
+   Example: version 3.1 will be returned as 0x0301.
+   This has the obvious limitation of not coping with version
+   numbers above 0x80 but that shouldn't be a problem... */
+int ntfs_get_version(ntfs_inode* volume)
+{
+	ntfs_attribute *volinfo;
+
+	volinfo = ntfs_find_attr(volume, volume->vol->at_volume_information, 0);
+	if (!volinfo) 
+		return -EINVAL;
+	if (!volinfo->resident) {
+		ntfs_error("Volume information attribute is not resident!\n");
+		return -EINVAL;
+	}
+	return ((ntfs_u8*)volinfo->d.data)[8] << 8 | ((ntfs_u8*)volinfo->d.data)[9];
+}
+
 int ntfs_load_special_files(ntfs_volume *vol)
 {
 	int error;
-	ntfs_inode upcase,attrdef;
+	ntfs_inode upcase, attrdef, volume;
 
 	vol->mft_ino=(ntfs_inode*)ntfs_calloc(3*sizeof(ntfs_inode));
 	error=ENOMEM;
@@ -232,6 +268,21 @@
 	error=ntfs_init_attrdef(&attrdef);
 	ntfs_clear_inode(&attrdef);
 	if(error)return error;
+
+	/* Check for NTFS version and if Win2k version (ie. 3.0+)
+	   do not allow write access since the driver write support
+	   is broken, especially for Win2k. */
+	ntfs_debug(DEBUG_BSD,"Going to load VOLUME\n");
+	error = ntfs_init_inode(&volume,vol,FILE_VOLUME);
+	if (error) return error;
+	if ((error = ntfs_get_version(&volume)) >= 0x0300) {
+		NTFS_SB(vol)->s_flags |= MS_RDONLY;
+		ntfs_error("Warning! NTFS volume version is Win2k+: Mounting read-only\n");
+	}
+	ntfs_clear_inode(&volume);
+	if (error < 0) return error;
+	ntfs_debug(DEBUG_BSD, "NTFS volume is version %d.%d\n", error >> 8, error & 0xff);
+
 	return 0;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ntfs/util.c linux.17p18/fs/ntfs/util.c
--- linux.vanilla/fs/ntfs/util.c	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/ntfs/util.c	Tue Aug  1 07:59:19 2000
@@ -266,6 +266,8 @@
 			return -1;
 		if(b[i]<a[i])
 			return 1;
+		if (a[i] == 0)
+			return 0;
 	}
 	return 0;
 }
@@ -281,6 +283,8 @@
 			return -1;
 		if(b[i]<NTFS_GETU16(a+i))
 			return 1;
+		if (b[i] == 0)
+			return 0;
 	}
 	return 0;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/proc/array.c linux.17p18/fs/proc/array.c
--- linux.vanilla/fs/proc/array.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/proc/array.c	Tue Aug  1 07:59:20 2000
@@ -1486,7 +1486,7 @@
 		case PROC_PID_CPU:
 			return 0;	
 	}
-	if(capable(CAP_DAC_OVERRIDE) || (current->fsuid == euid && ok))
+	if((current->fsuid == euid && ok) || capable(CAP_DAC_OVERRIDE))
 		return 0;
 	return 1;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/proc/inode.c linux.17p18/fs/proc/inode.c
--- linux.vanilla/fs/proc/inode.c	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/proc/inode.c	Tue Aug  1 07:59:20 2000
@@ -149,7 +149,7 @@
 		return 0;
 	/* read and search access */
 	if ((mask == S_IROTH) ||
-	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+	    (S_ISDIR(inode->i_mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
 		if (capable(CAP_DAC_READ_SEARCH))
 			return 0;
 	return -EACCES;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/read_write.c linux.17p18/fs/read_write.c
--- linux.vanilla/fs/read_write.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/read_write.c	Tue Aug  1 07:59:23 2000
@@ -210,12 +210,19 @@
 	if (copy_from_user(iov, vector, count*sizeof(*vector)))
 		goto out;
 
+	/* BSD readv/writev returns EINVAL if one of the iov_len
+	   values < 0 or tot_len overflowed a 32-bit integer. -ink */
 	tot_len = 0;
-	for (i = 0 ; i < count ; i++)
-		tot_len += iov[i].iov_len;
-
-	if((long) tot_len <0)
-		return -EINVAL;
+	ret = -EINVAL;
+	for (i = 0 ; i < count ; i++) {
+		size_t tmp = tot_len;
+		int len = iov[i].iov_len;
+		if (len < 0)
+			goto out;
+		(u32)tot_len += len;
+		if (tot_len < tmp || tot_len < (u32)len)
+			goto out;
+	}
 
 	inode = file->f_dentry->d_inode;
 	/* VERIFY_WRITE actually means a read, as we write to user space */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/ChangeLog linux.17p18/fs/smbfs/ChangeLog
--- linux.vanilla/fs/smbfs/ChangeLog	Thu Jan  1 01:00:00 1970
+++ linux.17p18/fs/smbfs/ChangeLog	Tue Aug  1 07:59:20 2000
@@ -0,0 +1,49 @@
+ChangeLog for smbfs.
+
+2000-07-20 Urban Widmark <urban@svenskatest.se>
+
+	* proc.c: fix 2 places where bad server responses could cause an Oops.
+
+2000-07-15 Urban Widmark <urban@svenskatest.se>
+
+	* *.c: more debug printk fixes
+
+2000-06-24: Matt Maynard <matthewm@corel.com>
+
+	* dir.c: dentry->d_inode->i_mtime isn't updated for all servers
+	  (NT?) and all operations (mv oldfile.txt newfile.txt) Removed for
+	  less efficient but better working directory cache.
+	* proc.c: included aDIR smbclient fix for renaming directories on
+	  OS/2 servers (win95/98?) (orig by John Janosik)
+
+2000-07-01 Urban Widmark <urban@svenskatest.se>
+
+	* *.c: replace ugly #ifdef's with less ugly debug macros.
+
+2000-03-?? Andrew Tridgell
+
+	* proc.c: removed support for old protocol levels. It didn't work
+	  anyway and was cluttering things up a lot.
+
+2000-01-?? cpg@aladdin.de
+
+	* proc.c: added posix semantics for unlink
+
+1999-11-16 Andrew Tridgell
+
+	* proc.c: use level 260 for most conns, or level 1 for <NT1
+	* proc.c: don't sleep every time with win95 on a FINDNEXT
+	* proc.c: fixed loop_count bug
+	* proc.c: got rid of resume_key
+
+[there are a few missing here :) ]
+
+1997-09-28 Riccardo Facchetti
+
+	* proc.c: Fixed smb_d_path [now smb_build_path()] to be non-recursive
+
+1996-06-28 Yuri Per
+
+	* proc.c: Fixed long file name support (smb_proc_readdir_long)
+
+You are in the wrong end for adding new entries. New entries at the top.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/Makefile linux.17p18/fs/smbfs/Makefile
--- linux.vanilla/fs/smbfs/Makefile	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/smbfs/Makefile	Tue Aug  1 07:59:20 2000
@@ -11,8 +11,13 @@
 O_OBJS   := proc.o dir.o cache.o sock.o inode.o file.o ioctl.o 
 M_OBJS   := $(O_TARGET)
 
-# If you want debugging output, please uncomment the following line
+# If you want debugging output, you may add these flags to the EXTRA_CFLAGS
+# Note: SMBFS_PARANOIA is also defined in most smbfs source files.
+
+EXTRA_CFLAGS += -DSMBFS_PARANOIA
+#EXTRA_CFLAGS += -DSMBFS_DEBUG
+#EXTRA_CFLAGS += -DSMBFS_DEBUG_VERBOSE
+#EXTRA_CFLAGS += -DDEBUG_SMB_MALLOC
 
-# EXTRA_CFLAGS += -DDEBUG -DDEBUG_SMB_MALLOC=1
 
 include $(TOPDIR)/Rules.make
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/cache.c linux.17p18/fs/smbfs/cache.c
--- linux.vanilla/fs/smbfs/cache.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/smbfs/cache.c	Tue Aug  1 07:59:20 2000
@@ -6,6 +6,8 @@
  * Routines to support directory cacheing using the page cache.
  * Right now this only works for smbfs, but will be generalized
  * for use with other filesystems.
+ *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -17,8 +19,8 @@
 
 #include <asm/page.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
+#include "smb_debug.h"
+
 
 static inline struct inode * 
 get_cache_inode(struct cache_head *cachep)
@@ -37,10 +39,7 @@
 	struct inode * inode = dentry->d_inode;
 	struct cache_head * cachep;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_get_dircache: finding cache for %s/%s\n",
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
+	VERBOSE("finding cache for %s/%s\n", DENTRY_PATH(dentry));
 	cachep = (struct cache_head *) get_cached_page(inode, 0, 1);
 	if (!cachep)
 		goto out;
@@ -59,8 +58,8 @@
 		for (i = 0; i < cachep->pages; i++, index++) {
 #ifdef SMBFS_PARANOIA
 			if (index->block)
-				printk(KERN_DEBUG "smb_get_dircache: cache %s/%s has existing block!\n",
-				       dentry->d_parent->d_name.name, dentry->d_name.name);
+				PARANOIA("cache %s/%s has existing block!\n",
+					 DENTRY_PATH(dentry));
 #endif
 			offset = PAGE_SIZE + (i << PAGE_SHIFT);
 			block = (struct cache_block *) get_cached_page(inode,
@@ -84,9 +83,7 @@
 	struct cache_index * index = cachep->index;
 	int i;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_free_cache_blocks: freeing %d blocks\n", cachep->pages);
-#endif
+	VERBOSE("freeing %d blocks\n", cachep->pages);
 	for (i = 0; i < cachep->pages; i++, index++)
 	{
 		if (index->block)
@@ -103,9 +100,7 @@
 void
 smb_free_dircache(struct cache_head * cachep)
 {
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_free_dircache: freeing cache\n");
-#endif
+	VERBOSE("freeing cache\n");
 	smb_free_cache_blocks(cachep);
 	put_cached_page((unsigned long) cachep);
 }
@@ -117,9 +112,7 @@
 void
 smb_init_dircache(struct cache_head * cachep)
 {
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_init_dircache: initializing cache, %d blocks\n", cachep->pages);
-#endif
+	VERBOSE("initializing cache, %d blocks\n", cachep->pages);
 	smb_free_cache_blocks(cachep);
 	memset(cachep, 0, sizeof(struct cache_head));
 }
@@ -139,10 +132,8 @@
 	unsigned int nent, offset, len = entry->len;
 	unsigned int needed = len + sizeof(struct cache_entry);
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_add_to_cache: cache inode %p, status %d, adding %s at %ld\n",
-inode, cachep->status, entry->name, fpos);
-#endif
+	VERBOSE("cache inode %p, status %d, adding %.*s at %ld\n",
+		inode, cachep->status, entry->len, entry->name, fpos);
 	/*
 	 * Don't do anything if we've had an error ...
 	 */
@@ -168,10 +159,8 @@
 		block->cb_data.table[nent].offset = offset;
 		block->cb_data.table[nent].ino = entry->ino;
 		cachep->entries++;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_add_to_cache: added entry %s, len=%d, pos=%ld, entries=%d\n",
-entry->name, len, fpos, cachep->entries);
-#endif
+		VERBOSE("added entry %.*s, len=%d, pos=%ld, entries=%d\n",
+			entry->len, entry->name, len, fpos, cachep->entries);
 		return;
 	}
 	/*
@@ -183,7 +172,7 @@
 	index++;
 #ifdef SMBFS_PARANOIA
 	if (index->block)
-		printk(KERN_DEBUG "smb_add_to_cache: new index already has block!\n");
+		PARANOIA("new index already has block!\n");
 #endif
 
 	/*
@@ -197,10 +186,8 @@
 	{
 		index->block = block;
 		index->space = PAGE_SIZE;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_add_to_cache: inode=%p, pages=%d, block at %ld\n",
-inode, cachep->pages, page_off);
-#endif
+		VERBOSE("inode=%p, pages=%d, block at %ld\n",
+			inode, cachep->pages, page_off);
 		goto add_entry;
 	}
 	/*
@@ -221,9 +208,7 @@
 	unsigned int i, nent, offset = 0;
 	off_t next_pos = 2;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_find_in_cache: cache %p, looking for pos=%ld\n", cachep, pos);
-#endif
+	VERBOSE("cache %p, looking for pos=%ld\n", cachep, pos);
 	for (i = 0; i < cachep->pages; i++, index++)
 	{
 		if (pos < next_pos)
@@ -241,10 +226,8 @@
 		entry->len = block->cb_data.table[nent].namelen;
 		offset = block->cb_data.table[nent].offset;
 		entry->name = &block->cb_data.names[offset];
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_find_in_cache: found %s, len=%d, pos=%ld\n",
-entry->name, entry->len, pos);
-#endif
+		VERBOSE("found %.*s, len=%d, pos=%ld\n",
+			entry->len, entry->name, entry->len, pos);
 		break;
 	}
 	return offset;
@@ -256,10 +239,7 @@
 	struct inode * inode = dentry->d_inode;
 	int result;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-	printk(KERN_DEBUG "smb_refill_dircache: cache %s/%s, blocks=%d\n",
-	       dentry->d_parent->d_name.name, dentry->d_name.name, cachep->pages);
-#endif
+	VERBOSE("cache %s/%s, blocks=%d\n", DENTRY_PATH(dentry), cachep->pages);
 	/*
 	 * Fill the cache, starting at position 2.
 	 */
@@ -268,9 +248,7 @@
 	result = smb_proc_readdir(dentry, 2, cachep);
 	if (result < 0)
 	{
-#ifdef SMBFS_PARANOIA
-		printk(KERN_DEBUG "smb_refill_dircache: readdir failed, result=%d\n", result);
-#endif
+		PARANOIA("readdir failed, result=%d\n", result);
 		goto out;
 	}
 
@@ -280,9 +258,7 @@
 	 */
 	if (!(inode->u.smbfs_i.cache_valid & SMB_F_CACHEVALID))
 	{
-#ifdef SMBFS_PARANOIA
-		printk(KERN_DEBUG "smb_refill_dircache: cache invalidated, retrying\n");
-#endif
+		PARANOIA("cache invalidated, retrying\n");
 		goto retry;
 	}
 
@@ -292,11 +268,8 @@
 		cachep->valid = 1;
 		cachep->mtime = dentry->d_inode->i_mtime;
 	}
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_refill_cache: cache %s/%s status=%d, entries=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-cachep->status, cachep->entries);
-#endif
+	VERBOSE("cache %s/%s status=%d, entries=%d\n",
+		DENTRY_PATH(dentry), cachep->status, cachep->entries);
 
 out:
 	return result;
@@ -313,4 +286,3 @@
 	dir->u.smbfs_i.cache_valid &= ~SMB_F_CACHEVALID;
 	dir->u.smbfs_i.oldmtime = 0;
 }
-
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/dir.c linux.17p18/fs/smbfs/dir.c
--- linux.vanilla/fs/smbfs/dir.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/smbfs/dir.c	Tue Aug  1 07:59:20 2000
@@ -4,18 +4,19 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
 #include <linux/errno.h>
 #include <linux/kernel.h>
+#include <linux/ctype.h>
 
 #include <linux/smb_fs.h>
 #include <linux/smbno.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-/* #define pr_debug printk */
+#include "smb_debug.h"
+
 #define SMBFS_MAX_AGE 5*HZ
 
 static ssize_t smb_dir_read(struct file *, char *, size_t, loff_t *);
@@ -83,10 +84,8 @@
 	struct cache_head *cachep = NULL;
 	int result;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-	printk("smb_readdir: reading %s/%s, f_pos=%d\n",
-	       dentry->d_parent->d_name.name, dentry->d_name.name, (int) filp->f_pos);
-#endif
+	VERBOSE("reading %s/%s, f_pos=%d\n", DENTRY_PATH(dentry),
+		(int) filp->f_pos);
 
 	result = 0;
 	switch ((unsigned int) filp->f_pos)
@@ -117,10 +116,13 @@
 		goto out;
 	/*
 	 * Make sure the cache is up-to-date.
+	 *
+	 * To detect changes on the server we refill on each "new" access.
+	 *
+	 * Directory mtime would be nice to use for finding changes,
+	 * unfortunately some servers (NT4) doesn't update on local changes.
 	 */
-	if (!cachep->valid ||
-	    (cachep->mtime != dentry->d_inode->i_mtime &&
-	     filp->f_pos == 2))
+	if (!cachep->valid || filp->f_pos == 2)
 	{
 		result = smb_refill_dircache(cachep, dentry);
 		if (result)
@@ -174,11 +176,9 @@
 	struct dentry *dentry = file->f_dentry;
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	int error = 0;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_dir_open: (%s/%s)\n", dentry->d_parent->d_name.name, 
-file->f_dentry->d_name.name);
-#endif
 
+	VERBOSE("(%s/%s)\n", dentry->d_parent->d_name.name, 
+		file->f_dentry->d_name.name);
 	if (server->conn_pid)
 		error = smb_revalidate_inode(dentry);
 	return error;
@@ -217,37 +217,24 @@
 	 */
 	valid = (age <= SMBFS_MAX_AGE);
 #ifdef SMBFS_DEBUG_VERBOSE
-if (!valid)
-printk("smb_lookup_validate: %s/%s not valid, age=%lu\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name, age);
+	if (!valid)
+		VERBOSE("%s/%s not valid, age=%lu\n", DENTRY_PATH(dentry), age);
 #endif
 
-	if (inode)
-	{
-		if (is_bad_inode(inode))
-		{
-#ifdef SMBFS_PARANOIA
-			printk(KERN_DEBUG "smb_lookup_validate: %s/%s has dud inode\n", 
-			       dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
+	if (inode) {
+		if (is_bad_inode(inode)) {
+			PARANOIA("%s/%s has dud inode\n", DENTRY_PATH(dentry));
 			valid = 0;
 		} else if (!valid)
 			valid = (smb_revalidate_inode(dentry) == 0);
-	} else
-	{
-	/*
-	 * What should we do for negative dentries?
-	 */
+	} else {
+		/*
+		 * What should we do for negative dentries?
+		 */
 	}
 	return valid;
 }
 
-/*
- * XXX: It would be better to use the tolower from linux/ctype.h,
- * but _ctype is needed and it is not exported.
- */
-#define tolower(c) (((c) >= 'A' && (c) <= 'Z') ? (c)-('A'-'a') : (c))
-
 static int 
 smb_hash_dentry(struct dentry *dir, struct qstr *this)
 {
@@ -286,20 +273,15 @@
 static void
 smb_delete_dentry(struct dentry * dentry)
 {
-	if (dentry->d_inode)
-	{
-		if (is_bad_inode(dentry->d_inode))
-		{
-#ifdef SMBFS_PARANOIA
-			printk(KERN_DEBUG "smb_delete_dentry: bad inode, unhashing %s/%s\n", 
-			       dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
+	if (dentry->d_inode) {
+		if (is_bad_inode(dentry->d_inode)) {
+			PARANOIA("bad inode, unhashing %s/%s\n", 
+				 DENTRY_PATH(dentry));
 			d_drop(dentry);
 		}
 		smb_close_dentry(dentry);
-	} else
-	{
-	/* N.B. Unhash negative dentries? */
+	} else {
+		/* N.B. Unhash negative dentries? */
 	}
 }
 
@@ -334,8 +316,8 @@
 	error = smb_proc_getattr(dentry, &finfo);
 #ifdef SMBFS_PARANOIA
 	if (error && error != -ENOENT)
-		printk(KERN_DEBUG "smb_lookup: find %s/%s failed, error=%d\n",
-		       dentry->d_parent->d_name.name, dentry->d_name.name, error);
+		PARANOIA("find %s/%s failed, error=%d\n",
+			 DENTRY_PATH(dentry), error);
 #endif
 
 	inode = NULL;
@@ -370,10 +352,7 @@
 	int error;
 	struct smb_fattr fattr;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_instantiate: file %s/%s, fileid=%u\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, fileid);
-#endif
+	VERBOSE("file %s/%s, fileid=%u\n", DENTRY_PATH(dentry), fileid);
 	error = smb_proc_getattr(dentry, &fattr);
 	if (error)
 		goto out_close;
@@ -399,10 +378,8 @@
 out_close:
 	if (have_id)
 	{
-#ifdef SMBFS_PARANOIA
-		printk(KERN_DEBUG "smb_instantiate: %s/%s failed, error=%d, closing %u\n",
-		       dentry->d_parent->d_name.name, dentry->d_name.name, error, fileid);
-#endif
+		PARANOIA("%s/%s failed, error=%d, closing %u\n",
+			 DENTRY_PATH(dentry), error, fileid);
 		smb_close_fileid(dentry, fileid);
 	}
 	goto out;
@@ -415,21 +392,14 @@
 	__u16 fileid;
 	int error;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_create: creating %s/%s, mode=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, mode);
-#endif
+	VERBOSE("creating %s/%s, mode=%d\n", DENTRY_PATH(dentry), mode);
 
 	error = smb_proc_create(dentry, 0, CURRENT_TIME, &fileid);
-	if (!error)
-	{
+	if (!error) {
 		error = smb_instantiate(dentry, fileid, 1);
-	} else
-	{
-#ifdef SMBFS_PARANOIA
-		printk(KERN_DEBUG "smb_create: %s/%s failed, error=%d\n",
-		       dentry->d_parent->d_name.name, dentry->d_name.name, error);
-#endif
+	} else {
+		PARANOIA("%s/%s failed, error=%d\n",
+			 DENTRY_PATH(dentry), error);
 	}
 	return error;
 }
@@ -509,10 +479,8 @@
 		error = smb_proc_unlink(new_dentry);
 		if (error)
 		{
-#ifdef SMBFS_DEBUG_VERBOSE
-			printk(KERN_DEBUG "smb_rename: unlink %s/%s, error=%d\n",
-			       new_dentry->d_parent->d_name.name, new_dentry->d_name.name, error);
-#endif
+			VERBOSE("unlink %s/%s, error=%d\n",
+				DENTRY_PATH(new_dentry), error);
 			goto out;
 		}
 		/* FIXME */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/file.c linux.17p18/fs/smbfs/file.c
--- linux.vanilla/fs/smbfs/file.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/smbfs/file.c	Tue Aug  1 07:59:20 2000
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996, 1997 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -22,15 +23,8 @@
 #include <linux/smbno.h>
 #include <linux/smb_fs.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-/* #define pr_debug printk */
+#include "smb_debug.h"
 
-static inline int
-min(int a, int b)
-{
-	return a < b ? a : b;
-}
 
 static inline void
 smb_unlock_page(struct page *page)
@@ -42,10 +36,7 @@
 static int
 smb_fsync(struct file *file, struct dentry * dentry)
 {
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_fsync: sync file %s/%s\n", 
-dentry->d_parent->d_name.name, dentry->d_name.name);
-#endif
+	VERBOSE("sync file %s/%s\n", DENTRY_PATH(dentry));
 	return 0;
 }
 
@@ -63,17 +54,13 @@
 
 	clear_bit(PG_error, &page->flags);
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_readpage_sync: file %s/%s, count=%d@%ld, rsize=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, rsize);
-#endif
+	VERBOSE("file %s/%s, count=%d@%ld, rsize=%d\n",
+		DENTRY_PATH(dentry), count, offset, rsize);
 	result = smb_open(dentry, SMB_O_RDONLY);
 	if (result < 0)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_readpage_sync: %s/%s open failed, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, result);
-#endif
+		PARANOIA("%s/%s open failed, error=%d\n",
+			 DENTRY_PATH(dentry), result);
 		goto io_error;
 	}
 
@@ -109,10 +96,10 @@
 	struct dentry *dentry = file->f_dentry;
 	int		error;
 
-	pr_debug("SMB: smb_readpage %08lx\n", page_address(page));
+	DEBUG1("SMB: smb_readpage %08lx\n", page_address(page));
 #ifdef SMBFS_PARANOIA
 	if (test_bit(PG_locked, &page->flags))
-		printk(KERN_DEBUG "smb_readpage: page already locked!\n");
+		PARANOIA("page already locked!\n");
 #endif
 	set_bit(PG_locked, &page->flags);
 	atomic_inc(&page->count);
@@ -135,10 +122,8 @@
 	int result, written = 0;
 
 	offset += page->offset;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_writepage_sync: file %s/%s, count=%d@%ld, wsize=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, count, offset, wsize);
-#endif
+	VERBOSE("file %s/%s, count=%d@%ld, wsize=%d\n",
+		DENTRY_PATH(dentry), count, offset, wsize);
 
 	do {
 		if (count < wsize)
@@ -149,8 +134,9 @@
 			break;
 		/* N.B. what if result < wsize?? */
 #ifdef SMBFS_PARANOIA
-if (result < wsize)
-printk(KERN_DEBUG "smb_writepage_sync: short write, wsize=%d, result=%d\n", wsize, result);
+		if (result < wsize)
+			printk(KERN_DEBUG "short write, wsize=%d, result=%d\n",
+			       wsize, result);
 #endif
 		buffer += wsize;
 		offset += wsize;
@@ -179,7 +165,7 @@
 
 #ifdef SMBFS_PARANOIA
 	if (test_bit(PG_locked, &page->flags))
-		printk(KERN_DEBUG "smb_writepage: page already locked!\n");
+		PARANOIA("page already locked!\n");
 #endif
 	set_bit(PG_locked, &page->flags);
 	atomic_inc(&page->count);
@@ -194,9 +180,8 @@
 {
 	struct dentry *dentry = file->f_dentry;
 
-	pr_debug("SMBFS: smb_updatepage(%s/%s %d@%ld, sync=%d)\n",
-		dentry->d_parent->d_name.name, dentry->d_name.name,
-	 	count, page->offset+offset, sync);
+	DEBUG1("(%s/%s %d@%ld, sync=%d)\n",
+	       DENTRY_PATH(dentry), count, page->offset+offset, sync);
 
 	return smb_writepage_sync(dentry, page, offset, count);
 }
@@ -207,27 +192,21 @@
 	struct dentry * dentry = file->f_dentry;
 	ssize_t	status;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_read: file %s/%s, count=%lu@%lu\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-(unsigned long) count, (unsigned long) *ppos);
-#endif
+	VERBOSE("file %s/%s, count=%lu@%lu\n", DENTRY_PATH(dentry),
+		(unsigned long) count, (unsigned long) *ppos);
 
 	status = smb_revalidate_inode(dentry);
 	if (status)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_file_read: %s/%s validation failed, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, status);
-#endif
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), status);
 		goto out;
 	}
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_read: before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n",
-dentry->d_inode->i_size, dentry->d_inode->i_nrpages, dentry->d_inode->i_flags,
-dentry->d_inode->i_atime);
-#endif
+	VERBOSE("before read, size=%ld, pages=%ld, flags=%x, atime=%ld\n",
+		dentry->d_inode->i_size, dentry->d_inode->i_nrpages,
+		dentry->d_inode->i_flags, dentry->d_inode->i_atime);
+
 	status = generic_file_read(file, buf, count, ppos);
 out:
 	return status;
@@ -239,18 +218,14 @@
 	struct dentry * dentry = file->f_dentry;
 	int	status;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_mmap: file %s/%s, address %lu - %lu\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, vma->vm_start, vma->vm_end);
-#endif
+	VERBOSE("file %s/%s, address %lu - %lu\n",
+		DENTRY_PATH(dentry), vma->vm_start, vma->vm_end);
 
 	status = smb_revalidate_inode(dentry);
 	if (status)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_file_mmap: %s/%s validation failed, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, status);
-#endif
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), status);
 		goto out;
 	}
 	status = generic_file_mmap(file, vma);
@@ -267,20 +242,16 @@
 	struct dentry * dentry = file->f_dentry;
 	ssize_t	result;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_write: file %s/%s, count=%lu@%lu, pages=%ld\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-(unsigned long) count, (unsigned long) *ppos, dentry->d_inode->i_nrpages);
-#endif
+	VERBOSE("file %s/%s, count=%lu@%lu, pages=%ld\n", DENTRY_PATH(dentry),
+		(unsigned long) count, (unsigned long) *ppos,
+		dentry->d_inode->i_nrpages);
 
 	result = smb_revalidate_inode(dentry);
 	if (result)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_file_write: %s/%s validation failed, error=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, result);
-#endif
-			goto out;
+		PARANOIA("%s/%s validation failed, error=%d\n",
+			 DENTRY_PATH(dentry), result);
+		goto out;
 	}
 
 	result = smb_open(dentry, SMB_O_WRONLY);
@@ -290,11 +261,9 @@
 	if (count > 0)
 	{
 		result = generic_file_write(file, buf, count, ppos);
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_write: pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
-(long) file->f_pos, dentry->d_inode->i_size, dentry->d_inode->i_mtime,
-dentry->d_inode->i_atime);
-#endif
+		VERBOSE("pos=%ld, size=%ld, mtime=%ld, atime=%ld\n",
+			(long) file->f_pos, dentry->d_inode->i_size,
+			dentry->d_inode->i_mtime, dentry->d_inode->i_atime);
 	}
 out:
 	return result;
@@ -303,11 +272,8 @@
 static int
 smb_file_open(struct inode *inode, struct file * file)
 {
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_open: opening %s/%s, d_count=%d\n",
-file->f_dentry->d_parent->d_name.name, file->f_dentry->d_name.name,
-file->f_dentry->d_count);
-#endif
+	VERBOSE("opening %s/%s, d_count=%d\n",
+		DENTRY_PATH(file->f_dentry), file->f_dentry->d_count);
 	return 0;
 }
 
@@ -316,15 +282,12 @@
 {
 	struct dentry * dentry = file->f_dentry;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_release: closing %s/%s, d_count=%d\n",
-dentry->d_parent->d_name.name, dentry->d_name.name, dentry->d_count);
-#endif
-	
+	VERBOSE("closing %s/%s, d_count=%d\n",
+		DENTRY_PATH(dentry), dentry->d_count);
+
 	if (dentry->d_count == 1)
-	{
 		smb_close(inode);
-	}
+
 	return 0;
 }
 
@@ -339,9 +302,8 @@
 	int mode = inode->i_mode;
 	int error = 0;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_file_permission: mode=%x, mask=%x\n", mode, mask);
-#endif
+	VERBOSE("mode=%x, mask=%x\n", mode, mask);
+
 	/* Look at user permissions */
 	mode >>= 6;
 	if ((mode & 7 & mask) != mask)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/inode.c linux.17p18/fs/smbfs/inode.c
--- linux.vanilla/fs/smbfs/inode.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/smbfs/inode.c	Tue Aug  1 07:59:20 2000
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/config.h>
@@ -28,8 +29,7 @@
 #include <asm/system.h>
 #include <asm/uaccess.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
+#include "smb_debug.h"
 
 static void smb_read_inode(struct inode *);
 static void smb_put_inode(struct inode *);
@@ -74,7 +74,7 @@
 {
 	struct inode *result;
 
-	pr_debug("smb_iget: %p\n", fattr);
+	DEBUG1("fattr @ %p\n", fattr);
 
 	result = get_empty_inode();
 	result->i_sb = sb;
@@ -155,7 +155,8 @@
 smb_read_inode(struct inode *inode)
 {
 	/* Now it can be called only by NFS */
-	printk("smb_read_inode called from invalid point\n");
+	/* FIXME! what does that comment mean!? */
+	PARANOIA("smb_read_inode called from invalid point\n");
 	return;
 }
 
@@ -166,9 +167,7 @@
 void
 smb_invalidate_inodes(struct smb_sb_info *server)
 {
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_invalidate_inodes\n");
-#endif
+	VERBOSE("\n");
 	shrink_dcache_sb(SB_of(server));
 	invalidate_inodes(SB_of(server));
 }
@@ -203,11 +202,10 @@
 			 * To limit damage, mark the inode as bad so that
 			 * subsequent lookup validations will fail.
 			 */
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_refresh_inode: %s/%s changed mode, %07o to %07o\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-inode->i_mode, fattr.f_mode);
-#endif
+			PARANOIA("%s/%s changed mode, %07o to %07o\n",
+				 DENTRY_PATH(dentry),
+				 inode->i_mode, fattr.f_mode);
+
 			fattr.f_mode = inode->i_mode; /* save mode */
 			make_bad_inode(inode);
 			inode->i_mode = fattr.f_mode; /* restore mode */
@@ -238,7 +236,8 @@
 	time_t last_time;
 	int error = 0;
 
-	pr_debug("smb_revalidate_inode\n");
+	DEBUG1("\n");
+
 	/*
 	 * If this is a file opened with write permissions,
 	 * the inode will be up-to-date.
@@ -254,10 +253,8 @@
 	 */
 	if (time_before(jiffies, inode->u.smbfs_i.oldmtime + HZ/10))
 	{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_revalidate_inode: up-to-date, jiffies=%lu, oldtime=%lu\n",
-jiffies, inode->u.smbfs_i.oldmtime);
-#endif
+		VERBOSE("up-to-date, jiffies=%lu, oldtime=%lu\n",
+			jiffies, inode->u.smbfs_i.oldmtime);
 		goto out;
 	}
 
@@ -269,11 +266,9 @@
 	error = smb_refresh_inode(dentry);
 	if (error || inode->i_mtime != last_time)
 	{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_revalidate: %s/%s changed, old=%ld, new=%ld\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-(long) last_time, (long) inode->i_mtime);
-#endif
+		VERBOSE("%s/%s changed, old=%ld, new=%ld\n",
+			DENTRY_PATH(dentry),
+			(long) last_time, (long) inode->i_mtime);
 		if (!S_ISDIR(inode->i_mode))
 			invalidate_inode_pages(inode);
 	}
@@ -288,7 +283,7 @@
 static void
 smb_put_inode(struct inode *ino)
 {
-	pr_debug("smb_put_inode: count = %d\n", ino->i_count);
+	DEBUG1("count = %d\n", ino->i_count);
 	if (ino->i_count == 1)
 		ino->i_nlink = 0;
 }
@@ -300,10 +295,9 @@
 static void
 smb_delete_inode(struct inode *ino)
 {
-	pr_debug("smb_delete_inode\n");
+	DEBUG1("\n");
 	if (smb_close(ino))
-		printk(KERN_DEBUG "smb_delete_inode: could not close inode %ld\n",
-			ino->i_ino);
+		PARANOIA("could not close inode %ld\n", ino->i_ino);
 	clear_inode(ino);
 }
 
@@ -319,7 +313,7 @@
 	}
 
 	if (server->conn_pid)
-	       kill_proc(server->conn_pid, SIGTERM, 1);
+		kill_proc(server->conn_pid, SIGTERM, 1);
 
 	kfree(server->mnt);
 	kfree(sb->u.smbfs_sb.temp_buf);
@@ -372,7 +366,7 @@
 	if (!mnt)
 		goto out_no_mount;
 	*mnt = *((struct smb_mount_data *) raw_data);
-	/* ** temp ** pass config flags in file mode */
+	/* FIXME: ** temp ** pass config flags in file mode */
 	mnt->version = (mnt->file_mode >> 9);
 	mnt->file_mode &= (S_IRWXU | S_IRWXG | S_IRWXO);
 	mnt->file_mode |= S_IFREG;
@@ -410,7 +404,7 @@
 	printk(KERN_ERR "SMBFS: need mount version %d\n", SMB_MOUNT_VERSION);
 	goto out_fail;
 out_no_data:
-	printk(KERN_DEBUG "smb_read_super: missing data argument\n");
+	printk(KERN_ERR "smb_read_super: missing data argument\n");
 out_fail:
 	sb->s_dev = 0;
 	MOD_DEC_USE_COUNT;
@@ -461,11 +455,9 @@
 
 	if ((attr->ia_valid & ATTR_SIZE) != 0)
 	{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_notify_change: changing %s/%s, old size=%ld, new size=%ld\n",
-dentry->d_parent->d_name.name, dentry->d_name.name,
-(long) inode->i_size, (long) attr->ia_size);
-#endif
+		VERBOSE("changing %s/%s, old size=%ld, new size=%ld\n",
+			DENTRY_PATH(dentry),
+			(long) inode->i_size, (long) attr->ia_size);
 		error = smb_open(dentry, O_WRONLY);
 		if (error)
 			goto out;
@@ -517,10 +509,8 @@
 	 */
 	if ((attr->ia_valid & ATTR_MODE) != 0)
 	{
-#ifdef SMBFS_DEBUG_VERBOSE
-		printk(KERN_DEBUG "smb_notify_change: %s/%s mode change, old=%x, new=%lx\n",
-		       dentry->d_parent->d_name.name, dentry->d_name.name, fattr.f_mode,attr->ia_mode);
-#endif
+		VERBOSE("%s/%s mode change, old=%x, new=%lx\n",
+			DENTRY_PATH(dentry), fattr.f_mode,attr->ia_mode);
 		changed = 0;
 		if (attr->ia_mode & S_IWUSR)
 		{
@@ -577,7 +567,7 @@
 int
 init_module(void)
 {
-	pr_debug("smbfs: init_module called\n");
+	DEBUG1("registering ...\n");
 
 #ifdef DEBUG_SMB_MALLOC
 	smb_malloced = 0;
@@ -591,7 +581,7 @@
 void
 cleanup_module(void)
 {
-	pr_debug("smbfs: cleanup_module called\n");
+	DEBUG1("unregistering ...\n");
 	unregister_filesystem(&smb_fs_type);
 #ifdef DEBUG_SMB_MALLOC
 	printk(KERN_DEBUG "smb_malloced: %d\n", smb_malloced);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/ioctl.c linux.17p18/fs/smbfs/ioctl.c
--- linux.vanilla/fs/smbfs/ioctl.c	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/smbfs/ioctl.c	Tue Aug  1 07:59:20 2000
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/errno.h>
@@ -17,41 +18,31 @@
 
 #include <asm/uaccess.h>
 
+
 int
 smb_ioctl(struct inode *inode, struct file *filp,
 	  unsigned int cmd, unsigned long arg)
 {
 	struct smb_sb_info *server = SMB_SERVER(inode);
+	struct smb_conn_opt opt;
 	int result = -EINVAL;
 
-	switch (cmd)
-	{
+	switch (cmd) {
 	case SMB_IOC_GETMOUNTUID:
 		result = put_user(server->mnt->mounted_uid, (uid_t *) arg);
 		break;
 
 	case SMB_IOC_NEWCONN:
-	{
-		struct smb_conn_opt opt;
-
-		if (arg)
-		{
-			result = -EFAULT;
-			if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
-				result = smb_newconn(server, &opt);
-		}
-		else
-		{
-#if 0
-			/* obsolete option ... print a warning */
-			printk("SMBFS: ioctl deprecated, please upgrade "
-				"smbfs package\n");
-#endif
-			result = 0;
-		}
+		/* require an argument == the mount data, else it is EINVAL */
+		if (!arg)
+			break;
+
+		result = -EFAULT;
+		if (!copy_from_user(&opt, (void *)arg, sizeof(opt)))
+			result = smb_newconn(server, &opt);
 		break;
-	}
 	default:
 	}
+
 	return result;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/proc.c linux.17p18/fs/smbfs/proc.c
--- linux.vanilla/fs/smbfs/proc.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/smbfs/proc.c	Tue Aug  1 07:59:20 2000
@@ -4,19 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
- *  28/06/96 - Fixed long file name support (smb_proc_readdir_long) by Yuri Per
- *  28/09/97 - Fixed smb_d_path [now smb_build_path()] to be non-recursive
- *             by Riccardo Facchetti
- *  16/11/99 (tridge) 
- *           - use level 260 for most conns, or level 1 for <NT1
- *           - don't sleep every time with win95 on a FINDNEXT
- *           - fixed loop_count bug
- *           - got rid of resume_key
- *  Jan 2000, cpg@aladdin.de
- *           - added posix semantics for unlink
- *  March 2000, tridge
- *           - removed support for old protocol levels. It didn't work anyway and 
- *             was cluttering things up a lot. 
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/types.h>
@@ -35,12 +23,12 @@
 
 #include <asm/string.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_TIMESTAMP 1 */
-/* #define SMBFS_DEBUG_VERBOSE 1 */
-/* #define pr_debug printk */
+/* Features. Undefine if they cause problems, this should perhaps be a
+   config option. */
 #define SMBFS_POSIX_UNLINK 1
 
+#include "smb_debug.h"
+
 #define SMB_VWV(packet)  ((packet) + SMB_HEADER_LEN)
 #define SMB_CMD(packet)  (*(packet+8))
 #define SMB_WCT(packet)  (*(packet+SMB_HEADER_LEN - 1))
@@ -50,17 +38,15 @@
 #define SMB_DIRINFO_SIZE 43
 #define SMB_STATUS_SIZE  21
 
-/* yes, this deliberately has two parts */
-#define DENTRY_PATH(dentry) (dentry)->d_parent->d_name.name,(dentry)->d_name.name
-
 static int smb_proc_setattr_ext(struct smb_sb_info *, struct inode *,
 				struct smb_fattr *);
 static int
 smb_proc_setattr_core(struct smb_sb_info *server, struct dentry *dentry,
 		      __u16 attr);
-
 static int
-smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct smb_sb_info *server);
+smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,
+		    struct smb_sb_info *server);
+
 
 /* reverse a string inline. This is used by the dircache walking routines */
 static void reverse_string(char *buf, int len) {
@@ -273,15 +259,15 @@
 	return 0;
 
 bad_command:
-	printk("smb_verify: command=%x, SMB_CMD=%x??\n",
+	printk(KERN_ERR "smb_verify: command=%x, SMB_CMD=%x??\n",
 		command, SMB_CMD(packet));
 	goto fail;
 bad_wct:
-	printk("smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
+	printk(KERN_ERR "smb_verify: command=%x, wct=%d, SMB_WCT=%d??\n",
 		command, wct, SMB_WCT(packet));
 	goto fail;
 bad_bcc:
-	printk("smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
+	printk(KERN_ERR "smb_verify: command=%x, bcc=%d, SMB_BCC=%d??\n",
 		command, bcc, SMB_BCC(packet));
 fail:
 	return -EIO;
@@ -314,10 +300,8 @@
 {
 	int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
 	int size = smb_get_xmitsize(server, overhead);
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_get_rsize: packet=%d, xmit=%d, size=%d\n",
-server->packet_size, server->opt.max_xmit, size);
-#endif
+	VERBOSE("packet=%d, xmit=%d, size=%d\n",
+		server->packet_size, server->opt.max_xmit, size);
 	return size;
 }
 
@@ -329,10 +313,8 @@
 {
 	int overhead = SMB_HEADER_LEN + 5 * sizeof(__u16) + 2 + 1 + 2;
 	int size = smb_get_xmitsize(server, overhead);
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_get_wsize: packet=%d, xmit=%d, size=%d\n",
-server->packet_size, server->opt.max_xmit, size);
-#endif
+	VERBOSE("packet=%d, xmit=%d, size=%d\n",
+		server->packet_size, server->opt.max_xmit, size);
 	return size;
 }
 
@@ -343,10 +325,8 @@
 	int error  = server->err;
 	char *class = "Unknown";
 
-#ifdef SMBFS_DEBUG_VERBOSE
-	printk("smb_errno: errcls %d  code %d  from command 0x%x\n",
+	VERBOSE("errcls %d  code %d  from command 0x%x\n",
 		errcls, error, SMB_CMD(server->packet));
-#endif
 
 	if (errcls == ERRDOS)
 		switch (error)
@@ -449,8 +429,8 @@
 		class = "ERRCMD";
 
 err_unknown:
-	printk("smb_errno: class %s, code %d from command 0x%x\n",
-		class, error, SMB_CMD(server->packet));
+	printk(KERN_ERR "smb_errno: class %s, code %d from command 0x%x\n",
+	       class, error, SMB_CMD(server->packet));
 	return EIO;
 }
 
@@ -487,7 +467,7 @@
 
 	if (pid == 0)
 	{
-		printk("smb_retry: no connection process\n");
+		printk(KERN_ERR "smb_retry: no connection process\n");
 		server->state = CONN_RETRIED;
 		goto out;
 	}
@@ -503,29 +483,26 @@
 	error = kill_proc(pid, SIGUSR1, 1);
 	if (error)
 	{
-		printk("smb_retry: signal failed, error=%d\n", error);
+		printk(KERN_ERR "smb_retry: signal failed, error=%d\n", error);
 		goto out_restore;
 	}
-#ifdef SMBFS_DEBUG_VERBOSE
-printk("smb_retry: signalled pid %d, waiting for new connection\n",
-server->conn_pid);
-#endif
+	VERBOSE("signalled pid %d, waiting for new connection\n",
+		server->conn_pid);
+
 	/*
 	 * Wait for the new connection.
 	 */
 	interruptible_sleep_on_timeout(&server->wait,  5*HZ);
 	if (signal_pending(current))
-		printk("smb_retry: caught signal\n");
+		printk(KERN_INFO "caught signal\n");
 
 	/*
 	 * Check for a valid connection.
 	 */
 	if (server->state == CONN_VALID)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_retry: new pid=%d, generation=%d\n",
-server->conn_pid, server->generation);
-#endif
+		PARANOIA("sucessful, new pid=%d, generation=%d\n",
+			 server->conn_pid, server->generation);
 		result = 1;
 	}
 
@@ -562,14 +539,12 @@
 
 	if (smb_request(s) < 0)
 	{
-		pr_debug("smb_request failed\n");
+		DEBUG1("smb_request failed\n");
 		goto out;
 	}
 	if (smb_valid_packet(s->packet) != 0)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_request_ok: invalid packet!\n");
-#endif
+		PARANOIA("invalid packet!\n");
 		goto out;
 	}
 
@@ -610,9 +585,8 @@
 	struct file *filp;
 	int error;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_newconn: fd=%d, pid=%d\n", opt->fd, current->pid);
-#endif
+	VERBOSE("fd=%d, pid=%d\n", opt->fd, current->pid);
+
 	/*
 	 * Make sure we don't already have a pid ...
 	 */
@@ -626,7 +600,7 @@
 		goto out;
 
 	if (opt->protocol < SMB_PROTOCOL_NT1) {
-		printk(KERN_NOTICE " smbfs: protocols older than NT1 are not suppported\n");
+		printk(KERN_NOTICE "smbfs: protocols older than NT1 are not suppported\n");
 		goto out;
 	}
 
@@ -660,11 +634,9 @@
 #endif
 	}
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_newconn: protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
-       server->opt.protocol, server->opt.max_xmit, server->conn_pid,
-       server->opt.capabilities);
-#endif
+	VERBOSE("protocol=%d, max_xmit=%d, pid=%d capabilities=0x%x\n",
+		server->opt.protocol, server->opt.max_xmit, server->conn_pid,
+		server->opt.capabilities);
 
 out:
 	wake_up_interruptible(&server->wait);
@@ -685,9 +657,9 @@
 	__u8 *p = server->packet;
 	__u8 *buf = server->packet;
 
-if (xmit_len > server->packet_size)
-printk(KERN_DEBUG "smb_setup_header: Aieee, xmit len > packet! len=%d, size=%d\n",
-xmit_len, server->packet_size);
+	if (xmit_len > server->packet_size)
+		printk(KERN_DEBUG "smb_setup_header: Aieee, xmit len > packet! len=%d, size=%d\n",
+		       xmit_len, server->packet_size);
 
 	p = smb_encode_smb_length(p, xmit_len - 4);
 
@@ -765,10 +737,8 @@
 		if (mode == read_write &&
 		    (error == -EACCES || error == -ETXTBSY || error == -EROFS))
 		{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_open: %s/%s R/W failed, error=%d, retrying R/O\n",
-       DENTRY_PATH(dentry), error);
-#endif
+			VERBOSE("%s/%s R/W failed, error=%d, retrying R/O\n",
+				DENTRY_PATH(dentry), error);
 			mode = read_only;
 			goto retry;
 		}
@@ -800,7 +770,7 @@
 	result = -ENOENT;
 	if (!inode)
 	{
-		printk(KERN_DEBUG "smb_open: no inode for dentry %s/%s\n",
+		printk(KERN_ERR "smb_open: no inode for dentry %s/%s\n",
 		       DENTRY_PATH(dentry));
 		goto out;
 	}
@@ -820,10 +790,8 @@
 		smb_unlock_server(server);
 		if (result)
 		{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_open: %s/%s open failed, result=%d\n",
-       DENTRY_PATH(dentry), result);
-#endif
+			PARANOIA("%s/%s open failed, result=%d\n",
+				 DENTRY_PATH(dentry), result);
 			goto out;
 		}
 		/*
@@ -839,10 +807,8 @@
 	if (inode->u.smbfs_i.access != wish && 
 	    inode->u.smbfs_i.access != SMB_O_RDWR)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_open: %s/%s access denied, access=%x, wish=%x\n",
-       DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
-#endif
+		PARANOIA("%s/%s access denied, access=%x, wish=%x\n",
+			 DENTRY_PATH(dentry), inode->u.smbfs_i.access, wish);
 		result = -EACCES;
 	}
 out:
@@ -950,18 +916,14 @@
 			 */
 			if (dentry->d_count <= 1)
 			{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_close_dentry: closing %s/%s, count=%d\n",
-       DENTRY_PATH(dentry), dentry->d_count);
-#endif
+				VERBOSE("closing %s/%s, count=%d\n",
+					DENTRY_PATH(dentry), dentry->d_count);
 				smb_proc_close_inode(server, ino);
 			}
 			smb_unlock_server(server);
 		}
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_close_dentry: closed %s/%s, count=%d\n",
-       DENTRY_PATH(dentry), dentry->d_count);
-#endif
+		VERBOSE("closed %s/%s, count=%d\n",
+			DENTRY_PATH(dentry), dentry->d_count);
 	}
 }
 
@@ -989,7 +951,7 @@
 {
 	struct smb_sb_info *server = server_from_dentry(dentry);
 	__u16 returned_count, data_len;
-	char *buf;
+	unsigned char *buf;
 	int result;
 
 	smb_lock_server(server);
@@ -1007,10 +969,19 @@
 
 	buf = SMB_BUF(server->packet);
 	data_len = WVAL(buf, 1);
+
+	/* we can NOT simply trust the data_len given by the server ... */
+	if (data_len > server->packet_size - (buf+3 - server->packet)) {
+		printk(KERN_ERR "smb_proc_read: invalid data length!! "
+		       "%d > %d - (%p - %p)\n",
+		       data_len, server->packet_size, buf+3, server->packet);
+		result = -EIO;
+		goto out;
+	}
+
 	memcpy(data, buf+3, data_len);
 
-	if (returned_count != data_len)
-	{
+	if (returned_count != data_len) {
 		printk(KERN_NOTICE "smb_proc_read: returned != data_len\n");
 		printk(KERN_NOTICE "smb_proc_read: ret_c=%d, data_len=%d\n",
 		       returned_count, data_len);
@@ -1018,10 +989,8 @@
 	result = data_len;
 
 out:
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_read: file %s/%s, count=%d, result=%d\n",
-       DENTRY_PATH(dentry), count, result);
-#endif
+	VERBOSE("file %s/%s, count=%d, result=%d\n",
+		DENTRY_PATH(dentry), count, result);
 	smb_unlock_server(server);
 	return result;
 }
@@ -1033,10 +1002,9 @@
 	int result;
 	__u8 *p;
 
-#if SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_write: file %s/%s, count=%d@%ld, packet_size=%d\n",
-       DENTRY_PATH(dentry), count, offset, server->packet_size);
-#endif
+	VERBOSE("file %s/%s, count=%d@%ld, packet_size=%d\n",
+		DENTRY_PATH(dentry), count, offset, server->packet_size);
+
 	smb_lock_server(server);
 	p = smb_setup_header(server, SMBwrite, 5, count + 3);
 	WSET(server->packet, smb_vwv0, dentry->d_inode->u.smbfs_i.fileid);
@@ -1099,7 +1067,7 @@
 
       retry:
 	p = smb_setup_header(server, SMBmv, 1, 0);
-	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN);
+	WSET(server->packet, smb_vwv0, aSYSTEM | aHIDDEN | aDIR);
 	*p++ = 4;
 	p = smb_encode_path(server, p, old_dentry, NULL);
 	*p++ = 4;
@@ -1162,6 +1130,7 @@
 }
 
 
+#if SMBFS_POSIX_UNLINK
 /*
  * Note: called with the server locked.
  * removes readonly attribute from a file. Used by unlink to give posix semantics
@@ -1184,6 +1153,7 @@
         }
         return result;
 }
+#endif
 
 int
 smb_proc_unlink(struct dentry *dentry)
@@ -1218,7 +1188,9 @@
 			   lead to a file being written by someone who
 			   shouldn't have access, but as far as I can
 			   tell that is unavoidable */
-                        result = smb_set_rw(dentry,server); /* remove RONLY attribute */
+
+			/* remove RONLY attribute */
+                        result = smb_set_rw(dentry,server);
                         if (result == 0) {
                                 flag = 1;
                                 goto retry;                 /* and try again */
@@ -1332,16 +1304,16 @@
 
 	result = p + WVAL(p, 0);
 	len = DVAL(p, 60);
-	if (len > 255) len = 255;
+	if (len > SMB_MAXNAMELEN)
+		len = SMB_MAXNAMELEN;
 	/* NT4 null terminates */
 	entry->name = p + 94;
 	if (len && entry->name[len-1] == '\0')
 		len--;
 	entry->len = len;
-#ifdef SMBFS_DEBUG_VERBOSE
-	printk(KERN_DEBUG "smb_decode_long_dirent: info 260 at %p, len=%d, name=%s\n",
-	       p, entry->len, entry->name);
-#endif
+
+	VERBOSE("info 260 at %p, len=%d, name=%.*s\n",
+		p, entry->len, entry->len, entry->name);
 
 	return result;
 }
@@ -1363,7 +1335,8 @@
 smb_proc_readdir_long(struct smb_sb_info *server, struct dentry *dir, int fpos,
 		      void *cachep)
 {
-	char *p, *mask, *param = server->temp_buf;
+	unsigned char *p;
+	char *mask, *param = server->temp_buf;
 	__u16 command;
 	int first, entries, entries_seen;
 	int info_level = 260;
@@ -1389,9 +1362,9 @@
 	mask = param + 12;
 	mask_len = smb_encode_path(server, mask, dir, &star) - mask;
 	first = 1;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_readdir_long: starting fpos=%d, mask=%s\n", fpos, mask);
-#endif
+
+	VERBOSE("starting fpos=%d, mask=%s\n", fpos, mask);
+
 	/*
 	 * We must reinitialize the dircache when retrying.
 	 */
@@ -1400,19 +1373,16 @@
 	entries_seen = 2;
 	ff_eos = 0;
 
-	while (ff_eos == 0)
-	{
+	while (ff_eos == 0) {
 		loop_count += 1;
-		if (loop_count > 10)
-		{
+		if (loop_count > 10) {
 			printk(KERN_WARNING "smb_proc_readdir_long: "
 			       "Looping in FIND_NEXT??\n");
 			entries = -EIO;
 			break;
 		}
 
-		if (first != 0)
-		{
+		if (first != 0) {
 			command = TRANSACT2_FINDFIRST;
 			WSET(param, 0, aSYSTEM | aHIDDEN | aDIR);
 			WSET(param, 2, max_matches);	/* max count */
@@ -1420,17 +1390,16 @@
 			     SMB_CONTINUE_BIT|SMB_CLOSE_IF_END); 
 			WSET(param, 6, info_level);
 			DSET(param, 8, 0);
-		} else
-		{
+		} else {
 			/* we don't need the mask after the first bit */
 			mask_len = 0;
 			mask[0] = 0;
 
 			command = TRANSACT2_FINDNEXT;
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_readdir_long: handle=0x%X, mask=%s\n",
-ff_dir_handle, mask);
-#endif
+
+			VERBOSE("handle=0x%X, mask=%s\n",
+				ff_dir_handle, mask);
+
 			WSET(param, 0, ff_dir_handle);	/* search handle */
 			WSET(param, 2, max_matches);	/* max count */
 			WSET(param, 4, info_level);
@@ -1444,18 +1413,12 @@
 					    &resp_data_len, &resp_data,
 					    &resp_param_len, &resp_param);
 
-		if (result < 0)
-		{
-			if (smb_retry(server))
-			{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_proc_readdir_long: error=%d, retrying\n", result);
-#endif
+		if (result < 0) {
+			if (smb_retry(server)) {
+				PARANOIA("error=%d, retrying\n", result);
 				goto retry;
 			}
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_proc_readdir_long: error=%d, breaking\n", result);
-#endif
+			PARANOIA("error=%d, breaking\n", result);
 			entries = result;
 			break;
 		}
@@ -1469,67 +1432,68 @@
 			continue;
 		}
 
-		if (server->rcls != 0)
-		{ 
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_proc_readdir_long: name=%s, entries=%d, rcls=%d, err=%d\n",
-mask, entries, server->rcls, server->err);
-#endif
+		if (server->rcls != 0) {
+			PARANOIA("name=%s, entries=%d, rcls=%d, err=%d\n",
+				 mask, entries, server->rcls, server->err);
 			entries = -smb_errno(server);
 			break;
 		}
 
 		/* parse out some important return info */
-		if (first != 0)
-		{
+		if (first != 0) {
 			ff_dir_handle = WVAL(resp_param, 0);
 			ff_searchcount = WVAL(resp_param, 2);
 			ff_eos = WVAL(resp_param, 4);
-		} else
-		{
+		} else {
 			ff_searchcount = WVAL(resp_param, 0);
 			ff_eos = WVAL(resp_param, 2);
 		}
 
 		if (ff_searchcount == 0)
-		{
 			break;
-		}
 
 		/* Now we are ready to parse smb directory entries. */
 
 		/* point to the data bytes */
 		p = resp_data;
-		for (i = 0; i < ff_searchcount; i++)
-		{
+		for (i = 0; i < ff_searchcount; i++) {
 			struct cache_dirent this_ent, *entry = &this_ent;
 
+			/* make sure we stay within the buffer */
+			if (p >= resp_data + resp_data_len) {
+				printk(KERN_ERR "smb_proc_readdir_long: "
+				       "dirent pointer outside buffer! "
+				       "%p  %d@%p  %d@%p\n",
+				       p, resp_data_len, resp_data,
+				       server->packet_size, server->packet);
+				result = -EIO; /* always a comm. error? */
+				goto unlock_return;
+			}
+
 			p = smb_decode_long_dirent(server, p, entry);
 
 			/* ignore . and .. from the server */
-			if (entries_seen == 2 && entry->name[0] == '.')
-			{
+			if (entries_seen == 2 && entry->name[0] == '.') {
 				if (entry->len == 1)
 					continue;
 				if (entry->name[1] == '.' && entry->len == 2)
 					continue;
 			}
-			if (entries_seen >= fpos)
-			{
+			if (entries_seen >= fpos) {
 				smb_add_to_cache(cachep, entry, entries_seen);
 				entries += 1;
 			}
  			entries_seen++;
 		}
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_readdir_long: received %d entries, eos=%d\n",
-       ff_searchcount, ff_eos);
-#endif
+		VERBOSE("received %d entries, eos=%d\n",
+			ff_searchcount, ff_eos);
+
 		first = 0;
 		loop_count = 0;
 	}
 
+unlock_return:
 	smb_unlock_server(server);
 	return entries;
 }
@@ -1559,8 +1523,7 @@
 	p = smb_encode_path(server, p, dir, NULL);
 	smb_setup_bcc(server, p);
 
-	if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0)
-	{
+	if ((result = smb_request_ok(server, SMBgetatr, 10, 0)) < 0) {
 		if (smb_retry(server))
 			goto retry;
 		goto out;
@@ -1580,8 +1543,8 @@
 	fattr->f_atime = fattr->f_mtime; 
 	fattr->f_size  = DVAL(server->packet, smb_vwv3);
 #ifdef SMBFS_DEBUG_TIMESTAMP
-printk(KERN_DEBUG "getattr_core: %s/%s, mtime=%ld\n",
-       DENTRY_PATH(dir), fattr->f_mtime);
+	printk(KERN_DEBUG "getattr_core: %s/%s, mtime=%ld\n",
+	       DENTRY_PATH(dir), fattr->f_mtime);
 #endif
 	result = 0;
 
@@ -1625,20 +1588,16 @@
 	}
 	if (server->rcls != 0)
 	{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_getattr_trans2: for %s: result=%d, rcls=%d, err=%d\n",
-&param[6], result, server->rcls, server->err);
-#endif
+		VERBOSE("for %s: result=%d, rcls=%d, err=%d\n",
+			&param[6], result, server->rcls, server->err);
 		result = -smb_errno(server);
 		goto out;
 	}
 	result = -ENOENT;
 	if (resp_data_len < 22)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_proc_getattr_trans2: not enough data for %s, len=%d\n",
-&param[6], resp_data_len);
-#endif
+		PARANOIA("not enough data for %s, len=%d\n",
+			 &param[6], resp_data_len);
 		goto out;
 	}
 
@@ -1662,8 +1621,8 @@
 	time = WVAL(resp_data, 8 + off_time);
 	attr->f_mtime = date_dos2unix(server, date, time);
 #ifdef SMBFS_DEBUG_TIMESTAMP
-printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
-       DENTRY_PATH(dir), date, time, attr->f_mtime);
+	printk(KERN_DEBUG "getattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n",
+	       DENTRY_PATH(dir), date, time, attr->f_mtime);
 #endif
 	attr->f_size = DVAL(resp_data, 12);
 	attr->attr = WVAL(resp_data, 20);
@@ -1679,7 +1638,8 @@
  * get the file attribute
  */
 static int
-smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,struct smb_sb_info *server)
+smb_proc_do_getattr(struct dentry *dir, struct smb_fattr *fattr,
+		    struct smb_sb_info *server)
 {
 	int result;
 
@@ -1770,10 +1730,9 @@
 	struct smb_sb_info *server = server_from_dentry(dir);
 	int result;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_setattr: setting %s/%s, open=%d\n", 
-       DENTRY_PATH(dir), smb_is_open(dir->d_inode));
-#endif
+	VERBOSE("setting %s/%s, open=%d\n", DENTRY_PATH(dir),
+		smb_is_open(dir->d_inode));
+
 	smb_lock_server(server);
 	result = smb_proc_setattr_core(server, dir, fattr->attr);
 	smb_unlock_server(server);
@@ -1803,9 +1762,10 @@
 	date_unix2dos(server, fattr->f_mtime, &date, &time);
 	WSET(server->packet, smb_vwv5, date);
 	WSET(server->packet, smb_vwv6, time);
+
 #ifdef SMBFS_DEBUG_TIMESTAMP
-printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n", 
-date, time, fattr->f_mtime);
+	printk(KERN_DEBUG "smb_proc_setattr_ext: date=%d, time=%d, mtime=%ld\n", 
+	       date, time, fattr->f_mtime);
 #endif
 
 	result = smb_request_ok(server, SMBsetattrE, 0, 0);
@@ -1853,10 +1813,12 @@
 	date_unix2dos(server, fattr->f_mtime, &date, &time);
 	WSET(data, 8, date);
 	WSET(data, 10, time);
+
 #ifdef SMBFS_DEBUG_TIMESTAMP
-printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 
-       DENTRY_PATH(dir), date, time, fattr->f_mtime);
+	printk(KERN_DEBUG "setattr_trans2: %s/%s, date=%x, time=%x, mtime=%ld\n", 
+	       DENTRY_PATH(dir), date, time, fattr->f_mtime);
 #endif
+
 	DSET(data, 12, 0); /* size */
 	DSET(data, 16, 0); /* blksize */
 	WSET(data, 20, 0); /* attr */
@@ -1900,27 +1862,23 @@
 	struct inode *inode = dentry->d_inode;
 	int result;
 
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_proc_settime: setting %s/%s, open=%d\n", 
-       DENTRY_PATH(dentry), smb_is_open(inode));
-#endif
+	VERBOSE("setting %s/%s, open=%d\n", DENTRY_PATH(dentry),
+		smb_is_open(inode));
+
 	smb_lock_server(server);
 	/* setting the time on a Win95 server fails (tridge) */
-	if (!(server->mnt->version & SMB_FIX_WIN95))
-	{
+	if (!(server->mnt->version & SMB_FIX_WIN95)) {
 		if (smb_is_open(inode) &&
 		    inode->u.smbfs_i.access != SMB_O_RDONLY)
 			result = smb_proc_setattr_ext(server, inode, fattr);
 		else
 			result = smb_proc_setattr_trans2(server, dentry, fattr);
-	} else
-	{
+	} else {
 		/*
 		 * Fail silently on directories ... timestamp can't be set?
 		 */
 		result = 0;
-		if (S_ISREG(inode->i_mode))
-		{
+		if (S_ISREG(inode->i_mode)) {
 			/*
 			 * Set the mtime by opening and closing the file.
 			 * Note that the file is opened read-only, but this
@@ -1929,8 +1887,7 @@
 			result = -EACCES;
 			if (!smb_is_open(inode))
 				smb_proc_open(server, dentry, SMB_O_RDONLY);
-			if (smb_is_open(inode))
-			{
+			if (smb_is_open(inode)) {
 				inode->i_mtime = fattr->f_mtime;
 				result = smb_proc_close_inode(server, inode);
 			}
@@ -1953,8 +1910,7 @@
       retry:
 	smb_setup_header(server, SMBdskattr, 0, 0);
 
-	if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0)
-	{
+	if ((error = smb_request_ok(server, SMBdskattr, 5, 0)) < 0) {
 		if (smb_retry(server))
 			goto retry;
 		goto out;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/smb_debug.h linux.17p18/fs/smbfs/smb_debug.h
--- linux.vanilla/fs/smbfs/smb_debug.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/fs/smbfs/smb_debug.h	Tue Aug  1 07:59:20 2000
@@ -0,0 +1,34 @@
+/*
+ * Defines some debug macros for smbfs.
+ */
+
+/* This makes a dentry parent/child pair. Useful for debugging printk's */
+#define DENTRY_PATH(dentry) \
+	(dentry)->d_parent->d_name.name,(dentry)->d_name.name
+
+/*
+ * safety checks that should never happen ??? 
+ * these are normally enabled.
+ */
+#ifdef SMBFS_PARANOIA
+#define PARANOIA(x...) printk(KERN_NOTICE __FUNCTION__ ": " ## x)
+#else
+#define PARANOIA(x...) do { ; } while(0)
+#endif
+
+/* lots of debug messages */
+#ifdef SMBFS_DEBUG_VERBOSE
+#define VERBOSE(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
+#else
+#define VERBOSE(x...) do { ; } while(0)
+#endif
+
+/*
+ * "normal" debug messages, but not with a normal DEBUG define ... way
+ * too common name.
+ */
+#ifdef SMBFS_DEBUG
+#define DEBUG1(x...) printk(KERN_DEBUG __FUNCTION__ ": " ## x)
+#else
+#define DEBUG1(x...) do { ; } while(0)
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/smbfs/sock.c linux.17p18/fs/smbfs/sock.c
--- linux.vanilla/fs/smbfs/sock.c	Sun Jun 11 21:44:22 2000
+++ linux.17p18/fs/smbfs/sock.c	Tue Aug  1 07:59:20 2000
@@ -4,6 +4,7 @@
  *  Copyright (C) 1995, 1996 by Paal-Kr. Engstad and Volker Lendecke
  *  Copyright (C) 1997 by Volker Lendecke
  *
+ * Please add a note about your changes to smbfs in the ChangeLog file.
  */
 
 #include <linux/sched.h>
@@ -25,8 +26,7 @@
 
 #include <asm/uaccess.h>
 
-#define SMBFS_PARANOIA 1
-/* #define SMBFS_DEBUG_VERBOSE 1 */
+#include "smb_debug.h"
 
 static int
 _recvfrom(struct socket *socket, unsigned char *ubuf, int size,
@@ -118,9 +118,7 @@
 		result = -EIO;
 		if (job->sk->dead)
 		{
-#ifdef SMBFS_PARANOIA
-			printk(KERN_DEBUG "smb_data_callback: sock dead!\n");
-#endif
+			PARANOIA("sock dead!\n");
 			break;
 		}
 
@@ -135,7 +133,7 @@
 		result = _recvfrom(socket, (void *) peek_buf, 4,
 				   MSG_DONTWAIT);
 
-		pr_debug("smb_data_callback: got SESSION KEEPALIVE\n");
+		DEBUG1("got SESSION KEEPALIVE\n");
 
 		if (result == -EAGAIN)
 			break;
@@ -154,7 +152,7 @@
 	struct data_callback* job;
 	job = kmalloc(sizeof(struct data_callback),GFP_ATOMIC);
 	if(job == 0) {
-		printk("smb_data_ready(): lost SESSION KEEPALIVE due to OOM.\n");
+		printk("smb_data_ready: lost SESSION KEEPALIVE due to OOM.\n");
 		found_data(sk);
 		return;
 	}
@@ -182,7 +180,7 @@
 	{
 #ifdef SMBFS_PARANOIA
 		if (!smb_valid_socket(file->f_dentry->d_inode))
-			printk(KERN_DEBUG "smb_server_sock: bad socket!\n");
+			PARANOIA("bad socket!\n");
 #endif
 		return &file->f_dentry->d_inode->u.socket_i;
 	}
@@ -209,13 +207,13 @@
 	sk = socket->sk;
 	if (sk == NULL)
 	{
-		pr_debug("smb_catch_keepalive: sk == NULL");
+		DEBUG1("sk == NULL");
 		server->data_ready = NULL;
 		goto out;
 	}
-	pr_debug("smb_catch_keepalive.: sk->d_r = %x, server->d_r = %x\n",
-		 (unsigned int) (sk->data_ready),
-		 (unsigned int) (server->data_ready));
+	DEBUG1("sk->d_r = %x, server->d_r = %x\n",
+	       (unsigned int) (sk->data_ready),
+	       (unsigned int) (server->data_ready));
 
 	/*
 	 * Install the callback atomically to avoid races ...
@@ -261,9 +259,9 @@
 		       "server->data_ready == NULL\n");
 		goto out;
 	}
-	pr_debug("smb_dont_catch_keepalive: sk->d_r = %x, server->d_r = %x\n",
-		 (unsigned int) (sk->data_ready),
-		 (unsigned int) (server->data_ready));
+	DEBUG1("sk->d_r = %x, server->d_r = %x\n",
+	       (unsigned int) (sk->data_ready),
+	       (unsigned int) (server->data_ready));
 
 	/*
 	 * Restore the original callback atomically to avoid races ...
@@ -272,7 +270,7 @@
 	server->data_ready = NULL;
 	if (data_ready != smb_data_ready)
 	{
-		printk("smb_dont_catch_keepalive: "
+		printk(KERN_ERR "smb_dont_catch_keepalive: "
 		       "sk->data_ready != smb_data_ready\n");
 	}
 	error = 0;
@@ -288,14 +286,11 @@
 {
 	struct file * file = server->sock_file;
 
-	if (file)
-	{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_close_socket: closing socket %p\n", server_sock(server));
-#endif
+	if (file) {
+		VERBOSE("closing socket %p\n", server_sock(server));
 #ifdef SMBFS_PARANOIA
-if (server_sock(server)->sk->data_ready == smb_data_ready)
-printk(KERN_DEBUG "smb_close_socket: still catching keepalives!\n");
+		if (server_sock(server)->sk->data_ready == smb_data_ready)
+			PARANOIA("still catching keepalives!\n");
 #endif
 		server->sock_file = NULL;
 		fput(file);
@@ -320,8 +315,7 @@
 		}
 		if (result < 0)
 		{
-			pr_debug("smb_send_raw: sendto error = %d\n",
-				 -result);
+			DEBUG1("sendto error = %d\n", -result);
 			return result;
 		}
 		already_sent += result;
@@ -347,8 +341,7 @@
 		}
 		if (result < 0)
 		{
-			pr_debug("smb_receive_raw: recvfrom error = %d\n",
-				 -result);
+			DEBUG1("recvfrom error = %d\n", -result);
 			return result;
 		}
 		already_read += result;
@@ -371,9 +364,7 @@
 
 	if (result < 0)
 	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_get_length: recv error = %d\n", -result);
-#endif
+		PARANOIA("recv error = %d\n", -result);
 		return result;
 	}
 	switch (peek_buf[0])
@@ -383,13 +374,11 @@
 		break;
 
 	case 0x85:
-		pr_debug("smb_get_length: Got SESSION KEEP ALIVE\n");
+		DEBUG1("Got SESSION KEEP ALIVE\n");
 		goto re_recv;
 
 	default:
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_get_length: Invalid NBT packet, code=%x\n", peek_buf[0]);
-#endif
+		PARANOIA("Invalid NBT packet, code=%x\n", peek_buf[0]);
 		return -EIO;
 	}
 
@@ -448,17 +437,15 @@
 	result = smb_receive_raw(socket, packet + 4, len);
 	if (result < 0)
 	{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_receive: receive error: %d\n", result);
-#endif
+		VERBOSE("receive error: %d\n", result);
 		goto out;
 	}
 	server->rcls = *(packet + smb_rcls);
 	server->err  = WVAL(packet, smb_err);
 
 #ifdef SMBFS_DEBUG_VERBOSE
-if (server->rcls != 0)
-printk(KERN_DEBUG "smb_receive: rcls=%d, err=%d\n", server->rcls, server->err);
+	if (server->rcls != 0)
+		VERBOSE("rcls=%d, err=%d\n", server->rcls, server->err);
 #endif
 out:
 	return result;
@@ -521,10 +508,10 @@
 			 */
 			if (parm_count == parm_tot && data_count == data_tot)
 			{
-#ifdef SMBFS_DEBUG_VERBOSE
-printk(KERN_DEBUG "smb_receive_trans2: fast track, parm=%u %u %u, data=%u %u %u\n",
-parm_disp, parm_offset, parm_count, data_disp, data_offset, data_count);
-#endif
+				VERBOSE("fast track, parm=%u %u %u, data=%u %u %u\n",
+					parm_disp, parm_offset, parm_count, 
+					data_disp, data_offset, data_count);
+
 				*parm  = base + parm_offset;
 				*data  = base + data_offset;
 				goto success;
@@ -561,10 +548,9 @@
 		memcpy(*parm + parm_disp, base + parm_offset, parm_count);
 		memcpy(*data + data_disp, base + data_offset, data_count);
 
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_receive_trans2: copied, parm=%u of %u, data=%u of %u\n",
-parm_len, parm_tot, data_len, data_tot);
-#endif
+		PARANOIA("copied, parm=%u of %u, data=%u of %u\n",
+			 parm_len, parm_tot, data_len, data_tot);
+
 		/*
 		 * Check whether we've received all of the data. Note that
 		 * we use the packet totals -- total lengths might shrink!
@@ -584,12 +570,9 @@
 		server->packet_size = buf_len;
 		server->packet = rcv_buf;
 		rcv_buf = inbuf;
-	} else
-	{
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_receive_trans2: copying data, old size=%d, new size=%u\n",
-server->packet_size, buf_len);
-#endif
+	} else {
+		PARANOIA("copying data, old size=%d, new size=%u\n",
+			 server->packet_size, buf_len);
 		memcpy(inbuf, rcv_buf, parm_len + data_len);
 	}
 
@@ -602,25 +585,23 @@
 	return result;
 
 out_no_mem:
-#ifdef SMBFS_PARANOIA
-	printk(KERN_DEBUG "smb_receive_trans2: couldn't allocate data area\n");
-#endif
+	printk(KERN_ERR "smb_receive_trans2: couldn't allocate data area\n");
 	result = -ENOMEM;
 	goto out;
 out_too_long:
-	printk(KERN_DEBUG "smb_receive_trans2: data/param too long, data=%d, parm=%d\n",
-		data_tot, parm_tot);
+	printk(KERN_ERR "smb_receive_trans2: data/param too long, data=%d, parm=%d\n",
+	       data_tot, parm_tot);
 	goto out_error;
 out_data_grew:
-	printk(KERN_DEBUG "smb_receive_trans2: data/params grew!\n");
+	printk(KERN_ERR "smb_receive_trans2: data/params grew!\n");
 	goto out_error;
 out_bad_parm:
-	printk(KERN_DEBUG "smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
-		parm_disp, parm_count, parm_tot);
+	printk(KERN_ERR "smb_receive_trans2: invalid parms, disp=%d, cnt=%d, tot=%d\n",
+	       parm_disp, parm_count, parm_tot);
 	goto out_error;
 out_bad_data:
-	printk(KERN_DEBUG "smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
-		data_disp, data_count, data_tot);
+	printk(KERN_ERR "smb_receive_trans2: invalid data, disp=%d, cnt=%d, tot=%d\n",
+	       data_disp, data_count, data_tot);
 out_error:
 	result = -EIO;
 	goto out;
@@ -651,7 +632,7 @@
 		goto bad_conn;
 
 	len = smb_len(buffer) + 4;
-	pr_debug("smb_request: len = %d cmd = 0x%X\n", len, buffer[8]);
+	DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
 
 	spin_lock_irqsave(&current->sigmask_lock, flags);
 	sigpipe = sigismember(&current->signal, SIGPIPE);
@@ -684,7 +665,7 @@
 		int result2 = smb_catch_keepalive(server);
 		if (result2 < 0)
 		{
-			printk(KERN_DEBUG "smb_request: catch keepalive failed\n");
+			printk(KERN_ERR "smb_request: catch keepalive failed\n");
 			result = result2;
 		}
 	}
@@ -696,28 +677,27 @@
 	if (server->rcls) {
 		int error = smb_errno(server);
 		if (error == EBADSLT) {
-			printk(KERN_DEBUG "smb_request: tree ID invalid\n");
+			printk(KERN_ERR "smb_request: tree ID invalid\n");
 			result = error;
 			goto bad_conn;
 		}
 	}
 
 out:
-	pr_debug("smb_request: result = %d\n", result);
+	DEBUG1("result = %d\n", result);
 	return result;
 	
 bad_conn:
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_request: result %d, setting invalid\n", result);
-#endif
+	PARANOIA("result %d, setting invalid\n", result);
 	server->state = CONN_INVALID;
 	smb_invalidate_inodes(server);
-	goto out;		
+	goto out;
 bad_no_packet:
-	printk(KERN_DEBUG "smb_request: no packet!\n");
+	printk(KERN_ERR "smb_request: no packet!\n");
 	goto out;
 bad_no_conn:
-	printk(KERN_DEBUG "smb_request: connection %d not valid!\n", server->state);
+	printk(KERN_ERR "smb_request: connection %d not valid!\n",
+	       server->state);
 	goto out;
 }
 
@@ -736,16 +716,15 @@
 
 	const int smb_parameters = 15;
 	const int oparam =
-	ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3);
+		ROUND_UP(SMB_HEADER_LEN + 2 * smb_parameters + 2 + 3);
 	const int odata =
-	ROUND_UP(oparam + lparam);
+		ROUND_UP(oparam + lparam);
 	const int bcc =
-	odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2);
+		odata + ldata - (SMB_HEADER_LEN + 2 * smb_parameters + 2);
 	const int packet_length =
-	SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2;
+		SMB_HEADER_LEN + 2 * smb_parameters + bcc + 2;
 
-	unsigned char padding[4] =
-	{0,};
+	unsigned char padding[4] = {0,};
 	char *p;
 
 	struct iovec iov[4];
@@ -819,8 +798,7 @@
 	mm_segment_t fs;
 	int result;
 
-	pr_debug("smb_trans2_request: com=%d, ld=%d, lp=%d\n",
-		 trans2_command, ldata, lparam);
+	DEBUG1("com=%d, ld=%d, lp=%d\n", trans2_command, ldata, lparam);
 
 	/*
 	 * These are initialized in smb_request_ok, but not here??
@@ -879,7 +857,7 @@
 	if (server->rcls) {
 		int error = smb_errno(server);
 		if (error == EBADSLT) {
-			printk(KERN_DEBUG "smb_request: tree ID invalid\n");
+			printk(KERN_ERR "smb_request: tree ID invalid\n");
 			result = error;
 			goto bad_conn;
 		}
@@ -889,9 +867,7 @@
 	return result;
 
 bad_conn:
-#ifdef SMBFS_PARANOIA
-printk(KERN_DEBUG "smb_trans2_request: result=%d, setting invalid\n", result);
-#endif
+	PARANOIA("result=%d, setting invalid\n", result);
 	server->state = CONN_INVALID;
 	smb_invalidate_inodes(server);
 	goto out;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/ufs/acl.c linux.17p18/fs/ufs/acl.c
--- linux.vanilla/fs/ufs/acl.c	Fri Apr 21 12:46:45 2000
+++ linux.17p18/fs/ufs/acl.c	Tue Aug  1 07:59:21 2000
@@ -61,7 +61,7 @@
 	if (((mode & mask & S_IRWXO) == mask) || capable(CAP_DAC_OVERRIDE))
 		return 0;
 	if ((mask == S_IROTH) ||
-	    (S_ISDIR(mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
+	    (S_ISDIR(inode->i_mode)  && !(mask & ~(S_IROTH | S_IXOTH))))
 		if (capable(CAP_DAC_READ_SEARCH))
 			return 0;
 	return -EACCES;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/umsdos/README-WIP.txt linux.17p18/fs/umsdos/README-WIP.txt
--- linux.vanilla/fs/umsdos/README-WIP.txt	Fri Apr 21 12:46:46 2000
+++ linux.17p18/fs/umsdos/README-WIP.txt	Tue Aug  1 07:59:21 2000
@@ -5,20 +5,16 @@
 There is no warning any more.
 Both read-only and read-write stuff is fixed, both in
 msdos-compatibile mode, and in umsdos EMD mode, and it seems stable.
-There are still few hardlink nuisances, but those are not fatal.
-
-I'd call it pre-release, and ask for as many people as possible to
-come and test it! See notes below for some more information, or if
-you are trying to use UMSDOS as root partition.
 
 Userland NOTE: new umsdos_progs (umssync, umssetup, udosctl & friends) that
-will compile and work on 2.2.x kernels and glibc based systems may be found
-at http://cvs.linux.hr/
+will compile and work on 2.2.x+ kernels and glibc based systems, as well as
+kernel patches and other umsdos related information may be found at
+http://linux.voyager.hr/umsdos/
 
 Legend: those lines marked with '+' on the beggining of line indicates it
 passed all of my tests, and performed perfect in all of them.
 
-Current status (000123) - UMSDOS 0.85g:
+Current status (000729) - UMSDOS 0.85i:
 
 (1) pure MSDOS (no --linux-.--- EMD file):
 
@@ -29,7 +25,7 @@
 
 WRITE:
 + creat file			- works
-+ delete file			- works
++ unlink file			- works
 + write file			- works
 + rename file (same dir)	- works
 + rename file (dif. dir)	- works
@@ -49,7 +45,7 @@
 + read file			- works
 + switching MSDOS/UMSDOS	- works
 + switching UMSDOS/MSDOS	- works
-- pseudo root things		- works mostly. See notes below.
+- pseudo root things		- works. See notes below.
 + resolve symlink		- works
 + dereference symlink		- works
 + dangling symlink		- works
@@ -60,21 +56,21 @@
 
 WRITE:
 + create symlink		- works
-- create hardlink		- works for same DIR (see notes)
++ create hardlink		- works
 + create file			- works
 + create special file		- works
 + write to file			- works
 + rename file (same dir)	- works
 + rename file (dif. dir)	- works
 + rename hardlink (same dir)	- works
-- rename hardlink (dif. dir)	-
++ rename hardlink (dif. dir)	- works
 + rename symlink (same dir)	- works
 + rename symlink (dif. dir)	- works
 + rename dir (same dir)		- works
 + rename dir (dif. dir)		- works
 + delete file			- works
 + notify_change (chown,perms)	- works
-- delete hardlink		- works for same DIR (see notes)
++ delete hardlink		- works
 + mkdir				- works
 + rmdir 			- works
 + umssyncing (many ioctls)	- works
@@ -91,26 +87,13 @@
 Note: creating and using pseudo-hardlinks is always non-perfect, especially
 in filesystems that might be externally modified like umsdos. There is
 example is specs file about it. Specifically, moving directory which
-contains hardlinks will break them.
-
-Note: (about pseudoroot) If you are currently trying to use UMSDOS as root
-partition (with linux installed in c:\linux) it will boot, but there may be
-some problems. Volunteers ready to test pseudoroot are needed (preferably
-ones with working backups or unimportant data).  For example, '/DOS' pseudo
-directory is only partially re-implemented and buggy. It works most of the
-time, though. Update: should work ok in 0.84, although it still does not
-work correctly in combination with initrd featere. Working on this!
+contains hardlinks will break them in some cases.
 
 Note: (about creating hardlinks in pseudoroot mode) - hardlinks created in
 pseudoroot mode are now again compatibile with 'normal' hardlinks, and vice
 versa. Thanks to Sorin Iordachescu <sorin@rodae.ro> for providing fix.
-
-Warning: (about hardlinks) - modifying hardlinks (esp. if they are in
-different directories) are currently somewhat broken, I'm working on it.
-Problem seems to be that code uses and updates EMD of directory where 'real
-hardlink' is stored, not EMD of directory where our pseudo-hardlink is
-located! I'm looking for ideas how to work around this in clean way, since
-without it modifying hardlinks in any but most simple ways is broken!
+See http://linux.voyager.hr/umsdos/hlbug.html for more info and upgrade
+procedure if you used broken versions...
 
 ------------------------------------------------------------------------------
 
@@ -124,6 +107,5 @@
 I'm unfortunately somewhat out of time to read linux-kernel@vger, but I do
 check for messages having "UMSDOS" in the subject, and read them.  I might
 miss some in all that volume, though.  I should reply to any direct e-mail
-in few days.  If I don't, probably I never got your message.  You can try
-mnalis-umsdos@voyager.hr; however mnalis@jagor.srce.hr is preferable.
+in few days.  If I don't, probably I never got your message.
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/umsdos/emd.c linux.17p18/fs/umsdos/emd.c
--- linux.vanilla/fs/umsdos/emd.c	Fri Apr 21 12:46:46 2000
+++ linux.17p18/fs/umsdos/emd.c	Tue Aug  1 07:59:22 2000
@@ -273,6 +273,16 @@
 	Printk ((KERN_DEBUG "umsdos_emd_dir_readentry /mn/: entering.\n"));
 
 	ret = umsdos_emd_dir_read (filp, (char *) entry, UMSDOS_REC_SIZE);
+
+	/* if this is an invalid entry (invalid name length), ignore it */
+	if( entry->name_len > UMSDOS_MAXNAME )
+	{
+		printk (KERN_WARNING "Ignoring invalid EMD entry with size %d\n", entry->name_len);
+		entry->name_len = 0; 
+		ret = -ENAMETOOLONG; /* notify umssync(8) code that something is wrong */
+	}
+
+
 	if (ret == 0) {	/* if no error */
 		/* Variable size record. Maybe, we have to read some more */
 		int recsize = umsdos_evalrecsize (entry->name_len);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/umsdos/inode.c linux.17p18/fs/umsdos/inode.c
--- linux.vanilla/fs/umsdos/inode.c	Fri Apr 21 12:46:46 2000
+++ linux.17p18/fs/umsdos/inode.c	Tue Aug  1 07:59:22 2000
@@ -56,8 +56,7 @@
 		 ,inode->i_count));
 
 	if (inode == pseudo_root) {
-		printk (KERN_ERR "Umsdos: Oops releasing pseudo_root."
-			" Notify jacques@solucorp.qc.ca\n");
+		printk (KERN_ERR "Umsdos: debug: releasing pseudo_root - ino=%lu count=%d\n", inode->i_ino, inode->i_count);
 	}
 
 	if (inode->i_count == 1)
@@ -180,21 +179,6 @@
 }
 
 
-int umsdos_notify_change_locked(struct dentry *, struct iattr *);
-/*
- * lock the parent dir before starting ...
- */
-int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
-{
-	struct inode *dir = dentry->d_parent->d_inode;
-	int ret;
-
-	down(&dir->i_sem);
-	ret = umsdos_notify_change_locked(dentry, attr);
-	up(&dir->i_sem);
-	return ret;
-}
-
 /*
  * Must be called with the parent lock held.
  */
@@ -300,6 +284,65 @@
 
 
 /*
+ * lock the parent dir before starting ...
+ * also handles hardlink converting
+ */
+int UMSDOS_notify_change (struct dentry *dentry, struct iattr *attr)
+{
+	struct inode *dir;
+	struct umsdos_info info;
+	struct dentry *temp, *old_dentry = NULL;
+	int ret;
+
+	ret = umsdos_parse (dentry->d_name.name, dentry->d_name.len,
+				&info);
+	if (ret)
+		goto out;
+	ret = umsdos_findentry (dentry->d_parent, &info, 0);
+	if (ret) {
+printk("UMSDOS_notify_change: %s/%s not in EMD, ret=%d\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, ret);
+		goto out;
+	}
+
+	if (info.entry.flags & UMSDOS_HLINK) {
+		/*
+		 * In order to get the correct (real) inode, we just drop
+		 * the original dentry.
+		 */ 
+		d_drop(dentry);
+Printk(("UMSDOS_notify_change: hard link %s/%s, fake=%s\n",
+dentry->d_parent->d_name.name, dentry->d_name.name, info.fake.fname));
+	
+		/* Do a real lookup to get the short name dentry */
+		temp = umsdos_covered(dentry->d_parent, info.fake.fname,
+						info.fake.len);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out;
+	
+		/* now resolve the link ... */
+		temp = umsdos_solve_hlink(temp);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out;
+		old_dentry = dentry;
+		dentry = temp;	/* so umsdos_notify_change_locked will operate on that */
+	}
+
+	dir = dentry->d_parent->d_inode;
+
+	down(&dir->i_sem);
+	ret = umsdos_notify_change_locked(dentry, attr);
+	up(&dir->i_sem);
+out:
+	if (old_dentry)
+		dput (dentry);	/* if we had to use fake dentry for hardlinks, dput() it now */
+	return ret;
+}
+
+
+/*
  * Update the disk with the inode content
  */
 void UMSDOS_write_inode (struct inode *inode)
@@ -332,11 +375,28 @@
 	UMSDOS_notify_change,	/* notify_change */
 	UMSDOS_put_super,	/* put_super */
 	NULL,			/* write_super */
-	fat_statfs,		/* statfs */
+	UMSDOS_statfs,		/* statfs */
 	NULL,			/* remount_fs */
 	fat_clear_inode,	/* clear_inode */
 };
 
+
+int UMSDOS_statfs(struct super_block *sb,struct statfs *buf, int bufsiz)
+{
+	int ret;
+	struct statfs tmp;
+	
+	ret = fat_statfs (sb, buf, bufsiz);
+	copy_from_user (&tmp, buf, bufsiz);
+	if (!ret) {
+		copy_from_user (&tmp, buf, bufsiz);
+		tmp.f_namelen = UMSDOS_MAXNAME;
+		copy_to_user (buf, &tmp, bufsiz);
+	}
+	return ret;
+}
+
+
 /*
  * Read the super block of an Extended MS-DOS FS.
  */
@@ -356,7 +416,7 @@
 	if (!res)
 		goto out_fail;
 
-	printk (KERN_INFO "UMSDOS 0.85g "
+	printk (KERN_INFO "UMSDOS 0.85i "
 		"(compatibility level %d.%d, fast msdos)\n", 
 		UMSDOS_VERSION, UMSDOS_RELEASE);
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/umsdos/ioctl.c linux.17p18/fs/umsdos/ioctl.c
--- linux.vanilla/fs/umsdos/ioctl.c	Fri Apr 21 12:46:46 2000
+++ linux.17p18/fs/umsdos/ioctl.c	Tue Aug  1 07:59:22 2000
@@ -179,6 +179,17 @@
 			struct umsdos_info info;
 
 			ret = umsdos_emd_dir_readentry (&new_filp, &entry);
+
+			if (ret == -ENAMETOOLONG) {
+				printk (KERN_INFO "Fixing EMD entry with invalid size -- zeroing out\n");
+				fill_new_filp (&new_filp, demd);
+				new_filp.f_pos = f_pos;
+				new_filp.f_reada = 0;
+				memset (&entry, 0, sizeof (entry));
+				ret = umsdos_emd_dir_write (&new_filp, (char *) &entry, UMSDOS_REC_SIZE);
+				continue;
+			}
+
 			if (ret)
 				break;
 			if (entry.name_len <= 0)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/fs/umsdos/namei.c linux.17p18/fs/umsdos/namei.c
--- linux.vanilla/fs/umsdos/namei.c	Fri Apr 21 12:46:46 2000
+++ linux.17p18/fs/umsdos/namei.c	Tue Aug  1 07:59:22 2000
@@ -715,17 +715,35 @@
 	if (ret == 0) {
 		struct iattr newattrs;
 
+		/* Do a real lookup to get the short name dentry */
+		temp = umsdos_covered(olddentry->d_parent,
+					old_info.fake.fname,
+					old_info.fake.len);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out_unlock2;
+
+		/* now resolve the link ... */
+		temp = umsdos_solve_hlink(temp);
+		ret = PTR_ERR(temp);
+		if (IS_ERR(temp))
+			goto out_unlock2;
+
 #ifdef UMSDOS_PARANOIA
 if (!oldinode->u.umsdos_i.i_is_hlink)
 printk("UMSDOS_link: %s/%s, ino=%ld, not marked as hlink!\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name, oldinode->i_ino);
 #endif
-		oldinode->i_nlink++;
+		temp->d_inode->i_nlink++;
 Printk(("UMSDOS_link: linked %s/%s, ino=%ld, nlink=%d\n",
 olddentry->d_parent->d_name.name, olddentry->d_name.name,
 oldinode->i_ino, oldinode->i_nlink));
 		newattrs.ia_valid = 0;
-		ret = umsdos_notify_change_locked(olddentry, &newattrs);
+		ret = umsdos_notify_change_locked(temp, &newattrs);
+ 		if (ret == 0)
+			mark_inode_dirty(temp->d_inode);
+		dput(temp);
+out_unlock2:	
 	}
 	if (olddir != dir)
 		up(&olddir->i_sem);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-alpha/bitops.h linux.17p18/include/asm-alpha/bitops.h
--- linux.vanilla/include/asm-alpha/bitops.h	Fri Apr 21 12:46:47 2000
+++ linux.17p18/include/asm-alpha/bitops.h	Mon Aug 14 20:13:04 2000
@@ -271,6 +271,8 @@
 	tmp = *p;
 found_first:
 	tmp |= ~0UL << size;
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
 found_middle:
 	return result + ffz(tmp);
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-alpha/unistd.h linux.17p18/include/asm-alpha/unistd.h
--- linux.vanilla/include/asm-alpha/unistd.h	Fri Apr 21 12:46:48 2000
+++ linux.17p18/include/asm-alpha/unistd.h	Tue Aug  1 08:00:00 2000
@@ -315,7 +315,7 @@
 #define __NR_mincore			375	/* implemented in 2.3 */
 #define __NR_pciconfig_iobase		376
 
-#if defined(__LIBRARY__) && defined(__GNUC__)
+#if defined(__GNUC__)
 
 #define _syscall_return(type)						\
 	return (_sc_err ? errno = _sc_ret, _sc_ret = -1L : 0), (type) _sc_ret
@@ -495,7 +495,7 @@
 	_syscall_return(type);						\
 }
 
-#endif /* __LIBRARY__ && __GNUC__ */
+#endif /* __GNUC__ */
 
 #ifdef __KERNEL_SYSCALLS__
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-i386/processor.h linux.17p18/include/asm-i386/processor.h
--- linux.vanilla/include/asm-i386/processor.h	Fri Apr 21 23:10:16 2000
+++ linux.17p18/include/asm-i386/processor.h	Tue Aug  1 08:38:20 2000
@@ -48,6 +48,8 @@
 #define X86_VENDOR_UMC 3
 #define X86_VENDOR_NEXGEN 4
 #define X86_VENDOR_CENTAUR 5
+#define X86_VENDOR_RISE 6
+#define X86_VENDOR_TRANSMETA 7
 #define X86_VENDOR_UNKNOWN 0xff
 
 /*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/bitops.h linux.17p18/include/asm-ppc/bitops.h
--- linux.vanilla/include/asm-ppc/bitops.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/bitops.h	Wed Aug 16 21:41:39 2000
@@ -104,6 +104,8 @@
 	tmp = *p;
 found_first:
 	tmp |= ~0UL << size;
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
 found_middle:
 	return result + ffz(tmp);
 }
@@ -194,6 +196,8 @@
 	tmp = cpu_to_le32p(p);
 found_first:
 	tmp |= ~0U << size;
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
 found_middle:
 	return result + ffz(tmp);
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/bootx.h linux.17p18/include/asm-ppc/bootx.h
--- linux.vanilla/include/asm-ppc/bootx.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/bootx.h	Tue Aug  1 08:00:03 2000
@@ -133,4 +133,3 @@
 #endif
 
 #endif
-    
\ No newline at end of file
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/elf.h linux.17p18/include/asm-ppc/elf.h
--- linux.vanilla/include/asm-ppc/elf.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/elf.h	Tue Aug  1 08:00:03 2000
@@ -5,9 +5,11 @@
  * ELF register definitions..
  */
 #include <asm/ptrace.h>
+#include <asm/types.h>
 
 #define ELF_NGREG	48	/* includes nip, msr, lr, etc. */
 #define ELF_NFPREG	33	/* includes fpscr */
+#define ELF_NVRREG	33	/* includes vscr */
 
 /*
  * This is used to ensure we don't load something for the wrong architecture.
@@ -36,6 +38,10 @@
 
 typedef double elf_fpreg_t;
 typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/* Altivec registers */
+typedef vector128 elf_vrreg_t;
+typedef elf_vrreg_t elf_vrregset_t[ELF_NVRREG];
 
 #define ELF_CORE_COPY_REGS(gregs, regs) \
 	memcpy(gregs, regs, \
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/feature.h linux.17p18/include/asm-ppc/feature.h
--- linux.vanilla/include/asm-ppc/feature.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/feature.h	Tue Aug  1 08:00:03 2000
@@ -8,12 +8,13 @@
  * for more details.
  *
  * Copyright (C) 1998 Paul Mackerras.
+ * 
  */
 #ifndef __ASM_PPC_FEATURE_H
 #define __ASM_PPC_FEATURE_H
 
 /*
- * The FCR bits for particular features vary somewhat between
+ * The FCR selector for particular features vary somewhat between
  * different machines.  So we abstract a list of features here
  * and let the feature_* routines map them to the actual bits.
  */
@@ -25,19 +26,25 @@
 	FEATURE_Serial_IO_B,
 	FEATURE_SWIM3_enable,
 	FEATURE_MESH_enable,
-	FEATURE_IDE_enable,
-	FEATURE_VIA_enable,
-	FEATURE_CD_power,
+	FEATURE_IDE0_enable,		/* Internal IDE */
+	FEATURE_IDE0_reset,		/* Internal IDE */
+	FEATURE_IOBUS_enable,		/* Internal IDE */
 	FEATURE_Mediabay_reset,
-	FEATURE_Mediabay_enable,
+	FEATURE_Mediabay_power,
 	FEATURE_Mediabay_PCI_enable,
-	FEATURE_Mediabay_IDE_enable,
+	FEATURE_IDE1_enable,		/* MediaBay IDE */
+	FEATURE_IDE1_reset,		/* MediaBay IDE */
 	FEATURE_Mediabay_floppy_enable,
 	FEATURE_BMac_reset,
 	FEATURE_BMac_IO_enable,
-	FEATURE_Modem_Reset,
-	FEATURE_IDE_DiskPower,
-	FEATURE_IDE_Reset,
+	FEATURE_Modem_power,
+	FEATURE_Slow_SCC_PCLK,
+	FEATURE_Sound_power,
+	FEATURE_Sound_CLK_enable,
+	FEATURE_IDE2_enable,
+	FEATURE_IDE2_reset,
+	FEATURE_Mediabay_IDE_switch,	/* MB IDE bus switch */
+	FEATURE_Mediabay_content,	/* MB content indicator enable */
 	FEATURE_last,
 };
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/heathrow.h linux.17p18/include/asm-ppc/heathrow.h
--- linux.vanilla/include/asm-ppc/heathrow.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/asm-ppc/heathrow.h	Tue Aug  1 08:00:03 2000
@@ -0,0 +1,47 @@
+/*
+ * heathrow.h: definitions for using the "Heathrow" I/O controller chip.
+ *
+ * Grabbed from Open Firmware definitions on a PowerBook G3 Series
+ *
+ * Copyright (C) 1997 Paul Mackerras.
+ */
+
+/* offset from ohare base for feature control register */
+#define HEATHROW_FEATURE_REG	0x38
+
+/*
+ * Bits in feature control register.
+ * Bits postfixed with a _N are in inverse logic
+ */
+#define HRW_RESET_SCC		0x00000001	/* Named in_use_led in OF ??? */
+#define HRW_BAY_POWER_N		0x00000002
+#define HRW_BAY_PCI_ENABLE	0x00000004
+#define HRW_BAY_IDE_ENABLE	0x00000008
+#define HRW_BAY_FLOPPY_ENABLE	0x00000010
+#define HRW_IDE0_ENABLE		0x00000020
+#define HRW_IDE0_RESET_N	0x00000040
+#define HRW_BAY_RESET_N		0x00000080
+#define HRW_IOBUS_ENABLE	0x00000100	/* Internal IDE ? */
+#define HRW_SCC_ENABLE		0x00000200
+#define HRW_MESH_ENABLE		0x00000400
+#define HRW_SWIM_ENABLE		0x00000800
+#define HRW_SOUND_POWER_N	0x00001000
+#define HRW_SOUND_CLK_ENABLE	0x00002000
+#define HRW_SCCA_IO		0x00004000
+#define HRW_SCCB_IO		0x00008000
+#define HRW_PORT_OR_DESK_VIA_N	0x00010000	/* This one is 0 on PowerBook */
+#define HRW_PWM_MON_ID_N	0x00020000	/* ??? (0) */
+#define HRW_HOOK_MB_CNT_N	0x00040000	/* ??? (0) */
+#define HRW_SWIM_CLONE_FLOPPY	0x00080000	/* ??? (0) */
+#define HRW_AUD_RUN22		0x00100000	/* ??? (1) */
+#define HRW_SCSI_LINK_MODE	0x00200000	/* Read ??? (1) */
+#define HRW_ARB_BYPASS		0x00400000	/* ??? (0 on main, 1 on gatwick) */
+#define HRW_IDE1_RESET_N	0x00800000	/* Media bay */
+#define HRW_SLOW_SCC_PCLK	0x01000000	/* ??? (0) */
+#define HRW_MODEM_POWER_N	0x02000000	/* Used by internal modem on wallstreet */
+#define HRW_MFDC_CELL_ENABLE	0x04000000	/* ??? (0) */
+#define HRW_USE_MFDC		0x08000000	/* ??? (0) */
+#define HRW_BMAC_IO_ENABLE	0x60000000	/* two bits, not documented in OF */
+#define HRW_BMAC_RESET		0x80000000	/* not documented in OF */
+
+#define PADD_MODEM_POWER_N	0x00000001	/* modem power on paddington */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/ide.h linux.17p18/include/asm-ppc/ide.h
--- linux.vanilla/include/asm-ppc/ide.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/ide.h	Tue Aug  1 08:00:03 2000
@@ -63,16 +63,6 @@
 void ide_outsw(ide_ioreg_t port, void *buf, int ns);
 void ppc_generic_ide_fix_driveid(struct hd_driveid *id);
 
-#undef insw
-#define insw(port, buf, ns) 	do {				\
-	ppc_ide_md.insw((port), (buf), (ns));			\
-} while (0)
-     
-#undef outsw
-#define outsw(port, buf, ns) 	do {				\
-	ppc_ide_md.outsw((port), (buf), (ns));			\
-} while (0)
-
 #undef	SUPPORT_SLOW_DATA_PORTS
 #define	SUPPORT_SLOW_DATA_PORTS	0
 #undef	SUPPORT_VLB_SYNC
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/io.h linux.17p18/include/asm-ppc/io.h
--- linux.vanilla/include/asm-ppc/io.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/io.h	Tue Aug  1 08:00:03 2000
@@ -54,10 +54,10 @@
 
 #define insb(port, buf, ns)	_insb((unsigned char *)((port)+_IO_BASE), (buf), (ns))
 #define outsb(port, buf, ns)	_outsb((unsigned char *)((port)+_IO_BASE), (buf), (ns))
-#define insw(port, buf, ns)	_insw((unsigned short *)((port)+_IO_BASE), (buf), (ns))
-#define outsw(port, buf, ns)	_outsw((unsigned short *)((port)+_IO_BASE), (buf), (ns))
-#define insl(port, buf, nl)	_insl((unsigned long *)((port)+_IO_BASE), (buf), (nl))
-#define outsl(port, buf, nl)	_outsl((unsigned long *)((port)+_IO_BASE), (buf), (nl))
+#define insw(port, buf, ns)	_insw_ns((unsigned short *)((port)+_IO_BASE), (buf), (ns))
+#define outsw(port, buf, ns)	_outsw_ns((unsigned short *)((port)+_IO_BASE), (buf), (ns))
+#define insl(port, buf, nl)	_insl_ns((unsigned long *)((port)+_IO_BASE), (buf), (nl))
+#define outsl(port, buf, nl)	_outsl_ns((unsigned long *)((port)+_IO_BASE), (buf), (nl))
 
 #define inb(port)		in_8((unsigned char *)((port)+_IO_BASE))
 #define outb(val, port)		out_8((unsigned char *)((port)+_IO_BASE), (val))
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/keyboard.h linux.17p18/include/asm-ppc/keyboard.h
--- linux.vanilla/include/asm-ppc/keyboard.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/keyboard.h	Tue Aug  1 08:00:03 2000
@@ -72,8 +72,7 @@
 }
 
 #define kbd_sysrq_xlate	(ppc_md.kbd_sysrq_xlate)
-
-#define SYSRQ_KEY 0x54
+#define SYSRQ_KEY (ppc_md.SYSRQ_KEY)
 
 /* resource allocation */
 #define kbd_request_region()
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/machdep.h linux.17p18/include/asm-ppc/machdep.h
--- linux.vanilla/include/asm-ppc/machdep.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/machdep.h	Tue Aug  1 08:00:03 2000
@@ -50,6 +50,7 @@
 	void		(*kbd_init_hw)(void);
 #ifdef CONFIG_MAGIC_SYSRQ
 	unsigned char 	*kbd_sysrq_xlate;
+	unsigned long	SYSRQ_KEY;
 #endif
 
 	/* PCI interfaces */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/mediabay.h linux.17p18/include/asm-ppc/mediabay.h
--- linux.vanilla/include/asm-ppc/mediabay.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/mediabay.h	Tue Aug  1 08:00:03 2000
@@ -7,11 +7,16 @@
 #ifndef _PPC_MEDIABAY_H
 #define _PPC_MEDIABAY_H
 
+#ifdef __KERNEL__
+
+/* We keep those constants local to the kernel to avoid
+ * compatibility problems with different HW. A /proc inteface
+ * could be defined to tell userland about the content of the bay
+ */
 #define MB_FD	0		/* media bay contains floppy drive */
+#define MB_FD1	1		/* media bay contains floppy drive */
 #define MB_CD	3		/* media bay contains ATA drive such as CD */
-#define MB_NO	7		/* media bay contains nothing */
-
-#ifdef __KERNEL__
+#define MB_NO	0xF		/* media bay contains nothing */
 
 void media_bay_init(void);
 int check_media_bay(struct device_node *which_bay, int what);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/nvram.h linux.17p18/include/asm-ppc/nvram.h
--- linux.vanilla/include/asm-ppc/nvram.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/nvram.h	Tue Aug  1 08:00:03 2000
@@ -14,13 +14,13 @@
 
 #define MOTO_RTC_SECONDS		0x1FF9
 #define MOTO_RTC_MINUTES		0x1FFA
-#define MOTO_RTC_HOURS		0x1FFB
+#define MOTO_RTC_HOURS			0x1FFB
 #define MOTO_RTC_DAY_OF_WEEK		0x1FFC
-#define MOTO_RTC_DAY_OF_MONTH	0x1FFD
-#define MOTO_RTC_MONTH		0x1FFE
-#define MOTO_RTC_YEAR		0x1FFF
-#define MOTO_RTC_CONTROLA            0x1FF8
-#define MOTO_RTC_CONTROLB            0x1FF9
+#define MOTO_RTC_DAY_OF_MONTH		0x1FFD
+#define MOTO_RTC_MONTH			0x1FFE
+#define MOTO_RTC_YEAR			0x1FFF
+#define MOTO_RTC_CONTROLA        	0x1FF8
+#define MOTO_RTC_CONTROLB        	0x1FF9
 
 #ifndef BCD_TO_BIN
 #define BCD_TO_BIN(val) ((val)=((val)&15) + ((val)>>4)*10)
@@ -29,5 +29,31 @@
 #ifndef BIN_TO_BCD
 #define BIN_TO_BCD(val) ((val)=(((val)/10)<<4) + (val)%10)
 #endif
+
+/* PowerMac specific nvram stuffs */
+
+enum {
+	pmac_nvram_OF,		/* Open Firmware partition */
+	pmac_nvram_XPRAM,	/* MacOS XPRAM partition */
+	pmac_nvram_NR		/* MacOS Name Registry partition */
+};
+
+/* Return partition offset in nvram */
+extern int	pmac_get_partition(int partition);
+
+/* Direct access to XPRAM */
+extern u8	pmac_xpram_read(int xpaddr);
+extern void	pmac_xpram_write(int xpaddr, u8 data);
+
+/* Some offsets in XPRAM */
+#define PMAC_XPRAM_MACHINE_LOC	0xe4
+#define PMAC_XPRAM_SOUND_VOLUME	0x08
+
+/* Machine location structure in XPRAM */
+struct pmac_machine_location {
+	u32	latitude;	/* 2+30 bit Fractional number */
+	u32	longitude;	/* 2+30 bit Fractional number */
+	u32	delta;		/* mix of GMT delta and DLS */
+};
 
 #endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/ohare.h linux.17p18/include/asm-ppc/ohare.h
--- linux.vanilla/include/asm-ppc/ohare.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/ohare.h	Tue Aug  1 08:00:03 2000
@@ -2,6 +2,9 @@
  * ohare.h: definitions for using the "O'Hare" I/O controller chip.
  *
  * Copyright (C) 1997 Paul Mackerras.
+ * 
+ * BenH: Changed to match those of heathrow (but not all of them). Please
+ *       check if I didn't break anything (especially the media bay).
  */
 
 /* offset from ohare base for feature control register */
@@ -13,21 +16,21 @@
  * and may differ for other machines.
  */
 #define OH_SCC_RESET		1
-#define OH_BAY_RESET		2	/* a guess */
+#define OH_BAY_POWER_N		2	/* a guess */
 #define OH_BAY_PCI_ENABLE	4	/* a guess */
 #define OH_BAY_IDE_ENABLE	8
 #define OH_BAY_FLOPPY_ENABLE	0x10
-#define OH_IDE_ENABLE		0x20
-#define OH_IDE_POWER		0x40	/* a guess */
-#define OH_BAY_ENABLE		0x80
-#define OH_IDE_RESET		0x100	/* 0-based, a guess */
+#define OH_IDE0_ENABLE		0x20
+#define OH_IDE0_RESET_N		0x40	/* a guess */
+#define OH_BAY_RESET_N		0x80
+#define OH_IOBUS_ENABLE		0x100	/* IOBUS seems to be IDE */
 #define OH_SCC_ENABLE		0x200
 #define OH_MESH_ENABLE		0x400
 #define OH_FLOPPY_ENABLE	0x800
 #define OH_SCCA_IO		0x4000
 #define OH_SCCB_IO		0x8000
-#define OH_VIA_ENABLE		0x10000
-#define OH_IDECD_POWER		0x800000
+#define OH_VIA_ENABLE		0x10000	/* Is apparently wrong, to be verified */
+#define OH_IDE1_RESET_N		0x800000
 
 /*
  * Bits to set in the feature control register on PowerBooks.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/page.h linux.17p18/include/asm-ppc/page.h
--- linux.vanilla/include/asm-ppc/page.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/page.h	Tue Aug  1 08:00:03 2000
@@ -64,7 +64,7 @@
 #define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
 
 extern void clear_page(unsigned long page);
-#define copy_page(to,from)	memcpy((void *)(to), (void *)(from), PAGE_SIZE)
+extern void copy_page(unsigned long to, unsigned long from);
 
 /* map phys->virtual and virtual->phys for RAM pages */
 #ifdef CONFIG_APUS
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/pmu.h linux.17p18/include/asm-ppc/pmu.h
--- linux.vanilla/include/asm-ppc/pmu.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/pmu.h	Fri Aug  4 15:27:32 2000
@@ -26,9 +26,11 @@
 #define PMU_INT_ACK		0x78	/* read interrupt bits */
 #define PMU_SHUTDOWN		0x7e	/* turn power off */
 #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 */
 #define PMU_GET_BRIGHTBUTTON	0xd9	/* report brightness up/down pos */
 #define PMU_GET_COVER		0xdc	/* report cover open/closed */
+#define PMU_SYSTEM_READY	0xdf	/* tell PMU we are awake */
 
 /* Bits to use with the PMU_POWER_CTRL command */
 #define PMU_POW_ON		0x80	/* OR this to power ON the device */
@@ -51,8 +53,28 @@
 	PMU_OHARE_BASED,	/* 2400, 3400, 3500 (old G3 powerbook) */
 	PMU_HEATHROW_BASED,	/* PowerBook G3 series */
 	PMU_PADDINGTON_BASED,	/* 1999 PowerBook G3 */
+	PMU_KEYLARGO_BASED,	/* Core99 motherboard (PMU99) */
 };
 
+/* PMU PMU_POWER_EVENTS commands */
+enum {
+	PMU_PWR_GET_POWERUP_EVENTS	= 0x00,
+	PMU_PWR_SET_POWERUP_EVENTS	= 0x01,
+	PMU_PWR_CLR_POWERUP_EVENTS	= 0x02,
+	PMU_PWR_GET_WAKEUP_EVENTS	= 0x03,
+	PMU_PWR_SET_WAKEUP_EVENTS	= 0x04,
+	PMU_PWR_CLR_WAKEUP_EVENTS	= 0x05,
+};
+
+/* Power events wakeup bits */
+enum {
+	PMU_PWR_WAKEUP_KEY		= 0x01,	/* Wake on key press */
+	PMU_PWR_WAKEUP_AC_INSERT	= 0x02, /* Wake on AC adapter plug */
+	PMU_PWR_WAKEUP_AC_CHANGE	= 0x04,
+	PMU_PWR_WAKEUP_LID_OPEN		= 0x08,
+	PMU_PWR_WAKEUP_RING		= 0x10,
+};
+	
 /*
  * Ioctl commands for the /dev/pmu device
  */
@@ -64,8 +86,10 @@
 #define PMU_IOC_GET_BACKLIGHT	_IOR('B', 1, sizeof(__u32*))
 /* in param: u32	backlight value: 0 to 31 */
 #define PMU_IOC_SET_BACKLIGHT	_IOW('B', 2, sizeof(__u32))
-/* out param: u32*	backlight value: 0 to 31 */
+/* out param: u32*	PMU model */
 #define PMU_IOC_GET_MODEL	_IOR('B', 3, sizeof(__u32*))
+/* out param: u32*	has_adb: 0 or 1 */
+#define PMU_IOC_HAS_ADB		_IOR('B', 4, sizeof(__u32*)) 
 
 #ifdef __KERNEL__
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/posix_types.h linux.17p18/include/asm-ppc/posix_types.h
--- linux.vanilla/include/asm-ppc/posix_types.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/posix_types.h	Fri Aug  4 15:27:32 2000
@@ -15,7 +15,7 @@
 typedef int		__kernel_pid_t;
 typedef unsigned int	__kernel_uid_t;
 typedef unsigned int	__kernel_gid_t;
-typedef unsigned long	__kernel_size_t;
+typedef unsigned int	__kernel_size_t;
 typedef long		__kernel_ssize_t;
 typedef long		__kernel_ptrdiff_t;
 typedef long		__kernel_time_t;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/processor.h linux.17p18/include/asm-ppc/processor.h
--- linux.vanilla/include/asm-ppc/processor.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/processor.h	Tue Aug  1 08:00:03 2000
@@ -4,9 +4,9 @@
 #include <linux/config.h>
 
 #include <asm/ptrace.h>
-#include <asm/residual.h>
 
 /* Bit encodings for Machine State Register (MSR) */
+#define MSR_VEC		(1<<25)		/* Enable Altivec */
 #define MSR_POW		(1<<18)		/* Enable Power Management */
 #define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
 #define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
@@ -53,6 +53,9 @@
 #define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
 #define HID0_SPD	(1<<9)		/* Speculative disable */
 #define HID0_SIED	(1<<7)		/* Serial Instruction Execution [Disable] */
+#define HID0_SGE	(1<<7)		/* Store Gathering Enable */
+#define HID0_BTIC	(1<<5)		/* Branch Target Instruction Cache Enable */
+#define HID0_ABE	(1<<3)		/* Address Broadcast Enable */
 #define HID0_BHTE	(1<<2)		/* Branch History Table Enable */
 #define HID0_BTCD	(1<<1)		/* Branch target cache disable */
 
@@ -147,6 +150,7 @@
 #define EAR	282	/* External Address Register */
 #define L2CR	1017    /* PPC 750 L2 control register */
 
+#define ICTC	1019
 #define THRM1	1020
 #define THRM2	1021
 #define THRM3	1022
@@ -177,6 +181,10 @@
 #define SR15	15
 
 #ifndef __ASSEMBLY__
+#include <asm/types.h>
+
+#ifdef __KERNEL__
+
 extern int _machine;
 
 /* Temporary hacks until we can clean things up better - Corey */
@@ -242,10 +250,21 @@
 	double		fpr[32];	/* Complete floating point set */
 	unsigned long	fpscr_pad;	/* fpr ... fpscr must be contiguous */
 	unsigned long	fpscr;		/* Floating point status */
+#ifdef CONFIG_ALTIVEC
+	vector128	vr[32];		/* Complete AltiVec set */
+	vector128	vscr;		/* AltiVec status */
+	unsigned long	vrsave;
+#endif /* CONFIG_ALTIVEC */
 };
 
 #define INIT_SP		(sizeof(init_stack) + (unsigned long) &init_stack)
 
+#ifdef CONFIG_ALTIVEC
+#define INIT_TSS_AVEC	{{{0}}}, {{0}}, 0,
+#else
+#define INIT_TSS_AVEC
+#endif /* CONFIG_ALTIVEC */
+
 #define INIT_TSS  { \
 	INIT_SP, /* ksp */ \
 	(unsigned long *) swapper_pg_dir, /* pg_tables */ \
@@ -253,7 +272,8 @@
 	(struct pt_regs *)INIT_SP - 1, /* regs */ \
 	KERNEL_DS, /*fs*/ \
 	0, /* last_syscall */ \
-	{0}, 0, 0 \
+	{0}, 0, 0, \
+	INIT_TSS_AVEC \
 }
 
 /*
@@ -295,5 +315,6 @@
 
 #endif /* ndef ASSEMBLY*/
 
-  
+#endif /* __KERNEL__ */
+
 #endif /* __ASM_PPC_PROCESSOR_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/prom.h linux.17p18/include/asm-ppc/prom.h
--- linux.vanilla/include/asm-ppc/prom.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/prom.h	Tue Aug  1 08:00:03 2000
@@ -72,7 +72,10 @@
 extern struct device_node *find_path_device(const char *path);
 extern struct device_node *find_compatible_devices(const char *type,
 						   const char *compat);
+extern struct device_node *find_pci_device_OFnode(unsigned char bus,
+	unsigned char dev_fn);
 extern struct device_node *find_phandle(phandle);
+extern struct device_node *find_all_nodes(void);
 extern int device_is_compatible(struct device_node *device, const char *);
 extern int machine_is_compatible(const char *compat);
 extern unsigned char *get_property(struct device_node *node, const char *name,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/residual.h linux.17p18/include/asm-ppc/residual.h
--- linux.vanilla/include/asm-ppc/residual.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/residual.h	Tue Aug  1 08:00:03 2000
@@ -25,7 +25,7 @@
 /*               Public structures...                                         */
 /*----------------------------------------------------------------------------*/
 
-#include "pnp.h"
+#include <asm/pnp.h>
 
 typedef enum _L1CACHE_TYPE {
   NoneCAC = 0,
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/system.h linux.17p18/include/asm-ppc/system.h
--- linux.vanilla/include/asm-ppc/system.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/system.h	Wed Aug 16 21:41:39 2000
@@ -52,6 +52,7 @@
         }
 }
 
+struct task_struct;
 
 extern void __sti(void);
 extern void __cli(void);
@@ -72,6 +73,7 @@
 extern void pmac_find_display(void);
 extern void giveup_fpu(struct task_struct *);
 extern void enable_kernel_fp(void);
+extern void giveup_altivec(struct task_struct *);
 extern void cvt_fd(float *from, double *to, unsigned long *fpscr);
 extern void cvt_df(double *from, float *to, unsigned long *fpscr);
 extern int call_rtas(const char *, int, int, unsigned long *, ...);
@@ -81,7 +83,6 @@
 struct device_node;
 extern void note_scsi_host(struct device_node *, void *);
 
-struct task_struct;
 #define switch_to(prev,next,last) _switch_to((prev),(next),&(last))
 extern void _switch_to(struct task_struct *, struct task_struct *,
 		       struct task_struct **);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/termbits.h linux.17p18/include/asm-ppc/termbits.h
--- linux.vanilla/include/asm-ppc/termbits.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/termbits.h	Tue Aug  1 08:00:03 2000
@@ -57,12 +57,9 @@
 #define ICRNL	0000400
 #define IXON	0001000
 #define IXOFF	0002000
-#if defined(__KERNEL__) || defined(__USE_BSD)
-  /* POSIX.1 doesn't want these... */
-# define IXANY		0004000
-# define IUCLC		0010000
-# define IMAXBEL	0020000
-#endif
+#define IXANY	0004000
+#define IUCLC	0010000
+#define IMAXBEL	0020000
 
 /* c_oflag bits */
 #define OPOST	0000001
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/time.h linux.17p18/include/asm-ppc/time.h
--- linux.vanilla/include/asm-ppc/time.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/asm-ppc/time.h	Tue Aug  1 08:00:03 2000
@@ -0,0 +1,34 @@
+/*
+ * $Id: time.h,v 1.11.2.1 1999/08/27 04:20:35 cort Exp $
+ * Common time prototypes and such for all ppc machines.
+ *
+ * Written by Cort Dougan (cort@cs.nmt.edu) to merge
+ * Paul Mackerras' version and mine for PReP and Pmac.
+ */
+
+#include <linux/mc146818rtc.h>
+
+/* time.c */
+extern unsigned decrementer_count;
+extern unsigned count_period_num;
+extern unsigned count_period_den;
+extern unsigned long mktime(unsigned int, unsigned int, unsigned int,
+			    unsigned int, unsigned int, unsigned int);
+extern void to_tm(int tim, struct rtc_time * tm);
+extern time_t last_rtc_update;
+
+int via_calibrate_decr(void);
+
+/* Accessor functions for the decrementer register. */
+static __inline__ unsigned int get_dec(void)
+{
+	unsigned int ret;
+
+	asm volatile("mfspr %0,22" : "=r" (ret) :);
+	return ret;
+}
+
+static __inline__ void set_dec(unsigned int val)
+{
+	asm volatile("mtspr 22,%0" : : "r" (val));
+}
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/types.h linux.17p18/include/asm-ppc/types.h
--- linux.vanilla/include/asm-ppc/types.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/types.h	Tue Aug  1 08:00:03 2000
@@ -39,6 +39,10 @@
 typedef signed long long s64;
 typedef unsigned long long u64;
 
+typedef struct {
+	u32 u[4];
+} __attribute((aligned(16))) vector128;
+
 #define BITS_PER_LONG 32
 
 #endif /* __KERNEL__ */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-ppc/unistd.h linux.17p18/include/asm-ppc/unistd.h
--- linux.vanilla/include/asm-ppc/unistd.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-ppc/unistd.h	Tue Aug  1 08:00:03 2000
@@ -195,6 +195,11 @@
 #define __NR_putpmsg		188	/* some people actually want streams */
 #define __NR_vfork		189
 
+#define __NR_sys_pciconfig_read         198
+#define __NR_sys_pciconfig_write        199
+#define __NR_sys_pciconfig_iobase       200
+#define __NR_multiplexer                201
+
 #define __NR(n)	#n
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/atomic.h linux.17p18/include/asm-s390/atomic.h
--- linux.vanilla/include/asm-s390/atomic.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-s390/atomic.h	Tue Aug  1 08:00:03 2000
@@ -38,7 +38,7 @@
 {
         __asm__ __volatile__("st  %1,%0\n\t"
                              "bcr 15,0"
-                             : : "m" (*v), "d" (i) : "memory");
+                             : "=m" (*v) : "d" (i) );
 }
 
 static __inline__ void atomic_add(int i, atomic_t *v)
@@ -48,7 +48,7 @@
                              "   ar    1,%1\n"
                              "   cs    0,1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v) : "d" (i) : "0", "1" );
+                             : "+m" (*v) : "d" (i) : "0", "1", "cc" );
 }
 
 static __inline__ void atomic_sub(int i, atomic_t *v)
@@ -58,7 +58,7 @@
                              "   sr    1,%1\n"
                              "   cs    0,1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v) : "d" (i) : "0", "1" );
+                             : "+m" (*v) : "d" (i) : "0", "1", "cc" );
 }
 
 static __inline__ void atomic_inc(volatile atomic_t *v)
@@ -68,7 +68,7 @@
                              "   ahi   1,1\n"
                              "   cs    0,1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v) : : "0", "1" );
+                             : "+m" (*v) : : "0", "1", "cc" );
 }
 
 static __inline__ int atomic_inc_return(volatile atomic_t *v)
@@ -79,7 +79,7 @@
                              "   ahi   %1,1\n"
                              "   cs    0,%1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v), "=&d" (i) : : "0" );
+                             : "+m" (*v), "=&d" (i) : : "0", "cc" );
         return i;
 }
 
@@ -90,7 +90,7 @@
                              "   ahi   1,-1\n"
                              "   cs    0,1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v) : : "0", "1" );
+                             : "+m" (*v) : : "0", "1", "cc" );
 }
 
 static __inline__ int atomic_dec_return(volatile atomic_t *v)
@@ -101,7 +101,7 @@
                              "   ahi   %1,-1\n"
                              "   cs    0,%1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v), "=&d" (i) : : "0" );
+                             : "+m" (*v), "=&d" (i) : : "0", "cc" );
         return i;
 }
 
@@ -113,7 +113,7 @@
                              "   ahi   %1,-1\n"
                              "   cs    0,%1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v), "=&d" (i) : : "0");
+                             : "+m" (*v), "=&d" (i) : : "0", "cc");
         return i == 0;
 }
 
@@ -124,7 +124,7 @@
                              "   nr    1,%1\n"
                              "   cs    0,1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v) : "d" (~(mask)) : "0", "1" );
+                             : "+m" (*v) : "d" (~(mask)) : "0", "1", "cc" );
 }
 
 static __inline__ void atomic_set_mask(unsigned long mask, atomic_t *v)
@@ -134,7 +134,7 @@
                              "   or    1,%1\n"
                              "   cs    0,1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v) : "d" (mask) : "0", "1" );
+                             : "+m" (*v) : "d" (mask) : "0", "1", "cc" );
 }
 
 /*
@@ -153,7 +153,7 @@
                 "0:"
                 : "=&r" (retval), "+m" (*v)
                 : "d" (expected_oldval) , "d" (new_val)
-                : "memory", "cc");
+                : "cc");
         return retval;
 }
 
@@ -169,13 +169,13 @@
                 "   jl  0b\n"
                 : "+m" (*v)
                 : "d" (expected_oldval) , "d" (new_val)
-                : "memory", "cc", "1");
+                : "cc", "1");
 }
 
 /*
  * Increase and test if atomic counter > 0
  */
-extern __inline__ int atomic_inc_and_test_greater_zero(volatile atomic_t *v)
+extern __inline__ int atomic_inc_and_test_greater_zero(atomic_t *v)
 {
         int i;
         __asm__ __volatile__("   l     0,%0\n"
@@ -183,8 +183,15 @@
                              "   ahi   %1,1\n"
                              "   cs    0,%1,%0\n"
                              "   jl    0b"
-                             : "+m" (*v), "=&d" (i) : : "0" );
+                             : "+m" (*v), "=&d" (i) : : "0", "cc" );
         return i > 0;
+}
+
+#define atomic_compare_and_swap_debug(where,from,to) \
+if (atomic_compare_and_swap ((from), (to), (where))) {\
+	printk (KERN_WARNING"%s/%d atomic counter:%s couldn't be changed from %d(%s) to %d(%s), was %d\n",\
+		__FILE__,__LINE__,#where,(from),#from,(to),#to,atomic_read (where));\
+        atomic_set(where,(to));\
 }
 
 #endif                                 /* __ARCH_S390_ATOMIC __            */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/bitops.h linux.17p18/include/asm-s390/bitops.h
--- linux.vanilla/include/asm-s390/bitops.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-s390/bitops.h	Tue Aug  1 08:00:03 2000
@@ -79,8 +79,8 @@
              "   nr    1,%0\n"         /* make shift value */
              "   xr    %0,1\n"
              "   srl   %0,3\n"
-             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   lhi   2,1\n"
+             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   sll   2,0(1)\n"       /* make OR mask */
              "   l     %0,0(%1)\n"
              "0: lr    1,%0\n"         /* CS loop starts here */
@@ -109,8 +109,8 @@
              "   nr    1,%0\n"         /* make shift value */
              "   xr    %0,1\n"
              "   srl   %0,3\n"
-             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   lhi   2,1\n"
+             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   sll   2,0(1)\n"
              "   x     2,%2\n"         /* make AND mask */
              "   l     %0,0(%1)\n"
@@ -139,8 +139,8 @@
              "   nr    1,%0\n"         /* make shift value */
              "   xr    %0,1\n"
              "   srl   %0,3\n"
-             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   lhi   2,1\n"
+             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   sll   2,0(1)\n"       /* make XR mask */
              "   l     %0,0(%1)\n"
              "0: lr    1,%0\n"         /* CS loop starts here */
@@ -168,8 +168,8 @@
              "   nr    1,%0\n"         /* make shift value */
              "   xr    %0,1\n"
              "   srl   %0,3\n"
-             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   lhi   2,1\n"
+             "   la    %1,0(%0,%1)\n"  /* calc. address for CS */
              "   sll   2,0(1)\n"       /* make OR mask */
              "   l     %0,0(%1)\n"
              "0: lr    1,%0\n"         /* CS loop starts here */
@@ -788,7 +788,6 @@
 #define ext2_test_bit(nr, addr)      test_bit((nr)^24, addr)
 extern __inline__ int ext2_find_first_zero_bit(void *vaddr, unsigned size)
 {
-        static const int mask = 0xffL;
         int res;
 
         if (!size)
@@ -806,6 +805,7 @@
                 "   j    4f\n"
                 "1: l    1,0(2,%2)\n"
                 "   sll  2,3(0)\n"
+                "   lhi  0,0xff\n"
                 "   ahi  2,24\n"
                 "   tmh  1,0xFFFF\n"
                 "   jo   2f\n"
@@ -815,13 +815,12 @@
                 "   jo   3f\n"
                 "   ahi  2,-8\n"
                 "   srl  1,8\n"
-                "3: n    1,%3\n"
-                "   ic   1,0(1,%4)\n"
-                "   n    1,%3\n"
+                "3: nr   1,0\n"
+                "   ic   1,0(1,%3)\n"
                 "   ar   2,1\n"
                 "4: lr   %0,2"
                 : "=d" (res) : "a" (size), "a" (vaddr),
-                  "m" (mask), "a" (&_zb_findmap)
+                  "a" (&_zb_findmap)
                   : "cc", "0", "1", "2" );
         return (res < size) ? res : size;
 }
@@ -829,17 +828,6 @@
 extern __inline__ int 
 ext2_find_next_zero_bit(void *vaddr, unsigned size, unsigned offset)
 {
-        static const int mask = 0xffL;
-        static unsigned long orword[32] = {
-		0x00000000, 0x01000000, 0x03000000, 0x07000000,
-		0x0f000000, 0x1f000000, 0x3f000000, 0x7f000000,
-		0xff000000, 0xff010000, 0xff030000, 0xff070000,
-                0xff0f0000, 0xff1f0000, 0xff3f0000, 0xff7f0000,
-		0xffff0000, 0xffff0100, 0xffff0300, 0xffff0700,
-		0xffff0f00, 0xffff1f00, 0xffff3f00, 0xffff7f00,
-		0xffffff00, 0xffffff01, 0xffffff03, 0xffffff07,
-		0xffffff0f, 0xffffff1f, 0xffffff3f, 0xffffff7f
-	};
         unsigned long *addr = vaddr;
         unsigned long *p = addr + (offset >> 5);
         unsigned long word;
@@ -849,23 +837,29 @@
                 return size;
 
         if (bit) {
-		word = *p | orword[bit];
+                __asm__("   ic   %0,0(%1)\n"
+                        "   icm  %0,2,1(%1)\n"
+                        "   icm  %0,4,2(%1)\n"
+                        "   icm  %0,8,3(%1)"
+                        : "=&a" (word) : "a" (p) );
+		word >>= bit;
+                res = bit;
                 /* Look for zero in first longword */
-                __asm__("   lhi  %0,24\n"
-                	"   tmh  %1,0xFFFF\n"
-                	"   jo   0f\n"
-                	"   ahi  %0,-16\n"
+                __asm__("   lhi  0,0xff\n"
+                        "   tml  %1,0xffff\n"
+                	"   jno   0f\n"
+                	"   ahi  %0,16\n"
                 	"   srl  %1,16\n"
-                	"0: tml  %1,0xFF00\n"
-                	"   jo   1f\n"
-                	"   ahi  %0,-8\n"
+                	"0: tml  %1,0x00ff\n"
+                	"   jno  1f\n"
+                	"   ahi  %0,8\n"
                 	"   srl  %1,8\n"
-                	"1: n    %1,%2\n"
-                	"   ic   %1,0(%1,%3)\n"
+                	"1: nr   %1,0\n"
+                	"   ic   %1,0(%1,%2)\n"
                 	"   alr  %0,%1"
-                	: "=&d" (res), "+&d" (word)
-                  	: "m" (mask), "a" (&_zb_findmap)
-                	: "cc" );
+                	: "+&d" (res), "+&d" (word)
+                  	: "a" (&_zb_findmap)
+                	: "cc", "0" );
                 if (res < 32)
 			return (p - addr)*32 + res;
                 p++;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/ccwcache.h linux.17p18/include/asm-s390/ccwcache.h
--- linux.vanilla/include/asm-s390/ccwcache.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/asm-s390/ccwcache.h	Tue Aug  1 08:00:03 2000
@@ -0,0 +1,88 @@
+/* 
+   * File...........: linux/drivers/s390/block/ccwcache.c
+   * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com>
+   * Bugreports.to..: <Linux390@de.ibm.com>
+   * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000
+ */
+#ifndef CCWCACHE_H
+#define CCWCACHE_H
+#include <linux/slab.h>
+#include <asm/irq.h>
+
+#ifndef __KERNEL__
+#define kmem_cache_t void
+#endif /* __KERNEL__ */
+/* 
+ * smalles slab to be allocated (DASD_MINIMUM_CCW CCWs + metadata) 
+ */
+
+typedef struct ccw_req_t {
+	/* these identify the request */
+	unsigned long magic;	/* magic number */
+	atomic_t status;	/* reflecting the status of this request */
+	unsigned long long expires;	/* clock value, when request expires */
+
+	/* these are important for executing the requests */
+	ccw1_t *cpaddr;		/* address of channel program */
+	void *data;		/* pointer to data area */
+	void *req;		/* pointer to originating request */
+	struct ccw_req_t *next;	/* pointer to next ccw_req_t in queue */
+
+	int options;		/* options for execution */
+	int cplength;		/* length of the channel program in CCWs */
+	int datasize;		/* amount of additional data in bytes */
+	devstat_t *dstat;	/* The device status in case of an error */
+
+	/* these are important for recovering erroneous requests */
+	int retries;		/* A retry counter to be set when filling */
+	devstat_t *devstat;	/* Keeping the device status */
+	struct ccw_req_t *refers;	/* Does this request refer to another one? */
+	void *function; /* refers to the originating ERP action */ ;
+
+	/* these are for profiling purposes */
+	unsigned long long buildclk;	/* TOD-clock of request generation */
+	unsigned long long startclk;	/* TOD-clock of request start */
+
+	unsigned long long stopclk;	/* TOD-clock of request interrupt */
+	unsigned long long endclk;	/* TOD-clock of request termination */
+
+	/* these are for internal use */
+	struct ccw_req_t *int_next;	/* for internal queueing */
+	struct ccw_req_t *int_prev;	/* for internal queueing */
+	kmem_cache_t *cache;	/* the cache this data comes from */
+	void *device;		/* index of the device the req is for */
+
+} __attribute__ ((packed,aligned(4))) ccw_req_t;
+
+/* 
+ * ccw_req_t -> status can be:
+ */
+#define CQR_STATUS_EMPTY  0x00	/* request is empty */
+#define CQR_STATUS_FILLED 0x01	/* request is ready to be preocessed */
+#define CQR_STATUS_QUEUED 0x02	/* request is queued to be processed */
+#define CQR_STATUS_IN_IO  0x04	/* request is currently in IO */
+#define CQR_STATUS_DONE   0x08	/* request is completed sucessfully */
+#define CQR_STATUS_ERROR  0x10	/* request is completed with error */
+#define CQR_STATUS_FAILED 0x20	/* request is finally failed */
+
+#ifdef __KERNEL__
+#define SMALLEST_SLAB (sizeof(struct ccw_req_t) <= 128 ? 128 :\
+ sizeof(struct ccw_req_t) <= 256 ? 256 :\
+ sizeof(struct ccw_req_t) <= 512 ? 512 :\
+ sizeof(struct ccw_req_t) <= 1024 ? 1024 : 2048)
+
+/* SMALLEST_SLAB(1),... PAGE_SIZE(CCW_NUMBER_CACHES) */
+#define CCW_NUMBER_CACHES (sizeof(struct ccw_req_t) <= 128 ? 6 :\
+ sizeof(struct ccw_req_t) <= 256 ? 5 :\
+ sizeof(struct ccw_req_t) <= 512 ? 4 :\
+ sizeof(struct ccw_req_t) <= 1024 ? 3 : 2)
+
+int ccwcache_init (void);
+
+ccw_req_t *ccw_alloc_request (char *magic, int cplength, int datasize);
+void ccw_free_request (ccw_req_t * request);
+#endif /* __KERNEL__ */
+#endif				/* CCWCACHE_H */
+
+
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/dasd.h linux.17p18/include/asm-s390/dasd.h
--- linux.vanilla/include/asm-s390/dasd.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/asm-s390/dasd.h	Tue Aug  1 08:00:03 2000
@@ -0,0 +1,253 @@
+
+#ifndef DASD_H
+#define DASD_H
+
+/* First of all the external stuff */
+#include <linux/ioctl.h>
+#include <linux/major.h>
+#include <linux/wait.h>
+#include <asm/ccwcache.h>
+/* #include <linux/blkdev.h> */
+#include <linux/genhd.h>
+#include <linux/hdreg.h>
+#include <linux/version.h>
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+#include <linux/devfs_fs_kernel.h>
+#endif /* LINUX_IS_24 */
+
+#define IOCTL_LETTER 'D'
+/* Format the volume or an extent */
+#define BIODASDFORMAT  _IOW(IOCTL_LETTER,0,format_data_t) 
+/* Disable the volume (for Linux) */
+#define BIODASDDISABLE _IO(IOCTL_LETTER,1) 
+/* Enable the volume (for Linux) */
+#define BIODASDENABLE  _IO(IOCTL_LETTER,2) 
+/* Stuff for reading and writing the Label-Area to/from user space */
+#define BIODASDGTVLBL  _IOR(IOCTL_LETTER,3,dasd_volume_label_t)
+#define BIODASDSTVLBL  _IOW(IOCTL_LETTER,4,dasd_volume_label_t)
+#define BIODASDRWTB    _IOWR(IOCTL_LETTER,5,int)
+#define BIODASDRSID    _IOR(IOCTL_LETTER,6,senseid_t)
+#define BIODASDRLB     _IOR(IOCTL_LETTER,7,int)
+#define BLKGETBSZ      _IOR(IOCTL_LETTER,8,int)
+#define BIODASDEXCP    _IOWR(IOCTL_LETTER,9,ccw_req_t)
+
+#define DASD_NAME "dasd"
+#define DASD_PARTN_BITS 2
+#define PARTN_BITS DASD_PARTN_BITS
+#define DASD_PER_MAJOR ( 1U<<(MINORBITS-DASD_PARTN_BITS))
+
+/* 
+ * struct format_data_t
+ * represents all data necessary to format a dasd
+ */
+typedef struct format_data_t {
+	int start_unit; /* from track */
+	int stop_unit;  /* to track */
+	int blksize;    /* sectorsize */
+        int intensity;  /* 0: normal, 1:record zero, 3:home address */
+} __attribute__ ((packed)) format_data_t;
+
+#define DASD_FORMAT_DEFAULT_START_UNIT 0
+#define DASD_FORMAT_DEFAULT_STOP_UNIT -1
+#define DASD_FORMAT_DEFAULT_BLOCKSIZE -1
+#define DASD_FORMAT_DEFAULT_INTENSITY -1
+
+#ifdef __KERNEL__
+
+typedef enum {
+	dasd_era_fatal = -1,	/* no chance to recover              */
+	dasd_era_none = 0,	/* don't recover, everything alright */
+	dasd_era_msg = 1,	/* don't recover, just report...     */
+	dasd_era_recover = 2	/* recovery action recommended       */
+} dasd_era_t;
+
+/* 
+ * struct dasd_sizes_t
+ * represents all data needed to access dasd with properly set up sectors
+ */
+typedef
+struct dasd_sizes_t {
+	unsigned int blocks;
+	unsigned int bp_block;
+	unsigned int s2b_shift;
+} __attribute__ ((packed)) dasd_sizes_t;
+
+/* 
+ * struct dasd_chanq_t 
+ * represents a queue of channel programs related to a single device
+ */
+typedef
+struct dasd_chanq_t {
+	ccw_req_t *head;
+	ccw_req_t *tail;
+	struct dasd_chanq_t *next_q;	/* pointer to next queue */
+	int queued_requests;
+	atomic_t flags;
+	atomic_t dirty_requests;
+} __attribute__ ((packed)) dasd_chanq_t;
+
+#define DASD_CHANQ_BUSY 0x01
+#define DASD_CHANQ_ACTIVE 0x02
+#define DASD_REQUEST_Q_BROKEN 0x04
+
+struct dasd_device_t;
+
+typedef ccw_req_t *(*dasd_erp_action_fn_t) (ccw_req_t * cqr);
+typedef int (*dasd_erp_postaction_fn_t) (ccw_req_t * cqr, int);
+
+typedef int (*dasd_ck_id_fn_t) (dev_info_t *);
+typedef int (*dasd_ck_characteristics_fn_t) (struct dasd_device_t *);
+typedef int (*dasd_fill_geometry_fn_t) (struct dasd_device_t *, struct hd_geometry *);
+typedef ccw_req_t *(*dasd_format_fn_t) (struct dasd_device_t *, struct format_data_t *);
+typedef ccw_req_t *(*dasd_init_analysis_fn_t) (struct dasd_device_t *);
+typedef int (*dasd_do_analysis_fn_t) (struct dasd_device_t *);
+typedef int (*dasd_io_starter_fn_t) (ccw_req_t *);
+typedef void (*dasd_int_handler_fn_t)(int irq, void *, struct pt_regs *);
+typedef dasd_era_t (*dasd_error_examine_fn_t) (ccw_req_t *, devstat_t * stat);
+typedef dasd_erp_action_fn_t (*dasd_error_analyse_fn_t) (ccw_req_t *);
+typedef dasd_erp_postaction_fn_t (*dasd_erp_analyse_fn_t) (ccw_req_t *);
+typedef ccw_req_t *(*dasd_cp_builder_fn_t)(struct dasd_device_t *,struct request *);
+typedef char *(*dasd_dump_sense_fn_t)(struct dasd_device_t *,ccw_req_t *);
+
+typedef struct dasd_discipline_t {
+	char ebcname[8]; /* a name used for tagging and printks */
+        char name[8];		/* a name used for tagging and printks */
+
+	struct dasd_discipline_t *next;	/* used for list of disciplines */
+
+	dasd_ck_id_fn_t id_check;	/* to check sense data */
+	dasd_ck_characteristics_fn_t check_characteristics;	/* to check the characteristics */
+	dasd_init_analysis_fn_t init_analysis;	/* to start the analysis of the volume */
+	dasd_do_analysis_fn_t do_analysis;	/* to complete the analysis of the volume */
+	dasd_fill_geometry_fn_t fill_geometry;	/* to set up hd_geometry */
+	dasd_io_starter_fn_t start_IO;
+        dasd_format_fn_t format_device;		/* to format the device */
+	dasd_error_examine_fn_t examine_error;
+	dasd_error_analyse_fn_t erp_action;
+	dasd_erp_analyse_fn_t erp_postaction;
+        dasd_cp_builder_fn_t build_cp_from_req;
+        dasd_dump_sense_fn_t dump_sense;
+        dasd_int_handler_fn_t int_handler;
+} __attribute__   ((packed)) dasd_discipline_t;
+
+typedef struct major_info_t {
+	struct major_info_t *next;
+	struct dasd_device_t **dasd_device;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+	void (*request_fn) (request_queue_t *);
+#else
+	void (*request_fn) (void);
+#endif /* LINUX_IS_24 */
+	int read_ahead;
+	int *blk_size;
+	int *hardsect_size;
+	int *blksize_size;
+	int *max_sectors;
+	struct gendisk gendisk;
+} __attribute__ ((packed)) major_info_t;
+
+typedef struct dasd_device_t {
+	dev_info_t devinfo;
+	dasd_discipline_t *discipline;
+	atomic_t level;
+        int open_count;
+        kdev_t kdev;
+        major_info_t *major_info;
+	struct dasd_chanq_t queue;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        wait_queue_head_t wait_q;
+        request_queue_t *request_queue;
+#else
+        struct wait_queue wait;
+        struct wait_queue *wait_q;
+#endif /* LINUX_IS_24 */
+        dasd_sizes_t sizes;
+	devstat_t dev_status;
+	char *characteristics;
+        char name[16]; /* The name of the device in /dev */
+	char *private;	/* to be used by the discipline internally */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,3,98))
+        devfs_handle_t devfs_entry;
+#endif /* LINUX_IS_24 */
+}  dasd_device_t;
+
+/* dasd_device_t.level can be: */
+#define DASD_DEVICE_LEVEL_UNKNOWN 0x00
+#define DASD_DEVICE_LEVEL_RECOGNIZED 0x01
+#define DASD_DEVICE_LEVEL_ANALYSIS_PENDING 0x02
+#define DASD_DEVICE_LEVEL_ANALYSIS_PREPARED 0x04
+#define DASD_DEVICE_LEVEL_ANALYSED 0x08
+#define DASD_DEVICE_LEVEL_PARTITIONED 0x10
+
+typedef
+union {
+	char bytes[512];
+	struct {
+		/* 80 Bytes of Label data */
+		char identifier[4];	/* e.g. "LNX1", "VOL1" or "CMS1" */
+		char label[6];	/* Given by user */
+		char security;
+		char vtoc[5];	/* Null in "LNX1"-labelled partitions */
+		char reserved0[5];
+		long ci_size;
+		long blk_per_ci;
+		long lab_per_ci;
+		char reserved1[4];
+		char owner[0xe];
+		char no_part;
+		char reserved2[0x1c];
+		/* 16 Byte of some information on the dasd */
+		short blocksize;
+		char nopart;
+		char unused;
+		long unused2[3];
+		/* 7*10 = 70 Bytes of partition data */
+		struct {
+			char type;
+			long start;
+			long size;
+			char unused;
+		} part[7];
+	} __attribute__ ((packed)) label;
+} dasd_volume_label_t;
+
+typedef union {
+	struct {
+		unsigned long no;
+		unsigned int ct;
+	} __attribute__ ((packed)) input;
+	struct {
+		unsigned long noct;
+	} __attribute__ ((packed)) output;
+} __attribute__ ((packed)) dasd_xlate_t;
+
+int dasd_init (void);
+/* int dasd_device_name (char *, int, int, struct gendisk *); */
+void dasd_discipline_enq (dasd_discipline_t *);
+int dasd_discipline_deq(dasd_discipline_t *);
+int dasd_start_IO (ccw_req_t *);
+void dasd_int_handler (int , void *, struct pt_regs *);
+
+#endif /* __KERNEL__ */
+
+#endif				/* DASD_H */
+
+/*
+ * Overrides for Emacs so that we follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 4 
+ * c-brace-imaginary-offset: 0
+ * c-brace-offset: -4
+ * c-argdecl-indent: 4
+ * c-label-offset: -4
+ * c-continued-statement-offset: 4
+ * c-continued-brace-offset: 0
+ * indent-tabs-mode: nil
+ * tab-width: 8
+ * End:
+ */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/debug.h linux.17p18/include/asm-s390/debug.h
--- linux.vanilla/include/asm-s390/debug.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/asm-s390/debug.h	Tue Aug  1 08:00:03 2000
@@ -0,0 +1,120 @@
+#ifndef DEBUG_H
+#define DEBUG_H
+
+#include <asm/spinlock.h>
+
+#ifdef __KERNEL__
+
+#define MAX_DEBUG_AREAS 16
+
+#define STCK(x) asm volatile ("STCK %0":"=m" (x))
+
+typedef struct
+{
+  union
+  {
+    struct
+    {
+      unsigned long long cpuid:4;
+      unsigned long long clock:60;
+    }
+    fields;
+    unsigned long long stck;
+  }
+  id;
+  void *caller;
+  union
+  {
+    unsigned long tag;
+    char text[4];
+  }
+  tag;
+}
+debug_entry_t;
+
+typedef struct
+{
+  char *name;
+  int level;
+  int nr_areas;
+  int page_order;
+  debug_entry_t **areas;
+  int active_area;
+  int *active_entry;
+  spinlock_t lock;
+}
+debug_info_t;
+
+int debug_init (void);
+debug_info_t *debug_register (char *name, int pages_index, int nr_areas);
+void debug_unregister (debug_info_t * id, char *name);
+void debug_event (debug_info_t * id, int level, unsigned int tag);
+void debug_text_event (debug_info_t * id, int level, char tag[4]);
+void debug_exception (debug_info_t * id, int level, unsigned int tag);
+void debug_text_exception (debug_info_t * id, int level, char tag[4]);
+
+/*
+   define the debug levels:
+   - 0 No debugging output to console or syslog
+   - 1 Log internal errors to syslog, ignore check conditions 
+   - 2 Log internal errors and check conditions to syslog
+   - 3 Log internal errors to console, log check conditions to syslog
+   - 4 Log internal errors and check conditions to console
+   - 5 panic on internal errors, log check conditions to console
+   - 6 panic on both, internal errors and check conditions
+ */
+
+#ifndef DEBUG_LEVEL
+#define DEBUG_LEVEL 4
+#endif
+
+#define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y
+#define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y
+#define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y
+#define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y
+
+#if DEBUG_LEVEL > 0
+#define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
+#define PRINT_INFO(x...) printk ( KERN_INFO PRINTK_HEADER x )
+#define PRINT_WARN(x...) printk ( KERN_WARNING PRINTK_HEADER x )
+#define PRINT_ERR(x...) printk ( KERN_ERR PRINTK_HEADER x )
+#define PRINT_FATAL(x...) panic ( PRINTK_HEADER x )
+#else
+#define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
+#define PRINT_INFO(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
+#define PRINT_WARN(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
+#define PRINT_ERR(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
+#define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
+#endif				/* DASD_DEBUG */
+
+#if DASD_DEBUG > 4
+#define INTERNAL_ERROR(x...) PRINT_FATAL ( INTERNAL_ERRMSG ( x ) )
+#elif DASD_DEBUG > 2
+#define INTERNAL_ERROR(x...) PRINT_ERR ( INTERNAL_ERRMSG ( x ) )
+#elif DASD_DEBUG > 0
+#define INTERNAL_ERROR(x...) PRINT_WARN ( INTERNAL_ERRMSG ( x ) )
+#else
+#define INTERNAL_ERROR(x...)
+#endif				/* DASD_DEBUG */
+
+#if DASD_DEBUG > 5
+#define INTERNAL_CHECK(x...) PRINT_FATAL ( INTERNAL_CHKMSG ( x ) )
+#elif DASD_DEBUG > 3
+#define INTERNAL_CHECK(x...) PRINT_ERR ( INTERNAL_CHKMSG ( x ) )
+#elif DASD_DEBUG > 1
+#define INTERNAL_CHECK(x...) PRINT_WARN ( INTERNAL_CHKMSG ( x ) )
+#else
+#define INTERNAL_CHECK(x...)
+#endif				/* DASD_DEBUG */
+
+#undef DEBUG_MALLOC
+#ifdef DEBUG_MALLOC
+void *b;
+#define kmalloc(x...) (PRINT_INFO(" kmalloc %p\n",b=kmalloc(x)),b)
+#define kfree(x) PRINT_INFO(" kfree %p\n",x);kfree(x)
+#define get_free_page(x...) (PRINT_INFO(" gfp %p\n",b=get_free_page(x)),b)
+#define __get_free_pages(x...) (PRINT_INFO(" gfps %p\n",b=__get_free_pages(x)),b)
+#endif				/* DEBUG_MALLOC */
+
+#endif				/* __KERNEL__ */
+#endif				/* DEBUG_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/delay.h linux.17p18/include/asm-s390/delay.h
--- linux.vanilla/include/asm-s390/delay.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-s390/delay.h	Tue Aug  1 08:00:03 2000
@@ -15,11 +15,8 @@
 #define _S390_DELAY_H
 
 extern void __udelay(unsigned long usecs);
-extern void __const_udelay(unsigned long usecs);
 extern void __delay(unsigned long loops);
 
-#define udelay(n) (__builtin_constant_p(n) ? \
-	__const_udelay((n) * 0x10c6ul) : \
-	__udelay(n))
+#define udelay(n) __udelay(n)
 
 #endif /* defined(_S390_DELAY_H) */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/irq.h linux.17p18/include/asm-s390/irq.h
--- linux.vanilla/include/asm-s390/irq.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/irq.h	Tue Aug  1 08:00:03 2000
@@ -1,6 +1,7 @@
 #ifndef __irq_h
 #define __irq_h
 
+#ifdef __KERNEL__
 #include <asm/hardirq.h>
 
 /*
@@ -9,6 +10,8 @@
 #define __MAX_SUBCHANNELS 65536
 #define NR_IRQS           __MAX_SUBCHANNELS
 
+#define LPM_ANYPATH 0xff /* doesn't really belong here, Ingo? */
+
 #define INVALID_STORAGE_AREA ((void *)(-1 - 0x3FFF ))
 
 extern int disable_irq(unsigned int);
@@ -68,6 +71,8 @@
                                    /*  ... in an operand exception.       */
    } __attribute__ ((packed)) pmcw_t;
 
+#endif /* __KERNEL__ */
+
 /*
  * subchannel status word
  */
@@ -130,6 +135,8 @@
 #define SCHN_STAT_INTF_CTRL_CHK  0x02
 #define SCHN_STAT_CHAIN_CHECK    0x01
 
+#ifdef __KERNEL__
+
 /*
  * subchannel information block
  */
@@ -139,6 +146,8 @@
       char mda[12];            /* model dependent area */
    } schib_t __attribute__ ((packed,aligned(4)));
 
+#endif /* __KERNEL__ */
+
 typedef struct {
       char            cmd_code;/* command code */
       char            flags;   /* flags, like IDA adressing, etc. */
@@ -164,6 +173,8 @@
 #define CCW_CMD_SET_PGID        0xAF
 #define CCW_CMD_SENSE_ID        0xE4
 
+#ifdef __KERNEL__
+
 #define SENSE_MAX_COUNT         0x20
 
 /*
@@ -197,6 +208,8 @@
       ccw1_t        *cpa;      /* channel program address */
    }  __attribute__ ((packed,aligned(4))) orb_t;
 
+#endif /* __KERNEL__ */
+
 typedef struct {
       unsigned int res0  : 4;  /* reserved */
       unsigned int pvrf  : 1;  /* path-verification-required flag */
@@ -284,6 +297,8 @@
       char   ecw[32];          /* extended control word */
    } irb_t __attribute__ ((aligned(4)));
 
+#ifdef __KERNEL__
+
 /*
  * TPI info structure
  */
@@ -323,6 +338,8 @@
       ciw_t    ciw[16];            /* variable # of CIWs */
    }  __attribute__ ((packed,aligned(4))) senseid_t;
 
+#endif /* __KERNEL__ */
+
 /*
  * sense data
  */
@@ -331,6 +348,7 @@
       unsigned char data[32];  /* sense data */
    } sense_t;
 
+
 /*
  * device status area, to be provided by the device driver
  *  when calling request_irq() as parameter "dev_id", later
@@ -367,16 +385,20 @@
 #define DEVSTAT_CLEAR_FUNCTION     0x00000100
 #define DEVSTAT_PCI                0x00000200
 #define DEVSTAT_SUSPENDED          0x00000400
+#define DEVSTAT_UNKNOWN_DEV        0x00000800
 #define DEVSTAT_FINAL_STATUS       0x80000000
 
 #define INTPARM_STATUS_PENDING     0xFFFFFFFF
 
+#ifdef __KERNEL__
+
 typedef  void (* io_handler_func1_t) ( int  irq,
                                        devstat_t *devstat,
                                        struct pt_regs *rgs);
 
 typedef  void (* io_handler_func_t) ( int  irq,
-                                      __u32 intparm );
+                                      void           *devstat,
+                                      struct pt_regs *rgs);
 
 typedef  void ( * not_oper_handler_func_t)( int irq,
                                             int status );
@@ -777,7 +799,7 @@
  * x86 profiling function, SMP safe. We might want to do this in
  * assembly totally?
  */
-extern unsigned long _stext;
+extern char _stext;
 static inline void s390_do_profile (unsigned long addr)
 {
         if (prof_buffer && current->pid) {
@@ -808,6 +830,7 @@
 
 #define s390irq_spin_unlock_irqrestore(irq,flags) \
         spin_unlock_irqrestore(&(ioinfo[irq]->irq_lock), flags)
+#endif /* __KERNEL__ */
 
 #endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/pgtable.h linux.17p18/include/asm-s390/pgtable.h
--- linux.vanilla/include/asm-s390/pgtable.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/pgtable.h	Tue Aug  1 08:00:03 2000
@@ -86,7 +86,7 @@
         __flush_tlb_one(vma->vm_mm,va);
 }
 #else
-#define flush_tlb_page(vma, va) flush_tlb_all()
+#define flush_tlb_page(vma, va) flush_tlb_mm(vma->vm_mm)
 #endif
 
 static inline void flush_tlb_range(struct mm_struct *mm,
@@ -171,7 +171,7 @@
 	__flush_tlb_one(vma->vm_mm,va);
 }
 #else
-#define flush_tlb_page(vma, va) flush_tlb_all()
+#define flush_tlb_page(vma, va) flush_tlb_mm(vma->vm_mm)
 #endif
 
 static inline void flush_tlb_range(struct mm_struct * mm,
@@ -281,6 +281,7 @@
 #define _PAGE_PRESENT   0x001          /* Software                         */
 #define _PAGE_ACCESSED  0x002          /* Software accessed                */
 #define _PAGE_DIRTY     0x004          /* Software dirty                   */
+#define _PAGE_WRITE     0x008          /* Software write-access allowed    */
 #define _PAGE_RO        0x200          /* HW read-only                     */
 #define _PAGE_INVALID   0x400          /* HW invalid                       */
 
@@ -305,19 +306,21 @@
 
 #define _SEGMENT_TABLE  (_USER_SEG_TABLE_LEN|0x80000000)
 #define _KERNSEG_TABLE  (_KERNEL_SEG_TABLE_LEN)
+
 /*
  * No mapping available
  */
 #define PAGE_NONE       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_INVALID)
-#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define PAGE_SHARED     __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_WRITE | _PAGE_RO)
 #define PAGE_COPY       __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_RO)
 #define PAGE_READONLY   __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_RO)
-#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define PAGE_KERNEL     __pgprot(_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_WRITE | _PAGE_DIRTY)
 
 /*
  * The S390 can't do page protection for execute, and considers that the same are read.
  * Also, write permissions imply read permissions. This is the closest we can get..
  */
+         /*xwr*/
 #define __P000  PAGE_NONE
 #define __P001  PAGE_READONLY
 #define __P010  PAGE_COPY
@@ -434,7 +437,7 @@
  * The following only work if pte_present() is true.
  * Undefined behaviour if not..
  */
-extern inline int pte_write(pte_t pte)          { return !(pte_val(pte) & _PAGE_RO); }
+extern inline int pte_write(pte_t pte)          { return pte_val(pte) & _PAGE_WRITE; }
 extern inline int pte_dirty(pte_t pte)          { return pte_val(pte) & _PAGE_DIRTY; }
 extern inline int pte_young(pte_t pte)          { return pte_val(pte) & _PAGE_ACCESSED; }
 
@@ -447,11 +450,17 @@
 extern inline pte_t pte_mkexec(pte_t pte)       { pte_val(pte) &= _PAGE_INVALID; return pte; }
 */
 
-extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) |= _PAGE_RO; return pte; }
-extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) &= ~_PAGE_RO ; return pte; }
+extern inline int __pte_set_ro(int pte)         { if ((pte & (_PAGE_WRITE|_PAGE_DIRTY)) == (_PAGE_WRITE|_PAGE_DIRTY))
+                                                      pte &= ~_PAGE_RO;
+                                                  else
+                                                      pte |= _PAGE_RO;
+                                                  return pte; }
+
+extern inline pte_t pte_wrprotect(pte_t pte)    { pte_val(pte) = __pte_set_ro(pte_val(pte) & ~_PAGE_WRITE); return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)      { pte_val(pte) = __pte_set_ro(pte_val(pte) | _PAGE_WRITE); return pte; }
 
-extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
-extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) |= _PAGE_DIRTY; return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)      { pte_val(pte) = __pte_set_ro(pte_val(pte) & ~_PAGE_DIRTY); return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)      { pte_val(pte) = __pte_set_ro(pte_val(pte) | _PAGE_DIRTY); return pte; }
 
 extern inline pte_t pte_mkold(pte_t pte)        { pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
 extern inline pte_t pte_mkyoung(pte_t pte)      { pte_val(pte) |= _PAGE_ACCESSED; return pte; }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/processor.h linux.17p18/include/asm-s390/processor.h
--- linux.vanilla/include/asm-s390/processor.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/processor.h	Tue Aug  1 08:00:03 2000
@@ -167,13 +167,33 @@
 static inline void disabled_wait(unsigned long code)
 {
         char psw_buffer[2*sizeof(psw_t)];
+        char ctl_buf[4];
         psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1)
                                   & -sizeof(psw_t));
 
         dw_psw->mask = 0x000a0000;
         dw_psw->addr = code;
-        /* load disabled wait psw, the processor is dead afterwards */
-        asm volatile ("lpsw 0(%0)" : : "a" (dw_psw));
+        /* 
+         * Store status and then load disabled wait psw,
+         * the processor is dead afterwards
+         */
+
+        asm volatile ("    stctl 0,0,0(%1)\n"
+                      "    ni    0(%1),0xef\n" /* switch off protection */
+                      "    lctl  0,0,0(%1)\n"
+                      "    stpt  0xd8\n"       /* store timer */
+                      "    stckc 0xe0\n"       /* store clock comparator */
+                      "    stpx  0x108\n"      /* store prefix register */
+                      "    stam  0,15,0x120\n" /* store access registers */
+                      "    std   0,0x160\n"    /* store f0 */
+                      "    std   2,0x168\n"    /* store f2 */
+                      "    std   4,0x170\n"    /* store f4 */
+                      "    std   6,0x178\n"    /* store f6 */
+                      "    stm   0,15,0x180\n" /* store general registers */
+                      "    stctl 0,15,0x1c0\n" /* store control registers */
+                      "    oi    0x1c0,0x10\n" /* fake protection bit */
+                      "    lpsw 0(%0)"
+                      : : "a" (dw_psw), "a" (&ctl_buf));
 }
 
 #endif                                 /* __ASM_S390_PROCESSOR_H           */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/queue.h linux.17p18/include/asm-s390/queue.h
--- linux.vanilla/include/asm-s390/queue.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/queue.h	Tue Aug  1 08:00:03 2000
@@ -70,6 +70,15 @@
 	*lhead=member;
 }
 
+static __inline__ list *remove_listhead(list **lhead)
+{
+	list *oldhead=*lhead;
+
+	if(oldhead)
+		*lhead=(*lhead)->next;
+	return(oldhead);
+}
+
 static __inline__ void add_to_list_tail(list **lhead,list *member)
 {
 	list *curr,*prev;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/s390io.h linux.17p18/include/asm-s390/s390io.h
--- linux.vanilla/include/asm-s390/s390io.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/s390io.h	Tue Aug  1 08:00:03 2000
@@ -52,7 +52,8 @@
            unsigned int  repnone   : 1;  /* don't call IRQ handler on interrupt */
            unsigned int  newreq    : 1;  /* new register interface */
            unsigned int  dval      : 1;  /* device number valid */
-           unsigned int  unused    : (sizeof(unsigned int)*8 - 23); /* unused */
+           unsigned int  unknown   : 1;  /* unknown device - if SenseID failed */
+           unsigned int  unused    : (sizeof(unsigned int)*8 - 24); /* unused */
               } __attribute__ ((packed)) flags;
         } ui;
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/setup.h linux.17p18/include/asm-s390/setup.h
--- linux.vanilla/include/asm-s390/setup.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/setup.h	Tue Aug  1 08:00:03 2000
@@ -44,6 +44,7 @@
 #define MACHINE_HAS_CSP  (MACHINE_FLAGS & 8)
 
 #define RAMDISK_ORIGIN            0x800000
+#define RAMDISK_SIZE              0x800000
 #define RAMDISK_BLKSIZE           0x1000
 #define RAMDISK_IMAGE_START_MASK  0x07FF
 #define RAMDISK_PROMPT_FLAG       0x8000
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/spinlock.h linux.17p18/include/asm-s390/spinlock.h
--- linux.vanilla/include/asm-s390/spinlock.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/spinlock.h	Tue Aug  1 08:00:03 2000
@@ -94,12 +94,13 @@
 
 extern inline void spin_lock(spinlock_t *lp)
 {
-	__asm__ __volatile("    basr  1,0\n"
-			   "0:  slr   0,0\n"
+        __asm__ __volatile("    bras  1,1f\n"
+                           "0:  diag  0,0,68\n"
+                           "1:  slr   0,0\n"
 			   "    cs    0,1,%1\n"
-			   "    jl    0b"
+                           "    jl    0b\n"
 			   : "=m" (lp->lock)
-			   : "0" (lp->lock) : "0", "1");
+                           : "0" (lp->lock) : "0", "1", "cc" );
 }
 
 extern inline int spin_trylock(spinlock_t *lp)
@@ -109,7 +110,7 @@
 			   "    basr  1,0\n"
 			   "0:  cs    %1,1,%0"
 			   : "=m" (lp->lock), "=&d" (result)
-			   : "0" (lp->lock) : "1");
+			   : "0" (lp->lock) : "1", "cc" );
 	return !result;
 }
 
@@ -119,7 +120,7 @@
 {
 	__asm__ __volatile("    xc 0(4,%0),0(%0)\n"
                            "    bcr 15,0"
-			   : /* no output */ : "a" (lp) );
+			   : /* no output */ : "a" (lp) : "memory", "cc" );
 }
 		
 #define spin_lock_irq(lock) \
@@ -156,37 +157,43 @@
 
 #define read_lock(rw)   \
         asm volatile("   l     2,%0\n"   \
-                     "0: sll   2,1\n"    \
-                     "   srl   2,1\n"     /* clear high (=write) bit */ \
-                     "   lr    3,2\n"    \
-                     "   ahi   3,1\n"     /* one more reader */ \
+                     "   j     1f\n"     \
+                     "0: diag  0,0,68\n" \
+                     "1: la    2,0(2)\n"  /* clear high (=write) bit */ \
+                     "   la    3,1(2)\n"  /* one more reader */ \
                      "   cs    2,3,%0\n"  /* try to write new value */ \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3" );
+                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
 
 #define read_unlock(rw) \
         asm volatile("   l     2,%0\n"   \
-                     "0: lr    3,2\n"    \
+                     "   j     1f\n"     \
+                     "0: diag  0,0,68\n" \
+                     "1: lr    3,2\n"    \
                      "   ahi   3,-1\n"    /* one less reader */ \
                      "   cs    2,3,%0\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3" );
+                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
 
 #define write_lock(rw) \
         asm volatile("   lhi   3,1\n"    \
                      "   sll   3,31\n"    /* new lock value = 0x80000000 */ \
-                     "0: slr   2,2\n"     /* old lock value must be 0 */ \
+                     "   j     1f\n"     \
+                     "0: diag  0,0,68\n" \
+                     "1: slr   2,2\n"     /* old lock value must be 0 */ \
                      "   cs    2,3,%0\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3" );
+                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
 
 #define write_unlock(rw) \
         asm volatile("   slr   3,3\n"     /* new lock value = 0 */ \
-                     "0: lhi   2,1\n"    \
+                     "   j     1f\n"     \
+                     "0: diag  0,0,68\n" \
+                     "1: lhi   2,1\n"    \
                      "   sll   2,31\n"    /* old lock value must be 0x80000000 */ \
                      "   cs    2,3,%0\n" \
                      "   jl    0b"       \
-                     : "+m" ((rw)->lock) : : "2", "3" );
+                     : "+m" ((rw)->lock) : : "2", "3", "cc" );
 
 #define read_lock_irq(lock)	do { __cli(); read_lock(lock); } while (0)
 #define read_unlock_irq(lock)	do { read_unlock(lock); __sti(); } while (0)
@@ -204,12 +211,4 @@
 
 #endif /* SMP */
 #endif /* __ASM_SPINLOCK_H */
-
-
-
-
-
-
-
-
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/string.h linux.17p18/include/asm-s390/string.h
--- linux.vanilla/include/asm-s390/string.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-s390/string.h	Tue Aug  1 08:00:03 2000
@@ -46,14 +46,15 @@
     void *ptr;
 
     __asm__ __volatile__ ("   lr    0,%2\n"
+                          "   lr    1,%1\n"
                           "   la    %0,0(%3,%1)\n"
-                          "0: srst  %0,%1\n"
+                          "0: srst  %0,1\n"
                           "   jo    0b\n"
                           "   brc   13,1f\n"
                           "   slr   %0,%0\n"
                           "1:"
-                          : "=a" (ptr) : "a" (cs), "d" (c), "d" (count)
-                          : "cc", "0" );
+                          : "=&a" (ptr) : "a" (cs), "d" (c), "d" (count)
+                          : "cc", "0", "1" );
     return ptr;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/uaccess.h linux.17p18/include/asm-s390/uaccess.h
--- linux.vanilla/include/asm-s390/uaccess.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/asm-s390/uaccess.h	Tue Aug  1 08:00:03 2000
@@ -84,15 +84,14 @@
 {
         int err;
 
-        __asm__ __volatile__ (  "   iac   1\n"
-				"   sr    %1,%1\n"
+        __asm__ __volatile__ (  "   sr    %1,%1\n"
 				"   la    4,%0\n"
                                 "   sacf  512\n"
                                 "0: st    %2,0(4)\n"
-                                "   sacf  0(1)\n"
+                                "   sacf  0\n"
 				"1:\n"
 				".section .fixup,\"ax\"\n"
-				"2: sacf  0(1)\n"
+				"2: sacf  0\n"
 				"   lhi   %1,%h3\n"
 				"   bras  4,3f\n"
 				"   .long 1b\n"
@@ -105,7 +104,7 @@
 				".previous"
                                 : "=m" (*((__u32*) ptr)) , "=&d" (err)
                                 : "d" (x), "K" (-EFAULT)
-                                : "1", "4" );
+                                : "4" );
         return err;
 }
 
@@ -113,15 +112,14 @@
 {
         int err;
 
-        __asm__ __volatile__ (  "   iac   1\n"
-				"   sr    %1,%1\n"
+        __asm__ __volatile__ (  "   sr    %1,%1\n"
 				"   la    4,%0\n"
                                 "   sacf  512\n"
                                 "0: sth   %2,0(4)\n"
-                                "   sacf  0(1)\n"
+                                "   sacf  0\n"
 				"1:\n"
 				".section .fixup,\"ax\"\n"
-				"2: sacf  0(1)\n"
+				"2: sacf  0\n"
 				"   lhi   %1,%h3\n"
 				"   bras  4,3f\n"
 				"   .long 1b\n"
@@ -134,7 +132,7 @@
 				".previous"
                                 : "=m" (*((__u16*) ptr)) , "=&d" (err)
                                 : "d" (x), "K" (-EFAULT)
-                                : "1", "4" );
+                                : "4" );
         return err;
 }
 
@@ -142,15 +140,14 @@
 {
         int err;
 
-        __asm__ __volatile__ (  "   iac   1\n"
-				"   sr    %1,%1\n"
+        __asm__ __volatile__ (  "   sr    %1,%1\n"
 				"   la    4,%0\n"
                                 "   sacf  512\n"
                                 "0: stc   %2,0(4)\n"
-                                "   sacf  0(1)\n"
+                                "   sacf  0\n"
 				"1:\n"
 				".section .fixup,\"ax\"\n"
-				"2: sacf  0(1)\n"
+				"2: sacf  0\n"
 				"   lhi   %1,%h3\n"
 				"   bras  4,3f\n"
 				"   .long 1b\n"
@@ -163,7 +160,7 @@
 				".previous"
                                 : "=m" (*((__u8*) ptr)) , "=&d" (err)
                                 : "d" (x), "K" (-EFAULT)
-                                : "1", "4" );
+                                : "4" );
         return err;
 }
 
@@ -208,15 +205,14 @@
 
 #define __get_user_asm_4(x, ptr, err)                                   \
 ({                                                                      \
-        __asm__ __volatile__ (  "   iac   1\n"                          \
-                                "   sr    %1,%1\n"                      \
+        __asm__ __volatile__ (  "   sr    %1,%1\n"                      \
                                 "   la    4,%2\n"                       \
                                 "   sacf  512\n"                        \
                                 "0: l     %0,0(4)\n"                    \
-                                "   sacf  0(1)\n"                       \
+                                "   sacf  0\n"                          \
                                 "1:\n"                                  \
                                 ".section .fixup,\"ax\"\n"              \
-                                "2: sacf  0(1)\n"                       \
+                                "2: sacf  0\n"                          \
                                 "   lhi   %1,%h3\n"                     \
                                 "   bras  4,3f\n"                       \
                                 "   .long 1b\n"                         \
@@ -229,20 +225,19 @@
                                 ".previous"                             \
                                 : "=d" (x) , "=&d" (err)                \
                                 : "m" (*(__u32*) ptr), "K" (-EFAULT)    \
-                                : "1", "4" );                           \
+                                : "4" );                                \
 })
 
 #define __get_user_asm_2(x, ptr, err)                                   \
 ({                                                                      \
-        __asm__ __volatile__ (  "   iac   1\n"                          \
-                                "   sr    %1,%1\n"                      \
+        __asm__ __volatile__ (  "   sr    %1,%1\n"                      \
                                 "   la    4,%2\n"                       \
                                 "   sacf  512\n"                        \
                                 "0: lh    %0,0(4)\n"                    \
-                                "   sacf  0(1)\n"                       \
+                                "   sacf  0\n"                          \
                                 "1:\n"                                  \
                                 ".section .fixup,\"ax\"\n"              \
-                                "2: sacf  0(1)\n"                       \
+                                "2: sacf  0\n"                          \
                                 "   lhi   %1,%h3\n"                     \
                                 "   bras  4,3f\n"                       \
                                 "   .long 1b\n"                         \
@@ -255,21 +250,20 @@
                                 ".previous"                             \
                                 : "=d" (x) , "=&d" (err)                \
                                 : "m" (*(__u16*) ptr), "K" (-EFAULT)    \
-                                : "1", "4" );                           \
+                                : "4" );                                \
 })
 
 #define __get_user_asm_1(x, ptr, err)                                   \
 ({                                                                      \
-        __asm__ __volatile__ (  "   iac   1\n"                          \
-                                "   sr    %1,%1\n"                      \
+        __asm__ __volatile__ (  "   sr    %1,%1\n"                      \
                                 "   la    4,%2\n"                       \
                                 "   sr    %0,%0\n"                      \
                                 "   sacf  512\n"                        \
                                 "0: ic    %0,0(4)\n"                    \
-                                "   sacf  0(1)\n"                       \
+                                "   sacf  0\n"                          \
                                 "1:\n"                                  \
                                 ".section .fixup,\"ax\"\n"              \
-                                "2: sacf  0(1)\n"                       \
+                                "2: sacf  0\n"                          \
                                 "   lhi   %1,%h3\n"                     \
                                 "   bras  4,3f\n"                       \
                                 "   .long 1b\n"                         \
@@ -282,7 +276,7 @@
                                 ".previous"                             \
                                 : "=d" (x) , "=&d" (err)                \
                                 : "m" (*(__u8*) ptr), "K" (-EFAULT)     \
-                                : "1", "4" );                           \
+                                : "4" );                                \
 })
 
 #define __get_user(x, ptr)                                      \
@@ -345,22 +339,32 @@
 __copy_to_user_asm(void* to, const void* from,  long n)
 {
 
-        __asm__ __volatile__ (  "   iac   1\n"
-                                "   lr    2,%2\n"
+        __asm__ __volatile__ (  "   lr    2,%2\n"
                                 "   lr    4,%1\n"
                                 "   lr    3,%0\n"
                                 "   lr    5,3\n"
                                 "   sacf  512\n"
                                 "0: mvcle 4,2,0\n"
                                 "   jo    0b\n"
-                                "1: sacf  0(1)\n"
-                                "   lr    %0,3\n"
+                                "   sacf  0\n"
+                                "1: lr    %0,3\n"
+                                ".section .fixup,\"ax\"\n"
+                                "2: lhi   5,-4096\n"
+                                "   n     5,0x90\n"
+                                "   sr    5,4\n"
+                                "   mvcle 4,2,0\n"
+                                "   sacf  0\n"
+                                "   basr  4,0\n"
+                                "   l     4,3f-.(4)\n"
+                                "   br    4\n"
+                                "3: .long 1b\n"
+                                ".previous\n"
 				".section __ex_table,\"a\"\n"
 				"   .align 4\n"
-				"   .long  0b,1b\n"
+				"   .long  0b,2b\n"
 				".previous"
                                 : "+&d" (n) : "d" (to), "d" (from)
-                                : "1", "2", "3", "4", "5" );
+                                : "2", "3", "4", "5" );
         return n;
 }
 
@@ -384,26 +388,35 @@
 extern inline unsigned long
 __copy_from_user_asm(void* to, const void* from,  long n)
 {
-        __asm__ __volatile__ (  "   iac   1\n"
-				"   lr    2,%1\n"
+        __asm__ __volatile__ (  "   lr    2,%1\n"
                                 "   lr    4,%2\n"
                                 "   lr    3,%0\n"
                                 "   lr    5,3\n"
                                 "   sacf  512\n"
                                 "0: mvcle 2,4,0\n"
                                 "   jo    0b\n"
-                                "1: sacf  0(1)\n"
-                                "   lr    %0,3\n"
+                                "   sacf  0\n"
+                                "1: lr    %0,5\n"
+                                ".section .fixup,\"ax\"\n"
+                                "2: lhi   3,-4096\n"
+                                "   n     3,0x90\n"
+                                "   sr    3,4\n"
+                                "   mvcle 2,4,0\n"
+                                "   sacf  0\n"
+                                "   basr  4,0\n"
+                                "   l     4,3f-.(4)\n"
+                                "   br    4\n"
+                                "3: .long 1b\n"
+                                ".previous\n"
 				".section __ex_table,\"a\"\n"
 				"   .align 4\n"
-				"   .long  0b,1b\n"
+				"   .long  0b,2b\n"
 				".previous"
                                 : "+&d" (n) : "d" (to), "d" (from)
-                                : "1", "2", "3", "4", "5" );
+                                : "2", "3", "4", "5" );
         return n;
 }
 
-
 #define __copy_from_user(to, from, n)                           \
 ({                                                              \
         __copy_from_user_asm(to,from,n);                        \
@@ -433,8 +446,7 @@
 strncpy_from_user(char *dst, const char *src, long count)
 {
         long len;
-        __asm__ __volatile__ (  "   iac   1\n"
-				"   slr   %0,%0\n"
+        __asm__ __volatile__ (  "   slr   %0,%0\n"
 				"   lr    2,%1\n"
                                 "   lr    4,%2\n"
                                 "   slr   3,3\n"
@@ -446,7 +458,7 @@
                                 "   ahi   %0,1\n"
                                 "   clr   %0,%3\n"
                                 "   jl    0b\n"
-                                "2: sacf  0(1)\n"
+                                "2: sacf  0\n"
 				".section .fixup,\"ax\"\n"
                                 "3: lhi   %0,%h4\n"
 				"   basr  3,0\n"
@@ -462,7 +474,7 @@
                                 : "=&a" (len)
                                 : "a"  (dst), "d" (src), "d" (count),
                                   "K" (-EFAULT)
-                                : "1", "2", "3", "4", "memory" );
+                                : "2", "3", "4", "memory" );
         return len;
 }
 
@@ -474,8 +486,7 @@
 static inline unsigned long
 strnlen_user(const char * src, unsigned long n)
 {
-	__asm__ __volatile__ ("   iac   1\n"
-                              "   alr   %0,%1\n"
+	__asm__ __volatile__ ("   alr   %0,%1\n"
 			      "   slr   0,0\n"
 			      "   lr    4,%1\n"
 			      "   sacf  512\n"
@@ -483,10 +494,10 @@
 			      "   jo    0b\n"
 			      "   slr   %0,%1\n"
 			      "   ahi   %0,1\n"
-			      "   sacf  0(1)\n"
+			      "   sacf  0\n"
                               "1:\n"
                               ".section .fixup,\"ax\"\n"
-                              "2: sacf  0(1)\n"
+                              "2: sacf  0\n"
                               "   slr   %0,%0\n"
                               "   bras  4,3f\n"
                               "   .long 1b\n"
@@ -498,7 +509,7 @@
 			      "   .long  0b,2b\n"
 			      ".previous"
 			      : "+&a" (n) : "d" (src)
-			      : "cc", "0", "1", "4" );
+			      : "cc", "0", "4" );
         return n;
 }
 #define strlen_user(str) strnlen_user(str, ~0UL)
@@ -510,23 +521,33 @@
 static inline unsigned long
 clear_user(void *to, unsigned long n)
 {
-        __asm__ __volatile__ (  "   iac   1\n"
-                                "   sacf  512\n"
+        __asm__ __volatile__ (  "   sacf  512\n"
                                 "   lr    4,%1\n"
                                 "   lr    5,%0\n"
                                 "   sr    2,2\n"
                                 "   sr    3,3\n"
                                 "0: mvcle 4,2,0\n"
                                 "   jo    0b\n"
-                                "1: sacf  0(1)\n"
-                                "   lr    %0,5\n"
+                                "   sacf  0\n"
+                                "1: lr    %0,3\n"
+                                ".section .fixup,\"ax\"\n"
+                                "2: lhi   5,-4096\n"
+                                "   n     5,0x90\n"
+                                "   sr    5,4\n"
+                                "   mvcle 4,2,0\n"
+                                "   sacf  0\n"
+                                "   basr  4,0\n"
+                                "   l     4,3f-.(4)\n"
+                                "   br    4\n"
+                                "3: .long 1b\n"
+                                ".previous\n"
 				".section __ex_table,\"a\"\n"
 				"   .align 4\n"
-				"   .long  0b,1b\n"
+				"   .long  0b,2b\n"
 				".previous"
                                 : "+&a" (n)
                                 : "a"   (to)
-                                : "cc", "1", "2", "3", "4", "5" );
+                                : "cc", "2", "3", "4", "5" );
         return n;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-s390/ucontext.h linux.17p18/include/asm-s390/ucontext.h
--- linux.vanilla/include/asm-s390/ucontext.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-s390/ucontext.h	Tue Aug  1 08:00:03 2000
@@ -14,6 +14,7 @@
 	struct ucontext  *uc_link;
 	stack_t		  uc_stack;
 	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+	struct sigcontext *sc; /* Added for pthread support */
 };
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-sparc/bitops.h linux.17p18/include/asm-sparc/bitops.h
--- linux.vanilla/include/asm-sparc/bitops.h	Fri Apr 21 12:46:49 2000
+++ linux.17p18/include/asm-sparc/bitops.h	Mon Aug 14 20:12:31 2000
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.54 1998/09/21 05:07:34 jj Exp $
+/* $Id: bitops.h,v 1.54.2.1 2000/08/10 23:50:04 davem Exp $
  * bitops.h: Bit string operations on the Sparc.
  *
  * Copyright 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -240,6 +240,8 @@
 
 found_first:
 	tmp |= ~0UL << size;
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
 found_middle:
 	return result + ffz(tmp);
 }
@@ -387,7 +389,11 @@
 	tmp = *p;
 
 found_first:
-	return result + ffz(__swab32(tmp) | (~0UL << size));
+	tmp = __swab32(tmp) | (~0UL << size);
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
+	return result + ffz(tmp);
+
 found_middle:
 	return result + ffz(__swab32(tmp));
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-sparc64/bitops.h linux.17p18/include/asm-sparc64/bitops.h
--- linux.vanilla/include/asm-sparc64/bitops.h	Fri Apr 21 12:46:50 2000
+++ linux.17p18/include/asm-sparc64/bitops.h	Mon Aug 14 20:12:31 2000
@@ -1,4 +1,4 @@
-/* $Id: bitops.h,v 1.26 1999/01/07 14:14:15 jj Exp $
+/* $Id: bitops.h,v 1.26.2.1 2000/08/10 23:50:04 davem Exp $
  * bitops.h: Bit string operations on the V9.
  *
  * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -273,6 +273,8 @@
 
 found_first:
 	tmp |= ~0UL << size;
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
 found_middle:
 	return result + ffz(tmp);
 }
@@ -369,6 +371,8 @@
 	tmp = __swab64p(p);
 found_first:
 	tmp |= (~0UL << size);
+	if (tmp == ~0UL)        /* Are any bits zero? */
+		return result + size; /* Nope. */
 found_middle:
 	return result + ffz(tmp);
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-sparc64/display7seg.h linux.17p18/include/asm-sparc64/display7seg.h
--- linux.vanilla/include/asm-sparc64/display7seg.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/asm-sparc64/display7seg.h	Tue Aug  1 08:13:46 2000
@@ -0,0 +1,79 @@
+/* $Id: display7seg.h,v 1.1.2.1 2000/07/27 01:50:59 davem Exp $
+ *
+ * display7seg - Driver interface for the 7-segment display
+ * present on Sun Microsystems CP1400 and CP1500
+ *
+ * Copyright (c) 2000 Eric Brower <ebrower@usa.net>
+ *
+ */
+
+#ifndef __display7seg_h__
+#define __display7seg_h__
+
+#define D7S_IOC	'p'
+
+#define D7SIOCRD _IOR(D7S_IOC, 0x45, int)	/* Read device state	*/
+#define D7SIOCWR _IOW(D7S_IOC, 0x46, int)	/* Write device state	*/
+#define D7SIOCTM _IO (D7S_IOC, 0x47)		/* Translate mode (FLIP)*/
+
+/*
+ * ioctl flag definitions
+ *
+ * POINT	- Toggle decimal point	(0=absent 1=present)
+ * ALARM	- Toggle alarm LED 		(0=green  1=red)
+ * FLIP		- Toggle inverted mode 	(0=normal 1=flipped) 
+ * bits 0-4	- Character displayed	(see definitions below)
+ *
+ * Display segments are defined as follows, 
+ * subject to D7S_FLIP register state:
+ *
+ *    a
+ *   ---
+ * f|   |b
+ *   -g-
+ * e|   |c
+ *   ---
+ *    d
+ */
+
+#define D7S_POINT	(1 << 7)	/* Decimal point*/
+#define D7S_ALARM	(1 << 6)	/* Alarm LED 	*/
+#define D7S_FLIP	(1 << 5)	/* Flip display */
+
+#define D7S_0		0x00		/* Numerals 0-9 */
+#define D7S_1		0x01
+#define D7S_2		0x02
+#define D7S_3		0x03
+#define D7S_4		0x04
+#define D7S_5		0x05
+#define D7S_6		0x06
+#define D7S_7		0x07
+#define D7S_8		0x08
+#define D7S_9		0x09
+#define D7S_A		0x0A		/* Letters A-F, H, L, P */
+#define D7S_B		0x0B
+#define D7S_C		0x0C
+#define D7S_D		0x0D
+#define D7S_E		0x0E
+#define D7S_F		0x0F
+#define D7S_H		0x10
+#define D7S_E2		0x11
+#define D7S_L		0x12
+#define D7S_P		0x13
+#define D7S_SEGA	0x14		/* Individual segments */
+#define D7S_SEGB	0x15
+#define D7S_SEGC	0x16
+#define D7S_SEGD	0x17
+#define D7S_SEGE	0x18
+#define D7S_SEGF	0x19
+#define D7S_SEGG	0x1A
+#define D7S_SEGABFG 0x1B		/* Segment groupings */
+#define D7S_SEGCDEG	0x1C
+#define D7S_SEGBCEF 0x1D
+#define D7S_SEGADG	0x1E
+#define D7S_BLANK	0x1F		/* Clear all segments */
+
+#define D7S_MIN_VAL	0x0
+#define D7S_MAX_VAL	0x1F
+
+#endif /* ifndef __display7seg_h__ */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/asm-sparc64/pbm.h linux.17p18/include/asm-sparc64/pbm.h
--- linux.vanilla/include/asm-sparc64/pbm.h	Fri Apr 21 12:46:51 2000
+++ linux.17p18/include/asm-sparc64/pbm.h	Tue Aug  1 08:13:46 2000
@@ -1,4 +1,4 @@
-/* $Id: pbm.h,v 1.16 1999/03/14 18:13:03 davem Exp $
+/* $Id: pbm.h,v 1.16.2.1 2000/06/14 07:41:19 davem Exp $
  * pbm.h: U2P PCI bus module pseudo driver software state.
  *
  * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu)
@@ -13,6 +13,8 @@
 #include <asm/oplib.h>
 
 struct linux_pbm_info;
+
+extern volatile u64 *pci_dma_wsync;
 
 /* This is what we use to determine what the PROM has assigned so
  * far, so that we can perform assignments for addresses which
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/blkdev.h linux.17p18/include/linux/blkdev.h
--- linux.vanilla/include/linux/blkdev.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/blkdev.h	Wed Aug  9 22:33:24 2000
@@ -50,7 +50,7 @@
 ((elevator_t) {						\
 	128,			/* read_latency */	\
 	8192,			/* write_latency */	\
-	4,			/* max_bomb_segments */	\
+	32,			/* max_bomb_segments */	\
         0                       /* queue_ID */          \
 	})
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/cdrom.h linux.17p18/include/linux/cdrom.h
--- linux.vanilla/include/linux/cdrom.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/cdrom.h	Tue Aug  1 08:38:23 2000
@@ -438,9 +438,12 @@
 #define GPCMD_MECHANISM_STATUS		    0xbd
 #define GPCMD_MODE_SELECT_10		    0x55
 #define GPCMD_MODE_SENSE_10		    0x5a
+#define GPCMD_MODE_SELECT_6		    0x15
+#define GPCMD_MODE_SENSE_6		    0x1a
 #define GPCMD_PAUSE_RESUME		    0x4b
 #define GPCMD_PLAY_AUDIO_10		    0x45
 #define GPCMD_PLAY_AUDIO_MSF		    0x47
+#define GPCMD_PLAY_AUDIO_TI		    0x48
 #define GPCMD_PLAY_CD			    0xbc
 #define GPCMD_PREVENT_ALLOW_MEDIUM_REMOVAL  0x1e
 #define GPCMD_READ_10			    0x28
@@ -734,8 +737,8 @@
     	char name[20];                  /* name of the device type */
 /* per-device flags */
         __u8 sanyo_slot		: 2;	/* Sanyo 3 CD changer support */
-        __u8 reserved		: 6;	/* not used yet */
-	struct cdrom_write_settings write;
+        __u8 scsi_2		: 1;	/* strict SCSI-II device */
+        __u8 reserved		: 5;	/* not used yet */
 };
 
 struct cdrom_device_ops {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/coda_cache.h linux.17p18/include/linux/coda_cache.h
--- linux.vanilla/include/linux/coda_cache.h	Fri Apr 21 12:46:59 2000
+++ linux.17p18/include/linux/coda_cache.h	Wed Aug  9 22:23:26 2000
@@ -32,46 +32,4 @@
 void coda_flag_inode(struct inode *inode, int flag);
 void coda_flag_inode_children(struct inode *inode, int flag);
 
-
-/*
- * Structure to contain statistics on the cache usage
- */
-
-struct cfsnc_statistics {
-	unsigned	hits;
-	unsigned	misses;
-	unsigned	enters;
-	unsigned	dbl_enters;
-	unsigned	long_name_enters;
-	unsigned	long_name_lookups;
-	unsigned	long_remove;
-	unsigned	lru_rm;
-	unsigned	zapPfids;
-	unsigned	zapFids;
-	unsigned	zapFile;
-	unsigned	zapUsers;
-	unsigned	Flushes;
-	unsigned        Sum_bucket_len;
-	unsigned        Sum2_bucket_len;
-	unsigned        Max_bucket_len;
-	unsigned        Num_zero_len;
-	unsigned        Search_len;
-};
-
-
-#define CFSNC_FIND		((u_long) 1)
-#define CFSNC_REMOVE		((u_long) 2)
-#define CFSNC_INIT		((u_long) 3)
-#define CFSNC_ENTER		((u_long) 4)
-#define CFSNC_LOOKUP		((u_long) 5)
-#define CFSNC_ZAPPFID		((u_long) 6)
-#define CFSNC_ZAPFID		((u_long) 7)
-#define CFSNC_ZAPVNODE		((u_long) 8)
-#define CFSNC_ZAPFILE		((u_long) 9)
-#define CFSNC_PURGEUSER	((u_long) 10)
-#define CFSNC_FLUSH		((u_long) 11)
-#define CFSNC_PRINTCFSNC	((u_long) 12)
-#define CFSNC_PRINTSTATS	((u_long) 13)
-#define CFSNC_REPLACE		((u_long) 14)
-
 #endif _CFSNC_HEADER_
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/coda_fs_i.h linux.17p18/include/linux/coda_fs_i.h
--- linux.vanilla/include/linux/coda_fs_i.h	Fri Apr 21 23:10:16 2000
+++ linux.17p18/include/linux/coda_fs_i.h	Wed Aug  9 22:23:26 2000
@@ -29,23 +29,18 @@
 
         struct ViceFid     c_fid;	/* Coda identifier */
         u_short	           c_flags;     /* flags (see below) */
-        u_short	           c_ocount;    /* count of openers */
-        u_short            c_owrite;    /* count of open for write */
-        u_short            c_mmcount;   /* count of mmappers */
         struct inode      *c_ovp;       /* open inode  pointer */
         struct list_head   c_cnhead;    /* head of cache entries */
 	struct list_head   c_volrootlist; /* list of volroot cnoddes */
         struct inode      *c_vnode;     /*  inode associated with cnode */
+	unsigned int	   c_contcount; /* refcount for container inode */
         int                c_magic;     /* to verify the data structure */
 };
 
 /* flags */
 #define C_VATTR       0x1   /* Validity of vattr in inode */
-#define C_PURGE       0x8
-#define C_ZAPDIR      0x10
-#define C_DYING       0x4   /* from venus (which died) */
-#define C_INITED      0x20
 #define C_FLUSH       0x2   /* used after a flush */
+#define C_PURGE       0x8
 
 int coda_cnode_make(struct inode **, struct ViceFid *, struct super_block *);
 int coda_cnode_makectl(struct inode **inode, struct super_block *sb);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/coda_linux.h linux.17p18/include/linux/coda_linux.h
--- linux.vanilla/include/linux/coda_linux.h	Fri Apr 21 23:24:17 2000
+++ linux.17p18/include/linux/coda_linux.h	Wed Aug  9 22:51:30 2000
@@ -53,7 +53,6 @@
 int coda_iscontrol(const char *name, size_t length);
 
 void coda_load_creds(struct coda_cred *cred);
-int coda_mycred(struct coda_cred *);
 void coda_vattr_to_iattr(struct inode *, struct coda_vattr *);
 void coda_iattr_to_vattr(struct iattr *, struct coda_vattr *);
 unsigned short coda_flags_to_cflags(unsigned short);
@@ -69,8 +68,6 @@
 			   struct inode *open_inode, struct file *open_file);
 int coda_inode_grab(dev_t dev, ino_t ino, struct inode **ind);
 
-#define NB_SFS_SIZ 0x895440
-
 /* cache.c */
 void coda_purge_children(struct inode *, int);
 void coda_purge_dentries(struct inode *);
@@ -99,15 +96,13 @@
   if (coda_debug & mask) {                                        \
     printk("(%s,l. %d): ",  __FUNCTION__, __LINE__);              \
     printk(format, ## a); }                                       \
-} while (0) ;                            
+} while (0)
 
 #define ENTRY    \
     if(coda_print_entry) printk("Process %d entered %s\n",current->pid,__FUNCTION__)
 
 #define EXIT    \
     if(coda_print_entry) printk("Process %d leaving %s\n",current->pid,__FUNCTION__)
-
-#define CHECK_CNODE(c) do {  } while (0);
 
 #define CODA_ALLOC(ptr, cast, size)                                       \
 do {                                                                      \
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/coda_opstats.h linux.17p18/include/linux/coda_opstats.h
--- linux.vanilla/include/linux/coda_opstats.h	Fri Apr 21 12:46:59 2000
+++ linux.17p18/include/linux/coda_opstats.h	Wed Aug  9 22:23:26 2000
@@ -1,94 +0,0 @@
-
-/*
- * Operation statistics for Coda.
- * Copyright (C) 1997 Carnegie Mellon University
- * 
- * Carnegie Mellon University encourages users of this software
- * to contribute improvements to the Coda project. Contact Peter Braam
- * <coda@coda.cs.cmu.edu>.
- */
-
-
-
-#define CFS_MOUNT_STATS  0
-#define CFS_UMOUNT_STATS 1
-#define CFS_ROOT_STATS   2
-#define CFS_STATFS_STATS 3
-#define CFS_SYNC_STATS   4
-#define CFS_VGET_STATS   5
-#define CFS_VFSOPS_SIZE  6
-
-/* vnodeops:
- *            open: all to venus
- *            close: all to venus
- *            rdrw: bogus.  Maybe redirected to UFS.
- *                          May call open/close for internal opens/closes
- *                          (Does exec not call open?)
- *            ioctl: causes a lookupname
- *                   passes through
- *            select: can't get there from here.
- *            getattr: can be satsified by cache
- *            setattr: all go through
- *            access: can be satisfied by cache
- *            readlink: can be satisfied by cache
- *            fsync: passes through
- *            inactive: passes through
- *            lookup: can be satisfied by cache
- *            create: passes through
- *            remove: passes through
- *            link: passes through
- *            rename: passes through
- *            mkdir: passes through
- *            rmdir: passes through
- *            symlink: passes through
- *            readdir: may be redirected to UFS
- *                     may cause an "internal" open/close
- */
-
-#define CFS_OPEN_STATS     0
-#define CFS_CLOSE_STATS    1
-#define CFS_RDWR_STATS     2
-#define CFS_IOCTL_STATS    3
-#define CFS_SELECT_STATS   4
-#define CFS_GETATTR_STATS  5
-#define CFS_SETATTR_STATS  6
-#define CFS_ACCESS_STATS   7
-#define CFS_READLINK_STATS 8
-#define CFS_FSYNC_STATS    9
-#define CFS_INACTIVE_STATS 10
-#define CFS_LOOKUP_STATS   11
-#define CFS_CREATE_STATS   12
-#define CFS_REMOVE_STATS   13
-#define CFS_LINK_STATS     14
-#define CFS_RENAME_STATS   15
-#define CFS_MKDIR_STATS    16
-#define CFS_RMDIR_STATS    17
-#define CFS_SYMLINK_STATS  18
-#define CFS_READDIR_STATS  19
-#define CFS_VNODEOPS_SIZE  20
-
-
-/*
- * I propose the following structres:
- */
-
-
-struct cfs_op_stats {
-    int opcode;       /* vfs opcode */
-    long entries;     /* number of times call attempted */
-    long sat_intrn;   /* number of times call satisfied by cache */
-    long unsat_intrn; /* number of times call failed in cache, but
-                         was not bounced to venus proper. */
-    long gen_intrn;   /* number of times call generated internally */
-                      /* (do we need that?) */
-};
-
-
-/*
- * With each call to the minicache, we'll bump the counters whenver
- * a call is satisfied internally (through the cache or through a
- * redirect), and whenever an operation is caused internally.
- * Then, we can add the total operations caught by the minicache
- * to the world-wide totals, and leave a caveat for the specific
- * graphs later.
- */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/coda_psdev.h linux.17p18/include/linux/coda_psdev.h
--- linux.vanilla/include/linux/coda_psdev.h	Fri Apr 21 12:46:59 2000
+++ linux.17p18/include/linux/coda_psdev.h	Wed Aug  9 22:23:26 2000
@@ -11,9 +11,8 @@
 struct coda_sb_info
 {
 	struct inode *      sbi_psdev;     /* /dev/cfs? Venus/kernel device */
-	struct inode *      sbi_ctlcp;     /* control magic file */
 	int                 sbi_refct;
-	struct venus_comm *      sbi_vcomm;
+	struct venus_comm * sbi_vcomm;
 	struct inode *      sbi_root;
 	struct super_block *sbi_sb;
 	struct list_head    sbi_cchead;
@@ -27,7 +26,6 @@
 	struct list_head    vc_pending;
 	struct list_head    vc_processing;
 	int                 vc_inuse;
-	pid_t               vc_pid;   /* Venus pid */
 };
 
 
@@ -101,6 +99,7 @@
 #define REQ_ASYNC  0x1
 #define REQ_READ   0x2
 #define REQ_WRITE  0x4
+#define REQ_ABORT  0x8
 
 
 /*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/dasd.h linux.17p18/include/linux/dasd.h
--- linux.vanilla/include/linux/dasd.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/dasd.h	Tue Aug  1 08:00:21 2000
@@ -1,241 +0,0 @@
-
-#ifndef DASD_H
-#define DASD_H
-
-/* First of all the external stuff */
-#include <linux/ioctl.h>
-#include <linux/major.h>
-#include <linux/wait.h>
-
-#define IOCTL_LETTER 'D'
-/* Format the volume or an extent */
-#define BIODASDFORMAT  _IOW(IOCTL_LETTER,0,format_data_t) 
-/* Disable the volume (for Linux) */
-#define BIODASDDISABLE _IO(IOCTL_LETTER,1) 
-/* Enable the volume (for Linux) */
-#define BIODASDENABLE  _IO(IOCTL_LETTER,2) 
-/* Stuff for reading and writing the Label-Area to/from user space */
-#define BIODASDGTVLBL  _IOR(IOCTL_LETTER,3,dasd_volume_label_t)
-#define BIODASDSTVLBL  _IOW(IOCTL_LETTER,4,dasd_volume_label_t)
-#define BIODASDRWTB    _IOWR(IOCTL_LETTER,5,int)
-#define BIODASDRSID    _IOR(IOCTL_LETTER,6,senseid_t)
-#define BIODASDRLB     _IOR(IOCTL_LETTER,7,int)
-#define BLKGETBSZ      _IOR(IOCTL_LETTER,8,int)
-
-typedef struct {
-	int start_unit;
-	int stop_unit;
-	int blksize;
-} format_data_t;
-
-typedef
-union {
-	char bytes[512];
-	struct {
-		/* 80 Bytes of Label data */
-		char identifier[4];	/* e.g. "LNX1", "VOL1" or "CMS1" */
-		char label[6];	/* Given by user */
-		char security;
-		char vtoc[5];	/* Null in "LNX1"-labelled partitions */
-		char reserved0[5];
-		long ci_size;
-		long blk_per_ci;
-		long lab_per_ci;
-		char reserved1[4];
-		char owner[0xe];
-		char no_part;
-		char reserved2[0x1c];
-		/* 16 Byte of some information on the dasd */
-		short blocksize;
-		char nopart;
-		char unused;
-		long unused2[3];
-		/* 7*10 = 70 Bytes of partition data */
-		struct {
-			char type;
-			long start;
-			long size;
-			char unused;
-		} part[7];
-	} __attribute__ ((packed)) label;
-} dasd_volume_label_t;
-
-typedef union {
-	struct {
-		unsigned long no;
-		unsigned int ct;
-	} __attribute__ ((packed)) input;
-	struct {
-		unsigned long noct;
-	} __attribute__ ((packed)) output;
-} __attribute__ ((packed)) dasd_xlate_t;
-
-int dasd_init (void);
-#ifdef MODULE
-int init_module (void);
-void cleanup_module (void);
-#endif				/* MODULE */
-
-/* Definitions for blk.h */
-/* #define DASD_MAGIC 0x44415344  is ascii-"DASD" */
-/* #define dasd_MAGIC 0x64617364;  is ascii-"dasd" */
-#define DASD_MAGIC 0xC4C1E2C4 /* is ebcdic-"DASD" */
-#define dasd_MAGIC 0x8481A284 /* is ebcdic-"dasd" */
-#define MDSK_MAGIC 0xD4C4E2D2 /* is ebcdic-"MDSK" */
-#define mdsk_MAGIC 0x9484A292 /* is ebcdic-"mdsk" */
-#define ERP_MAGIC  0xC5D9D740 /* is ebcdic-"ERP" */
-#define erp_MAGIC  0x45999740 /* is ebcdic-"erp" */
-
-#define DASD_NAME "dasd"
-#define DASD_PARTN_BITS 2
-#define DASD_MAX_DEVICES (256>>DASD_PARTN_BITS)
-
-#define MAJOR_NR DASD_MAJOR
-#define PARTN_BITS DASD_PARTN_BITS
-
-#ifdef __KERNEL__
-/* Now lets turn to the internal sbtuff */
-/*
-   define the debug levels:
-   - 0 No debugging output to console or syslog
-   - 1 Log internal errors to syslog, ignore check conditions 
-   - 2 Log internal errors and check conditions to syslog
-   - 3 Log internal errors to console, log check conditions to syslog
-   - 4 Log internal errors and check conditions to console
-   - 5 panic on internal errors, log check conditions to console
-   - 6 panic on both, internal errors and check conditions
- */
-#define DASD_DEBUG 4
-
-#define DASD_PROFILE
-/*
-   define the level of paranoia
-   - 0 quite sure, that things are going right
-   - 1 sanity checking, only to avoid panics
-   - 2 normal sanity checking
-   - 3 extensive sanity checks
-   - 4 exhaustive debug messages
- */
-#define DASD_PARANOIA 2
-
-/*
-   define the depth of flow control, which is logged as a check condition
-   - 0 No flow control messages
-   - 1 Entry of functions logged like check condition
-   - 2 Entry and exit of functions logged like check conditions
-   - 3 Internal structure broken down
-   - 4 unrolling of loops,...
- */
-#define DASD_FLOW_CONTROL 0
-
-#if DASD_DEBUG > 0
-#define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
-#define PRINT_INFO(x...) printk ( KERN_INFO PRINTK_HEADER x )
-#define PRINT_WARN(x...) printk ( KERN_WARNING PRINTK_HEADER x )
-#define PRINT_ERR(x...) printk ( KERN_ERR PRINTK_HEADER x )
-#define PRINT_FATAL(x...) panic ( PRINTK_HEADER x )
-#else
-#define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
-#define PRINT_INFO(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
-#define PRINT_WARN(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
-#define PRINT_ERR(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
-#define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x )
-#endif				/* DASD_DEBUG */
-
-#define INTERNAL_ERRMSG(x,y...) \
-"Internal error: in file " __FILE__ " line: %d: " x, __LINE__, y
-#define INTERNAL_CHKMSG(x,y...) \
-"Inconsistency: in file " __FILE__ " line: %d: " x, __LINE__, y
-#define INTERNAL_FLWMSG(x,y...) \
-"Flow control: file " __FILE__ " line: %d: " x, __LINE__, y
-
-#if DASD_DEBUG > 4
-#define INTERNAL_ERROR(x...) PRINT_FATAL ( INTERNAL_ERRMSG ( x ) )
-#elif DASD_DEBUG > 2
-#define INTERNAL_ERROR(x...) PRINT_ERR ( INTERNAL_ERRMSG ( x ) )
-#elif DASD_DEBUG > 0
-#define INTERNAL_ERROR(x...) PRINT_WARN ( INTERNAL_ERRMSG ( x ) )
-#else
-#define INTERNAL_ERROR(x...)
-#endif				/* DASD_DEBUG */
-
-#if DASD_DEBUG > 5
-#define INTERNAL_CHECK(x...) PRINT_FATAL ( INTERNAL_CHKMSG ( x ) )
-#elif DASD_DEBUG > 3
-#define INTERNAL_CHECK(x...) PRINT_ERR ( INTERNAL_CHKMSG ( x ) )
-#elif DASD_DEBUG > 1
-#define INTERNAL_CHECK(x...) PRINT_WARN ( INTERNAL_CHKMSG ( x ) )
-#else
-#define INTERNAL_CHECK(x...)
-#endif				/* DASD_DEBUG */
-
-#if DASD_DEBUG > 3
-#define INTERNAL_FLOW(x...) PRINT_ERR ( INTERNAL_FLWMSG ( x ) )
-#elif DASD_DEBUG > 2
-#define INTERNAL_FLOW(x...) PRINT_WARN ( INTERNAL_FLWMSG ( x ) )
-#else
-#define INTERNAL_FLOW(x...)
-#endif				/* DASD_DEBUG */
-
-#if DASD_FLOW_CONTROL > 0
-#define FUNCTION_ENTRY(x) INTERNAL_FLOW( x "entered %s\n","" );
-#else
-#define FUNCTION_ENTRY(x)
-#endif				/* DASD_FLOW_CONTROL */
-
-#if DASD_FLOW_CONTROL > 1
-#define FUNCTION_EXIT(x) INTERNAL_FLOW( x "exited %s\n","" );
-#else
-#define FUNCTION_EXIT(x)
-#endif				/* DASD_FLOW_CONTROL */
-
-#if DASD_FLOW_CONTROL > 2
-#define FUNCTION_CONTROL(x...) INTERNAL_FLOW( x );
-#else
-#define FUNCTION_CONTROL(x...)
-#endif				/* DASD_FLOW_CONTROL */
-
-#if DASD_FLOW_CONTROL > 3
-#define LOOP_CONTROL(x...) INTERNAL_FLOW( x );
-#else
-#define LOOP_CONTROL(x...)
-#endif				/* DASD_FLOW_CONTROL */
-
-#define DASD_DO_IO_SLEEP 0x01
-#define DASD_DO_IO_NOLOCK 0x02
-#define DASD_DO_IO_NODEC 0x04
-
-#define DASD_NOT_FORMATTED 0x01
-
-extern struct wait_queue *dasd_waitq;
-
-#undef DEBUG_DASD_MALLOC
-#ifdef DEBUG_DASD_MALLOC
-void *b;
-#define kmalloc(x...) (PRINT_INFO(" kmalloc %p\n",b=kmalloc(x)),b)
-#define kfree(x) PRINT_INFO(" kfree %p\n",x);kfree(x)
-#define get_free_page(x...) (PRINT_INFO(" gfp %p\n",b=get_free_page(x)),b)
-#define __get_free_pages(x...) (PRINT_INFO(" gfps %p\n",b=__get_free_pages(x)),b)
-#endif				/* DEBUG_DASD_MALLOC */
-
-#endif				/* __KERNEL__ */
-#endif				/* DASD_H */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4 
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/falc-lh.h linux.17p18/include/linux/falc-lh.h
--- linux.vanilla/include/linux/falc-lh.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/linux/falc-lh.h	Tue Aug  1 08:00:21 2000
@@ -0,0 +1,1231 @@
+/*
+ * falc.h	Description of the Siemens FALC T1/E1 framer.
+ *
+ * Author:	Ivan Passos <ivan@cyclades.com>
+ *
+ * Copyright:	(c) 2000 Cyclades Corp.
+ *
+ *	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.
+ *
+ * $Log: falc.h,v $
+ * Revision 1.1 2000/05/15 ivan
+ * Included DJA bits for the LIM2 register.
+ *
+ * Revision 1.0 2000/02/22 ivan
+ * Initial version.
+ *
+ */
+
+#ifndef _FALC_LH_H
+#define _FALC_LH_H
+
+#define NUM_OF_T1_CHANNELS	24
+#define NUM_OF_E1_CHANNELS	32
+
+/*>>>>>>>>>>>>>>>>>  FALC Register Bits (Transmit Mode)  <<<<<<<<<<<<<<<<<<< */
+
+/* CMDR (Command Register)
+   ---------------- E1 & T1 ------------------------------ */
+#define CMDR_RMC	0x80
+#define CMDR_RRES	0x40
+#define CMDR_XREP	0x20
+#define CMDR_XRES	0x10
+#define CMDR_XHF	0x08
+#define CMDR_XTF	0x04
+#define CMDR_XME	0x02
+#define CMDR_SRES	0x01
+
+/* MODE (Mode Register)
+   ----------------- E1 & T1 ----------------------------- */
+#define MODE_MDS2	0x80
+#define MODE_MDS1	0x40
+#define MODE_MDS0	0x20
+#define MODE_BRAC	0x10
+#define MODE_HRAC	0x08
+
+/* IPC (Interrupt Port Configuration)
+   ----------------- E1 & T1 ----------------------------- */
+#define IPC_VIS		0x80
+#define IPC_SCI		0x04
+#define IPC_IC1		0x02
+#define IPC_IC0		0x01
+
+/* CCR1 (Common Configuration Register 1)
+   ----------------- E1 & T1 ----------------------------- */
+#define CCR1_SFLG       0x80
+#define CCR1_XTS16RA    0x40
+#define CCR1_BRM        0x40
+#define CCR1_CASSYM     0x20
+#define CCR1_EDLX       0x20
+#define CCR1_EITS       0x10
+#define CCR1_ITF        0x08
+#define CCR1_RFT1       0x02
+#define CCR1_RFT0       0x01
+
+/* CCR3 (Common Configuration Register 3)
+   ---------------- E1 & T1 ------------------------------ */
+
+#define CCR3_PRE1       0x80
+#define CCR3_PRE0       0x40
+#define CCR3_EPT        0x20
+#define CCR3_RADD       0x10
+#define CCR3_RCRC       0x04
+#define CCR3_XCRC       0x02
+
+
+/* RTR1-4 (Receive Timeslot Register 1-4)
+   ---------------- E1 & T1 ------------------------------ */
+
+#define RTR1_TS0        0x80
+#define RTR1_TS1        0x40
+#define RTR1_TS2        0x20
+#define RTR1_TS3        0x10
+#define RTR1_TS4        0x08
+#define RTR1_TS5        0x04
+#define RTR1_TS6        0x02
+#define RTR1_TS7        0x01
+
+#define RTR2_TS8        0x80
+#define RTR2_TS9        0x40
+#define RTR2_TS10       0x20
+#define RTR2_TS11       0x10
+#define RTR2_TS12       0x08
+#define RTR2_TS13       0x04
+#define RTR2_TS14       0x02
+#define RTR2_TS15       0x01
+
+#define RTR3_TS16       0x80
+#define RTR3_TS17       0x40
+#define RTR3_TS18       0x20
+#define RTR3_TS19       0x10
+#define RTR3_TS20       0x08
+#define RTR3_TS21       0x04
+#define RTR3_TS22       0x02
+#define RTR3_TS23       0x01
+
+#define RTR4_TS24       0x80
+#define RTR4_TS25       0x40
+#define RTR4_TS26       0x20
+#define RTR4_TS27       0x10
+#define RTR4_TS28       0x08
+#define RTR4_TS29       0x04
+#define RTR4_TS30       0x02
+#define RTR4_TS31       0x01
+
+
+/* TTR1-4 (Transmit Timeslot Register 1-4)
+   ---------------- E1 & T1 ------------------------------ */
+
+#define TTR1_TS0        0x80
+#define TTR1_TS1        0x40
+#define TTR1_TS2        0x20
+#define TTR1_TS3        0x10
+#define TTR1_TS4        0x08
+#define TTR1_TS5        0x04
+#define TTR1_TS6        0x02
+#define TTR1_TS7        0x01
+
+#define TTR2_TS8        0x80
+#define TTR2_TS9        0x40
+#define TTR2_TS10       0x20
+#define TTR2_TS11       0x10
+#define TTR2_TS12       0x08
+#define TTR2_TS13       0x04
+#define TTR2_TS14       0x02
+#define TTR2_TS15       0x01
+
+#define TTR3_TS16       0x80
+#define TTR3_TS17       0x40
+#define TTR3_TS18       0x20
+#define TTR3_TS19       0x10
+#define TTR3_TS20       0x08
+#define TTR3_TS21       0x04
+#define TTR3_TS22       0x02
+#define TTR3_TS23       0x01
+
+#define TTR4_TS24       0x80
+#define TTR4_TS25       0x40
+#define TTR4_TS26       0x20
+#define TTR4_TS27       0x10
+#define TTR4_TS28       0x08
+#define TTR4_TS29       0x04
+#define TTR4_TS30       0x02
+#define TTR4_TS31       0x01
+
+
+
+/* IMR0-4 (Interrupt Mask Register 0-4)
+
+   ----------------- E1 & T1 ----------------------------- */
+
+#define IMR0_RME        0x80
+#define IMR0_RFS        0x40
+#define IMR0_T8MS       0x20
+#define IMR0_ISF        0x20
+#define IMR0_RMB        0x10
+#define IMR0_CASC       0x08
+#define IMR0_RSC        0x08
+#define IMR0_CRC6       0x04
+#define IMR0_CRC4       0x04
+#define IMR0_PDEN	0x02
+#define IMR0_RPF        0x01
+
+#define IMR1_CASE       0x80
+#define IMR1_RDO        0x40
+#define IMR1_ALLS       0x20
+#define IMR1_XDU        0x10
+#define IMR1_XMB        0x08
+#define IMR1_XLSC       0x02
+#define IMR1_XPR        0x01
+#define IMR1_LLBSC	0x80
+
+#define IMR2_FAR        0x80
+#define IMR2_LFA        0x40
+#define IMR2_MFAR       0x20
+#define IMR2_T400MS     0x10
+#define IMR2_LMFA       0x10
+#define IMR2_AIS        0x08
+#define IMR2_LOS        0x04
+#define IMR2_RAR        0x02
+#define IMR2_RA         0x01
+
+#define IMR3_ES         0x80
+#define IMR3_SEC        0x40
+#define IMR3_LMFA16     0x20
+#define IMR3_AIS16      0x10
+#define IMR3_RA16       0x08
+#define IMR3_API        0x04
+#define IMR3_XSLP       0x20
+#define IMR3_XSLN       0x10
+#define IMR3_LLBSC      0x08
+#define IMR3_XRS        0x04
+#define IMR3_SLN        0x02
+#define IMR3_SLP        0x01
+
+#define IMR4_LFA        0x80
+#define IMR4_FER        0x40
+#define IMR4_CER        0x20
+#define IMR4_AIS        0x10
+#define IMR4_LOS        0x08
+#define IMR4_CVE        0x04
+#define IMR4_SLIP       0x02
+#define IMR4_EBE        0x01
+
+/* FMR0-5 for E1 and T1  (Framer Mode Register ) */
+
+#define FMR0_XC1        0x80
+#define FMR0_XC0        0x40
+#define FMR0_RC1        0x20
+#define FMR0_RC0        0x10
+#define FMR0_EXTD       0x08
+#define FMR0_ALM        0x04
+#define E1_FMR0_FRS     0x02
+#define T1_FMR0_FRS     0x08
+#define FMR0_SRAF       0x04
+#define FMR0_EXLS       0x02
+#define FMR0_SIM        0x01
+
+#define FMR1_MFCS       0x80
+#define FMR1_AFR        0x40
+#define FMR1_ENSA       0x20
+#define FMR1_CTM        0x80
+#define FMR1_SIGM       0x40
+#define FMR1_EDL        0x20
+#define FMR1_PMOD       0x10
+#define FMR1_XFS        0x08
+#define FMR1_CRC        0x08
+#define FMR1_ECM        0x04
+#define FMR1_IMOD       0x02
+#define FMR1_XAIS       0x01
+
+#define FMR2_RFS1       0x80
+#define FMR2_RFS0       0x40
+#define FMR2_MCSP	0x40
+#define FMR2_RTM        0x20
+#define FMR2_SSP        0x20
+#define FMR2_DAIS       0x10
+#define FMR2_SAIS       0x08
+#define FMR2_PLB        0x04
+#define FMR2_AXRA       0x02
+#define FMR2_ALMF       0x01
+#define FMR2_EXZE       0x01
+
+#define LOOP_RTM	0x40
+#define LOOP_SFM	0x40
+#define LOOP_ECLB	0x20
+#define LOOP_CLA	0x1f
+
+/*--------------------- E1 ----------------------------*/
+#define FMR3_XLD	0x20
+#define FMR3_XLU	0x10
+
+/*--------------------- T1 ----------------------------*/
+#define FMR4_AIS3       0x80
+#define FMR4_TM         0x40
+#define FMR4_XRA        0x20
+#define FMR4_SSC1       0x10
+#define FMR4_SSC0       0x08
+#define FMR4_AUTO       0x04
+#define FMR4_FM1        0x02
+#define FMR4_FM0        0x01
+
+#define FMR5_SRS        0x80
+#define FMR5_EIBR       0x40
+#define FMR5_XLD        0x20
+#define FMR5_XLU        0x10
+
+
+/* LOOP (Channel Loop Back)
+
+   ------------------ E1 & T1 ---------------------------- */
+
+#define LOOP_SFM        0x40
+#define LOOP_ECLB       0x20
+#define LOOP_CLA4       0x10
+#define LOOP_CLA3       0x08
+#define LOOP_CLA2       0x04
+#define LOOP_CLA1       0x02
+#define LOOP_CLA0       0x01
+
+
+
+/* XSW (Transmit Service Word Pulseframe)
+
+   ------------------- E1 --------------------------- */
+
+#define XSW_XSIS        0x80
+#define XSW_XRA         0x20
+#define XSW_XY0         0x10
+#define XSW_XY1         0x08
+#define XSW_XY2         0x04
+#define XSW_XY3         0x02
+#define XSW_XY4         0x01
+
+
+/* XSP (Transmit Spare Bits)
+
+   ------------------- E1 --------------------------- */
+
+#define XSP_XAP         0x80
+#define XSP_CASEN       0x40
+#define XSP_TT0         0x20
+#define XSP_EBP         0x10
+#define XSP_AXS         0x08
+#define XSP_XSIF        0x04
+#define XSP_XS13        0x02
+#define XSP_XS15        0x01
+
+
+/* XC0/1 (Transmit Control 0/1)
+   ------------------ E1 & T1 ---------------------------- */
+
+#define XC0_SA8E        0x80
+#define XC0_SA7E        0x40
+#define XC0_SA6E        0x20
+#define XC0_SA5E        0x10
+#define XC0_SA4E        0x08
+#define XC0_BRM         0x80
+#define XC0_MFBS        0x40
+#define XC0_SFRZ        0x10
+#define XC0_XCO2        0x04
+#define XC0_XCO1        0x02
+#define XC0_XCO0        0x01
+
+#define XC1_XTO5        0x20
+#define XC1_XTO4        0x10
+#define XC1_XTO3        0x08
+#define XC1_XTO2        0x04
+#define XC1_XTO1        0x02
+#define XC1_XTO0        0x01
+
+
+/* RC0/1 (Receive Control 0/1)
+   ------------------ E1 & T1 ---------------------------- */
+
+#define RC0_SICS        0x40
+#define RC0_CRCI        0x20
+#define RC0_XCRCI       0x10
+#define RC0_RDIS        0x08
+#define RC0_RCO2        0x04
+#define RC0_RCO1        0x02
+#define RC0_RCO0        0x01
+
+#define RC1_SWD         0x80
+#define RC1_ASY4        0x40
+#define RC1_RRAM        0x40
+#define RC1_RTO5        0x20
+#define RC1_RTO4        0x10
+#define RC1_RTO3        0x08
+#define RC1_RTO2        0x04
+#define RC1_RTO1        0x02
+#define RC1_RTO0        0x01
+
+
+
+/* XPM0-2 (Transmit Pulse Mask 0-2)
+   --------------------- E1 & T1 ------------------------- */
+
+#define XPM0_XP12       0x80
+#define XPM0_XP11       0x40
+#define XPM0_XP10       0x20
+#define XPM0_XP04       0x10
+#define XPM0_XP03       0x08
+#define XPM0_XP02       0x04
+#define XPM0_XP01       0x02
+#define XPM0_XP00       0x01
+
+#define XPM1_XP30       0x80
+#define XPM1_XP24       0x40
+#define XPM1_XP23       0x20
+#define XPM1_XP22       0x10
+#define XPM1_XP21       0x08
+#define XPM1_XP20       0x04
+#define XPM1_XP14       0x02
+#define XPM1_XP13       0x01
+
+#define XPM2_XLHP       0x80
+#define XPM2_XLT        0x40
+#define XPM2_DAXLT      0x20
+#define XPM2_XP34       0x08
+#define XPM2_XP33       0x04
+#define XPM2_XP32       0x02
+#define XPM2_XP31       0x01
+
+
+/* TSWM (Transparent Service Word Mask)
+   ------------------ E1 ---------------------------- */
+
+#define TSWM_TSIS       0x80
+#define TSWM_TSIF       0x40
+#define TSWM_TRA        0x20
+#define TSWM_TSA4       0x10
+#define TSWM_TSA5       0x08
+#define TSWM_TSA6       0x04
+#define TSWM_TSA7       0x02
+#define TSWM_TSA8       0x01
+
+/* IDLE <Idle Channel Code Register>
+
+   ------------------ E1 & T1 ----------------------- */
+
+#define IDLE_IDL7       0x80
+#define IDLE_IDL6       0x40
+#define IDLE_IDL5       0x20
+#define IDLE_IDL4       0x10
+#define IDLE_IDL3       0x08
+#define IDLE_IDL2       0x04
+#define IDLE_IDL1       0x02
+#define IDLE_IDL0       0x01
+
+
+/* XSA4-8 <Transmit SA4-8 Register(Read/Write) >
+   -------------------E1 ----------------------------- */
+
+#define XSA4_XS47       0x80
+#define XSA4_XS46       0x40
+#define XSA4_XS45       0x20
+#define XSA4_XS44       0x10
+#define XSA4_XS43       0x08
+#define XSA4_XS42       0x04
+#define XSA4_XS41       0x02
+#define XSA4_XS40       0x01
+
+#define XSA5_XS57       0x80
+#define XSA5_XS56       0x40
+#define XSA5_XS55       0x20
+#define XSA5_XS54       0x10
+#define XSA5_XS53       0x08
+#define XSA5_XS52       0x04
+#define XSA5_XS51       0x02
+#define XSA5_XS50       0x01
+
+#define XSA6_XS67       0x80
+#define XSA6_XS66       0x40
+#define XSA6_XS65       0x20
+#define XSA6_XS64       0x10
+#define XSA6_XS63       0x08
+#define XSA6_XS62       0x04
+#define XSA6_XS61       0x02
+#define XSA6_XS60       0x01
+
+#define XSA7_XS77       0x80
+#define XSA7_XS76       0x40
+#define XSA7_XS75       0x20
+#define XSA7_XS74       0x10
+#define XSA7_XS73       0x08
+#define XSA7_XS72       0x04
+#define XSA7_XS71       0x02
+#define XSA7_XS70       0x01
+
+#define XSA8_XS87       0x80
+#define XSA8_XS86       0x40
+#define XSA8_XS85       0x20
+#define XSA8_XS84       0x10
+#define XSA8_XS83       0x08
+#define XSA8_XS82       0x04
+#define XSA8_XS81       0x02
+#define XSA8_XS80       0x01
+
+
+/* XDL1-3 (Transmit DL-Bit Register1-3 (read/write))
+   ----------------------- T1 --------------------- */
+
+#define XDL1_XDL17      0x80
+#define XDL1_XDL16      0x40
+#define XDL1_XDL15      0x20
+#define XDL1_XDL14      0x10
+#define XDL1_XDL13      0x08
+#define XDL1_XDL12      0x04
+#define XDL1_XDL11      0x02
+#define XDL1_XDL10      0x01
+
+#define XDL2_XDL27      0x80
+#define XDL2_XDL26      0x40
+#define XDL2_XDL25      0x20
+#define XDL2_XDL24      0x10
+#define XDL2_XDL23      0x08
+#define XDL2_XDL22      0x04
+#define XDL2_XDL21      0x02
+#define XDL2_XDL20      0x01
+
+#define XDL3_XDL37      0x80
+#define XDL3_XDL36      0x40
+#define XDL3_XDL35      0x20
+#define XDL3_XDL34      0x10
+#define XDL3_XDL33      0x08
+#define XDL3_XDL32      0x04
+#define XDL3_XDL31      0x02
+#define XDL3_XDL30      0x01
+
+
+/* ICB1-4 (Idle Channel Register 1-4)
+   ------------------ E1 ---------------------------- */
+
+#define E1_ICB1_IC0	0x80
+#define E1_ICB1_IC1	0x40
+#define E1_ICB1_IC2	0x20
+#define E1_ICB1_IC3	0x10
+#define E1_ICB1_IC4	0x08
+#define E1_ICB1_IC5	0x04
+#define E1_ICB1_IC6	0x02
+#define E1_ICB1_IC7	0x01
+
+#define E1_ICB2_IC8	0x80
+#define E1_ICB2_IC9	0x40
+#define E1_ICB2_IC10	0x20
+#define E1_ICB2_IC11	0x10
+#define E1_ICB2_IC12	0x08
+#define E1_ICB2_IC13	0x04
+#define E1_ICB2_IC14	0x02
+#define E1_ICB2_IC15	0x01
+
+#define E1_ICB3_IC16	0x80
+#define E1_ICB3_IC17	0x40
+#define E1_ICB3_IC18	0x20
+#define E1_ICB3_IC19	0x10
+#define E1_ICB3_IC20	0x08
+#define E1_ICB3_IC21	0x04
+#define E1_ICB3_IC22	0x02
+#define E1_ICB3_IC23	0x01
+
+#define E1_ICB4_IC24	0x80
+#define E1_ICB4_IC25	0x40
+#define E1_ICB4_IC26	0x20
+#define E1_ICB4_IC27	0x10
+#define E1_ICB4_IC28	0x08
+#define E1_ICB4_IC29	0x04
+#define E1_ICB4_IC30	0x02
+#define E1_ICB4_IC31	0x01
+
+/* ICB1-4 (Idle Channel Register 1-4)
+   ------------------ T1 ---------------------------- */
+
+#define T1_ICB1_IC1	0x80
+#define T1_ICB1_IC2	0x40
+#define T1_ICB1_IC3	0x20
+#define T1_ICB1_IC4	0x10
+#define T1_ICB1_IC5	0x08
+#define T1_ICB1_IC6	0x04
+#define T1_ICB1_IC7	0x02
+#define T1_ICB1_IC8	0x01
+
+#define T1_ICB2_IC9	0x80
+#define T1_ICB2_IC10	0x40
+#define T1_ICB2_IC11	0x20
+#define T1_ICB2_IC12	0x10
+#define T1_ICB2_IC13	0x08
+#define T1_ICB2_IC14	0x04
+#define T1_ICB2_IC15	0x02
+#define T1_ICB2_IC16	0x01
+
+#define T1_ICB3_IC17	0x80
+#define T1_ICB3_IC18	0x40
+#define T1_ICB3_IC19	0x20
+#define T1_ICB3_IC20	0x10
+#define T1_ICB3_IC21	0x08
+#define T1_ICB3_IC22	0x04
+#define T1_ICB3_IC23	0x02
+#define T1_ICB3_IC24	0x01
+
+/* FMR3 (Framer Mode Register 3)
+   --------------------E1------------------------ */
+
+#define FMR3_CMI        0x08
+#define FMR3_SYNSA      0x04
+#define FMR3_CFRZ       0x02
+#define FMR3_EXTIW      0x01
+
+
+
+/* CCB1-3 (Clear Channel Register)
+   ------------------- T1 ----------------------- */
+
+#define CCB1_CH1        0x80
+#define CCB1_CH2        0x40
+#define CCB1_CH3        0x20
+#define CCB1_CH4        0x10
+#define CCB1_CH5        0x08
+#define CCB1_CH6        0x04
+#define CCB1_CH7        0x02
+#define CCB1_CH8        0x01
+
+#define CCB2_CH9        0x80
+#define CCB2_CH10       0x40
+#define CCB2_CH11       0x20
+#define CCB2_CH12       0x10
+#define CCB2_CH13       0x08
+#define CCB2_CH14       0x04
+#define CCB2_CH15       0x02
+#define CCB2_CH16       0x01
+
+#define CCB3_CH17       0x80
+#define CCB3_CH18       0x40
+#define CCB3_CH19       0x20
+#define CCB3_CH20       0x10
+#define CCB3_CH21       0x08
+#define CCB3_CH22       0x04
+#define CCB3_CH23       0x02
+#define CCB3_CH24       0x01
+
+
+/* LIM0/1 (Line Interface Mode 0/1)
+   ------------------- E1 & T1 --------------------------- */
+
+#define LIM0_XFB        0x80
+#define LIM0_XDOS       0x40
+#define LIM0_SCL1       0x20
+#define LIM0_SCL0       0x10
+#define LIM0_EQON       0x08
+#define LIM0_ELOS       0x04
+#define LIM0_LL         0x02
+#define LIM0_MAS        0x01
+
+#define LIM1_EFSC       0x80
+#define LIM1_RIL2       0x40
+#define LIM1_RIL1       0x20
+#define LIM1_RIL0       0x10
+#define LIM1_DCOC       0x08
+#define LIM1_JATT       0x04
+#define LIM1_RL         0x02
+#define LIM1_DRS        0x01
+
+
+/* PCDR (Pulse Count Detection Register(Read/Write))
+   ------------------ E1 & T1 ------------------------- */
+
+#define PCDR_PCD7	0x80
+#define PCDR_PCD6	0x40
+#define PCDR_PCD5	0x20
+#define PCDR_PCD4	0x10
+#define PCDR_PCD3	0x08
+#define PCDR_PCD2	0x04
+#define PCDR_PCD1	0x02
+#define PCDR_PCD0	0x01
+
+#define PCRR_PCR7	0x80
+#define PCRR_PCR6	0x40
+#define PCRR_PCR5	0x20
+#define PCRR_PCR4	0x10
+#define PCRR_PCR3	0x08
+#define PCRR_PCR2	0x04
+#define PCRR_PCR1	0x02
+#define PCRR_PCR0	0x01
+
+
+/* LIM2 (Line Interface Mode 2)
+
+   ------------------ E1 & T1 ---------------------------- */
+
+#define LIM2_DJA2	0x20
+#define LIM2_DJA1	0x10
+#define LIM2_LOS2	0x02
+#define LIM2_LOS1	0x01
+
+/* LCR1 (Loop Code Register 1) */
+
+#define LCR1_EPRM	0x80
+#define	LCR1_XPRBS	0x40
+
+/* SIC1 (System Interface Control 1) */
+#define SIC1_SRSC	0x80
+#define SIC1_RBS1	0x20
+#define SIC1_RBS0	0x10
+#define SIC1_SXSC	0x08
+#define SIC1_XBS1	0x02
+#define SIC1_XBS0	0x01
+
+/* DEC (Disable Error Counter)
+   ------------------ E1 & T1 ---------------------------- */
+
+#define DEC_DCEC3       0x20
+#define DEC_DBEC        0x10
+#define DEC_DCEC1       0x08
+#define DEC_DCEC        0x08
+#define DEC_DEBC        0x04
+#define DEC_DCVC        0x02
+#define DEC_DFEC        0x01
+
+
+/* FALC Register Bits (Receive Mode)
+   ---------------------------------------------------------------------------- */
+
+
+/* FRS0/1 (Framer Receive Status Register 0/1)
+   ----------------- E1 & T1 ---------------------------------- */
+
+#define FRS0_LOS        0x80
+#define FRS0_AIS        0x40
+#define FRS0_LFA        0x20
+#define FRS0_RRA        0x10
+#define FRS0_API        0x08
+#define FRS0_NMF        0x04
+#define FRS0_LMFA       0x02
+#define FRS0_FSRF       0x01
+
+#define FRS1_TS16RA     0x40
+#define FRS1_TS16LOS    0x20
+#define FRS1_TS16AIS    0x10
+#define FRS1_TS16LFA    0x08
+#define FRS1_EXZD       0x80
+#define FRS1_LLBDD      0x10
+#define FRS1_LLBAD      0x08
+#define FRS1_XLS        0x02
+#define FRS1_XLO        0x01
+#define FRS1_PDEN	0x40
+
+/* FRS2/3 (Framer Receive Status Register 2/3)
+   ----------------- T1 ---------------------------------- */
+
+#define FRS2_ESC2       0x80
+#define FRS2_ESC1       0x40
+#define FRS2_ESC0       0x20
+
+#define FRS3_FEH5       0x20
+#define FRS3_FEH4       0x10
+#define FRS3_FEH3       0x08
+#define FRS3_FEH2       0x04
+#define FRS3_FEH1       0x02
+#define FRS3_FEH0       0x01
+
+
+/* RSW (Receive Service Word Pulseframe)
+   ----------------- E1 ------------------------------ */
+
+#define RSW_RSI         0x80
+#define RSW_RRA         0x20
+#define RSW_RYO         0x10
+#define RSW_RY1         0x08
+#define RSW_RY2         0x04
+#define RSW_RY3         0x02
+#define RSW_RY4         0x01
+
+
+/* RSP (Receive Spare Bits / Additional Status)
+   ---------------- E1 ------------------------------- */
+
+#define RSP_SI1         0x80
+#define RSP_SI2         0x40
+#define RSP_LLBDD	0x10
+#define RSP_LLBAD	0x08
+#define RSP_RSIF        0x04
+#define RSP_RS13        0x02
+#define RSP_RS15        0x01
+
+
+/* FECL (Framing Error Counter)
+   ---------------- E1 & T1 -------------------------- */
+
+#define FECL_FE7        0x80
+#define FECL_FE6        0x40
+#define FECL_FE5        0x20
+#define FECL_FE4        0x10
+#define FECL_FE3        0x08
+#define FECL_FE2        0x04
+#define FECL_FE1        0x02
+#define FECL_FE0        0x01
+
+#define FECH_FE15       0x80
+#define FECH_FE14       0x40
+#define FECH_FE13       0x20
+#define FECH_FE12       0x10
+#define FECH_FE11       0x08
+#define FECH_FE10       0x04
+#define FECH_FE9        0x02
+#define FECH_FE8        0x01
+
+
+/* CVCl (Code Violation Counter)
+   ----------------- E1 ------------------------- */
+
+#define CVCL_CV7        0x80
+#define CVCL_CV6        0x40
+#define CVCL_CV5        0x20
+#define CVCL_CV4        0x10
+#define CVCL_CV3        0x08
+#define CVCL_CV2        0x04
+#define CVCL_CV1        0x02
+#define CVCL_CV0        0x01
+
+#define CVCH_CV15       0x80
+#define CVCH_CV14       0x40
+#define CVCH_CV13       0x20
+#define CVCH_CV12       0x10
+#define CVCH_CV11       0x08
+#define CVCH_CV10       0x04
+#define CVCH_CV9        0x02
+#define CVCH_CV8        0x01
+
+
+/* CEC1-3L (CRC Error Counter)
+   ------------------ E1 ----------------------------- */
+
+#define CEC1L_CR7       0x80
+#define CEC1L_CR6       0x40
+#define CEC1L_CR5       0x20
+#define CEC1L_CR4       0x10
+#define CEC1L_CR3       0x08
+#define CEC1L_CR2       0x04
+#define CEC1L_CR1       0x02
+#define CEC1L_CR0       0x01
+
+#define CEC1H_CR15      0x80
+#define CEC1H_CR14      0x40
+#define CEC1H_CR13      0x20
+#define CEC1H_CR12      0x10
+#define CEC1H_CR11      0x08
+#define CEC1H_CR10      0x04
+#define CEC1H_CR9       0x02
+#define CEC1H_CR8       0x01
+
+#define CEC2L_CR7       0x80
+#define CEC2L_CR6       0x40
+#define CEC2L_CR5       0x20
+#define CEC2L_CR4       0x10
+#define CEC2L_CR3       0x08
+#define CEC2L_CR2       0x04
+#define CEC2L_CR1       0x02
+#define CEC2L_CR0       0x01
+
+#define CEC2H_CR15      0x80
+#define CEC2H_CR14      0x40
+#define CEC2H_CR13      0x20
+#define CEC2H_CR12      0x10
+#define CEC2H_CR11      0x08
+#define CEC2H_CR10      0x04
+#define CEC2H_CR9       0x02
+#define CEC2H_CR8       0x01
+
+#define CEC3L_CR7       0x80
+#define CEC3L_CR6       0x40
+#define CEC3L_CR5       0x20
+#define CEC3L_CR4       0x10
+#define CEC3L_CR3       0x08
+#define CEC3L_CR2       0x04
+#define CEC3L_CR1       0x02
+#define CEC3L_CR0       0x01
+
+#define CEC3H_CR15      0x80
+#define CEC3H_CR14      0x40
+#define CEC3H_CR13      0x20
+#define CEC3H_CR12      0x10
+#define CEC3H_CR11      0x08
+#define CEC3H_CR10      0x04
+#define CEC3H_CR9       0x02
+#define CEC3H_CR8       0x01
+
+
+/* CECL (CRC Error Counter)
+
+   ------------------ T1 ----------------------------- */
+
+#define CECL_CR7        0x80
+#define CECL_CR6        0x40
+#define CECL_CR5        0x20
+#define CECL_CR4        0x10
+#define CECL_CR3        0x08
+#define CECL_CR2        0x04
+#define CECL_CR1        0x02
+#define CECL_CR0        0x01
+
+#define CECH_CR15       0x80
+#define CECH_CR14       0x40
+#define CECH_CR13       0x20
+#define CECH_CR12       0x10
+#define CECH_CR11       0x08
+#define CECH_CR10       0x04
+#define CECH_CR9        0x02
+#define CECH_CR8        0x01
+
+/* EBCL (E Bit Error Counter)
+   ------------------- E1 & T1 ------------------------- */
+
+#define EBCL_EB7        0x80
+#define EBCL_EB6        0x40
+#define EBCL_EB5        0x20
+#define EBCL_EB4        0x10
+#define EBCL_EB3        0x08
+#define EBCL_EB2        0x04
+#define EBCL_EB1        0x02
+#define EBCL_EB0        0x01
+
+#define EBCH_EB15       0x80
+#define EBCH_EB14       0x40
+#define EBCH_EB13       0x20
+#define EBCH_EB12       0x10
+#define EBCH_EB11       0x08
+#define EBCH_EB10       0x04
+#define EBCH_EB9        0x02
+#define EBCH_EB8        0x01
+
+
+/* RSA4-8 (Receive Sa4-8-Bit Register)
+   -------------------- E1 --------------------------- */
+
+#define RSA4_RS47       0x80
+#define RSA4_RS46       0x40
+#define RSA4_RS45       0x20
+#define RSA4_RS44       0x10
+#define RSA4_RS43       0x08
+#define RSA4_RS42       0x04
+#define RSA4_RS41       0x02
+#define RSA4_RS40       0x01
+
+#define RSA5_RS57       0x80
+#define RSA5_RS56       0x40
+#define RSA5_RS55       0x20
+#define RSA5_RS54       0x10
+#define RSA5_RS53       0x08
+#define RSA5_RS52       0x04
+#define RSA5_RS51       0x02
+#define RSA5_RS50       0x01
+
+#define RSA6_RS67       0x80
+#define RSA6_RS66       0x40
+#define RSA6_RS65       0x20
+#define RSA6_RS64       0x10
+#define RSA6_RS63       0x08
+#define RSA6_RS62       0x04
+#define RSA6_RS61       0x02
+#define RSA6_RS60       0x01
+
+#define RSA7_RS77       0x80
+#define RSA7_RS76       0x40
+#define RSA7_RS75       0x20
+#define RSA7_RS74       0x10
+#define RSA7_RS73       0x08
+#define RSA7_RS72       0x04
+#define RSA7_RS71       0x02
+#define RSA7_RS70       0x01
+
+#define RSA8_RS87       0x80
+#define RSA8_RS86       0x40
+#define RSA8_RS85       0x20
+#define RSA8_RS84       0x10
+#define RSA8_RS83       0x08
+#define RSA8_RS82       0x04
+#define RSA8_RS81       0x02
+#define RSA8_RS80       0x01
+
+/* RSA6S (Receive Sa6 Bit Status Register)
+   ------------------------ T1 ------------------------- */
+
+#define RSA6S_SX        0x20
+#define RSA6S_SF        0x10
+#define RSA6S_SE        0x08
+#define RSA6S_SC        0x04
+#define RSA6S_SA        0x02
+#define RSA6S_S8        0x01
+
+
+/* RDL1-3 Receive DL-Bit Register1-3)
+   ------------------------ T1 ------------------------- */
+
+#define RDL1_RDL17      0x80
+#define RDL1_RDL16      0x40
+#define RDL1_RDL15      0x20
+#define RDL1_RDL14      0x10
+#define RDL1_RDL13      0x08
+#define RDL1_RDL12      0x04
+#define RDL1_RDL11      0x02
+#define RDL1_RDL10      0x01
+
+#define RDL2_RDL27      0x80
+#define RDL2_RDL26      0x40
+#define RDL2_RDL25      0x20
+#define RDL2_RDL24      0x10
+#define RDL2_RDL23      0x08
+#define RDL2_RDL22      0x04
+#define RDL2_RDL21      0x02
+#define RDL2_RDL20      0x01
+
+#define RDL3_RDL37      0x80
+#define RDL3_RDL36      0x40
+#define RDL3_RDL35      0x20
+#define RDL3_RDL34      0x10
+#define RDL3_RDL33      0x08
+#define RDL3_RDL32      0x04
+#define RDL3_RDL31      0x02
+#define RDL3_RDL30      0x01
+
+
+/* SIS (Signaling Status Register)
+
+   -------------------- E1 & T1 -------------------------- */
+
+#define SIS_XDOV        0x80
+#define SIS_XFW         0x40
+#define SIS_XREP        0x20
+#define SIS_RLI         0x08
+#define SIS_CEC         0x04
+#define SIS_BOM         0x01
+
+
+/* RSIS (Receive Signaling Status Register)
+
+   -------------------- E1 & T1 --------------------------- */
+
+#define RSIS_VFR        0x80
+#define RSIS_RDO        0x40
+#define RSIS_CRC16      0x20
+#define RSIS_RAB        0x10
+#define RSIS_HA1        0x08
+#define RSIS_HA0        0x04
+#define RSIS_HFR        0x02
+#define RSIS_LA         0x01
+
+
+/* RBCL/H (Receive Byte Count Low/High)
+
+   ------------------- E1 & T1 ----------------------- */
+
+#define RBCL_RBC7       0x80
+#define RBCL_RBC6       0x40
+#define RBCL_RBC5       0x20
+#define RBCL_RBC4       0x10
+#define RBCL_RBC3       0x08
+#define RBCL_RBC2       0x04
+#define RBCL_RBC1       0x02
+#define RBCL_RBC0       0x01
+
+#define RBCH_OV         0x10
+#define RBCH_RBC11      0x08
+#define RBCH_RBC10      0x04
+#define RBCH_RBC9       0x02
+#define RBCH_RBC8       0x01
+
+
+/* ISR1-3  (Interrupt Status Register 1-3)
+
+   ------------------ E1 & T1 ------------------------------ */
+
+#define  FISR0_RME	0x80
+#define  FISR0_RFS	0x40
+#define  FISR0_T8MS	0x20
+#define  FISR0_ISF	0x20
+#define  FISR0_RMB	0x10
+#define  FISR0_CASC	0x08
+#define  FISR0_RSC	0x08
+#define  FISR0_CRC6	0x04
+#define  FISR0_CRC4	0x04
+#define  FISR0_PDEN	0x02
+#define  FISR0_RPF	0x01
+
+#define  FISR1_CASE	0x80
+#define  FISR1_LLBSC	0x80
+#define  FISR1_RDO	0x40
+#define  FISR1_ALLS	0x20
+#define  FISR1_XDU	0x10
+#define  FISR1_XMB	0x08
+#define  FISR1_XLSC	0x02
+#define  FISR1_XPR	0x01
+
+#define  FISR2_FAR	0x80
+#define  FISR2_LFA	0x40
+#define  FISR2_MFAR	0x20
+#define  FISR2_T400MS	0x10
+#define  FISR2_LMFA	0x10
+#define  FISR2_AIS	0x08
+#define  FISR2_LOS	0x04
+#define  FISR2_RAR	0x02
+#define  FISR2_RA	0x01
+
+#define  FISR3_ES	0x80
+#define  FISR3_SEC	0x40
+#define  FISR3_LMFA16	0x20
+#define  FISR3_AIS16	0x10
+#define  FISR3_RA16	0x08
+#define  FISR3_API	0x04
+#define  FISR3_XSLP	0x20
+#define  FISR3_XSLN	0x10
+#define  FISR3_LLBSC	0x08
+#define  FISR3_XRS	0x04
+#define  FISR3_SLN	0x02
+#define  FISR3_SLP	0x01
+
+
+/* GIS  (Global Interrupt Status Register)
+
+   --------------------- E1 & T1 --------------------- */
+
+#define  GIS_ISR3	0x08
+#define  GIS_ISR2	0x04
+#define  GIS_ISR1	0x02
+#define  GIS_ISR0	0x01
+
+
+/* VSTR  (Version Status Register)
+
+   --------------------- E1 & T1 --------------------- */
+
+#define  VSTR_VN3	0x08
+#define  VSTR_VN2	0x04
+#define  VSTR_VN1	0x02
+#define  VSTR_VN0	0x01
+
+
+/*>>>>>>>>>>>>>>>>>>>>>  Local Control Structures  <<<<<<<<<<<<<<<<<<<<<<<<< */
+
+/* Write-only Registers (E1/T1 control mode write registers) */
+#define XFIFOH	0x00		/* Tx FIFO High Byte */
+#define XFIFOL	0x01		/* Tx FIFO Low Byte */
+#define CMDR	0x02		/* Command Reg */
+#define DEC	0x60		/* Disable Error Counter */
+#define TEST2	0x62		/* Manuf. Test Reg 2 */
+#define XS(nbr)	(0x70 + (nbr))	/* Tx CAS Reg (0 to 15) */
+
+/* Read-write Registers (E1/T1 status mode read registers) */
+#define MODE	0x03	/* Mode Reg */
+#define RAH1	0x04	/* Receive Address High 1 */
+#define RAH2	0x05	/* Receive Address High 2 */
+#define RAL1	0x06	/* Receive Address Low 1 */
+#define RAL2	0x07	/* Receive Address Low 2 */
+#define IPC	0x08	/* Interrupt Port Configuration */
+#define CCR1	0x09	/* Common Configuration Reg 1 */
+#define CCR3	0x0A	/* Common Configuration Reg 3 */
+#define PRE	0x0B	/* Preamble Reg */
+#define RTR1	0x0C	/* Receive Timeslot Reg 1 */
+#define RTR2	0x0D	/* Receive Timeslot Reg 2 */
+#define RTR3	0x0E	/* Receive Timeslot Reg 3 */
+#define RTR4	0x0F	/* Receive Timeslot Reg 4 */
+#define TTR1	0x10	/* Transmit Timeslot Reg 1 */
+#define TTR2	0x11	/* Transmit Timeslot Reg 2 */
+#define TTR3	0x12	/* Transmit Timeslot Reg 3 */
+#define TTR4	0x13	/* Transmit Timeslot Reg 4 */
+#define IMR0	0x14	/* Interrupt Mask Reg 0 */
+#define IMR1	0x15	/* Interrupt Mask Reg 1 */
+#define IMR2	0x16	/* Interrupt Mask Reg 2 */
+#define IMR3	0x17	/* Interrupt Mask Reg 3 */
+#define IMR4	0x18	/* Interrupt Mask Reg 4 */
+#define IMR5	0x19	/* Interrupt Mask Reg 5 */
+#define FMR0	0x1A	/* Framer Mode Reigster 0 */
+#define FMR1	0x1B	/* Framer Mode Reigster 1 */
+#define FMR2	0x1C	/* Framer Mode Reigster 2 */
+#define LOOP	0x1D	/* Channel Loop Back */
+#define XSW	0x1E	/* Transmit Service Word */
+#define FMR4	0x1E	/* Framer Mode Reg 4 */
+#define XSP	0x1F	/* Transmit Spare Bits */
+#define FMR5	0x1F	/* Framer Mode Reg 5 */
+#define XC0	0x20	/* Transmit Control 0 */
+#define XC1	0x21	/* Transmit Control 1 */
+#define RC0	0x22	/* Receive Control 0 */
+#define RC1	0x23	/* Receive Control 1 */
+#define XPM0	0x24	/* Transmit Pulse Mask 0 */
+#define XPM1	0x25	/* Transmit Pulse Mask 1 */
+#define XPM2	0x26	/* Transmit Pulse Mask 2 */
+#define TSWM	0x27	/* Transparent Service Word Mask */
+#define TEST1	0x28	/* Manuf. Test Reg 1 */
+#define IDLE	0x29	/* Idle Channel Code */
+#define XSA4    0x2A	/* Transmit SA4 Bit Reg */
+#define XDL1	0x2A	/* Transmit DL-Bit Reg 2 */
+#define XSA5    0x2B	/* Transmit SA4 Bit Reg */
+#define XDL2	0x2B	/* Transmit DL-Bit Reg 2 */
+#define XSA6    0x2C	/* Transmit SA4 Bit Reg */
+#define XDL3	0x2C	/* Transmit DL-Bit Reg 2 */
+#define XSA7    0x2D	/* Transmit SA4 Bit Reg */
+#define CCB1	0x2D	/* Clear Channel Reg 1 */
+#define XSA8    0x2E	/* Transmit SA4 Bit Reg */
+#define CCB2	0x2E	/* Clear Channel Reg 2 */
+#define FMR3	0x2F	/* Framer Mode Reg. 3 */
+#define CCB3	0x2F	/* Clear Channel Reg 3 */
+#define ICB1	0x30	/* Idle Channel Reg 1 */
+#define ICB2	0x31	/* Idle Channel Reg 2 */
+#define ICB3	0x32	/* Idle Channel Reg 3 */
+#define ICB4	0x33	/* Idle Channel Reg 4 */
+#define LIM0	0x34	/* Line Interface Mode 0 */
+#define LIM1	0x35	/* Line Interface Mode 1 */
+#define PCDR	0x36	/* Pulse Count Detection */
+#define PCRR	0x37	/* Pulse Count Recovery */
+#define LIM2	0x38	/* Line Interface Mode Reg 2 */
+#define LCR1	0x39	/* Loop Code Reg 1 */
+#define LCR2	0x3A	/* Loop Code Reg 2 */
+#define LCR3	0x3B	/* Loop Code Reg 3 */
+#define SIC1	0x3C	/* System Interface Control 1 */
+
+/* Read-only Registers (E1/T1 control mode read registers) */
+#define RFIFOH	0x00		/* Receive FIFO */
+#define RFIFOL	0x01		/* Receive FIFO */
+#define FRS0	0x4C		/* Framer Receive Status 0 */
+#define FRS1	0x4D		/* Framer Receive Status 1 */
+#define RSW	0x4E		/* Receive Service Word */
+#define FRS2	0x4E		/* Framer Receive Status 2 */
+#define RSP	0x4F		/* Receive Spare Bits */
+#define FRS3	0x4F		/* Framer Receive Status 3 */
+#define FECL	0x50		/* Framing Error Counter */
+#define FECH	0x51		/* Framing Error Counter */
+#define CVCL	0x52		/* Code Violation Counter */
+#define CVCH	0x53		/* Code Violation Counter */
+#define CECL	0x54		/* CRC Error Counter 1 */
+#define CECH	0x55		/* CRC Error Counter 1 */
+#define EBCL	0x56		/* E-Bit Error Counter */
+#define EBCH	0x57		/* E-Bit Error Counter */
+#define BECL	0x58		/* Bit Error Counter Low */
+#define BECH	0x59		/* Bit Error Counter Low */
+#define CEC3	0x5A		/* CRC Error Counter 3 (16-bit) */
+#define RSA4	0x5C		/* Receive SA4 Bit Reg */
+#define RDL1	0x5C		/* Receive DL-Bit Reg 1 */
+#define RSA5	0x5D		/* Receive SA5 Bit Reg */
+#define RDL2	0x5D		/* Receive DL-Bit Reg 2 */
+#define RSA6	0x5E		/* Receive SA6 Bit Reg */
+#define RDL3	0x5E		/* Receive DL-Bit Reg 3 */
+#define RSA7	0x5F		/* Receive SA7 Bit Reg */
+#define RSA8	0x60		/* Receive SA8 Bit Reg */
+#define RSA6S	0x61		/* Receive SA6 Bit Status Reg */
+#define TSR0	0x62		/* Manuf. Test Reg 0 */
+#define TSR1	0x63		/* Manuf. Test Reg 1 */
+#define SIS	0x64		/* Signaling Status Reg */
+#define RSIS	0x65		/* Receive Signaling Status Reg */
+#define RBCL	0x66		/* Receive Byte Control */
+#define RBCH	0x67		/* Receive Byte Control */
+#define FISR0	0x68		/* Interrupt Status Reg 0 */
+#define FISR1	0x69		/* Interrupt Status Reg 1 */
+#define FISR2	0x6A		/* Interrupt Status Reg 2 */
+#define FISR3	0x6B		/* Interrupt Status Reg 3 */
+#define GIS	0x6E		/* Global Interrupt Status */
+#define VSTR	0x6F		/* Version Status */
+#define RS(nbr)	(0x70 + (nbr))	/* Rx CAS Reg (0 to 15) */
+
+#endif	/* _FALC_LH_H */
+
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/fb.h linux.17p18/include/linux/fb.h
--- linux.vanilla/include/linux/fb.h	Fri Apr 21 12:46:59 2000
+++ linux.17p18/include/linux/fb.h	Wed Aug  9 22:34:13 2000
@@ -74,6 +74,7 @@
 #define FB_ACCEL_SUN_CGTHREE	24	/* Sun cgthree			 */
 #define FB_ACCEL_SUN_TCX	25	/* Sun tcx			 */
 #define FB_ACCEL_MATROX_MGAG400 26	/* Matrox G400                   */
+#define FB_ACCEL_ATI_RAGE128	32	/* ATI Rage 128                  */
 
 struct fb_fix_screeninfo {
 	char id[16];			/* identification string eg "TT Builtin" */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/fs.h linux.17p18/include/linux/fs.h
--- linux.vanilla/include/linux/fs.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/fs.h	Wed Aug  9 22:33:24 2000
@@ -754,7 +754,7 @@
 
 extern void refile_buffer(struct buffer_head * buf);
 extern void set_writetime(struct buffer_head * buf, int flag);
-extern int try_to_free_buffers(struct page *);
+extern int try_to_free_buffers(struct page *, int wait);
 
 extern int nr_buffers;
 extern long buffermem;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/hd64572.h linux.17p18/include/linux/hd64572.h
--- linux.vanilla/include/linux/hd64572.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/linux/hd64572.h	Tue Aug  1 08:00:21 2000
@@ -0,0 +1,437 @@
+/*
+ * hd64572.h	Description of the Hitachi HD64572 (SCA-II), valid for 
+ * 		CPU modes 0 & 2.
+ *
+ * Author:	Ivan Passos <ivan@cyclades.com>
+ *
+ * Copyright:   (c) 2000 Cyclades Corp.
+ *
+ *	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.
+ *
+ * $Log: hd64572.h,v $
+ * Revision 1.0 2000/01/25 ivan
+ * Initial version.
+ *
+ */
+
+#ifndef _HD64572_H
+#define _HD64572_H
+
+/* Illegal Access Register */
+#define	ILAR	0x00
+
+/* Wait Controller Registers */
+#define PABR0L	0x20	/* Physical Addr Boundary Register 0 L */
+#define PABR0H	0x21	/* Physical Addr Boundary Register 0 H */
+#define PABR1L	0x22	/* Physical Addr Boundary Register 1 L */
+#define PABR1H	0x23	/* Physical Addr Boundary Register 1 H */
+#define WCRL	0x24	/* Wait Control Register L */
+#define WCRM	0x25	/* Wait Control Register M */
+#define WCRH	0x26	/* Wait Control Register H */
+
+/* Interrupt Registers */
+#define IVR	0x60	/* Interrupt Vector Register */
+#define IMVR	0x64	/* Interrupt Modified Vector Register */
+#define ITCR	0x68	/* Interrupt Control Register */
+#define ISR0	0x6c	/* Interrupt Status Register 0 */
+#define ISR1	0x70	/* Interrupt Status Register 1 */
+#define IER0	0x74	/* Interrupt Enable Register 0 */
+#define IER1	0x78	/* Interrupt Enable Register 1 */
+
+/* Register Access Macros (chan is 0 or 1 in _any_ case) */
+#define	M_REG(reg, chan)	(reg + 0x80*chan)		/* MSCI */
+#define	DRX_REG(reg, chan)	(reg + 0x40*chan)		/* DMA Rx */
+#define	DTX_REG(reg, chan)	(reg + 0x20*(2*chan + 1))	/* DMA Tx */
+#define	TRX_REG(reg, chan)	(reg + 0x20*chan)		/* Timer Rx */
+#define	TTX_REG(reg, chan)	(reg + 0x10*(2*chan + 1))	/* Timer Tx */
+#define	ST_REG(reg, chan)	(reg + 0x80*chan)		/* Status Cnt */
+#define IR0_DRX(val, chan)	((val)<<(8*(chan)))		/* Int DMA Rx */
+#define IR0_DTX(val, chan)	((val)<<(4*(2*chan + 1)))	/* Int DMA Tx */
+#define IR0_M(val, chan)	((val)<<(8*(chan)))		/* Int MSCI */
+
+/* MSCI Channel Registers */
+#define MD0	0x138	/* Mode reg 0 */
+#define MD1	0x139	/* Mode reg 1 */
+#define MD2	0x13a	/* Mode reg 2 */
+#define MD3	0x13b	/* Mode reg 3 */
+#define CTL	0x130	/* Control reg */
+#define RXS	0x13c	/* RX clock source */
+#define TXS	0x13d	/* TX clock source */
+#define EXS	0x13e	/* External clock input selection */
+#define TMCT	0x144	/* Time constant (Tx) */
+#define TMCR	0x145	/* Time constant (Rx) */
+#define CMD	0x128	/* Command reg */
+#define ST0	0x118	/* Status reg 0 */
+#define ST1	0x119	/* Status reg 1 */
+#define ST2	0x11a	/* Status reg 2 */
+#define ST3	0x11b	/* Status reg 3 */
+#define ST4	0x11c	/* Status reg 4 */
+#define FST	0x11d	/* frame Status reg  */
+#define IE0	0x120	/* Interrupt enable reg 0 */
+#define IE1	0x121	/* Interrupt enable reg 1 */
+#define IE2	0x122	/* Interrupt enable reg 2 */
+#define IE4	0x124	/* Interrupt enable reg 4 */
+#define FIE	0x125	/* Frame Interrupt enable reg  */
+#define SA0	0x140	/* Syn Address reg 0 */
+#define SA1	0x141	/* Syn Address reg 1 */
+#define IDL	0x142	/* Idle register */
+#define TRBL	0x100	/* TX/RX buffer reg L */ 
+#define TRBK	0x101	/* TX/RX buffer reg K */ 
+#define TRBJ	0x102	/* TX/RX buffer reg J */ 
+#define TRBH	0x103	/* TX/RX buffer reg H */ 
+#define TRC0	0x148	/* TX Ready control reg 0 */ 
+#define TRC1	0x149	/* TX Ready control reg 1 */ 
+#define RRC	0x14a	/* RX Ready control reg */ 
+#define CST0	0x108	/* Current Status Register 0 */ 
+#define CST1	0x109	/* Current Status Register 1 */ 
+#define CST2	0x10a	/* Current Status Register 2 */ 
+#define CST3	0x10b	/* Current Status Register 3 */ 
+#define GPO	0x131	/* General Purpose Output Pin Ctl Reg */
+#define TFS	0x14b	/* Tx Start Threshold Ctl Reg */
+#define TFN	0x143	/* Inter-transmit-frame Time Fill Ctl Reg */
+#define TBN	0x110	/* Tx Buffer Number Reg */
+#define RBN	0x111	/* Rx Buffer Number Reg */
+#define TNR0	0x150	/* Tx DMA Request Ctl Reg 0 */
+#define TNR1	0x151	/* Tx DMA Request Ctl Reg 1 */
+#define TCR	0x152	/* Tx DMA Critical Request Reg */
+#define RNR	0x154	/* Rx DMA Request Ctl Reg */
+#define RCR	0x156	/* Rx DMA Critical Request Reg */
+
+/* Timer Registers */
+#define TCNTL	0x200	/* Timer Upcounter L */
+#define TCNTH	0x201	/* Timer Upcounter H */
+#define TCONRL	0x204	/* Timer Constant Register L */
+#define TCONRH	0x205	/* Timer Constant Register H */
+#define TCSR	0x206	/* Timer Control/Status Register */
+#define TEPR	0x207	/* Timer Expand Prescale Register */
+
+/* DMA registers */
+#define PCR		0x40		/* DMA priority control reg */
+#define DRR		0x44		/* DMA reset reg */
+#define DMER		0x07		/* DMA Master Enable reg */
+#define BTCR		0x08		/* Burst Tx Ctl Reg */
+#define BOLR		0x0c		/* Back-off Length Reg */
+#define DSR_RX(chan)	(0x48 + 2*chan)	/* DMA Status Reg (Rx) */
+#define DSR_TX(chan)	(0x49 + 2*chan)	/* DMA Status Reg (Tx) */
+#define DIR_RX(chan)	(0x4c + 2*chan)	/* DMA Interrupt Enable Reg (Rx) */
+#define DIR_TX(chan)	(0x4d + 2*chan)	/* DMA Interrupt Enable Reg (Tx) */
+#define FCT_RX(chan)	(0x50 + 2*chan)	/* Frame End Interrupt Counter (Rx) */
+#define FCT_TX(chan)	(0x51 + 2*chan)	/* Frame End Interrupt Counter (Tx) */
+#define DMR_RX(chan)	(0x54 + 2*chan)	/* DMA Mode Reg (Rx) */
+#define DMR_TX(chan)	(0x55 + 2*chan)	/* DMA Mode Reg (Tx) */
+#define DCR_RX(chan)	(0x58 + 2*chan)	/* DMA Command Reg (Rx) */
+#define DCR_TX(chan)	(0x59 + 2*chan)	/* DMA Command Reg (Tx) */
+
+/* DMA Channel Registers */
+#define DARL	0x80	/* Dest Addr Register L (single-block, RX only) */
+#define DARH	0x81	/* Dest Addr Register H (single-block, RX only) */
+#define DARB	0x82	/* Dest Addr Register B (single-block, RX only) */
+#define DARBH	0x83	/* Dest Addr Register BH (single-block, RX only) */
+#define SARL	0x80	/* Source Addr Register L (single-block, TX only) */
+#define SARH	0x81	/* Source Addr Register H (single-block, TX only) */
+#define SARB	0x82	/* Source Addr Register B (single-block, TX only) */
+#define DARBH	0x83	/* Source Addr Register BH (single-block, TX only) */
+#define BARL	0x80	/* Buffer Addr Register L (chained-block) */
+#define BARH	0x81	/* Buffer Addr Register H (chained-block) */
+#define BARB	0x82	/* Buffer Addr Register B (chained-block) */
+#define BARBH	0x83	/* Buffer Addr Register BH (chained-block) */
+#define CDAL	0x84	/* Current Descriptor Addr Register L */
+#define CDAH	0x85	/* Current Descriptor Addr Register H */
+#define CDAB	0x86	/* Current Descriptor Addr Register B */
+#define CDABH	0x87	/* Current Descriptor Addr Register BH */
+#define EDAL	0x88	/* Error Descriptor Addr Register L */
+#define EDAH	0x89	/* Error Descriptor Addr Register H */
+#define EDAB	0x8a	/* Error Descriptor Addr Register B */
+#define EDABH	0x8b	/* Error Descriptor Addr Register BH */
+#define BFLL	0x90	/* RX Buffer Length L (only RX) */
+#define BFLH	0x91	/* RX Buffer Length H (only RX) */
+#define BCRL	0x8c	/* Byte Count Register L */
+#define BCRH	0x8d	/* Byte Count Register H */
+
+/* Block Descriptor Structure */
+typedef struct {
+	unsigned long	next;		/* pointer to next block descriptor */
+	unsigned long	ptbuf;		/* buffer pointer */
+	unsigned short	len;		/* data length */
+	unsigned char	status;		/* status */
+	unsigned char	filler[5];	/* alignment filler (16 bytes) */ 
+} pcsca_bd_t;
+
+/* 
+	Descriptor Status definitions:
+
+	Bit	Transmission	Reception
+
+	7	EOM		EOM
+	6	-		Short Frame
+	5	-		Abort
+	4	-		Residual bit
+	3	Underrun	Overrun	
+	2	-		CRC
+	1	Ownership	Ownership
+	0	EOT		-
+*/
+#define DST_EOT		0x01	/* End of transmit command */
+#define DST_OSB		0x02	/* Ownership bit */
+#define DST_CRC		0x04	/* CRC Error */
+#define DST_OVR		0x08	/* Overrun */
+#define DST_UDR		0x08	/* Underrun */
+#define DST_RBIT	0x10	/* Residual bit */
+#define DST_ABT		0x20	/* Abort */
+#define DST_SHRT	0x40	/* Short Frame  */
+#define DST_EOM		0x80	/* End of Message  */
+
+/* Status Counter Registers */
+#define CMCR	0x158	/* Counter Master Ctl Reg */
+#define TECNTL	0x160	/* Tx EOM Counter L */
+#define TECNTM	0x161	/* Tx EOM Counter M */
+#define TECNTH	0x162	/* Tx EOM Counter H */
+#define TECCR	0x163	/* Tx EOM Counter Ctl Reg */
+#define URCNTL	0x164	/* Underrun Counter L */
+#define URCNTH	0x165	/* Underrun Counter H */
+#define URCCR	0x167	/* Underrun Counter Ctl Reg */
+#define RECNTL	0x168	/* Rx EOM Counter L */
+#define RECNTM	0x169	/* Rx EOM Counter M */
+#define RECNTH	0x16a	/* Rx EOM Counter H */
+#define RECCR	0x16b	/* Rx EOM Counter Ctl Reg */
+#define ORCNTL	0x16c	/* Overrun Counter L */
+#define ORCNTH	0x16d	/* Overrun Counter H */
+#define ORCCR	0x16f	/* Overrun Counter Ctl Reg */
+#define CECNTL	0x170	/* CRC Counter L */
+#define CECNTH	0x171	/* CRC Counter H */
+#define CECCR	0x173	/* CRC Counter Ctl Reg */
+#define ABCNTL	0x174	/* Abort frame Counter L */
+#define ABCNTH	0x175	/* Abort frame Counter H */
+#define ABCCR	0x177	/* Abort frame Counter Ctl Reg */
+#define SHCNTL	0x178	/* Short frame Counter L */
+#define SHCNTH	0x179	/* Short frame Counter H */
+#define SHCCR	0x17b	/* Short frame Counter Ctl Reg */
+#define RSCNTL	0x17c	/* Residual bit Counter L */
+#define RSCNTH	0x17d	/* Residual bit Counter H */
+#define RSCCR	0x17f	/* Residual bit Counter Ctl Reg */
+
+/* Register Programming Constants */
+
+#define IR0_DMIC	0x00000001
+#define IR0_DMIB	0x00000002
+#define IR0_DMIA	0x00000004
+#define IR0_EFT		0x00000008
+#define IR0_DMAREQ	0x00010000
+#define IR0_TXINT	0x00020000
+#define IR0_RXINTB	0x00040000
+#define IR0_RXINTA	0x00080000
+#define IR0_TXRDY	0x00100000
+#define IR0_RXRDY	0x00200000
+
+#define MD0_CRC16_0	0x00
+#define MD0_CRC16_1	0x01
+#define MD0_CRC32	0x02
+#define MD0_CRC_CCITT	0x03
+#define MD0_CRCC0	0x04
+#define MD0_CRCC1	0x08
+#define MD0_AUTO_ENA	0x10
+#define MD0_ASYNC	0x00
+#define MD0_BY_MSYNC	0x20
+#define MD0_BY_BISYNC	0x40
+#define MD0_BY_EXT	0x60
+#define MD0_BIT_SYNC	0x80
+#define MD0_TRANSP	0xc0
+
+#define MD1_NOADDR	0x00
+#define MD1_SADDR1	0x40
+#define MD1_SADDR2	0x80
+#define MD1_DADDR	0xc0
+
+#define MD2_F_DUPLEX	0x00
+#define MD2_AUTO_ECHO	0x01
+#define MD2_LOOP_HI_Z	0x02
+#define MD2_LOOP_MIR	0x03
+#define MD2_ADPLL_X8	0x00
+#define MD2_ADPLL_X16	0x08
+#define MD2_ADPLL_X32	0x10
+#define MD2_NRZ		0x00
+#define MD2_NRZI	0x20
+#define MD2_NRZ_IEEE	0x40
+#define MD2_MANCH	0x00
+#define MD2_FM1		0x20
+#define MD2_FM0		0x40
+#define MD2_FM		0x80
+
+#define CTL_RTS		0x01
+#define CTL_DTR		0x02
+#define CTL_SYN		0x04
+#define CTL_IDLC	0x10
+#define CTL_UDRNC	0x20
+#define CTL_URSKP	0x40
+#define CTL_URCT	0x80
+
+#define	RXS_BR0		0x01
+#define	RXS_BR1		0x02
+#define	RXS_BR2		0x04
+#define	RXS_BR3		0x08
+#define	RXS_ECLK	0x00
+#define	RXS_ECLK_NS	0x20
+#define	RXS_IBRG	0x40
+#define	RXS_PLL1	0x50
+#define	RXS_PLL2	0x60
+#define	RXS_PLL3	0x70
+#define	RXS_DRTXC	0x80
+
+#define	TXS_BR0		0x01
+#define	TXS_BR1		0x02
+#define	TXS_BR2		0x04
+#define	TXS_BR3		0x08
+#define	TXS_ECLK	0x00
+#define	TXS_IBRG	0x40
+#define	TXS_RCLK	0x60
+#define	TXS_DTRXC	0x80
+
+#define	EXS_RES0	0x01
+#define	EXS_RES1	0x02
+#define	EXS_RES2	0x04
+#define	EXS_TES0	0x10
+#define	EXS_TES1	0x20
+#define	EXS_TES2	0x40
+
+#define CMD_RX_RST	0x11
+#define CMD_RX_ENA	0x12
+#define CMD_RX_DIS	0x13
+#define CMD_RX_CRC_INIT	0x14
+#define CMD_RX_MSG_REJ	0x15
+#define CMD_RX_MP_SRCH	0x16
+#define CMD_RX_CRC_EXC	0x17
+#define CMD_RX_CRC_FRC	0x18
+#define CMD_TX_RST	0x01
+#define CMD_TX_ENA	0x02
+#define CMD_TX_DISA	0x03
+#define CMD_TX_CRC_INIT	0x04
+#define CMD_TX_CRC_EXC	0x05
+#define CMD_TX_EOM	0x06
+#define CMD_TX_ABORT	0x07
+#define CMD_TX_MP_ON	0x08
+#define CMD_TX_BUF_CLR	0x09
+#define CMD_TX_DISB	0x0b
+#define CMD_CH_RST	0x21
+#define CMD_SRCH_MODE	0x31
+#define CMD_NOP		0x00
+
+#define ST0_RXRDY	0x01
+#define ST0_TXRDY	0x02
+#define ST0_RXINTB	0x20
+#define ST0_RXINTA	0x40
+#define ST0_TXINT	0x80
+
+#define ST1_IDLE	0x01
+#define ST1_ABORT	0x02
+#define ST1_CDCD	0x04
+#define ST1_CCTS	0x08
+#define ST1_SYN_FLAG	0x10
+#define ST1_CLMD	0x20
+#define ST1_TXIDLE	0x40
+#define ST1_UDRN	0x80
+
+#define ST2_CRCE	0x04
+#define ST2_ONRN	0x08
+#define ST2_RBIT	0x10
+#define ST2_ABORT	0x20
+#define ST2_SHORT	0x40
+#define ST2_EOM		0x80
+
+#define ST3_RX_ENA	0x01
+#define ST3_TX_ENA	0x02
+#define ST3_DCD		0x04
+#define ST3_CTS		0x08
+#define ST3_SRCH_MODE	0x10
+#define ST3_SLOOP	0x20
+#define ST3_GPI		0x80
+
+#define ST4_RDNR	0x01
+#define ST4_RDCR	0x02
+#define ST4_TDNR	0x04
+#define ST4_TDCR	0x08
+#define ST4_OCLM	0x20
+#define ST4_CFT		0x40
+#define ST4_CGPI	0x80
+
+#define FST_CRCEF	0x04
+#define FST_OVRNF	0x08
+#define FST_RBIF	0x10
+#define FST_ABTF	0x20
+#define FST_SHRTF	0x40
+#define FST_EOMF	0x80
+
+#define IE0_RXRDY	0x01
+#define IE0_TXRDY	0x02
+#define IE0_RXINTB	0x20
+#define IE0_RXINTA	0x40
+#define IE0_TXINT	0x80
+
+#define IE1_IDLD	0x01
+#define IE1_ABTD	0x02
+#define IE1_CDCD	0x04
+#define IE1_CCTS	0x08
+#define IE1_SYNCD	0x10
+#define IE1_CLMD	0x20
+#define IE1_IDL		0x40
+#define IE1_UDRN	0x80
+
+#define IE2_CRCE	0x04
+#define IE2_OVRN	0x08
+#define IE2_RBIT	0x10
+#define IE2_ABT		0x20
+#define IE2_SHRT	0x40
+#define IE2_EOM		0x80
+
+#define IE4_RDNR	0x01
+#define IE4_RDCR	0x02
+#define IE4_TDNR	0x04
+#define IE4_TDCR	0x08
+#define IE4_OCLM	0x20
+#define IE4_CFT		0x40
+#define IE4_CGPI	0x80
+
+#define FIE_CRCEF	0x04
+#define FIE_OVRNF	0x08
+#define FIE_RBIF	0x10
+#define FIE_ABTF	0x20
+#define FIE_SHRTF	0x40
+#define FIE_EOMF	0x80
+
+#define DSR_DWE		0x01
+#define DSR_DE		0x02
+#define DSR_REF		0x04
+#define DSR_UDRF	0x04
+#define DSR_COA		0x08
+#define DSR_COF		0x10
+#define DSR_BOF		0x20
+#define DSR_EOM		0x40
+#define DSR_EOT		0x80
+
+#define DIR_REF		0x04
+#define DIR_UDRF	0x04
+#define DIR_COA		0x08
+#define DIR_COF		0x10
+#define DIR_BOF		0x20
+#define DIR_EOM		0x40
+#define DIR_EOT		0x80
+
+#define DMR_CNTE	0x02
+#define DMR_NF		0x04
+#define DMR_SEOME	0x08
+#define DMR_TMOD	0x10
+
+#define DCR_SW_ABT	0x01
+#define DCR_FCT_CLR	0x02
+
+#define PCR_PR0		0x01
+#define PCR_PR1		0x02
+#define PCR_PR2		0x04
+#define PCR_CCC		0x08
+#define PCR_BRC		0x10
+#define PCR_OSB		0x40
+#define PCR_BURST	0x80
+
+#endif /* (_HD64572_H) */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/hdlc.h linux.17p18/include/linux/hdlc.h
--- linux.vanilla/include/linux/hdlc.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/hdlc.h	Wed Aug  9 22:36:05 2000
@@ -38,6 +38,8 @@
 #define LINE_X21	3
 #define LINE_LOOPBACK	4	/* On-card loopback */
 #define LINE_NOLOOPBACK	5
+#define LINE_T1		6
+#define LINE_E1		7
 #define LINE_MIN_CLOCK 75	/* This & higher values are real clock rates */
 
 
@@ -126,6 +128,8 @@
 	u16 rel;		/* reliability */
 	u32 time;
 }__attribute__ ((packed)) cisco_packet;
+#define	CISCO_PACKET_LEN	18
+#define	CISCO_BIG_PACKET_LEN	20
 
 
 
@@ -153,8 +157,8 @@
 	u8 N391cnt;
 
 	u8 state;		/* ! */
-	u8 txseq;		/* ! TX sequence number */
-	u8 rxseq;		/* ! RX sequence number */
+	u32 txseq;		/* ! TX sequence number - Cisco uses 4 bytes */
+	u32 rxseq;		/* ! RX sequence number */
 }fr_lmi;			/* ! means used in Cisco HDLC as well */
 
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/i2o.h linux.17p18/include/linux/i2o.h
--- linux.vanilla/include/linux/i2o.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/i2o.h	Tue Aug  1 18:33:58 2000
@@ -91,6 +91,7 @@
 
 	struct i2o_controller *controller;	/* Controlling IOP */
 	struct i2o_device *next;	/* Chain */
+	struct i2o_device *prev;
 	char dev_name[8];		/* linux /dev name if available */
 };
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/ixjuser.h linux.17p18/include/linux/ixjuser.h
--- linux.vanilla/include/linux/ixjuser.h	Fri Apr 21 23:23:32 2000
+++ linux.17p18/include/linux/ixjuser.h	Tue Aug  1 08:00:21 2000
@@ -1,7 +1,8 @@
-/*
+/******************************************************************************
+ *
  *    ixjuser.h
  *
- *    User-space include file for the Internet PhoneJACK and
+ *    Device Driver for the Internet PhoneJACK and
  *    Internet LineJACK Telephony Cards.
  *
  *    (c) Copyright 1999 Quicknet Technologies, Inc.
@@ -22,31 +23,48 @@
  * at our website:    http://www.quicknet.net
  *
  * Fixes:
- */
+ *
+ * IN NO EVENT SHALL QUICKNET TECHNOLOGIES, INC. BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT
+ * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF QUICKNET
+ * TECHNOLOGIES, INC.HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * QUICKNET TECHNOLOGIES, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND QUICKNET TECHNOLOGIES, INC. HAS NO OBLIGATION 
+ * TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ *****************************************************************************/
 
-static char ixjuser_h_rcsid[] = "$Id: ixjuser.h,v 3.4 1999/12/16 22:18:36 root Exp root $";
+static char ixjuser_h_rcsid[] = "$Id: ixjuser.h,v 3.11 2000/03/30 22:06:48 eokerson Exp $";
 
-#include <linux/telephony.h>
+#include "telephony.h"
 
-/***************************************************************************
 
-  If you use the IXJCTL_TESTRAM command, the card must be power
-  cycled to reset the SRAM values before futher use.
+/******************************************************************************
+*
+* IOCTL's used for the Quicknet Cards
+*
+* If you use the IXJCTL_TESTRAM command, the card must be power cycled to
+* reset the SRAM values before futher use.
+*
+******************************************************************************/
 
-***************************************************************************/
 #define IXJCTL_DSP_RESET 		_IO  ('q', 0xC0)
 
-#define IXJCTL_RING         PHONE_RING
-#define IXJCTL_HOOKSTATE    PHONE_HOOKSTATE
+#define IXJCTL_RING                     PHONE_RING
+#define IXJCTL_HOOKSTATE                PHONE_HOOKSTATE
 #define IXJCTL_MAXRINGS			PHONE_MAXRINGS
-#define IXJCTL_RING_CADENCE	PHONE_RING_CADENCE
+#define IXJCTL_RING_CADENCE		PHONE_RING_CADENCE
 #define IXJCTL_RING_START		PHONE_RING_START
 #define IXJCTL_RING_STOP		PHONE_RING_STOP
 
 #define IXJCTL_CARDTYPE			_IOR ('q', 0xC1, int)
-#define IXJCTL_SERIAL			  _IOR ('q', 0xC2, int)
-#define IXJCTL_DSP_TYPE     _IOR ('q', 0xC3, int)
-#define IXJCTL_DSP_VERSION  _IOR ('q', 0xC4, int)
+#define IXJCTL_SERIAL			_IOR ('q', 0xC2, int)
+#define IXJCTL_DSP_TYPE                 _IOR ('q', 0xC3, int)
+#define IXJCTL_DSP_VERSION              _IOR ('q', 0xC4, int)
+#define IXJCTL_VERSION              	_IOR ('q', 0xDA, char *)
 #define IXJCTL_DSP_IDLE			_IO  ('q', 0xC5)
 #define IXJCTL_TESTRAM			_IO  ('q', 0xC6)
 
@@ -104,8 +122,22 @@
 	char enable;
 } IXJ_FILTER;
 
+typedef struct {
+	char enable;
+	char en_filter;
+	unsigned int filter;
+	unsigned int on1;
+	unsigned int off1;
+	unsigned int on2;
+	unsigned int off2;
+	unsigned int on3;
+	unsigned int off3;
+} IXJ_FILTER_CADENCE;
+
 #define IXJCTL_SET_FILTER		_IOW ('q', 0xC7, IXJ_FILTER *)
 #define IXJCTL_GET_FILTER_HIST		_IOW ('q', 0xC8, int)
+#define IXJCTL_FILTER_CADENCE		_IOW ('q', 0xD6, IXJ_FILTER_CADENCE *)
+#define IXJCTL_PLAY_CID			_IO  ('q', 0xD7)
 /******************************************************************************
 *
 * This IOCTL allows you to reassign values in the tone index table.  The
@@ -222,7 +254,9 @@
 	hz1800 = 0x1405,
 	hz1860 = 0xe0b,
 	hz2100 = 0xf5f6,
-	hz2450 = 0xd3b3
+	hz2130 = 0xf2f5,
+	hz2450 = 0xd3b3,
+	hz2750 = 0xb8e4
 } IXJ_FREQ;
 
 typedef enum {
@@ -344,6 +378,7 @@
 #define AEC_LOW   1
 #define AEC_MED   2
 #define AEC_HIGH  3
+#define AEC_AUTO  4
 /******************************************************************************
 *
 * Call Progress Tones, DTMF, etc.
@@ -533,16 +568,16 @@
 
 /******************************************************************************
 * 
-* The DAA Analog GAIN sets 2 parameters at one time, the receive gain (AGRR), 
+* The DAA Analog GAIN sets 2 parameters at one time, the recieve gain (AGRR), 
 * and the transmit gain (AGX).  OR together the components and pass them
 * as the parameter to IXJCTL_DAA_AGAIN.  The default setting is both at 0dB.
 * 
 ******************************************************************************/
 #define IXJCTL_DAA_AGAIN		_IOW ('q', 0xD2, int)
 
-#define AGRR00DB	0x00	// Analog gain in receive direction 0dB
-#define AGRR3_5DB	0x10	// Analog gain in receive direction 3.5dB
-#define AGRR06DB	0x30	// Analog gain in receive direction 6dB
+#define AGRR00DB	0x00	// Analog gain in recieve direction 0dB
+#define AGRR3_5DB	0x10	// Analog gain in recieve direction 3.5dB
+#define AGRR06DB	0x30	// Analog gain in recieve direction 6dB
 
 #define AGX00DB		0x00	// Analog gain in transmit direction 0dB
 #define AGX_6DB		0x04	// Analog gain in transmit direction -6dB
@@ -551,18 +586,9 @@
 
 #define IXJCTL_PSTN_LINETEST		_IO  ('q', 0xD3)
 
-typedef struct {
-	char month[3];
-	char day[3];
-	char hour[3];
-	char min[3];
-	int numlen;
-	char number[11];
-	int namelen;
-	char name[80];
-} IXJ_CID;
-
-#define IXJCTL_CID			_IOR ('q', 0xD4, IXJ_CID *)
+#define IXJCTL_CID			_IOR ('q', 0xD4, PHONE_CID *)
+#define IXJCTL_VMWI			_IOR ('q', 0xD8, int)
+#define IXJCTL_CIDCW			_IOW ('q', 0xD9, PHONE_CID *)
 /******************************************************************************
 * 
 * The wink duration is tunable with this ioctl.  The default wink duration  
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/kmod.h linux.17p18/include/linux/kmod.h
--- linux.vanilla/include/linux/kmod.h	Fri Apr 21 12:46:59 2000
+++ linux.17p18/include/linux/kmod.h	Tue Aug  1 08:00:21 2000
@@ -6,7 +6,14 @@
 
 #ifdef CONFIG_KMOD
 extern int request_module(const char * name);
+extern int exec_usermodehelper(char *program_path, char *argv[], char *envp[]);
 #else
+#include <linux/errno.h>
+
 #define request_module(x) do {} while(0)
+static inline int exec_usermodehelper(char *program_path, char *argv[], char *envp[])
+{
+        return -EACCES;
+}
 #endif
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/nls.h linux.17p18/include/linux/nls.h
--- linux.vanilla/include/linux/nls.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/nls.h	Tue Aug  1 08:00:21 2000
@@ -54,6 +54,7 @@
 extern int init_nls_cp866(void);
 extern int init_nls_cp869(void);
 extern int init_nls_cp874(void);
+extern int init_nls_euc_jp(void);
 extern int init_nls_cp932(void);
 extern int init_nls_cp936(void);
 extern int init_nls_cp949(void);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/ntfs_fs_sb.h linux.17p18/include/linux/ntfs_fs_sb.h
--- linux.vanilla/include/linux/ntfs_fs_sb.h	Fri Apr 21 12:47:00 2000
+++ linux.17p18/include/linux/ntfs_fs_sb.h	Tue Aug  1 08:00:21 2000
@@ -15,7 +15,10 @@
 	ntfs_u32 at_standard_information;
 	ntfs_u32 at_attribute_list;
 	ntfs_u32 at_file_name;
+	ntfs_u32 at_volume_version;
 	ntfs_u32 at_security_descriptor;
+	ntfs_u32 at_volume_name;
+	ntfs_u32 at_volume_information;
 	ntfs_u32 at_data;
 	ntfs_u32 at_index_root;
 	ntfs_u32 at_index_allocation;
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/openpic.h linux.17p18/include/linux/openpic.h
--- linux.vanilla/include/linux/openpic.h	Fri Apr 21 12:47:00 2000
+++ linux.17p18/include/linux/openpic.h	Tue Aug  1 08:00:21 2000
@@ -262,8 +262,12 @@
      *  Interrupt Source Registers
      */
 
-#define OPENPIC_SENSE_POLARITY			0x00800000	/* Undoc'd */
+#define OPENPIC_POLARITY_POSITIVE		0x00800000
+#define OPENPIC_POLARITY_NEGATIVE		0x00000000
+#define OPENPIC_POLARITY_MASK			0x00800000
 #define OPENPIC_SENSE_LEVEL			0x00400000
+#define OPENPIC_SENSE_EDGE			0x00000000
+#define OPENPIC_SENSE_MASK			0x00400000
 
 
     /*
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/pc300.h linux.17p18/include/linux/pc300.h
--- linux.vanilla/include/linux/pc300.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/linux/pc300.h	Wed Aug  9 22:45:24 2000
@@ -0,0 +1,382 @@
+/*
+ * pc300.h	Cyclades-PC300(tm) Kernel API Definitions.
+ *
+ * Author:	Ivan Passos <ivan@cyclades.com>
+ *
+ * Copyright:	(c) 1999-2000 Cyclades Corp.
+ *
+ *	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.
+ *
+ * $Log: pc300.h,v $
+ * Revision 2.2 2000/06/23 ivan
+ * Inclusion of 'loopback' field on structure 'pc300chconf', to allow 
+ * loopback mode operation.
+ * 
+ * Revision 2.1 2000/06/09 ivan
+ * Changes to use the new generic HDLC layer in the driver.
+ *
+ * Revision 2.0 2000/03/27 ivan
+ * Added support for the PC300/TE cards.
+ *
+ * Revision 1.1 2000/01/31 ivan
+ * Replaced 'pc300[drv|sca].h' former PC300 driver include files.
+ *
+ * Revision 1.0 1999/12/16 ivan
+ * First official release.
+ * Inclusion of 'nchan' field on structure 'pc300hw', to allow variable 
+ * number of ports per card.
+ * Inclusion of 'if_ptr' field on structure 'pc300dev'.
+ *
+ * Revision 0.6 1999/11/17 ivan
+ * Changed X.25-specific function names to comply with adopted convention.
+ *
+ * Revision 0.5 1999/11/16 Daniela Squassoni
+ * X.25 support.
+ *
+ * Revision 0.4 1999/11/15 ivan
+ * Inclusion of 'clock' field on structure 'pc300hw'.
+ *
+ * Revision 0.3 1999/11/10 ivan
+ * IOCTL name changing.
+ * Inclusion of driver function prototypes.
+ *
+ * Revision 0.2 1999/11/03 ivan
+ * Inclusion of 'tx_skb' and union 'ifu' on structure 'pc300dev'.
+ *
+ * Revision 0.1 1999/01/15 ivan
+ * Initial version.
+ *
+ */
+
+#ifndef	_PC300_H
+#define	_PC300_H
+
+#ifndef __HDLC_H
+#include <linux/hdlc.h>
+#endif
+#ifndef _HD64572_H
+#include <linux/hd64572.h>
+#endif
+#ifndef _FALC_LH_H
+#include <linux/falc-lh.h>
+#endif
+
+#ifndef CY_TYPES
+#define CY_TYPES
+#if defined(__alpha__)
+typedef	unsigned long	ucdouble;	/* 64 bits, unsigned */
+typedef	unsigned int	uclong;		/* 32 bits, unsigned */
+#else
+typedef	unsigned long	uclong;		/* 32 bits, unsigned */
+#endif
+typedef	unsigned short	ucshort;	/* 16 bits, unsigned */
+typedef	unsigned char	ucchar;		/* 8 bits, unsigned */
+#endif /* CY_TYPES */
+
+#define	PC300_DEVNAME	"hdlc"	/* Dev. name base (for hdlc0, hdlc1, etc.) */
+#define	PC300_MAXINDEX	100	/* Max dev. name index (the '0' in hdlc0) */
+
+#define	PC300_MAXCARDS	4	/* Max number of cards per system */
+#define	PC300_MAXCHAN	2	/* Number of channels per card */
+
+#define	PC300_PLX_WIN	0x80    /* PLX control window size (128b) */
+#define	PC300_RAMSIZE	0x80000 /* RAM window size (512Kb) */
+#define	PC300_SCASIZE	0x400   /* SCA window size (1Kb) */
+#define	PC300_FALCSIZE	0x400	/* FALC window size (1Kb) */
+
+#define PC300_OSC_CLOCK	24576000
+#define PC300_PCI_CLOCK	33000000
+
+#define BD_DEF_LEN	0x0800	/* DMA buffer length (2KB) */
+#define DMA_TX_MEMSZ	0x8000	/* Total DMA Tx memory size (32KB/ch) */
+#define DMA_RX_MEMSZ	0x10000	/* Total DMA Rx memory size (64KB/ch) */
+
+#define N_DMA_TX_BUF	(DMA_TX_MEMSZ / BD_DEF_LEN)	/* DMA Tx buffers */
+#define N_DMA_RX_BUF	(DMA_RX_MEMSZ / BD_DEF_LEN)	/* DMA Rx buffers */
+
+/* DMA Buffer Offsets */
+#define DMA_TX_BASE	((N_DMA_TX_BUF + N_DMA_RX_BUF) *	\
+			 PC300_MAXCHAN * sizeof(pcsca_bd_t))
+#define DMA_RX_BASE	(DMA_TX_BASE + PC300_MAXCHAN*DMA_TX_MEMSZ)
+
+/* DMA Descriptor Offsets */
+#define DMA_TX_BD_BASE	0x0000
+#define DMA_RX_BD_BASE	(DMA_TX_BD_BASE + ((PC300_MAXCHAN*DMA_TX_MEMSZ / \
+				BD_DEF_LEN) * sizeof(pcsca_bd_t)))
+
+/* DMA Descriptor Macros */
+#define TX_BD_ADDR(chan, n)	(DMA_TX_BD_BASE + \
+				 ((N_DMA_TX_BUF*chan) + n) * sizeof(pcsca_bd_t))
+#define RX_BD_ADDR(chan, n)	(DMA_RX_BD_BASE + \
+				 ((N_DMA_RX_BUF*chan) + n) * sizeof(pcsca_bd_t))
+
+/* Macro to access the FALC registers (TE only) */
+#define F_REG(reg, chan)	(0x200*(chan) + ((reg)<<2))
+
+/***************************************
+ * Memory access functions/macros      *
+ * (required to support Alpha systems) *
+ ***************************************/
+#ifdef __KERNEL__
+#define cpc_writeb(port,val)	{writeb((ucchar)(val),(ulong)(port)); mb();}
+#define cpc_writew(port,val)	{writew((ushort)(val),(ulong)(port)); mb();}
+#define cpc_writel(port,val)	{writel((uclong)(val),(ulong)(port)); mb();}
+
+#define cpc_readb(port)		readb(port)
+#define cpc_readw(port)		readw(port)
+#define cpc_readl(port)		readl(port)
+
+#else /* __KERNEL__ */
+#define cpc_writeb(port,val)	(*(volatile ucchar *)(port) = (ucchar)(val))
+#define cpc_writew(port,val)	(*(volatile ucshort *)(port) = (ucshort)(val))
+#define cpc_writel(port,val)	(*(volatile uclong *)(port) = (uclong)(val))
+
+#define cpc_readb(port)		(*(volatile ucchar *)(port))
+#define cpc_readw(port)		(*(volatile ucshort *)(port))
+#define cpc_readl(port)		(*(volatile uclong *)(port))
+
+#endif /* __KERNEL__ */
+
+/****** Data Structures *****************************************************/
+
+/*
+ *      RUNTIME_9050 - PLX PCI9050-1 local configuration and shared runtime
+ *      registers. This structure can be used to access the 9050 registers
+ *      (memory mapped).
+ */
+struct RUNTIME_9050 {
+	uclong	loc_addr_range[4];	/* 00-0Ch : Local Address Ranges */
+	uclong	loc_rom_range;		/* 10h : Local ROM Range */
+	uclong	loc_addr_base[4];	/* 14-20h : Local Address Base Addrs */
+	uclong	loc_rom_base;		/* 24h : Local ROM Base */
+	uclong	loc_bus_descr[4];	/* 28-34h : Local Bus Descriptors */
+	uclong	rom_bus_descr;		/* 38h : ROM Bus Descriptor */
+	uclong	cs_base[4];		/* 3C-48h : Chip Select Base Addrs */
+	uclong	intr_ctrl_stat;		/* 4Ch : Interrupt Control/Status */
+	uclong	init_ctrl;		/* 50h : EEPROM ctrl, Init Ctrl, etc */
+};
+
+#define PLX_9050_LINT1_ENABLE	0x01
+#define PLX_9050_LINT1_POL	0x02
+#define PLX_9050_LINT1_STATUS	0x04
+#define PLX_9050_LINT2_ENABLE	0x08
+#define PLX_9050_LINT2_POL	0x10
+#define PLX_9050_LINT2_STATUS	0x20
+#define PLX_9050_INTR_ENABLE	0x40
+#define PLX_9050_SW_INTR	0x80
+
+/* Masks to access the init_ctrl PLX register */
+#define	PC300_CLKSEL_MASK		(0x00000004UL)
+#define	PC300_CHMEDIA_MASK(chan)	(0x00000020UL<<(chan*3))
+#define	PC300_CTYPE_MASK		(0x00000800UL)
+
+/* CPLD Registers (base addr = falcbase, TE only) */
+#define CPLD_REG1	0x140	/* Chip resets, DCD/CTS status */
+#define CPLD_REG2	0x144	/* Clock enable , LED control */
+
+/* CPLD Register bit description: for the FALC bits, they should always be 
+   set based on the channel (use (bit<<(2*ch)) to access the correct bit for 
+   that channel) */
+#define CPLD_REG1_FALC_RESET	0x01
+#define CPLD_REG1_SCA_RESET	0x02
+#define CPLD_REG1_GLOBAL_CLK	0x08
+#define CPLD_REG1_FALC_DCD	0x10
+#define CPLD_REG1_FALC_CTS	0x20
+
+#define CPLD_REG2_FALC_TX_CLK	0x01
+#define CPLD_REG2_FALC_RX_CLK	0x02
+#define CPLD_REG2_FALC_LED1	0x10
+#define CPLD_REG2_FALC_LED2	0x20
+
+/* Structure with FALC-related fields (TE only) */
+#define PC300_FALC_MAXLOOP	0x0000ffff	/* for falc_issue_cmd() */
+
+typedef struct falc {
+	ucchar sync;		/* If true FALC is synchronized */
+	ucchar active;		/* if TRUE then already active */
+	ucchar loop_active;	/* if TRUE a line loopback UP was received */
+	ucchar loop_gen;	/* if TRUE a line loopback UP was issued */
+
+	ucchar num_channels;
+	ucchar offset;		/* 1 for T1, 0 for E1 */
+	ucchar full_bandwidth;
+
+	ucchar xmb_cause;
+	ucchar multiframe_mode;
+
+	/* Statistics */
+	ucshort pden;	/* Pulse Density violation count */
+	ucshort los;	/* Loss of Signal count */
+	ucshort losr;	/* Loss of Signal recovery count */
+	ucshort lfa;	/* Loss of frame alignment count */
+	ucshort farec;	/* Frame Alignment Recovery count */
+	ucshort lmfa;	/* Loss of multiframe alignment count */
+	ucshort ais;	/* Remote Alarm indication Signal count */
+	ucshort sec;	/* One-second timer */
+	ucshort es;	/* Errored second */
+	ucshort rai;	/* remote alarm received */
+	ucshort bec;
+	ucshort fec;
+	ucshort cvc;
+	ucshort cec;
+	ucshort ebc;
+
+	/* Status */
+	ucchar red_alarm;
+	ucchar blue_alarm;
+	ucchar loss_fa;
+	ucchar yellow_alarm;
+	ucchar loss_mfa;
+	ucchar prbs;
+} falc_t;
+
+typedef struct pc300dev {
+	void *if_ptr;	/* General purpose pointer */
+	struct pc300ch *chan;
+#ifdef __KERNEL__
+	char name[16];
+	void *private;
+	hdlc_device *hdlc;
+	struct net_device_stats stats;
+	struct sk_buff *tx_skb;
+#endif /* __KERNEL__ */
+}pc300dev_t;
+
+typedef struct pc300hw {
+	int type;		/* RSV, X21, etc. */
+	int nchan;		/* number of channels */
+	int irq;		/* interrupt request level */
+	uclong clock;		/* Board clock */
+	uclong plxphys;		/* PLX registers MMIO base (physical) */
+	uclong plxbase;		/* PLX registers MMIO base (virtual) */
+	uclong plxsize;		/* PLX registers MMIO size */
+	uclong scaphys;		/* SCA registers MMIO base (physical) */
+	uclong scabase;		/* SCA registers MMIO base (virtual) */
+	uclong scasize;		/* SCA registers MMIO size */
+	uclong ramphys;		/* On-board RAM MMIO base (physical) */
+	uclong rambase;		/* On-board RAM MMIO base (virtual) */
+	uclong ramsize;		/* On-board RAM MMIO size */
+	uclong falcphys;	/* FALC registers MMIO base (physical) */
+	uclong falcbase;	/* FALC registers MMIO base (virtual) */
+	uclong falcsize;	/* FALC registers MMIO size */
+} pc300hw_t;
+
+typedef struct pc300chconf {
+	ucchar media;		/* HW media (RS232, V.35, etc.) */
+	uclong proto;		/* Protocol (PPP, X.25, etc.) */
+	uclong clkrate;		/* Clock rate (in bps, 0 = ext. clock) */
+	ucchar loopback;	/* Loopback mode */
+
+	/* TE-specific parameters */
+	ucchar lcode;		/* Line Code (AMI, B8ZS, etc.) */
+	ucchar fr_mode;		/* Frame Mode (ESF, D4, etc.) */
+	ucchar lbo;		/* Line Build Out */
+	ucchar rx_sens;		/* Rx Sensitivity (long- or short-haul) */
+	uclong tslot_bitmap;	/* bit[i]=1  =>  timeslot _i_ is active */
+} pc300chconf_t;
+
+typedef struct pc300ch {
+	struct pc300 *card;
+	int channel;
+	pc300dev_t d;
+	pc300chconf_t conf;
+	ucchar tx_first_bd;	/* First TX DMA block descr. w/ data */
+	ucchar tx_next_bd;	/* Next free TX DMA block descriptor */
+	ucchar rx_first_bd;	/* First free RX DMA block descriptor */
+	ucchar rx_last_bd;	/* Last free RX DMA block descriptor */
+	falc_t falc;		/* FALC structure (TE only) */
+} pc300ch_t;
+
+typedef struct pc300 {
+	pc300hw_t hw;			/* hardware config. */
+	pc300ch_t chan[PC300_MAXCHAN];
+#ifdef __KERNEL__
+	spinlock_t card_lock;
+#endif /* __KERNEL__ */
+} pc300_t;
+
+/* DEV ioctl() commands */
+#define	N_SPPP_IOCTLS	2
+
+enum pc300_ioctl_cmds {
+	SIOCCPCRESERVED = (SIOCDEVPRIVATE + N_SPPP_IOCTLS),
+	SIOCGPC300CONF,
+	SIOCSPC300CONF,
+	SIOCGPC300STATUS,
+	SIOCGPC300FALCSTATUS,
+};
+
+/* Control Constant Definitions */
+#define	PC300_RSV	0x01
+#define	PC300_X21	0x02
+#define	PC300_TE	0x03
+
+#define PC300_LC_AMI	0x01
+#define PC300_LC_B8ZS	0x02
+#define PC300_LC_NRZ	0x03
+#define PC300_LC_HDB3	0x04
+
+/* Framing (T1) */
+#define PC300_FR_ESF		0x01
+#define PC300_FR_D4		0x02
+#define PC300_FR_ESF_JAPAN	0x03
+
+/* Framing (E1) */
+#define PC300_FR_MF_CRC4	0x04
+#define PC300_FR_MF_NON_CRC4	0x05
+
+#define PC300_LBO_0_DB		0x00
+#define PC300_LBO_7_5_DB	0x01
+#define PC300_LBO_15_DB		0x02
+#define PC300_LBO_22_5_DB	0x03
+
+#define PC300_RX_SENS_SH	0x01
+#define PC300_RX_SENS_LH	0x02
+
+#define PC300_TX_TIMEOUT	(2*HZ)
+#define PC300_TX_QUEUE_LEN	10
+#define	PC300_DEF_MTU		1500
+
+#ifdef __KERNEL__
+/* Function Prototypes */
+static void tx_dma_buf_pt_init(pc300_t *, int);
+static void tx_dma_buf_init(pc300_t *, int);
+static void rx_dma_buf_pt_init(pc300_t *, int);
+static void rx_dma_buf_init(pc300_t *, int);
+static void tx_dma_buf_check(pc300_t *, int);
+static void rx_dma_buf_check(pc300_t *, int);
+int dma_buf_write(pc300_t *, int, ucchar *, int);
+int dma_buf_read(pc300_t *, int, struct sk_buff *);
+void tx_dma_start(pc300_t *, int);
+void rx_dma_start(pc300_t *, int);
+void tx_dma_stop(pc300_t *, int);
+void rx_dma_stop(pc300_t *, int);
+int cpc_queue_xmit(struct sk_buff *, struct device *);
+void cpc_net_rx(hdlc_device *);
+#ifdef CONFIG_PC300_X25
+int cpc_x25_packetlayer_xmit(struct sk_buff *, struct device *);
+void cpc_lapb_connected(void *, int);
+void cpc_lapb_disconnected(void *, int);
+void cpc_lapb_data_indication(void *, struct sk_buff *);
+void cpc_lapb_data_transmit(void *, struct sk_buff *);
+#endif /* CONFIG_PC300_X25 */
+static void cpc_intr(int, void *, struct pt_regs *);
+void cpc_sca_status(pc300_t *, int);
+int cpc_ioctl(hdlc_device *, struct ifreq *, int);
+static int clock_rate_calc(uclong, uclong, int *);
+int ch_config(pc300dev_t *);
+int rx_config(pc300dev_t *);
+int tx_config(pc300dev_t *);
+int cpc_opench(pc300dev_t *);
+void cpc_closech(pc300dev_t *);
+int cpc_open(hdlc_device *);
+void cpc_close(hdlc_device *);
+static uclong detect_ram(pc300_t *);
+static void plx_init(pc300_t *);
+static int cpc_detect(void);
+#endif /* __KERNEL__ */
+
+#endif	/* _PC300_H */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/pci.h linux.17p18/include/linux/pci.h
--- linux.vanilla/include/linux/pci.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/linux/pci.h	Wed Aug  9 22:31:08 2000
@@ -327,8 +327,16 @@
 #define PCI_DEVICE_ID_ATI_215GT		0x4754
 #define PCI_DEVICE_ID_ATI_215GTB	0x4755
 #define PCI_DEVICE_ID_ATI_210888GX	0x4758
+#define PCI_DEVICE_ID_ATI_RAGE128_LE	0x4c45
+#define PCI_DEVICE_ID_ATI_RAGE128_LF	0x4c46
 #define PCI_DEVICE_ID_ATI_215LG		0x4c47
 #define PCI_DEVICE_ID_ATI_264LT		0x4c54
+#define PCI_DEVICE_ID_ATI_RAGE128_PF	0x5046
+#define PCI_DEVICE_ID_ATI_RAGE128_PR	0x5052
+#define PCI_DEVICE_ID_ATI_RAGE128_RE	0x5245
+#define PCI_DEVICE_ID_ATI_RAGE128_RF	0x5246
+#define PCI_DEVICE_ID_ATI_RAGE128_RK	0x524b
+#define PCI_DEVICE_ID_ATI_RAGE128_RL	0x524c
 #define PCI_DEVICE_ID_ATI_264VT		0x5654
 
 #define PCI_VENDOR_ID_VLSI		0x1004
@@ -377,6 +385,7 @@
 #define PCI_DEVICE_ID_DEC_21153		0x0025
 #define PCI_DEVICE_ID_DEC_21154		0x0026
 #define PCI_DEVICE_ID_DEC_21285		0x1065
+#define PCI_DEVICE_ID_DEC_21554		0x0046
 #define PCI_DEVICE_ID_COMPAQ_42XX	0x0046
 
 #define PCI_VENDOR_ID_CIRRUS		0x1013
@@ -559,10 +568,12 @@
 #define PCI_DEVICE_ID_PICOP_PT80C524	0x8002
 
 #define PCI_VENDOR_ID_MYLEX		0x1069
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V2	0x0001
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V3	0x0002
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V4	0x0010
-#define PCI_DEVICE_ID_MYLEX_DAC960P_V5	0x0020
+#define PCI_DEVICE_ID_MYLEX_DAC960_P	0x0001
+#define PCI_DEVICE_ID_MYLEX_DAC960_PD	0x0002
+#define PCI_DEVICE_ID_MYLEX_DAC960_PG	0x0010
+#define PCI_DEVICE_ID_MYLEX_DAC960_LA	0x0020
+#define PCI_DEVICE_ID_MYLEX_DAC960_LP	0x0050
+#define PCI_DEVICE_ID_MYLEX_DAC960_BA	0xBA56
 
 #define PCI_VENDOR_ID_APPLE		0x106b
 #define PCI_DEVICE_ID_APPLE_BANDIT	0x0001
@@ -951,6 +962,10 @@
 #define PCI_DEVICE_ID_CYCLOM_8Y_Hi	0x0105
 #define PCI_DEVICE_ID_CYCLOM_Z_Lo	0x0200
 #define PCI_DEVICE_ID_CYCLOM_Z_Hi	0x0201
+#define PCI_DEVICE_ID_PC300_RX_2	0x0300
+#define PCI_DEVICE_ID_PC300_RX_1	0x0301
+#define PCI_DEVICE_ID_PC300_TE_2	0x0310
+#define PCI_DEVICE_ID_PC300_TE_1	0x0311
 
 #define PCI_VENDOR_ID_ESSENTIAL		0x120f
 #define PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER	0x0001
@@ -1042,13 +1057,11 @@
 
 #define PCI_VENDOR_ID_TIMEDIA		0x1409
 #define PCI_DEVICE_ID_TIMEDIA_1889	0x7168
+#define PCI_DEVICE_ID_TIMEDIA_4008A	0x7268
 
 #define PCI_VENDOR_ID_AFAVLAB		0x14db
 #define PCI_DEVICE_ID_AFAVLAB_TK9902	0x2120
 
-#define PCI_VENDOR_ID_TIMEDIA		0x1409
-#define PCI_DEVICE_ID_TIMEDIA_4008A	0x7268
-
 #define PCI_VENDOR_ID_SYMPHONY		0x1c1c
 #define PCI_DEVICE_ID_SYMPHONY_101	0x0001
 
@@ -1109,6 +1122,7 @@
 #define PCI_DEVICE_ID_INTEL_82430	0x0486
 #define PCI_DEVICE_ID_INTEL_82434	0x04a3
 #define PCI_DEVICE_ID_INTEL_I960	0x0960
+#define PCI_DEVICE_ID_INTEL_I960RN	0x0964
 #define PCI_DEVICE_ID_INTEL_82559ER	0x1209
 #define PCI_DEVICE_ID_INTEL_82092AA_0	0x1221
 #define PCI_DEVICE_ID_INTEL_82092AA_1	0x1222
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/sched.h linux.17p18/include/linux/sched.h
--- linux.vanilla/include/linux/sched.h	Fri Apr 21 23:10:16 2000
+++ linux.17p18/include/linux/sched.h	Wed Aug  9 22:33:24 2000
@@ -291,7 +291,6 @@
 /* mm fault and swap info: this can arguably be seen as either mm-specific or thread-specific */
 	unsigned long min_flt, maj_flt, nswap, cmin_flt, cmaj_flt, cnswap;
 	int swappable:1;
-	int trashing_mem:1;
 /* process credentials */
 	uid_t uid,euid,suid,fsuid;
 	gid_t gid,egid,sgid,fsgid;
@@ -382,7 +381,7 @@
 /* utime */	{0,0,0,0},0, \
 /* per CPU times */ {0, }, {0, }, \
 /* flt */	0,0,0,0,0,0, \
-/* swp */	0,0, \
+/* swp */	0, \
 /* process credentials */					\
 /* uid etc */	0,0,0,0,0,0,0,0,				\
 /* suppl grps*/ 0, {0,},					\
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/telephony.h linux.17p18/include/linux/telephony.h
--- linux.vanilla/include/linux/telephony.h	Fri Apr 21 12:47:01 2000
+++ linux.17p18/include/linux/telephony.h	Tue Aug  1 08:00:21 2000
@@ -1,32 +1,33 @@
-/*
- *              telephony.h
+/******************************************************************************
+ *
+ *		telephony.h
  *
- *              Basic Linux Telephony Interface
+ *		Basic Linux Telephony Interface
  *
- *              (c) Copyright 1999 Quicknet Technologies, Inc.
+ *		(c) Copyright 1999 Quicknet Technologies, Inc.
  *
- *              This program is free software; you can redistribute it and/or
- *              modify it under the terms of the GNU General Public License
- *              as published by the Free Software Foundation; either version
- *              2 of the License, or (at your option) any later version.
+ *		This program is free software; you can redistribute it and/or
+ *		modify it under the terms of the GNU General Public License
+ *		as published by the Free Software Foundation; either version
+ *		2 of the License, or (at your option) any later version.
  *
- * Authors:       Ed Okerson, <eokerson@quicknet.net>
- *                Greg Herlein, <gherlein@quicknet.net>
+ *    Authors:       Ed Okerson, <eokerson@quicknet.net>
+ *                   Greg Herlein, <gherlein@quicknet.net>
  *
- * Contributors:  Alan Cox, <acox@redhat.com>
- *                David Erhart, <derhart@quicknet.net>
+ *    Contributors:  Alan Cox, <alan@redhat.com>
+ *                   David W. Erhart, <derhart@quicknet.net>
  *
  * Version:       0.1.0 - December 19, 1999
  *
  * Fixes:
- */
+ * 
+ *****************************************************************************/
 
 #ifndef TELEPHONY_H
 #define TELEPHONY_H
 
-/* vendor identification numbers */
 #define PHONE_VENDOR_IXJ          1
-#define PHONE_VENDOR_QUICKNET     PHONE_IXJ
+#define PHONE_VENDOR_QUICKNET	  PHONE_VENDOR_IXJ
 #define PHONE_VENDOR_VOICETRONIX  2
 #define PHONE_VENDOR_ACULAB       3
 #define PHONE_VENDOR_DIGI         4
@@ -43,7 +44,6 @@
  *
  *****************************************************************************/
 
- 
 /******************************************************************************
 *
 * The capabilities ioctls can inform you of the capabilities of each phone
@@ -81,11 +81,23 @@
 #define PHONE_CAPABILITIES_LIST         _IOR ('q', 0x81, struct phone_capability *)
 #define PHONE_CAPABILITIES_CHECK        _IOW ('q', 0x82, struct phone_capability *)
 
+typedef struct {
+        char month[3];
+        char day[3];
+        char hour[3];
+        char min[3];
+        int numlen;
+        char number[11];
+        int namelen;
+        char name[80];
+} PHONE_CID;
+
 #define PHONE_RING			_IO  ('q', 0x83)
 #define PHONE_HOOKSTATE			_IO  ('q', 0x84)
 #define PHONE_MAXRINGS			_IOW ('q', 0x85, char)
 #define PHONE_RING_CADENCE		_IOW ('q', 0x86, short)
-#define PHONE_RING_START		_IO  ('q', 0x87)
+#define OLD_PHONE_RING_START		_IO  ('q', 0x87)
+#define PHONE_RING_START		_IOW ('q', 0x87, PHONE_CID *)
 #define PHONE_RING_STOP			_IO  ('q', 0x88)
 
 #define USA_RING_CADENCE	 0xC0C0
@@ -167,6 +179,23 @@
 #define PHONE_QUERY_CODEC		_IOWR ('q', 0xA7, struct phone_codec_data *)
 #define PHONE_PSTN_LINETEST		_IO ('q', 0xA8)
 
+/******************************************************************************
+* 
+* This controls the VAD/CNG functionality of G.723.1.  The driver will
+* always pass full size frames, any unused bytes will be padded with zeros,
+* and frames passed to the driver should also be padded with zeros.  The
+* frame type is encoded in the least significant two bits of the first
+* WORD of the frame as follows:
+*
+* bits 1-0	Frame Type	Data Rate		Significant Words
+* 00		0		G.723.1 6.3		12
+* 01		1		G.723.1 5.3		10
+* 10		2		VAD/CNG			 2
+* 11		3		Repeat last CNG		 2 bits
+* 
+******************************************************************************/
+#define PHONE_VAD			_IOW ('q', 0xA9, int)
+
 
 /******************************************************************************
 *
@@ -198,7 +227,12 @@
 	unsigned int f1:1;
 	unsigned int f2:1;
 	unsigned int f3:1;
-	unsigned int reserved:23;
+	unsigned int flash:1;
+	unsigned int fc0:1;
+	unsigned int fc1:1;
+	unsigned int fc2:1;
+	unsigned int fc3:1;
+	unsigned int reserved:18;
 };
 
 union telephony_exception {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/linux/toshiba.h linux.17p18/include/linux/toshiba.h
--- linux.vanilla/include/linux/toshiba.h	Thu Jan  1 01:00:00 1970
+++ linux.17p18/include/linux/toshiba.h	Tue Aug  1 08:00:21 2000
@@ -0,0 +1,36 @@
+/* toshiba.h -- Linux driver for accessing the SMM on Toshiba laptops 
+ *
+ * Copyright (c) 1996-2000  Jonathan A. Buzzard (jonathan@buzzard.org.uk)
+ *
+ * Thanks to Juergen Heinzl <juergen@monocerus.demon.co.uk> for the pointers
+ * on making sure the structure is aligned and packed.
+ *
+ * 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, 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.
+ *
+ */
+
+#ifndef _LINUX_TOSHIBA_H
+#define _LINUX_TOSHIBA_H
+
+#define TOSH_PROC "/proc/toshiba"
+#define TOSH_DEVICE "/dev/toshiba"
+#define TOSH_SMM _IOWR('t', 0x90, 24)
+
+typedef struct {
+	unsigned int eax;
+	unsigned int ebx __attribute__ ((packed));
+	unsigned int ecx __attribute__ ((packed));
+	unsigned int edx __attribute__ ((packed));
+	unsigned int esi __attribute__ ((packed));
+	unsigned int edi __attribute__ ((packed));
+} SMMRegisters;
+
+#endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/net/slhc_vj.h linux.17p18/include/net/slhc_vj.h
--- linux.vanilla/include/net/slhc_vj.h	Fri Apr 21 12:47:01 2000
+++ linux.17p18/include/net/slhc_vj.h	Tue Aug  1 18:25:56 2000
@@ -115,6 +115,9 @@
 typedef __u8 byte_t;
 typedef __u32 int32;
 
+
+#include <linux/ip.h>
+#include <linux/tcp.h>
 /*
  * "state" data for each active tcp conversation on the wire.  This is
  * basically a copy of the entire IP/TCP header from the last packet
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/net/snmp.h linux.17p18/include/net/snmp.h
--- linux.vanilla/include/net/snmp.h	Fri Apr 21 12:47:01 2000
+++ linux.17p18/include/net/snmp.h	Tue Aug  1 08:00:21 2000
@@ -178,6 +178,7 @@
 	unsigned long	OfoPruned;
 	unsigned long	OutOfWindowIcmps; 
 	unsigned long	LockDroppedIcmps; 
+	unsigned long	SockMallocOOM; 
 };
  	
 #endif
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/net/sock.h linux.17p18/include/net/sock.h
--- linux.vanilla/include/net/sock.h	Fri Apr 21 23:11:02 2000
+++ linux.17p18/include/net/sock.h	Wed Aug  9 22:34:08 2000
@@ -717,6 +717,10 @@
 extern struct sk_buff		*sock_wmalloc(struct sock *sk,
 					      unsigned long size, int force,
 					      int priority);
+
+extern struct sk_buff		*sock_wmalloc_err(struct sock *sk,
+					      unsigned long size, int force,
+					      int priority, int *err);
 extern struct sk_buff		*sock_rmalloc(struct sock *sk,
 					      unsigned long size, int force,
 					      int priority);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/include/scsi/sg.h linux.17p18/include/scsi/sg.h
--- linux.vanilla/include/scsi/sg.h	Sun Jun 11 21:44:23 2000
+++ linux.17p18/include/scsi/sg.h	Tue Aug  1 08:00:21 2000
@@ -11,10 +11,12 @@
 2.x extensions to driver:
 *       Copyright (C) 1998 - 2000 Douglas Gilbert
 
-    Version: 2.1.38 (20000527)
+    Version: 2.1.39 (20000626)
     This version for 2.2.x series kernels
     D. P. Gilbert (dgilbert@interlog.com, dougg@triode.net.au)
 
+    Changes since 2.1.38 (20000527)
+        - more scatter gather fine tuning for sym53c416
     Changes since 2.1.37 (20000504)
         - fine tune state machine to stop read() race
         - switch to numeric device description (e.g. sg0 instead of sga)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/init/main.c linux.17p18/init/main.c
--- linux.vanilla/init/main.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/init/main.c	Tue Aug  1 07:59:23 2000
@@ -47,7 +47,7 @@
 #endif
 
 #ifdef CONFIG_DASD
-#include <linux/dasd.h>
+#include <asm/dasd.h>
 #endif
 
 #ifdef CONFIG_BLK_DEV_XPRAM
@@ -58,6 +58,8 @@
 extern void nubus_init(void);
 #endif
 
+extern int irda_device_init(void);
+
 /*
  * Versions of gcc older than that listed below may actually compile
  * and link okay, but the end product can have subtle run time bugs.
@@ -199,9 +201,6 @@
 #endif
 #ifdef CONFIG_DASD
 extern void dasd_setup(char *str, int *ints);
-#ifdef CONFIG_DASD_MDSK
-extern void dasd_mdsk_setup(char *str, int *ints);
-#endif
 #endif
 #ifdef CONFIG_BLK_DEV_XPRAM
 extern void xpram_setup(char *str, int *ints);
@@ -1098,9 +1097,6 @@
 #endif
 #ifdef CONFIG_DASD
         { "dasd=", dasd_setup },
-#ifdef CONFIG_DASD_MDSK
-        { "dasd_force_diag=", dasd_mdsk_setup },
-#endif
 #endif
 #ifdef CONFIG_BLK_DEV_XPRAM
         { "xpram_parts=", xpram_setup },
@@ -1414,6 +1410,9 @@
 	vma_init();
 	buffer_init(memory_end-memory_start);
  	page_cache_init(memory_end-memory_start);
+#ifdef CONFIG_ARCH_S390
+	ccwcache_init();
+#endif
 	signals_init();
 	inode_init();
 	file_table_init();
@@ -1552,9 +1551,7 @@
 
 	/* Set up devices .. */
 	device_setup();
-#if  CONFIG_CHANDEV
-	chandev_init();
-#endif   
+
 	/* .. executable formats .. */
 	binfmt_setup();
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/kernel/ksyms.c linux.17p18/kernel/ksyms.c
--- linux.vanilla/kernel/ksyms.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/kernel/ksyms.c	Thu Aug 17 17:49:30 2000
@@ -75,6 +75,7 @@
 
 #ifdef CONFIG_KMOD
 EXPORT_SYMBOL(request_module);
+EXPORT_SYMBOL(exec_usermodehelper);
 #endif
 
 #ifdef CONFIG_MODULES
@@ -339,6 +340,7 @@
 EXPORT_SYMBOL(do_gettimeofday);
 EXPORT_SYMBOL(loops_per_sec);
 EXPORT_SYMBOL(kstat);
+EXPORT_SYMBOL(pidhash); 
 
 /* misc */
 EXPORT_SYMBOL(panic);
@@ -423,4 +425,11 @@
 
 /* init task, for moving kthread roots - ought to export a function ?? */
 EXPORT_SYMBOL(init_task_union);
+
+/* Support for external backtracer */ 
+extern char _stext[], _etext[];
+EXPORT_SYMBOL(_stext);
+EXPORT_SYMBOL(_etext); 
+EXPORT_SYMBOL(module_list); 
+
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/mm/filemap.c linux.17p18/mm/filemap.c
--- linux.vanilla/mm/filemap.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/mm/filemap.c	Fri Aug  4 15:23:01 2000
@@ -141,10 +141,12 @@
 	unsigned long limit = num_physpages;
 	struct page * page;
 	int count;
-
+	int nr_dirty = 0;
+	
 	/* Make sure we scan all pages twice at priority 0. */
 	count = (limit << 1) >> priority;
 
+ refresh_clock:
 	page = mem_map + clock;
 	do {
 		int referenced;
@@ -177,8 +179,6 @@
 		if ((gfp_mask & __GFP_DMA) && !PageDMA(page))
 			continue;
 
-		count--;
-
 		/*
 		 * Is it a page swap page? If so, we want to
 		 * drop it if it is no longer used, even if it
@@ -196,10 +196,23 @@
 
 		/* Is it a buffer page? */
 		if (page->buffers) {
+			/*
+			 * Wait for async IO to complete
+			 * at each 64 buffers
+			 */ 
+
+			int wait = ((gfp_mask & __GFP_IO) 
+				&& (!(nr_dirty++ % 64)));
+
 			if (buffer_under_min())
 				continue;
-			if (!try_to_free_buffers(page))
-				continue;
+			/*
+			 * We can sleep if we need to do some write
+			 * throttling.
+			 */
+
+			if (!try_to_free_buffers(page, wait))
+				goto refresh_clock;
 			return 1;
 		}
 
@@ -211,7 +224,7 @@
 			return 1;
 		}
 
-	} while (count > 0);
+	} while (--count > 0);
 	return 0;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/mm/page_alloc.c linux.17p18/mm/page_alloc.c
--- linux.vanilla/mm/page_alloc.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/mm/page_alloc.c	Tue Aug  1 08:00:22 2000
@@ -182,7 +182,6 @@
 unsigned long __get_free_pages(int gfp_mask, unsigned long order)
 {
 	unsigned long flags;
-	static unsigned long last_woke_kswapd = 0;
 	static atomic_t free_before_allocate = ATOMIC_INIT(0);
 
 	if (order >= NR_MEM_LISTS)
@@ -208,41 +207,41 @@
 		int freed;
 		extern struct wait_queue * kswapd_wait;
 
-		if (nr_free_pages > freepages.high)
-			goto ok_to_allocate;
-		
-		/* Maybe wake up kswapd for background swapping. */
-		if (time_before(last_woke_kswapd + HZ, jiffies)) {
-			last_woke_kswapd = jiffies;
-			wake_up_interruptible(&kswapd_wait);
-		}
-
 		/* Somebody needs to free pages so we free some of our own. */
 		if (atomic_read(&free_before_allocate)) {
 			current->flags |= PF_MEMALLOC;
-			freed = try_to_free_pages(gfp_mask);
+			try_to_free_pages(gfp_mask);
 			current->flags &= ~PF_MEMALLOC;
-			if (freed)
-				goto ok_to_allocate;
 		}
 
-		/* Do we have to help kswapd or can we proceed? */
-		if (nr_free_pages < (freepages.low + freepages.low) / 2) {
+		if (nr_free_pages > freepages.low)
+			goto ok_to_allocate;
+
+		if (waitqueue_active(&kswapd_wait))
 			wake_up_interruptible(&kswapd_wait);
 
-			/* Help kswapd a bit... */
-			current->flags |= PF_MEMALLOC;
-			atomic_inc(&free_before_allocate);
-			freed = try_to_free_pages(gfp_mask);
-			atomic_dec(&free_before_allocate);
-			current->flags &= ~PF_MEMALLOC;
+		/* Do we have to block or can we proceed? */
+		if (nr_free_pages > freepages.min)
+			goto ok_to_allocate;
 
-			if (nr_free_pages > freepages.min)
-				goto ok_to_allocate;
+		current->flags |= PF_MEMALLOC;
+		atomic_inc(&free_before_allocate);
+		freed = try_to_free_pages(gfp_mask);
+		atomic_dec(&free_before_allocate);
+		current->flags &= ~PF_MEMALLOC;
+
+		/*
+		 * Re-check we're still low on memory after we blocked
+		 * for some time. Somebody may have released lots of
+		 * memory from under us while we was trying to free
+		 * the pages. We check against pages_high to be sure
+		 * to succeed only if lots of memory is been released.
+		 */
+		if (nr_free_pages > freepages.high)
+			goto ok_to_allocate;
 
-			if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
-				goto nopage;
-		}
+		if (!freed && !(gfp_mask & (__GFP_MED | __GFP_HIGH)))
+			goto nopage;
 	}
 ok_to_allocate:
 	spin_lock_irqsave(&page_alloc_lock, flags);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/mm/vmscan.c linux.17p18/mm/vmscan.c
--- linux.vanilla/mm/vmscan.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/mm/vmscan.c	Tue Aug  1 08:00:22 2000
@@ -333,7 +333,6 @@
 
 	for (; counter >= 0; counter--) {
 		max_cnt = 0;
-		assign = 0;
 		pbest = NULL;
 	select:
 		read_lock(&tasklist_lock);
@@ -378,17 +377,12 @@
  * cluster them so that we get good swap-out behaviour. See
  * the "free_memory()" macro for details.
  */
-#define FLUSH_COUNT	8
 static int do_try_to_free_pages(unsigned int gfp_mask)
 {
-	int priority, count, swapcount;
-	int flushcount = FLUSH_COUNT;
+	int priority;
 	int ret = 0;
-
-	/* Kswapd does nothing but freeing pages so we can do big bites. */
-	if (gfp_mask == GFP_KSWAPD)
-		flushcount = SWAP_CLUSTER_MAX;
-	count = flushcount;
+	int swapcount;
+	int count = SWAP_CLUSTER_MAX;
 
 	lock_kernel();
 
@@ -413,21 +407,15 @@
 		}
 
 		/* Then, try to page stuff out.. */
-		swapcount = flushcount;
+		swapcount = count;
 		while (swap_out(priority, gfp_mask)) {
+			ret = 1;
 			if (!--swapcount)
 				break;
 		}
 
 		shrink_dcache_memory(priority, gfp_mask);
 	} while (--priority >= 0);
-
-	/* End with a shrink_mmap() to make sure we free something. */
-	while (shrink_mmap(0, gfp_mask)) {
-		ret = 1;
-		if (!--count)
-			goto done;
-	}
 done:
 	unlock_kernel();
 
@@ -507,18 +495,11 @@
 		 * the processes needing more memory will wake us
 		 * up on a more timely basis.
 		 */
-		int failed = 0;
-sleep:
 		interruptible_sleep_on(&kswapd_wait);
-		/* Enough free pages? -> call do_try_to_free_pages only once. */
-		if (nr_free_pages > freepages.low) {
-			do_try_to_free_pages(GFP_KSWAPD);
-			goto sleep;
-		}
-		/* Not enough free pages? -> free pages agressively. */
+
 		while (nr_free_pages < freepages.high)
 		{
-			if (do_try_to_free_pages(GFP_KSWAPD) && failed++ < 10)
+			if (do_try_to_free_pages(GFP_KSWAPD))
 			{
 				if (tsk->need_resched)
 					schedule();
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/appletalk/aarp.c linux.17p18/net/appletalk/aarp.c
--- linux.vanilla/net/appletalk/aarp.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/appletalk/aarp.c	Tue Aug  1 08:00:29 2000
@@ -363,6 +363,7 @@
 static void aarp_expire_timeout(unsigned long unused)
 {
 	int ct=0;
+	SOCKHASH_LOCK();
 	for(ct=0;ct<AARP_HASH_SIZE;ct++)
 	{
 		aarp_expire_timer(&resolved[ct]);
@@ -370,6 +371,7 @@
 		aarp_expire_timer(&unresolved[ct]);
 		aarp_expire_timer(&proxies[ct]);
 	}
+	SOCKHASH_UNLOCK();
 
 	mod_timer(&aarp_timer, jiffies + 
 		  (unresolved_count ? sysctl_aarp_tick_time:
@@ -385,12 +387,14 @@
 	int ct=0;
 	if(event==NETDEV_DOWN)
 	{
+		SOCKHASH_LOCK();
 		for(ct=0;ct<AARP_HASH_SIZE;ct++)
 		{
 			aarp_expire_device(&resolved[ct],ptr);
 			aarp_expire_device(&unresolved[ct],ptr);
 			aarp_expire_device(&proxies[ct],ptr);
 		}
+		SOCKHASH_UNLOCK();
 	}
 	return NOTIFY_DONE;
 }
@@ -414,9 +418,7 @@
  */
 static struct aarp_entry *aarp_find_entry(struct aarp_entry *list, struct device *dev, struct at_addr *sat)
 {
-	unsigned long flags;
-	save_flags(flags);
-	cli();
+	SOCKHASH_LOCK();
 	while(list)
 	{
 		if(list->target_addr.s_net==sat->s_net &&
@@ -424,7 +426,7 @@
 			break;
 		list=list->next;
 	}
-	restore_flags(flags);
+	SOCKHASH_UNLOCK();
 	return list;
 }
 
@@ -434,12 +436,14 @@
 	int hash;
 	
 	hash = 	sa->s_node % (AARP_HASH_SIZE-1);
+	SOCKHASH_LOCK();
 	a = aarp_find_entry(proxies[hash], dev, sa);
 	if (a)
 	{
 		a->expires_at = 0;
 		
 	}
+	SOCKHASH_UNLOCK();
 }
 
 struct at_addr* aarp_proxy_find(struct device *dev, struct at_addr *sa)
@@ -547,6 +551,7 @@
 	entry->target_addr.s_net = sa->s_net;
 	entry->dev = atif->dev;
 
+	SOCKHASH_LOCK();
 	hash = sa->s_node % (AARP_HASH_SIZE-1);
 	entry->next = proxies[hash];
 	proxies[hash] = entry;
@@ -559,14 +564,18 @@
 		 * Defer 1/10th
 		 */
 		current->state = TASK_INTERRUPTIBLE;
+		SOCKHASH_UNLOCK();
 		schedule_timeout(HZ/10);
+		SOCKHASH_LOCK();
 		
 		/*
 		 * our atif may no longer be valid, if the device was brought
 		 * down while we waited!
 		 */
-		if (atalk_find_dev(dev) != atif)
+		if (atalk_find_dev(dev) != atif) {
+			SOCKHASH_UNLOCK();
 			return -ENODEV;
+		}
 						
 		if (entry->status & ATIF_PROBE_FAIL)
 			break;
@@ -583,6 +592,7 @@
 		entry->expires_at = 0;
 		
 		/* return network full */
+		SOCKHASH_UNLOCK();
 		return (-EADDRINUSE);
 	}
 	else
@@ -591,6 +601,7 @@
 		entry->status &= ~ATIF_PROBE;
 	}
 
+	SOCKHASH_UNLOCK();
 	return 1;	
 }
 
@@ -603,7 +614,6 @@
 	static char ddp_eth_multicast[ETH_ALEN]={ 0x09, 0x00, 0x07, 0xFF, 0xFF, 0xFF };
 	int hash;
 	struct aarp_entry *a;
-	unsigned long flags;
 	
 	skb->nh.raw=skb->data;
 	
@@ -680,9 +690,7 @@
 	skb->protocol = htons(ETH_P_ATALK);
 			
 	hash=sa->s_node%(AARP_HASH_SIZE-1);
-	save_flags(flags);
-	cli();
-	
+
 	/*
 	 *	Do we have a resolved entry ?
 	 */
@@ -693,9 +701,9 @@
 		if(skb->sk)
 			skb->priority = skb->sk->priority;
 		dev_queue_xmit(skb);
-		restore_flags(flags);
 		return 1;
 	}
+	SOCKHASH_LOCK();
 	a=aarp_find_entry(resolved[hash],dev,sa);
 	if(a!=NULL)
 	{
@@ -708,7 +716,7 @@
 		if(skb->sk)
 			skb->priority = skb->sk->priority;
 		dev_queue_xmit(skb);
-		restore_flags(flags);
+		SOCKHASH_UNLOCK();
 		return 1;
 	}
 
@@ -724,7 +732,7 @@
 		 */
 
 		skb_queue_tail(&a->packet_queue, skb);
-		restore_flags(flags);
+		SOCKHASH_UNLOCK();
 		return 0;
 	}
 
@@ -739,7 +747,7 @@
 		 *	Whoops slipped... good job it's an unreliable 
 		 *	protocol 8)	
 		 */
-		restore_flags(flags);
+		SOCKHASH_UNLOCK();
 		return -1;
 	}
 
@@ -755,7 +763,6 @@
 	a->xmit_count=0;
 	unresolved[hash]=a;
 	unresolved_count++;
-	restore_flags(flags);
 
 	/*
 	 *	Send an initial request for the address
@@ -777,6 +784,7 @@
 	 *	Tell the ddp layer we have taken over for this frame.
 	 */
 
+	SOCKHASH_UNLOCK();
 	return 0;
 }
 
@@ -828,7 +836,6 @@
 	struct elapaarp *ea=(struct elapaarp *)skb->h.raw;
 	struct aarp_entry *a;
 	struct at_addr sa, *ma, da;
-	unsigned long flags;
 	int hash;
 	struct atalk_iface *ifa;
 	int func;
@@ -884,16 +891,15 @@
 	 *	Process the packet
 	 */
 	 
-	save_flags(flags);
-
 	/*
 	 *	Check for replies of me
 	 */
 			
+	SOCKHASH_LOCK();
 	ifa=atalk_find_dev(dev);
 	if(ifa==NULL)
 	{
-		restore_flags(flags);
+		SOCKHASH_UNLOCK();
 		kfree_skb(skb);
 		return 1;		
 	}
@@ -906,7 +912,7 @@
 			 */
 			 
 			ifa->status|=ATIF_PROBE_FAIL;
-			restore_flags(flags);
+			SOCKHASH_UNLOCK();
 			kfree_skb(skb);
 			return 1;		
 		}
@@ -916,11 +922,6 @@
 	 * Check for replies of proxy AARP entries
 	 */
 
-	/*
-	 * FIX ME: do we need a cli() here? 
-	 * aarp_find_entry does one on its own, between saving and restoring flags, so
-	 * I don't think it is necessary, but I could be wrong -- it's happened before
-	 */
 	da.s_node = ea->pa_dst_node;
 	da.s_net = ea->pa_dst_net;
 	a = aarp_find_entry(proxies[hash], dev, &da);
@@ -933,7 +934,7 @@
 			 * we do not respond to probe or request packets for 
 			 * this address while we are probing this address
 			 */
-			restore_flags(flags);
+			SOCKHASH_UNLOCK();
 			kfree_skb(skb);
 			return 1;
 		}
@@ -947,7 +948,6 @@
 			 *	Find the entry	
 			 */
 			 
-			cli();	/* FIX ME: is this cli() necessary? aarp_find_entry does one on its own... */
 			if((a=aarp_find_entry(unresolved[hash],dev,&sa))==NULL || dev != a->dev)
 				break;
 			/*
@@ -1025,7 +1025,7 @@
 			aarp_send_reply(dev,ma,&sa,ea->hw_src);
 			break;
 	}
-	restore_flags(flags);
+	SOCKHASH_UNLOCK();
 	kfree_skb(skb);
 	return 1;		
 }
@@ -1060,6 +1060,7 @@
 {
 	int ct = 0;
 
+	SOCKHASH_LOCK();
 	for(ct = 0; ct < AARP_HASH_SIZE; ct++)
 	{
 		aarp_expire_device(&resolved[ct], dev);
@@ -1067,6 +1068,7 @@
 		aarp_expire_device(&proxies[ct], dev);
 	}
 
+	SOCKHASH_UNLOCK();
 	return;
 }
 
@@ -1082,6 +1084,7 @@
 	len = sprintf(buffer,
 		"%-10.10s  ""%-10.10s""%-18.18s""%12.12s""%12.12s"" xmit_count  status\n",
 		"address","device","hw addr","last_sent", "expires");
+	SOCKHASH_LOCK();
 	for (ct = 0; ct < AARP_HASH_SIZE; ct++)
 	{
 		for (entry = resolved[ct]; entry; entry = entry->next)
@@ -1159,6 +1162,7 @@
 	}
 
 
+	SOCKHASH_UNLOCK();
 	return len;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/appletalk/ddp.c linux.17p18/net/appletalk/ddp.c
--- linux.vanilla/net/appletalk/ddp.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/appletalk/ddp.c	Tue Aug  1 08:00:29 2000
@@ -129,18 +129,23 @@
 
 extern inline void atalk_remove_socket(struct sock *sk)
 {
+	SOCKHASH_LOCK();
 	sklist_remove_socket(&atalk_socket_list,sk);
+	SOCKHASH_UNLOCK();
 }
 
 extern inline void atalk_insert_socket(struct sock *sk)
 {
+	SOCKHASH_LOCK();
 	sklist_insert_socket(&atalk_socket_list,sk);
+	SOCKHASH_UNLOCK();
 }
 
 static struct sock *atalk_search_socket(struct sockaddr_at *to, struct atalk_iface *atif)
 {
 	struct sock *s;
 
+	SOCKHASH_LOCK();
 	for(s = atalk_socket_list; s != NULL; s = s->next)
 	{
 		if(to->sat_port != s->protinfo.af_at.src_port)
@@ -172,6 +177,7 @@
 			break; 
 		}
 	}
+	SOCKHASH_UNLOCK();
 
 	return (s);
 }
@@ -183,6 +189,8 @@
 {
 	struct sock *s;
 
+	SOCKHASH_LOCK();
+
 	for(s = atalk_socket_list; s != NULL; s = s->next)
 	{
 		if(s->protinfo.af_at.src_net != sat->sat_addr.s_net)
@@ -203,12 +211,15 @@
 		break;
 	}
 
+	SOCKHASH_UNLOCK();
 	return (s);
 }
 
 extern inline void atalk_destroy_socket(struct sock *sk)
 {
+	SOCKHASH_LOCK();
 	sklist_destroy_socket(&atalk_socket_list, sk);
+	SOCKHASH_UNLOCK();
 	MOD_DEC_USE_COUNT;
 }
 
@@ -227,6 +238,7 @@
 	 */
 
 	len += sprintf(buffer,"Type local_addr  remote_addr tx_queue rx_queue st uid\n");
+	SOCKHASH_LOCK();
 	for(s = atalk_socket_list; s != NULL; s = s->next)
 	{
 		len += sprintf(buffer+len,"%02X   ", s->type);
@@ -256,6 +268,8 @@
 			break;
 	}
 
+	SOCKHASH_UNLOCK();
+
 	/* The data in question runs from begin to begin+len */
 	*start = buffer + (offset - begin);	/* Start of wanted data */
 	len -= (offset - begin);   /* Remove unwanted header data from length */
@@ -288,6 +302,7 @@
 	struct atalk_iface **iface = &atalk_iface_list;
 	struct atalk_iface *tmp;
 
+	SOCKHASH_LOCK();
 	while((tmp = *iface) != NULL)
 	{
 		if(tmp->dev == dev)
@@ -300,14 +315,13 @@
 		else
 			iface = &tmp->next;
 	}
-
+	SOCKHASH_UNLOCK();
 }
 
 static struct atalk_iface *atif_add_device(struct device *dev, struct at_addr *sa)
 {
 	struct atalk_iface *iface = (struct atalk_iface *)
 		kmalloc(sizeof(*iface), GFP_KERNEL);
-	unsigned long flags;
 
 	if(iface==NULL)
 		return (NULL);
@@ -316,11 +330,11 @@
 	dev->atalk_ptr=iface;
 	iface->address= *sa;
 	iface->status=0;
-	save_flags(flags);
-	cli();
+
+	SOCKHASH_LOCK();
 	iface->next=atalk_iface_list;
 	atalk_iface_list=iface;
-	restore_flags(flags);
+	SOCKHASH_UNLOCK();
 
 	MOD_INC_USE_COUNT;
 
@@ -487,20 +501,29 @@
 	 * Return a point-to-point interface only if
 	 * there is no non-ptp interface available.
 	 */
+	SOCKHASH_LOCK();
 	for(iface=atalk_iface_list; iface != NULL; iface=iface->next)
 	{
 		if(!fiface && !(iface->dev->flags & IFF_LOOPBACK))
 			fiface=iface;
-		if(!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT)))
+		if(!(iface->dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
+			SOCKHASH_UNLOCK();
 			return (&iface->address);
+		}
 	}
 
-	if(fiface)
+	if(fiface) {
+		SOCKHASH_UNLOCK();
 		return (&fiface->address);
-	if(atalk_iface_list != NULL)
+	}
+	if(atalk_iface_list != NULL) {
+		SOCKHASH_UNLOCK();
 		return (&atalk_iface_list->address);
-	else
+	}
+	else {
+		SOCKHASH_UNLOCK();
 		return (NULL);
+	}
 }
 
 /*
@@ -527,21 +550,27 @@
 {
 	struct atalk_iface *iface;
 
+	SOCKHASH_LOCK();
 	for(iface=atalk_iface_list; iface != NULL; iface=iface->next)
 	{
 		if((node==ATADDR_BCAST || node==ATADDR_ANYNODE 
 			|| iface->address.s_node==node)
 			&& iface->address.s_net==net 
-			&& !(iface->status & ATIF_PROBE))
+			&& !(iface->status & ATIF_PROBE)) {
+			SOCKHASH_UNLOCK();
 			return (iface);
+		}
 
 		/* XXXX.0 -- net.0 returns the iface associated with net */
 		if ((node==ATADDR_ANYNODE) && (net != ATADDR_ANYNET) &&
 		    (ntohs(iface->nets.nr_firstnet) <= ntohs(net)) &&
-		    (ntohs(net) <= ntohs(iface->nets.nr_lastnet)))
+		    (ntohs(net) <= ntohs(iface->nets.nr_lastnet))) {
+			SOCKHASH_UNLOCK();
 		        return (iface);
+		}
 	}
 
+	SOCKHASH_UNLOCK();
 	return (NULL);
 }
 
@@ -561,6 +590,7 @@
 	struct atalk_route *r;
 	struct atalk_route *net_route = NULL;
 	
+	SOCKHASH_LOCK();
 	for(r=atalk_router_list; r != NULL; r=r->next)
 	{
 		if(!(r->flags & RTF_UP))
@@ -573,8 +603,10 @@
 				 * if this host route is for the target,
 				 * the we're done
 				 */
-				if (r->target.s_node == target->s_node)
+				if (r->target.s_node == target->s_node) {
+					SOCKHASH_UNLOCK();
 					return (r);
+				}
 			}
 			else
 			{
@@ -591,12 +623,17 @@
 	 * if we found a network route but not a direct host
 	 * route, then return it
 	 */
-	if (net_route != NULL)
+	if (net_route != NULL) {
+		SOCKHASH_UNLOCK();
 		return (net_route);
+	}
 
-	if(atrtr_default.dev)
+	if(atrtr_default.dev) {
+		SOCKHASH_UNLOCK();
 		return (&atrtr_default);
+	}
 
+	SOCKHASH_UNLOCK();
 	return (NULL);
 }
 
@@ -637,9 +674,6 @@
 	struct sockaddr_at *ga=(struct sockaddr_at *)&r->rt_gateway;
 	struct atalk_route *rt;
 	struct atalk_iface *iface, *riface;
-	unsigned long flags;
-
-	save_flags(flags);
 
 	/*
 	 * Fixme: Raise/Lower a routing change semaphore for these
@@ -657,6 +691,7 @@
 	/*
 	 * Now walk the routing table and make our decisions.
 	 */
+	SOCKHASH_LOCK();
 	for(rt=atalk_router_list; rt!=NULL; rt=rt->next)
 	{
 		if(r->rt_flags != rt->flags)
@@ -685,17 +720,21 @@
 				riface = iface;
 		}
 
-		if(riface == NULL)
+		if(riface == NULL) {
+			SOCKHASH_UNLOCK();
 			return (-ENETUNREACH);
+		}
 		devhint = riface->dev;
 	}
 
 	if(rt == NULL)
 	{
-		rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_KERNEL);
-		if(rt == NULL)
+		rt = (struct atalk_route *)kmalloc(sizeof(struct atalk_route), GFP_ATOMIC);
+		if(rt == NULL) {
+			SOCKHASH_UNLOCK();
 			return (-ENOBUFS);
-		cli();
+		}
+
 		rt->next = atalk_router_list;
 		atalk_router_list = rt;
 	}
@@ -708,8 +747,7 @@
 	rt->flags   = r->rt_flags;
 	rt->gateway = ga->sat_addr;
 
-	restore_flags(flags);
-
+	SOCKHASH_UNLOCK();
 	return (0);
 }
 
@@ -720,7 +758,8 @@
 {
 	struct atalk_route **r = &atalk_router_list;
 	struct atalk_route *tmp;
-
+	
+	SOCKHASH_LOCK();
 	while((tmp = *r) != NULL)
 	{
 		if(tmp->target.s_net == addr->s_net
@@ -729,11 +768,13 @@
 		{
 			*r = tmp->next;
 			kfree_s(tmp, sizeof(struct atalk_route));
+			SOCKHASH_UNLOCK();
 			return (0);
 		}
 		r = &tmp->next;
 	}
-
+	
+	SOCKHASH_UNLOCK();
 	return (-ENOENT);
 }
 
@@ -746,6 +787,7 @@
 	struct atalk_route **r = &atalk_router_list;
 	struct atalk_route *tmp;
 
+	SOCKHASH_LOCK();
 	while((tmp = *r) != NULL)
 	{
 		if(tmp->dev == dev)
@@ -756,6 +798,7 @@
 		else
 			r = &tmp->next;
 	}
+	SOCKHASH_UNLOCK();
 
 	if(atrtr_default.dev == dev)
 		atrtr_set_default(NULL);
@@ -1061,6 +1104,7 @@
 	off_t begin=0;
 
 	len += sprintf(buffer,"Interface	  Address   Networks   Status\n");
+	SOCKHASH_LOCK();
 	for(iface = atalk_iface_list; iface != NULL; iface = iface->next)
 	{
 		len += sprintf(buffer+len,"%-16s %04X:%02X  %04X-%04X  %d\n",
@@ -1076,6 +1120,8 @@
 		if(pos > offset + length)
 			break;
 	}
+	SOCKHASH_UNLOCK();
+
 	*start = buffer + (offset - begin);
 	len -= (offset - begin);
 	if(len > length)
@@ -1102,6 +1148,7 @@
 			rt->dev->name);
 	}
 
+	SOCKHASH_LOCK();
 	for(rt = atalk_router_list; rt != NULL; rt = rt->next)
 	{
 		len += sprintf(buffer+len,"%04X:%02X     %04X:%02X  %-4d  %s\n",
@@ -1117,6 +1164,7 @@
 		if(pos > offset + length)
 			break;
 	}
+	SOCKHASH_UNLOCK();
 
 	*start = buffer + (offset - begin);
 	len -= (offset - begin);
@@ -1238,12 +1286,16 @@
  */
 static int atalk_pick_port(struct sockaddr_at *sat)
 {
+	SOCKHASH_LOCK();
 	for(sat->sat_port = ATPORT_RESERVED; sat->sat_port < ATPORT_LAST; sat->sat_port++)
 	{
 		if(atalk_find_socket(sat) == NULL)
+		{
+			SOCKHASH_UNLOCK();
 			return sat->sat_port;
+		}
 	}
-
+	SOCKHASH_UNLOCK();
 	return (-EBUSY);
 }
 
@@ -1583,8 +1635,12 @@
 		 * Note. ddp-> becomes invalid at the realloc.
 		 */
 		if(skb_headroom(skb) < 22)
+		{
 			/* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
-			skb = skb_realloc_headroom(skb, 32);
+			struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
+			kfree(skb);
+			skb=nskb;
+		}
 		else
 			skb = skb_unshare(skb, GFP_ATOMIC);
 		
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/bridge/br.c linux.17p18/net/bridge/br.c
--- linux.vanilla/net/bridge/br.c	Fri Apr 21 12:47:11 2000
+++ linux.17p18/net/bridge/br.c	Tue Aug  1 18:17:47 2000
@@ -2258,7 +2258,7 @@
 					break;
 			        case BRCMD_IF_ENABLE:
 				        bcf.arg1 = br_find_port(bcf.arg1);
-					if (bcf.arg1 < 0)
+					if ((signed)bcf.arg1 < 0)
 						return(bcf.arg1);
 				case BRCMD_PORT_ENABLE:
 					if (port_info[bcf.arg1].dev == 0)
@@ -2276,7 +2276,7 @@
 					break;
 			        case BRCMD_IF_DISABLE:
 				        bcf.arg1 = br_find_port(bcf.arg1);
-					if (bcf.arg1 < 0)
+					if ((signed)bcf.arg1 < 0)
 						return(bcf.arg1);
 				case BRCMD_PORT_DISABLE:
 					if (port_info[bcf.arg1].dev == 0)
@@ -2299,7 +2299,7 @@
 					break;
 			        case BRCMD_SET_IF_PRIORITY:
 				        bcf.arg1 = br_find_port(bcf.arg1);
-					if (bcf.arg1 < 0)
+					if ((signed)bcf.arg1 < 0)
 						return(bcf.arg1);
 				case BRCMD_SET_PORT_PRIORITY:
 					if((port_info[bcf.arg1].dev == 0)
@@ -2310,7 +2310,7 @@
 					break;
 			        case BRCMD_SET_IF_PATH_COST:
 				        bcf.arg1 = br_find_port(bcf.arg1);
-					if (bcf.arg1 < 0)
+					if ((signed)bcf.arg1 < 0)
 						return(bcf.arg1);
 				case BRCMD_SET_PATH_COST:
 					if (port_info[bcf.arg1].dev == 0)
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/core/dev.c linux.17p18/net/core/dev.c
--- linux.vanilla/net/core/dev.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/core/dev.c	Mon Aug 14 20:11:32 2000
@@ -98,6 +98,7 @@
 extern void n2_init(void);
 extern void c101_init(void);
 extern int wanxl_init(void);
+extern int cpc_init(void);
 extern void sync_ppp_init(void);
 
 NET_PROFILE_DEFINE(dev_queue_xmit)
@@ -459,6 +460,10 @@
 	if (!(dev->flags&IFF_UP))
 		return 0;
 
+	/* If the device is a slave we should not touch it*/
+	if(dev->flags&IFF_SLAVE)
+		return -EBUSY;
+                                
 	dev_deactivate(dev);
 
 	dev_lock_wait();
@@ -773,6 +778,10 @@
 	if (backlog.qlen <= netdev_max_backlog) {
 		if (backlog.qlen) {
 			if (netdev_dropping == 0) {
+				if (skb->dev->flags & IFF_SLAVE  && 
+				    skb->dev->slave) {
+					skb->dev = skb->dev->slave;
+				}
 				skb_queue_tail(&backlog,skb);
 				mark_bh(NET_BH);
 				return;
@@ -2039,6 +2048,9 @@
 #endif
 #ifdef CONFIG_WANXL
 	wanxl_init();
+#endif
+#ifdef CONFIG_PC300
+	cpc_init();
 #endif
 #ifdef CONFIG_HDLC
 	sync_ppp_init();
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/core/sock.c linux.17p18/net/core/sock.c
--- linux.vanilla/net/core/sock.c	Fri Apr 21 12:47:11 2000
+++ linux.17p18/net/core/sock.c	Fri Aug  4 15:36:23 2000
@@ -132,6 +132,8 @@
 
 #define min(a,b)	((a)<(b)?(a):(b))
 
+struct linux_mib net_statistics;
+
 /* Run time adjustable parameters. */
 __u32 sysctl_wmem_max = SK_WMEM_MAX;
 __u32 sysctl_rmem_max = SK_RMEM_MAX;
@@ -566,6 +568,35 @@
 			skb->sk = sk;
 			return skb;
 		}
+#ifdef CONFIG_INET
+		net_statistics.SockMallocOOM++; 
+#endif
+	}
+	return NULL;
+}
+
+/*
+ * Allocate memory from the sockets send buffer, telling caller about real OOM. 
+ * err is only set for oom, not for socket buffer overflow.
+ */ 
+struct sk_buff *sock_wmalloc_err(struct sock *sk, unsigned long size, int force, int priority, int *err)
+{
+	*err = 0; 
+	/* Note: overcommitment possible */ 
+	if (force || atomic_read(&sk->wmem_alloc) < sk->sndbuf) {
+		struct sk_buff * skb;
+		*err = -ENOMEM; 
+		skb = alloc_skb(size, priority);
+		if (skb) {
+			*err = 0;
+			atomic_add(skb->truesize, &sk->wmem_alloc);
+			skb->destructor = sock_wfree;
+			skb->sk = sk;
+			return skb;
+		}
+#ifdef CONFIG_INET
+		net_statistics.SockMallocOOM++; 
+#endif
 	}
 	return NULL;
 }
@@ -583,6 +614,9 @@
 			skb->sk = sk;
 			return skb;
 		}
+#ifdef CONFIG_INET
+		net_statistics.SockMallocOOM++;
+#endif 
 	}
 	return NULL;
 }
@@ -602,6 +636,9 @@
 		if (mem)
 			return mem;
 		atomic_sub(size, &sk->omem_alloc);
+#ifdef CONFIG_INET
+		net_statistics.SockMallocOOM++; 
+#endif
 	}
 	return NULL;
 }
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/af_inet.c linux.17p18/net/ipv4/af_inet.c
--- linux.vanilla/net/ipv4/af_inet.c	Fri Apr 21 12:47:12 2000
+++ linux.17p18/net/ipv4/af_inet.c	Tue Aug  1 08:00:30 2000
@@ -118,8 +118,6 @@
 
 #define min(a,b)	((a)<(b)?(a):(b))
 
-struct linux_mib net_statistics;
-
 extern int raw_get_info(char *, char **, off_t, int, int);
 extern int snmp_get_info(char *, char **, off_t, int, int);
 extern int netstat_get_info(char *, char **, off_t, int, int);
@@ -281,7 +279,8 @@
 	struct sock *sk = sock->sk;
 	unsigned char old_state;
 
-	if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM)
+	if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM ||
+	    !((1<<sk->state)&(TCPF_CLOSE|TCPF_LISTEN)))
 		return(-EINVAL);
 
 	if ((unsigned) backlog == 0)	/* BSDism */
@@ -699,9 +698,6 @@
 	sk2->socket = newsock;
 	newsk->socket = NULL;
 
-	if (flags & O_NONBLOCK)
-		goto do_half_success;
-
 	if(sk2->state == TCP_ESTABLISHED)
 		goto do_full_success;
 	if(sk2->err > 0)
@@ -713,10 +709,6 @@
 	destroy_sock(newsk);
 	newsock->state = SS_CONNECTED;
 	return 0;
-
-do_half_success:
-	destroy_sock(newsk);
-	return(0);
 
 do_connect_err:
 	err = sock_error(sk2);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/ip_fw.c linux.17p18/net/ipv4/ip_fw.c
--- linux.vanilla/net/ipv4/ip_fw.c	Fri Apr 21 12:47:12 2000
+++ linux.17p18/net/ipv4/ip_fw.c	Tue Aug  1 08:00:30 2000
@@ -740,7 +740,7 @@
 		for (; f; f = f->next) {
 			count++;
 			if (ip_rule_match(f,rif,ip,
-					  tcpsyn,src_port,dst_port,offset)) {
+					  tcpsyn,src_port,dst_port,offset!=0)) {
 				if (!testing
 				    && !ip_fw_domatch(f, ip, rif, chain->label,
 						      skb, slot, 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/proc.c linux.17p18/net/ipv4/proc.c
--- linux.vanilla/net/ipv4/proc.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/ipv4/proc.c	Tue Aug  1 08:00:30 2000
@@ -359,8 +359,8 @@
 	len = sprintf(buffer,
 		      "TcpExt: SyncookiesSent SyncookiesRecv SyncookiesFailed"
 		      " EmbryonicRsts PruneCalled RcvPruned OfoPruned"
-		      " OutOfWindowIcmps LockDroppedIcmps\n" 	
-		      "TcpExt: %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
+		      " OutOfWindowIcmps LockDroppedIcmps SockMallocOOM\n" 	
+		      "TcpExt: %lu %lu %lu %lu %lu %lu %lu %lu %lu %lu\n",
 		      net_statistics.SyncookiesSent,
 		      net_statistics.SyncookiesRecv,
 		      net_statistics.SyncookiesFailed,
@@ -369,7 +369,8 @@
 		      net_statistics.RcvPruned,
 		      net_statistics.OfoPruned,
 		      net_statistics.OutOfWindowIcmps,
-		      net_statistics.LockDroppedIcmps);
+		      net_statistics.LockDroppedIcmps,
+		      net_statistics.SockMallocOOM);
 
 	if (offset >= len)
 	{
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/tcp.c linux.17p18/net/ipv4/tcp.c
--- linux.vanilla/net/ipv4/tcp.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/ipv4/tcp.c	Fri Aug  4 15:36:23 2000
@@ -697,32 +697,39 @@
 }
 
 /*
- *	Wait for more memory for a socket
+ *	Wait for more memory for a socket.
+ *	Special case is err == -ENOMEM, in this case just sleep a bit waiting
+ *	for the system to free up some memory. 
  */
-static void wait_for_tcp_memory(struct sock * sk)
+static void wait_for_tcp_memory(struct sock * sk, int err)
 {
-	release_sock(sk);
-	if (!tcp_memory_free(sk)) {
+	if (1) { 
 		struct wait_queue wait = { current, NULL };
-
+	
 		sk->socket->flags &= ~SO_NOSPACE;
 		add_wait_queue(sk->sleep, &wait);
+		release_sock(sk);
 		for (;;) {
 			if (signal_pending(current))
 				break;
 			current->state = TASK_INTERRUPTIBLE;
-			if (tcp_memory_free(sk))
+			if (tcp_memory_free(sk) && !err)
 				break;
 			if (sk->shutdown & SEND_SHUTDOWN)
 				break;
 			if (sk->err)
 				break;
-			schedule();
+			if (!err) 
+				schedule();
+			else {
+				schedule_timeout(net_random()%(HZ/5) + 1); 
+				break;
+			} 	
 		}
+		lock_sock(sk);
 		current->state = TASK_RUNNING;
 		remove_wait_queue(sk->sleep, &wait);
 	}
-	lock_sock(sk);
 }
 
 /*
@@ -915,12 +922,12 @@
 				tmp += copy;
 				queue_it = 0;
 			}
-			skb = sock_wmalloc(sk, tmp, 0, GFP_KERNEL);
+			skb = sock_wmalloc_err(sk, tmp, 0, GFP_KERNEL, &err);
 
 			/* If we didn't get any memory, we need to sleep. */
 			if (skb == NULL) {
 				sk->socket->flags |= SO_NOSPACE;
-				if (flags&MSG_DONTWAIT) {
+				if ((flags&MSG_DONTWAIT) && !err) {
 					err = -EAGAIN;
 					goto do_interrupted;
 				}
@@ -928,8 +935,11 @@
 					err = -ERESTARTSYS;
 					goto do_interrupted;
 				}
-				tcp_push_pending_frames(sk, tp);
-				wait_for_tcp_memory(sk);
+
+				/* In OOM that would fail anyways so do not bother. */ 
+				if (!err) 
+					tcp_push_pending_frames(sk, tp);
+				wait_for_tcp_memory(sk, err);
 
 				/* If SACK's were formed or PMTU events happened,
 				 * we must find out about it.
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/tcp_input.c linux.17p18/net/ipv4/tcp_input.c
--- linux.vanilla/net/ipv4/tcp_input.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/ipv4/tcp_input.c	Tue Aug  1 08:00:30 2000
@@ -448,9 +448,6 @@
  */
 static __inline__ int tcp_fast_parse_options(struct sock *sk, struct tcphdr *th, struct tcp_opt *tp)
 {
-	/* If we didn't send out any options ignore them all. */
-	if (tp->tcp_header_len == sizeof(struct tcphdr))
-		return 0;
 	if (th->doff == sizeof(struct tcphdr)>>2) {
 		tp->saw_tstamp = 0;
 		return 0;
@@ -780,6 +777,7 @@
 		   u32 ack_seq, u32 ack, int len)
 {
 	struct tcp_opt *tp = &(sk->tp_pinfo.af_tcp);
+	u32 nwin = ntohs(th->window) << tp->snd_wscale;
 	int flag = 0;
 	u32 seq = 0;
 	u32 seq_rtt = 0;
@@ -810,20 +808,21 @@
 	 * snd_wl{1,2} are used to prevent unordered
 	 * segments from shrinking the window 
 	 */
-	if (before(tp->snd_wl1, ack_seq) ||
-	    (tp->snd_wl1 == ack_seq && !after(tp->snd_wl2, ack))) {
-		u32 nwin = ntohs(th->window) << tp->snd_wscale;
-
-		if ((tp->snd_wl2 != ack) || (nwin > tp->snd_wnd)) {
-			flag |= FLAG_WIN_UPDATE;
-			tp->snd_wnd = nwin;
-
-			tp->snd_wl1 = ack_seq;
-			tp->snd_wl2 = ack;
-
-			if (nwin > tp->max_window)
-				tp->max_window = nwin;
-		}
+	if (after(ack_seq, tp->snd_wl1) ||
+	    (tp->snd_wl1 == ack_seq &&
+	     (after(ack, tp->snd_wl2) ||
+	      (tp->snd_wl2 == ack && nwin > tp->snd_wnd)))) {
+		flag |= FLAG_WIN_UPDATE;
+		tp->snd_wl1 = ack_seq;
+		tp->snd_wl2 = ack;
+		tp->snd_wnd = nwin;
+
+		if (nwin > tp->max_window)
+			tp->max_window = nwin;
+	} else if (after(ack, tp->snd_una)) {
+		/* Bad case. Window update is not accepted.
+		 * We will lockup. Break RFC to survive. */
+		tp->snd_wnd -= min(ack-tp->snd_una, tp->snd_wnd);
 	}
 
 	/* We passed data and got it acked, remove any soft error
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/tcp_ipv4.c linux.17p18/net/ipv4/tcp_ipv4.c
--- linux.vanilla/net/ipv4/tcp_ipv4.c	Fri Apr 21 12:47:15 2000
+++ linux.17p18/net/ipv4/tcp_ipv4.c	Tue Aug  1 08:00:30 2000
@@ -327,6 +327,11 @@
 {
 	struct sock **skp;
 
+	if (sk->pprev) {
+		printk("tcp_v4_hash: bug, socket state is %d\n", sk->state);
+		*(int *)0 = 0;
+	}
+
 	if(sk->state == TCP_LISTEN)
 		skp = &tcp_listening_hash[tcp_sk_listen_hashfn(sk)];
 	else
@@ -356,7 +361,8 @@
 		*sk->pprev = sk->next;
 		sk->pprev = NULL;
 		tcp_reg_zap(sk);
-		__tcp_put_port(sk);
+		if (sk->prev != NULL)
+			__tcp_put_port(sk);
 	}
 	SOCKHASH_UNLOCK();
 }
@@ -1041,8 +1047,8 @@
 	rth.source = th->dest; 
 	rth.doff = sizeof(struct tcphdr)/4;
 
-	rth.seq = seq;
-	rth.ack_seq = ack; 
+	rth.seq = htonl(seq);
+	rth.ack_seq = htonl(ack); 
 	rth.ack = 1;
 
 	rth.window = htons(window);
@@ -1365,6 +1371,8 @@
 
 		memcpy(newsk, sk, sizeof(*newsk));
 		newsk->sklist_next = NULL;
+		newsk->next = NULL;
+		newsk->pprev = NULL;
 		newsk->state = TCP_SYN_RECV;
 
 		/* Clone the TCP header template */
@@ -1570,24 +1578,28 @@
 	return NULL;
 }
 
-static void tcp_v4_rst_req(struct sock *sk, struct sk_buff *skb)
+static struct sock *tcp_v4_rst_req(struct sock *sk, struct sk_buff *skb)
 {
 	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
 	struct open_request *req, *prev;
 
 	req = tcp_v4_search_req(tp,skb->nh.iph, skb->h.th, &prev);
 	if (!req)
-		return;
+		return NULL;
 	/* Sequence number check required by RFC793 */
 	if (before(TCP_SKB_CB(skb)->seq, req->rcv_isn) ||
 	    after(TCP_SKB_CB(skb)->seq, req->rcv_isn+1))
-		return;
+		return NULL;
+	if (req->sk)
+		return req->sk;
+
 	tcp_synq_unlink(tp, req, prev);
-	(req->sk ? sk->ack_backlog : tp->syn_backlog)--;
+	tp->syn_backlog--;
 	req->class->destructor(req);
 	tcp_openreq_free(req); 
 
 	net_statistics.EmbryonicRsts++;
+	return NULL;
 }
 
 /* Check for embryonic sockets (open_requests) We check packets with
@@ -1601,10 +1613,8 @@
 	u32 flg = ((u32 *)th)[3]; 
 
 	/* Check for RST */
-	if (flg & __constant_htonl(0x00040000)) {
-		tcp_v4_rst_req(sk, skb);
-		return NULL;
-	}
+	if (flg & __constant_htonl(0x00040000))
+		return tcp_v4_rst_req(sk, skb);
 
 	/* Check for SYN|ACK */
 	if (flg & __constant_htonl(0x00120000)) {
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/ipv4/tcp_output.c linux.17p18/net/ipv4/tcp_output.c
--- linux.vanilla/net/ipv4/tcp_output.c	Sun Jun 11 21:44:23 2000
+++ linux.17p18/net/ipv4/tcp_output.c	Tue Aug  1 08:00:30 2000
@@ -63,6 +63,31 @@
 		tp->send_head = NULL;
 }
 
+static __inline__ u32 tcp_acceptable_seq(struct sock *sk)
+{
+	struct tcp_opt *tp = &sk->tp_pinfo.af_tcp;
+	struct sk_buff *skb;
+	u32 snd_nxt;
+
+	if (!before(tp->snd_una+tp->snd_wnd, tp->snd_nxt))
+		return tp->snd_nxt;
+
+	/* Umm... No better choice. The case is marginal, no hurry. */
+	skb = skb_peek(&sk->write_queue);
+
+	snd_nxt = tp->snd_una;
+	while((skb != NULL) &&
+	      (skb != tp->send_head) &&
+	      (skb != (struct sk_buff *)&sk->write_queue)) {
+		if (after(TCP_SKB_CB(skb)->end_seq, tp->snd_una+tp->snd_wnd))
+			break;
+		snd_nxt = TCP_SKB_CB(skb)->end_seq;
+		skb = skb->next;
+	}
+
+	return snd_nxt;
+}
+
 /* This routine actually transmits TCP packets queued in by
  * tcp_do_sendmsg().  This is used by both the initial
  * transmission and possible later retransmissions.
@@ -802,7 +827,7 @@
 	TCP_SKB_CB(skb)->urg_ptr = 0;
 
 	/* Send it off. */
-	TCP_SKB_CB(skb)->seq = tp->write_seq;
+	TCP_SKB_CB(skb)->seq = tcp_acceptable_seq(sk);
 	TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
 	TCP_SKB_CB(skb)->when = tcp_time_stamp;
 	tcp_transmit_skb(sk, skb);
@@ -1066,7 +1091,7 @@
 		TCP_SKB_CB(buff)->urg_ptr = 0;
 
 		/* Send it off, this clears delayed acks for us. */
-		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tp->snd_nxt;
+		TCP_SKB_CB(buff)->seq = TCP_SKB_CB(buff)->end_seq = tcp_acceptable_seq(sk);
 		TCP_SKB_CB(buff)->when = tcp_time_stamp;
 		tcp_transmit_skb(sk, buff);
 	}
@@ -1091,15 +1116,15 @@
 		      TCPF_LAST_ACK|TCPF_CLOSING))
 			return;
 
-		if (before(tp->snd_nxt, tp->snd_una + tp->snd_wnd) &&
-		    ((skb = tp->send_head) != NULL)) {
+		if ((skb = tp->send_head) != NULL &&
+		    before(TCP_SKB_CB(skb)->seq, tp->snd_una+tp->snd_wnd)) {
 			unsigned long win_size;
 
 			/* We are probing the opening of a window
 			 * but the window size is != 0
 			 * must have been a result SWS avoidance ( sender )
 			 */
-			win_size = tp->snd_wnd - (tp->snd_nxt - tp->snd_una);
+			win_size = tp->snd_una+tp->snd_wnd - TCP_SKB_CB(skb)->seq;
 			if (win_size < TCP_SKB_CB(skb)->end_seq - TCP_SKB_CB(skb)->seq) {
 				if (tcp_fragment(sk, skb, win_size))
 					return; /* Let a retransmit get it. */
@@ -1129,7 +1154,7 @@
 			 * end to send an ack.  Don't queue or clone SKB, just
 			 * send it.
 			 */
-			TCP_SKB_CB(skb)->seq = tp->snd_nxt - 1;
+			TCP_SKB_CB(skb)->seq = tp->snd_una - 1;
 			TCP_SKB_CB(skb)->end_seq = TCP_SKB_CB(skb)->seq;
 			TCP_SKB_CB(skb)->when = tcp_time_stamp;
 			tcp_transmit_skb(sk, skb);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/irda/af_irda.c linux.17p18/net/irda/af_irda.c
--- linux.vanilla/net/irda/af_irda.c	Sun Jun 11 21:44:24 2000
+++ linux.17p18/net/irda/af_irda.c	Wed Aug 16 22:13:49 2000
@@ -8,7 +8,7 @@
  * Created at:    Sun May 31 10:12:43 1998
  * Modified at:   Tue Apr 11 19:06:24 2000
  * Modified by:   Dag Brattli <dagb@cs.uit.no>
- * Sources:       af_netroom.c, af_ax25.c, af_rose.c, af_x25.c etc.
+ * Sources:       af_netrom.c, af_ax25.c, af_rose.c, af_x25.c etc.
  * 
  *     Copyright (c) 1999-2000 Dag Brattli <dagb@cs.uit.no>
  *     Copyright (c) 1999 Jean Tourrilhes <jeant@rockfort.hpl.hp.com>
@@ -1073,7 +1073,7 @@
 
         sock->sk   = NULL;      
         sk->socket = NULL;      /* Not used, but we should do this. */
-
+	sk->protinfo.irda = NULL;
         return 0;
 }
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/irda/irda_device.c linux.17p18/net/irda/irda_device.c
--- linux.vanilla/net/irda/irda_device.c	Fri Apr 21 12:47:16 2000
+++ linux.17p18/net/irda/irda_device.c	Tue Aug  1 08:00:31 2000
@@ -63,6 +63,8 @@
 extern int tekram_init(void);
 extern int actisys_init(void);
 extern int girbil_init(void);
+extern int toshoboe_init(void);
+extern int litelink_init(void);
 
 static void __irda_task_delete(struct irda_task *task);
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/irda/irmod.c linux.17p18/net/irda/irmod.c
--- linux.vanilla/net/irda/irmod.c	Fri Apr 21 12:47:16 2000
+++ linux.17p18/net/irda/irmod.c	Tue Aug  1 08:00:31 2000
@@ -73,7 +73,7 @@
 
 #ifdef CONFIG_IRDA_COMPRESSION
 #ifdef CONFIG_IRDA_DEFLATE
-extern irda_deflate_init();
+extern irda_deflate_init(void);
 #endif /* CONFIG_IRDA_DEFLATE */
 #endif /* CONFIG_IRDA_COMPRESSION */
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/irda/irttp.c linux.17p18/net/irda/irttp.c
--- linux.vanilla/net/irda/irttp.c	Fri Apr 21 12:47:16 2000
+++ linux.17p18/net/irda/irttp.c	Tue Aug  1 08:00:31 2000
@@ -1528,9 +1528,9 @@
 			       self->remote_credit);
 		len += sprintf(buf+len, "send credit: %d\n",
 			       self->send_credit);
-		len += sprintf(buf+len, "  tx packets: %d, ",
+		len += sprintf(buf+len, "  tx packets: %ld, ",
 			       self->stats.tx_packets);
-		len += sprintf(buf+len, "rx packets: %d, ",
+		len += sprintf(buf+len, "rx packets: %ld, ",
 			       self->stats.rx_packets);
 		len += sprintf(buf+len, "tx_queue len: %d ", 
 			       skb_queue_len(&self->tx_queue));
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/irda/parameters.c linux.17p18/net/irda/parameters.c
--- linux.vanilla/net/irda/parameters.c	Fri Apr 21 12:47:16 2000
+++ linux.17p18/net/irda/parameters.c	Wed Aug 16 22:14:57 2000
@@ -513,10 +513,7 @@
 		      buf[0]);
 		
 		/* Skip this parameter */
-		n += (2 + buf[n+1]);
-		len -= (2 + buf[n+1]);
-
-		return 0;  /* Continue */
+		return 2 + buf[n + 1];  /* Continue */
 	}
 
 	/* Lookup the info on how to parse this parameter */
@@ -532,10 +529,7 @@
 	if (!pi_minor_info->func) {
 		MESSAGE(__FUNCTION__"(), no handler for pi=%#x\n", buf[n]);
 		/* Skip this parameter */
-		n += (2 + buf[n+1]);
-		len -= (2 + buf[n+1]);
-
-		return 0; /* Continue */
+		return 2 + buf[n + 1]; /* Continue */
 	}
 
 	/* Parse parameter value */
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/net/sunrpc/sched.c linux.17p18/net/sunrpc/sched.c
--- linux.vanilla/net/sunrpc/sched.c	Fri Apr 21 12:47:17 2000
+++ linux.17p18/net/sunrpc/sched.c	Wed Aug 16 21:36:36 2000
@@ -445,16 +445,16 @@
 			if (current->pid == rpciod_pid)
 				printk(KERN_ERR "RPC: rpciod waiting on sync task!\n");
 
-			sti();
 			__wait_event(task->tk_wait, RPC_IS_RUNNING(task));
-			cli();
 
 			/*
 			 * When the task received a signal, remove from
 			 * any queues etc, and make runnable again.
 			 */
-			if (signalled())
+			if (signalled()) { 
+				cli(); 
 				__rpc_wake_up(task);
+			}
 
 			dprintk("RPC: %4d sync task resuming\n",
 							task->tk_pid);
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/scripts/Configure linux.17p18/scripts/Configure
--- linux.vanilla/scripts/Configure	Sun Jun 11 21:44:24 2000
+++ linux.17p18/scripts/Configure	Tue Aug  1 08:00:32 2000
@@ -542,7 +542,7 @@
   echo "# Using defaults found in" $DEFAULTS
   echo "#"
   . $DEFAULTS
-  sed -e 's/# \(.*\) is not.*/\1=n/' < $DEFAULTS > .config-is-not.$$
+  sed -e 's/# \(CONFIG_[^ ]*\) is not.*/\1=n/' <$DEFAULTS >.config-is-not.$$
   . .config-is-not.$$
   rm .config-is-not.$$
 else
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/scripts/Menuconfig linux.17p18/scripts/Menuconfig
--- linux.vanilla/scripts/Menuconfig	Sun Jun 11 21:44:24 2000
+++ linux.17p18/scripts/Menuconfig	Tue Aug  1 08:00:32 2000
@@ -425,7 +425,7 @@
 			--menu '$menu_instructions' \
 			$ROWS $COLS $((ROWS-10)) \
 			'$default' " >MCmenu
-	>MCradiolists
+	echo "#!/bin/sh" >MCradiolists
 }
 
 #
@@ -713,11 +713,11 @@
 			++menu_no
 
 			printf("submenu %s MCmenu%s\n", $0, menu_no) >>menu
-
-			printf( "function MCmenu%s () {\n"\
+			printf( "#!/bin/sh\n"\
+				"function MCmenu%s () {\n"\
 				"default=$1\n"\
 				"menu_name %s\n",\
-				 menu_no, $0) >"MCmenu"menu_no
+				 menu_no, $0) >>"MCmenu"menu_no
 
 			parser(ifile, "MCmenu"menu_no)
 		}
@@ -772,7 +772,8 @@
 function parse_config_files () {
 	rm -f MCmenu*
 
-	echo "function MCmenu0 () {" >MCmenu0
+	echo "#!/bin/sh" > MCmenu0
+	echo "function MCmenu0 () {" >>MCmenu0
 	echo 'default=$1' >>MCmenu0
 	echo "menu_name 'Main Menu'" >>MCmenu0
 
diff -u --new-file --recursive --exclude-from ../../exclude linux.vanilla/scripts/makelst linux.17p18/scripts/makelst
--- linux.vanilla/scripts/makelst	Thu Jan  1 01:00:00 1970
+++ linux.17p18/scripts/makelst	Tue Aug  1 08:00:32 2000
@@ -0,0 +1,21 @@
+#!/bin/bash
+# A script to dump mixed source code & assembly
+# with correct relocations from System.map
+# Requires the following lines in Rules.make.
+#
+#%.lst: %.c
+#	$(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -g -c -o $*.o $<
+#	$(TOPDIR)/scripts/makelst $* $(TOPDIR) $(OBJDUMP)
+#
+#    Copyright (C) 2000 IBM Corporation
+#    Author(s): DJ Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) 
+#
+
+t1=`$3 --syms $2/$1.o | grep .text | grep " F " | head -n 1`
+t2=`echo $t1 | gawk '{ print $6 }'`
+t3=`grep $t2 $2/System.map`
+t4=`echo $t3 | gawk '{ print $1 }'`
+t5=`echo $t1 | gawk '{ print $1 }'`
+t6=`echo $t4 - $t5 | sed s/a/A/g | sed s/b/B/g | sed s/c/C/g | sed s/d/D/g | sed s/e/E/g | sed s/f/F/g`
+t7=`( echo  ibase=16 ; echo $t6 ) | bc`
+$3 --source --adjust-vma=$t7 $2/$1.o > $2/$1.lst
