## Automatically generated incremental diff
## From:   linux-2.4.23-pre6
## To:     linux-2.4.23-pre7
## Robot:  $Id: make-incremental-diff,v 1.11 2002/02/20 02:59:33 hpa Exp $

diff -urN linux-2.4.23-pre6/CREDITS linux-2.4.23-pre7/CREDITS
--- linux-2.4.23-pre6/CREDITS	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/CREDITS	2003-10-09 17:48:21.000000000 -0700
@@ -2719,7 +2719,7 @@
 D: Dosemu
 
 N: Duncan Sands
-E: duncan.sands@wanadoo.fr
+E: duncan.sands@free.fr
 W: http://topo.math.u-psud.fr/~sands
 D: Alcatel SpeedTouch USB driver
 S: 69 rue Dunois
@@ -2976,7 +2976,7 @@
 
 N: Marcelo W. Tosatti
 E: marcelo@parcelfarce.linux.theplanet.co.uk
-E: marcelo.tosatti@cyclades.com.br
+E: marcelo.tosatti@cyclades.com
 D: Miscellaneous kernel hacker (mostly VM/MM work)
 D: 2.4 maintainer
 S: Av Cristovao Colombo, 462. Floresta.
diff -urN linux-2.4.23-pre6/Documentation/Configure.help linux-2.4.23-pre7/Documentation/Configure.help
--- linux-2.4.23-pre6/Documentation/Configure.help	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/Configure.help	2003-10-09 17:48:21.000000000 -0700
@@ -100,6 +100,15 @@
   like MGA monitors that you are very unlikely to see on today's
   systems.
 
+Prompt for advanced kernel configuration options
+CONFIG_ADVANCED_OPTIONS
+  This option will enable prompting for a variety of advanced kernel
+  configuration options.  These options can cause the kernel to not
+  work if they are set incorrectly, but can be used to optimize certain
+  aspects of kernel memory management.
+
+  Unless you know what you are doing you *should not* enable this option.
+
 Symmetric Multi-Processing support
 CONFIG_SMP
   This enables support for systems with more than one CPU. If you have
@@ -9049,16 +9058,31 @@
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called AM53C974.o.
 
-AMI MegaRAID support
+AMI MegaRAID support (old driver)
 CONFIG_SCSI_MEGARAID
-  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490
-  and 467 SCSI host adapters.
+  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490,
+  467, 471 and 493 SCSI host adapters. 
+
+  This is the old and very heavily tested driver but lacks features
+  like clustering.
 
   If you want to compile this driver as a module ( = code which can be
   inserted in and removed from the running kernel whenever you want),
   say M here and read <file:Documentation/modules.txt>.  The module
   will be called megaraid.o.
 
+AMI MegaRAID support (new driver)
+CONFIG_SCSI_MEGARAID2
+  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490,
+  467, 471, 493 and new Ultra320(518, 520, 531, 532) SCSI host adapters.
+
+  This is the newer less tested but more featureful driver.
+
+  If you want to compile this driver as a module ( = code which can be
+  inserted in and removed from the running kernel whenever you want),
+  say M here and read <file:Documentation/modules.txt>.  The module
+  will be called megaraid2.o.
+
 Intel/ICP (former GDT SCSI Disk Array) RAID Controller support
 CONFIG_SCSI_GDTH
   Formerly called GDT SCSI Disk Array Controller Support.
@@ -10881,6 +10905,26 @@
   The module will be called dscc4.o. For general information about
   modules read <file:Documentation/modules.txt>.
 
+PCISYNC feature
+CONFIG_DSCC4_PCISYNC
+  Due to Etinc's design choice for its PCISYNC cards, some operations
+  are only allowed on specific ports of the DSCC4. This option is the
+  only way for the driver to know that it shouldn't return a success
+  code for these operations.
+
+  Please say Y if your card is an Etinc's PCISYNC.
+
+Hard reset support
+CONFIG_DSCC4_PCI_RST
+  Various DSCC4 bug forbid any reliable software reset of the asic.
+  As a replacement, some vendors provide a way to assert the PCI #RST
+  pin of DSCC4 through the GPIO port of the card. If you choose Y, the
+  driver will make use of this feature before module removal (i.e. rmmod).
+  This feature is known to exist on Commtech's cards.
+  Contact your manufacturer for details.
+
+  Say Y if yout card supports this feature.
+
 LanMedia Corp. serial boards (SSI/V.35, T1/E1, HSSI, T3)
 CONFIG_LANMEDIA
   This is a driver for the following Lan Media family of serial
@@ -14676,8 +14720,8 @@
 USB HIDBP Mouse (basic) support
 CONFIG_USB_MOUSE
   Say Y here only if you are absolutely sure that you don't want
-  to use the generic HID driver for your USB keyboard and prefer
-  to use the keyboard in its limited Boot Protocol mode instead.
+  to use the generic HID driver for your USB mouse and prefer
+  to use the mouse in its limited Boot Protocol mode instead.
 
   This is almost certainly not what you want.
 
@@ -15037,6 +15081,9 @@
 CONFIG_USB_SERIAL_KEYSPAN_USA49W
   Say Y here to include firmware for the USA-49W converter.
 
+CONFIG_USB_SERIAL_KEYSPAN_USA49WLC
+  Say Y here to include firmware for the USA-49WLC converter.
+
 USB ZyXEL omni.net LCD Plus Driver
 CONFIG_USB_SERIAL_OMNINET
   Say Y here if you want to use a ZyXEL omni.net LCD ISDN TA.
@@ -20134,6 +20181,15 @@
   <file:Documentation/modules.txt>. The module will be called
   cpuid.o
 
+x86 BIOS Enhanced Disk Drive support
+CONFIG_EDD
+  Say Y or M here if you want to enable BIOS Enhanced Disk Drive
+  Services real mode BIOS calls to determine which disk
+  BIOS tries boot from.  This information is then exported via /proc.
+
+  This option is experimental, but believed to be safe,
+  and most disk controller BIOS vendors do not yet implement this feature.
+
 SBC-60XX Watchdog Timer
 CONFIG_60XX_WDT
  This driver can be used with the watchdog timer found on some
@@ -24047,6 +24103,38 @@
       /proc/sys/dev/mac_hid/mouse_button2_keycode
       /proc/sys/dev/mac_hid/mouse_button3_keycode
 
+Set high memory pool address
+CONFIG_HIGHMEM_START_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the default PKMAP_BASE address which
+  is the location of the high memory pool.  This can be useful in
+  optimizing virtual memory usage in a system.
+
+Set maximum low memory
+CONFIG_LOWMEM_SIZE_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the standard calculated value of
+  MAX_LOW_MEM. This can be useful in optimizing virtual memory usage
+  in a system.
+
+Set custom kernel base address
+CONFIG_KERNEL_START_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the standard PAGE_OFFSET/KERNELBASE
+  value used by the kernel.  This can be useful in controlling
+  amount of virtual address space available to the kernel.
+
+Set custom user task size
+CONFIG_TASK_SIZE_BOOL
+  Unless you know what you are doing you *should not* set this option.
+
+  It can be used to override the standard TASK_SIZE value used
+  by the kernel.  This can be useful in controlling amount of
+  virtual address space available to user tasks.
+
 Enhanced Real Time Clock Support (/dev/rtc)
 CONFIG_PPC_RTC
   If you say Y here and create a character special file /dev/rtc with
@@ -27104,6 +27192,58 @@
   To use this option, you have to check that the "/proc file system
   support" (CONFIG_PROC_FS) is enabled, too.
 
+PPC4xx DMA controller support
+CONFIG_PPC4xx_DMA
+  Select this to enable support for the PPC4xx general purpose DMA
+  controller.
+
+ttyS0 device
+CONFIG_UART0_TTYS0
+  This option reverses the mapping between the hardware UART and software
+  device.  Selecting UART0 gives the normal mapping of UART0=ttyS0 and
+  UART1=ttyS1.  Selecting UART1 gives the reverse mapping of UART0=ttyS1
+  and UART1=ttyS0.  Most people will use UART0.
+
+PowerPC 405 on-chip ethernet
+CONFIG_IBM_OCP_ENET
+  If you want to use the 405 built-in ethernet select this.
+
+CONFIG_IBM_OCP_ENET_ERROR_MSG
+  Enable this option to print verbose debug messages for troubleshooting.
+
+PowerPC 405 on-chip ethernet -- Number of receive buffers
+CONFIG_IBM_OCP_ENET_RX_BUFF
+  Number of ethernet receive (read) buffers.  Unless you know what you
+  are doing the default should be fine.
+
+PowerPC 405 on-chip ethernet -- Number of transmit buffers
+CONFIG_IBM_OCP_ENET_TX_BUFF
+  Number of ethernet transmit (write) buffers.  Unless you know what
+  you are doing the default should be fine.
+
+PowerPC 405 on-chip ethernet -- Amount of bytes to Reserve on a skb
+CONFIG_IBM_OCP_ENET_SKB_RES
+  Many standard ethernet drivers need to reserve 2 bytes of data
+  on the skb before giving the data ptr to the hardware. This is
+  so the IP data will be 16-byte aligned when it goes up the stack.
+  This is a requirement for some processors and it can cause major
+  slow downs on others. The 405GP dose not have problems with the 
+  misaligned data so the default is 0. If you need to route the
+  incoming ethernet packets to another device that has alignment
+  requirements this can help remove a data copy. A value of 2 can
+  help at getting 16-byte aligned IP data for another device. A
+  larger value can be used when routing to a IP tunnel device.
+  Make sure XXX_DESC_SIZE - XXX_SKB_RES >= 1514, or larger if VLANS
+  are used.
+
+PPC 405 I2C Algorithm
+CONFIG_PPC405_I2C_ALGO
+  Enable this option to use the built-in I2C on your 405.
+
+PPC 405 I2C Adapter
+CONFIG_PPC405_I2C_ADAP
+  Enable this option to use the built-in I2C on your 405.
+
 /proc/efi/vars support
 CONFIG_EFI_VARS
   If you say Y here, you are able to get EFI (Extensible Firmware
diff -urN linux-2.4.23-pre6/Documentation/README.nsp32_cb.eng linux-2.4.23-pre7/Documentation/README.nsp32_cb.eng
--- linux-2.4.23-pre6/Documentation/README.nsp32_cb.eng	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/Documentation/README.nsp32_cb.eng	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,57 @@
+	<<NinjaSCSI-32Bi/UDE CardBus/PCI card driver for Linux>>
+
+
+1. What's this?
+
+ This is Workbit corp.'s(http://www.workbit.co.jp/) NinjaSCSI-32Bi
+(http://www.workbit.co.jp/ts/z_njsc32bi.html) PCMCIA card and NinjaSCSI-32UDE
+PCI card driver module for Linux.
+
+
+
+2. Install
+
+[1] This driver requires Kernel 2.4.x/2.6.x or later.
+    And you want to load the module when Ninja card was inserted, you also
+    install "hotplug" (http://linux-hotplug.sourceforge.net/) utility.
+
+[2] Insert Ninja card to your PC, and check your card is NinjaSCSI-32Bi/UDE
+    card.
+
+# lspci
+....
+01:00.0 SCSI storage controller: I-O Data Device, Inc. CBSC-II duo SCSI PCMCIA card (rev 01)
+
+[3] This driver requires Kernel 2.4/2.6's source code. Please install cernel
+    source code.
+
+[4] Please check your kernel have PCI, CardBus, PCMCIA and SCSI support.
+    If not, rebuild your kernel. And also requires PCMCIA-CS if you use
+    CardBus card.
+
+[5] Extract this archive somewhere.
+
+[6] Edit "Makefile" and type "make" to compile the driver.
+
+[7] Copy "nsp32.o" to /lib/modules/<kernel version>/kernel/driver/scsi/pcmcia/ .
+
+[8] Type "depmod -ae" to re-made "/lib/modules/<kernel version>/modules.pcimap"
+
+[9] Ok. Now you can use Ninja card in CardBus mode. Check your Ninja card is in
+    CardBus mode, and insert the card to PC card slot.
+
+
+
+3. Caution
+ If you eject card when doing some operation for your SCSI device or suspend
+your computer, you encount some *BAD* error like disk crash.
+ It works good when I using this driver right way. But I'm not guarantee
+your data. Please backup your data when you use this driver.
+
+
+4. Copyright.
+
+ No, no, this is Copyleft software. See GPL.
+
+
+YOKOTA Hiroshi
diff -urN linux-2.4.23-pre6/Documentation/README.nsp_cs.eng linux-2.4.23-pre7/Documentation/README.nsp_cs.eng
--- linux-2.4.23-pre6/Documentation/README.nsp_cs.eng	2001-10-11 11:17:22.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/README.nsp_cs.eng	2003-10-09 17:48:21.000000000 -0700
@@ -8,8 +8,8 @@
 for Linux.
 
 2. My Linux environment
-Linux kernel: 2.4.7 / 2.2.19
-pcmcia-cs:    3.1.27
+Linux kernel: 2.4.20 / 2.5.63
+pcmcia-cs:    3.1.33
 gcc:          gcc-2.95.4
 PC card:      I-O data PCSC-F (NinjaSCSI-3)
               I-O data CBSC-II in 16 bit mode (NinjaSCSI-32Bi)
@@ -46,22 +46,16 @@
 $ make config
 ...
 
-[3] If you use this driver with Kernel 2.2, Unpack pcmcia-cs in some directory
-    and make & install. This driver requies pcmcia-cs header file.
-$ cd /usr/src
-$ tar zxvf cs-pcmcia-cs-3.x.x.tar.gz
-...
-
-[4] Extract this driver's archive somewhere, and edit Makefile, then do make.
+[3] Extract this driver's archive somewhere, and edit Makefile, then do make.
 $ tar -zxvf nsp_cs-x.x.tar.gz
 $ cd nsp_cs-x.x
 $ emacs Makefile
 ...
 $ make
 
-[5] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
+[4] Copy nsp_cs.o to suitable plase, like /lib/modules/<Kernel version>/pcmcia/ .
 
-[6] Add these lines to /etc/pcmcia/config .
+[5] Add these lines to /etc/pcmcia/config .
     If you yse pcmcia-cs-3.1.8 or later, we can use "nsp_cs.conf" file.
     So, you don't need to edit file. Just copy to /etc/pcmcia/ .
 
@@ -97,7 +91,7 @@
   bind "nsp_cs"
 -------------------------------------
 
-[7] Start (or restart) pcmcia-cs.
+[6] Start (or restart) pcmcia-cs.
 # /etc/rc.d/rc.pcmcia start        (BSD style)
 or
 # /etc/init.d/pcmcia start         (SYSV style)
@@ -113,8 +107,7 @@
 your data. Please backup your data when you use this driver.
 
 6. Known Bugs
- In 2.4 kernel, you can't use 640MB Optical disk. This error comes from
-high level SCSI driver.
+ Many bugs in this driver. Be careful!
 
 7. Testing
  Please send me some reports(bug reports etc..) of this software.
@@ -127,4 +120,4 @@
  See GPL.
 
 
-2001/08/08 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
+2002/01/17 yokota@netlab.is.tsukuba.ac.jp <YOKOTA Hiroshi>
diff -urN linux-2.4.23-pre6/Documentation/SubmittingDrivers linux-2.4.23-pre7/Documentation/SubmittingDrivers
--- linux-2.4.23-pre6/Documentation/SubmittingDrivers	2002-11-28 15:53:08.000000000 -0800
+++ linux-2.4.23-pre7/Documentation/SubmittingDrivers	2003-10-09 17:48:21.000000000 -0700
@@ -35,12 +35,12 @@
 
 Linux 2.4:
 	The same rules apply as 2.2. The final contact point for Linux 2.4 
-	submissions is Marcelo Tosatti <marcelo@conectiva.com.br>.
+	submissions is Marcelo Tosatti <marcelo@cyclades.com>.
 
 Linux 2.5:
 	The same rules apply as 2.4 except that you should follow linux-kernel
 	to track changes in API's. The final contact point for Linux 2.5
-	submissions is Linus Torvalds <torvalds@transmeta.com>.
+	submissions is Linus Torvalds <torvalds@osdl.org>.
 
 What Criteria Determine Acceptance
 ----------------------------------
diff -urN linux-2.4.23-pre6/Documentation/cciss.txt linux-2.4.23-pre7/Documentation/cciss.txt
--- linux-2.4.23-pre6/Documentation/cciss.txt	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/cciss.txt	2003-10-09 17:48:21.000000000 -0700
@@ -13,6 +13,7 @@
 	* SA 642
 	* SA 6400
 	* SA 6400 U320 Expansion Module
+	* SA 6i
 
 If nodes are not already created in the /dev/cciss directory
 
diff -urN linux-2.4.23-pre6/Documentation/i386/zero-page.txt linux-2.4.23-pre7/Documentation/i386/zero-page.txt
--- linux-2.4.23-pre6/Documentation/i386/zero-page.txt	1999-08-30 10:47:02.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/i386/zero-page.txt	2003-10-09 17:48:21.000000000 -0700
@@ -31,6 +31,7 @@
 
 0x1e0	unsigned long	ALT_MEM_K, alternative mem check, in Kb
 0x1e8	char		number of entries in E820MAP (below)
+0x1e9	unsigned char	number of entries in EDDBUF (below)
 0x1f1	char		size of setup.S, number of sectors
 0x1f2	unsigned short	MOUNT_ROOT_RDONLY (if !=0)
 0x1f4	unsigned short	size of compressed kernel-part in the
@@ -66,6 +67,7 @@
 0x220	4 bytes		(setup.S)
 0x224	unsigned short	setup.S heap end pointer
 0x2d0 - 0x600		E820MAP
+0x600 - 0x7D4		EDDBUF (setup.S)
 
 0x800	string, 2K max	COMMAND_LINE, the kernel commandline as
 			copied using CL_OFFSET.
diff -urN linux-2.4.23-pre6/Documentation/ioctl-number.txt linux-2.4.23-pre7/Documentation/ioctl-number.txt
--- linux-2.4.23-pre6/Documentation/ioctl-number.txt	2001-07-11 16:35:37.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/ioctl-number.txt	2003-10-09 17:48:21.000000000 -0700
@@ -171,10 +171,6 @@
 					<mailto:buk@buks.ipn.de>
 0xA0	all	linux/sdp/sdp.h		Industrial Device Project
 					<mailto:kenji@bitgate.com>
-0xA2    00-0F   DVD decoder driver      in development:
-                                        <http://linuxtv.org/dvd/api/>
-0xA3	00-1F	Philips SAA7146 dirver	in development:
-					<mailto:Andreas.Beckmann@hamburg.sc.philips.com>
 0xA3	80-8F	Port ACL		in development:
 					<mailto:tlewis@mindspring.com>
 0xA3	90-9F	linux/dtlk.h
diff -urN linux-2.4.23-pre6/Documentation/laptop-mode.txt linux-2.4.23-pre7/Documentation/laptop-mode.txt
--- linux-2.4.23-pre6/Documentation/laptop-mode.txt	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/Documentation/laptop-mode.txt	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,72 @@
+Laptop mode
+===========
+
+This small doc describes the 2.4 laptop mode patch.
+
+Last updated 2003-05-25, Jens Axboe <axboe@suse.de>
+
+Introduction
+------------
+
+A few properties of the Linux vm makes it virtually impossible to attempt
+to spin down the hard drive in a laptop for a longer period of time (more
+than a handful of seconds). This means you are lucky if you can even reach
+the break even point with regards to power consumption, let alone expect any
+decrease.
+
+One problem is the age time of dirty buffers. Linux uses 30 seconds per
+default, so if you dirty any data then flusing of that data will commence
+at most 30 seconds from then. Another is the journal commit interval of
+journalled file systems such as ext3, which is 5 seconds on a stock kernel.
+Both of these are tweakable either from proc/sysctl or as mount options
+though, and thus partly solvable from user space.
+
+The kernel update daemon (kupdated) also runs at specific intervals, flushing
+old dirty data out. Default is every 5 seconds, this too can be tweaked
+from sysctl.
+
+So what does the laptop mode patch do? It attempts to fully utilize the
+hard drive once it has been spun up, flushing the old dirty data out to
+disk. Instead of flushing just the expired data, it will clean everything.
+When a read causes the disk to spin up, we kick off this flushing after
+a few seconds. This means that once the disk spins down again, everything
+is up to date. That allows longer dirty data and journal expire times.
+
+It follows that you have to set long expire times to get long spin downs.
+This means you could potentially loose 10 minutes worth of data, if you
+set a 10 minute expire count instead of just 30 seconds worth. The biggest
+risk here is undoubtedly running out of battery.
+
+Settings
+--------
+
+The main knob is /proc/sys/vm/laptop_mode. Setting that to 1 switches the
+vm (and block layer) to laptop mode. Leaving it to 0 makes the kernel work
+like before. When in laptop mode, you also want to extend the intervals
+desribed above. See the laptop-mode.sh script for how to do that.
+
+It can happen that the disk still keeps spinning up and you don't quite
+know why or what causes it. The laptop mode patch has a little helper for
+that as well, /proc/sys/vm/block_dump. When set to 1, it will dump info to
+the kernel message buffer about what process caused the io. Be very careful
+when playing with this setting, it is advisable to shut down syslog first!
+
+Result
+------
+
+Using the laptop-mode.sh script with its default settings, I get the full
+10 minutes worth of drive spin down. Provided your work load is cached,
+the disk will only spin up every 10 minutes (well actually, 9 minutes and 55
+seconds due to the 5 second delay in flushing dirty data after the last read
+completes). I can't tell you exactly how much extra battery life you will
+gain in laptop mode, it will vary greatly on the laptop and workload in
+question. The only way to know for sure is to try it out. Getting 10% extra
+battery life is not unrealistic.
+
+Notes
+-----
+
+Patch only changes journal expire time for ext3. reiserfs uses a hardwire
+value, should be trivial to adapt though (basically just make it call
+get_buffer_flushtime() and uses that). I have not looked at other
+journalling file systems, I'll happily accept patches to rectify that!
diff -urN linux-2.4.23-pre6/Documentation/video4linux/bttv/CARDLIST linux-2.4.23-pre7/Documentation/video4linux/bttv/CARDLIST
--- linux-2.4.23-pre6/Documentation/video4linux/bttv/CARDLIST	2003-08-25 04:44:39.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/video4linux/bttv/CARDLIST	2003-10-09 17:48:21.000000000 -0700
@@ -7,7 +7,7 @@
   card=5 - Diamond DTV2000
   card=6 - AVerMedia TVPhone
   card=7 - MATRIX-Vision MV-Delta
-  card=8 - Lifeview FlyVideo II (Bt848) LR26
+  card=8 - Lifeview FlyVideo II (Bt848) LR26 / MAXI TV Video PCI2 LR26
   card=9 - IMS/IXmicro TurboTV
   card=10 - Hauppauge (bt878)
   card=11 - MIRO PCTV pro
@@ -104,6 +104,11 @@
   card=102 - IVC-200
   card=103 - Grand X-Guard / Trust 814PCI
   card=104 - Nebula Electronics DigiTV
+  card=105 - ProVideo PV143
+  card=106 - PHYTEC VD-009-X1 MiniDIN (bt878)
+  card=107 - PHYTEC VD-009-X1 Combi (bt878)
+  card=108 - PHYTEC VD-009 MiniDIN (bt878)
+  card=109 - PHYTEC VD-009 Combi (bt878)
 
 tuner.o
   type=0 - Temic PAL (4002 FH5)
@@ -147,3 +152,4 @@
   type=38 - Philips PAL/SECAM multi (FM1216ME MK3)
   type=39 - LG NTSC (newer TAPC series)
   type=40 - HITACHI V7-J180AT
+  type=41 - Philips PAL_MK (FI1216 MK)
diff -urN linux-2.4.23-pre6/Documentation/zorro.txt linux-2.4.23-pre7/Documentation/zorro.txt
--- linux-2.4.23-pre6/Documentation/zorro.txt	2000-10-16 12:51:16.000000000 -0700
+++ linux-2.4.23-pre7/Documentation/zorro.txt	2003-10-09 17:48:21.000000000 -0700
@@ -2,7 +2,7 @@
 		----------------------------------------
 
 Written by Geert Uytterhoeven <geert@linux-m68k.org>
-Last revised: February 27, 2000
+Last revised: September 5, 2003
 
 
 1. Introduction
@@ -77,7 +77,7 @@
 The treatment of these regions depends on the type of Zorro space:
 
   - Zorro II address space is always mapped and does not have to be mapped
-    explicitly using ioremap().
+    explicitly using z_ioremap().
     
     Conversion from bus/physical Zorro II addresses to kernel virtual addresses
     and vice versa is done using:
@@ -85,22 +85,20 @@
 	virt_addr = ZTWO_VADDR(bus_addr);
 	bus_addr = ZTWO_PADDR(virt_addr);
 
-  - Zorro III address space must be mapped explicitly using ioremap() first
+  - Zorro III address space must be mapped explicitly using z_ioremap() first
     before it can be accessed:
  
-	virt_addr = ioremap(bus_addr, size);
+	virt_addr = z_ioremap(bus_addr, size);
 	...
-	iounmap(virt_addr);
+	z_iounmap(virt_addr);
 
 
 5. References
 -------------
 
 linux/include/linux/zorro.h
-linux/include/linux/ioport.h
-linux/include/asm-m68k/io.h
-linux/include/asm-m68k/amigahw.h
-linux/include/asm-ppc/io.h
+linux/include/asm-{m68k,ppc}/zorro.h
+linux/include/linux/zorro_ids.h
 linux/drivers/zorro
 /proc/bus/zorro
 
diff -urN linux-2.4.23-pre6/MAINTAINERS linux-2.4.23-pre7/MAINTAINERS
--- linux-2.4.23-pre6/MAINTAINERS	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/MAINTAINERS	2003-10-09 17:48:21.000000000 -0700
@@ -202,7 +202,7 @@
 
 ALCATEL SPEEDTOUCH USB DRIVER
 P:	Duncan Sands
-M:	duncan.sands@wanadoo.fr
+M:	duncan.sands@free.fr
 L:	linux-usb-users@lists.sourceforge.net
 L:	linux-usb-devel@lists.sourceforge.net
 W:	http://www.linux-usb.org/SpeedTouch/
diff -urN linux-2.4.23-pre6/Makefile linux-2.4.23-pre7/Makefile
--- linux-2.4.23-pre6/Makefile	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -1,7 +1,7 @@
 VERSION = 2
 PATCHLEVEL = 4
 SUBLEVEL = 23
-EXTRAVERSION = -pre6
+EXTRAVERSION = -pre7
 
 KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
 
@@ -181,6 +181,7 @@
 DRIVERS-$(CONFIG_HAMRADIO) += drivers/net/hamradio/hamradio.o
 DRIVERS-$(CONFIG_TC) += drivers/tc/tc.a
 DRIVERS-$(CONFIG_USB) += drivers/usb/usbdrv.o
+DRIVERS-$(CONFIG_USB_GADGET) += drivers/usb/gadget/built-in.o
 DRIVERS-y +=drivers/media/media.o
 DRIVERS-$(CONFIG_INPUT) += drivers/input/inputdrv.o
 DRIVERS-$(CONFIG_HIL) += drivers/hil/hil.o
diff -urN linux-2.4.23-pre6/arch/i386/boot/setup.S linux-2.4.23-pre7/arch/i386/boot/setup.S
--- linux-2.4.23-pre6/arch/i386/boot/setup.S	2002-08-02 17:39:42.000000000 -0700
+++ linux-2.4.23-pre7/arch/i386/boot/setup.S	2003-10-09 17:48:21.000000000 -0700
@@ -45,6 +45,10 @@
  * New A20 code ported from SYSLINUX by H. Peter Anvin. AMD Elan bugfixes
  * by Robert Schwebel, December 2001 <robert@schwebel.de>
  *
+ * BIOS Enhanced Disk Drive support
+ * by Matt Domsch <Matt_Domsch@dell.com> October 2002
+ * conformant to T13 Committee www.t13.org
+ *   projects 1572D, 1484D, 1386D, 1226DT
  */
 
 #include <linux/config.h>
@@ -53,6 +57,7 @@
 #include <linux/compile.h>
 #include <asm/boot.h>
 #include <asm/e820.h>
+#include <asm/edd.h>
 #include <asm/page.h>
 	
 /* Signature words to ensure LILO loaded us right */
@@ -543,6 +548,70 @@
 done_apm_bios:
 #endif
 
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+# Do the BIOS Enhanced Disk Drive calls
+# This consists of two calls:
+#    int 13h ah=41h "Check Extensions Present"
+#    int 13h ah=48h "Get Device Parameters"
+#
+# A buffer of size EDDMAXNR*(EDDEXTSIZE+EDDPARMSIZE) is reserved for our use
+# in the empty_zero_page at EDDBUF.  The first four bytes of which are
+# used to store the device number, interface support map and version
+# results from fn41.  The following 74 bytes are used to store
+# the results from fn48.  Starting from device 80h, fn41, then fn48
+# are called and their results stored in EDDBUF+n*(EDDEXTSIZE+EDDPARMIZE).
+# Then the pointer is incremented to store the data for the next call.
+# This repeats until either a device doesn't exist, or until EDDMAXNR
+# devices have been stored.
+# The one tricky part is that ds:si always points four bytes into
+# the structure, and the fn41 results are stored at offsets
+# from there.  This removes the need to increment the pointer for
+# every store, and leaves it ready for the fn48 call.
+# A second one-byte buffer, EDDNR, in the empty_zero_page stores
+# the number of BIOS devices which exist, up to EDDMAXNR.
+# In setup.c, copy_edd() stores both empty_zero_page buffers away
+# for later use, as they would get overwritten otherwise.
+# This code is sensitive to the size of the structs in edd.h
+edd_start:
+						# %ds points to the bootsector
+       						# result buffer for fn48
+    	movw	$EDDBUF+EDDEXTSIZE, %si		# in ds:si, fn41 results
+						# kept just before that
+	movb	$0, (EDDNR)			# zero value at EDDNR
+    	movb	$0x80, %dl			# BIOS device 0x80
+
+edd_check_ext:
+	movb	$CHECKEXTENSIONSPRESENT, %ah    # Function 41
+	movw	$EDDMAGIC1, %bx			# magic
+	int	$0x13				# make the call
+	jc	edd_done			# no more BIOS devices
+
+    	cmpw	$EDDMAGIC2, %bx			# is magic right?
+	jne	edd_next			# nope, next...
+
+    	movb	%dl, %ds:-4(%si)		# store device number
+    	movb	%ah, %ds:-3(%si)		# store version
+	movw	%cx, %ds:-2(%si)		# store extensions
+	incb	(EDDNR)				# note that we stored something
+
+edd_get_device_params:
+	movw	$EDDPARMSIZE, %ds:(%si)		# put size
+    	movb	$GETDEVICEPARAMETERS, %ah	# Function 48
+	int	$0x13				# make the call
+						# Don't check for fail return
+						# it doesn't matter.
+	movw	%si, %ax			# increment si
+	addw	$EDDPARMSIZE+EDDEXTSIZE, %ax
+	movw	%ax, %si
+
+edd_next:
+        incb	%dl				# increment to next device
+       	cmpb	$EDDMAXNR, (EDDNR) 		# Out of space?
+	jb	edd_check_ext			# keep looping
+
+edd_done:
+#endif
+
 # Now we want to move to protected mode ...
 	cmpw	$0, %cs:realmode_swtch
 	jz	rmodeswtch_normal
diff -urN linux-2.4.23-pre6/arch/i386/config.in linux-2.4.23-pre7/arch/i386/config.in
--- linux-2.4.23-pre6/arch/i386/config.in	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/i386/config.in	2003-10-09 17:48:21.000000000 -0700
@@ -201,6 +201,10 @@
 tristate '/dev/cpu/*/msr - Model-specific register support' CONFIG_X86_MSR
 tristate '/dev/cpu/*/cpuid - CPU information support' CONFIG_X86_CPUID
 
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+   tristate 'BIOS Enhanced Disk Drive calls determine boot disk (EXPERIMENTAL)' CONFIG_EDD
+fi
+
 choice 'High Memory Support' \
 	"off    CONFIG_NOHIGHMEM \
 	 4GB    CONFIG_HIGHMEM4G \
diff -urN linux-2.4.23-pre6/arch/i386/defconfig linux-2.4.23-pre7/arch/i386/defconfig
--- linux-2.4.23-pre6/arch/i386/defconfig	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/i386/defconfig	2003-10-09 17:48:21.000000000 -0700
@@ -56,6 +56,7 @@
 # CONFIG_MICROCODE is not set
 # CONFIG_X86_MSR is not set
 # CONFIG_X86_CPUID is not set
+# CONFIG_EDD is not set
 CONFIG_NOHIGHMEM=y
 # CONFIG_HIGHMEM4G is not set
 # CONFIG_HIGHMEM64G is not set
diff -urN linux-2.4.23-pre6/arch/i386/kernel/Makefile linux-2.4.23-pre7/arch/i386/kernel/Makefile
--- linux-2.4.23-pre6/arch/i386/kernel/Makefile	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/i386/kernel/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -42,5 +42,6 @@
 obj-$(CONFIG_X86_LOCAL_APIC)	+= mpparse.o apic.o nmi.o
 obj-$(CONFIG_X86_IO_APIC)	+= io_apic.o
 obj-$(CONFIG_X86_VISWS_APIC)	+= visws_apic.o
+obj-$(CONFIG_EDD)             	+= edd.o
 
 include $(TOPDIR)/Rules.make
diff -urN linux-2.4.23-pre6/arch/i386/kernel/edd.c linux-2.4.23-pre7/arch/i386/kernel/edd.c
--- linux-2.4.23-pre6/arch/i386/kernel/edd.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/arch/i386/kernel/edd.c	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,672 @@
+/*
+ * linux/arch/i386/kernel/edd.c
+ *  Copyright (C) 2002 Dell Computer Corporation
+ *  by Matt Domsch <Matt_Domsch@dell.com>
+ *
+ * BIOS Enhanced Disk Drive Services (EDD)
+ * conformant to T13 Committee www.t13.org
+ *   projects 1572D, 1484D, 1386D, 1226DT
+ *
+ * This code takes information provided by BIOS EDD calls
+ * fn41 - Check Extensions Present and
+ * fn48 - Get Device Parametes with EDD extensions
+ * made in setup.S, copied to safe structures in setup.c,
+ * and presents it in /proc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * 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.
+ *
+ */
+
+/*
+ * TODO:
+ * - move edd.[ch] to better locations if/when one is decided
+ * - keep current with 2.5 EDD code changes
+ */
+
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/init.h>
+#include <linux/stat.h>
+#include <linux/ctype.h>
+#include <linux/slab.h>
+#include <linux/limits.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <asm/edd.h>
+
+MODULE_AUTHOR("Matt Domsch <Matt_Domsch@Dell.com>");
+MODULE_DESCRIPTION("proc interface to BIOS EDD information");
+MODULE_LICENSE("GPL");
+
+#define EDD_VERSION "0.09 2003-Jan-21"
+#define EDD_DEVICE_NAME_SIZE 16
+#define REPORT_URL "http://domsch.com/linux/edd30/results.html"
+
+#define left (count - (p - page) - 1)
+
+static struct proc_dir_entry *bios_dir;
+
+struct attr_entry {
+	struct proc_dir_entry *entry;
+	struct list_head node;
+};
+
+struct edd_device {
+	char name[EDD_DEVICE_NAME_SIZE];
+	struct edd_info *info;
+	struct proc_dir_entry *dir;
+	struct list_head attr_list;
+};
+
+static struct edd_device *edd_devices[EDDMAXNR];
+
+struct edd_attribute {
+	char *name;
+	int (*show)(char *page, char **start, off_t off,
+		    int count, int *eof, void *data);
+	int (*test) (struct edd_device * edev);
+};
+
+#define EDD_DEVICE_ATTR(_name,_show,_test) \
+struct edd_attribute edd_attr_##_name = { 	\
+	.name = __stringify(_name), \
+	.show	= _show,	    \
+        .test   = _test,            \
+};
+
+static inline struct edd_info *
+edd_dev_get_info(struct edd_device *edev)
+{
+	return edev->info;
+}
+
+static inline void
+edd_dev_set_info(struct edd_device *edev, struct edd_info *info)
+{
+	edev->info = info;
+}
+
+static int
+proc_calc_metrics(char *page, char **start, off_t off,
+		  int count, int *eof, int len)
+{
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int
+edd_dump_raw_data(char *b, int count, void *data, int length)
+{
+	char *orig_b = b;
+	char hexbuf[80], ascbuf[20], *h, *a, c;
+	unsigned char *p = data;
+	unsigned long column = 0;
+	int length_printed = 0, d;
+	const char maxcolumn = 16;
+	while (length_printed < length && count > 0) {
+		h = hexbuf;
+		a = ascbuf;
+		for (column = 0;
+		     column < maxcolumn && length_printed < length; column++) {
+			h += sprintf(h, "%02x ", (unsigned char) *p);
+			if (!isprint(*p))
+				c = '.';
+			else
+				c = *p;
+			a += sprintf(a, "%c", c);
+			p++;
+			length_printed++;
+		}
+		/* pad out the line */
+		for (; column < maxcolumn; column++) {
+			h += sprintf(h, "   ");
+			a += sprintf(a, " ");
+		}
+		d = snprintf(b, count, "%s\t%s\n", hexbuf, ascbuf);
+		b += d;
+		count -= d;
+	}
+	return (b - orig_b);
+}
+
+static int
+edd_show_host_bus(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	int i;
+
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (isprint(info->params.host_bus_type[i])) {
+			p += snprintf(p, left, "%c", info->params.host_bus_type[i]);
+		} else {
+			p += snprintf(p, left, " ");
+		}
+	}
+
+	if (!strncmp(info->params.host_bus_type, "ISA", 3)) {
+		p += snprintf(p, left, "\tbase_address: %x\n",
+			     info->params.interface_path.isa.base_address);
+	} else if (!strncmp(info->params.host_bus_type, "PCIX", 4) ||
+		   !strncmp(info->params.host_bus_type, "PCI", 3)) {
+		p += snprintf(p, left,
+			     "\t%02x:%02x.%d  channel: %u\n",
+			     info->params.interface_path.pci.bus,
+			     info->params.interface_path.pci.slot,
+			     info->params.interface_path.pci.function,
+			     info->params.interface_path.pci.channel);
+	} else if (!strncmp(info->params.host_bus_type, "IBND", 4) ||
+		   !strncmp(info->params.host_bus_type, "XPRS", 4) ||
+		   !strncmp(info->params.host_bus_type, "HTPT", 4)) {
+		p += snprintf(p, left,
+			     "\tTBD: %llx\n",
+			     info->params.interface_path.ibnd.reserved);
+
+	} else {
+		p += snprintf(p, left, "\tunknown: %llx\n",
+			     info->params.interface_path.unknown.reserved);
+	}
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_interface(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	int i;
+
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	for (i = 0; i < 8; i++) {
+		if (isprint(info->params.interface_type[i])) {
+			p += snprintf(p, left, "%c", info->params.interface_type[i]);
+		} else {
+			p += snprintf(p, left, " ");
+		}
+	}
+	if (!strncmp(info->params.interface_type, "ATAPI", 5)) {
+		p += snprintf(p, left, "\tdevice: %u  lun: %u\n",
+			     info->params.device_path.atapi.device,
+			     info->params.device_path.atapi.lun);
+	} else if (!strncmp(info->params.interface_type, "ATA", 3)) {
+		p += snprintf(p, left, "\tdevice: %u\n",
+			     info->params.device_path.ata.device);
+	} else if (!strncmp(info->params.interface_type, "SCSI", 4)) {
+		p += snprintf(p, left, "\tid: %u  lun: %llu\n",
+			     info->params.device_path.scsi.id,
+			     info->params.device_path.scsi.lun);
+	} else if (!strncmp(info->params.interface_type, "USB", 3)) {
+		p += snprintf(p, left, "\tserial_number: %llx\n",
+			     info->params.device_path.usb.serial_number);
+	} else if (!strncmp(info->params.interface_type, "1394", 4)) {
+		p += snprintf(p, left, "\teui: %llx\n",
+			     info->params.device_path.i1394.eui);
+	} else if (!strncmp(info->params.interface_type, "FIBRE", 5)) {
+		p += snprintf(p, left, "\twwid: %llx lun: %llx\n",
+			     info->params.device_path.fibre.wwid,
+			     info->params.device_path.fibre.lun);
+	} else if (!strncmp(info->params.interface_type, "I2O", 3)) {
+		p += snprintf(p, left, "\tidentity_tag: %llx\n",
+			     info->params.device_path.i2o.identity_tag);
+	} else if (!strncmp(info->params.interface_type, "RAID", 4)) {
+		p += snprintf(p, left, "\tidentity_tag: %x\n",
+			     info->params.device_path.raid.array_number);
+	} else if (!strncmp(info->params.interface_type, "SATA", 4)) {
+		p += snprintf(p, left, "\tdevice: %u\n",
+			     info->params.device_path.sata.device);
+	} else {
+		p += snprintf(p, left, "\tunknown: %llx %llx\n",
+			     info->params.device_path.unknown.reserved1,
+			     info->params.device_path.unknown.reserved2);
+	}
+
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+/**
+ * edd_show_raw_data() - unparses EDD information, returned to user-space
+ *
+ * Returns: number of bytes written, or 0 on failure
+ */
+static int
+edd_show_raw_data(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	int i, warn_padding = 0, nonzero_path = 0,
+		len = sizeof (*info) - 4;
+	uint8_t checksum = 0, c = 0;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE))
+		len = info->params.length;
+
+	p += snprintf(p, left, "int13 fn48 returned data:\n\n");
+	p += edd_dump_raw_data(p, left, ((char *) info) + 4, len);
+
+	/* Spec violation.  Adaptec AIC7899 returns 0xDDBE
+	   here, when it should be 0xBEDD.
+	 */
+	p += snprintf(p, left, "\n");
+	if (info->params.key == 0xDDBE) {
+		p += snprintf(p, left,
+			     "Warning: Spec violation.  Key should be 0xBEDD, is 0xDDBE\n");
+	}
+
+	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
+		goto out;
+	}
+
+	for (i = 30; i <= 73; i++) {
+		c = *(((uint8_t *) info) + i + 4);
+		if (c)
+			nonzero_path++;
+		checksum += c;
+	}
+
+	if (checksum) {
+		p += snprintf(p, left,
+			     "Warning: Spec violation.  Device Path checksum invalid.\n");
+	}
+
+	if (!nonzero_path) {
+		p += snprintf(p, left, "Error: Spec violation.  Empty device path.\n");
+		goto out;
+	}
+
+	for (i = 0; i < 4; i++) {
+		if (!isprint(info->params.host_bus_type[i])) {
+			warn_padding++;
+		}
+	}
+	for (i = 0; i < 8; i++) {
+		if (!isprint(info->params.interface_type[i])) {
+			warn_padding++;
+		}
+	}
+
+	if (warn_padding) {
+		p += snprintf(p, left,
+			     "Warning: Spec violation.  Padding should be 0x20.\n");
+	}
+
+out:
+	p += snprintf(p, left, "\nPlease check %s\n", REPORT_URL);
+	p += snprintf(p, left, "to see if this device has been reported.  If not,\n");
+	p += snprintf(p, left, "please send the information requested there.\n");
+
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_version(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%02x\n", info->version);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_extensions(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	if (info->interface_support & EDD_EXT_FIXED_DISK_ACCESS) {
+		p += snprintf(p, left, "Fixed disk access\n");
+	}
+	if (info->interface_support & EDD_EXT_DEVICE_LOCKING_AND_EJECTING) {
+		p += snprintf(p, left, "Device locking and ejecting\n");
+	}
+	if (info->interface_support & EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT) {
+		p += snprintf(p, left, "Enhanced Disk Drive support\n");
+	}
+	if (info->interface_support & EDD_EXT_64BIT_EXTENSIONS) {
+		p += snprintf(p, left, "64-bit extensions\n");
+	}
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_info_flags(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	if (info->params.info_flags & EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT)
+		p += snprintf(p, left, "DMA boundry error transparent\n");
+	if (info->params.info_flags & EDD_INFO_GEOMETRY_VALID)
+		p += snprintf(p, left, "geometry valid\n");
+	if (info->params.info_flags & EDD_INFO_REMOVABLE)
+		p += snprintf(p, left, "removable\n");
+	if (info->params.info_flags & EDD_INFO_WRITE_VERIFY)
+		p += snprintf(p, left, "write verify\n");
+	if (info->params.info_flags & EDD_INFO_MEDIA_CHANGE_NOTIFICATION)
+		p += snprintf(p, left, "media change notification\n");
+	if (info->params.info_flags & EDD_INFO_LOCKABLE)
+		p += snprintf(p, left, "lockable\n");
+	if (info->params.info_flags & EDD_INFO_NO_MEDIA_PRESENT)
+		p += snprintf(p, left, "no media present\n");
+	if (info->params.info_flags & EDD_INFO_USE_INT13_FN50)
+		p += snprintf(p, left, "use int13 fn50\n");
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_default_cylinders(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%x\n", info->params.num_default_cylinders);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_default_heads(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%x\n", info->params.num_default_heads);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_default_sectors_per_track(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%x\n", info->params.sectors_per_track);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_show_sectors(char *page, char **start, off_t off, int count, int *eof, void *data)
+{
+	struct edd_info *info = data;
+	char *p = page;
+	if (!info || !page || off) {
+		return proc_calc_metrics(page, start, off, count, eof, 0);
+	}
+
+	p += snprintf(p, left, "0x%llx\n", info->params.number_of_sectors);
+	return proc_calc_metrics(page, start, off, count, eof, (p - page));
+}
+
+static int
+edd_has_default_cylinders(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	if (!edev || !info)
+		return 0;
+	return info->params.num_default_cylinders > 0;
+}
+
+static int
+edd_has_default_heads(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	if (!edev || !info)
+		return 0;
+	return info->params.num_default_heads > 0;
+}
+
+static int
+edd_has_default_sectors_per_track(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	if (!edev || !info)
+		return 0;
+	return info->params.sectors_per_track > 0;
+}
+
+static int
+edd_has_edd30(struct edd_device *edev)
+{
+	struct edd_info *info = edd_dev_get_info(edev);
+	int i, nonzero_path = 0;
+	char c;
+
+	if (!edev || !info)
+		return 0;
+
+	if (!(info->params.key == 0xBEDD || info->params.key == 0xDDBE)) {
+		return 0;
+	}
+
+	for (i = 30; i <= 73; i++) {
+		c = *(((uint8_t *) info) + i + 4);
+		if (c) {
+			nonzero_path++;
+			break;
+		}
+	}
+	if (!nonzero_path) {
+		return 0;
+	}
+
+	return 1;
+}
+
+static EDD_DEVICE_ATTR(raw_data, edd_show_raw_data, NULL);
+static EDD_DEVICE_ATTR(version, edd_show_version, NULL);
+static EDD_DEVICE_ATTR(extensions, edd_show_extensions, NULL);
+static EDD_DEVICE_ATTR(info_flags, edd_show_info_flags, NULL);
+static EDD_DEVICE_ATTR(sectors, edd_show_sectors, NULL);
+static EDD_DEVICE_ATTR(default_cylinders, edd_show_default_cylinders,
+		       edd_has_default_cylinders);
+static EDD_DEVICE_ATTR(default_heads, edd_show_default_heads,
+		       edd_has_default_heads);
+static EDD_DEVICE_ATTR(default_sectors_per_track,
+		       edd_show_default_sectors_per_track,
+		       edd_has_default_sectors_per_track);
+static EDD_DEVICE_ATTR(interface, edd_show_interface,edd_has_edd30);
+static EDD_DEVICE_ATTR(host_bus, edd_show_host_bus, edd_has_edd30);
+
+static struct edd_attribute *def_attrs[] = {
+	&edd_attr_raw_data,
+	&edd_attr_version,
+	&edd_attr_extensions,
+	&edd_attr_info_flags,
+	&edd_attr_sectors,
+	&edd_attr_default_cylinders,
+	&edd_attr_default_heads,
+	&edd_attr_default_sectors_per_track,
+	&edd_attr_interface,
+	&edd_attr_host_bus,
+	NULL,
+};
+
+static inline void
+edd_device_unregister(struct edd_device *edev)
+{
+	struct list_head *pos, *next;
+	struct attr_entry *ae;
+
+	list_for_each_safe(pos, next, &edev->attr_list) {
+		ae = list_entry(pos, struct attr_entry, node);
+		remove_proc_entry(ae->entry->name, edev->dir);
+		list_del(&ae->node);
+		kfree(ae);
+	}
+
+	remove_proc_entry(edev->dir->name, bios_dir);
+}
+
+static int
+edd_populate_dir(struct edd_device *edev)
+{
+	struct edd_attribute *attr;
+	struct attr_entry *ae;
+	int i;
+	int error = 0;
+
+	for (i = 0; (attr=def_attrs[i]); i++) {
+		if (!attr->test || (attr->test && attr->test(edev))) {
+			ae = kmalloc(sizeof (*ae), GFP_KERNEL);
+			if (ae == NULL) {
+				error = 1;
+				break;
+			}
+			INIT_LIST_HEAD(&ae->node);
+			ae->entry =
+				create_proc_read_entry(attr->name, 0444,
+						       edev->dir, attr->show,
+						       edd_dev_get_info(edev));
+			if (ae->entry == NULL) {
+				error = 1;
+				break;
+			}
+			list_add(&ae->node, &edev->attr_list);
+		}
+	}
+
+	if (error)
+		return error;
+
+	return 0;
+}
+
+static int
+edd_make_dir(struct edd_device *edev)
+{
+	int error=1;
+
+	edev->dir = proc_mkdir(edev->name, bios_dir);
+	if (edev->dir != NULL) {
+		edev->dir->mode = (S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO);
+		error = edd_populate_dir(edev);
+	}
+	return error;
+}
+
+static int
+edd_device_register(struct edd_device *edev, int i)
+{
+	int error;
+
+	if (!edev)
+		return 1;
+	memset(edev, 0, sizeof (*edev));
+	INIT_LIST_HEAD(&edev->attr_list);
+	edd_dev_set_info(edev, &edd[i]);
+	snprintf(edev->name, EDD_DEVICE_NAME_SIZE, "int13_dev%02x",
+		 edd[i].device);
+	error = edd_make_dir(edev);
+	return error;
+}
+
+/**
+ * edd_init() - creates /proc/bios tree of EDD data
+ *
+ * This assumes that eddnr and edd were
+ * assigned in setup.c already.
+ */
+static int __init
+edd_init(void)
+{
+	unsigned int i;
+	int rc = 0;
+	struct edd_device *edev;
+
+	printk(KERN_INFO "BIOS EDD facility v%s, %d devices found\n",
+	       EDD_VERSION, eddnr);
+
+	if (!eddnr) {
+		printk(KERN_INFO "EDD information not available.\n");
+		return 1;
+	}
+
+	bios_dir = proc_mkdir("bios", NULL);
+	if (bios_dir == NULL)
+		return 1;
+
+	for (i = 0; i < eddnr && i < EDDMAXNR && !rc; i++) {
+		edev = kmalloc(sizeof (*edev), GFP_KERNEL);
+		if (!edev) {
+			rc = 1;
+			break;
+		}
+
+		rc = edd_device_register(edev, i);
+		if (rc) {
+			break;
+		}
+		edd_devices[i] = edev;
+	}
+
+	if (rc) {
+		for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
+			if ((edev = edd_devices[i])) {
+				edd_device_unregister(edev);
+				kfree(edev);
+			}
+		}
+
+		remove_proc_entry(bios_dir->name, NULL);
+	}
+
+	return rc;
+}
+
+static void __exit
+edd_exit(void)
+{
+	int i;
+	struct edd_device *edev;
+
+	for (i = 0; i < eddnr && i < EDDMAXNR; i++) {
+		if ((edev = edd_devices[i])) {
+			edd_device_unregister(edev);
+			kfree(edev);
+		}
+	}
+
+	remove_proc_entry(bios_dir->name, NULL);
+}
+
+module_init(edd_init);
+module_exit(edd_exit);
diff -urN linux-2.4.23-pre6/arch/i386/kernel/i386_ksyms.c linux-2.4.23-pre7/arch/i386/kernel/i386_ksyms.c
--- linux-2.4.23-pre6/arch/i386/kernel/i386_ksyms.c	2003-06-13 07:51:29.000000000 -0700
+++ linux-2.4.23-pre7/arch/i386/kernel/i386_ksyms.c	2003-10-09 17:48:21.000000000 -0700
@@ -28,6 +28,7 @@
 #include <asm/desc.h>
 #include <asm/pgtable.h>
 #include <asm/pgalloc.h>
+#include <asm/edd.h>
 
 extern void dump_thread(struct pt_regs *, struct user *);
 extern spinlock_t rtc_lock;
@@ -180,3 +181,8 @@
 #ifdef CONFIG_MULTIQUAD
 EXPORT_SYMBOL(xquad_portio);
 #endif
+
+#ifdef CONFIG_EDD_MODULE
+EXPORT_SYMBOL(edd);
+EXPORT_SYMBOL(eddnr);
+#endif
diff -urN linux-2.4.23-pre6/arch/i386/kernel/setup.c linux-2.4.23-pre7/arch/i386/kernel/setup.c
--- linux-2.4.23-pre6/arch/i386/kernel/setup.c	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/i386/kernel/setup.c	2003-10-09 17:48:21.000000000 -0700
@@ -120,6 +120,7 @@
 #include <asm/dma.h>
 #include <asm/mpspec.h>
 #include <asm/mmu_context.h>
+#include <asm/edd.h>
 /*
  * Machine setup..
  */
@@ -211,6 +212,8 @@
 #define KERNEL_START (*(unsigned long *) (PARAM+0x214))
 #define INITRD_START (*(unsigned long *) (PARAM+0x218))
 #define INITRD_SIZE (*(unsigned long *) (PARAM+0x21c))
+#define EDD_NR     (*(unsigned char *) (PARAM+EDDNR))
+#define EDD_BUF     ((struct edd_info *) (PARAM+EDDBUF))
 #define COMMAND_LINE ((char *) (PARAM+2048))
 #define COMMAND_LINE_SIZE 256
 
@@ -715,6 +718,23 @@
 	return 0;
 }
 
+#if defined(CONFIG_EDD) || defined(CONFIG_EDD_MODULE)
+unsigned char eddnr;
+struct edd_info edd[EDDMAXNR];
+/**
+ * copy_edd() - Copy the BIOS EDD information
+ *              from empty_zero_page into a safe place.
+ *
+ */
+static inline void copy_edd(void)
+{
+     eddnr = EDD_NR;
+     memcpy(edd, EDD_BUF, sizeof(edd));
+}
+#else
+static inline void copy_edd(void) {}
+#endif
+
 /*
  * Do NOT EVER look at the BIOS memory size location.
  * It does not work on many machines.
@@ -1151,6 +1171,7 @@
 	rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0);
 #endif
 	setup_memory_region();
+	copy_edd();
 
 	if (!MOUNT_ROOT_RDONLY)
 		root_mountflags &= ~MS_RDONLY;
@@ -2269,6 +2290,8 @@
 	{ 0x23, LVL_3,      1024 },
 	{ 0x25, LVL_3,      2048 },
 	{ 0x29, LVL_3,      4096 },
+	{ 0x2c, LVL_1_DATA, 32 },
+	{ 0x30, LVL_1_INST, 32 },
 	{ 0x39, LVL_2,      128 },
 	{ 0x3b, LVL_2,      128 },
 	{ 0x3C, LVL_2,      256 },
diff -urN linux-2.4.23-pre6/arch/ia64/Makefile linux-2.4.23-pre7/arch/ia64/Makefile
--- linux-2.4.23-pre6/arch/ia64/Makefile	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/ia64/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -62,9 +62,11 @@
 
 ifdef CONFIG_IA64_HP_SIM
         SUBDIRS         :=      arch/$(ARCH)/hp		\
+                                arch/$(ARCH)/drivers	\
                                 $(SUBDIRS)
         CORE_FILES      :=      arch/$(ARCH)/hp/hp.o	\
                                 $(CORE_FILES)
+        DRIVERS         +=      arch/$(ARCH)/drivers/drivers.o
 endif
 
 ifdef CONFIG_IA64_HP_ZX1
diff -urN linux-2.4.23-pre6/arch/ia64/drivers/Makefile linux-2.4.23-pre7/arch/ia64/drivers/Makefile
--- linux-2.4.23-pre6/arch/ia64/drivers/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/arch/ia64/drivers/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,13 @@
+#
+# ia64/drivers/Makefile
+#
+# Copyright (C) 2003 Hewlett-Packard Co.
+#	Bjorn Helgaas <bjorn.helgaas@hp.com>
+
+O_TARGET := drivers.o
+
+obj-$(CONFIG_HP_SIMETH) += simeth.o
+obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
+obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
+
+include $(TOPDIR)/Rules.make
diff -urN linux-2.4.23-pre6/arch/ia64/drivers/simeth.c linux-2.4.23-pre7/arch/ia64/drivers/simeth.c
--- linux-2.4.23-pre6/arch/ia64/drivers/simeth.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/arch/ia64/drivers/simeth.c	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,537 @@
+/*
+ * Simulated Ethernet Driver
+ *
+ * Copyright (C) 1999-2001, 2003 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ */
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/in.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/inetdevice.h>
+#include <linux/if_ether.h>
+#include <linux/if_arp.h>
+#include <linux/skbuff.h>
+#include <linux/notifier.h>
+#include <asm/bitops.h>
+#include <asm/system.h>
+#include <asm/irq.h>
+
+#define SIMETH_RECV_MAX	10
+
+/*
+ * Maximum possible received frame for Ethernet.
+ * We preallocate an sk_buff of that size to avoid costly
+ * memcpy for temporary buffer into sk_buff. We do basically
+ * what's done in other drivers, like eepro with a ring.
+ * The difference is, of course, that we don't have real DMA !!!
+ */
+#define SIMETH_FRAME_SIZE	ETH_FRAME_LEN
+
+
+#define SSC_NETDEV_PROBE		100
+#define SSC_NETDEV_SEND			101
+#define SSC_NETDEV_RECV			102
+#define SSC_NETDEV_ATTACH		103
+#define SSC_NETDEV_DETACH		104
+
+#define NETWORK_INTR			8
+
+struct simeth_local {
+	struct net_device_stats stats;
+	int 			simfd;	 /* descriptor in the simulator */
+};
+
+static int simeth_probe1(void);
+static int simeth_open(struct net_device *dev);
+static int simeth_close(struct net_device *dev);
+static int simeth_tx(struct sk_buff *skb, struct net_device *dev);
+static int simeth_rx(struct net_device *dev);
+static struct net_device_stats *simeth_get_stats(struct net_device *dev);
+static void simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs);
+static void set_multicast_list(struct net_device *dev);
+static int simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr);
+
+static char *simeth_version="0.3";
+
+/*
+ * This variable is used to establish a mapping between the Linux/ia64 kernel
+ * and the host linux kernel.
+ *
+ * As of today, we support only one card, even though most of the code
+ * is ready for many more. The mapping is then:
+ *	linux/ia64 -> linux/x86
+ * 	   eth0    -> eth1
+ *
+ * In the future, we some string operations, we could easily support up
+ * to 10 cards (0-9).
+ *
+ * The default mapping can be changed on the kernel command line by
+ * specifying simeth=ethX (or whatever string you want).
+ */
+static char *simeth_device="eth0";	 /* default host interface to use */
+
+
+
+static volatile unsigned int card_count; /* how many cards "found" so far */
+static int simeth_debug;		/* set to 1 to get debug information */
+
+/*
+ * Used to catch IFF_UP & IFF_DOWN events
+ */
+static struct notifier_block simeth_dev_notifier = {
+	simeth_device_event,
+	0
+};
+
+
+/*
+ * Function used when using a kernel command line option.
+ *
+ * Format: simeth=interface_name (like eth0)
+ */
+static int __init
+simeth_setup(char *str)
+{
+	simeth_device = str;
+	return 1;
+}
+
+__setup("simeth=", simeth_setup);
+
+/*
+ * Function used to probe for simeth devices when not installed
+ * as a loadable module
+ */
+
+int __init
+simeth_probe (void)
+{
+	int r;
+
+	printk(KERN_INFO "simeth: v%s\n", simeth_version);
+
+	r = simeth_probe1();
+
+	if (r == 0) register_netdevice_notifier(&simeth_dev_notifier);
+
+	return r;
+}
+
+extern long ia64_ssc (long, long, long, long, int);
+extern void ia64_ssc_connect_irq (long intr, long irq);
+
+static inline int
+netdev_probe(char *name, unsigned char *ether)
+{
+	return ia64_ssc(__pa(name), __pa(ether), 0,0, SSC_NETDEV_PROBE);
+}
+
+
+static inline int
+netdev_connect(int irq)
+{
+	/* XXX Fix me
+	 * this does not support multiple cards
+	 * also no return value
+	 */
+	ia64_ssc_connect_irq(NETWORK_INTR, irq);
+	return 0;
+}
+
+static inline int
+netdev_attach(int fd, int irq, unsigned int ipaddr)
+{
+	/* this puts the host interface in the right mode (start interrupting) */
+	return ia64_ssc(fd, ipaddr, 0,0, SSC_NETDEV_ATTACH);
+}
+
+
+static inline int
+netdev_detach(int fd)
+{
+	/*
+	 * inactivate the host interface (don't interrupt anymore) */
+	return ia64_ssc(fd, 0,0,0, SSC_NETDEV_DETACH);
+}
+
+static inline int
+netdev_send(int fd, unsigned char *buf, unsigned int len)
+{
+	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_SEND);
+}
+
+static inline int
+netdev_read(int fd, unsigned char *buf, unsigned int len)
+{
+	return ia64_ssc(fd, __pa(buf), len, 0, SSC_NETDEV_RECV);
+}
+
+/*
+ * Function shared with module code, so cannot be in init section
+ *
+ * So far this function "detects" only one card (test_&_set) but could
+ * be extended easily.
+ *
+ * Return:
+ * 	- -ENODEV is no device found
+ *	- -ENOMEM is no more memory
+ *	- 0 otherwise
+ */
+static int
+simeth_probe1(void)
+{
+	unsigned char mac_addr[ETH_ALEN];
+	struct simeth_local *local;
+	struct net_device *dev;
+	int fd, i;
+
+	/*
+	 * XXX Fix me
+	 * let's support just one card for now
+	 */
+	if (test_and_set_bit(0, &card_count))
+		return -ENODEV;
+
+	/*
+	 * check with the simulator for the device
+	 */
+	fd = netdev_probe(simeth_device, mac_addr);
+	if (fd == -1)
+		return -ENODEV;
+
+	dev = init_etherdev(NULL, sizeof(struct simeth_local));
+	if (!dev)
+		return -ENOMEM;
+
+	memcpy(dev->dev_addr, mac_addr, sizeof(mac_addr));
+
+	dev->irq = ia64_alloc_vector();
+
+	/*
+	 * attach the interrupt in the simulator, this does enable interrupts
+	 * until a netdev_attach() is called
+	 */
+	netdev_connect(dev->irq);
+
+	memset(dev->priv, 0, sizeof(struct simeth_local));
+
+	local = dev->priv;
+	local->simfd = fd; /* keep track of underlying file descriptor */
+
+	dev->open		= simeth_open;
+	dev->stop		= simeth_close;
+	dev->hard_start_xmit	= simeth_tx;
+	dev->get_stats		= simeth_get_stats;
+	dev->set_multicast_list = set_multicast_list; /* no yet used */
+
+	/* Fill in the fields of the device structure with ethernet-generic values. */
+	ether_setup(dev);
+
+	printk(KERN_INFO "%s: hosteth=%s simfd=%d, HwAddr",
+	       dev->name, simeth_device, local->simfd);
+	for(i = 0; i < ETH_ALEN; i++) {
+		printk(" %2.2x", dev->dev_addr[i]);
+	}
+	printk(", IRQ %d\n", dev->irq);
+
+	return 0;
+}
+
+/*
+ * actually binds the device to an interrupt vector
+ */
+static int
+simeth_open(struct net_device *dev)
+{
+	if (request_irq(dev->irq, simeth_interrupt, 0, "simeth", dev)) {
+		printk(KERN_WARNING "simeth: unable to get IRQ %d.\n", dev->irq);
+		return -EAGAIN;
+	}
+
+	netif_start_queue(dev);
+
+	return 0;
+}
+
+/* copied from lapbether.c */
+static __inline__ int dev_is_ethdev(struct net_device *dev)
+{
+       return ( dev->type == ARPHRD_ETHER && strncmp(dev->name, "dummy", 5));
+}
+
+
+/*
+ * Handler for IFF_UP or IFF_DOWN
+ *
+ * The reason for that is that we don't want to be interrupted when the
+ * interface is down. There is no way to unconnect in the simualtor. Instead
+ * we use this function to shutdown packet processing in the frame filter
+ * in the simulator. Thus no interrupts are generated
+ *
+ *
+ * That's also the place where we pass the IP address of this device to the
+ * simulator so that that we can start filtering packets for it
+ *
+ * There may be a better way of doing this, but I don't know which yet.
+ */
+static int
+simeth_device_event(struct notifier_block *this,unsigned long event, void *ptr)
+{
+	struct net_device *dev = (struct net_device *)ptr;
+	struct simeth_local *local;
+	struct in_device *in_dev;
+	struct in_ifaddr **ifap = NULL;
+	struct in_ifaddr *ifa = NULL;
+	int r;
+
+
+	if ( ! dev ) {
+		printk(KERN_WARNING "simeth_device_event dev=0\n");
+		return NOTIFY_DONE;
+	}
+
+	if ( event != NETDEV_UP && event != NETDEV_DOWN ) return NOTIFY_DONE;
+
+	/*
+	 * Check whether or not it's for an ethernet device
+	 *
+	 * XXX Fixme: This works only as long as we support one
+	 * type of ethernet device.
+	 */
+	if ( !dev_is_ethdev(dev) ) return NOTIFY_DONE;
+
+	if ((in_dev=dev->ip_ptr) != NULL) {
+		for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; ifap=&ifa->ifa_next)
+			if (strcmp(dev->name, ifa->ifa_label) == 0) break;
+	}
+	if ( ifa == NULL ) {
+		printk(KERN_ERR "simeth_open: can't find device %s's ifa\n", dev->name);
+		return NOTIFY_DONE;
+	}
+
+	printk(KERN_INFO "simeth_device_event: %s ipaddr=0x%x\n",
+	       dev->name, htonl(ifa->ifa_local));
+
+	/*
+	 * XXX Fix me
+	 * if the device was up, and we're simply reconfiguring it, not sure
+	 * we get DOWN then UP.
+	 */
+
+	local = dev->priv;
+	/* now do it for real */
+	r = event == NETDEV_UP ?
+		netdev_attach(local->simfd, dev->irq, htonl(ifa->ifa_local)):
+		netdev_detach(local->simfd);
+
+	printk(KERN_INFO "simeth: netdev_attach/detach: event=%s ->%d\n",
+	       event == NETDEV_UP ? "attach":"detach", r);
+
+	return NOTIFY_DONE;
+}
+
+static int
+simeth_close(struct net_device *dev)
+{
+	netif_stop_queue(dev);
+
+	free_irq(dev->irq, dev);
+
+	return 0;
+}
+
+/*
+ * Only used for debug
+ */
+static void
+frame_print(unsigned char *from, unsigned char *frame, int len)
+{
+	int i;
+
+	printk("%s: (%d) %02x", from, len, frame[0] & 0xff);
+	for(i=1; i < 6; i++ ) {
+		printk(":%02x", frame[i] &0xff);
+	}
+	printk(" %2x", frame[6] &0xff);
+	for(i=7; i < 12; i++ ) {
+		printk(":%02x", frame[i] &0xff);
+	}
+	printk(" [%02x%02x]\n", frame[12], frame[13]);
+
+	for(i=14; i < len; i++ ) {
+		printk("%02x ", frame[i] &0xff);
+		if ( (i%10)==0) printk("\n");
+	}
+	printk("\n");
+}
+
+
+/*
+ * Function used to transmit of frame, very last one on the path before
+ * going to the simulator.
+ */
+static int
+simeth_tx(struct sk_buff *skb, struct net_device *dev)
+{
+	struct simeth_local *local = (struct simeth_local *)dev->priv;
+
+#if 0
+	/* ensure we have at least ETH_ZLEN bytes (min frame size) */
+	unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+	/* Where do the extra padding bytes comes from inthe skbuff ? */
+#else
+	/* the real driver in the host system is going to take care of that
+	 * or maybe it's the NIC itself.
+	 */
+	unsigned int length = skb->len;
+#endif
+
+	local->stats.tx_bytes += skb->len;
+	local->stats.tx_packets++;
+
+
+	if (simeth_debug > 5) frame_print("simeth_tx", skb->data, length);
+
+	netdev_send(local->simfd, skb->data, length);
+
+	/*
+	 * we are synchronous on write, so we don't simulate a
+	 * trasnmit complete interrupt, thus we don't need to arm a tx
+	 */
+
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+static inline struct sk_buff *
+make_new_skb(struct net_device *dev)
+{
+	struct sk_buff *nskb;
+
+	/*
+	 * The +2 is used to make sure that the IP header is nicely
+	 * aligned (on 4byte boundary I assume 14+2=16)
+	 */
+	nskb = dev_alloc_skb(SIMETH_FRAME_SIZE + 2);
+	if ( nskb == NULL ) {
+		printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
+		return NULL;
+	}
+	nskb->dev = dev;
+
+	skb_reserve(nskb, 2);	/* Align IP on 16 byte boundaries */
+
+	skb_put(nskb,SIMETH_FRAME_SIZE);
+
+	return nskb;
+}
+
+/*
+ * called from interrupt handler to process a received frame
+ */
+static int
+simeth_rx(struct net_device *dev)
+{
+	struct simeth_local	*local;
+	struct sk_buff		*skb;
+	int			len;
+	int			rcv_count = SIMETH_RECV_MAX;
+
+	local = (struct simeth_local *)dev->priv;
+	/*
+	 * the loop concept has been borrowed from other drivers
+	 * looks to me like it's a throttling thing to avoid pushing to many
+	 * packets at one time into the stack. Making sure we can process them
+	 * upstream and make forward progress overall
+	 */
+	do {
+		if ( (skb=make_new_skb(dev)) == NULL ) {
+			printk(KERN_NOTICE "%s: memory squeeze. dropping packet.\n", dev->name);
+			local->stats.rx_dropped++;
+			return 0;
+		}
+		/*
+		 * Read only one frame at a time
+		 */
+		len = netdev_read(local->simfd, skb->data, SIMETH_FRAME_SIZE);
+		if ( len == 0 ) {
+			if ( simeth_debug > 0 ) printk(KERN_WARNING "%s: count=%d netdev_read=0\n",
+						       dev->name, SIMETH_RECV_MAX-rcv_count);
+			break;
+		}
+#if 0
+		/*
+		 * XXX Fix me
+		 * Should really do a csum+copy here
+		 */
+		memcpy(skb->data, frame, len);
+#endif
+		skb->protocol = eth_type_trans(skb, dev);
+
+		if ( simeth_debug > 6 ) frame_print("simeth_rx", skb->data, len);
+
+		/*
+		 * push the packet up & trigger software interrupt
+		 */
+		netif_rx(skb);
+
+		local->stats.rx_packets++;
+		local->stats.rx_bytes += len;
+
+	} while ( --rcv_count );
+
+	return len; /* 0 = nothing left to read, otherwise, we can try again */
+}
+
+/*
+ * Interrupt handler (Yes, we can do it too !!!)
+ */
+static void
+simeth_interrupt(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct net_device *dev = dev_id;
+
+	if ( dev == NULL ) {
+		printk(KERN_WARNING "simeth: irq %d for unknown device\n", irq);
+		return;
+	}
+
+	/*
+	 * very simple loop because we get interrupts only when receiving
+	 */
+	while (simeth_rx(dev));
+}
+
+static struct net_device_stats *
+simeth_get_stats(struct net_device *dev)
+{
+	struct simeth_local  *local = (struct simeth_local *) dev->priv;
+
+	return &local->stats;
+}
+
+/* fake multicast ability */
+static void
+set_multicast_list(struct net_device *dev)
+{
+	printk(KERN_WARNING "%s: set_multicast_list called\n", dev->name);
+}
+
+#ifdef CONFIG_NET_FASTROUTE
+static int
+simeth_accept_fastpath(struct net_device *dev, struct dst_entry *dst)
+{
+	printk(KERN_WARNING "%s: simeth_accept_fastpath called\n", dev->name);
+	return -1;
+}
+#endif
+
+__initcall(simeth_probe);
diff -urN linux-2.4.23-pre6/arch/ia64/drivers/simscsi.c linux-2.4.23-pre7/arch/ia64/drivers/simscsi.c
--- linux-2.4.23-pre6/arch/ia64/drivers/simscsi.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/arch/ia64/drivers/simscsi.c	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,396 @@
+/*
+ * Simulated SCSI driver.
+ *
+ * Copyright (C) 1999, 2001-2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * 02/01/15 David Mosberger	Updated for v2.5.1
+ * 99/12/18 David Mosberger	Added support for READ10/WRITE10 needed by linux v2.3.33
+ */
+#include <linux/config.h>
+#include <linux/blk.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+
+#include <scsi/scsi.h>
+
+#include <asm/irq.h>
+
+#include "../drivers/scsi/scsi.h"
+#include "../drivers/scsi/sd.h"
+#include "../drivers/scsi/hosts.h"
+#include "simscsi.h"
+
+#define DEBUG_SIMSCSI	1
+
+/* Simulator system calls: */
+
+#define SSC_OPEN			50
+#define SSC_CLOSE			51
+#define SSC_READ			52
+#define SSC_WRITE			53
+#define SSC_GET_COMPLETION		54
+#define SSC_WAIT_COMPLETION		55
+
+#define SSC_WRITE_ACCESS		2
+#define SSC_READ_ACCESS			1
+
+#if DEBUG_SIMSCSI
+  int simscsi_debug;
+# define DBG	simscsi_debug
+#else
+# define DBG	0
+#endif
+
+static void simscsi_interrupt (unsigned long val);
+DECLARE_TASKLET(simscsi_tasklet, simscsi_interrupt, 0);
+
+struct disk_req {
+	unsigned long addr;
+	unsigned len;
+};
+
+struct disk_stat {
+	int fd;
+	unsigned count;
+};
+
+extern long ia64_ssc (long arg0, long arg1, long arg2, long arg3, int nr);
+
+static int desc[16] = {
+	-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
+};
+
+static struct queue_entry {
+	Scsi_Cmnd *sc;
+} queue[SIMSCSI_REQ_QUEUE_LEN];
+
+static int rd, wr;
+static atomic_t num_reqs = ATOMIC_INIT(0);
+
+/* base name for default disks */
+static char *simscsi_root = DEFAULT_SIMSCSI_ROOT;
+
+#define MAX_ROOT_LEN	128
+
+/*
+ * used to setup a new base for disk images
+ * to use /foo/bar/disk[a-z] as disk images
+ * you have to specify simscsi=/foo/bar/disk on the command line
+ */
+static int __init
+simscsi_setup (char *s)
+{
+	/* XXX Fix me we may need to strcpy() ? */
+	if (strlen(s) > MAX_ROOT_LEN) {
+		printk(KERN_ERR "simscsi_setup: prefix too long---using default %s\n",
+		       simscsi_root);
+	}
+	simscsi_root = s;
+	return 1;
+}
+
+__setup("simscsi=", simscsi_setup);
+
+static void
+simscsi_interrupt (unsigned long val)
+{
+	unsigned long flags;
+	Scsi_Cmnd *sc;
+
+	spin_lock_irqsave(&io_request_lock, flags);
+	{
+		while ((sc = queue[rd].sc) != 0) {
+			atomic_dec(&num_reqs);
+			queue[rd].sc = 0;
+			if (DBG)
+				printk("simscsi_interrupt: done with %ld\n", sc->serial_number);
+			(*sc->scsi_done)(sc);
+			rd = (rd + 1) % SIMSCSI_REQ_QUEUE_LEN;
+		}
+	}
+	spin_unlock_irqrestore(&io_request_lock, flags);
+}
+
+int
+simscsi_detect (Scsi_Host_Template *templ)
+{
+	templ->proc_name = "simscsi";
+	return 1;	/* fake one SCSI host adapter */
+}
+
+int
+simscsi_release (struct Scsi_Host *host)
+{
+	return 0;	/* this is easy...  */
+}
+
+const char *
+simscsi_info (struct Scsi_Host *host)
+{
+	return "simulated SCSI host adapter";
+}
+
+int
+simscsi_biosparam (Disk *disk, kdev_t n, int ip[])
+{
+	unsigned capacity = disk->capacity;
+
+	ip[0] = 64;		/* heads */
+	ip[1] = 32;		/* sectors */
+	ip[2] = capacity >> 11;	/* cylinders */
+	return 0;
+}
+
+static void
+simscsi_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset, unsigned long len)
+{
+	struct disk_stat stat;
+	struct disk_req req;
+
+	req.addr = __pa(sc->request_buffer);
+	req.len  = len;			/* # of bytes to transfer */
+
+	if (sc->request_bufflen < req.len)
+		return;
+
+	stat.fd = desc[sc->target];
+	if (DBG)
+		printk("simscsi_%s @ %lx (off %lx)\n",
+		       mode == SSC_READ ? "read":"write", req.addr, offset);
+	ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
+	ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+
+	if (stat.count == req.len) {
+		sc->result = GOOD;
+	} else {
+		sc->result = DID_ERROR << 16;
+	}
+}
+
+static void
+simscsi_sg_readwrite (Scsi_Cmnd *sc, int mode, unsigned long offset)
+{
+	int list_len = sc->use_sg;
+	struct scatterlist *sl = (struct scatterlist *)sc->buffer;
+	struct disk_stat stat;
+	struct disk_req req;
+
+	stat.fd = desc[sc->target];
+
+	while (list_len) {
+		req.addr = __pa(sl->address);
+		req.len  = sl->length;
+		if (DBG)
+			printk("simscsi_sg_%s @ %lx (off %lx) use_sg=%d len=%d\n",
+			       mode == SSC_READ ? "read":"write", req.addr, offset,
+			       list_len, sl->length);
+		ia64_ssc(stat.fd, 1, __pa(&req), offset, mode);
+		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+
+		/* should not happen in our case */
+		if (stat.count != req.len) {
+			sc->result = DID_ERROR << 16;
+			return;
+		}
+		offset +=  sl->length;
+		sl++;
+		list_len--;
+	}
+	sc->result = GOOD;
+}
+
+/*
+ * function handling both READ_6/WRITE_6 (non-scatter/gather mode)
+ * commands.
+ * Added 02/26/99 S.Eranian
+ */
+static void
+simscsi_readwrite6 (Scsi_Cmnd *sc, int mode)
+{
+	unsigned long offset;
+
+	offset = (((sc->cmnd[1] & 0x1f) << 16) | (sc->cmnd[2] << 8) | sc->cmnd[3])*512;
+	if (sc->use_sg > 0)
+		simscsi_sg_readwrite(sc, mode, offset);
+	else
+		simscsi_readwrite(sc, mode, offset, sc->cmnd[4]*512);
+}
+
+static size_t
+simscsi_get_disk_size (int fd)
+{
+	struct disk_stat stat;
+	size_t bit, sectors = 0;
+	struct disk_req req;
+	char buf[512];
+
+	/*
+	 * This is a bit kludgey: the simulator doesn't provide a direct way of determining
+	 * the disk size, so we do a binary search, assuming a maximum disk size of 4GB.
+	 */
+	for (bit = (4UL << 30)/512; bit != 0; bit >>= 1) {
+		req.addr = __pa(&buf);
+		req.len = sizeof(buf);
+		ia64_ssc(fd, 1, __pa(&req), ((sectors | bit) - 1)*512, SSC_READ);
+		stat.fd = fd;
+		ia64_ssc(__pa(&stat), 0, 0, 0, SSC_WAIT_COMPLETION);
+		if (stat.count == sizeof(buf))
+			sectors |= bit;
+	}
+	return sectors - 1;	/* return last valid sector number */
+}
+
+static void
+simscsi_readwrite10 (Scsi_Cmnd *sc, int mode)
+{
+	unsigned long offset;
+
+	offset = (  (sc->cmnd[2] << 24) | (sc->cmnd[3] << 16)
+		  | (sc->cmnd[4] <<  8) | (sc->cmnd[5] <<  0))*512;
+	if (sc->use_sg > 0)
+		simscsi_sg_readwrite(sc, mode, offset);
+	else
+		simscsi_readwrite(sc, mode, offset, ((sc->cmnd[7] << 8) | sc->cmnd[8])*512);
+}
+
+int
+simscsi_queuecommand (Scsi_Cmnd *sc, void (*done)(Scsi_Cmnd *))
+{
+	char fname[MAX_ROOT_LEN+16];
+	size_t disk_size;
+	char *buf;
+#if DEBUG_SIMSCSI
+	register long sp asm ("sp");
+
+	if (DBG)
+		printk("simscsi_queuecommand: target=%d,cmnd=%u,sc=%lu,sp=%lx,done=%p\n",
+		       sc->target, sc->cmnd[0], sc->serial_number, sp, done);
+#endif
+
+	sc->result = DID_BAD_TARGET << 16;
+	sc->scsi_done = done;
+	if (sc->target <= 15 && sc->lun == 0) {
+		switch (sc->cmnd[0]) {
+		      case INQUIRY:
+			if (sc->request_bufflen < 35) {
+				break;
+			}
+			sprintf (fname, "%s%c", simscsi_root, 'a' + sc->target);
+			desc[sc->target] = ia64_ssc(__pa(fname), SSC_READ_ACCESS|SSC_WRITE_ACCESS,
+						    0, 0, SSC_OPEN);
+			if (desc[sc->target] < 0) {
+				/* disk doesn't exist... */
+				break;
+			}
+			buf = sc->request_buffer;
+			buf[0] = 0;	/* magnetic disk */
+			buf[1] = 0;	/* not a removable medium */
+			buf[2] = 2;	/* SCSI-2 compliant device */
+			buf[3] = 2;	/* SCSI-2 response data format */
+			buf[4] = 31;	/* additional length (bytes) */
+			buf[5] = 0;	/* reserved */
+			buf[6] = 0;	/* reserved */
+			buf[7] = 0;	/* various flags */
+			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
+			sc->result = GOOD;
+			break;
+
+		      case TEST_UNIT_READY:
+			sc->result = GOOD;
+			break;
+
+		      case READ_6:
+			if (desc[sc->target] < 0 )
+				break;
+			simscsi_readwrite6(sc, SSC_READ);
+			break;
+
+		      case READ_10:
+			if (desc[sc->target] < 0 )
+				break;
+			simscsi_readwrite10(sc, SSC_READ);
+			break;
+
+		      case WRITE_6:
+			if (desc[sc->target] < 0)
+				break;
+			simscsi_readwrite6(sc, SSC_WRITE);
+			break;
+
+		      case WRITE_10:
+			if (desc[sc->target] < 0)
+				break;
+			simscsi_readwrite10(sc, SSC_WRITE);
+			break;
+
+
+		      case READ_CAPACITY:
+			if (desc[sc->target] < 0 || sc->request_bufflen < 8) {
+				break;
+			}
+			buf = sc->request_buffer;
+
+			disk_size = simscsi_get_disk_size(desc[sc->target]);
+			buf[0] = (disk_size >> 24) & 0xff;
+			buf[1] = (disk_size >> 16) & 0xff;
+			buf[2] = (disk_size >>  8) & 0xff;
+			buf[3] = (disk_size >>  0) & 0xff;
+			/* set block size of 512 bytes: */
+			buf[4] = 0;
+			buf[5] = 0;
+			buf[6] = 2;
+			buf[7] = 0;
+			sc->result = GOOD;
+			break;
+
+		      case MODE_SENSE:
+			/* sd.c uses this to determine whether disk does write-caching. */
+			memset(sc->request_buffer, 0, 128);
+			sc->result = GOOD;
+			break;
+
+		      case START_STOP:
+			printk(KERN_ERR "START_STOP\n");
+			break;
+
+		      default:
+			panic("simscsi: unknown SCSI command %u\n", sc->cmnd[0]);
+		}
+	}
+	if (sc->result == DID_BAD_TARGET) {
+		sc->result |= DRIVER_SENSE << 24;
+		sc->sense_buffer[0] = 0x70;
+		sc->sense_buffer[2] = 0x00;
+	}
+	if (atomic_read(&num_reqs) >= SIMSCSI_REQ_QUEUE_LEN) {
+		panic("Attempt to queue command while command is pending!!");
+	}
+	atomic_inc(&num_reqs);
+	queue[wr].sc = sc;
+	wr = (wr + 1) % SIMSCSI_REQ_QUEUE_LEN;
+
+	tasklet_schedule(&simscsi_tasklet);
+	return 0;
+}
+
+int
+simscsi_reset (Scsi_Cmnd *cmd, unsigned int reset_flags)
+{
+	printk(KERN_ERR "simscsi_reset: unimplemented\n");
+	return SCSI_RESET_SUCCESS;
+}
+
+int
+simscsi_abort (Scsi_Cmnd *cmd)
+{
+	printk(KERN_ERR "simscsi_abort: unimplemented\n");
+	return SCSI_ABORT_SUCCESS;
+}
+
+static Scsi_Host_Template driver_template = SIMSCSI;
+
+#include "../drivers/scsi/scsi_module.c"
diff -urN linux-2.4.23-pre6/arch/ia64/drivers/simscsi.h linux-2.4.23-pre7/arch/ia64/drivers/simscsi.h
--- linux-2.4.23-pre6/arch/ia64/drivers/simscsi.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/arch/ia64/drivers/simscsi.h	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,39 @@
+/*
+ * Simulated SCSI driver.
+ *
+ * Copyright (C) 1999, 2002 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+#ifndef SIMSCSI_H
+#define SIMSCSI_H
+
+#define SIMSCSI_REQ_QUEUE_LEN	64
+
+#define DEFAULT_SIMSCSI_ROOT	"/var/ski-disks/sd"
+
+extern int simscsi_detect (Scsi_Host_Template *);
+extern int simscsi_release (struct Scsi_Host *);
+extern const char *simscsi_info (struct Scsi_Host *);
+extern int simscsi_queuecommand (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+extern int simscsi_abort (Scsi_Cmnd *);
+extern int simscsi_reset (Scsi_Cmnd *, unsigned int);
+extern int simscsi_biosparam (Disk *, kdev_t, int[]);
+
+#define SIMSCSI {						\
+	.detect			= simscsi_detect,		\
+	.release		= simscsi_release,		\
+	.info			= simscsi_info,			\
+	.queuecommand		= simscsi_queuecommand,		\
+	.abort			= simscsi_abort,		\
+	.reset			= simscsi_reset,		\
+	.bios_param		= simscsi_biosparam,		\
+	.can_queue		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.this_id		= -1,				\
+	.sg_tablesize		= SG_ALL,			\
+	.cmd_per_lun		= SIMSCSI_REQ_QUEUE_LEN,	\
+	.present		= 0,				\
+	.unchecked_isa_dma	= 0,				\
+	.use_clustering		= DISABLE_CLUSTERING		\
+}
+
+#endif /* SIMSCSI_H */
diff -urN linux-2.4.23-pre6/arch/ia64/drivers/simserial.c linux-2.4.23-pre7/arch/ia64/drivers/simserial.c
--- linux-2.4.23-pre6/arch/ia64/drivers/simserial.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/arch/ia64/drivers/simserial.c	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,1094 @@
+/*
+ * Simulated Serial Driver (fake serial)
+ *
+ * This driver is mostly used for bringup purposes and will go away.
+ * It has a strong dependency on the system console. All outputs
+ * are rerouted to the same facility as the one used by printk which, in our
+ * case means sys_sim.c console (goes via the simulator). The code hereafter
+ * is completely leveraged from the serial.c driver.
+ *
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
+ *	Stephane Eranian <eranian@hpl.hp.com>
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * 02/04/00 D. Mosberger	Merged in serial.c bug fixes in rs_close().
+ * 02/25/00 D. Mosberger	Synced up with 2.3.99pre-5 version of serial.c.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/major.h>
+#include <linux/fcntl.h>
+#include <linux/mm.h>
+#include <linux/slab.h>
+#include <linux/console.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/serialP.h>
+
+#include <asm/irq.h>
+#include <asm/uaccess.h>
+
+#undef SIMSERIAL_DEBUG	/* define this to get some debug information */
+
+#define KEYBOARD_INTR	3	/* must match with simulator! */
+
+#define NR_PORTS	1	/* only one port for now */
+#define SERIAL_INLINE	1
+
+#ifdef SERIAL_INLINE
+#define _INLINE_ inline
+#endif
+
+#ifndef MIN
+#define MIN(a,b)	((a) < (b) ? (a) : (b))
+#endif
+
+#define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
+
+#define SSC_GETCHAR	21
+
+extern long ia64_ssc (long, long, long, long, int);
+extern void ia64_ssc_connect_irq (long intr, long irq);
+
+static char *serial_name = "SimSerial driver";
+static char *serial_version = "0.6";
+
+/*
+ * This has been extracted from asm/serial.h. We need one eventually but
+ * I don't know exactly what we're going to put in it so just fake one
+ * for now.
+ */
+#define BASE_BAUD ( 1843200 / 16 )
+
+#define STD_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+
+/*
+ * Most of the values here are meaningless to this particular driver.
+ * However some values must be preserved for the code (leveraged from serial.c
+ * to work correctly).
+ * port must not be 0
+ * type must not be UNKNOWN
+ * So I picked arbitrary (guess from where?) values instead
+ */
+static struct serial_state rs_table[NR_PORTS]={
+  /* UART CLK   PORT IRQ     FLAGS        */
+  { 0, BASE_BAUD, 0x3F8, 0, STD_COM_FLAGS,0,PORT_16550 }  /* ttyS0 */
+};
+
+/*
+ * Just for the fun of it !
+ */
+static struct serial_uart_config uart_config[] = {
+	{ "unknown", 1, 0 },
+	{ "8250", 1, 0 },
+	{ "16450", 1, 0 },
+	{ "16550", 1, 0 },
+	{ "16550A", 16, UART_CLEAR_FIFO | UART_USE_FIFO },
+	{ "cirrus", 1, 0 },
+	{ "ST16650", 1, UART_CLEAR_FIFO | UART_STARTECH },
+	{ "ST16650V2", 32, UART_CLEAR_FIFO | UART_USE_FIFO |
+		  UART_STARTECH },
+	{ "TI16750", 64, UART_CLEAR_FIFO | UART_USE_FIFO},
+	{ 0, 0}
+};
+
+static struct tty_driver serial_driver, callout_driver;
+static int serial_refcount;
+
+static struct async_struct *IRQ_ports[NR_IRQS];
+static struct tty_struct *serial_table[NR_PORTS];
+static struct termios *serial_termios[NR_PORTS];
+static struct termios *serial_termios_locked[NR_PORTS];
+
+static struct console *console;
+
+static unsigned char *tmp_buf;
+static DECLARE_MUTEX(tmp_buf_sem);
+
+extern struct console *console_drivers; /* from kernel/printk.c */
+
+/*
+ * ------------------------------------------------------------
+ * rs_stop() and rs_start()
+ *
+ * This routines are called before setting or resetting tty->stopped.
+ * They enable or disable transmitter interrupts, as necessary.
+ * ------------------------------------------------------------
+ */
+static void rs_stop(struct tty_struct *tty)
+{
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_stop: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
+		tty->stopped, tty->hw_stopped, tty->flow_stopped);
+#endif
+
+}
+
+static void rs_start(struct tty_struct *tty)
+{
+#if SIMSERIAL_DEBUG
+	printk("rs_start: tty->stopped=%d tty->hw_stopped=%d tty->flow_stopped=%d\n",
+		tty->stopped, tty->hw_stopped, tty->flow_stopped);
+#endif
+}
+
+static  void receive_chars(struct tty_struct *tty, struct pt_regs *regs)
+{
+	unsigned char ch;
+	static unsigned char seen_esc = 0;
+
+	while ( (ch = ia64_ssc(0, 0, 0, 0, SSC_GETCHAR)) ) {
+		if ( ch == 27 && seen_esc == 0 ) {
+			seen_esc = 1;
+			continue;
+		} else {
+			if ( seen_esc==1 && ch == 'O' ) {
+				seen_esc = 2;
+				continue;
+			} else if ( seen_esc == 2 ) {
+				if ( ch == 'P' ) show_state();		/* F1 key */
+				if ( ch == 'Q' ) show_buffers();	/* F2 key */
+				seen_esc = 0;
+				continue;
+			}
+		}
+		seen_esc = 0;
+		if (tty->flip.count >= TTY_FLIPBUF_SIZE) break;
+
+		*tty->flip.char_buf_ptr = ch;
+
+		*tty->flip.flag_buf_ptr = 0;
+
+		tty->flip.flag_buf_ptr++;
+		tty->flip.char_buf_ptr++;
+		tty->flip.count++;
+	}
+	tty_flip_buffer_push(tty);
+}
+
+/*
+ * This is the serial driver's interrupt routine for a single port
+ */
+static void rs_interrupt_single(int irq, void *dev_id, struct pt_regs * regs)
+{
+	struct async_struct * info;
+
+	/*
+	 * I don't know exactly why they don't use the dev_id opaque data
+	 * pointer instead of this extra lookup table
+	 */
+	info = IRQ_ports[irq];
+	if (!info || !info->tty) {
+		printk(KERN_INFO "simrs_interrupt_single: info|tty=0 info=%p problem\n", info);
+		return;
+	}
+	/*
+	 * pretty simple in our case, because we only get interrupts
+	 * on inbound traffic
+	 */
+	receive_chars(info->tty, regs);
+}
+
+/*
+ * -------------------------------------------------------------------
+ * Here ends the serial interrupt routines.
+ * -------------------------------------------------------------------
+ */
+
+#if 0
+/*
+ * not really used in our situation so keep them commented out for now
+ */
+static DECLARE_TASK_QUEUE(tq_serial); /* used to be at the top of the file */
+static void do_serial_bh(void)
+{
+	run_task_queue(&tq_serial);
+	printk(KERN_ERR "do_serial_bh: called\n");
+}
+#endif
+
+static void do_softint(void *private_)
+{
+	printk(KERN_ERR "simserial: do_softint called\n");
+}
+
+static void rs_put_char(struct tty_struct *tty, unsigned char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf) return;
+
+	save_flags(flags); cli();
+	if (CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE) == 0) {
+		restore_flags(flags);
+		return;
+	}
+	info->xmit.buf[info->xmit.head] = ch;
+	info->xmit.head = (info->xmit.head + 1) & (SERIAL_XMIT_SIZE-1);
+	restore_flags(flags);
+}
+
+static _INLINE_ void transmit_chars(struct async_struct *info, int *intr_done)
+{
+	int count;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+
+	if (info->x_char) {
+		char c = info->x_char;
+
+		console->write(console, &c, 1);
+
+		info->state->icount.tx++;
+		info->x_char = 0;
+
+		goto out;
+	}
+
+	if (info->xmit.head == info->xmit.tail || info->tty->stopped || info->tty->hw_stopped) {
+#ifdef SIMSERIAL_DEBUG
+		printk("transmit_chars: head=%d, tail=%d, stopped=%d\n",
+		       info->xmit.head, info->xmit.tail, info->tty->stopped);
+#endif
+		goto out;
+	}
+	/*
+	 * We removed the loop and try to do it in to chunks. We need
+	 * 2 operations maximum because it's a ring buffer.
+	 *
+	 * First from current to tail if possible.
+	 * Then from the beginning of the buffer until necessary
+	 */
+
+	count = MIN(CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE),
+		    SERIAL_XMIT_SIZE - info->xmit.tail);
+	console->write(console, info->xmit.buf+info->xmit.tail, count);
+
+	info->xmit.tail = (info->xmit.tail+count) & (SERIAL_XMIT_SIZE-1);
+
+	/*
+	 * We have more at the beginning of the buffer
+	 */
+	count = CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+	if (count) {
+		console->write(console, info->xmit.buf, count);
+		info->xmit.tail += count;
+	}
+out:
+	restore_flags(flags);
+}
+
+static void rs_flush_chars(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (info->xmit.head == info->xmit.tail || tty->stopped || tty->hw_stopped ||
+	    !info->xmit.buf)
+		return;
+
+	transmit_chars(info, NULL);
+}
+
+
+static int rs_write(struct tty_struct * tty, int from_user,
+		    const unsigned char *buf, int count)
+{
+	int	c, ret = 0;
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	if (!tty || !info->xmit.buf || !tmp_buf) return 0;
+
+	save_flags(flags);
+	if (from_user) {
+		down(&tmp_buf_sem);
+		while (1) {
+			int c1;
+			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0)
+				break;
+
+			c -= copy_from_user(tmp_buf, buf, c);
+			if (!c) {
+				if (!ret)
+					ret = -EFAULT;
+				break;
+			}
+			cli();
+			c1 = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (c1 < c)
+				c = c1;
+			memcpy(info->xmit.buf + info->xmit.head, tmp_buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			restore_flags(flags);
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		up(&tmp_buf_sem);
+	} else {
+		cli();
+		while (1) {
+			c = CIRC_SPACE_TO_END(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+			if (count < c)
+				c = count;
+			if (c <= 0) {
+				break;
+			}
+			memcpy(info->xmit.buf + info->xmit.head, buf, c);
+			info->xmit.head = ((info->xmit.head + c) &
+					   (SERIAL_XMIT_SIZE-1));
+			buf += c;
+			count -= c;
+			ret += c;
+		}
+		restore_flags(flags);
+	}
+	/*
+	 * Hey, we transmit directly from here in our case
+	 */
+	if (CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE)
+	    && !tty->stopped && !tty->hw_stopped) {
+		transmit_chars(info, NULL);
+	}
+	return ret;
+}
+
+static int rs_write_room(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_SPACE(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static int rs_chars_in_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	return CIRC_CNT(info->xmit.head, info->xmit.tail, SERIAL_XMIT_SIZE);
+}
+
+static void rs_flush_buffer(struct tty_struct *tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+	unsigned long flags;
+
+	save_flags(flags); cli();
+	info->xmit.head = info->xmit.tail = 0;
+	restore_flags(flags);
+
+	wake_up_interruptible(&tty->write_wait);
+
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
+	    tty->ldisc.write_wakeup)
+		(tty->ldisc.write_wakeup)(tty);
+}
+
+/*
+ * This function is used to send a high-priority XON/XOFF character to
+ * the device
+ */
+static void rs_send_xchar(struct tty_struct *tty, char ch)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	info->x_char = ch;
+	if (ch) {
+		/*
+		 * I guess we could call console->write() directly but
+		 * let's do that for now.
+		 */
+		transmit_chars(info, NULL);
+	}
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_throttle()
+ *
+ * This routine is called by the upper-layer tty layer to signal that
+ * incoming characters should be throttled.
+ * ------------------------------------------------------------
+ */
+static void rs_throttle(struct tty_struct * tty)
+{
+	if (I_IXOFF(tty)) rs_send_xchar(tty, STOP_CHAR(tty));
+
+	printk(KERN_INFO "simrs_throttle called\n");
+}
+
+static void rs_unthrottle(struct tty_struct * tty)
+{
+	struct async_struct *info = (struct async_struct *)tty->driver_data;
+
+	if (I_IXOFF(tty)) {
+		if (info->x_char)
+			info->x_char = 0;
+		else
+			rs_send_xchar(tty, START_CHAR(tty));
+	}
+	printk(KERN_INFO "simrs_unthrottle called\n");
+}
+
+/*
+ * rs_break() --- routine which turns the break handling on or off
+ */
+static void rs_break(struct tty_struct *tty, int break_state)
+{
+}
+
+static int rs_ioctl(struct tty_struct *tty, struct file * file,
+		    unsigned int cmd, unsigned long arg)
+{
+	if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) &&
+	    (cmd != TIOCSERCONFIG) && (cmd != TIOCSERGSTRUCT) &&
+	    (cmd != TIOCMIWAIT) && (cmd != TIOCGICOUNT)) {
+		if (tty->flags & (1 << TTY_IO_ERROR))
+		    return -EIO;
+	}
+
+	switch (cmd) {
+		case TIOCMGET:
+			printk(KERN_INFO "rs_ioctl: TIOCMGET called\n");
+			return -EINVAL;
+		case TIOCMBIS:
+		case TIOCMBIC:
+		case TIOCMSET:
+			printk(KERN_INFO "rs_ioctl: TIOCMBIS/BIC/SET called\n");
+			return -EINVAL;
+		case TIOCGSERIAL:
+			printk(KERN_INFO "simrs_ioctl TIOCGSERIAL called\n");
+			return 0;
+		case TIOCSSERIAL:
+			printk(KERN_INFO "simrs_ioctl TIOCSSERIAL called\n");
+			return 0;
+		case TIOCSERCONFIG:
+			printk(KERN_INFO "rs_ioctl: TIOCSERCONFIG called\n");
+			return -EINVAL;
+
+		case TIOCSERGETLSR: /* Get line status register */
+			printk(KERN_INFO "rs_ioctl: TIOCSERGETLSR called\n");
+			return  -EINVAL;
+
+		case TIOCSERGSTRUCT:
+			printk(KERN_INFO "rs_ioctl: TIOCSERGSTRUCT called\n");
+#if 0
+			if (copy_to_user((struct async_struct *) arg,
+					 info, sizeof(struct async_struct)))
+				return -EFAULT;
+#endif
+			return 0;
+
+		/*
+		 * Wait for any of the 4 modem inputs (DCD,RI,DSR,CTS) to change
+		 * - mask passed in arg for lines of interest
+		 *   (use |'ed TIOCM_RNG/DSR/CD/CTS for masking)
+		 * Caller should use TIOCGICOUNT to see which one it was
+		 */
+		case TIOCMIWAIT:
+			printk(KERN_INFO "rs_ioctl: TIOCMIWAIT: called\n");
+			return 0;
+		/*
+		 * Get counter of input serial line interrupts (DCD,RI,DSR,CTS)
+		 * Return: write counters to the user passed counter struct
+		 * NB: both 1->0 and 0->1 transitions are counted except for
+		 *     RI where only 0->1 is counted.
+		 */
+		case TIOCGICOUNT:
+			printk(KERN_INFO "rs_ioctl: TIOCGICOUNT called\n");
+			return 0;
+
+		case TIOCSERGWILD:
+		case TIOCSERSWILD:
+			/* "setserial -W" is called in Debian boot */
+			printk (KERN_INFO "TIOCSER?WILD ioctl obsolete, ignored.\n");
+			return 0;
+
+		default:
+			return -ENOIOCTLCMD;
+		}
+	return 0;
+}
+
+#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
+
+static void rs_set_termios(struct tty_struct *tty, struct termios *old_termios)
+{
+	unsigned int cflag = tty->termios->c_cflag;
+
+	if (   (cflag == old_termios->c_cflag)
+	    && (   RELEVANT_IFLAG(tty->termios->c_iflag)
+		== RELEVANT_IFLAG(old_termios->c_iflag)))
+	  return;
+
+
+	/* Handle turning off CRTSCTS */
+	if ((old_termios->c_cflag & CRTSCTS) &&
+	    !(tty->termios->c_cflag & CRTSCTS)) {
+		tty->hw_stopped = 0;
+		rs_start(tty);
+	}
+}
+/*
+ * This routine will shutdown a serial port; interrupts are disabled, and
+ * DTR is dropped if the hangup on close termio flag is on.
+ */
+static void shutdown(struct async_struct * info)
+{
+	unsigned long	flags;
+	struct serial_state *state;
+	int		retval;
+
+	if (!(info->flags & ASYNC_INITIALIZED)) return;
+
+	state = info->state;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("Shutting down serial port %d (irq %d)....", info->line,
+	       state->irq);
+#endif
+
+	save_flags(flags); cli(); /* Disable interrupts */
+
+	/*
+	 * First unlink the serial port from the IRQ chain...
+	 */
+	if (info->next_port)
+		info->next_port->prev_port = info->prev_port;
+	if (info->prev_port)
+		info->prev_port->next_port = info->next_port;
+	else
+		IRQ_ports[state->irq] = info->next_port;
+
+	/*
+	 * Free the IRQ, if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			free_irq(state->irq, NULL);
+			retval = request_irq(state->irq, rs_interrupt_single,
+					     IRQ_T(info), "serial", NULL);
+
+			if (retval)
+				printk(KERN_ERR "serial shutdown: request_irq: error %d"
+				       "  Couldn't reacquire IRQ.\n", retval);
+		} else
+			free_irq(state->irq, NULL);
+	}
+
+	if (info->xmit.buf) {
+		free_page((unsigned long) info->xmit.buf);
+		info->xmit.buf = 0;
+	}
+
+	if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->flags &= ~ASYNC_INITIALIZED;
+	restore_flags(flags);
+}
+
+/*
+ * ------------------------------------------------------------
+ * rs_close()
+ *
+ * This routine is called when the serial port gets closed.  First, we
+ * wait for the last remaining data to be sent.  Then, we unlink its
+ * async structure from the interrupt chain if necessary, and we free
+ * that IRQ if nothing is left in the chain.
+ * ------------------------------------------------------------
+ */
+static void rs_close(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state;
+	unsigned long flags;
+
+	if (!info ) return;
+
+	state = info->state;
+
+	save_flags(flags); cli();
+
+	if (tty_hung_up_p(filp)) {
+#ifdef SIMSERIAL_DEBUG
+		printk("rs_close: hung_up\n");
+#endif
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_close ttys%d, count = %d\n", info->line, state->count);
+#endif
+	if ((tty->count == 1) && (state->count != 1)) {
+		/*
+		 * Uh, oh.  tty->count is 1, which means that the tty
+		 * structure will be freed.  state->count should always
+		 * be one in these conditions.  If it's greater than
+		 * one, we've got real problems, since it means the
+		 * serial port won't be shutdown.
+		 */
+		printk(KERN_ERR "rs_close: bad serial port count; tty->count is 1, "
+		       "state->count is %d\n", state->count);
+		state->count = 1;
+	}
+	if (--state->count < 0) {
+		printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
+		       info->line, state->count);
+		state->count = 0;
+	}
+	if (state->count) {
+		MOD_DEC_USE_COUNT;
+		restore_flags(flags);
+		return;
+	}
+	info->flags |= ASYNC_CLOSING;
+	restore_flags(flags);
+
+	/*
+	 * Now we wait for the transmit buffer to clear; and we notify
+	 * the line discipline to only process XON/XOFF characters.
+	 */
+	shutdown(info);
+	if (tty->driver.flush_buffer) tty->driver.flush_buffer(tty);
+	if (tty->ldisc.flush_buffer) tty->ldisc.flush_buffer(tty);
+	info->event = 0;
+	info->tty = 0;
+	if (info->blocked_open) {
+		if (info->close_delay) {
+			current->state = TASK_INTERRUPTIBLE;
+			schedule_timeout(info->close_delay);
+		}
+		wake_up_interruptible(&info->open_wait);
+	}
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE|ASYNC_CLOSING);
+	wake_up_interruptible(&info->close_wait);
+	MOD_DEC_USE_COUNT;
+}
+
+/*
+ * rs_wait_until_sent() --- wait until the transmitter is empty
+ */
+static void rs_wait_until_sent(struct tty_struct *tty, int timeout)
+{
+}
+
+
+/*
+ * rs_hangup() --- called by tty_hangup() when a hangup is signaled.
+ */
+static void rs_hangup(struct tty_struct *tty)
+{
+	struct async_struct * info = (struct async_struct *)tty->driver_data;
+	struct serial_state *state = info->state;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_hangup: called\n");
+#endif
+
+	state = info->state;
+
+	rs_flush_buffer(tty);
+	if (info->flags & ASYNC_CLOSING)
+		return;
+	shutdown(info);
+
+	info->event = 0;
+	state->count = 0;
+	info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CALLOUT_ACTIVE);
+	info->tty = 0;
+	wake_up_interruptible(&info->open_wait);
+}
+
+
+static int get_async_struct(int line, struct async_struct **ret_info)
+{
+	struct async_struct *info;
+	struct serial_state *sstate;
+
+	sstate = rs_table + line;
+	sstate->count++;
+	if (sstate->info) {
+		*ret_info = sstate->info;
+		return 0;
+	}
+	info = kmalloc(sizeof(struct async_struct), GFP_KERNEL);
+	if (!info) {
+		sstate->count--;
+		return -ENOMEM;
+	}
+	memset(info, 0, sizeof(struct async_struct));
+	init_waitqueue_head(&info->open_wait);
+	init_waitqueue_head(&info->close_wait);
+	init_waitqueue_head(&info->delta_msr_wait);
+	info->magic = SERIAL_MAGIC;
+	info->port = sstate->port;
+	info->flags = sstate->flags;
+	info->xmit_fifo_size = sstate->xmit_fifo_size;
+	info->line = line;
+	info->tqueue.routine = do_softint;
+	info->tqueue.data = info;
+	info->state = sstate;
+	if (sstate->info) {
+		kfree(info);
+		*ret_info = sstate->info;
+		return 0;
+	}
+	*ret_info = sstate->info = info;
+	return 0;
+}
+
+static int
+startup(struct async_struct *info)
+{
+	unsigned long flags;
+	int	retval=0;
+	void (*handler)(int, void *, struct pt_regs *);
+	struct serial_state *state= info->state;
+	unsigned long page;
+
+	page = get_free_page(GFP_KERNEL);
+	if (!page)
+		return -ENOMEM;
+
+	save_flags(flags); cli();
+
+	if (info->flags & ASYNC_INITIALIZED) {
+		free_page(page);
+		goto errout;
+	}
+
+	if (!state->port || !state->type) {
+		if (info->tty) set_bit(TTY_IO_ERROR, &info->tty->flags);
+		free_page(page);
+		goto errout;
+	}
+	if (info->xmit.buf)
+		free_page(page);
+	else
+		info->xmit.buf = (unsigned char *) page;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("startup: ttys%d (irq %d)...", info->line, state->irq);
+#endif
+
+	/*
+	 * Allocate the IRQ if necessary
+	 */
+	if (state->irq && (!IRQ_ports[state->irq] ||
+			  !IRQ_ports[state->irq]->next_port)) {
+		if (IRQ_ports[state->irq]) {
+			retval = -EBUSY;
+			goto errout;
+		} else
+			handler = rs_interrupt_single;
+
+		retval = request_irq(state->irq, handler, IRQ_T(info), "simserial", NULL);
+		if (retval) {
+			if (capable(CAP_SYS_ADMIN)) {
+				if (info->tty)
+					set_bit(TTY_IO_ERROR,
+						&info->tty->flags);
+				retval = 0;
+			}
+			goto errout;
+		}
+	}
+
+	/*
+	 * Insert serial port into IRQ chain.
+	 */
+	info->prev_port = 0;
+	info->next_port = IRQ_ports[state->irq];
+	if (info->next_port)
+		info->next_port->prev_port = info;
+	IRQ_ports[state->irq] = info;
+
+	if (info->tty) clear_bit(TTY_IO_ERROR, &info->tty->flags);
+
+	info->xmit.head = info->xmit.tail = 0;
+
+#if 0
+	/*
+	 * Set up serial timers...
+	 */
+	timer_table[RS_TIMER].expires = jiffies + 2*HZ/100;
+	timer_active |= 1 << RS_TIMER;
+#endif
+
+	/*
+	 * Set up the tty->alt_speed kludge
+	 */
+	if (info->tty) {
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
+			info->tty->alt_speed = 57600;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
+			info->tty->alt_speed = 115200;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
+			info->tty->alt_speed = 230400;
+		if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
+			info->tty->alt_speed = 460800;
+	}
+
+	info->flags |= ASYNC_INITIALIZED;
+	restore_flags(flags);
+	return 0;
+
+errout:
+	restore_flags(flags);
+	return retval;
+}
+
+
+/*
+ * This routine is called whenever a serial port is opened.  It
+ * enables interrupts for a serial port, linking in its async structure into
+ * the IRQ chain.   It also performs the serial-specific
+ * initialization for the tty structure.
+ */
+static int rs_open(struct tty_struct *tty, struct file * filp)
+{
+	struct async_struct	*info;
+	int			retval, line;
+	unsigned long		page;
+
+	MOD_INC_USE_COUNT;
+	line = MINOR(tty->device) - tty->driver.minor_start;
+	if ((line < 0) || (line >= NR_PORTS)) {
+		MOD_DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	retval = get_async_struct(line, &info);
+	if (retval) {
+		MOD_DEC_USE_COUNT;
+		return retval;
+	}
+	tty->driver_data = info;
+	info->tty = tty;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_open %s%d, count = %d\n", tty->driver.name, info->line,
+	       info->state->count);
+#endif
+	info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+
+	if (!tmp_buf) {
+		page = get_free_page(GFP_KERNEL);
+		if (!page) {
+			/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+			return -ENOMEM;
+		}
+		if (tmp_buf)
+			free_page(page);
+		else
+			tmp_buf = (unsigned char *) page;
+	}
+
+	/*
+	 * If the port is the middle of closing, bail out now
+	 */
+	if (tty_hung_up_p(filp) ||
+	    (info->flags & ASYNC_CLOSING)) {
+		if (info->flags & ASYNC_CLOSING)
+			interruptible_sleep_on(&info->close_wait);
+		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+#ifdef SERIAL_DO_RESTART
+		return ((info->flags & ASYNC_HUP_NOTIFY) ?
+			-EAGAIN : -ERESTARTSYS);
+#else
+		return -EAGAIN;
+#endif
+	}
+
+	/*
+	 * Start up serial port
+	 */
+	retval = startup(info);
+	if (retval) {
+		/* MOD_DEC_USE_COUNT; "info->tty" will cause this? */
+		return retval;
+	}
+
+	if ((info->state->count == 1) &&
+	    (info->flags & ASYNC_SPLIT_TERMIOS)) {
+		if (tty->driver.subtype == SERIAL_TYPE_NORMAL)
+			*tty->termios = info->state->normal_termios;
+		else
+			*tty->termios = info->state->callout_termios;
+	}
+
+	/*
+	 * figure out which console to use (should be one already)
+	 */
+	console = console_drivers;
+	while (console) {
+		if ((console->flags & CON_ENABLED) && console->write) break;
+		console = console->next;
+	}
+
+	info->session = current->session;
+	info->pgrp = current->pgrp;
+
+#ifdef SIMSERIAL_DEBUG
+	printk("rs_open ttys%d successful\n", info->line);
+#endif
+	return 0;
+}
+
+/*
+ * /proc fs routines....
+ */
+
+static inline int line_info(char *buf, struct serial_state *state)
+{
+	return sprintf(buf, "%d: uart:%s port:%lX irq:%d\n",
+		       state->line, uart_config[state->type].name,
+		       state->port, state->irq);
+}
+
+static int rs_read_proc(char *page, char **start, off_t off, int count,
+		 int *eof, void *data)
+{
+	int i, len = 0, l;
+	off_t	begin = 0;
+
+	len += sprintf(page, "simserinfo:1.0 driver:%s\n", serial_version);
+	for (i = 0; i < NR_PORTS && len < 4000; i++) {
+		l = line_info(page + len, &rs_table[i]);
+		len += l;
+		if (len+begin > off+count)
+			goto done;
+		if (len+begin < off) {
+			begin += len;
+			len = 0;
+		}
+	}
+	*eof = 1;
+done:
+	if (off >= len+begin)
+		return 0;
+	*start = page + (begin-off);
+	return ((count < begin+len-off) ? count : begin+len-off);
+}
+
+/*
+ * ---------------------------------------------------------------------
+ * rs_init() and friends
+ *
+ * rs_init() is called at boot-time to initialize the serial driver.
+ * ---------------------------------------------------------------------
+ */
+
+/*
+ * This routine prints out the appropriate serial driver version
+ * number, and identifies which options were configured into this
+ * driver.
+ */
+static inline void show_serial_version(void)
+{
+	printk(KERN_INFO "%s version %s with", serial_name, serial_version);
+	printk(KERN_INFO " no serial options enabled\n");
+}
+
+/*
+ * The serial driver boot-time initialization code!
+ */
+static int __init
+simrs_init (void)
+{
+	int			i;
+	struct serial_state	*state;
+
+	show_serial_version();
+
+	/* Initialize the tty_driver structure */
+
+	memset(&serial_driver, 0, sizeof(struct tty_driver));
+	serial_driver.magic = TTY_DRIVER_MAGIC;
+	serial_driver.driver_name = "simserial";
+	serial_driver.name = "ttyS";
+	serial_driver.major = TTY_MAJOR;
+	serial_driver.minor_start = 64;
+	serial_driver.num = 1;
+	serial_driver.type = TTY_DRIVER_TYPE_SERIAL;
+	serial_driver.subtype = SERIAL_TYPE_NORMAL;
+	serial_driver.init_termios = tty_std_termios;
+	serial_driver.init_termios.c_cflag =
+		B9600 | CS8 | CREAD | HUPCL | CLOCAL;
+	serial_driver.flags = TTY_DRIVER_REAL_RAW;
+	serial_driver.refcount = &serial_refcount;
+	serial_driver.table = serial_table;
+	serial_driver.termios = serial_termios;
+	serial_driver.termios_locked = serial_termios_locked;
+
+	serial_driver.open = rs_open;
+	serial_driver.close = rs_close;
+	serial_driver.write = rs_write;
+	serial_driver.put_char = rs_put_char;
+	serial_driver.flush_chars = rs_flush_chars;
+	serial_driver.write_room = rs_write_room;
+	serial_driver.chars_in_buffer = rs_chars_in_buffer;
+	serial_driver.flush_buffer = rs_flush_buffer;
+	serial_driver.ioctl = rs_ioctl;
+	serial_driver.throttle = rs_throttle;
+	serial_driver.unthrottle = rs_unthrottle;
+	serial_driver.send_xchar = rs_send_xchar;
+	serial_driver.set_termios = rs_set_termios;
+	serial_driver.stop = rs_stop;
+	serial_driver.start = rs_start;
+	serial_driver.hangup = rs_hangup;
+	serial_driver.break_ctl = rs_break;
+	serial_driver.wait_until_sent = rs_wait_until_sent;
+	serial_driver.read_proc = rs_read_proc;
+
+	/*
+	 * Let's have a little bit of fun !
+	 */
+	for (i = 0, state = rs_table; i < NR_PORTS; i++,state++) {
+
+		if (state->type == PORT_UNKNOWN) continue;
+
+		if (!state->irq) {
+			state->irq = ia64_alloc_vector();
+			ia64_ssc_connect_irq(KEYBOARD_INTR, state->irq);
+		}
+
+		printk(KERN_INFO "ttyS%02d at 0x%04lx (irq = %d) is a %s\n",
+		       state->line,
+		       state->port, state->irq,
+		       uart_config[state->type].name);
+	}
+	/*
+	 * The callout device is just like normal device except for
+	 * major number and the subtype code.
+	 */
+	callout_driver = serial_driver;
+	callout_driver.name = "cua";
+	callout_driver.major = TTYAUX_MAJOR;
+	callout_driver.subtype = SERIAL_TYPE_CALLOUT;
+	callout_driver.read_proc = 0;
+	callout_driver.proc_entry = 0;
+
+	if (tty_register_driver(&serial_driver))
+		panic("Couldn't register simserial driver\n");
+
+	if (tty_register_driver(&callout_driver))
+		panic("Couldn't register callout driver\n");
+
+	return 0;
+}
+
+#ifndef MODULE
+__initcall(simrs_init);
+#endif
diff -urN linux-2.4.23-pre6/arch/m68k/q40/q40ints.c linux-2.4.23-pre7/arch/m68k/q40/q40ints.c
--- linux-2.4.23-pre6/arch/m68k/q40/q40ints.c	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/m68k/q40/q40ints.c	2003-10-09 17:48:21.000000000 -0700
@@ -124,7 +124,6 @@
 	  case 11: 	      
 	    printk("warning IRQ 10 and 11 not distinguishable\n");
 	    irq=10;
-	  default:
 	  }
 
 	if (irq<Q40_IRQ_SAMPLE)
@@ -171,7 +170,6 @@
 	    printk("%s: ISA IRQ %d from %x invalid\n", __FUNCTION__, irq, (unsigned)dev_id);
 	    return;
 	  case 11: irq=10;
-	  default:
 	  }
 	
 	if (irq<Q40_IRQ_SAMPLE)
@@ -196,7 +194,9 @@
 
 void q40_process_int (int level, struct pt_regs *fp)
 {
-  printk("unexpected interrupt %x\n",level);
+  printk("unexpected interrupt vec=%x, pc=%lx, d0=%lx, d0_orig=%lx, d1=%lx, d2=%lx\n",
+          level, fp->pc, fp->d0, fp->orig_d0, fp->d1, fp->d2);
+  printk("\tIIRQ_REG = %x, EIRQ_REG = %x\n",master_inb(IIRQ_REG),master_inb(EIRQ_REG));
 }
 
 /* 
@@ -313,7 +313,6 @@
   unsigned mir, mer;
   int irq,i;
 
- repeat:
   mir=master_inb(IIRQ_REG);
   if (mir&Q40_IRQ_FRAME_MASK) {
 	  irq_tab[Q40_IRQ_FRAME].count++;
@@ -373,7 +372,6 @@
 				  /*printk("reenabling irq %d\n",irq); */
 #endif
 			  }
-// used to do 'goto repeat;' her, this delayed bh processing too long
 			  return;
 		  }
 	  }
@@ -382,6 +380,7 @@
   } 
  iirq:
   mir=master_inb(IIRQ_REG);
+  /* should test whether keyboard irq is really enabled, doing it in defhand */
   if (mir&Q40_IRQ_KEYB_MASK) {
 	  irq_tab[Q40_IRQ_KEYBOARD].count++;
 	  irq_tab[Q40_IRQ_KEYBOARD].handler(Q40_IRQ_KEYBOARD,irq_tab[Q40_IRQ_KEYBOARD].dev_id,fp);
@@ -408,7 +407,9 @@
 
 static void q40_defhand (int irq, void *dev_id, struct pt_regs *fp)
 {
-	printk ("Unknown q40 interrupt 0x%02x\n", irq);
+        if (irq!=Q40_IRQ_KEYBOARD)
+	     printk ("Unknown q40 interrupt %d\n", irq);
+	else master_outb(-1,KEYBOARD_UNLOCK_REG);
 }
 static void sys_default_handler(int lev, void *dev_id, struct pt_regs *regs)
 {
diff -urN linux-2.4.23-pre6/arch/ppc/8xx_io/uart.c linux-2.4.23-pre7/arch/ppc/8xx_io/uart.c
--- linux-2.4.23-pre6/arch/ppc/8xx_io/uart.c	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/ppc/8xx_io/uart.c	2003-10-09 17:48:21.000000000 -0700
@@ -81,7 +81,11 @@
 #define TX_WAKEUP	ASYNC_SHARE_IRQ
 
 static char *serial_name = "CPM UART driver";
-static char *serial_version = "0.03";
+static char *serial_version = "0.04";
+
+/* TX buffer length used by my_console_write.
+   Assume minumun length until it gets set by this driver */
+static int console_tx_buf_len = 1;
 
 static DECLARE_TASK_QUEUE(tq_serial);
 
@@ -196,6 +200,7 @@
 
 /* The number of buffer descriptors and their sizes.
 */
+#define EARLY_BUF_SIZE	4
 #define RX_NUM_FIFO	4
 #define RX_BUF_SIZE	32
 #define TX_NUM_FIFO	4
@@ -1068,6 +1073,7 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	volatile cbd_t	*bdp;
 	unsigned char *cp;
+	unsigned long flags;
 
 	if (serial_paranoia_check(info, tty->device, "rs_put_char"))
 		return;
@@ -1075,7 +1081,16 @@
 	if (!tty)
 		return;
 
+	local_irq_save(flags);
 	bdp = info->tx_cur;
+	/* Get next BD.
+	*/
+	if (bdp->cbd_sc & BD_SC_WRAP)
+		info->tx_cur = info->tx_bd_base;
+	else
+		info->tx_cur = (cbd_t *)bdp + 1;
+	local_irq_restore(flags);
+
 	while (bdp->cbd_sc & BD_SC_READY);
 
 	cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
@@ -1083,14 +1098,6 @@
 	bdp->cbd_datlen = 1;
 	bdp->cbd_sc |= BD_SC_READY;
 
-	/* Get next BD.
-	*/
-	if (bdp->cbd_sc & BD_SC_WRAP)
-		bdp = info->tx_bd_base;
-	else
-		bdp++;
-
-	info->tx_cur = (cbd_t *)bdp;
 }
 
 static int rs_8xx_write(struct tty_struct * tty, int from_user,
@@ -1100,6 +1107,7 @@
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 	volatile cbd_t *bdp;
 	unsigned char	*cp;
+	unsigned long flags;
 
 #ifdef CONFIG_KGDB_CONSOLE
         /* Try to let stub handle output. Returns true if it did. */
@@ -1113,44 +1121,50 @@
 	if (!tty)
 		return 0;
 
-	bdp = info->tx_cur;
-
 	while (1) {
 		c = MIN(count, TX_BUF_SIZE);
 
 		if (c <= 0)
 			break;
 
+		local_irq_save(flags);
+		bdp = info->tx_cur;
 		if (bdp->cbd_sc & BD_SC_READY) {
 			info->flags |= TX_WAKEUP;
+			local_irq_restore(flags);
 			break;
 		}
+		/* Get next BD.
+		 */
+		if (bdp->cbd_sc & BD_SC_WRAP)
+			info->tx_cur = info->tx_bd_base;
+		else
+			info->tx_cur = (cbd_t *)bdp + 1;
+		local_irq_restore(flags);
 
-		cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
-		if (from_user) {
-			if (copy_from_user((void *)cp, buf, c)) {
-				if (!ret)
-					ret = -EFAULT;
-				break;
-			}
-		} else {
+		cp = info->tx_va_base + ((bdp - info->tx_bd_base) *
+				TX_BUF_SIZE);
+		if (from_user)
+			c -= copy_from_user((void *)cp, buf, c);
+		else
 			memcpy((void *)cp, buf, c);
-		}
 
-		bdp->cbd_datlen = c;
-		bdp->cbd_sc |= BD_SC_READY;
+		if (c) {
+			bdp->cbd_datlen = c;
+			bdp->cbd_sc |= BD_SC_READY;
+		} else {
+			/* Need to TX at least 1 char to keep CPM sane */
+			bdp->cbd_datlen = 1;
+			*cp = 0;
+			bdp->cbd_sc |= BD_SC_READY;
 
+			if (!ret)
+				ret = -EFAULT;
+			break;
+		}
 		buf += c;
 		count -= c;
 		ret += c;
-
-		/* Get next BD.
-		*/
-		if (bdp->cbd_sc & BD_SC_WRAP)
-			bdp = info->tx_bd_base;
-		else
-			bdp++;
-		info->tx_cur = (cbd_t *)bdp;
 	}
 	return ret;
 }
@@ -1210,28 +1224,28 @@
 {
 	volatile cbd_t	*bdp;
 	unsigned char	*cp;
+	unsigned long flags;
 
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
 
 	if (serial_paranoia_check(info, tty->device, "rs_send_char"))
 		return;
 
+	local_irq_save(flags);
 	bdp = info->tx_cur;
+	/* Get next BD.
+	*/
+	if (bdp->cbd_sc & BD_SC_WRAP)
+		info->tx_cur = info->tx_bd_base;
+	else
+		info->tx_cur = (cbd_t *)bdp + 1;
+	local_irq_restore(flags);
 	while (bdp->cbd_sc & BD_SC_READY);
 
 	cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
 	*cp = ch;
 	bdp->cbd_datlen = 1;
 	bdp->cbd_sc |= BD_SC_READY;
-
-	/* Get next BD.
-	*/
-	if (bdp->cbd_sc & BD_SC_WRAP)
-		bdp = info->tx_bd_base;
-	else
-		bdp++;
-
-	info->tx_cur = (cbd_t *)bdp;
 }
 
 /*
@@ -1802,7 +1816,7 @@
 static void rs_8xx_wait_until_sent(struct tty_struct *tty, int timeout)
 {
 	ser_info_t *info = (ser_info_t *)tty->driver_data;
-	unsigned long orig_jiffies, char_time;
+	unsigned long orig_jiffies, char_time, tst_res;
 	/*int lsr;*/
 	volatile cbd_t *bdp;
 
@@ -1837,6 +1851,7 @@
 	 * are empty.
 	 */
 	do {
+		unsigned long flags;
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 		printk("lsr = %d (jiff=%lu)...", lsr, jiffies);
 #endif
@@ -1854,12 +1869,15 @@
 		 * is the buffer is available.  There are still characters
 		 * in the CPM FIFO.
 		 */
+		local_irq_save(flags);
 		bdp = info->tx_cur;
 		if (bdp == info->tx_bd_base)
 			bdp += (TX_NUM_FIFO-1);
 		else
 			bdp--;
-	} while (bdp->cbd_sc & BD_SC_READY);
+		tst_res = !!(bdp->cbd_sc & BD_SC_READY);
+		local_irq_restore(flags);
+	} while (tst_res);
 	current->state = TASK_RUNNING;
 #ifdef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 	printk("lsr = %d (jiff=%lu)...done\n", lsr, jiffies);
@@ -2261,10 +2279,11 @@
 {
 	struct		serial_state	*ser;
 	ser_info_t			*info;
-	unsigned			i;
+	unsigned			i, c, cr_missing, max_tx_size;
 	volatile	cbd_t		*bdp, *bdbase;
 	volatile	smc_uart_t	*up;
 	volatile	u_char		*cp;
+	unsigned long                   flags;
 
 	ser = rs_table + idx;
 
@@ -2273,40 +2292,39 @@
 	 * we simply use the single buffer allocated.
 	 */
 	if ((info = (ser_info_t *)ser->info) != NULL) {
-		bdp = info->tx_cur;
 		bdbase = info->tx_bd_base;
-	}
-	else {
-		/* Pointer to UART in parameter ram.
-		*/
+	} else {
+		/* Pointer to UART in parameter ram. */
 		up = (smc_uart_t *)&cpmp->cp_dparam[ser->port];
 
-		/* Get the address of the host memory buffer.
-		 */
-		bdp = bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
-		
+		/* Get the address of the host memory buffer.*/
 		info = &consinfo;
+		info->tx_bd_base = (cbd_t *)bdbase = (cbd_t *)&cpmp->cp_dpmem[up->smc_tbase];
+		info->tx_cur = (cbd_t *)bdbase;
 	}
+	max_tx_size = console_tx_buf_len;
+	cr_missing = 0;
+	while (1){
+		c = MIN(max_tx_size, count);
+		if (c <= 0)
+			break;
 
-	/*
-	 * We need to gracefully shut down the transmitter, disable
-	 * interrupts, then send our bytes out.
-	 */
+		local_irq_save(flags);
+		bdp = info->tx_cur;
+		bdbase = info->tx_bd_base;
+		if (bdp->cbd_sc & BD_SC_WRAP)
+			info->tx_cur = (cbd_t *)bdbase;
+		else
+			info->tx_cur = (cbd_t *)(bdp+1);
+		local_irq_restore(flags);
 
-	/*
-	 * Now, do each character.  This is not as bad as it looks
-	 * since this is a holding FIFO and not a transmitting FIFO.
-	 * We could add the complexity of filling the entire transmit
-	 * buffer, but we would just wait longer between accesses......
-	 */
-	for (i = 0; i < count; i++, s++) {
 		/* Wait for transmitter fifo to empty.
 		 * Ready indicates output is ready, and xmt is doing
 		 * that, not that it is ready for us to send.
 		 */
 		while (bdp->cbd_sc & BD_SC_READY);
 
-		/* Send the character out.
+		/* Send the characters out.
 		 * If the buffer address is in the CPM DPRAM, don't
 		 * convert it.
 		 */
@@ -2314,54 +2332,32 @@
 			cp = (u_char *)(bdp->cbd_bufaddr);
 		else
 			cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
-		*cp = *s;
 
-		bdp->cbd_datlen = 1;
+		i=1; /* Keeps track of consumed TX buffer space */
+		if (cr_missing) {
+			/* Previus loop didn't have room for the CR, insert it first in this */
+			*cp++ = '\r';
+			i++;
+		}
+		cr_missing = 0;
+		for (; i <= c; i++) {
+			if ((*cp++ = *s++) != '\n')
+				continue; /* Copy bytes until a NewLine is found */
+			/* NewLine found, see if there is space in the TX buffer to add a CR */
+			if (i < max_tx_size) {
+				*cp++ = '\r'; /* yes, there is space to add a CR */
+				i++;
+			} else
+				cr_missing = 1; /* No space in the TX buffer,
+						   rember it so it can be inserted in the next loop */
+		}
+		count -= (c-cr_missing);
+		bdp->cbd_datlen = i-1;
 		bdp->cbd_sc |= BD_SC_READY;
 
-		if (bdp->cbd_sc & BD_SC_WRAP)
-			bdp = bdbase;
-		else
-			bdp++;
-
-		/* if a LF, also do CR... */
-		if (*s == 10) {
-			while (bdp->cbd_sc & BD_SC_READY);
-			/* This 'if' below will never be true, but a few
-			 * people argued with me that it was a "bug by
-			 * inspection" that is was easier to add the code
-			 * than continue the discussion.  The only time
-			 * the buffer address is in DPRAM is during early
-			 * use by kgdb/xmon, which format their own packets
-			 * and we never get here. -- Dan
-			 */
-			if ((uint)(bdp->cbd_bufaddr) > (uint)IMAP_ADDR)
-				cp = (u_char *)(bdp->cbd_bufaddr);
-			else
-				cp = info->tx_va_base + ((bdp - info->tx_bd_base) * TX_BUF_SIZE);
-			*cp = 13;
-			bdp->cbd_datlen = 1;
-			bdp->cbd_sc |= BD_SC_READY;
-
-			if (bdp->cbd_sc & BD_SC_WRAP) {
-				bdp = bdbase;
-			}
-			else {
-				bdp++;
-			}
-		}
 	}
-
-	/*
-	 * Finally, Wait for transmitter & holding register to empty
-	 *  and restore the IER
-	 */
-	while (bdp->cbd_sc & BD_SC_READY);
-
-	if (info)
-		info->tx_cur = (cbd_t *)bdp;
+	/* while (bdp->cbd_sc & BD_SC_READY); is this really needed? */
 }
-
 static void serial_console_write(struct console *c, const char *s,
 				unsigned count)
 {
@@ -3002,7 +2998,7 @@
 
 		}
 	}
-
+	console_tx_buf_len = TX_BUF_SIZE;
 	return 0;
 }
 
@@ -3058,7 +3054,7 @@
 	 * memory yet because vm allocator isn't initialized
 	 * during this early console init.
 	 */
-	dp_addr = m8xx_cpm_dpalloc(8);
+	dp_addr = m8xx_cpm_dpalloc(2*EARLY_BUF_SIZE);
 	mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]);
 
 	/* Allocate space for two buffer descriptors in the DP ram.
@@ -3072,10 +3068,10 @@
 	bdp->cbd_bufaddr = iopa(mem_addr);
 	(bdp+1)->cbd_bufaddr = iopa(mem_addr+4);
 
-	consinfo.rx_va_base = mem_addr;
-	consinfo.rx_bd_base = bdp;
-	consinfo.tx_va_base = mem_addr + 4;
-	consinfo.tx_bd_base = bdp+1;
+	consinfo.rx_va_base = (unsigned char *) mem_addr;
+	consinfo.rx_bd_base = (cbd_t *) bdp;
+	consinfo.tx_va_base = (unsigned char *) (mem_addr + EARLY_BUF_SIZE);
+	consinfo.tx_bd_base = (cbd_t *) (bdp+1);
 
 	/* For the receive, set empty and wrap.
 	 * For transmit, set wrap.
@@ -3176,7 +3172,7 @@
 	/* Set up the baud rate generator.
 	*/
 	m8xx_cpm_setbrg((ser - rs_table), bd->bi_baudrate);
-
+	console_tx_buf_len = EARLY_BUF_SIZE;
 	return 0;
 }
 
diff -urN linux-2.4.23-pre6/arch/ppc/Makefile linux-2.4.23-pre7/arch/ppc/Makefile
--- linux-2.4.23-pre6/arch/ppc/Makefile	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/ppc/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -85,7 +85,7 @@
 checks:
 	@$(MAKE) -C arch/$(ARCH)/kernel checks
 
-BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd
+BOOT_TARGETS = zImage zImage.initrd znetboot znetboot.initrd uImage
 
 # All the instructions talk about "make bzImage".
 bzImage: zImage
diff -urN linux-2.4.23-pre6/arch/ppc/boot/Makefile linux-2.4.23-pre7/arch/ppc/boot/Makefile
--- linux-2.4.23-pre6/arch/ppc/boot/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.23-pre7/arch/ppc/boot/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -17,7 +17,7 @@
 AFLAGS	+= -D__BOOTER__
 OBJCOPY_ARGS = -O elf32-powerpc
 
-MKIMAGE				:= ./utils/mkimage.wrapper
+MKIMAGE				:= $(TOPDIR)/scripts/mkuboot.sh
 
 lib/zlib.a: lib/zlib.c
 	$(MAKE) -C lib
@@ -61,12 +61,14 @@
 	gzip $(GZIP_FLAGS) images/vmapus
 endif
 
-# Make an image for PPCBoot
-pImage: images/vmlinux.gz
-	$(MKIMAGE) -A ppc -O linux -T kernel -C gzip -a 00000000 -e 00000000 \
+# Make an image for PPCBoot / U-Boot.
+uImage: $(MKIMAGE) images/vmlinux.gz
+	$(CONFIG_SHELL) $(MKIMAGE) -A ppc -O linux -T kernel \
+	-C gzip -a 00000000 -e 00000000 \
 	-n 'Linux-$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)' \
-	-d $< images/vmlinux.PPCBoot
-	ln -sf vmlinux.PPCBoot images/pImage
+	-d images/vmlinux.gz images/vmlinux.UBoot
+	ln -sf vmlinux.UBoot images/uImage
+	rm -f ./mkuboot
 
 # These are subdirs with files not normally rm'ed. -- Tom
 clean:
diff -urN linux-2.4.23-pre6/arch/ppc/boot/images/Makefile linux-2.4.23-pre7/arch/ppc/boot/images/Makefile
--- linux-2.4.23-pre6/arch/ppc/boot/images/Makefile	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.23-pre7/arch/ppc/boot/images/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -9,4 +9,4 @@
 	gzip -vf9 vmlinux
 
 clean:
-	rm -f sImage vmapus vmlinux* miboot* zImage* zvmlinux*
+	rm -f sImage vmapus vmlinux* miboot* zImage* zvmlinux* uImage
diff -urN linux-2.4.23-pre6/arch/ppc/boot/utils/mkimage.wrapper linux-2.4.23-pre7/arch/ppc/boot/utils/mkimage.wrapper
--- linux-2.4.23-pre6/arch/ppc/boot/utils/mkimage.wrapper	2002-08-02 17:39:43.000000000 -0700
+++ linux-2.4.23-pre7/arch/ppc/boot/utils/mkimage.wrapper	1969-12-31 16:00:00.000000000 -0800
@@ -1,16 +0,0 @@
-#!/bin/bash
-
-#
-# Build PPCBoot image when `mkimage' tool is available.
-#
-
-MKIMAGE=$(type -path mkimage)
-
-if [ -z "${MKIMAGE}" ]; then
-	# Doesn't exist
-	echo '"mkimage" command not found - PPCBoot images will not be built' >&2
-	exit 0;
-fi
-
-# Call "mkimage" to create PPCBoot image
-${MKIMAGE} "$@"
diff -urN linux-2.4.23-pre6/arch/ppc/kernel/setup.c linux-2.4.23-pre7/arch/ppc/kernel/setup.c
--- linux-2.4.23-pre6/arch/ppc/kernel/setup.c	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/ppc/kernel/setup.c	2003-10-09 17:48:21.000000000 -0700
@@ -152,12 +152,12 @@
 		return 0;
 	pvr = cpu_data[i].pvr;
 	lpj = cpu_data[i].loops_per_jiffy;
-	seq_printf(m, "processor\t: %lu\n", i);
 #else
 	pvr = mfspr(PVR);
 	lpj = loops_per_jiffy;
 #endif
 
+	seq_printf(m, "processor\t: %lu\n", i);
 	seq_printf(m, "cpu\t\t: ");
 
 	if (cur_cpu_spec[i]->pvr_mask)
diff -urN linux-2.4.23-pre6/arch/x86_64/kernel/e820.c linux-2.4.23-pre7/arch/x86_64/kernel/e820.c
--- linux-2.4.23-pre6/arch/x86_64/kernel/e820.c	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/arch/x86_64/kernel/e820.c	2003-10-09 17:48:21.000000000 -0700
@@ -13,6 +13,7 @@
 #include <asm/e820.h>
 #include <asm/proto.h>
 #include <asm/acpi.h>
+#include <asm/apic.h>
 #include <asm/bootsetup.h>
 
 extern unsigned long table_start, table_end;
diff -urN linux-2.4.23-pre6/drivers/Makefile linux-2.4.23-pre7/drivers/Makefile
--- linux-2.4.23-pre6/drivers/Makefile	2003-08-25 04:44:40.000000000 -0700
+++ linux-2.4.23-pre7/drivers/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -8,7 +8,7 @@
 
 mod-subdirs :=	dio hil mtd sbus video macintosh usb input telephony ide \
 		message/i2o message/fusion scsi md ieee1394 pnp isdn atm \
-		fc4 net/hamradio i2c acpi bluetooth
+		fc4 net/hamradio i2c acpi bluetooth usb/gadget
 
 subdir-y :=	parport char block net sound misc media cdrom hotplug
 subdir-m :=	$(subdir-y)
@@ -28,6 +28,7 @@
 subdir-$(CONFIG_MAC)		+= macintosh
 subdir-$(CONFIG_PPC32)		+= macintosh
 subdir-$(CONFIG_USB)		+= usb
+subdir-$(CONFIG_USB_GADGET)	+= usb/gadget
 subdir-$(CONFIG_INPUT)		+= input
 subdir-$(CONFIG_PHONE)		+= telephony
 subdir-$(CONFIG_IDE)		+= ide
diff -urN linux-2.4.23-pre6/drivers/acpi/Config.in linux-2.4.23-pre7/drivers/acpi/Config.in
--- linux-2.4.23-pre6/drivers/acpi/Config.in	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/drivers/acpi/Config.in	2003-10-09 17:48:21.000000000 -0700
@@ -32,7 +32,8 @@
     tristate     '  Toshiba Laptop Extras'	CONFIG_ACPI_TOSHIBA
     bool         '  Debug Statements'	CONFIG_ACPI_DEBUG
     bool         '  Relaxed AML Checking'	CONFIG_ACPI_RELAXED_AML
-  else if [ "$CONFIG_SMP" = "y" ]; then
+  else 
+    if [ "$CONFIG_SMP" = "y" ]; then
       define_bool CONFIG_ACPI_BOOT		y
     fi
   fi
diff -urN linux-2.4.23-pre6/drivers/acpi/system.c linux-2.4.23-pre7/drivers/acpi/system.c
--- linux-2.4.23-pre6/drivers/acpi/system.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.23-pre7/drivers/acpi/system.c	2003-10-09 17:48:21.000000000 -0700
@@ -1192,11 +1192,21 @@
 
 #if defined(CONFIG_MAGIC_SYSRQ) && defined(CONFIG_PM)
 
+static int po_cb_active; 
+
+static void acpi_po_tramp(void *x)
+{ 
+	acpi_power_off();	
+} 
+
 /* Simple wrapper calling power down function. */
 static void acpi_sysrq_power_off(int key, struct pt_regs *pt_regs,
 	struct kbd_struct *kbd, struct tty_struct *tty)
-{
-	acpi_power_off();
+{	
+	static struct tq_struct tq = { .routine = acpi_po_tramp };
+	if (po_cb_active++)
+		return;
+	schedule_task(&tq); 
 }
 
 struct sysrq_key_op sysrq_acpi_poweroff_op = {
diff -urN linux-2.4.23-pre6/drivers/block/cciss.c linux-2.4.23-pre7/drivers/block/cciss.c
--- linux-2.4.23-pre6/drivers/block/cciss.c	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/drivers/block/cciss.c	2003-10-09 17:48:21.000000000 -0700
@@ -45,13 +45,13 @@
 #include <linux/genhd.h>
 
 #define CCISS_DRIVER_VERSION(maj,min,submin) ((maj<<16)|(min<<8)|(submin))
-#define DRIVER_NAME "HP CISS Driver (v 2.4.47)"
-#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,47)
+#define DRIVER_NAME "HP CISS Driver (v 2.4.50)"
+#define DRIVER_VERSION CCISS_DRIVER_VERSION(2,4,50)
 
 /* Embedded module documentation macros - see modules.h */
 MODULE_AUTHOR("Hewlett-Packard Company");
-MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.47");
-MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400"); 
+MODULE_DESCRIPTION("Driver for HP SA5xxx SA6xxx Controllers version 2.4.50");
+MODULE_SUPPORTED_DEVICE("HP SA5i SA5i+ SA532 SA5300 SA5312 SA641 SA642 SA6400 6i"); 
 MODULE_LICENSE("GPL");
 
 #include "cciss_cmd.h"
@@ -76,6 +76,8 @@
                         0x0E11, 0x409C, 0, 0, 0},
 	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
                         0x0E11, 0x409D, 0, 0, 0},
+	{ PCI_VENDOR_ID_COMPAQ, PCI_DEVICE_ID_COMPAQ_CISSC,
+                        0x0E11, 0x4091, 0, 0, 0},
 	{0,}
 };
 MODULE_DEVICE_TABLE(pci, cciss_pci_device_id);
@@ -95,6 +97,7 @@
 	{ 0x409B0E11, "Smart Array 642", &SA5_access},
 	{ 0x409C0E11, "Smart Array 6400", &SA5_access},
 	{ 0x409D0E11, "Smart Array 6400 EM", &SA5_access},
+	{ 0x40910E11, "Smart Array 6i", &SA5_access},
 };
 
 /* How long to wait (in millesconds) for board to go into simple mode */
diff -urN linux-2.4.23-pre6/drivers/block/ll_rw_blk.c linux-2.4.23-pre7/drivers/block/ll_rw_blk.c
--- linux-2.4.23-pre6/drivers/block/ll_rw_blk.c	2003-08-25 04:44:41.000000000 -0700
+++ linux-2.4.23-pre7/drivers/block/ll_rw_blk.c	2003-10-09 17:48:21.000000000 -0700
@@ -121,6 +121,10 @@
 unsigned long blk_max_low_pfn, blk_max_pfn;
 int blk_nohighio = 0;
 
+int block_dump = 0;
+
+static struct timer_list writeback_timer;
+
 static inline int get_max_sectors(kdev_t dev)
 {
 	if (!max_sectors[MAJOR(dev)])
@@ -1293,6 +1297,9 @@
 	if (waitqueue_active(&bh->b_wait))
 		wake_up(&bh->b_wait);
 
+	if (block_dump)
+		printk(KERN_DEBUG "%s: %s block %lu/%u on %s\n", current->comm, rw == WRITE ? "WRITE" : "READ", bh->b_rsector, count, kdevname(bh->b_rdev));
+
 	put_bh(bh);
 	switch (rw) {
 		case WRITE:
@@ -1413,6 +1420,11 @@
 extern int stram_device_init (void);
 #endif
 
+static void blk_writeback_timer(unsigned long data)
+{
+	wakeup_bdflush();
+	wakeup_kupdate();
+}
 
 /**
  * end_that_request_first - end I/O on one buffer.
@@ -1469,10 +1481,18 @@
 	return 0;
 }
 
+extern int laptop_mode;
+
 void end_that_request_last(struct request *req)
 {
 	struct completion *waiting = req->waiting;
 
+	/*
+	 * schedule the writeout of pending dirty data when the disk is idle
+	 */
+	if (laptop_mode && req->cmd == READ)
+		mod_timer(&writeback_timer, jiffies + 5 * HZ);
+
 	req_finished_io(req);
 	blkdev_release_request(req);
 	if (waiting)
@@ -1500,6 +1520,9 @@
 	blk_max_low_pfn = max_low_pfn - 1;
 	blk_max_pfn = max_pfn - 1;
 
+	init_timer(&writeback_timer);
+	writeback_timer.function = blk_writeback_timer;
+
 #ifdef CONFIG_AMIGA_Z2RAM
 	z2_init();
 #endif
diff -urN linux-2.4.23-pre6/drivers/char/Config.in linux-2.4.23-pre7/drivers/char/Config.in
--- linux-2.4.23-pre6/drivers/char/Config.in	2003-10-09 17:48:17.000000000 -0700
+++ linux-2.4.23-pre7/drivers/char/Config.in	2003-10-09 17:48:21.000000000 -0700
@@ -104,11 +104,14 @@
        fi
      fi
   fi
-fi
-if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ] ; then
-  bool 'SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL
-  if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then
-    bool '  SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE
+  if [ "$CONFIG_IA64" = "y" ]; then
+    bool '  SGI SN2 l1 serial port support' CONFIG_SGI_L1_SERIAL
+    if [ "$CONFIG_SGI_L1_SERIAL" = "y" ]; then
+      bool '    SGI SN2 l1 Console support' CONFIG_SGI_L1_SERIAL_CONSOLE
+    fi
+    if [ "$CONFIG_IA64_GENERIC" = "y" -o "$CONFIG_IA64_SGI_SN2" = "y" ]; then
+      bool '  SGI SN2 IOC4 serial port support' CONFIG_SGI_IOC4_SERIAL
+    fi
   fi
 fi
 if [ "$CONFIG_EXPERIMENTAL" = "y" -a "$CONFIG_ZORRO" = "y" ]; then
diff -urN linux-2.4.23-pre6/drivers/char/mem.c linux-2.4.23-pre7/drivers/char/mem.c
--- linux-2.4.23-pre6/drivers/char/mem.c	2003-06-13 07:51:33.000000000 -0700
+++ linux-2.4.23-pre7/drivers/char/mem.c	2003-10-09 17:48:21.000000000 -0700
@@ -21,6 +21,7 @@
 #include <linux/raw.h>
 #include <linux/tty.h>
 #include <linux/capability.h>
+#include <linux/ptrace.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
@@ -503,16 +504,23 @@
  */
 static loff_t memory_lseek(struct file * file, loff_t offset, int orig)
 {
+	loff_t ret;
+
 	switch (orig) {
 		case 0:
 			file->f_pos = offset;
-			return file->f_pos;
+			ret = file->f_pos;
+			force_successful_syscall_return();
+			break;
 		case 1:
 			file->f_pos += offset;
-			return file->f_pos;
+			ret = file->f_pos;
+			force_successful_syscall_return();
+			break;
 		default:
-			return -EINVAL;
+			ret = -EINVAL;
 	}
+	return ret;
 }
 
 static int open_port(struct inode * inode, struct file * filp)
diff -urN linux-2.4.23-pre6/drivers/char/sn_serial.c linux-2.4.23-pre7/drivers/char/sn_serial.c
--- linux-2.4.23-pre6/drivers/char/sn_serial.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/char/sn_serial.c	2003-10-09 17:48:21.000000000 -0700
@@ -38,27 +38,19 @@
  */
 
 #include <linux/config.h>
-#include <linux/errno.h>
 #include <linux/interrupt.h>
 #include <linux/tty.h>
 #include <linux/serial.h>
 #include <linux/console.h>
 #include <linux/module.h>
-#ifdef CONFIG_MAGIC_SYSRQ
 #include <linux/sysrq.h>
-#endif
-#include <linux/string.h>
 #include <linux/circ_buf.h>
 #include <linux/serial_reg.h>
-#include <asm/irq.h>
-#include <asm/system.h>
-#include <asm/io.h>
+#include <asm/uaccess.h>
 #include <asm/sn/sn_sal.h>
-#include <asm/sn/nodepda.h>
+#include <asm/sn/pci/pciio.h>		/* this is needed for get_console_nasid */
 #include <asm/sn/simulator.h>
-#include <asm/sn/sn2/intr.h>
 #include <asm/sn/sn2/sn_private.h>
-#include <asm/sn/clksupport.h>
 
 #if defined(CONFIG_SGI_L1_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 static char sysrq_serial_str[] = "\eSYS";
@@ -66,60 +58,53 @@
 static unsigned long sysrq_requested;
 #endif /* CONFIG_SGI_L1_SERIAL_CONSOLE && CONFIG_MAGIC_SYSRQ */
 
-static char *serial_revdate = "2003-07-31";
-
-/* driver subtype - what does this mean? */
-#define SN_SAL_SUBTYPE 1
-
 /* minor device number */
 #define SN_SAL_MINOR 64
 
+#define SN_SAL_SUBTYPE	1
+
 /* number of characters left in xmit buffer before we ask for more */
 #define WAKEUP_CHARS 128
 
 /* number of characters we can transmit to the SAL console at a time */
 #define SN_SAL_MAX_CHARS 120
 
-/* event types for our task queue -- so far just one */
 #define SN_SAL_EVENT_WRITE_WAKEUP 0
 
 #define CONSOLE_RESTART 1
 
+
 /* 64K, when we're asynch, it must be at least printk's LOG_BUF_LEN to
  * avoid losing chars, (always has to be a power of 2) */
-#if 1
 #define SN_SAL_BUFFER_SIZE (64 * (1 << 10))
-#else
-#define SN_SAL_BUFFER_SIZE (64)
-#endif
 
 #define SN_SAL_UART_FIFO_DEPTH 16
 #define SN_SAL_UART_FIFO_SPEED_CPS 9600/10
 
 /* we don't kmalloc/get_free_page these as we want them available
  * before either of those are initialized */
-static volatile char xmit_buff_mem[SN_SAL_BUFFER_SIZE];
+static char sn_xmit_buff_mem[SN_SAL_BUFFER_SIZE];
 
 struct volatile_circ_buf {
-	volatile char *buf;
-	int head;
-	int tail;
+	char *cb_buf;
+	int cb_head;
+	int cb_tail;
 };
 
-static volatile struct volatile_circ_buf xmit = { .buf = xmit_buff_mem };
-static char sal_tmp_buffer[SN_SAL_BUFFER_SIZE];
+static struct volatile_circ_buf xmit = { .cb_buf = sn_xmit_buff_mem };
+static char sn_tmp_buffer[SN_SAL_BUFFER_SIZE];
 
-static volatile struct tty_struct *sn_sal_tty;
+static struct tty_struct *sn_sal_tty;
 
 static struct timer_list sn_sal_timer;
 static int sn_sal_event; /* event type for task queue */
 static int sn_sal_refcount;
 
-static volatile int sn_sal_is_asynch;
-static volatile int sn_sal_irq;
+static int sn_sal_is_asynch;
+static int sn_sal_irq;
 static spinlock_t sn_sal_lock = SPIN_LOCK_UNLOCKED;
-static volatile int tx_count;
-static volatile int rx_count;
+static int sn_total_tx_count;
+static int sn_total_rx_count;
 
 static struct tty_struct *sn_sal_table;
 static struct termios *sn_sal_termios;
@@ -128,32 +113,63 @@
 static void sn_sal_tasklet_action(unsigned long data);
 static DECLARE_TASKLET(sn_sal_tasklet, sn_sal_tasklet_action, 0);
 
-static volatile unsigned long interrupt_timeout;
+static unsigned long sn_interrupt_timeout;
 
 extern u64 master_node_bedrock_address;
 
-int debug_printf(const char *fmt, ...);
+static int sn_debug_printf(const char *fmt, ...);
 
 #undef DEBUG
 #ifdef DEBUG
-#define DPRINTF(x...) debug_printf(x)
+#define DPRINTF(x...) sn_debug_printf(x)
 #else
 #define DPRINTF(x...) do { } while (0)
 #endif
 
-static void intr_transmit_chars(void);
-static void poll_transmit_chars(void);
-static int sn_sal_write(struct tty_struct *tty, int from_user,
-			const unsigned char *buf, int count);
-
 struct sn_sal_ops {
-	int (*puts)(const char *s, int len);
-	int (*getc)(void);
-	int (*input_pending)(void);
-	void (*wakeup_transmit)(void);
+	int (*sal_puts)(const char *s, int len);
+	int (*sal_getc)(void);
+	int (*sal_input_pending)(void);
+	void (*sal_wakeup_transmit)(void);
 };
 
-static volatile struct sn_sal_ops *sn_sal_ops;
+/* This is the pointer used. It is assigned to point to one of
+ * the tables below.
+ */
+static struct sn_sal_ops *sn_func;
+
+/* Prototypes */
+static int snt_hw_puts(const char *, int);
+static int snt_poll_getc(void);
+static int snt_poll_input_pending(void);
+static int snt_sim_puts(const char *, int);
+static int snt_sim_getc(void);
+static int snt_sim_input_pending(void);
+static int snt_intr_getc(void);
+static int snt_intr_input_pending(void);
+static void sn_intr_transmit_chars(void);
+
+/* A table for polling */
+static struct sn_sal_ops poll_ops = {
+	.sal_puts		= snt_hw_puts,
+	.sal_getc 		= snt_poll_getc,
+	.sal_input_pending	= snt_poll_input_pending
+};
+
+/* A table for the simulator */
+static struct sn_sal_ops sim_ops = {
+	.sal_puts		= snt_sim_puts,
+	.sal_getc		= snt_sim_getc,
+	.sal_input_pending	= snt_sim_input_pending
+};
+
+/* A table for interrupts enabled */
+static struct sn_sal_ops intr_ops = {
+	.sal_puts		= snt_hw_puts,
+	.sal_getc		= snt_intr_getc,
+	.sal_input_pending	= snt_intr_input_pending,
+	.sal_wakeup_transmit	= sn_intr_transmit_chars
+};
 
 
 /* the console does output in two distinctly different ways:
@@ -170,7 +186,8 @@
 
 /* routines for running the console in polling mode */
 
-static int hw_puts(const char *s, int len)
+static int
+snt_hw_puts(const char *s, int len)
 {
 	/* looking at the PROM source code, putb calls the flush
 	 * routine, so if we send characters in FIFO sized chunks, it
@@ -178,14 +195,16 @@
 	return ia64_sn_console_putb(s, len);
 }
 
-static int poll_getc(void)
+static int
+snt_poll_getc(void)
 {
 	int ch;
 	ia64_sn_console_getc(&ch);
 	return ch;
 }
 
-static int poll_input_pending(void)
+static int
+snt_poll_input_pending(void)
 {
 	int status, input;
 
@@ -193,16 +212,11 @@
 	return !status && input;
 }
 
-static struct sn_sal_ops poll_ops = {
-	.puts = hw_puts,
-	.getc = poll_getc,
-	.input_pending = poll_input_pending
-};
-
 
 /* routines for running the console on the simulator */
 
-static int sim_puts(const char *str, int count)
+static int
+snt_sim_puts(const char *str, int count)
 {
 	int counter = count;
 
@@ -223,65 +237,64 @@
 	return count;
 }
 
-static int sim_getc(void)
+static int
+snt_sim_getc(void)
 {
 	return readb(master_node_bedrock_address + (UART_RX << 3));
 }
 
-static int sim_input_pending(void)
+static int
+snt_sim_input_pending(void)
 {
 	return readb(master_node_bedrock_address + (UART_LSR << 3)) & UART_LSR_DR;
 }
 
-static struct sn_sal_ops sim_ops = {
-	.puts = sim_puts,
-	.getc = sim_getc,
-	.input_pending = sim_input_pending
-};
-
 
 /* routines for an interrupt driven console (normal) */
 
-static int intr_getc(void)
+static int
+snt_intr_getc(void)
 {
 	return ia64_sn_console_readc();
 }
 
-static int intr_input_pending(void)
+static int
+snt_intr_input_pending(void)
 {
 	return ia64_sn_console_intr_status() & SAL_CONSOLE_INTR_RECV;
 }
 
-static struct sn_sal_ops intr_ops = {
-	.puts = hw_puts,
-	.getc = intr_getc,
-	.input_pending = intr_input_pending,
-	.wakeup_transmit = intr_transmit_chars
-};
-
-extern void early_sn_setup(void);
+/* The early printk (possible setup) and function call */
 
 void
 early_printk_sn_sal(const char *s, unsigned count)
 {
-	if (!sn_sal_ops) {
+#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
+	extern void early_sn_setup(void);
+#endif
+
+	if (!sn_func) {
 		if (IS_RUNNING_ON_SIMULATOR())
-			sn_sal_ops = &sim_ops;
+			sn_func = &sim_ops;
 		else
-			sn_sal_ops = &poll_ops;
+			sn_func = &poll_ops;
 
+#if defined(CONFIG_IA64_EARLY_PRINTK_SGI_SN) || defined(CONFIG_IA64_SGI_SN_SIM)
 		early_sn_setup();
+#endif
 	}
-	sn_sal_ops->puts(s, count);
+	sn_func->sal_puts(s, count);
 }
 
 /* this is as "close to the metal" as we can get, used when the driver
  * itself may be broken */
-int debug_printf(const char *fmt, ...)
+static int
+sn_debug_printf(const char *fmt, ...)
 {
 	static char printk_buf[1024];
 	int printed_len;
 	va_list args;
+
 	va_start(args, fmt);
 	printed_len = vsnprintf(printk_buf, sizeof(printk_buf), fmt, args);
 	early_printk_sn_sal(printk_buf, printed_len);
@@ -289,7 +302,7 @@
 	return printed_len;
 }
 
-/*********************************************************************
+/*
  * Interrupt handling routines.
  */
 
@@ -300,29 +313,29 @@
 	tasklet_schedule(&sn_sal_tasklet);
 }
 
-/* receive_chars can be called before sn_sal_tty is initialized.  in
+/* sn_receive_chars can be called before sn_sal_tty is initialized.  in
  * that case, its only use is to trigger sysrq and kdb */
 static void
-receive_chars(struct pt_regs *regs)
+sn_receive_chars(struct pt_regs *regs, unsigned long *flags)
 {
 	int ch;
 
-	while (sn_sal_ops->input_pending()) {
-		ch = sn_sal_ops->getc();
+	while (sn_func->sal_input_pending()) {
+		ch = sn_func->sal_getc();
 		if (ch < 0) {
 			printk(KERN_ERR "sn_serial: An error occured while "
 			       "obtaining data from the console (0x%0x)\n", ch);
 			break;
 		}
-
 #if defined(CONFIG_SGI_L1_SERIAL_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
 		if (sysrq_requested) {
 			unsigned long sysrq_timeout = sysrq_requested + HZ*5;
+
 			sysrq_requested = 0;
 			if (ch && time_before(jiffies, sysrq_timeout)) {
-				spin_unlock(&sn_sal_lock);
+				spin_unlock_irqrestore(&sn_sal_lock, *flags);
 				handle_sysrq(ch, regs, NULL, NULL);
-				spin_lock(&sn_sal_lock);
+				spin_lock_irqsave(&sn_sal_lock, *flags);
 				/* don't record this char */
 				continue;
 			}
@@ -344,11 +357,11 @@
 			if (sn_sal_tty->flip.count == TTY_FLIPBUF_SIZE)
 				break;
 		}
-		rx_count++;
+		sn_total_rx_count++;
 	}
 
 	if (sn_sal_tty)
-		tty_flip_buffer_push(sn_sal_tty);
+		tty_flip_buffer_push((struct tty_struct *)sn_sal_tty);
 }
 
 
@@ -360,43 +373,40 @@
 	int result;
 	char *start;
 
-	if (xmit.head == xmit.tail)
-		/* Nothing to do. */
-		return;
+	if (xmit.cb_head == xmit.cb_tail)
+		return; /* Nothing to do. */
 
-	head = xmit.head;
-	tail = xmit.tail;
-	start = &xmit.buf[tail];
+	head = xmit.cb_head;
+	tail = xmit.cb_tail;
+	start = &xmit.cb_buf[tail];
 
 	/* twice around gets the tail to the end of the buffer and
 	 * then to the head, if needed */
 	loops = (head < tail) ? 2 : 1;
 
 	for (ii = 0; ii < loops; ii++) {
-		xmit_count = (head < tail) ?
-			(SN_SAL_BUFFER_SIZE - tail) : (head - tail);
+		xmit_count = (head < tail) ?  (SN_SAL_BUFFER_SIZE - tail) : (head - tail);
 
 		if (xmit_count > 0) {
-			result = sn_sal_ops->puts(start, xmit_count);
+			result = sn_func->sal_puts((char *)start, xmit_count);
 			if (!result)
-				debug_printf("\n*** synch_flush_xmit failed to flush\n");
+				sn_debug_printf("\n*** synch_flush_xmit failed to flush\n");
 			if (result > 0) {
 				xmit_count -= result;
-				tx_count += result;
+				sn_total_tx_count += result;
 				tail += result;
 				tail &= SN_SAL_BUFFER_SIZE - 1;
-				xmit.tail = tail;
-				start = &xmit.buf[tail];
+				xmit.cb_tail = tail;
+				start = (char *)&xmit.cb_buf[tail];
 			}
 		}
 	}
-
 }
 
 /* must be called with a lock protecting the circular buffer and
  * sn_sal_tty */
 static void
-poll_transmit_chars(void)
+sn_poll_transmit_chars(void)
 {
 	int xmit_count, tail, head;
 	int result;
@@ -404,44 +414,40 @@
 
 	BUG_ON(!sn_sal_is_asynch);
 
-	if (xmit.head == xmit.tail ||
+	if (xmit.cb_head == xmit.cb_tail ||
 	    (sn_sal_tty && (sn_sal_tty->stopped || sn_sal_tty->hw_stopped))) {
 		/* Nothing to do. */
 		return;
 	}
 
-	head = xmit.head;
-	tail = xmit.tail;
-	start = &xmit.buf[tail];
+	head = xmit.cb_head;
+	tail = xmit.cb_tail;
+	start = &xmit.cb_buf[tail];
 
-	xmit_count = (head < tail) ?
-		(SN_SAL_BUFFER_SIZE - tail) : (head - tail);
+	xmit_count = (head < tail) ?  (SN_SAL_BUFFER_SIZE - tail) : (head - tail);
 
 	if (xmit_count == 0)
-		debug_printf("\n*** empty xmit_count\n");
+		sn_debug_printf("\n*** empty xmit_count\n");
 
-	if (xmit_count > SN_SAL_UART_FIFO_DEPTH)
-		xmit_count = SN_SAL_UART_FIFO_DEPTH;
-	
 	/* use the ops, as we could be on the simulator */
-	result = sn_sal_ops->puts(start, xmit_count);
+	result = sn_func->sal_puts((char *)start, xmit_count);
 	if (!result)
-		debug_printf("\n*** error in synchronous puts\n");
+		sn_debug_printf("\n*** error in synchronous sal_puts\n");
 	/* XXX chadt clean this up */
 	if (result > 0) {
 		xmit_count -= result;
-		tx_count += result;
+		sn_total_tx_count += result;
 		tail += result;
 		tail &= SN_SAL_BUFFER_SIZE - 1;
-		xmit.tail = tail;
-		start = &xmit.buf[tail];
+		xmit.cb_tail = tail;
+		start = &xmit.cb_buf[tail];
 	}
 
 	/* if there's few enough characters left in the xmit buffer
 	 * that we could stand for the upper layer to send us some
 	 * more, ask for it. */
 	if (sn_sal_tty)
-		if (CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS)
+		if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS)
 			sn_sal_sched_event(SN_SAL_EVENT_WRITE_WAKEUP);
 }
 
@@ -449,7 +455,7 @@
 /* must be called with a lock protecting the circular buffer and
  * sn_sal_tty */
 static void
-intr_transmit_chars(void)
+sn_intr_transmit_chars(void)
 {
 	int xmit_count, tail, head, loops, ii;
 	int result;
@@ -457,15 +463,15 @@
 
 	BUG_ON(!sn_sal_is_asynch);
 
-	if (xmit.head == xmit.tail ||
+	if (xmit.cb_head == xmit.cb_tail ||
 	    (sn_sal_tty && (sn_sal_tty->stopped || sn_sal_tty->hw_stopped))) {
 		/* Nothing to do. */
 		return;
 	}
 
-	head = xmit.head;
-	tail = xmit.tail;
-	start = &xmit.buf[tail];
+	head = xmit.cb_head;
+	tail = xmit.cb_tail;
+	start = &xmit.cb_buf[tail];
 
 	/* twice around gets the tail to the end of the buffer and
 	 * then to the head, if needed */
@@ -476,18 +482,18 @@
 			(SN_SAL_BUFFER_SIZE - tail) : (head - tail);
 
 		if (xmit_count > 0) {
-			result = ia64_sn_console_xmit_chars(start, xmit_count);
+			result = ia64_sn_console_xmit_chars((char *)start, xmit_count);
 #ifdef DEBUG
 			if (!result)
-				debug_printf("`");
+				sn_debug_printf("`");
 #endif
 			if (result > 0) {
 				xmit_count -= result;
-				tx_count += result;
+				sn_total_tx_count += result;
 				tail += result;
 				tail &= SN_SAL_BUFFER_SIZE - 1;
-				xmit.tail = tail;
-				start = &xmit.buf[tail];
+				xmit.cb_tail = tail;
+				start = &xmit.cb_buf[tail];
 			}
 		}
 	}
@@ -496,7 +502,7 @@
 	 * that we could stand for the upper layer to send us some
 	 * more, ask for it. */
 	if (sn_sal_tty)
-		if (CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS)
+		if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) < WAKEUP_CHARS)
 			sn_sal_sched_event(SN_SAL_EVENT_WRITE_WAKEUP);
 }
 
@@ -508,13 +514,14 @@
 	 * SAL, since it doesn't intercept the UART interrupts
 	 * itself */
 	int status = ia64_sn_console_intr_status();
+	unsigned long flags;
 
-	spin_lock(&sn_sal_lock);
+	spin_lock_irqsave(&sn_sal_lock, flags);
 	if (status & SAL_CONSOLE_INTR_RECV)
-		receive_chars(regs);
+		sn_receive_chars(regs, &flags);
 	if (status & SAL_CONSOLE_INTR_XMIT)
-		intr_transmit_chars();
-	spin_unlock(&sn_sal_lock);
+		sn_intr_transmit_chars();
+	spin_unlock_irqrestore(&sn_sal_lock, flags);
 }
 
 
@@ -539,17 +546,15 @@
 	}
 
 	console_nasid = ia64_sn_get_console_nasid();
-	intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))
-		->node_first_cpu;
+	intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu;
 	intr_cpuloc = cpu_physical_id(intr_cpuid);
 	console_irq = CPU_VECTOR_TO_IRQ(intr_cpuloc, SGI_UART_VECTOR);
 
-	result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR,
-				    0 /*not used*/, 0 /*not used*/);
+	result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR, 0 /*not used*/, 0 /*not used*/);
 	BUG_ON(result != SGI_UART_VECTOR);
 
-	result = request_irq(console_irq, sn_sal_interrupt,
-			     SA_INTERRUPT,  "SAL console driver", &sn_sal_tty);
+	result = request_irq(console_irq, sn_sal_interrupt, SA_INTERRUPT,
+		       			"SAL console driver", &sn_sal_tty);
 	if (result >= 0)
 		return console_irq;
 
@@ -557,11 +562,6 @@
 	return 0;
 }
 
-/*
- * End of the interrupt routines.
- *********************************************************************/
-
-
 static void
 sn_sal_tasklet_action(unsigned long data)
 {
@@ -569,13 +569,14 @@
 
 	if (sn_sal_tty) {
 		spin_lock_irqsave(&sn_sal_lock, flags);
-		if (sn_sal_tty)
+		if (sn_sal_tty) {
 			if (test_and_clear_bit(SN_SAL_EVENT_WRITE_WAKEUP, &sn_sal_event)) {
-				if ((sn_sal_tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-				    sn_sal_tty->ldisc.write_wakeup)
-					(sn_sal_tty->ldisc.write_wakeup)(sn_sal_tty);
-				wake_up_interruptible(&sn_sal_tty->write_wait);
+				if ((sn_sal_tty->flags & (1 << TTY_DO_WRITE_WAKEUP))
+							&& sn_sal_tty->ldisc.write_wakeup)
+					(sn_sal_tty->ldisc.write_wakeup)((struct tty_struct *)sn_sal_tty);
+				wake_up_interruptible((wait_queue_head_t *)&sn_sal_tty->write_wait);
 			}
+		}
 		spin_unlock_irqrestore(&sn_sal_lock, flags);
 	}
 }
@@ -587,12 +588,14 @@
 static void
 sn_sal_timer_poll(unsigned long dummy)
 {
+	unsigned long flags;
+
 	if (!sn_sal_irq) {
-		spin_lock(&sn_sal_lock);
-		receive_chars(NULL);
-		poll_transmit_chars();
-		spin_unlock(&sn_sal_lock);
-		mod_timer(&sn_sal_timer, jiffies + interrupt_timeout);
+		spin_lock_irqsave(&sn_sal_lock, flags);
+		sn_receive_chars(NULL, &flags);
+		sn_poll_transmit_chars();
+		spin_unlock_irqrestore(&sn_sal_lock, flags);
+		mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout);
 	}
 }
 
@@ -604,15 +607,10 @@
 	local_irq_save(flags);
 	sn_sal_interrupt(0, NULL, NULL);
 	local_irq_restore(flags);
-	mod_timer(&sn_sal_timer, jiffies + interrupt_timeout);
+	mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout);
 }
 
 /*
- * End of "sofware interrupt" routines.
- *********************************************************************/
-
-
-/*********************************************************************
  * User-level console routines
  */
 
@@ -639,7 +637,7 @@
 static void
 sn_sal_close(struct tty_struct *tty, struct file * filp)
 {
-	if (atomic_read(&tty->count) == 1) {
+	if (tty->count == 1) {
 		unsigned long flags;
 		tty->closing = 1;
 		if (tty->driver.flush_buffer)
@@ -664,7 +662,7 @@
 	if (from_user) {
 		while (1) {
 			int c1;
-			c = CIRC_SPACE_TO_END(xmit.head, xmit.tail,
+			c = CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail,
 					      SN_SAL_BUFFER_SIZE);
 
 			if (count < c)
@@ -672,7 +670,7 @@
 			if (c <= 0)
 				break;
 
-			c -= copy_from_user(sal_tmp_buffer, buf, c);
+			c -= copy_from_user(sn_tmp_buffer, buf, c);
 			if (!c) {
 				if (!ret)
 					ret = -EFAULT;
@@ -683,14 +681,13 @@
 			 * moved since the last time we looked.
 			 */
 			spin_lock_irqsave(&sn_sal_lock, flags);
-			c1 = CIRC_SPACE_TO_END(xmit.head, xmit.tail,
-					       SN_SAL_BUFFER_SIZE);
+			c1 = CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE);
 
 			if (c1 < c)
 				c = c1;
 
-			memcpy(xmit.buf + xmit.head, sal_tmp_buffer, c);
-			xmit.head = ((xmit.head + c) & (SN_SAL_BUFFER_SIZE - 1));
+			memcpy(xmit.cb_buf + xmit.cb_head, sn_tmp_buffer, c);
+			xmit.cb_head = ((xmit.cb_head + c) & (SN_SAL_BUFFER_SIZE - 1));
 			spin_unlock_irqrestore(&sn_sal_lock, flags);
 
 			buf += c;
@@ -699,20 +696,19 @@
 		}
 	} else {
 		/* The buffer passed in isn't coming from userland,
-		 * so cut out the middleman (sal_tmp_buffer).
+		 * so cut out the middleman (sn_tmp_buffer).
 		 */
 		spin_lock_irqsave(&sn_sal_lock, flags);
 		while (1) {
-			c = CIRC_SPACE_TO_END(xmit.head, xmit.tail,
-					      SN_SAL_BUFFER_SIZE);
+			c = CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE);
 
 			if (count < c)
 				c = count;
 			if (c <= 0) {
 				break;
 			}
-			memcpy(xmit.buf + xmit.head, buf, c);
-			xmit.head = ((xmit.head + c) & (SN_SAL_BUFFER_SIZE - 1));
+			memcpy(xmit.cb_buf + xmit.cb_head, buf, c);
+			xmit.cb_head = ((xmit.cb_head + c) & (SN_SAL_BUFFER_SIZE - 1));
 			buf += c;
 			count -= c;
 			ret += c;
@@ -721,10 +717,9 @@
 	}
 
 	spin_lock_irqsave(&sn_sal_lock, flags);
-	if (xmit.head != xmit.tail &&
-	    !(tty && (tty->stopped || tty->hw_stopped)))
-		if (sn_sal_ops->wakeup_transmit)
-			sn_sal_ops->wakeup_transmit();
+	if (xmit.cb_head != xmit.cb_tail && !(tty && (tty->stopped || tty->hw_stopped)))
+		if (sn_func->sal_wakeup_transmit)
+			sn_func->sal_wakeup_transmit();
 	spin_unlock_irqrestore(&sn_sal_lock, flags);
 
 	return ret;
@@ -737,10 +732,11 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&sn_sal_lock, flags);
-	if (CIRC_SPACE(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE) != 0) {
-		xmit.buf[xmit.head] = ch;
-		xmit.head = (xmit.head + 1) & (SN_SAL_BUFFER_SIZE-1);
-		sn_sal_ops->wakeup_transmit();
+	if (CIRC_SPACE(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE) != 0) {
+		xmit.cb_buf[xmit.cb_head] = ch;
+		xmit.cb_head = (xmit.cb_head + 1) & (SN_SAL_BUFFER_SIZE-1);
+		if ( sn_func->sal_wakeup_transmit )
+			sn_func->sal_wakeup_transmit();
 	}
 	spin_unlock_irqrestore(&sn_sal_lock, flags);
 }
@@ -752,9 +748,9 @@
 	unsigned long flags;
 
 	spin_lock_irqsave(&sn_sal_lock, flags);
-	if (CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE))
-		if (sn_sal_ops->wakeup_transmit)
-			sn_sal_ops->wakeup_transmit();
+	if (CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE))
+		if (sn_func->sal_wakeup_transmit)
+			sn_func->sal_wakeup_transmit();
 	spin_unlock_irqrestore(&sn_sal_lock, flags);
 }
 
@@ -766,7 +762,7 @@
 	int space;
 
 	spin_lock_irqsave(&sn_sal_lock, flags);
-	space = CIRC_SPACE(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE);
+	space = CIRC_SPACE(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE);
 	spin_unlock_irqrestore(&sn_sal_lock, flags);
 	return space;
 }
@@ -779,23 +775,13 @@
 	int space;
 
 	spin_lock_irqsave(&sn_sal_lock, flags);
-	space = CIRC_CNT(xmit.head, xmit.tail, SN_SAL_BUFFER_SIZE);
+	space = CIRC_CNT(xmit.cb_head, xmit.cb_tail, SN_SAL_BUFFER_SIZE);
 	DPRINTF("<%d>", space);
 	spin_unlock_irqrestore(&sn_sal_lock, flags);
 	return space;
 }
 
 
-static int
-sn_sal_ioctl(struct tty_struct *tty, struct file *file,
-	       unsigned int cmd, unsigned long arg)
-{
-	/* nothing supported */
-
-	return -ENOIOCTLCMD;
-}
-
-
 static void
 sn_sal_flush_buffer(struct tty_struct *tty)
 {
@@ -803,13 +789,12 @@
 
 	/* drop everything */
 	spin_lock_irqsave(&sn_sal_lock, flags);
-	xmit.head = xmit.tail = 0;
+	xmit.cb_head = xmit.cb_tail = 0;
 	spin_unlock_irqrestore(&sn_sal_lock, flags);
 
 	/* wake up tty level */
 	wake_up_interruptible(&tty->write_wait);
-	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) &&
-	    tty->ldisc.write_wakeup)
+	if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && tty->ldisc.write_wakeup)
 		(tty->ldisc.write_wakeup)(tty);
 }
 
@@ -841,11 +826,10 @@
 {
 	int len = 0;
 	off_t	begin = 0;
-	extern nasid_t get_console_nasid(void);
 
-	len += sprintf(page, "sn_serial: revision:%s nasid:%d irq:%d tx:%d rx:%d\n",
-		       serial_revdate, get_console_nasid(), sn_sal_irq,
-		       tx_count, rx_count);
+	len += sprintf(page, "sn_serial: nasid:%d irq:%d tx:%d rx:%d\n",
+		       snia_get_console_nasid(), sn_sal_irq,
+		       sn_total_tx_count, sn_total_rx_count);
 	*eof = 1;
 
 	if (off >= len+begin)
@@ -857,39 +841,38 @@
 
 
 static struct tty_driver sn_sal_driver = {
-	.magic = TTY_DRIVER_MAGIC,
-	.driver_name = "sn_serial",
+	.magic		= TTY_DRIVER_MAGIC,
+	.driver_name	= "sn_serial",
 #if defined(CONFIG_DEVFS_FS)
-	.name = "tts/%d",
+	.name		= "tts/%d",
 #else
-	.name = "ttyS",
+	.name		= "ttyS",
 #endif
-	.major = TTY_MAJOR,
-	.minor_start = SN_SAL_MINOR,
-	.num = 1,
-	.type = TTY_DRIVER_TYPE_SERIAL,
-	.subtype = SN_SAL_SUBTYPE,
-	.flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
-	.refcount = &sn_sal_refcount,
-	.table = &sn_sal_table,
-	.termios = &sn_sal_termios,
+	.major		= TTY_MAJOR,
+	.minor_start	= SN_SAL_MINOR,
+	.num		= 1,
+	.type		= TTY_DRIVER_TYPE_SERIAL,
+	.subtype	= SN_SAL_SUBTYPE,
+	.flags		= TTY_DRIVER_REAL_RAW | TTY_DRIVER_NO_DEVFS,
+	.refcount	= &sn_sal_refcount,
+	.table		= &sn_sal_table,
+	.termios	= &sn_sal_termios,
 	.termios_locked = &sn_sal_termios_locked,
 
-	.open = sn_sal_open,
-	.close = sn_sal_close,
-	.write = sn_sal_write,
-	.put_char = sn_sal_put_char,
-	.flush_chars = sn_sal_flush_chars,
-	.write_room = sn_sal_write_room,
+	.open		= sn_sal_open,
+	.close		= sn_sal_close,
+	.write		= sn_sal_write,
+	.put_char	= sn_sal_put_char,
+	.flush_chars	= sn_sal_flush_chars,
+	.write_room	= sn_sal_write_room,
 	.chars_in_buffer = sn_sal_chars_in_buffer,
-	.ioctl = sn_sal_ioctl,
-	.hangup = sn_sal_hangup,
+	.hangup		= sn_sal_hangup,
 	.wait_until_sent = sn_sal_wait_until_sent,
-	.read_proc = sn_sal_read_proc,
+	.read_proc	= sn_sal_read_proc,
 };
 
 /* sn_sal_init wishlist:
- * - allocate sal_tmp_buffer
+ * - allocate sn_tmp_buffer
  * - fix up the tty_driver struct
  * - turn on receive interrupts
  * - do any termios twiddling once and for all
@@ -902,19 +885,21 @@
 static void __init
 sn_sal_switch_to_asynch(void)
 {
-	debug_printf("sn_serial: about to switch to asynchronous console\n");
+	unsigned long flags;
+
+	sn_debug_printf("sn_serial: about to switch to asynchronous console\n");
 
 	/* without early_printk, we may be invoked late enough to race
 	 * with other cpus doing console IO at this point, however
 	 * console interrupts will never be enabled */
-	spin_lock(&sn_sal_lock);
+	spin_lock_irqsave(&sn_sal_lock, flags);
 
 	/* early_printk invocation may have done this for us */
-	if (!sn_sal_ops) {
+	if (!sn_func) {
 		if (IS_RUNNING_ON_SIMULATOR())
-			sn_sal_ops = &sim_ops;
+			sn_func = &sim_ops;
 		else
-			sn_sal_ops = &poll_ops;
+			sn_func = &poll_ops;
 	}
 
 	/* we can't turn on the console interrupt (as request_irq
@@ -926,17 +911,17 @@
 	sn_sal_timer.function = sn_sal_timer_poll;
 
 	if (IS_RUNNING_ON_SIMULATOR())
-		interrupt_timeout = 6;
-	else
+		sn_interrupt_timeout = 6;
+	else {
 		/* 960cps / 16 char FIFO = 60HZ 
-		   HZ / (SN_SAL_FIFO_SPEED_CPS / SN_SAL_FIFO_DEPTH) */
-		interrupt_timeout = HZ * SN_SAL_UART_FIFO_DEPTH / 
-			SN_SAL_UART_FIFO_SPEED_CPS;
-
-	mod_timer(&sn_sal_timer, jiffies + interrupt_timeout);
+		 * HZ / (SN_SAL_FIFO_SPEED_CPS / SN_SAL_FIFO_DEPTH) */
+		sn_interrupt_timeout = HZ * SN_SAL_UART_FIFO_DEPTH
+					/ SN_SAL_UART_FIFO_SPEED_CPS;
+	}
+	mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout);
 
 	sn_sal_is_asynch = 1;
-	spin_unlock(&sn_sal_lock);
+	spin_unlock_irqrestore(&sn_sal_lock, flags);
 }
 
 static void __init
@@ -944,17 +929,19 @@
 {
 	int irq;
 
-	debug_printf("sn_serial: switching to interrupt driven console\n");
+	sn_debug_printf("sn_serial: switching to interrupt driven console\n");
 
 	irq = sn_sal_connect_interrupt();
 	if (irq) {
 		unsigned long flags;
 		spin_lock_irqsave(&sn_sal_lock, flags);
+
 		/* sn_sal_irq is a global variable.  When it's set to
 		 * a non-zero value, we stop polling for input (since
 		 * interrupts should now be enabled). */
 		sn_sal_irq = irq;
-		sn_sal_ops = &intr_ops;
+		sn_func = &intr_ops;
+
 		/* turn on receive interrupts */
 		ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
 
@@ -965,9 +952,9 @@
 		if (CONSOLE_RESTART) {
 			/* kick the console every once in a while in
 			 * case we miss an interrupt */
-			interrupt_timeout = 20*HZ;
+			sn_interrupt_timeout = 20*HZ;
 			sn_sal_timer.function = sn_sal_timer_restart;
-			mod_timer(&sn_sal_timer, jiffies + interrupt_timeout);
+			mod_timer(&sn_sal_timer, jiffies + sn_interrupt_timeout);
 		}
 		spin_unlock_irqrestore(&sn_sal_lock, flags);
 	}
@@ -989,8 +976,7 @@
 	if (!sn_sal_is_asynch)
 		sn_sal_switch_to_asynch();
 
-	/* at this point (module_init) we can try to turn on
-	 * interrupts */
+	/* at this point (module_init) we can try to turn on interrupts */
 	if (!IS_RUNNING_ON_SIMULATOR())
 	    sn_sal_switch_to_interrupts();
 
@@ -1011,26 +997,14 @@
 static void __exit
 sn_sal_module_exit(void)
 {
-	unsigned long flags;
-	int e;
-
 	del_timer_sync(&sn_sal_timer);
-	spin_lock_irqsave(&sn_sal_lock, flags);
-	if ((e = tty_unregister_driver(&sn_sal_driver)))
-		printk(KERN_ERR "sn_serial: failed to unregister driver (%d)\n", e);
-
-	spin_unlock_irqrestore(&sn_sal_lock, flags);
+	tty_unregister_driver(&sn_sal_driver);
 }
 
 module_init(sn_sal_module_init);
 module_exit(sn_sal_module_exit);
 
 /*
- * End of user-level console routines.
- *********************************************************************/
-
-
-/*********************************************************************
  * Kernel console definitions
  */
 
@@ -1042,24 +1016,33 @@
 static void
 sn_sal_console_write(struct console *co, const char *s, unsigned count)
 {
-	BUG_ON(!sn_sal_is_asynch);
+	unsigned long flags;
 
-	if (count > CIRC_SPACE_TO_END(xmit.head, xmit.tail,
+	if (count > CIRC_SPACE_TO_END(xmit.cb_head, xmit.cb_tail,
 				      SN_SAL_BUFFER_SIZE))
-		debug_printf("\n*** SN_SAL_BUFFER_SIZE too small, lost chars\n");
+		sn_debug_printf("\n*** SN_SAL_BUFFER_SIZE too small, lost chars\n");
 
 	/* somebody really wants this output, might be an
 	 * oops, kdb, panic, etc.  make sure they get it. */
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 	if (spin_is_locked(&sn_sal_lock)) {
 		synch_flush_xmit();
-		sn_sal_ops->puts(s, count);
-	} else if (in_interrupt()) {
-		spin_lock(&sn_sal_lock);
-		synch_flush_xmit();
-		spin_unlock(&sn_sal_lock);
-		sn_sal_ops->puts(s, count);
+		sn_func->sal_puts(s, count);
 	} else
+#endif
+	if (in_interrupt()) {
+		spin_lock_irqsave(&sn_sal_lock, flags);
+		synch_flush_xmit();
+		spin_unlock_irqrestore(&sn_sal_lock, flags);
+		sn_func->sal_puts(s, count);
+	} else {
+#if defined(CONFIG_SMP) || defined(CONFIG_PREEMPT)
 		sn_sal_write(NULL, 0, s, count);
+#else
+		synch_flush_xmit();
+		sn_func->sal_puts(s, count);
+#endif
+	}
 }
 
 static kdev_t
@@ -1076,18 +1059,13 @@
 
 
 static struct console sal_console = {
-	.name = "ttyS",
-	.write = sn_sal_console_write,
-	.device = sn_sal_console_device,
-	.setup = sn_sal_console_setup,
-	.index = -1
+	.name	= "ttyS",
+	.write	= sn_sal_console_write,
+	.device	= sn_sal_console_device,
+	.setup	= sn_sal_console_setup,
+	.index	= -1
 };
 
-/*
- * End of kernel console definitions.
- *********************************************************************/
-
-
 void __init
 sn_sal_serial_console_init(void)
 {
diff -urN linux-2.4.23-pre6/drivers/md/lvm.c linux-2.4.23-pre7/drivers/md/lvm.c
--- linux-2.4.23-pre6/drivers/md/lvm.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/md/lvm.c	2003-10-09 17:48:21.000000000 -0700
@@ -1584,8 +1584,10 @@
 		minor = vg_ptr->vg_number;
 
 	/* check limits */
-	if (minor >= ABS_MAX_VG)
+	if (minor >= ABS_MAX_VG) {
+		kfree(vg_ptr);
 		return -EFAULT;
+	}
 
 	/* Validate it */
 	if (vg[VG_CHR(minor)] != NULL) {
@@ -1653,8 +1655,7 @@
 				P_IOCTL
 				    ("ERROR: copying LV ptr %p (%d bytes)\n",
 				     lvp, sizeof(lv_t));
-				lvm_do_vg_remove(minor);
-				return -EFAULT;
+				goto copy_fault;
 			}
 			if (lv.lv_access & LV_SNAPSHOT) {
 				snap_lv_ptr[ls] = lvp;
@@ -1665,8 +1666,7 @@
 			vg_ptr->lv[l] = NULL;
 			/* only create original logical volumes for now */
 			if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {
-				lvm_do_vg_remove(minor);
-				return -EFAULT;
+				goto copy_fault;
 			}
 		}
 	}
@@ -1676,12 +1676,10 @@
 	for (l = 0; l < ls; l++) {
 		lv_t *lvp = snap_lv_ptr[l];
 		if (copy_from_user(&lv, lvp, sizeof(lv_t)) != 0) {
-			lvm_do_vg_remove(minor);
-			return -EFAULT;
+			goto copy_fault;
 		}
 		if (lvm_do_lv_create(minor, lv.lv_name, &lv) != 0) {
-			lvm_do_vg_remove(minor);
-			return -EFAULT;
+			goto copy_fault;
 		}
 	}
 
@@ -1696,6 +1694,10 @@
 	vg_ptr->vg_status |= VG_ACTIVE;
 
 	return 0;
+copy_fault:
+	lvm_do_vg_remove(minor);
+	vfree(snap_lv_ptr);
+	return -EFAULT;
 }				/* lvm_do_vg_create() */
 
 
diff -urN linux-2.4.23-pre6/drivers/media/video/bttv-cards.c linux-2.4.23-pre7/drivers/media/video/bttv-cards.c
--- linux-2.4.23-pre6/drivers/media/video/bttv-cards.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/bttv-cards.c	2003-10-09 17:48:21.000000000 -0700
@@ -31,6 +31,9 @@
 #include <linux/init.h>
 #include <linux/pci.h>
 #include <linux/vmalloc.h>
+#ifdef CONFIG_FW_LOADER
+# include <linux/firmware.h>
+#endif
 
 #include <asm/io.h>
 
@@ -76,6 +79,7 @@
 static unsigned int card[BTTV_MAX]  = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
 static unsigned int pll[BTTV_MAX]   = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
 static unsigned int tuner[BTTV_MAX] = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
+static unsigned int svhs[BTTV_MAX]  = { [ 0 ... (BTTV_MAX-1) ] = UNSET};
 #ifdef MODULE
 static unsigned int autoload = 1;
 #else
@@ -1212,7 +1216,7 @@
 	.tuner_type     = -1,
 	.pll            = PLL_28,
 	.muxsel         = { 2 },
-	gpiomask:       0
+	.gpiomask       = 0
 },{
         /* Tomasz Pyra <hellfire@sedez.iq.pl> */
         .name           = "Prolink Pixelview PV-BT878P+ (Rev.4C,8E)",
@@ -1299,7 +1303,7 @@
 },{
         .name           = "Powercolor MTV878/ MTV878R/ MTV878F",
         .video_inputs   = 3,
-        audio_inputs:   2, 
+        .audio_inputs   = 2, 
 	.tuner		= 0,
         .svhs           = 2,
         .gpiomask       = 0x1C800F,  // Bit0-2: Audio select, 8-12:remote control 14:remote valid 15:remote reset
@@ -1339,7 +1343,7 @@
 },{
         .name           = "Jetway TV/Capture JW-TV878-FBK, Kworld KW-TV878RF",
         .video_inputs   = 4,
-        audio_inputs:   3, 
+        .audio_inputs   = 3,
         .tuner          = 0,
         .svhs           = 2,
         .gpiomask       = 7,
@@ -1389,18 +1393,19 @@
 	.gpiomask       = 7,
 	.audiomux       = {7},
 },{
-	.name           = "GV-BCTV5/PCI",
+	.name           = "IODATA GV-BCTV5/PCI",
 	.video_inputs   = 3,
 	.audio_inputs   = 1,
 	.tuner          = 0,
 	.svhs           = 2,
-	.gpiomask       = 0x010f00,
+	.gpiomask       = 0x0f0f80,
 	.muxsel         = {2, 3, 1, 0},
-	.audiomux       = {0x10000, 0, 0x10000, 0, 0, 0},
+	.audiomux       = {0x030000, 0x010000, 0x030000, 0, 0x020000, 0},
 	.no_msp34xx     = 1,
 	.pll            = PLL_28,
 	.tuner_type     = TUNER_PHILIPS_NTSC_M,
 	.audio_hook     = gvbctv3pci_audio,
+	.has_radio      = 1,
 },{
 	.name           = "Osprey 100/150 (878)", /* 0x1(2|3)-45C6-C1 */
 	.video_inputs   = 4,                  /* id-inputs-clock */
@@ -1854,12 +1859,8 @@
 		btv->type=card[btv->nr];
 	
 	/* print which card config we are using */
-	sprintf(btv->video_dev.name,"BT%d%s(%.23s)",
-		btv->id,
-		(btv->id==848 && btv->revision==0x12) ? "A" : "",
-		bttv_tvcards[btv->type].name);
 	printk(KERN_INFO "bttv%d: using: %s [card=%d,%s]\n",btv->nr,
-	       btv->video_dev.name,btv->type,
+	       bttv_tvcards[btv->type].name, btv->type,
 	       card[btv->nr] < bttv_num_tvcards
 	       ? "insmod option" : "autodetected");
 
@@ -2270,6 +2271,9 @@
 				      &btv->pinnacle_id);
 	if (btv->tuner_type != UNSET)
 		bttv_call_i2c_clients(btv,TUNER_SET_TYPE,&btv->tuner_type);
+	btv->svhs = bttv_tvcards[btv->type].svhs;
+	if (svhs[btv->nr] != UNSET)
+		btv->svhs = svhs[btv->nr];
 
 	if (bttv_tvcards[btv->type].has_radio)
 		btv->has_radio=1;
@@ -2549,18 +2553,19 @@
 int __devinit pvr_boot(struct bttv *btv)
 {
         const struct firmware *fw_entry;
-	struct device *dev = btv->dev->dev;
-	int result;
+	int rc;
 
-	result = request_firmware(&fw_entry, "hcwamc.rbf", dev);
-	if (result != 0) {
+	rc = request_firmware(&fw_entry, "hcwamc.rbf", pci_name(btv->dev));
+	if (rc != 0) {
 		printk(KERN_WARNING "bttv%d: no altera firmware [via hotplug]\n",
 		       btv->nr);
                 return rc;
         }
-	result = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
+	rc = pvr_altera_load(btv, fw_entry->data, fw_entry->size);
+	printk(KERN_INFO "bttv%d: altera firmware upload %s\n",
+	       btv->nr, (rc < 0) ? "failed" : "ok");
         release_firmware(fw_entry);
-	return result;
+	return rc;
 }	
 #endif
 
@@ -2695,12 +2700,12 @@
 
 static void __devinit avermedia_eeprom(struct bttv *btv)
 {
-        int tuner_make,tuner_tv_fm,tuner_format,tuner=0,remote;
+        int tuner_make,tuner_tv_fm,tuner_format,tuner=0;
 
-	tuner_make   = (eeprom_data[0x41] & 0x7);
-        tuner_tv_fm  = (eeprom_data[0x41] & 0x18) >> 3;
-        tuner_format = (eeprom_data[0x42] & 0xf0) >> 4;
-	remote       = (eeprom_data[0x42] & 0x01);
+	tuner_make      = (eeprom_data[0x41] & 0x7);
+        tuner_tv_fm     = (eeprom_data[0x41] & 0x18) >> 3;
+        tuner_format    = (eeprom_data[0x42] & 0xf0) >> 4;
+	btv->has_remote = (eeprom_data[0x42] & 0x01);
 
 	if (tuner_make == 0 || tuner_make == 2)
 		if(tuner_format <=9)
@@ -2717,8 +2722,8 @@
 	} else
 		printk("Unknown type");
 	printk(" radio:%s remote control:%s\n",
-		tuner_tv_fm?"yes":"no",
-		remote?"yes":"no");
+	       tuner_tv_fm     ? "yes" : "no",
+	       btv->has_remote ? "yes" : "no");
 }
 
 /* used on Voodoo TV/FM (Voodoo 200), S0 wired to 0x10000 */
@@ -3466,9 +3471,11 @@
 		latency = 0x0A;
 #endif
 
+#if 0
 	/* print which chipset we have */
 	while ((dev = pci_find_class(PCI_CLASS_BRIDGE_HOST << 8,dev)))
-		printk(KERN_INFO "bttv: Host bridge is %s\n",dev->name);
+		printk(KERN_INFO "bttv: Host bridge is %s\n",pci_name(dev));
+#endif
 
 	/* print warnings about any quirks found */
 	if (triton1)
diff -urN linux-2.4.23-pre6/drivers/media/video/bttv-driver.c linux-2.4.23-pre7/drivers/media/video/bttv-driver.c
--- linux-2.4.23-pre6/drivers/media/video/bttv-driver.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/bttv-driver.c	2003-10-09 17:48:21.000000000 -0700
@@ -400,13 +400,10 @@
 #endif
 
 	input %= bttv_tvcards[btv->type].video_inputs;
-	if (input==bttv_tvcards[btv->type].svhs)
-	{
+	if (input == btv->svhs) {
 		btor(BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btor(BT848_CONTROL_COMP, BT848_O_CONTROL);
-	}
-	else
-	{
+	} else {
 		btand(~BT848_CONTROL_COMP, BT848_E_CONTROL);
 		btand(~BT848_CONTROL_COMP, BT848_O_CONTROL);
 	}
@@ -1668,7 +1665,7 @@
 			v.type=VIDEO_TYPE_TV;
 			v.tuners=1;
 		} 
-		else if (channel==bttv_tvcards[btv->type].svhs) 
+		else if (channel == btv->svhs) 
 			strcpy(v.name,"S-Video");
 		else if (bttv_tvcards[btv->type].muxsel[v.channel] < 0)
 			strcpy(v.name,"Digital Video");
@@ -2200,7 +2197,7 @@
 static struct video_device bttv_template=
 {
 	.owner		= THIS_MODULE,
-	.name		= "UNSET",
+	.name		= "bttv video",
 	.type		= VID_TYPE_TUNER|VID_TYPE_CAPTURE|VID_TYPE_OVERLAY|VID_TYPE_TELETEXT,
 	.hardware	= VID_HARDWARE_BT848,
 	.open		= bttv_open,
@@ -2369,7 +2366,6 @@
 static int radio_open(struct video_device *dev, int flags)
 {
 	struct bttv *btv = (struct bttv *)(dev-1);
-	unsigned long v;
 
         down(&btv->lock);
 	if (btv->user)
@@ -2377,8 +2373,6 @@
 	btv->user++;
 
 	btv->radio = 1;
-	v = 400*16;
-	bttv_call_i2c_clients(btv,VIDIOCSFREQ,&v);
 	bttv_call_i2c_clients(btv,AUDC_SET_RADIO,&btv->tuner_type);
 	bt848_muxsel(btv,0);
 	up(&btv->lock);
@@ -3153,7 +3147,7 @@
 	return result;
 }
 
-static struct pci_device_id bttv_pci_tbl[] __devinitdata = {
+static struct pci_device_id bttv_pci_tbl[] = {
         {PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT848,
          PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_BROOKTREE, PCI_DEVICE_ID_BT849,
diff -urN linux-2.4.23-pre6/drivers/media/video/bttv-if.c linux-2.4.23-pre7/drivers/media/video/bttv-if.c
--- linux-2.4.23-pre6/drivers/media/video/bttv-if.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/bttv-if.c	2003-10-09 17:48:21.000000000 -0700
@@ -190,6 +190,7 @@
 	return state;
 }
 
+#ifndef I2C_PEC
 static void bttv_inc_use(struct i2c_adapter *adap)
 {
 	MOD_INC_USE_COUNT;
@@ -199,6 +200,7 @@
 {
 	MOD_DEC_USE_COUNT;
 }
+#endif
 
 static int attach_inform(struct i2c_client *client)
 {
@@ -241,8 +243,15 @@
 };
 
 static struct i2c_adapter bttv_i2c_adap_template = {
+#ifdef I2C_PEC
+	.owner             = THIS_MODULE,
+#else
 	.inc_use           = bttv_inc_use,
 	.dec_use           = bttv_dec_use,
+#endif
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	.class             = I2C_ADAP_CLASS_TV_ANALOG,
+#endif
 	I2C_DEVNAME("bt848"),
 	.id                = I2C_HW_B_BT848,
 	.client_register   = attach_inform,
diff -urN linux-2.4.23-pre6/drivers/media/video/bttvp.h linux-2.4.23-pre7/drivers/media/video/bttvp.h
--- linux-2.4.23-pre6/drivers/media/video/bttvp.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/bttvp.h	2003-10-09 17:48:21.000000000 -0700
@@ -26,7 +26,7 @@
 #define _BTTVP_H_
 
 #include <linux/version.h>
-#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,107)
+#define BTTV_VERSION_CODE KERNEL_VERSION(0,7,108)
 
 #include <linux/types.h>
 #include <linux/wait.h>
@@ -131,6 +131,7 @@
         unsigned int tuner_type;
         unsigned int pinnacle_id;
         unsigned int channel;
+	unsigned int svhs;
         
         unsigned int nr;
 	unsigned short id;
@@ -150,6 +151,7 @@
 	int audio_chip;      /* set to one of the chips supported by bttv.c */
 	int radio;
 	int has_radio;
+	int has_remote;
 
 	/* miro/pinnacle + Aimslab VHX
 	   philips matchbox (tea5757 radio tuner) support */
diff -urN linux-2.4.23-pre6/drivers/media/video/id.h linux-2.4.23-pre7/drivers/media/video/id.h
--- linux-2.4.23-pre6/drivers/media/video/id.h	2002-08-02 17:39:44.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/id.h	2003-10-09 17:48:21.000000000 -0700
@@ -27,6 +27,9 @@
 #ifndef  I2C_DRIVERID_TDA9874
 # define I2C_DRIVERID_TDA9874 I2C_DRIVERID_EXP0+7
 #endif
+#ifndef  I2C_DRIVERID_SAA6752HS
+# define I2C_DRIVERID_SAA6752HS I2C_DRIVERID_EXP0+8
+#endif
 
 /* algorithms */
 #ifndef I2C_ALGO_SAA7134
diff -urN linux-2.4.23-pre6/drivers/media/video/msp3400.c linux-2.4.23-pre7/drivers/media/video/msp3400.c
--- linux-2.4.23-pre6/drivers/media/video/msp3400.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/msp3400.c	2003-10-09 17:48:21.000000000 -0700
@@ -1405,8 +1405,13 @@
 
 static int msp_probe(struct i2c_adapter *adap)
 {
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
+		return i2c_probe(adap, &addr_data, msp_attach);
+#else
 	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
 		return i2c_probe(adap, &addr_data, msp_attach);
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.23-pre6/drivers/media/video/tda7432.c linux-2.4.23-pre7/drivers/media/video/tda7432.c
--- linux-2.4.23-pre6/drivers/media/video/tda7432.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/tda7432.c	2003-10-09 17:48:21.000000000 -0700
@@ -341,8 +341,13 @@
 
 static int tda7432_probe(struct i2c_adapter *adap)
 {
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
+		return i2c_probe(adap, &addr_data, tda7432_attach);
+#else
 	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
 		return i2c_probe(adap, &addr_data, tda7432_attach);
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.23-pre6/drivers/media/video/tda9875.c linux-2.4.23-pre7/drivers/media/video/tda9875.c
--- linux-2.4.23-pre6/drivers/media/video/tda9875.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/tda9875.c	2003-10-09 17:48:21.000000000 -0700
@@ -275,8 +275,13 @@
 
 static int tda9875_probe(struct i2c_adapter *adap)
 {
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
+		return i2c_probe(adap, &addr_data, tda9875_attach);
+#else
 	if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
 		return i2c_probe(adap, &addr_data, tda9875_attach);
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.23-pre6/drivers/media/video/tda9887.c linux-2.4.23-pre7/drivers/media/video/tda9887.c
--- linux-2.4.23-pre6/drivers/media/video/tda9887.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/tda9887.c	2003-10-09 17:48:21.000000000 -0700
@@ -369,6 +369,10 @@
 
 static int tda9887_probe(struct i2c_adapter *adap)
 {
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
+		return i2c_probe(adap, &addr_data, tda9887_attach);
+#else
 	switch (adap->id) {
 	case I2C_ALGO_BIT | I2C_HW_B_BT848:
 	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
@@ -376,6 +380,7 @@
 		return i2c_probe(adap, &addr_data, tda9887_attach);
 		break;
 	}
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.23-pre6/drivers/media/video/tuner.c linux-2.4.23-pre7/drivers/media/video/tuner.c
--- linux-2.4.23-pre6/drivers/media/video/tuner.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/tuner.c	2003-10-09 17:48:21.000000000 -0700
@@ -847,6 +847,10 @@
 	}
 	this_adap = 0;
 
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
+		return i2c_probe(adap, &addr_data, tuner_attach);
+#else
 	switch (adap->id) {
 	case I2C_ALGO_BIT | I2C_HW_B_BT848:
 	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
@@ -855,6 +859,7 @@
 		return i2c_probe(adap, &addr_data, tuner_attach);
 		break;
 	}
+#endif
 	return 0;
 }
 
@@ -893,7 +898,10 @@
                         mt2032_init(client);
 		break;
 	case AUDC_SET_RADIO:
-		t->radio = 1;
+		if (!t->radio) {
+			set_tv_freq(client,400 * 16);
+			t->radio = 1;
+		}
 		break;
 	case AUDC_CONFIG_PINNACLE:
 		switch (*iarg) {
diff -urN linux-2.4.23-pre6/drivers/media/video/tvaudio.c linux-2.4.23-pre7/drivers/media/video/tvaudio.c
--- linux-2.4.23-pre6/drivers/media/video/tvaudio.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/tvaudio.c	2003-10-09 17:48:21.000000000 -0700
@@ -1507,12 +1507,17 @@
 
 static int chip_probe(struct i2c_adapter *adap)
 {
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
+		return i2c_probe(adap, &addr_data, chip_attach);
+#else
 	switch (adap->id) {
 	case I2C_ALGO_BIT | I2C_HW_B_BT848:
 	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
 	case I2C_ALGO_SAA7134:
 		return i2c_probe(adap, &addr_data, chip_attach);
 	}
+#endif
 	return 0;
 }
 
diff -urN linux-2.4.23-pre6/drivers/media/video/tvmixer.c linux-2.4.23-pre7/drivers/media/video/tvmixer.c
--- linux-2.4.23-pre6/drivers/media/video/tvmixer.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/tvmixer.c	2003-10-09 17:48:21.000000000 -0700
@@ -18,6 +18,7 @@
 
 # include "i2c-compat.h"
 # define strlcpy(dest,src,len) strncpy(dest,src,(len)-1)
+# define iminor(inode) minor(inode->i_rdev)
 
 #define DEV_MAX  4
 
@@ -175,7 +176,7 @@
 
 static int tvmixer_open(struct inode *inode, struct file *file)
 {
-        int i, minor = minor(inode->i_rdev);
+        int i, minor = iminor(inode);
         struct TVMIXER *mix = NULL;
 	struct i2c_client *client = NULL;
 
@@ -192,8 +193,10 @@
 
 	/* lock bttv in memory while the mixer is in use  */
 	file->private_data = mix;
+#ifndef I2C_PEC
 	if (client->adapter->inc_use)
 		client->adapter->inc_use(client->adapter);
+#endif
         return 0;
 }
 
@@ -207,15 +210,25 @@
 		return -ENODEV;
 	}
 
+#ifndef I2C_PEC
 	if (client->adapter->dec_use)
 		client->adapter->dec_use(client->adapter);
+#endif
 	return 0;
 }
 
 static struct i2c_driver driver = {
+#ifdef I2C_PEC
+	.owner           = THIS_MODULE,
+#endif
 	.name            = "tv card mixer driver",
         .id              = I2C_DRIVERID_TVMIXER,
+#ifdef I2C_DF_DUMMY
 	.flags           = I2C_DF_DUMMY,
+#else
+	.flags           = I2C_DF_NOTIFY,
+        .detach_adapter  = tvmixer_adapters,
+#endif
         .attach_adapter  = tvmixer_adapters,
         .detach_client   = tvmixer_clients,
 };
@@ -247,6 +260,10 @@
 	struct video_audio va;
 	int i,minor;
 
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
+	if (!(client->adapter->class & I2C_ADAP_CLASS_TV_ANALOG))
+		return -1;
+#else
 	/* TV card ??? */
 	switch (client->adapter->id) {
 	case I2C_ALGO_BIT | I2C_HW_B_BT848:
@@ -257,6 +274,7 @@
 		/* ignore that one */
 		return -1;
 	}
+#endif
 
 	/* unregister ?? */
 	for (i = 0; i < DEV_MAX; i++) {
diff -urN linux-2.4.23-pre6/drivers/media/video/videodev.c linux-2.4.23-pre7/drivers/media/video/videodev.c
--- linux-2.4.23-pre6/drivers/media/video/videodev.c	2003-06-13 07:51:34.000000000 -0700
+++ linux-2.4.23-pre7/drivers/media/video/videodev.c	2003-10-09 17:48:21.000000000 -0700
@@ -62,6 +62,20 @@
 
 #endif /* CONFIG_PROC_FS && CONFIG_VIDEO_PROC_FS */
 
+struct video_device *video_device_alloc(void)
+{
+	struct video_device *vfd;
+	vfd = kmalloc(sizeof(*vfd),GFP_KERNEL);
+	if (NULL == vfd)
+		return NULL;
+	memset(vfd,0,sizeof(*vfd));
+	return vfd;
+}
+
+void video_device_release(struct video_device *vfd)
+{
+	kfree(vfd);
+}
 
 /*
  *	Read will do some smarts later on. Buffer pin etc.
@@ -611,6 +625,8 @@
 #endif
 
 	devfs_unregister (vfd->devfs_handle);
+	if (vfd->release)
+		vfd->release(vfd);
 	video_device[vfd->minor]=NULL;
 	MOD_DEC_USE_COUNT;
 	up(&videodev_lock);
@@ -661,6 +677,8 @@
 module_init(videodev_init)
 module_exit(videodev_exit)
 
+EXPORT_SYMBOL(video_device_alloc);
+EXPORT_SYMBOL(video_device_release);
 EXPORT_SYMBOL(video_register_device);
 EXPORT_SYMBOL(video_unregister_device);
 EXPORT_SYMBOL(video_devdata);
diff -urN linux-2.4.23-pre6/drivers/net/pppoe.c linux-2.4.23-pre7/drivers/net/pppoe.c
--- linux-2.4.23-pre6/drivers/net/pppoe.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/net/pppoe.c	2003-10-09 17:48:21.000000000 -0700
@@ -654,8 +654,10 @@
 	release_sock(sk);
 	return error;
 err_put:
-	dev_put(po->pppoe_dev);
-	po->pppoe_dev = NULL;
+	if (po->pppoe_dev) {
+		dev_put(po->pppoe_dev);
+		po->pppoe_dev = NULL;
+	}
 	goto end;
 }
 
diff -urN linux-2.4.23-pre6/drivers/net/wan/8253x/build linux-2.4.23-pre7/drivers/net/wan/8253x/build
--- linux-2.4.23-pre6/drivers/net/wan/8253x/build	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/net/wan/8253x/build	1969-12-31 16:00:00.000000000 -0800
@@ -1,8 +0,0 @@
-cc -g  -o 8253xcfg -I. -U__KERNEL__ 8253xcfg.c
-cc -g  -o 8253xspeed -I. -U__KERNEL__ 8253xspeed.c
-cc -g  -o 8253xmode -I. -U__KERNEL__ 8253xmode.c
-cc -g  -o 8253xpeer -I. -U__KERNEL__ 8253xpeer.c
-cc -g  -o eprom9050 -I. -U__KERNEL__ eprom9050.c
-
-
-
diff -urN linux-2.4.23-pre6/drivers/net/wan/Config.in linux-2.4.23-pre7/drivers/net/wan/Config.in
--- linux-2.4.23-pre6/drivers/net/wan/Config.in	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/net/wan/Config.in	2003-10-09 17:48:21.000000000 -0700
@@ -38,12 +38,12 @@
       fi
       dep_tristate '    Support for Frame Relay on MultiGate boards' CONFIG_COMX_PROTO_FR $CONFIG_COMX
    fi
-#
-# The Etinc driver has not been tested as non-modular yet.
-#
-
-   dep_tristate '  Etinc PCISYNC serial board support (EXPERIMENTAL)' CONFIG_DSCC4 m
 
+   dep_tristate '  DSCC4 support' CONFIG_DSCC4 m
+   if [ "$CONFIG_DSCC4" = "m" ]; then
+      bool '    Etinc PCISYNC features' CONFIG_DSCC4_PCISYNC
+      bool '    GPIO and PCI #RST pins wired together' CONFIG_DSCC4_PCI_RST
+   fi
 
 #
 # Lan Media's board. Currently 1000, 1200, 5200, 5245
diff -urN linux-2.4.23-pre6/drivers/net/wan/dscc4.c linux-2.4.23-pre7/drivers/net/wan/dscc4.c
--- linux-2.4.23-pre6/drivers/net/wan/dscc4.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/net/wan/dscc4.c	2003-10-09 17:48:21.000000000 -0700
@@ -47,7 +47,7 @@
  * Tx direction
  * When the tx ring is full, the xmit routine issues a call to netdev_stop.
  * The device is supposed to be enabled again during an ALLS irq (we could
- * use HI but as it's easy to loose events, it's fscked).
+ * use HI but as it's easy to lose events, it's fscked).
  *
  * Rx direction
  * The received frames aren't supposed to span over multiple receiving areas.
@@ -80,7 +80,6 @@
  * - misc crapectomy.
  */
 
-#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/types.h>
 #include <linux/errno.h>
@@ -108,10 +107,15 @@
 #include <linux/hdlc.h>
 
 /* Version */
-static const char version[] = "$Id: dscc4.c,v 1.159 2002/04/10 22:05:17 romieu Exp $ for Linux\n";
+static const char version[] = "$Id: dscc4.c,v 1.173 2003/09/20 23:55:34 romieu Exp $ for Linux\n";
 static int debug;
 static int quartz;
 
+#ifdef CONFIG_DSCC4_PCI_RST
+static DECLARE_MUTEX(dscc4_sem);
+static u32 dscc4_pci_config_store[16];
+#endif
+
 #define	DRV_NAME	"dscc4"
 
 #undef DSCC4_POLLING
@@ -164,8 +168,15 @@
 
 #define SOURCE_ID(flags)	(((flags) >> 28) & 0x03)
 #define TO_SIZE(state)		(((state) >> 16) & 0x1fff)
-#define TO_STATE(len)		cpu_to_le32(((len) & TxSizeMax) << 16)
-#define RX_MAX(len)		((((len) >> 5) + 1) << 5)
+
+/*
+ * Given the operating range of Linux HDLC, the 2 defines below could be
+ * made simpler. However they are a fine reminder for the limitations of
+ * the driver: it's better to stay < TxSizeMax and < RxSizeMax.
+ */
+#define TO_STATE_TX(len)	cpu_to_le32(((len) & TxSizeMax) << 16)
+#define TO_STATE_RX(len)	cpu_to_le32((RX_MAX(len) % RxSizeMax) << 16)
+#define RX_MAX(len)		((((len) >> 5) + 1) << 5)	/* Cf RLCR */
 #define SCC_REG_START(dpriv)	(SCC_START+(dpriv->dev_id)*SCC_OFFSET)
 
 struct dscc4_pci_priv {
@@ -256,6 +267,10 @@
 #define IMR     0x54
 #define ISR     0x58
 
+#define GPDIR	0x0400
+#define GPDATA	0x0404
+#define GPIM	0x0408
+
 /* Bit masks */
 #define EncodingMask	0x00700000
 #define CrcMask		0x00000003
@@ -272,7 +287,8 @@
 #define Idt		0x00080000
 #define TxSccRes	0x01000000
 #define RxSccRes	0x00010000
-#define TxSizeMax	0x1fff
+#define TxSizeMax	0x1fff		/* Datasheet DS1 - 11.1.1.1 */
+#define RxSizeMax	0x1ffc		/* Datasheet DS1 - 11.1.2.1 */
 
 #define Ccr0ClockMask	0x0000003f
 #define Ccr1LoopMask	0x00000200
@@ -283,6 +299,7 @@
 #define Hold		0x40000000
 #define SccBusy		0x10000000
 #define PowerUp		0x80000000
+#define Vis		0x00001000
 #define FrameOk		(FrameVfr | FrameCrc)
 #define FrameVfr	0x80
 #define FrameRdo	0x40
@@ -319,10 +336,19 @@
 #define Arf		0x00000002
 #define ArAck		0x00000001
 
-/* Misc */
+/* State flags */
+#define Ready		0x00000000
 #define NeedIDR		0x00000001
 #define NeedIDT		0x00000002
 #define RdoSet		0x00000004
+#define FakeReset	0x00000008
+
+/* Don't mask RDO. Ever. */
+#ifdef DSCC4_POLLING
+#define EventsMask	0xfffeef7f
+#else
+#define EventsMask	0xfffa8f7a
+#endif
 
 /* Functions prototypes */
 static inline void dscc4_rx_irq(struct dscc4_pci_priv *, struct dscc4_dev_priv *);
@@ -487,9 +513,9 @@
 	skb = dev_alloc_skb(len);
 	dpriv->rx_skbuff[dirty] = skb;
 	if (skb) {
-	skb->dev = dev;
+		skb->dev = dev;
 		skb->protocol = hdlc_type_trans(skb, dev);
-	skb->mac.raw = skb->data;
+		skb->mac.raw = skb->data;
 		rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
 					     len, PCI_DMA_FROMDEVICE);
 	} else {
@@ -566,15 +592,19 @@
 	return (i >= 0 ) ? i : -EAGAIN;
 }
 
-/* Requires protection against interrupt */
+#if 0 /* dscc4_{rx/tx}_reset are both unreliable - more tweak needed */
 static void dscc4_rx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev)
 {
+	unsigned long flags;
+
+	spin_lock_irqsave(&dpriv->pci_priv->lock, flags);
 	/* Cf errata DS5 p.6 */
 	writel(0x00000000, dev->base_addr + CH0LRDA + dpriv->dev_id*4);
-	scc_writel(~PowerUp & scc_readl(dpriv, CCR0), dpriv, dev, CCR0);
+	scc_patchl(PowerUp, 0, dpriv, dev, CCR0);
 	readl(dev->base_addr + CH0LRDA + dpriv->dev_id*4);
 	writel(MTFi|Rdr, dev->base_addr + dpriv->dev_id*0x0c + CH0CFG);
 	writel(Action, dev->base_addr + GCMDR);
+	spin_unlock_irqrestore(&dpriv->pci_priv->lock, flags);
 }
 
 static void dscc4_tx_reset(struct dscc4_dev_priv *dpriv, struct net_device *dev)
@@ -582,7 +612,7 @@
 	u16 i = 0;
 
 	/* Cf errata DS5 p.7 */
-	scc_writel(~PowerUp & scc_readl(dpriv, CCR0), dpriv, dev, CCR0);
+	scc_patchl(PowerUp, 0, dpriv, dev, CCR0);
 	scc_writel(0x00050000, dpriv, dev, CCR2);
 	/*
 	 * Must be longer than the time required to fill the fifo.
@@ -596,6 +626,7 @@
 	if (dscc4_do_action(dev, "Rdt") < 0)
 		printk(KERN_ERR "%s: Tx reset failed\n", dev->name);
 }
+#endif
 
 /* TODO: (ab)use this function to refill a completely depleted RX ring. */
 static inline void dscc4_rx_skb(struct dscc4_dev_priv *dpriv,
@@ -619,6 +650,8 @@
 		stats->rx_packets++;
 		stats->rx_bytes += pkt_len;
 		skb_put(skb, pkt_len);
+		if (netif_running(dev))
+			skb->protocol = hdlc_type_trans(skb, dev);
 		skb->dev->last_rx = jiffies;
 		netif_rx(skb);
 	} else {
@@ -661,8 +694,8 @@
 	kfree(ppriv);
 }
 
-static int __init dscc4_init_one(struct pci_dev *pdev,
-				  const struct pci_device_id *ent)
+static int __devinit dscc4_init_one(struct pci_dev *pdev,
+				    const struct pci_device_id *ent)
 {
 	struct dscc4_pci_priv *priv;
 	struct dscc4_dev_priv *dpriv;
@@ -805,7 +838,8 @@
 static void dscc4_init_registers(struct dscc4_dev_priv *dpriv,
 				 struct net_device *dev)
 {
-	scc_writel(0x80001000, dpriv, dev, CCR0);
+	/* No interrupts, SCC core disabled. Let's relax */
+	scc_writel(0x00000000, dpriv, dev, CCR0);
 
 	scc_writel(LengthCheck | (HDLC_MAX_MRU >> 5), dpriv, dev, RLCR);
 
@@ -813,29 +847,21 @@
 	 * No address recognition/crc-CCITT/cts enabled
 	 * Shared flags transmission disabled - cf errata DS5 p.11
 	 * Carrier detect disabled - cf errata p.14
+	 * FIXME: carrier detection/polarity may be handled more gracefully.
 	 */
-	scc_writel(0x021c8000, dpriv, dev, CCR1);
+	scc_writel(0x02408000, dpriv, dev, CCR1);
 
 	/* crc not forwarded - Cf errata DS5 p.11 */
 	scc_writel(0x00050008 & ~RxActivate, dpriv, dev, CCR2);
 	// crc forwarded
 	//scc_writel(0x00250008 & ~RxActivate, dpriv, dev, CCR2);
-
-	/* Don't mask RDO. Ever. */
-#ifdef DSCC4_POLLING
-	scc_writel(0xfffeef7f, dpriv, dev, IMR); /* Interrupt mask */
-#else
-	//scc_writel(0xfffaef7f, dpriv, dev, IMR); /* Interrupt mask */
-	//scc_writel(0xfffaef7e, dpriv, dev, IMR); /* Interrupt mask */
-	scc_writel(0xfffa8f7a, dpriv, dev, IMR); /* Interrupt mask */
-#endif
 }
 
 static int dscc4_found1(struct pci_dev *pdev, unsigned long ioaddr)
 {
 	struct dscc4_pci_priv *ppriv;
 	struct dscc4_dev_priv *root;
-	int i = 0;
+	int i, ret = -ENOMEM;
 
 	root = (struct dscc4_dev_priv *)
 		kmalloc(dev_per_card*sizeof(*root), GFP_KERNEL);
@@ -867,6 +893,8 @@
 		d->tx_timeout = dscc4_tx_timeout;
 		d->watchdog_timeo = TX_TIMEOUT;
 
+		SET_MODULE_OWNER(d);
+
 		dpriv->dev_id = i;
 		dpriv->pci_priv = ppriv;
 		spin_lock_init(&dpriv->lock);
@@ -874,31 +902,40 @@
 		hdlc->xmit = dscc4_start_xmit;
 		hdlc->attach = dscc4_hdlc_attach;
 
-	        if (register_hdlc_device(hdlc)) {
+		ret = register_hdlc_device(hdlc);
+		if (ret < 0) {
 			printk(KERN_ERR "%s: unable to register\n", DRV_NAME);
 			goto err_unregister;
 	        }
-		hdlc->proto = IF_PROTO_HDLC;
-		SET_MODULE_OWNER(d);
+
 		dscc4_init_registers(dpriv, d);
 		dpriv->parity = PARITY_CRC16_PR0_CCITT;
 		dpriv->encoding = ENCODING_NRZ;
+
+		ret = dscc4_init_ring(d);
+		if (ret < 0) {
+			unregister_hdlc_device(hdlc);
+			goto err_unregister;
+		}
 	}
-	if (dscc4_set_quartz(root, quartz) < 0)
+	ret = dscc4_set_quartz(root, quartz);
+	if (ret < 0)
 		goto err_unregister;
 	ppriv->root = root;
 	spin_lock_init(&ppriv->lock);
 	pci_set_drvdata(pdev, ppriv);
-	return 0;
+	return ret;
 
 err_unregister:
-	while (--i >= 0)
+	while (--i >= 0) {
+		dscc4_release_ring(root + i);
 		unregister_hdlc_device(&root[i].hdlc);
+	}
 	kfree(ppriv);
 err_free_dev:
 	kfree(root);
 err_out:
-	return -1;
+	return ret;
 };
 
 /* FIXME: get rid of the unneeded code */
@@ -932,6 +969,46 @@
 	return 0;
 }
 
+#ifdef CONFIG_DSCC4_PCI_RST
+/*
+ * Some DSCC4-based cards wires the GPIO port and the PCI #RST pin together
+ * so as to provide a safe way to reset the asic while not the whole machine
+ * rebooting.
+ *
+ * This code doesn't need to be efficient. Keep It Simple
+ */
+static void dscc4_pci_reset(struct pci_dev *pdev, u32 ioaddr)
+{
+	int i;
+
+	down(&dscc4_sem);
+	for (i = 0; i < 16; i++)
+		pci_read_config_dword(pdev, i << 2, dscc4_pci_config_store + i);
+
+	/* Maximal LBI clock divider (who cares ?) and whole GPIO range. */
+	writel(0x001c0000, ioaddr + GMODE);
+	/* Configure GPIO port as output */
+	writel(0x0000ffff, ioaddr + GPDIR);
+	/* Disable interruption */
+	writel(0x0000ffff, ioaddr + GPIM);
+
+	writel(0x0000ffff, ioaddr + GPDATA);
+	writel(0x00000000, ioaddr + GPDATA);
+
+	/* Flush posted writes */
+	readl(ioaddr + GSTAR);
+
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	schedule_timeout(10);
+
+	for (i = 0; i < 16; i++)
+		pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
+	up(&dscc4_sem);
+}
+#else
+#define dscc4_pci_reset(pdev,ioaddr)	do {} while (0)
+#endif /* CONFIG_DSCC4_PCI_RST */
+
 static int dscc4_open(struct net_device *dev)
 {
 	struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
@@ -949,12 +1026,29 @@
 
 	ppriv = dpriv->pci_priv;
 
-	if ((ret = dscc4_init_ring(dev)))
-		goto err_out;
+	/*
+	 * Due to various bugs, there is no way to reliably reset a
+	 * specific port (manufacturer's dependant special PCI #RST wiring
+	 * apart: it affects all ports). Thus the device goes in the best
+	 * silent mode possible at dscc4_close() time and simply claims to
+	 * be up if it's opened again. It still isn't possible to change
+	 * the HDLC configuration without rebooting but at least the ports
+	 * can be up/down ifconfig'ed without killing the host.
+	 */
+	if (dpriv->flags & FakeReset) {
+		dpriv->flags &= ~FakeReset;
+		scc_patchl(0, PowerUp, dpriv, dev, CCR0);
+		scc_patchl(0, 0x00050000, dpriv, dev, CCR2);
+		scc_writel(EventsMask, dpriv, dev, IMR);
+		printk(KERN_INFO "%s: up again.\n", dev->name);
+		goto done;
+	}
 
 	/* IDT+IDR during XPR */
 	dpriv->flags = NeedIDR | NeedIDT;
 
+	scc_patchl(0, PowerUp | Vis, dpriv, dev, CCR0);
+
 	/*
 	 * The following is a bit paranoid...
 	 *
@@ -965,15 +1059,17 @@
 	if (scc_readl_star(dpriv, dev) & SccBusy) {
 		printk(KERN_ERR "%s busy. Try later\n", dev->name);
 		ret = -EAGAIN;
-		goto err_free_ring;
+		goto err_out;
 	} else
 		printk(KERN_INFO "%s: available. Good\n", dev->name);
 
+	scc_writel(EventsMask, dpriv, dev, IMR);
+
 	/* Posted write is flushed in the wait_ack loop */
 	scc_writel(TxSccRes | RxSccRes, dpriv, dev, CMDR);
 
 	if ((ret = dscc4_wait_ack_cec(dpriv, dev, "Cec")) < 0)
-		goto err_free_ring;
+		goto err_disable_scc_events;
 
 	/*
 	 * I would expect XPR near CE completion (before ? after ?).
@@ -984,12 +1080,13 @@
 	 */
 	if ((ret = dscc4_xpr_ack(dpriv)) < 0) {
 		printk(KERN_ERR "%s: %s timeout\n", DRV_NAME, "XPR");
-		goto err_free_ring;
+		goto err_disable_scc_events;
 	}
 	
 	if (debug > 2)
 		dscc4_tx_print(dev, dpriv, "Open");
 
+done:
 	netif_start_queue(dev);
 
         init_timer(&dpriv->timer);
@@ -1001,8 +1098,9 @@
 
 	return 0;
 
-err_free_ring:
-	dscc4_release_ring(dpriv);
+err_disable_scc_events:
+	scc_writel(0xffffffff, dpriv, dev, IMR);
+	scc_patchl(PowerUp | Vis, 0, dpriv, dev, CCR0);
 err_out:
 	hdlc_close(hdlc);
 	MOD_DEC_USE_COUNT;
@@ -1027,7 +1125,7 @@
 	next = dpriv->tx_current%TX_RING_SIZE;
 	dpriv->tx_skbuff[next] = skb;
 	tx_fd = dpriv->tx_fd + next;
-	tx_fd->state = FrameEnd | TO_STATE(skb->len);
+	tx_fd->state = FrameEnd | TO_STATE_TX(skb->len);
 	tx_fd->data = pci_map_single(ppriv->pdev, skb->data, skb->len,
 				     PCI_DMA_TODEVICE);
 	tx_fd->complete = 0x00000000;
@@ -1058,19 +1156,17 @@
 {
 	struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
 	hdlc_device *hdlc = dev_to_hdlc(dev);
-	unsigned long flags;
 
 	del_timer_sync(&dpriv->timer);
 	netif_stop_queue(dev);
 
-	spin_lock_irqsave(&dpriv->pci_priv->lock, flags);
-	dscc4_rx_reset(dpriv, dev);
-	spin_unlock_irqrestore(&dpriv->pci_priv->lock, flags);
+	scc_patchl(PowerUp | Vis, 0, dpriv, dev, CCR0);
+	scc_patchl(0x00050000, 0, dpriv, dev, CCR2);
+	scc_writel(0xffffffff, dpriv, dev, IMR);
 
-	dscc4_tx_reset(dpriv, dev);
+	dpriv->flags |= FakeReset;
 
 	hdlc_close(hdlc);
-	dscc4_release_ring(dpriv);
 
 	MOD_DEC_USE_COUNT;
 	return 0;
@@ -1080,13 +1176,56 @@
 {
 	int ret = 0;
 
-#ifdef CONFIG_DSCC4_CLOCK_ON_TWO_PORTS_ONLY
+#ifdef CONFIG_DSCC4_PCISYNC
 	if (port >= 2)
 		ret = -1;
 #endif
 	return ret;
 }
 
+/*
+ * DS1 p.137: "There are a total of 13 different clocking modes..."
+ *                                  ^^
+ * Design choices:
+ * - by default, assume a clock is provided on pin RxClk/TxClk (clock mode 0a).
+ *   Clock mode 3b _should_ work but the testing seems to make this point
+ *   dubious (DIY testing requires setting CCR0 at 0x00000033).
+ *   This is supposed to provide least surprise "DTE like" behavior.
+ * - if line rate is specified, clocks are assumed to be locally generated.
+ *   A quartz must be available (on pin XTAL1). Modes 6b/7b are used. Choosing
+ *   between these it automagically done according on the required frequency
+ *   scaling. Of course some rounding may take place.
+ * - no high speed mode (40Mb/s). May be trivial to do but I don't have an
+ *   appropriate external clocking device for testing.
+ * - no time-slot/clock mode 5: shameless lazyness.
+ *
+ * The clock signals wiring can be (is ?) manufacturer dependant. Good luck.
+ *
+ * BIG FAT WARNING: if the device isn't provided enough clocking signal, it
+ * won't pass the init sequence. For example, straight back-to-back DTE without
+ * external clock will fail when dscc4_open() (<- 'ifconfig hdlcx xxx') is
+ * called.
+ *
+ * Typos lurk in datasheet (missing divier in clock mode 7a figure 51 p.153
+ * DS0 for example)
+ * 
+ * Clock mode related bits of CCR0:
+ *     +------------ TOE: output TxClk (0b/2b/3a/3b/6b/7a/7b only)
+ *     | +---------- SSEL: sub-mode select 0 -> a, 1 -> b
+ *     | | +-------- High Speed: say 0
+ *     | | | +-+-+-- Clock Mode: 0..7
+ *     | | | | | |
+ * -+-+-+-+-+-+-+-+
+ * x|x|5|4|3|2|1|0| lower bits
+ *
+ * Division factor of BRR: k = (N+1)x2^M (total divider = 16xk in mode 6b)
+ *            +-+-+-+------------------ M (0..15)
+ *            | | | |     +-+-+-+-+-+-- N (0..63)
+ *    0 0 0 0 | | | | 0 0 | | | | | |
+ * ...-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ *    f|e|d|c|b|a|9|8|7|6|5|4|3|2|1|0| lower bits
+ *
+ */
 static int dscc4_set_clock(struct net_device *dev, u32 *bps, u32 *state)
 {
 	struct dscc4_dev_priv *dpriv = dscc4_priv(dev);
@@ -1123,13 +1262,13 @@
 		}
 		brr = (m << 8) | n;
 		divider = n << m;
-		if (!(*state & 0x00000001)) /* Clock mode 6b */
+		if (!(*state & 0x00000001)) /* ?b mode mask => clock mode 6b */
 			divider <<= 4;
 		*bps = xtal / divider;
 	} else {
 		/*
 		 * External clock - DTE
-		 * "state" already reflects Clock mode 0a.
+		 * "state" already reflects Clock mode 0a (CCR0 = 0xzzzzzz00).
 		 * Nothing more to be done
 		 */
 		brr = 0;
@@ -1168,6 +1307,11 @@
 		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
+		if (dpriv->flags & FakeReset) {
+			printk(KERN_INFO "%s: please reset the device"
+			       " before this command\n", dev->name);
+			return -EPERM;
+		}
 		if (copy_from_user(&dpriv->settings, line, size))
 			return -EFAULT;
 		ret = dscc4_set_iface(dpriv, dev);
@@ -1221,12 +1365,12 @@
 	if (bps) { /* DCE */
 		printk(KERN_DEBUG "%s: generated RxClk (DCE)\n", dev->name);
 		if (settings->clock_rate != bps) {
-			settings->clock_rate = bps;
 			printk(KERN_DEBUG "%s: clock adjusted (%08d -> %08d)\n",
-				dev->name, dpriv->settings.clock_rate, bps);
+				dev->name, settings->clock_rate, bps);
+			settings->clock_rate = bps;
 		}
 	} else { /* DTE */
-		state = 0x80001000;
+		state |= PowerUp | Vis;
 		printk(KERN_DEBUG "%s: external RxClk (DTE)\n", dev->name);
 	}
 	scc_writel(state, dpriv, dev, CCR0);
@@ -1332,6 +1476,8 @@
 	state = readl(ioaddr + GSTAR);
 	if (!state)
 		goto out;
+	if (debug > 3)
+		printk(KERN_DEBUG "%s: GSTAR = 0x%08x\n", DRV_NAME, state);
 	writel(state, ioaddr + GSTAR);
 
 	if (state & Arf) {
@@ -1377,6 +1523,9 @@
 	cur = dpriv->iqtx_current%IRQ_RING_SIZE;
 	state = dpriv->iqtx[cur];
 	if (!state) {
+		if (debug > 4)
+			printk(KERN_DEBUG "%s: Tx ISR = 0x%08x\n", dev->name,
+			       state);
 		if ((debug > 1) && (loop > 1))
 			printk(KERN_DEBUG "%s: Tx irq loop=%d\n", dev->name, loop);
 		if (loop && netif_queue_stopped(dev))
@@ -1431,7 +1580,7 @@
 			 * random freeze induced by null sized tx frames.
 			 */
 			tx_fd->data = tx_fd->next;
-			tx_fd->state = FrameEnd | TO_STATE(2*DUMMY_SKB_SIZE);
+			tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE);
 			tx_fd->complete = 0x00000000;
 			tx_fd->jiffies = 0;
 
@@ -1463,9 +1612,19 @@
 		}
 		if (state & Xpr) {
 			u32 scc_addr, ring;
+			int i;
+
+			/*
+			 * - the busy condition happens (sometimes);
+			 * - it doesn't seem to make the handler unreliable.
+			 */
+			for (i = 1; i; i <<= 1) {
+				if (!(scc_readl_star(dpriv, dev) & SccBusy))
+					break;
+			}
+			if (!i)
+				printk(KERN_INFO "%s busy in irq\n", dev->name);
 
-			if (scc_readl_star(dpriv, dev) & SccBusy)
-				printk(KERN_ERR "%s busy. Fatal\n", dev->name);
 			scc_addr = dev->base_addr + 0x0c*dpriv->dev_id;
 			/* Keep this order: IDT before IDR */
 			if (dpriv->flags & NeedIDT) {
@@ -1500,7 +1659,8 @@
 				goto try;
 		}
 		if (state & Cd) {
-			printk(KERN_INFO "%s: CD transition\n", dev->name);
+			if (debug > 0)
+				printk(KERN_INFO "%s: CD transition\n", dev->name);
 			if (!(state &= ~Cd)) /* DEBUG */
 				goto try;
 		}
@@ -1542,6 +1702,9 @@
 	if (!(state & SccEvt)){
 		struct RxFD *rx_fd;
 
+		if (debug > 4)
+			printk(KERN_DEBUG "%s: Rx ISR = 0x%08x\n", dev->name,
+			       state);
 		state &= 0x00ffffff;
 		if (state & Err) { /* Hold or reset */
 			printk(KERN_DEBUG "%s: Rx ERR\n", dev->name);
@@ -1718,7 +1881,7 @@
 
 		skb->len = DUMMY_SKB_SIZE;
 		memcpy(skb->data, version, strlen(version)%DUMMY_SKB_SIZE);
-		tx_fd->state = FrameEnd | TO_STATE(DUMMY_SKB_SIZE);
+		tx_fd->state = FrameEnd | TO_STATE_TX(DUMMY_SKB_SIZE);
 		tx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
 					     DUMMY_SKB_SIZE, PCI_DMA_TODEVICE);
 		dpriv->tx_skbuff[last] = skb;
@@ -1749,7 +1912,7 @@
 	dpriv->tx_dirty = 0xffffffff;
 	i = dpriv->tx_current = 0;
 	do {
-		tx_fd->state = FrameEnd | TO_STATE(2*DUMMY_SKB_SIZE);
+		tx_fd->state = FrameEnd | TO_STATE_TX(2*DUMMY_SKB_SIZE);
 		tx_fd->complete = 0x00000000;
 	        /* FIXME: NULL should be ok - to be tried */
 	        tx_fd->data = dpriv->tx_fd_dma;
@@ -1757,7 +1920,7 @@
 					(++i%TX_RING_SIZE)*sizeof(*tx_fd));
 	} while (i < TX_RING_SIZE);
 
-	if (dscc4_init_dummy_skb(dpriv) < 0)
+	if (dscc4_init_dummy_skb(dpriv) == NULL)
 		goto err_free_dma_tx;
 
 	memset(dpriv->rx_skbuff, 0, sizeof(struct sk_buff *)*RX_RING_SIZE);
@@ -1767,7 +1930,7 @@
 	        rx_fd->state1 = HiDesc;
 	        rx_fd->state2 = 0x00000000;
 	        rx_fd->end = 0xbabeface;
-	        rx_fd->state1 |= TO_STATE(RX_MAX(HDLC_MAX_MRU));
+	        rx_fd->state1 |= TO_STATE_RX(HDLC_MAX_MRU);
 		// FIXME: return value verifiee mais traitement suspect
 		if (try_get_rx_skb(dpriv, dev) >= 0)
 			dpriv->rx_dirty++;
@@ -1785,7 +1948,7 @@
 	return -ENOMEM;
 }
 
-static void __exit dscc4_remove_one(struct pci_dev *pdev)
+static void __devexit dscc4_remove_one(struct pci_dev *pdev)
 {
 	struct dscc4_pci_priv *ppriv;
 	struct dscc4_dev_priv *root;
@@ -1796,12 +1959,16 @@
 	root = ppriv->root;
 
 	ioaddr = hdlc_to_dev(&root->hdlc)->base_addr;
+
+	dscc4_pci_reset(pdev, ioaddr);
+
 	free_irq(pdev->irq, root);
 	pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32), ppriv->iqcfg,
 			    ppriv->iqcfg_dma);
 	for (i = 0; i < dev_per_card; i++) {
 		struct dscc4_dev_priv *dpriv = root + i;
 
+		dscc4_release_ring(dpriv);
 		pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
 				    dpriv->iqrx, dpriv->iqrx_dma);
 		pci_free_consistent(pdev, IRQ_RING_SIZE*sizeof(u32),
@@ -1843,6 +2010,7 @@
 	return 0;
 }
 
+#ifndef MODULE
 static int __init dscc4_setup(char *str)
 {
 	int *args[] = { &debug, &quartz, NULL }, **p = args;
@@ -1853,8 +2021,9 @@
 }
 
 __setup("dscc4.setup=", dscc4_setup);
+#endif /* MODULE */
 
-static struct pci_device_id dscc4_pci_tbl[] __devinitdata = {
+static struct pci_device_id dscc4_pci_tbl[] = {
 	{ PCI_VENDOR_ID_SIEMENS, PCI_DEVICE_ID_SIEMENS_DSCC4,
 	        PCI_ANY_ID, PCI_ANY_ID, },
 	{ 0,}
@@ -1865,7 +2034,7 @@
 	.name		= DRV_NAME,
 	.id_table	= dscc4_pci_tbl,
 	.probe		= dscc4_init_one,
-	.remove		= dscc4_remove_one,
+	.remove		= __devexit_p(dscc4_remove_one),
 };
 
 static int __init dscc4_init_module(void)
diff -urN linux-2.4.23-pre6/drivers/pci/pci.c linux-2.4.23-pre7/drivers/pci/pci.c
--- linux-2.4.23-pre6/drivers/pci/pci.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/pci/pci.c	2003-10-09 17:48:21.000000000 -0700
@@ -921,7 +921,7 @@
  *
  * RETURNS: An appriopriate -ERRNO error value on eror, or zero for success.
  */
-int
+static int
 pci_generic_prep_mwi(struct pci_dev *dev)
 {
 	u8 cacheline_size;
@@ -2164,7 +2164,6 @@
 EXPORT_SYMBOL(pci_set_master);
 EXPORT_SYMBOL(pci_set_mwi);
 EXPORT_SYMBOL(pci_clear_mwi);
-EXPORT_SYMBOL(pci_generic_prep_mwi);
 EXPORT_SYMBOL(pci_set_dma_mask);
 EXPORT_SYMBOL(pci_dac_set_dma_mask);
 EXPORT_SYMBOL(pci_assign_resource);
diff -urN linux-2.4.23-pre6/drivers/pcmcia/i82092.c linux-2.4.23-pre7/drivers/pcmcia/i82092.c
--- linux-2.4.23-pre6/drivers/pcmcia/i82092.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/pcmcia/i82092.c	2003-10-09 17:48:21.000000000 -0700
@@ -26,7 +26,6 @@
 
 #include "i82092aa.h"
 #include "i82365.h"
-#include "cirrus.h"
 
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Red Hat, Inc. - Arjan Van De Ven <arjanv@redhat.com>");
@@ -44,15 +43,8 @@
 	      subdevice:PCI_ANY_ID,
 	      class: 0, class_mask:0,
 
-	},
-	{
-	      vendor:PCI_VENDOR_ID_CIRRUS,
-	      device:PCI_DEVICE_ID_CIRRUS_6729,
-	      subvendor:PCI_ANY_ID,
-	      subdevice:PCI_ANY_ID,
-	      class: 0, class_mask:0,
-	},
-	{} 
+	 },
+	 {} 
 };
 
 static struct pci_driver i82092aa_pci_drv = {
@@ -98,18 +90,14 @@
 	void	*info;		/* to be passed to the handler */
 	
 	struct pci_dev *dev;	/* The PCI device for the socket */
-	
-	int type;		/* Type of socket */
-#define IS_I82092	0x0001
-#define IS_PD6729	0x0002
 };
 
 #define MAX_SOCKETS 4
 static struct socket_info sockets[MAX_SOCKETS];
 static int socket_count;  /* shortcut */
 
-static int membase = -1;
-static int isa_setup;
+int membase = -1;
+int isa_setup;
 
 MODULE_PARM(membase, "i");
 MODULE_PARM(isa_setup, "i");
@@ -119,7 +107,6 @@
 	unsigned char configbyte;
 	struct pci_dev *parent;
 	int i;
-	int type;
 	
 	enter("i82092aa_pci_probe");
 	
@@ -129,18 +116,7 @@
 	/* Since we have no memory BARs some firmware we may not
 	   have had PCI_COMMAND_MEM enabled, yet the device needs
 	   it. */
-
-	// pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
-	if (dev->vendor == PCI_VENDOR_ID_CIRRUS) {
-		type = IS_PD6729;
-		configbyte = 0;	/* always 2 sockets */
-		printk(KERN_INFO "Cirrus PD6729 PCI to PCMCIA Bridge \n");
-	} else {
-		type = IS_I82092;
-		pci_read_config_byte(dev, 0x40, &configbyte);  /* PCI Configuration Control */
-		printk(KERN_INFO "Intel I82092AA PCI to PCMCIA Bridge \n");
-	}
-
+	pci_read_config_byte(dev, PCI_COMMAND, &configbyte);
 	if (!(configbyte | PCI_COMMAND_MEMORY)) {
 		dprintk(KERN_DEBUG "Enabling PCI_COMMAND_MEMORY\n");
 		configbyte |= PCI_COMMAND_MEMORY;
@@ -227,7 +203,6 @@
 		sockets[i].cap.map_size = 0x1000;
 		sockets[i].cap.irq_mask = 0;
 		sockets[i].cap.pci_irq  = dev->irq;
-		sockets[i].type = type;
 
 		/* Trick the resource code into doing the right thing... */
 		sockets[i].cap.cb_dev = dev;
@@ -240,11 +215,10 @@
 		}
 	}
 		
-	if (type == IS_I82092) {
-		/* Now, specifiy that all interrupts are to be done as PCI interrupts */
-		configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */
-		pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
-	}
+	/* Now, specifiy that all interrupts are to be done as PCI interrupts */
+	configbyte = 0xFF; /* bitmask, one bit per event, 1 = PCI interrupt, 0 = ISA interrupt */
+	pci_write_config_byte(dev, 0x50, configbyte); /* PCI Interrupt Routing Register */
+
 
 	/* Register the interrupt handler */
 	dprintk(KERN_DEBUG "Requesting interrupt %i \n",dev->irq);
@@ -266,7 +240,6 @@
 	enter("i82092aa_pci_remove");
 	
 	free_irq(dev->irq, i82092aa_interrupt);
-	flush_scheduled_tasks();
 
 	leave("i82092aa_pci_remove");
 }
@@ -681,7 +654,6 @@
 static int i82092aa_set_socket(unsigned int sock, socket_state_t *state) 
 {
 	unsigned char reg;
-	unsigned long flags;
 	
 	enter("i82092aa_set_socket");
 	
@@ -768,26 +740,9 @@
 	
 	/* now write the value and clear the (probably bogus) pending stuff by doing a dummy read*/
 	
-	spin_lock_irqsave(&port_lock,flags);
-
 	indirect_write(sock,I365_CSCINT,reg);
 	(void)indirect_read(sock,I365_CSC);
 
-	if (sockets[sock].type == IS_PD6729) {
-		/* Configure PD6729 bridge for PCI interrupts */
-		reg |= 0x30;	/* management IRQ: PCI INTA = "irq 3" */
-		indirect_write(sock,I365_CSCINT,reg);
-		(void)indirect_read(sock,I365_CSC);
-
-		reg = indirect_read(sock,I365_INTCTL);
-		reg |= 0x03; /* card IRQ: PCI INTA = "irq 3" */
-		indirect_write(sock,I365_INTCTL,reg);
-
-		indirect_write(sock, PD67_EXT_INDEX, PD67_EXT_CTL_1);
-		indirect_write(sock, PD67_EXT_DATA, PD67_EC1_INV_MGMT_IRQ | PD67_EC1_INV_CARD_IRQ);
-	}
-	spin_unlock_irqrestore(&port_lock,flags);
-
 	leave("i82092aa_set_socket");
 	return 0;
 }
@@ -813,10 +768,9 @@
 	io->speed = to_ns(ioctl & I365_IOCTL_WAIT(map)) ? 1 : 0; /* check this out later */
 	io->flags = 0;
 	
-	io->flags |= (ioctl & I365_IOCTL_0WS(map)) ? MAP_0WS : 0;
-	io->flags |= (ioctl & I365_IOCTL_16BIT(map)) ? MAP_16BIT : 0;
-	io->flags |= (ioctl & I365_IOCTL_IOCS16(map)) ? MAP_AUTOSZ : 0;
-
+	if (addr & I365_IOCTL_16BIT(map))
+		io->flags |= MAP_AUTOSZ;
+		
 	leave("i82092aa_get_io_map");
 	return 0;
 }
@@ -834,7 +788,7 @@
 		leave("i82092aa_set_io_map with invalid map");
 		return -EINVAL;
 	}
-	if (io->start > 0xffff || io->stop > 0xffff || io->stop < io->start){
+	if ((io->start > 0xffff) || (io->stop > 0xffff) || (io->stop < io->start)){
 		leave("i82092aa_set_io_map with invalid io");
 		return -EINVAL;
 	}
@@ -851,10 +805,9 @@
 	            	
 	ioctl = indirect_read(sock,I365_IOCTL) & ~I365_IOCTL_MASK(map);
 	
-    	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
-    	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
-    	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
-
+	if (io->flags & (MAP_16BIT|MAP_AUTOSZ))
+		ioctl |= I365_IOCTL_16BIT(map);
+		
 	indirect_write(sock,I365_IOCTL,ioctl);
 	
 	/* Turn the window back on if needed */
@@ -913,19 +866,11 @@
 		mem->flags |= MAP_WRPROT;
 	if (i & I365_MEM_REG)
 		mem->flags |= MAP_ATTRIB;
+	mem->card_start = ( (unsigned long)(i & 0x3fff)<12) + mem->sys_start;
+	mem->card_start &=  0x3ffffff;
 	
-	if (sockets[sock].type == IS_PD6729) {
-		/* Take care of high byte */
-		indirect_write(sock,PD67_EXT_INDEX, PD67_MEM_PAGE(map));
-		addr = indirect_read16(sock, PD67_EXT_DATA) << 24;
-		mem->sys_stop += addr; mem->sys_start += addr;
-		mem->card_start = (unsigned long)(i) + mem->sys_start;
-	} else {
-		mem->card_start = ((unsigned long)(i & 0x3fff)<12) + mem->sys_start;
-		mem->card_start &=  0x3ffffff;
-	}
-
 	dprintk("Card %i is from %lx to %lx \n",sock,mem->sys_start,mem->sys_stop);
+	
 	leave("i82092aa_get_mem_map");
 	return 0;
 	
@@ -952,9 +897,7 @@
 	if (!(mem->flags & MAP_ACTIVE))
 		return 0;
 
-	if (sockets[sock].type == IS_PD6729)  {
-		;	/* PD6729 accepts high byte */	
-	} else if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) ||
+	if ( (mem->card_start > 0x3ffffff) || (mem->sys_start > mem->sys_stop) ||
 	     ((mem->sys_start >> 24) != membase) || ((mem->sys_stop >> 24) != membase) ||
 	     (mem->speed > 1000) ) {
 		leave("i82092aa_set_mem_map: invalid address / speed");
@@ -963,6 +906,7 @@
 	}
 	
 	                 
+	                 
 /* 	printk("set_mem_map: Setting map %i range to %x - %x on socket %i, speed is %i, active = %i \n",map, mem->sys_start,mem->sys_stop,sock,mem->speed,mem->flags & MAP_ACTIVE);  */
 
 	/* write the start address */
@@ -993,12 +937,6 @@
 	
 	indirect_write16(sock,base+I365_W_STOP,i);
 	
-	if (sockets[sock].type == IS_PD6729)  {
-		/* Take care of high byte */
-		indirect_write(sock, PD67_EXT_INDEX, PD67_MEM_PAGE(map));
-		indirect_write16(sock, PD67_EXT_DATA, mem->sys_start >> 24);
-	}
-
 	/* card start */
 	
 	i = (((mem->card_start - mem->sys_start) >> 12) - (membase << 12)) & 0x3fff;
@@ -1011,9 +949,7 @@
 /*		printk("requesting normal memory for socket %i\n",sock);*/
 	}
 	indirect_write16(sock,base+I365_W_OFF,i);
-	if (sockets[sock].type == IS_I82092) {
-		indirect_write(sock, I365_CPAGE, membase);
-	}
+	indirect_write(sock, I365_CPAGE, membase);
 
 	/* Enable the window if necessary */
 	indirect_setbit(sock, I365_ADDRWIN, I365_ENA_MEM(map));
diff -urN linux-2.4.23-pre6/drivers/pcmcia/i82365.c linux-2.4.23-pre7/drivers/pcmcia/i82365.c
--- linux-2.4.23-pre6/drivers/pcmcia/i82365.c	2002-11-28 15:53:14.000000000 -0800
+++ linux-2.4.23-pre7/drivers/pcmcia/i82365.c	2003-10-09 17:48:21.000000000 -0700
@@ -42,7 +42,6 @@
 #include <linux/timer.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
-#include <linux/pci.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
 #include <linux/proc_fs.h>
@@ -89,7 +88,6 @@
 
 /* Parameters that can be set with 'insmod' */
 
-#ifdef CONFIG_ISA
 /* Default base address for i82365sl and other ISA chips */
 static int i365_base = 0x3e0;
 /* Should we probe at 0x3e2 for an extra ISA controller? */
@@ -101,7 +99,6 @@
 static int irq_list[16] = { -1 };
 /* The card status change interrupt -- 0 means autoselect */
 static int cs_irq = 0;
-#endif
 
 /* Probe for safe interrupts? */
 static int do_scan = 1;
@@ -120,14 +117,11 @@
 static int cmd_time = -1;
 static int recov_time = -1;
 
-#ifdef CONFIG_ISA
 /* Vadem options */
 static int async_clock = -1;
 static int cable_mode = -1;
 static int wakeup = 0;
-#endif
 
-#ifdef CONFIG_ISA
 MODULE_PARM(i365_base, "i");
 MODULE_PARM(ignore, "i");
 MODULE_PARM(extra_sockets, "i");
@@ -137,7 +131,6 @@
 MODULE_PARM(async_clock, "i");
 MODULE_PARM(cable_mode, "i");
 MODULE_PARM(wakeup, "i");
-#endif
 
 MODULE_PARM(do_scan, "i");
 MODULE_PARM(poll_interval, "i");
@@ -188,45 +181,29 @@
 /* Default ISA interrupt mask */
 #define I365_MASK	0xdeb8	/* irq 15,14,12,11,10,9,7,5,4,3 */
 
-#ifdef CONFIG_ISA
 static int grab_irq;
 static spinlock_t isa_lock = SPIN_LOCK_UNLOCKED;
 #define ISA_LOCK(n, f) spin_lock_irqsave(&isa_lock, f)
 #define ISA_UNLOCK(n, f) spin_unlock_irqrestore(&isa_lock, f)
-#else
-#define ISA_LOCK(n, f) do { } while (0)
-#define ISA_UNLOCK(n, f) do { } while (0)
-#endif
 
 static struct timer_list poll_timer;
 
 /*====================================================================*/
 
-/* Default settings for PCI command configuration register */
-#define CMD_DFLT (PCI_COMMAND_IO|PCI_COMMAND_MEMORY| \
-		  PCI_COMMAND_MASTER|PCI_COMMAND_WAIT)
-
 /* These definitions must match the pcic table! */
-#ifdef CONFIG_ISA
 typedef enum pcic_id {
     IS_I82365A, IS_I82365B, IS_I82365DF,
     IS_IBM, IS_RF5Cx96, IS_VLSI, IS_VG468, IS_VG469,
     IS_PD6710, IS_PD672X, IS_VT83C469,
 } pcic_id;
-#endif
 
 /* Flags for classifying groups of controllers */
 #define IS_VADEM	0x0001
 #define IS_CIRRUS	0x0002
-#define IS_TI		0x0004
-#define IS_O2MICRO	0x0008
 #define IS_VIA		0x0010
-#define IS_TOPIC	0x0020
-#define IS_RICOH	0x0040
 #define IS_UNKNOWN	0x0400
 #define IS_VG_PWR	0x0800
 #define IS_DF_PWR	0x1000
-#define IS_PCI		0x2000
 #define IS_ALIVE	0x8000
 
 typedef struct pcic_t {
@@ -235,7 +212,6 @@
 } pcic_t;
 
 static pcic_t pcic[] = {
-#ifdef CONFIG_ISA
     { "Intel i82365sl A step", 0 },
     { "Intel i82365sl B step", 0 },
     { "Intel i82365sl DF", IS_DF_PWR },
@@ -247,7 +223,6 @@
     { "Cirrus PD6710", IS_CIRRUS },
     { "Cirrus PD672x", IS_CIRRUS },
     { "VIA VT83C469", IS_CIRRUS|IS_VIA },
-#endif
 };
 
 #define PCIC_COUNT	(sizeof(pcic)/sizeof(pcic_t))
@@ -369,26 +344,24 @@
     if (has_ring == -1) has_ring = 1;
     flip(p->misc2, PD67_MC2_IRQ15_RI, has_ring);
     flip(p->misc2, PD67_MC2_DYNAMIC_MODE, dynamic_mode);
+    flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
     if (p->misc2 & PD67_MC2_IRQ15_RI)
 	strcat(buf, " [ring]");
     if (p->misc2 & PD67_MC2_DYNAMIC_MODE)
 	strcat(buf, " [dyn mode]");
+    if (p->misc2 & PD67_MC2_FREQ_BYPASS)
+	strcat(buf, " [freq bypass]");
     if (p->misc1 & PD67_MC1_INPACK_ENA)
 	strcat(buf, " [inpack]");
-    if (!(t->flags & IS_PCI)) {
-	if (p->misc2 & PD67_MC2_IRQ15_RI)
-	    mask &= ~0x8000;
-	if (has_led > 0) {
-	    strcat(buf, " [led]");
-	    mask &= ~0x1000;
-	}
-	if (has_dma > 0) {
-	    strcat(buf, " [dma]");
-	    mask &= ~0x0600;
-	flip(p->misc2, PD67_MC2_FREQ_BYPASS, freq_bypass);
-	if (p->misc2 & PD67_MC2_FREQ_BYPASS)
-	    strcat(buf, " [freq bypass]");
-	}
+    if (p->misc2 & PD67_MC2_IRQ15_RI)
+	mask &= ~0x8000;
+    if (has_led > 0) {
+	strcat(buf, " [led]");
+	mask &= ~0x1000;
+    }
+    if (has_dma > 0) {
+	strcat(buf, " [dma]");
+	mask &= ~0x0600;
     }
     if (!(t->flags & IS_VIA)) {
 	if (setup_time >= 0)
@@ -419,8 +392,6 @@
     
 ======================================================================*/
 
-#ifdef CONFIG_ISA
-
 static void vg46x_get_state(u_short s)
 {
     vg46x_state_t *p = &socket[s].state.vg46x;
@@ -462,9 +433,6 @@
     return 0xffff;
 }
 
-#endif
-
-
 /*======================================================================
 
     Generic routines to get and set controller options
@@ -476,10 +444,8 @@
     socket_info_t *t = &socket[s];
     if (t->flags & IS_CIRRUS)
 	cirrus_get_state(s);
-#ifdef CONFIG_ISA
     else if (t->flags & IS_VADEM)
 	vg46x_get_state(s);
-#endif
 }
 
 static void set_bridge_state(u_short s)
@@ -492,10 +458,8 @@
 	i365_set(s, I365_GENCTL, 0x00);
     }
     i365_bflip(s, I365_INTCTL, I365_INTR_ENA, t->intr);
-#ifdef CONFIG_ISA
     if (t->flags & IS_VADEM)
 	vg46x_set_state(s);
-#endif
 }
 
 static u_int __init set_bridge_opts(u_short s, u_short ns)
@@ -513,10 +477,8 @@
 	get_bridge_state(i);
 	if (socket[i].flags & IS_CIRRUS)
 	    m = cirrus_set_opts(i, buf);
-#ifdef CONFIG_ISA
 	else if (socket[i].flags & IS_VADEM)
 	    m = vg46x_set_opts(i, buf);
-#endif
 	set_bridge_state(i);
 	printk(KERN_INFO "    host opts [%d]:%s\n", i,
 	       (*buf) ? buf : " none");
@@ -568,8 +530,6 @@
     return (irq_hits != 1);
 }
 
-#ifdef CONFIG_ISA
-
 static u_int __init isa_scan(u_short sock, u_int mask0)
 {
     u_int mask1 = 0;
@@ -614,8 +574,6 @@
     return mask1;
 }
 
-#endif /* CONFIG_ISA */
-
 /*====================================================================*/
 
 /* Time conversion functions */
@@ -632,8 +590,6 @@
 
 /*====================================================================*/
 
-#ifdef CONFIG_ISA
-
 static int __init identify(u_short port, u_short sock)
 {
     u_char val;
@@ -693,8 +649,6 @@
     return type;
 } /* identify */
 
-#endif
-
 /*======================================================================
 
     See if a card is present, powered up, in IO mode, and already
@@ -738,7 +692,7 @@
 static void __init add_pcic(int ns, int type)
 {
     u_int mask = 0, i, base;
-    int use_pci = 0, isa_irq = 0;
+    int isa_irq = 0;
     socket_info_t *t = &socket[sockets-ns];
 
     base = sockets-ns;
@@ -750,32 +704,25 @@
 	       t->ioaddr, t->psock*0x40);
     printk(", %d socket%s\n", ns, ((ns > 1) ? "s" : ""));
 
-#ifdef CONFIG_ISA
     /* Set host options, build basic interrupt mask */
     if (irq_list[0] == -1)
 	mask = irq_mask;
     else
 	for (i = mask = 0; i < 16; i++)
 	    mask |= (1<<irq_list[i]);
-#endif
     mask &= I365_MASK & set_bridge_opts(base, ns);
-#ifdef CONFIG_ISA
     /* Scan for ISA interrupts */
     mask = isa_scan(base, mask);
-#else
-    printk(KERN_INFO "    PCI card interrupts,");
-#endif
         
-#ifdef CONFIG_ISA
     /* Poll if only two interrupts available */
-    if (!use_pci && !poll_interval) {
+    if (!poll_interval) {
 	u_int tmp = (mask & 0xff20);
 	tmp = tmp & (tmp-1);
 	if ((tmp & (tmp-1)) == 0)
 	    poll_interval = HZ;
     }
     /* Only try an ISA cs_irq if this is the first controller */
-    if (!use_pci && !grab_irq && (cs_irq || !poll_interval)) {
+    if (!grab_irq && (cs_irq || !poll_interval)) {
 	/* Avoid irq 12 unless it is explicitly requested */
 	u_int cs_mask = mask & ((cs_irq) ? (1<<cs_irq) : ~(1<<12));
 	for (cs_irq = 15; cs_irq > 0; cs_irq--)
@@ -788,9 +735,8 @@
 	    printk(" status change on irq %d\n", cs_irq);
 	}
     }
-#endif
     
-    if (!use_pci && !isa_irq) {
+    if (!isa_irq) {
 	if (poll_interval == 0)
 	    poll_interval = HZ;
 	printk(" polling interval = %d ms\n",
@@ -808,11 +754,8 @@
 
 } /* add_pcic */
 
-
 /*====================================================================*/
 
-#ifdef CONFIG_ISA
-
 #if defined(CONFIG_ISAPNP) || (defined(CONFIG_ISAPNP_MODULE) && defined(MODULE))
 #define I82365_ISAPNP
 #endif
@@ -882,7 +825,9 @@
 	    }
 	}
     } else {
-	for (i = 0; i < (extra_sockets ? 8 : 4); i += 2) {
+	for (i = 0; i < 8; i += 2) {
+	    if (sockets && !extra_sockets && (i == 4))
+		break;
 	    port = i365_base + 2*(i>>2);
 	    sock = (i & 3);
 	    id = identify(port, sock);
@@ -906,8 +851,6 @@
     }
 }
 
-#endif
-
 /*====================================================================*/
 
 static u_int pending_events[8];
@@ -946,17 +889,14 @@
 {
     int i, j, csc;
     u_int events, active;
-#ifdef CONFIG_ISA
     u_long flags = 0;
-#endif
     
     DEBUG(4, "i82365: pcic_interrupt(%d)\n", irq);
 
     for (j = 0; j < 20; j++) {
 	active = 0;
 	for (i = 0; i < sockets; i++) {
-	    if ((socket[i].cs_irq != irq) &&
-		(socket[i].cap.pci_irq != irq))
+	    if (socket[i].cs_irq != irq)
 		continue;
 	    ISA_LOCK(i, flags);
 	    csc = i365_get(i, I365_CSC);
@@ -1055,7 +995,6 @@
     *value |= (status & I365_CS_READY) ? SS_READY : 0;
     *value |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
 
-#ifdef CONFIG_ISA
     if (socket[sock].type == IS_VG469) {
 	status = i365_get(sock, VG469_VSENSE);
 	if (socket[sock].psock & 1) {
@@ -1066,7 +1005,6 @@
 	    *value |= (status & VG469_VSENSE_A_VS2) ? 0 : SS_XVCARD;
 	}
     }
-#endif
     
     DEBUG(1, "i82365: GetStatus(%d) = %#4.4x\n", sock, *value);
     return 0;
@@ -1160,7 +1098,7 @@
     
     /* IO card, RESET flag, IO interrupt */
     reg = t->intr;
-    if (state->io_irq != t->cap.pci_irq) reg |= state->io_irq;
+    reg |= state->io_irq;
     reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
     reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
     i365_set(sock, I365_INTCTL, reg);
@@ -1357,8 +1295,7 @@
     if ((map > 4) || (mem->card_start > 0x3ffffff) ||
 	(mem->sys_start > mem->sys_stop) || (mem->speed > 1000))
 	return -EINVAL;
-    if (!(socket[sock].flags & IS_PCI) &&
-	((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff)))
+    if ((mem->sys_start > 0xffffff) || (mem->sys_stop > 0xffffff))
 	return -EINVAL;
 	
     /* Turn off the window before changing anything */
@@ -1417,9 +1354,7 @@
     char *p = buf;
     int i, top;
     
-#ifdef CONFIG_ISA
     u_long flags = 0;
-#endif
     ISA_LOCK(sock, flags);
     top = 0x40;
     for (i = 0; i < top; i += 4) {
@@ -1464,15 +1399,8 @@
 
 /*====================================================================*/
 
-/*
- * The locking is rather broken. Why do we only lock for ISA, not for
- * all other cases? If there are reasons to lock, we should lock. Not
- * this silly conditional.
- *
- * Plan: make it bug-for-bug compatible with the old stuff, and clean
- * it up when the infrastructure is done.
- */
-#ifdef CONFIG_ISA
+/* this is horribly ugly... proper locking needs to be done here at 
+ * some time... */
 #define LOCKED(x) do { \
 	int retval; \
 	unsigned long flags; \
@@ -1481,10 +1409,6 @@
 	spin_unlock_irqrestore(&isa_lock, flags); \
 	return retval; \
 } while (0)
-#else
-#define LOCKED(x) return x
-#endif
-	
 
 static int pcic_get_status(unsigned int sock, u_int *value)
 {
@@ -1595,12 +1519,10 @@
 	return -1;
     }
     DEBUG(0, "%s\n", version);
-    printk(KERN_INFO "Intel PCIC probe: ");
+    printk(KERN_INFO "Intel ISA PCIC probe: ");
     sockets = 0;
 
-#ifdef CONFIG_ISA
     isa_probe();
-#endif
 
     if (sockets == 0) {
 	printk("not found.\n");
@@ -1608,10 +1530,8 @@
     }
 
     /* Set up interrupt handler(s) */
-#ifdef CONFIG_ISA
     if (grab_irq != 0)
 	request_irq(cs_irq, pcic_interrupt, 0, "i82365", pcic_interrupt);
-#endif
     
     if (register_ss_entry(sockets, &pcic_operations) != 0)
 	printk(KERN_NOTICE "i82365: register_ss_entry() failed\n");
@@ -1638,16 +1558,14 @@
     unregister_ss_entry(&pcic_operations);
     if (poll_interval != 0)
 	del_timer(&poll_timer);
-#ifdef CONFIG_ISA
     if (grab_irq != 0)
 	free_irq(cs_irq, pcic_interrupt);
-#endif
     for (i = 0; i < sockets; i++) {
 	/* Turn off all interrupt sources! */
 	i365_set(i, I365_CSCINT, 0);
 	release_region(socket[i].ioaddr, 2);
     }
-#if defined(CONFIG_ISA) && defined(I82365_ISAPNP)
+#if defined(I82365_ISAPNP)
     if (i82365_pnpdev && i82365_pnpdev->deactivate)
 		i82365_pnpdev->deactivate(i82365_pnpdev);
 #endif
diff -urN linux-2.4.23-pre6/drivers/scsi/Config.in linux-2.4.23-pre7/drivers/scsi/Config.in
--- linux-2.4.23-pre6/drivers/scsi/Config.in	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/Config.in	2003-10-09 17:48:21.000000000 -0700
@@ -67,6 +67,7 @@
 dep_tristate 'Always IN2000 SCSI support' CONFIG_SCSI_IN2000 $CONFIG_SCSI
 dep_tristate 'AM53/79C974 PCI SCSI support' CONFIG_SCSI_AM53C974 $CONFIG_SCSI $CONFIG_PCI
 dep_tristate 'AMI MegaRAID support' CONFIG_SCSI_MEGARAID $CONFIG_SCSI
+dep_tristate 'AMI MegaRAID2 support' CONFIG_SCSI_MEGARAID2 $CONFIG_SCSI
 
 dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC $CONFIG_SCSI
 if [ "$CONFIG_SCSI_BUSLOGIC" != "n" ]; then
diff -urN linux-2.4.23-pre6/drivers/scsi/Makefile linux-2.4.23-pre7/drivers/scsi/Makefile
--- linux-2.4.23-pre6/drivers/scsi/Makefile	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/Makefile	2003-10-09 17:48:21.000000000 -0700
@@ -97,7 +97,7 @@
 obj-$(CONFIG_SCSI_NCR53C7xx)	+= 53c7,8xx.o 
 subdir-$(CONFIG_SCSI_SYM53C8XX_2)	+= sym53c8xx_2
 ifeq ($(CONFIG_SCSI_SYM53C8XX_2),y)
-  obj-$(CONFIG_SCSI_SYM53C8XX_2)	+= sym53c8xx_2/sym53c8xx.o
+  obj-$(CONFIG_SCSI_SYM53C8XX_2)	+= sym53c8xx_2/sym53c8xx_2.o
 endif
 obj-$(CONFIG_SCSI_SYM53C8XX)	+= sym53c8xx.o 
 obj-$(CONFIG_SCSI_NCR53C8XX)	+= ncr53c8xx.o 
@@ -110,6 +110,7 @@
 obj-$(CONFIG_SCSI_DC390T)	+= tmscsim.o
 obj-$(CONFIG_SCSI_AM53C974)	+= AM53C974.o
 obj-$(CONFIG_SCSI_MEGARAID)	+= megaraid.o
+obj-$(CONFIG_SCSI_MEGARAID2)	+= megaraid2.o
 obj-$(CONFIG_SCSI_ACARD)	+= atp870u.o
 obj-$(CONFIG_SCSI_SUNESP)	+= esp.o
 obj-$(CONFIG_SCSI_GDTH)		+= gdth.o
diff -urN linux-2.4.23-pre6/drivers/scsi/changelog.megaraid2 linux-2.4.23-pre7/drivers/scsi/changelog.megaraid2
--- linux-2.4.23-pre6/drivers/scsi/changelog.megaraid2	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/scsi/changelog.megaraid2	2003-10-09 17:48:21.000000000 -0700
@@ -0,0 +1,124 @@
+### Version 2.00.9
+Thu Sep  4 17:49:42 EDT 2003 - Atul Mukker <atulm@lsil.com>
+i.	For extended passthru commands, 64-bit scatter-gather list and 64-bit
+	mailbox address must only be used if the controller supports extended
+	CDBs and 64-bit addressing and the kernel is configured to support
+	memory beyond 4GB.
+	With 2.00.8 and previous drivers, if the controllers supports extended
+	CDBs but the kernel does not support high memory - the driver prepares
+	a 32-bit sg list but the mailbox address is chosen to be 64-bit. This
+	causes FW to incorrectly read 32-bit (8 bytes) sg list as 64-bit
+	(12 bytes) sglist. This would cause IO from non-disk devices to fail
+
+### Version 2.00.8
+Wed Aug 27 16:40:05 EDT 2003 - Atul Mukker <atulm@lsil.com>
+i.	Make sure the value of number of statuses, completed command id array,
+	and the mailbox status fields are updated in host memory before we
+	read and interpret them. For this to happen - mailbox numstatus and
+	command id array's first element are invalidated. The ISR busy waits
+	till valid values are obtained in these two fields. Now since the
+	status field is between these two fields it is assumed that status
+	values is sane when write to numstatus and completed id array is
+	complete
+ii.	while returning from the ioctl handler for the SCSI passthru commands
+	a direct access was made to the user address. Now the user structure
+	is copied in before the required field is accessed.
+iii.	Remove redundant volatile casts from pending command counter pend_cmds.
+
+### Version 2.00.7
+Fri Aug  1 11:01:11 EDT 2003 - Atul Mukker <atulm@lsil.com>
+i.	Adapter lock re-definition so that patch for kernels w/o per host lock
+	is less intrusive - Jens Axboe <axboe@suse.de>
+
+ii.	While in abort and reset handling, check for non-empty pending list is
+	invalid. The intent is to wait for pending commands in FW to complete,
+	not the pending commands with the driver - Atul Mukker <atulm@lsil.com>
+
+### Version 2.00.6
+Wed Jul 30 11:35:31 EDT 2003 - Sreenivas Bagalkote <sreenib@lsil.com>
+i.	Declare the function prototypes used for "/proc" within the compiler
+	directives #ifdef CONFIG_PROC_FS. Similary, move global/local variable
+	declarations and code fragments related to /proc within the directives.
+	- Mark Haverkamp <markh@osdl.org>
+
+ii.	Initialize host->lock with adapter->lock.
+
+iii.	Wait for mailbox status to become valid
+	- Haruo Tomita <haruo.tomita@toshiba.co.jp>
+
+iv.	Right structure is passed to FW for 4-span read configuration command.
+	- Sreenivas Bagalkote <sreenivas.bagalkote@lsil.com>
+
+### Version 2.00.5
+Thu Apr 24 14:06:55 EDT 2003 - Atul Mukker <atulm@lsil.com>
+i.	Do not use repeated allocations for "pci_dev" for internal
+	allocations. Allocate the handle at load time and set the DMA mask for
+	allocations below 4GB.
+
+ii.	Remove superfluous definitions, mid-layer /proc entry and synchronous
+	commands
+
+iii.	Logical drive numbers were incremented in passthru structure after
+	random-deletion operation! Also, the logical drive deletion command is
+	issued in polled mode because of the racy nature of interrupt based
+	operation.
+
+iv.	Add support for Intel's subsystem vendor id
+
+### Version 2.00.4
+Thu Apr 17 15:58:58 EDT 2003
+i.	Do not put the completed SCSI commands in a list. Complete them to
+	mid-layer as soon as we have completed them and reclaimed our
+	associated resources
+
+ii.	Break ISR functionality in two portions. The lower half serves as
+	interrupt acknowledgment sequence for the firmware. This half can also
+	be called from other places in the driver, e.g., the abort and reset
+	handlers.
+
+iii.	New abort and reset handling. In these situations, driver allows more
+	time for the firmware to complete outstanding requests instead of
+	failing handlers right-away.
+
+### Version 2.00.3
+Wed Jan 29 09:13:44 EST 200 - Atul Mukker <atulm@lsil.com>
+i.	Change the handshake in ISR while acknowledging interrupts. Write the
+	valid interrupt pattern 0x10001234 as soon as it is read from the
+	outdoor register. In existing driver and on certain platform, invalid
+	command ids were being returned.
+
+	Also, do not wait on status be become 0xFF, since FW can return this
+	status in certain circumstances.
+
+	Initialize the numstatus field of mailbox to 0xFF so that we can wait
+	on this wait in next interrupt. Firmware does not change its value
+	unless there are some status to be posted
+
+ii.	Specify the logical drive number while issuing the RESERVATION_STATUS
+
+iii.	Reduce the default mailbox busy wait time from 300us to 10us. This is
+	done to avoid a possible deadlock in FW because of longer bust waits.
+
+iv.	The max outstanding commands are reduced to 126 because that's the
+	safest value on all FW.
+
+v.	Number of sectors per IO are reduced to 128 (64kb), because FW needs
+	resources in special circumstances like check consistency, rebuilds
+	etc.
+
+vi.	max_commands is no longer a module parameter because of iv.
+
+### Version: 2.00.2
+i.	Intermediate release with kernel specific code
+
+
+### Version: 2.00.1i
+Wed Dec  4 14:34:51 EST 2002 - Atul Mukker <atulm@lsil.com>
+i.	Making the older IO based controllers to work with this driver
+
+
+### Version 2.00.1
+Fri Nov 15 10:59:44 EST 2002 - Atul Mukker <atulm@lsil.com>
+i.	Release host lock before issuing internal command to reset
+	reservations in megaraid_reset() and reacquire after internal command
+	is completed.
diff -urN linux-2.4.23-pre6/drivers/scsi/megaraid2.c linux-2.4.23-pre7/drivers/scsi/megaraid2.c
--- linux-2.4.23-pre6/drivers/scsi/megaraid2.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/scsi/megaraid2.c	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,5664 @@
+/*
+ *
+ *			Linux MegaRAID device driver
+ *
+ * Copyright (c) 2002  LSI Logic Corporation.
+ *
+ *	   This program is free software; you can redistribute it and/or
+ *	   modify it under the terms of the GNU General Public License
+ *	   as published by the Free Software Foundation; either version
+ *	   2 of the License, or (at your option) any later version.
+ *
+ * Copyright (c) 2002  Red Hat, Inc. All rights reserved.
+ *	  - fixes
+ *	  - speed-ups (list handling fixes, issued_list, optimizations.)
+ *	  - lots of cleanups.
+ *
+ * Version : v2.00.9 (Sep 04, 2003) - Atul Mukker <Atul.Mukker@lsil.com>
+ *
+ * Description: Linux device driver for LSI Logic MegaRAID controller
+ *
+ * Supported controllers: MegaRAID 418, 428, 438, 466, 762, 467, 471, 490, 493
+ *					518, 520, 531, 532
+ *
+ * This driver is supported by LSI Logic, with assistance from Red Hat, Dell,
+ * and others. Please send updates to the public mailing list
+ * linux-megaraid-devel@dell.com, and subscribe to and read archives of this
+ * list at http://lists.us.dell.com/.
+ *
+ * For history of changes, see ChangeLog.megaraid.
+ *
+ */
+
+#include <linux/mm.h>
+#include <linux/fs.h>
+#include <linux/blk.h>
+#include <asm/uaccess.h>
+#include <linux/delay.h>
+#include <linux/reboot.h>
+#include <linux/module.h>
+#include <linux/list.h>
+
+#include "sd.h"
+#include "scsi.h"
+#include "hosts.h"
+
+#include "megaraid2.h"
+
+MODULE_AUTHOR ("LSI Logic Corporation");
+MODULE_DESCRIPTION ("LSI Logic MegaRAID driver");
+MODULE_LICENSE ("GPL");
+
+static unsigned int max_cmd_per_lun = DEF_CMD_PER_LUN;
+MODULE_PARM(max_cmd_per_lun, "i");
+MODULE_PARM_DESC(max_cmd_per_lun, "Maximum number of commands which can be issued to a single LUN (default=DEF_CMD_PER_LUN=63)");
+
+static unsigned short int max_sectors_per_io = MAX_SECTORS_PER_IO;
+MODULE_PARM(max_sectors_per_io, "h");
+MODULE_PARM_DESC(max_sectors_per_io, "Maximum number of sectors per I/O request (default=MAX_SECTORS_PER_IO=128)");
+
+
+static unsigned short int max_mbox_busy_wait = MBOX_BUSY_WAIT;
+MODULE_PARM(max_mbox_busy_wait, "h");
+MODULE_PARM_DESC(max_mbox_busy_wait, "Maximum wait for mailbox in microseconds if busy (default=MBOX_BUSY_WAIT=10)");
+
+#define RDINDOOR(adapter)		readl((adapter)->base + 0x20)
+#define RDOUTDOOR(adapter)		readl((adapter)->base + 0x2C)
+#define WRINDOOR(adapter,value)		writel(value, (adapter)->base + 0x20)
+#define WROUTDOOR(adapter,value)	writel(value, (adapter)->base + 0x2C)
+
+/*
+ * Global variables
+ */
+
+static int hba_count;
+static adapter_t *hba_soft_state[MAX_CONTROLLERS];
+#ifdef CONFIG_PROC_FS
+static struct proc_dir_entry *mega_proc_dir_entry;
+#endif
+
+static struct notifier_block mega_notifier = {
+	.notifier_call = megaraid_reboot_notify
+};
+
+/* For controller re-ordering */
+static struct mega_hbas mega_hbas[MAX_CONTROLLERS];
+
+/*
+ * The File Operations structure for the serial/ioctl interface of the driver
+ */
+static struct file_operations megadev_fops = {
+	.ioctl		= megadev_ioctl,
+	.open		= megadev_open,
+	.release	= megadev_close,
+	.owner		= THIS_MODULE,
+};
+
+/*
+ * Array to structures for storing the information about the controllers. This
+ * information is sent to the user level applications, when they do an ioctl
+ * for this information.
+ */
+static struct mcontroller mcontroller[MAX_CONTROLLERS];
+
+/* The current driver version */
+static u32 driver_ver = 0x02000000;
+
+/* major number used by the device for character interface */
+static int major;
+
+#define IS_RAID_CH(hba, ch)	(((hba)->mega_ch_class >> (ch)) & 0x01)
+
+
+/*
+ * Debug variable to print some diagnostic messages
+ */
+static int trace_level;
+
+/*
+ * megaraid_validate_parms()
+ *
+ * Validate that any module parms passed in
+ * have proper values.
+ */
+static void
+megaraid_validate_parms(void)
+{
+	if( (max_cmd_per_lun <= 0) || (max_cmd_per_lun > MAX_CMD_PER_LUN) )
+		max_cmd_per_lun = MAX_CMD_PER_LUN;
+	if( max_mbox_busy_wait > MBOX_BUSY_WAIT )
+		max_mbox_busy_wait = MBOX_BUSY_WAIT;
+}
+
+
+/**
+ * megaraid_detect()
+ * @host_template - Our soft state maintained by mid-layer
+ *
+ * the detect entry point for the mid-layer.
+ * We scan the PCI bus for our controllers and start them.
+ *
+ * Note: PCI_DEVICE_ID_PERC4_DI below represents the PERC4/Di class of
+ * products. All of them share the same vendor id, device id, and subsystem
+ * vendor id but different subsystem ids. As of now, driver does not use the
+ * subsystem id.
+ */
+static int
+megaraid_detect(Scsi_Host_Template *host_template)
+{
+	int	i;
+	u16	dev_sw_table[] = {	/* Table of all supported
+					   vendor/device ids */
+
+		PCI_VENDOR_ID_DELL,		PCI_DEVICE_ID_DISCOVERY, 
+		PCI_VENDOR_ID_DELL,		PCI_DEVICE_ID_PERC4_DI, 
+		PCI_VENDOR_ID_LSI_LOGIC,	PCI_DEVICE_ID_PERC4_QC_VERDE, 
+		PCI_VENDOR_ID_AMI,		PCI_DEVICE_ID_AMI_MEGARAID, 
+		PCI_VENDOR_ID_AMI,		PCI_DEVICE_ID_AMI_MEGARAID2, 
+		PCI_VENDOR_ID_AMI,		PCI_DEVICE_ID_AMI_MEGARAID3, 
+		PCI_VENDOR_ID_INTEL,		PCI_DEVICE_ID_AMI_MEGARAID3, 
+		PCI_VENDOR_ID_LSI_LOGIC,	PCI_DEVICE_ID_AMI_MEGARAID3 };
+
+
+	printk(KERN_NOTICE "megaraid: " MEGARAID_VERSION);
+
+	megaraid_validate_parms();
+
+	/*
+	 * Scan PCI bus for our all devices.
+	 */
+	for( i = 0; i < sizeof(dev_sw_table)/sizeof(u16); i += 2 ) {
+
+		mega_find_card(host_template, dev_sw_table[i],
+				dev_sw_table[i+1]);
+	}
+
+	if(hba_count) {
+		/*
+		 * re-order hosts so that one with bootable logical drive
+		 * comes first
+		 */
+		mega_reorder_hosts();
+
+#ifdef CONFIG_PROC_FS
+		mega_proc_dir_entry = proc_mkdir("megaraid", &proc_root);
+
+		if(!mega_proc_dir_entry) {
+			printk(KERN_WARNING
+				"megaraid: failed to create megaraid root\n");
+		}
+		else {
+			for(i = 0; i < hba_count; i++) {
+				mega_create_proc_entry(i, mega_proc_dir_entry);
+			}
+		}
+#endif
+
+		/*
+		 * Register the driver as a character device, for applications
+		 * to access it for ioctls.
+		 * First argument (major) to register_chrdev implies a dynamic
+		 * major number allocation.
+		 */
+		major = register_chrdev(0, "megadev", &megadev_fops);
+
+		/*
+		 * Register the Shutdown Notification hook in kernel
+		 */
+		if(register_reboot_notifier(&mega_notifier)) {
+			printk(KERN_WARNING
+				"MegaRAID Shutdown routine not registered!!\n");
+		}
+
+	}
+
+	return hba_count;
+}
+
+
+
+/**
+ * mega_find_card() - find and start this controller
+ * @host_template - Our soft state maintained by mid-layer
+ * @pci_vendor - pci vendor id for this controller
+ * @pci_device - pci device id for this controller
+ *
+ * Scans the PCI bus for this vendor and device id combination, setup the
+ * resources, and register ourselves as a SCSI HBA driver, and setup all
+ * parameters for our soft state.
+ *
+ * This routine also checks for some buggy firmware and ajust the flags
+ * accordingly.
+ */
+static void
+mega_find_card(Scsi_Host_Template *host_template, u16 pci_vendor,
+	u16 pci_device)
+{
+	struct Scsi_Host	*host = NULL;
+	adapter_t	*adapter = NULL;
+	u32	magic64;
+	unsigned long	mega_baseport;
+	u16	subsysid, subsysvid;
+	u8	pci_bus;
+	u8	pci_dev_func;
+	u8	irq;
+	struct pci_dev	*pdev = NULL;
+	u8	did_ioremap_f = 0;
+	u8	did_req_region_f = 0;
+	u8	did_scsi_reg_f = 0;
+	u8	got_ipdev_f = 0;
+	u8	alloc_int_buf_f = 0;
+	u8	alloc_scb_f = 0;
+	u8	got_irq_f = 0;
+	u8	did_setup_mbox_f = 0;
+	unsigned long	tbase;
+	unsigned long	flag = 0;
+	int	i, j;
+
+	while((pdev = pci_find_device(pci_vendor, pci_device, pdev))) {
+
+		// reset flags for all controllers in this class
+		did_ioremap_f = 0;
+		did_req_region_f = 0;
+		did_scsi_reg_f = 0;
+		got_ipdev_f = 0;
+		alloc_int_buf_f = 0;
+		alloc_scb_f = 0;
+		got_irq_f = 0;
+		did_setup_mbox_f = 0;
+
+		if(pci_enable_device (pdev)) continue;
+
+		pci_bus = pdev->bus->number;
+		pci_dev_func = pdev->devfn;
+
+		/*
+		 * For these vendor and device ids, signature offsets are not
+		 * valid and 64 bit is implicit
+		 */
+		if( (pci_vendor == PCI_VENDOR_ID_DELL &&
+			pci_device == PCI_DEVICE_ID_PERC4_DI) ||
+			(pci_vendor == PCI_VENDOR_ID_LSI_LOGIC &&
+			pci_device == PCI_DEVICE_ID_PERC4_QC_VERDE) ) {
+
+			flag |= BOARD_64BIT;
+		}
+		else {
+			pci_read_config_dword(pdev, PCI_CONF_AMISIG64,
+					&magic64);
+
+			if (magic64 == HBA_SIGNATURE_64BIT)
+				flag |= BOARD_64BIT;
+		}
+
+		subsysvid = pdev->subsystem_vendor;
+		subsysid = pdev->subsystem_device;
+
+		/*
+		 * If we do not find the valid subsys vendor id, refuse to
+		 * load the driver. This is part of PCI200X compliance
+		 * We load the driver if subsysvid is 0.
+		 */
+		if( subsysvid && (subsysvid != AMI_SUBSYS_VID) &&
+				(subsysvid != DELL_SUBSYS_VID) &&
+				(subsysvid != HP_SUBSYS_VID) &&
+				(subsysvid != INTEL_SUBSYS_VID) &&
+				(subsysvid != LSI_SUBSYS_VID) ) continue;
+
+
+		printk(KERN_NOTICE "megaraid: found 0x%4.04x:0x%4.04x:bus %d:",
+			pci_vendor, pci_device, pci_bus);
+
+		printk("slot %d:func %d\n",
+			PCI_SLOT(pci_dev_func), PCI_FUNC(pci_dev_func));
+
+		/* Read the base port and IRQ from PCI */
+		mega_baseport = pci_resource_start(pdev, 0);
+		irq = pdev->irq;
+
+		tbase = mega_baseport;
+
+		if( pci_resource_flags(pdev, 0) & IORESOURCE_MEM ) {
+
+			if( check_mem_region(mega_baseport, 128) ) {
+				printk(KERN_WARNING
+					"megaraid: mem region busy!\n");
+				continue;
+			}
+			request_mem_region(mega_baseport, 128,
+					"MegaRAID: LSI Logic Corporation.");
+
+			mega_baseport =
+				(unsigned long)ioremap(mega_baseport, 128);
+
+			if( !mega_baseport ) {
+				printk(KERN_WARNING
+					"megaraid: could not map hba memory\n");
+
+				release_mem_region(tbase, 128);
+
+				continue;
+			}
+
+			flag |= BOARD_MEMMAP;
+
+			did_ioremap_f = 1;
+		}
+		else {
+			mega_baseport += 0x10;
+
+			if( !request_region(mega_baseport, 16, "megaraid") )
+				goto fail_attach;
+
+			flag |= BOARD_IOMAP;
+
+			did_req_region_f = 1;
+		}
+
+		/* Initialize SCSI Host structure */
+		host = scsi_register(host_template, sizeof(adapter_t));
+
+		if(!host) goto fail_attach;
+
+		did_scsi_reg_f = 1;
+
+		scsi_set_pci_device(host, pdev);
+
+		adapter = (adapter_t *)host->hostdata;
+		memset(adapter, 0, sizeof(adapter_t));
+
+		/*
+		 * Allocate a pci device structure for allocations done
+		 * internally - all of which would be in memory <4GB
+		 */
+		adapter->ipdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
+
+		if( adapter->ipdev == NULL ) goto fail_attach;
+
+		got_ipdev_f = 1;
+
+		memcpy(adapter->ipdev, pdev, sizeof(struct pci_dev));
+
+		if( pci_set_dma_mask(adapter->ipdev, 0xffffffff) != 0 )
+			goto fail_attach;
+
+		printk(KERN_NOTICE
+			"scsi%d:Found MegaRAID controller at 0x%lx, IRQ:%d\n",
+			host->host_no, mega_baseport, irq);
+
+		adapter->base = mega_baseport;
+
+		/* Copy resource info into structure */
+		INIT_LIST_HEAD(&adapter->free_list);
+		INIT_LIST_HEAD(&adapter->pending_list);
+
+		adapter->flag = flag;
+		spin_lock_init(&adapter->lock);
+
+		// replace adapter->lock with io_request_lock for kernels w/o
+		// per host lock and delete the line which tries to initialize
+		// the lock in host structure.
+		adapter->host_lock = &adapter->lock;
+
+		host->lock = adapter->host_lock;
+
+		host->cmd_per_lun = max_cmd_per_lun;
+		host->max_sectors = max_sectors_per_io;
+
+		adapter->dev = pdev;
+		adapter->host = host;
+
+		adapter->host->irq = irq;
+
+		if( flag & BOARD_MEMMAP ) {
+			adapter->host->base = tbase;
+		}
+		else {
+			adapter->host->io_port = tbase;
+			adapter->host->n_io_port = 16;
+		}
+
+		adapter->host->unique_id = (pci_bus << 8) | pci_dev_func;
+
+		/*
+		 * Allocate buffer to issue internal commands.
+		 */
+		adapter->mega_buffer = pci_alloc_consistent(adapter->dev,
+			MEGA_BUFFER_SIZE, &adapter->buf_dma_handle);
+
+		if( !adapter->mega_buffer ) {
+			printk(KERN_WARNING "megaraid: out of RAM.\n");
+			goto fail_attach;
+		}
+		alloc_int_buf_f = 1;
+
+		adapter->scb_list = kmalloc(sizeof(scb_t)*MAX_COMMANDS,
+				GFP_KERNEL);
+
+		if(!adapter->scb_list) {
+			printk(KERN_WARNING "megaraid: out of RAM.\n");
+			goto fail_attach;
+		}
+
+		alloc_scb_f = 1;
+
+		/* Request our IRQ */
+		if( adapter->flag & BOARD_MEMMAP ) {
+			if(request_irq(irq, megaraid_isr_memmapped, SA_SHIRQ,
+						"megaraid", adapter)) {
+				printk(KERN_WARNING
+					"megaraid: Couldn't register IRQ %d!\n",
+					irq);
+				goto fail_attach;
+			}
+		}
+		else {
+			if(request_irq(irq, megaraid_isr_iomapped, SA_SHIRQ,
+						"megaraid", adapter)) {
+				printk(KERN_WARNING
+					"megaraid: Couldn't register IRQ %d!\n",
+					irq);
+				goto fail_attach;
+			}
+		}
+		got_irq_f = 1;
+
+		if( mega_setup_mailbox(adapter) != 0 )
+			goto fail_attach;
+
+		did_setup_mbox_f = 1;
+
+		if( mega_query_adapter(adapter) != 0 )
+			goto fail_attach;
+
+		/*
+		 * Have checks for some buggy f/w
+		 */
+		if((subsysid == 0x1111) && (subsysvid == 0x1111)) {
+			/*
+			 * Which firmware
+			 */
+			if (!strcmp(adapter->fw_version, "3.00") ||
+					!strcmp(adapter->fw_version, "3.01")) {
+
+				printk( KERN_WARNING
+					"megaraid: Your  card is a Dell PERC "
+					"2/SC RAID controller with  "
+					"firmware\nmegaraid: 3.00 or 3.01.  "
+					"This driver is known to have "
+					"corruption issues\nmegaraid: with "
+					"those firmware versions on this "
+					"specific card.  In order\nmegaraid: "
+					"to protect your data, please upgrade "
+					"your firmware to version\nmegaraid: "
+					"3.10 or later, available from the "
+					"Dell Technical Support web\n"
+					"megaraid: site at\nhttp://support."
+					"dell.com/us/en/filelib/download/"
+					"index.asp?fileid=2940\n"
+				);
+			}
+		}
+
+		/*
+		 * If we have a HP 1M(0x60E7)/2M(0x60E8) controller with
+		 * firmware H.01.07, H.01.08, and H.01.09 disable 64 bit
+		 * support, since this firmware cannot handle 64 bit
+		 * addressing
+		 */
+
+		if((subsysvid == HP_SUBSYS_VID) &&
+				((subsysid == 0x60E7)||(subsysid == 0x60E8))) {
+
+			/*
+			 * which firmware
+			 */
+			if( !strcmp(adapter->fw_version, "H01.07") ||
+				!strcmp(adapter->fw_version, "H01.08") ||
+				!strcmp(adapter->fw_version, "H01.09") ) {
+
+				printk(KERN_WARNING
+					"megaraid: Firmware H.01.07, "
+					"H.01.08, and H.01.09 on 1M/2M "
+					"controllers\n"
+					"megaraid: do not support 64 bit "
+					"addressing.\nmegaraid: DISABLING "
+					"64 bit support.\n");
+				adapter->flag &= ~BOARD_64BIT;
+			}
+		}
+
+
+		if(mega_is_bios_enabled(adapter)) {
+			mega_hbas[hba_count].is_bios_enabled = 1;
+		}
+		mega_hbas[hba_count].hostdata_addr = adapter;
+
+		/*
+		 * Find out which channel is raid and which is scsi. This is
+		 * for ROMB support.
+		 */
+		mega_enum_raid_scsi(adapter);
+
+		/*
+		 * Find out if a logical drive is set as the boot drive. If
+		 * there is one, will make that as the first logical drive.
+		 * ROMB: Do we have to boot from a physical drive. Then all
+		 * the physical drives would appear before the logical disks.
+		 * Else, all the physical drives would be exported to the mid
+		 * layer after logical drives.
+		 */
+		mega_get_boot_drv(adapter);
+
+		if( ! adapter->boot_pdrv_enabled ) {
+			for( i = 0; i < NVIRT_CHAN; i++ )
+				adapter->logdrv_chan[i] = 1;
+
+			for( i = NVIRT_CHAN; i<MAX_CHANNELS+NVIRT_CHAN; i++ )
+				adapter->logdrv_chan[i] = 0;
+
+			adapter->mega_ch_class <<= NVIRT_CHAN;
+		}
+		else {
+			j = adapter->product_info.nchannels;
+			for( i = 0; i < j; i++ )
+				adapter->logdrv_chan[i] = 0;
+
+			for( i = j; i < NVIRT_CHAN + j; i++ )
+				adapter->logdrv_chan[i] = 1;
+		}
+
+
+		/*
+		 * Do we support random deletion and addition of logical
+		 * drives
+		 */
+		adapter->read_ldidmap = 0;	/* set it after first logdrv
+						   delete cmd */
+		adapter->support_random_del = mega_support_random_del(adapter);
+
+		/* Initialize SCBs */
+		if(mega_init_scb(adapter)) {
+			goto fail_attach;
+		}
+
+		/*
+		 * Reset the pending commands counter
+		 */
+		atomic_set(&adapter->pend_cmds, 0);
+
+		/*
+		 * Reset the adapter quiescent flag
+		 */
+		atomic_set(&adapter->quiescent, 0);
+
+		hba_soft_state[hba_count] = adapter;
+
+		/*
+		 * Fill in the structure which needs to be passed back to the
+		 * application when it does an ioctl() for controller related
+		 * information.
+		 */
+		i = hba_count;
+
+		mcontroller[i].base = mega_baseport;
+		mcontroller[i].irq = irq;
+		mcontroller[i].numldrv = adapter->numldrv;
+		mcontroller[i].pcibus = pci_bus;
+		mcontroller[i].pcidev = pci_device;
+		mcontroller[i].pcifun = PCI_FUNC (pci_dev_func);
+		mcontroller[i].pciid = -1;
+		mcontroller[i].pcivendor = pci_vendor;
+		mcontroller[i].pcislot = PCI_SLOT (pci_dev_func);
+		mcontroller[i].uid = (pci_bus << 8) | pci_dev_func;
+
+
+		/* Set the Mode of addressing to 64 bit if we can */
+		if((adapter->flag & BOARD_64BIT)&&(sizeof(dma_addr_t) == 8)) {
+			pci_set_dma_mask(pdev, 0xffffffffffffffff);
+			adapter->has_64bit_addr = 1;
+		}
+		else  {
+			pci_set_dma_mask(pdev, 0xffffffff);
+			adapter->has_64bit_addr = 0;
+		}
+		
+		init_MUTEX(&adapter->int_mtx);
+		init_waitqueue_head(&adapter->int_waitq);
+
+		adapter->this_id = DEFAULT_INITIATOR_ID;
+		adapter->host->this_id = DEFAULT_INITIATOR_ID;
+
+#if MEGA_HAVE_CLUSTERING
+		/*
+		 * Is cluster support enabled on this controller
+		 * Note: In a cluster the HBAs ( the initiators ) will have
+		 * different target IDs and we cannot assume it to be 7. Call
+		 * to mega_support_cluster() will get the target ids also if
+		 * the cluster support is available
+		 */
+		adapter->has_cluster = mega_support_cluster(adapter);
+
+		if( adapter->has_cluster ) {
+			printk(KERN_NOTICE
+				"megaraid: Cluster driver, initiator id:%d\n",
+				adapter->this_id);
+		}
+#endif
+
+		hba_count++;
+		continue;
+
+fail_attach:
+		if( did_setup_mbox_f ) {
+			pci_free_consistent(adapter->dev, sizeof(mbox64_t),
+					(void *)adapter->una_mbox64,
+					adapter->una_mbox64_dma);
+		}
+
+		if( got_irq_f ) {
+			irq_disable(adapter);
+			free_irq(adapter->host->irq, adapter);
+		}
+
+		if( alloc_scb_f ) {
+			kfree(adapter->scb_list);
+		}
+
+		if( alloc_int_buf_f ) {
+			pci_free_consistent(adapter->dev, MEGA_BUFFER_SIZE,
+					(void *)adapter->mega_buffer,
+					adapter->buf_dma_handle);
+		}
+
+		if( got_ipdev_f ) kfree(adapter->ipdev);
+
+		if( did_scsi_reg_f ) scsi_unregister(host);
+
+		if( did_ioremap_f ) {
+			iounmap((void *)mega_baseport);
+			release_mem_region(tbase, 128);
+		}
+
+		if( did_req_region_f )
+			release_region(mega_baseport, 16);
+	}
+
+	return;
+}
+
+
+/**
+ * mega_setup_mailbox()
+ * @adapter - pointer to our soft state
+ *
+ * Allocates a 8 byte aligned memory for the handshake mailbox.
+ */
+static int
+mega_setup_mailbox(adapter_t *adapter)
+{
+	unsigned long	align;
+
+	adapter->una_mbox64 = pci_alloc_consistent(adapter->dev,
+			sizeof(mbox64_t), &adapter->una_mbox64_dma);
+
+	if( !adapter->una_mbox64 ) return -1;
+		
+	adapter->mbox = &adapter->una_mbox64->mbox;
+
+	adapter->mbox = (mbox_t *)((((unsigned long) adapter->mbox) + 15) &
+			(~0UL ^ 0xFUL));
+
+	adapter->mbox64 = (mbox64_t *)(((unsigned long)adapter->mbox) - 8);
+
+	align = ((void *)adapter->mbox) - ((void *)&adapter->una_mbox64->mbox);
+
+	adapter->mbox_dma = adapter->una_mbox64_dma + 8 + align;
+
+	/*
+	 * Register the mailbox if the controller is an io-mapped controller
+	 */
+	if( adapter->flag & BOARD_IOMAP ) {
+
+		outb_p(adapter->mbox_dma & 0xFF,
+				adapter->host->io_port + MBOX_PORT0);
+
+		outb_p((adapter->mbox_dma >> 8) & 0xFF,
+				adapter->host->io_port + MBOX_PORT1);
+
+		outb_p((adapter->mbox_dma >> 16) & 0xFF,
+				adapter->host->io_port + MBOX_PORT2);
+
+		outb_p((adapter->mbox_dma >> 24) & 0xFF,
+				adapter->host->io_port + MBOX_PORT3);
+
+		outb_p(ENABLE_MBOX_BYTE,
+				adapter->host->io_port + ENABLE_MBOX_REGION);
+
+		irq_ack(adapter);
+
+		irq_enable(adapter);
+	}
+
+	return 0;
+}
+
+
+/*
+ * mega_query_adapter()
+ * @adapter - pointer to our soft state
+ *
+ * Issue the adapter inquiry commands to the controller and find out
+ * information and parameter about the devices attached
+ */
+static int
+mega_query_adapter(adapter_t *adapter)
+{
+	dma_addr_t	prod_info_dma_handle;
+	mega_inquiry3	*inquiry3;
+	u8	raw_mbox[16];
+	mbox_t	*mbox;
+	int	retval;
+
+	/* Initialize adapter inquiry mailbox */
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
+	memset(mbox, 0, 16);
+
+	/*
+	 * Try to issue Inquiry3 command
+	 * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
+	 * update enquiry3 structure
+	 */
+	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+
+	inquiry3 = (mega_inquiry3 *)adapter->mega_buffer;
+
+	raw_mbox[0] = FC_NEW_CONFIG;		/* i.e. mbox->cmd=0xA1 */
+	raw_mbox[2] = NC_SUBOP_ENQUIRY3;	/* i.e. 0x0F */
+	raw_mbox[3] = ENQ3_GET_SOLICITED_FULL;	/* i.e. 0x02 */
+
+	/* Issue a blocking command to the card */
+	if ((retval = issue_scb_block(adapter, raw_mbox))) {
+		/* the adapter does not support 40ld */
+
+		mraid_ext_inquiry	*ext_inq;
+		mraid_inquiry		*inq;
+		dma_addr_t		dma_handle;
+
+		ext_inq = pci_alloc_consistent(adapter->dev,
+				sizeof(mraid_ext_inquiry), &dma_handle);
+
+		if( ext_inq == NULL ) return -1;
+
+		inq = &ext_inq->raid_inq;
+
+		mbox->xferaddr = (u32)dma_handle;
+
+		/*issue old 0x04 command to adapter */
+		mbox->cmd = MEGA_MBOXCMD_ADPEXTINQ;
+
+		issue_scb_block(adapter, raw_mbox);
+
+		/*
+		 * update Enquiry3 and ProductInfo structures with
+		 * mraid_inquiry structure
+		 */
+		mega_8_to_40ld(inq, inquiry3,
+				(mega_product_info *)&adapter->product_info);
+
+		pci_free_consistent(adapter->dev, sizeof(mraid_ext_inquiry),
+				ext_inq, dma_handle);
+
+	} else {		/*adapter supports 40ld */
+		adapter->flag |= BOARD_40LD;
+
+		/*
+		 * get product_info, which is static information and will be
+		 * unchanged
+		 */
+		prod_info_dma_handle = pci_map_single(adapter->dev, (void *)
+				&adapter->product_info,
+				sizeof(mega_product_info), PCI_DMA_FROMDEVICE);
+
+		mbox->xferaddr = prod_info_dma_handle;
+
+		raw_mbox[0] = FC_NEW_CONFIG;	/* i.e. mbox->cmd=0xA1 */
+		raw_mbox[2] = NC_SUBOP_PRODUCT_INFO;	/* i.e. 0x0E */
+
+		if ((retval = issue_scb_block(adapter, raw_mbox)))
+			printk(KERN_WARNING
+			"megaraid: Product_info cmd failed with error: %d\n",
+				retval);
+
+		pci_dma_sync_single(adapter->dev, prod_info_dma_handle,
+				sizeof(mega_product_info),
+				PCI_DMA_FROMDEVICE);
+
+		pci_unmap_single(adapter->dev, prod_info_dma_handle,
+				sizeof(mega_product_info), PCI_DMA_FROMDEVICE);
+	}
+
+
+	/*
+	 * kernel scans the channels from 0 to <= max_channel
+	 */
+	adapter->host->max_channel =
+		adapter->product_info.nchannels + NVIRT_CHAN -1;
+
+	adapter->host->max_id = 16;	/* max targets per channel */
+
+	adapter->host->max_lun = 7;	/* Upto 7 luns for non disk devices */
+
+	adapter->host->cmd_per_lun = max_cmd_per_lun;
+
+	adapter->numldrv = inquiry3->num_ldrv;
+
+	adapter->max_cmds = adapter->product_info.max_commands;
+
+	if(adapter->max_cmds > MAX_COMMANDS)
+		adapter->max_cmds = MAX_COMMANDS;
+
+	adapter->host->can_queue = adapter->max_cmds - 1;
+
+	/*
+	 * Get the maximum number of scatter-gather elements supported by this
+	 * firmware
+	 */
+	mega_get_max_sgl(adapter);
+
+	adapter->host->sg_tablesize = adapter->sglen;
+
+
+	/* use HP firmware and bios version encoding */
+	if (adapter->product_info.subsysvid == HP_SUBSYS_VID) {
+		sprintf (adapter->fw_version, "%c%d%d.%d%d",
+			 adapter->product_info.fw_version[2],
+			 adapter->product_info.fw_version[1] >> 8,
+			 adapter->product_info.fw_version[1] & 0x0f,
+			 adapter->product_info.fw_version[0] >> 8,
+			 adapter->product_info.fw_version[0] & 0x0f);
+		sprintf (adapter->bios_version, "%c%d%d.%d%d",
+			 adapter->product_info.bios_version[2],
+			 adapter->product_info.bios_version[1] >> 8,
+			 adapter->product_info.bios_version[1] & 0x0f,
+			 adapter->product_info.bios_version[0] >> 8,
+			 adapter->product_info.bios_version[0] & 0x0f);
+	} else {
+		memcpy(adapter->fw_version,
+				(char *)adapter->product_info.fw_version, 4);
+		adapter->fw_version[4] = 0;
+
+		memcpy(adapter->bios_version,
+				(char *)adapter->product_info.bios_version, 4);
+
+		adapter->bios_version[4] = 0;
+	}
+
+	printk(KERN_NOTICE "megaraid: [%s:%s] detected %d logical drives.\n",
+		adapter->fw_version, adapter->bios_version, adapter->numldrv);
+
+	/*
+	 * Do we support extended (>10 bytes) cdbs
+	 */
+	adapter->support_ext_cdb = mega_support_ext_cdb(adapter);
+	if (adapter->support_ext_cdb)
+		printk(KERN_NOTICE "megaraid: supports extended CDBs.\n");
+
+
+	return 0;
+}
+
+
+/*
+ * megaraid_queue()
+ * @scmd - Issue this scsi command
+ * @done - the callback hook into the scsi mid-layer
+ *
+ * The command queuing entry point for the mid-layer.
+ */
+static int
+megaraid_queue(Scsi_Cmnd *scmd, void (*done)(Scsi_Cmnd *))
+{
+	adapter_t	*adapter;
+	scb_t	*scb;
+	int	busy=0;
+
+	adapter = (adapter_t *)scmd->host->hostdata;
+
+	scmd->scsi_done = done;
+
+
+	/*
+	 * Allocate and build a SCB request
+	 * busy flag will be set if mega_build_cmd() command could not
+	 * allocate scb. We will return non-zero status in that case.
+	 * NOTE: scb can be null even though certain commands completed
+	 * successfully, e.g., MODE_SENSE and TEST_UNIT_READY, we would
+	 * return 0 in that case.
+	 */
+
+	scb = mega_build_cmd(adapter, scmd, &busy);
+
+	if(scb) {
+		scb->state |= SCB_PENDQ;
+		list_add_tail(&scb->list, &adapter->pending_list);
+
+		/*
+		 * Check if the HBA is in quiescent state, e.g., during a
+		 * delete logical drive opertion. If it is, don't run
+		 * the pending_list.
+		 */
+		if(atomic_read(&adapter->quiescent) == 0) {
+			mega_runpendq(adapter);
+		}
+		return 0;
+	}
+
+	return busy;
+}
+
+
+/**
+ * mega_build_cmd()
+ * @adapter - pointer to our soft state
+ * @cmd - Prepare using this scsi command
+ * @busy - busy flag if no resources
+ *
+ * Prepares a command and scatter gather list for the controller. This routine
+ * also finds out if the commands is intended for a logical drive or a
+ * physical device and prepares the controller command accordingly.
+ *
+ * We also re-order the logical drives and physical devices based on their
+ * boot settings.
+ */
+static scb_t *
+mega_build_cmd(adapter_t *adapter, Scsi_Cmnd *cmd, int *busy)
+{
+	mega_ext_passthru	*epthru;
+	mega_passthru	*pthru;
+	scb_t	*scb;
+	mbox_t	*mbox;
+	long	seg;
+	char	islogical;
+	int	max_ldrv_num;
+	int	channel = 0;
+	int	target = 0;
+	int	ldrv_num = 0;   /* logical drive number */
+
+
+	/*
+	 * filter the internal and ioctl commands
+	 */
+	if((cmd->cmnd[0] == MEGA_INTERNAL_CMD)) {
+		return cmd->buffer;
+	}
+
+
+	/*
+	 * We know what channels our logical drives are on - mega_find_card()
+	 */
+	islogical = adapter->logdrv_chan[cmd->channel];
+
+	/*
+	 * The theory: If physical drive is chosen for boot, all the physical
+	 * devices are exported before the logical drives, otherwise physical
+	 * devices are pushed after logical drives, in which case - Kernel sees
+	 * the physical devices on virtual channel which is obviously converted
+	 * to actual channel on the HBA.
+	 */
+	if( adapter->boot_pdrv_enabled ) {
+		if( islogical ) {
+			/* logical channel */
+			channel = cmd->channel -
+				adapter->product_info.nchannels;
+		}
+		else {
+			channel = cmd->channel; /* this is physical channel */
+			target = cmd->target;
+
+			/*
+			 * boot from a physical disk, that disk needs to be
+			 * exposed first IF both the channels are SCSI, then
+			 * booting from the second channel is not allowed.
+			 */
+			if( target == 0 ) {
+				target = adapter->boot_pdrv_tgt;
+			}
+			else if( target == adapter->boot_pdrv_tgt ) {
+				target = 0;
+			}
+		}
+	}
+	else {
+		if( islogical ) {
+			channel = cmd->channel;	/* this is the logical channel
+						 */
+		}
+		else {
+			channel = cmd->channel - NVIRT_CHAN;	/* physical
+								   channel */
+			target = cmd->target;
+		}
+	}
+
+
+	if(islogical) {
+
+		/* have just LUN 0 for each target on virtual channels */
+		if (cmd->lun) {
+			cmd->result = (DID_BAD_TARGET << 16);
+			cmd->scsi_done(cmd);
+			return NULL;
+		}
+
+		ldrv_num = mega_get_ldrv_num(adapter, cmd, channel);
+
+
+		max_ldrv_num = (adapter->flag & BOARD_40LD) ?
+			MAX_LOGICAL_DRIVES_40LD : MAX_LOGICAL_DRIVES_8LD;
+
+		/*
+		 * max_ldrv_num increases by 0x80 if some logical drive was
+		 * deleted.
+		 */
+		if(adapter->read_ldidmap)
+			max_ldrv_num += 0x80;
+
+		if(ldrv_num > max_ldrv_num ) {
+			cmd->result = (DID_BAD_TARGET << 16);
+			cmd->scsi_done(cmd);
+			return NULL;
+		}
+
+	}
+	else {
+		if( cmd->lun > 7) {
+			/*
+			 * Do not support lun >7 for physically accessed
+			 * devices
+			 */
+			cmd->result = (DID_BAD_TARGET << 16);
+			cmd->scsi_done(cmd);
+			return NULL;
+		}
+	}
+
+	/*
+	 *
+	 * Logical drive commands
+	 *
+	 */
+	if(islogical) {
+		switch (cmd->cmnd[0]) {
+		case TEST_UNIT_READY:
+			memset(cmd->request_buffer, 0, cmd->request_bufflen);
+
+#if MEGA_HAVE_CLUSTERING
+			/*
+			 * Do we support clustering and is the support enabled
+			 * If no, return success always
+			 */
+			if( !adapter->has_cluster ) {
+				cmd->result = (DID_OK << 16);
+				cmd->scsi_done(cmd);
+				return NULL;
+			}
+
+			if(!(scb = mega_allocate_scb(adapter, cmd))) {
+
+				cmd->result = (DID_ERROR << 16);
+				cmd->scsi_done(cmd);
+				*busy = 1;
+
+				return NULL;
+			}
+
+			scb->raw_mbox[0] = MEGA_CLUSTER_CMD;
+			scb->raw_mbox[2] = MEGA_RESERVATION_STATUS;
+			scb->raw_mbox[3] = ldrv_num;
+
+			scb->dma_direction = PCI_DMA_NONE;
+
+			return scb;
+#else
+			cmd->result = (DID_OK << 16);
+			cmd->scsi_done(cmd);
+			return NULL;
+#endif
+
+		case MODE_SENSE:
+			memset(cmd->request_buffer, 0, cmd->cmnd[4]);
+			cmd->result = (DID_OK << 16);
+			cmd->scsi_done(cmd);
+			return NULL;
+
+		case READ_CAPACITY:
+		case INQUIRY:
+
+			if(!(adapter->flag & (1L << cmd->channel))) {
+
+				printk(KERN_NOTICE
+					"scsi%d: scanning scsi channel %d ",
+						adapter->host->host_no,
+						cmd->channel);
+				printk("for logical drives.\n");
+
+				adapter->flag |= (1L << cmd->channel);
+			}
+
+			/* Allocate a SCB and initialize passthru */
+			if(!(scb = mega_allocate_scb(adapter, cmd))) {
+
+				cmd->result = (DID_ERROR << 16);
+				cmd->scsi_done(cmd);
+				*busy = 1;
+
+				return NULL;
+			}
+			pthru = scb->pthru;
+
+			mbox = (mbox_t *)scb->raw_mbox;
+			memset(mbox, 0, sizeof(scb->raw_mbox));
+			memset(pthru, 0, sizeof(mega_passthru));
+
+			pthru->timeout = 0;
+			pthru->ars = 1;
+			pthru->reqsenselen = 14;
+			pthru->islogical = 1;
+			pthru->logdrv = ldrv_num;
+			pthru->cdblen = cmd->cmd_len;
+			memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
+
+			if( adapter->has_64bit_addr ) {
+				mbox->cmd = MEGA_MBOXCMD_PASSTHRU64;
+			}
+			else {
+				mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+			}
+
+			scb->dma_direction = PCI_DMA_FROMDEVICE;
+
+			pthru->numsgelements = mega_build_sglist(adapter, scb,
+				&pthru->dataxferaddr, &pthru->dataxferlen);
+
+			mbox->xferaddr = scb->pthru_dma_addr;
+
+			return scb;
+
+		case READ_6:
+		case WRITE_6:
+		case READ_10:
+		case WRITE_10:
+		case READ_12:
+		case WRITE_12:
+
+			/* Allocate a SCB and initialize mailbox */
+			if(!(scb = mega_allocate_scb(adapter, cmd))) {
+
+				cmd->result = (DID_ERROR << 16);
+				cmd->scsi_done(cmd);
+				*busy = 1;
+
+				return NULL;
+			}
+			mbox = (mbox_t *)scb->raw_mbox;
+
+			memset(mbox, 0, sizeof(scb->raw_mbox));
+			mbox->logdrv = ldrv_num;
+
+			/*
+			 * A little hack: 2nd bit is zero for all scsi read
+			 * commands and is set for all scsi write commands
+			 */
+			if( adapter->has_64bit_addr ) {
+				mbox->cmd = (*cmd->cmnd & 0x02) ?
+					MEGA_MBOXCMD_LWRITE64:
+					MEGA_MBOXCMD_LREAD64 ;
+			}
+			else {
+				mbox->cmd = (*cmd->cmnd & 0x02) ?
+					MEGA_MBOXCMD_LWRITE:
+					MEGA_MBOXCMD_LREAD ;
+			}
+
+			/*
+			 * 6-byte READ(0x08) or WRITE(0x0A) cdb
+			 */
+			if( cmd->cmd_len == 6 ) {
+				mbox->numsectors = (u32) cmd->cmnd[4];
+				mbox->lba =
+					((u32)cmd->cmnd[1] << 16) |
+					((u32)cmd->cmnd[2] << 8) |
+					(u32)cmd->cmnd[3];
+
+				mbox->lba &= 0x1FFFFF;
+
+#if MEGA_HAVE_STATS
+				/*
+				 * Take modulo 0x80, since the logical drive
+				 * number increases by 0x80 when a logical
+				 * drive was deleted
+				 */
+				if (*cmd->cmnd == READ_6) {
+					adapter->nreads[ldrv_num%0x80]++;
+					adapter->nreadblocks[ldrv_num%0x80] +=
+						mbox->numsectors;
+				} else {
+					adapter->nwrites[ldrv_num%0x80]++;
+					adapter->nwriteblocks[ldrv_num%0x80] +=
+						mbox->numsectors;
+				}
+#endif
+			}
+
+			/*
+			 * 10-byte READ(0x28) or WRITE(0x2A) cdb
+			 */
+			if( cmd->cmd_len == 10 ) {
+				mbox->numsectors =
+					(u32)cmd->cmnd[8] |
+					((u32)cmd->cmnd[7] << 8);
+				mbox->lba =
+					((u32)cmd->cmnd[2] << 24) |
+					((u32)cmd->cmnd[3] << 16) |
+					((u32)cmd->cmnd[4] << 8) |
+					(u32)cmd->cmnd[5];
+
+#if MEGA_HAVE_STATS
+				if (*cmd->cmnd == READ_10) {
+					adapter->nreads[ldrv_num%0x80]++;
+					adapter->nreadblocks[ldrv_num%0x80] +=
+						mbox->numsectors;
+				} else {
+					adapter->nwrites[ldrv_num%0x80]++;
+					adapter->nwriteblocks[ldrv_num%0x80] +=
+						mbox->numsectors;
+				}
+#endif
+			}
+
+			/*
+			 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
+			 */
+			if( cmd->cmd_len == 12 ) {
+				mbox->lba =
+					((u32)cmd->cmnd[2] << 24) |
+					((u32)cmd->cmnd[3] << 16) |
+					((u32)cmd->cmnd[4] << 8) |
+					(u32)cmd->cmnd[5];
+
+				mbox->numsectors =
+					((u32)cmd->cmnd[6] << 24) |
+					((u32)cmd->cmnd[7] << 16) |
+					((u32)cmd->cmnd[8] << 8) |
+					(u32)cmd->cmnd[9];
+
+#if MEGA_HAVE_STATS
+				if (*cmd->cmnd == READ_12) {
+					adapter->nreads[ldrv_num%0x80]++;
+					adapter->nreadblocks[ldrv_num%0x80] +=
+						mbox->numsectors;
+				} else {
+					adapter->nwrites[ldrv_num%0x80]++;
+					adapter->nwriteblocks[ldrv_num%0x80] +=
+						mbox->numsectors;
+				}
+#endif
+			}
+
+			/*
+			 * If it is a read command
+			 */
+			if( (*cmd->cmnd & 0x0F) == 0x08 ) {
+				scb->dma_direction = PCI_DMA_FROMDEVICE;
+			}
+			else {
+				scb->dma_direction = PCI_DMA_TODEVICE;
+			}
+
+			/* Calculate Scatter-Gather info */
+			mbox->numsgelements = mega_build_sglist(adapter, scb,
+					(u32 *)&mbox->xferaddr, (u32 *)&seg);
+
+			return scb;
+
+#if MEGA_HAVE_CLUSTERING
+		case RESERVE:	/* Fall through */
+		case RELEASE:
+
+			/*
+			 * Do we support clustering and is the support enabled
+			 */
+			if( ! adapter->has_cluster ) {
+
+				cmd->result = (DID_BAD_TARGET << 16);
+				cmd->scsi_done(cmd);
+				return NULL;
+			}
+
+			/* Allocate a SCB and initialize mailbox */
+			if(!(scb = mega_allocate_scb(adapter, cmd))) {
+
+				cmd->result = (DID_ERROR << 16);
+				cmd->scsi_done(cmd);
+				*busy = 1;
+
+				return NULL;
+			}
+
+			scb->raw_mbox[0] = MEGA_CLUSTER_CMD;
+			scb->raw_mbox[2] = ( *cmd->cmnd == RESERVE ) ?
+				MEGA_RESERVE_LD : MEGA_RELEASE_LD;
+
+			scb->raw_mbox[3] = ldrv_num;
+
+			scb->dma_direction = PCI_DMA_NONE;
+
+			return scb;
+#endif
+
+		default:
+			cmd->result = (DID_BAD_TARGET << 16);
+			cmd->scsi_done(cmd);
+			return NULL;
+		}
+	}
+
+	/*
+	 * Passthru drive commands
+	 */
+	else {
+		/* Allocate a SCB and initialize passthru */
+		if(!(scb = mega_allocate_scb(adapter, cmd))) {
+
+			cmd->result = (DID_ERROR << 16);
+			cmd->scsi_done(cmd);
+			*busy = 1;
+
+			return NULL;
+		}
+
+		mbox = (mbox_t *)scb->raw_mbox;
+		memset(mbox, 0, sizeof(scb->raw_mbox));
+
+		if( adapter->support_ext_cdb ) {
+
+			epthru = mega_prepare_extpassthru(adapter, scb, cmd,
+					channel, target);
+
+			mbox->cmd = MEGA_MBOXCMD_EXTPTHRU;
+
+			mbox->xferaddr = scb->epthru_dma_addr;
+
+		}
+		else {
+
+			pthru = mega_prepare_passthru(adapter, scb, cmd,
+					channel, target);
+
+			/* Initialize mailbox */
+			if( adapter->has_64bit_addr ) {
+				mbox->cmd = MEGA_MBOXCMD_PASSTHRU64;
+			}
+			else {
+				mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+			}
+
+			mbox->xferaddr = scb->pthru_dma_addr;
+
+		}
+		return scb;
+	}
+	return NULL;
+}
+
+
+/**
+ * mega_prepare_passthru()
+ * @adapter - pointer to our soft state
+ * @scb - our scsi control block
+ * @cmd - scsi command from the mid-layer
+ * @channel - actual channel on the controller
+ * @target - actual id on the controller.
+ *
+ * prepare a command for the scsi physical devices.
+ */
+static mega_passthru *
+mega_prepare_passthru(adapter_t *adapter, scb_t *scb, Scsi_Cmnd *cmd,
+		int channel, int target)
+{
+	mega_passthru *pthru;
+
+	pthru = scb->pthru;
+	memset(pthru, 0, sizeof (mega_passthru));
+
+	/* 0=6sec/1=60sec/2=10min/3=3hrs */
+	pthru->timeout = 2;
+
+	pthru->ars = 1;
+	pthru->reqsenselen = 14;
+	pthru->islogical = 0;
+
+	pthru->channel = (adapter->flag & BOARD_40LD) ? 0 : channel;
+
+	pthru->target = (adapter->flag & BOARD_40LD) ?
+		(channel << 4) | target : target;
+
+	pthru->cdblen = cmd->cmd_len;
+	pthru->logdrv = cmd->lun;
+
+	memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
+
+	/* Not sure about the direction */
+	scb->dma_direction = PCI_DMA_BIDIRECTIONAL;
+
+	/* Special Code for Handling READ_CAPA/ INQ using bounce buffers */
+	switch (cmd->cmnd[0]) {
+	case INQUIRY:
+	case READ_CAPACITY:
+		if(!(adapter->flag & (1L << cmd->channel))) {
+
+			printk(KERN_NOTICE
+				"scsi%d: scanning scsi channel %d [P%d] ",
+					adapter->host->host_no,
+					cmd->channel, channel);
+			printk("for physical devices.\n");
+
+			adapter->flag |= (1L << cmd->channel);
+		}
+		/* Fall through */
+	default:
+		pthru->numsgelements = mega_build_sglist(adapter, scb,
+				&pthru->dataxferaddr, &pthru->dataxferlen);
+		break;
+	}
+	return pthru;
+}
+
+
+/**
+ * mega_prepare_extpassthru()
+ * @adapter - pointer to our soft state
+ * @scb - our scsi control block
+ * @cmd - scsi command from the mid-layer
+ * @channel - actual channel on the controller
+ * @target - actual id on the controller.
+ *
+ * prepare a command for the scsi physical devices. This rountine prepares
+ * commands for devices which can take extended CDBs (>10 bytes)
+ */
+static mega_ext_passthru *
+mega_prepare_extpassthru(adapter_t *adapter, scb_t *scb, Scsi_Cmnd *cmd,
+		int channel, int target)
+{
+	mega_ext_passthru	*epthru;
+
+	epthru = scb->epthru;
+	memset(epthru, 0, sizeof(mega_ext_passthru));
+
+	/* 0=6sec/1=60sec/2=10min/3=3hrs */
+	epthru->timeout = 2;
+
+	epthru->ars = 1;
+	epthru->reqsenselen = 14;
+	epthru->islogical = 0;
+
+	epthru->channel = (adapter->flag & BOARD_40LD) ? 0 : channel;
+	epthru->target = (adapter->flag & BOARD_40LD) ?
+		(channel << 4) | target : target;
+
+	epthru->cdblen = cmd->cmd_len;
+	epthru->logdrv = cmd->lun;
+
+	memcpy(epthru->cdb, cmd->cmnd, cmd->cmd_len);
+
+	/* Not sure about the direction */
+	scb->dma_direction = PCI_DMA_BIDIRECTIONAL;
+
+	switch(cmd->cmnd[0]) {
+	case INQUIRY:
+	case READ_CAPACITY:
+		if(!(adapter->flag & (1L << cmd->channel))) {
+
+			printk(KERN_NOTICE
+				"scsi%d: scanning scsi channel %d [P%d] ",
+					adapter->host->host_no,
+					cmd->channel, channel);
+			printk("for physical devices.\n");
+
+			adapter->flag |= (1L << cmd->channel);
+		}
+		/* Fall through */
+	default:
+		epthru->numsgelements = mega_build_sglist(adapter, scb,
+				&epthru->dataxferaddr, &epthru->dataxferlen);
+		break;
+	}
+
+	return epthru;
+}
+
+
+/**
+ * mega_allocate_scb()
+ * @adapter - pointer to our soft state
+ * @cmd - scsi command from the mid-layer
+ *
+ * Allocate a SCB structure. This is the central structure for controller
+ * commands.
+ */
+static inline scb_t *
+mega_allocate_scb(adapter_t *adapter, Scsi_Cmnd *cmd)
+{
+	struct list_head *head = &adapter->free_list;
+	scb_t	*scb;
+
+	/* Unlink command from Free List */
+	if( !list_empty(head) ) {
+
+		scb = list_entry(head->next, scb_t, list);
+
+		list_del_init(head->next);
+
+		scb->state = SCB_ACTIVE;
+		scb->cmd = cmd;
+		scb->dma_type = MEGA_DMA_TYPE_NONE;
+
+		return scb;
+	}
+
+	return NULL;
+}
+
+
+/**
+ * mega_runpendq()
+ * @adapter - pointer to our soft state
+ *
+ * Runs through the list of pending requests.
+ */
+static inline void
+mega_runpendq(adapter_t *adapter)
+{
+	if(!list_empty(&adapter->pending_list))
+		__mega_runpendq(adapter);
+}
+
+static void
+__mega_runpendq(adapter_t *adapter)
+{
+	scb_t *scb;
+	struct list_head *pos, *next;
+
+	/* Issue any pending commands to the card */
+	list_for_each_safe(pos, next, &adapter->pending_list) {
+
+		scb = list_entry(pos, scb_t, list);
+
+		if( !(scb->state & SCB_ISSUED) ) {
+
+			if( issue_scb(adapter, scb) != 0 )
+				return;
+		}
+	}
+
+	return;
+}
+
+
+/**
+ * issue_scb()
+ * @adapter - pointer to our soft state
+ * @scb - scsi control block
+ *
+ * Post a command to the card if the mailbox is available, otherwise return
+ * busy. We also take the scb from the pending list if the mailbox is
+ * available.
+ */
+static inline int
+issue_scb(adapter_t *adapter, scb_t *scb)
+{
+	volatile mbox64_t	*mbox64 = adapter->mbox64;
+	volatile mbox_t		*mbox = adapter->mbox;
+	unsigned int	i = 0;
+
+	if(unlikely(mbox->busy)) {
+		do {
+			udelay(1);
+			i++;
+		} while( mbox->busy && (i < max_mbox_busy_wait) );
+
+		if(mbox->busy) return -1;
+	}
+
+	/* Copy mailbox data into host structure */
+	memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
+
+	mbox->cmdid = scb->idx;	/* Set cmdid */
+	mbox->busy = 1;		/* Set busy */
+
+
+	/*
+	 * Increment the pending queue counter
+	 */
+	atomic_inc(&adapter->pend_cmds);
+
+	switch (mbox->cmd) {
+	case MEGA_MBOXCMD_EXTPTHRU:
+		if( !adapter->has_64bit_addr ) break;
+		// else fall through
+	case MEGA_MBOXCMD_LREAD64:
+	case MEGA_MBOXCMD_LWRITE64:
+	case MEGA_MBOXCMD_PASSTHRU64:
+		mbox64->xfer_segment_lo = mbox->xferaddr;
+		mbox64->xfer_segment_hi = 0;
+		mbox->xferaddr = 0xFFFFFFFF;
+		break;
+	default:
+		mbox64->xfer_segment_lo = 0;
+		mbox64->xfer_segment_hi = 0;
+	}
+
+	/*
+	 * post the command
+	 */
+	scb->state |= SCB_ISSUED;
+
+	if( likely(adapter->flag & BOARD_MEMMAP) ) {
+		mbox->poll = 0;
+		mbox->ack = 0;
+		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
+	}
+	else {
+		irq_enable(adapter);
+		issue_command(adapter);
+	}
+
+	return 0;
+}
+
+
+/**
+ * issue_scb_block()
+ * @adapter - pointer to our soft state
+ * @raw_mbox - the mailbox
+ *
+ * Issue a scb in synchronous and non-interrupt mode
+ */
+static int
+issue_scb_block(adapter_t *adapter, u_char *raw_mbox)
+{
+	volatile mbox64_t *mbox64 = adapter->mbox64;
+	volatile mbox_t *mbox = adapter->mbox;
+	u8	byte;
+	u8	status;
+	int	i;
+
+	raw_mbox[0x1] = 0xFE;	/* Set cmdid */
+	raw_mbox[0xF] = 1;	/* Set busy */
+
+	/* Wait until mailbox is free */
+	if(mega_busywait_mbox (adapter))
+		goto bug_blocked_mailbox;
+
+	/* Copy mailbox data into host structure */
+	memcpy((char *) mbox, raw_mbox, 16);
+
+	switch (raw_mbox[0]) {
+	case MEGA_MBOXCMD_LREAD64:
+	case MEGA_MBOXCMD_LWRITE64:
+	case MEGA_MBOXCMD_PASSTHRU64:
+	case MEGA_MBOXCMD_EXTPTHRU:
+		mbox64->xfer_segment_lo = mbox->xferaddr;
+		mbox64->xfer_segment_hi = 0;
+		mbox->xferaddr = 0xFFFFFFFF;
+		break;
+	default:
+		mbox64->xfer_segment_lo = 0;
+		mbox64->xfer_segment_hi = 0;
+	}
+
+	if( likely(adapter->flag & BOARD_MEMMAP) ) {
+		mbox->poll = 0;
+		mbox->ack = 0;
+		mbox->numstatus = 0xFF;
+		mbox->status = 0xFF;
+		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
+
+		while((volatile u8)mbox->numstatus == 0xFF)
+			cpu_relax();
+
+		mbox->numstatus = 0xFF;
+
+		while((volatile u8)mbox->status == 0xFF)
+			cpu_relax();
+
+		status = mbox->status;
+		mbox->status = 0xFF;
+
+		while( (volatile u8)mbox->poll != 0x77 )
+			cpu_relax();
+
+		mbox->poll = 0;
+		mbox->ack = 0x77;
+
+		WRINDOOR(adapter, adapter->mbox_dma | 0x2);
+
+		while(RDINDOOR(adapter) & 0x2)
+			cpu_relax();
+	}
+	else {
+		irq_disable(adapter);
+		issue_command(adapter);
+
+		while (!((byte = irq_state(adapter)) & INTR_VALID))
+			cpu_relax();
+
+		status = mbox->status;
+		mbox->numstatus = 0xFF;
+		mbox->status = 0xFF;
+
+		set_irq_state(adapter, byte);
+		irq_enable(adapter);
+		irq_ack(adapter);
+	}
+
+	// invalidate the completed command id array. After command
+	// completion, firmware would write the valid id.
+	for (i = 0; i < MAX_FIRMWARE_STATUS; i++) {
+		mbox->completed[i] = 0xFF;
+	}
+
+	return status;
+
+bug_blocked_mailbox:
+	printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n");
+	udelay (1000);
+	return -1;
+}
+
+
+/**
+ * megaraid_isr_iomapped()
+ * @irq - irq
+ * @devp - pointer to our soft state
+ * @regs - unused
+ *
+ * Interrupt service routine for io-mapped controllers.
+ * Find out if our device is interrupting. If yes, acknowledge the interrupt
+ * and service the completed commands.
+ */
+static void
+megaraid_isr_iomapped(int irq, void *devp, struct pt_regs *regs)
+{
+	adapter_t	*adapter = devp;
+	unsigned long	flags;
+
+
+	spin_lock_irqsave(adapter->host_lock, flags);
+
+	megaraid_iombox_ack_sequence(adapter);
+
+	/* Loop through any pending requests */
+	if( atomic_read(&adapter->quiescent ) == 0) {
+		mega_runpendq(adapter);
+	}
+
+	spin_unlock_irqrestore(adapter->host_lock, flags);
+
+	return;
+}
+
+
+/**
+ * megaraid_iombox_ack_sequence - interrupt ack sequence for IO mapped HBAs
+ * @adapter	- controller's soft state
+ *
+ * Interrupt ackrowledgement sequence for IO mapped HBAs
+ */
+static inline void
+megaraid_iombox_ack_sequence(adapter_t *adapter)
+{
+	u8	status;
+	u8	nstatus;
+	u8	completed[MAX_FIRMWARE_STATUS];
+	u8	byte;
+	int	i;
+
+
+	/*
+	 * loop till F/W has more commands for us to complete.
+	 */
+	do {
+		/* Check if a valid interrupt is pending */
+		byte = irq_state(adapter);
+		if( (byte & VALID_INTR_BYTE) == 0 ) {
+			return;
+		}
+		set_irq_state(adapter, byte);
+
+		while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
+			cpu_relax();
+		}
+		adapter->mbox->numstatus = 0xFF;
+
+		for (i = 0; i < nstatus; i++) {
+			while ((completed[i] = adapter->mbox->completed[i])
+					== 0xFF) {
+				cpu_relax();
+			}
+
+			adapter->mbox->completed[i] = 0xFF;
+		}
+
+		// we must read the valid status now
+		if ((status = adapter->mbox->status) == 0xFF) {
+			printk(KERN_WARNING
+			"megaraid critical: status 0xFF from firmware.\n");
+		}
+		adapter->mbox->status = 0xFF;
+
+		/*
+		 * decrement the pending queue counter
+		 */
+		atomic_sub(nstatus, &adapter->pend_cmds);
+
+		/* Acknowledge interrupt */
+		irq_ack(adapter);
+
+		mega_cmd_done(adapter, completed, nstatus, status);
+
+	} while(1);
+}
+
+
+/**
+ * megaraid_isr_memmapped()
+ * @irq - irq
+ * @devp - pointer to our soft state
+ * @regs - unused
+ *
+ * Interrupt service routine for memory-mapped controllers.
+ * Find out if our device is interrupting. If yes, acknowledge the interrupt
+ * and service the completed commands.
+ */
+static void
+megaraid_isr_memmapped(int irq, void *devp, struct pt_regs *regs)
+{
+	adapter_t	*adapter = devp;
+	unsigned long	flags;
+
+
+	spin_lock_irqsave(adapter->host_lock, flags);
+
+	megaraid_memmbox_ack_sequence(adapter);
+
+	/* Loop through any pending requests */
+	if(atomic_read(&adapter->quiescent) == 0) {
+		mega_runpendq(adapter);
+	}
+
+	spin_unlock_irqrestore(adapter->host_lock, flags);
+
+	return;
+}
+
+
+/**
+ * megaraid_memmbox_ack_sequence - interrupt ack sequence for memory mapped HBAs
+ * @adapter	- controller's soft state
+ *
+ * Interrupt ackrowledgement sequence for memory mapped HBAs
+ */
+static inline void
+megaraid_memmbox_ack_sequence(adapter_t *adapter)
+{
+	u8	status;
+	u32	dword = 0;
+	u8	nstatus;
+	u8	completed[MAX_FIRMWARE_STATUS];
+	int	i;
+
+
+	/*
+	 * loop till F/W has more commands for us to complete.
+	 */
+	do {
+		/* Check if a valid interrupt is pending */
+		dword = RDOUTDOOR(adapter);
+		if( dword != 0x10001234 ) {
+			/*
+			 * No more pending commands
+			 */
+			return;
+		}
+		WROUTDOOR(adapter, 0x10001234);
+
+		while ((nstatus = adapter->mbox->numstatus) == 0xFF) {
+			cpu_relax();
+		}
+		adapter->mbox->numstatus = 0xFF;
+
+		for (i = 0; i < nstatus; i++ ) {
+			while ((completed[i] = adapter->mbox->completed[i])
+					== 0xFF) {
+				cpu_relax();
+			}
+
+			adapter->mbox->completed[i] = 0xFF;
+		}
+
+		// we must read the valid status now
+		if ((status = adapter->mbox->status) == 0xFF) {
+			printk(KERN_WARNING
+			"megaraid critical: status 0xFF from firmware.\n");
+		}
+		adapter->mbox->status = 0xFF;
+
+		/*
+		 * decrement the pending queue counter
+		 */
+		atomic_sub(nstatus, &adapter->pend_cmds);
+
+		/* Acknowledge interrupt */
+		WRINDOOR(adapter, 0x2);
+
+		while( RDINDOOR(adapter) & 0x02 ) cpu_relax();
+
+		mega_cmd_done(adapter, completed, nstatus, status);
+
+	} while(1);
+}
+
+
+/**
+ * mega_cmd_done()
+ * @adapter - pointer to our soft state
+ * @completed - array of ids of completed commands
+ * @nstatus - number of completed commands
+ * @status - status of the last command completed
+ *
+ * Complete the comamnds and call the scsi mid-layer callback hooks.
+ */
+static inline void
+mega_cmd_done(adapter_t *adapter, u8 completed[], int nstatus, int status)
+{
+	mega_ext_passthru	*epthru = NULL;
+	struct scatterlist	*sgl;
+	Scsi_Cmnd	*cmd = NULL;
+	mega_passthru	*pthru = NULL;
+	mbox_t	*mbox = NULL;
+	u8	c;
+	scb_t	*scb;
+	int	cmdid;
+	int	i;
+
+	/*
+	 * for all the commands completed, call the mid-layer callback routine
+	 * and free the scb.
+	 */
+	for( i = 0; i < nstatus; i++ ) {
+
+		cmdid = completed[i];
+
+		if( cmdid == CMDID_INT_CMDS ) { /* internal command */
+			scb = &adapter->int_scb;
+			cmd = scb->cmd;
+			mbox = (mbox_t *)scb->raw_mbox;
+
+			/*
+			 * Internal command interface do not fire the extended
+			 * passthru or 64-bit passthru
+			 */
+			pthru = scb->pthru;
+
+		}
+		else {
+			scb = &adapter->scb_list[cmdid];
+			cmd = scb->cmd;
+			pthru = scb->pthru;
+			epthru = scb->epthru;
+			mbox = (mbox_t *)scb->raw_mbox;
+
+			/*
+			 * Make sure f/w has completed a valid command
+			 */
+			if( !(scb->state & SCB_ISSUED) || scb->cmd == NULL ) {
+				printk(KERN_CRIT
+					"megaraid: invalid command ");
+				printk("Id %d, scb->state:%x, scsi cmd:%p\n",
+					cmdid, scb->state, scb->cmd);
+
+				continue;
+			}
+
+			/*
+			 * Was an abort issued for this command
+			 */
+			if( scb->state & SCB_ABORT ) {
+
+				printk(KERN_NOTICE
+				"megaraid: aborted cmd %lx[%x] complete.\n",
+					scb->cmd->serial_number, scb->idx);
+
+				cmd->result = (DID_ABORT << 16);
+
+				mega_free_scb(adapter, scb);
+
+				cmd->scsi_done(cmd);
+
+				continue;
+			}
+
+			/*
+			 * Was a reset issued for this command
+			 */
+			if( scb->state & SCB_RESET ) {
+
+				printk(KERN_WARNING
+				"megaraid: reset cmd %lx[%x] complete.\n",
+					scb->cmd->serial_number, scb->idx);
+
+				scb->cmd->result = (DID_RESET << 16);
+
+				mega_free_scb (adapter, scb);
+
+				cmd->scsi_done(cmd);
+
+				continue;
+			}
+
+#if MEGA_HAVE_STATS
+			{
+
+			int	islogical = adapter->logdrv_chan[cmd->channel];
+			int	logdrv = mbox->logdrv;
+
+			/*
+			 * Maintain an error counter for the logical drive.
+			 * Some application like SNMP agent need such
+			 * statistics
+			 */
+			if( status && islogical && (cmd->cmnd[0] == READ_6 ||
+						cmd->cmnd[0] == READ_10 ||
+						cmd->cmnd[0] == READ_12)) {
+				/*
+				 * Logical drive number increases by 0x80 when
+				 * a logical drive is deleted
+				 */
+				adapter->rd_errors[logdrv%0x80]++;
+			}
+
+			if( status && islogical && (cmd->cmnd[0] == WRITE_6 ||
+						cmd->cmnd[0] == WRITE_10 ||
+						cmd->cmnd[0] == WRITE_12)) {
+				/*
+				 * Logical drive number increases by 0x80 when
+				 * a logical drive is deleted
+				 */
+				adapter->wr_errors[logdrv%0x80]++;
+			}
+
+			}
+#endif
+		}
+
+		/*
+		 * Do not return the presence of hard disk on the channel so,
+		 * inquiry sent, and returned data==hard disk or removable
+		 * hard disk and not logical, request should return failure! -
+		 * PJ
+		 */
+		if(cmd->cmnd[0] == INQUIRY) {
+			int islogical = adapter->logdrv_chan[cmd->channel];
+
+			if(!islogical) {
+				if( cmd->use_sg ) {
+					sgl = (struct scatterlist *)
+						cmd->request_buffer;
+					c = *(u8 *)sgl[0].address;
+				}
+				else {
+					c = *(u8 *)cmd->request_buffer;
+				}
+
+				if(IS_RAID_CH(adapter, cmd->channel) &&
+						((c & 0x1F ) == TYPE_DISK)) {
+					status = 0xF0;
+				}
+			}
+		}
+
+		/* clear result; otherwise, success returns corrupt value */
+		cmd->result = 0;
+
+		/* Convert MegaRAID status to Linux error code */
+		switch (status) {
+		case 0x00:	/* SUCCESS , i.e. SCSI_STATUS_GOOD */
+			cmd->result |= (DID_OK << 16);
+			break;
+
+		case 0x02:	/* ERROR_ABORTED, i.e.
+				   SCSI_STATUS_CHECK_CONDITION */
+
+			/* set sense_buffer and result fields */
+			if( mbox->cmd == MEGA_MBOXCMD_PASSTHRU ||
+				mbox->cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
+
+				memcpy(cmd->sense_buffer, pthru->reqsensearea,
+						14);
+
+				cmd->result = (DRIVER_SENSE << 24) |
+					(DID_OK << 16) |
+					(CHECK_CONDITION << 1);
+			}
+			else {
+				if (mbox->cmd == MEGA_MBOXCMD_EXTPTHRU) {
+
+					memcpy(cmd->sense_buffer,
+						epthru->reqsensearea, 14);
+
+					cmd->result = (DRIVER_SENSE << 24) |
+						(DID_OK << 16) |
+						(CHECK_CONDITION << 1);
+				} else {
+					cmd->sense_buffer[0] = 0x70;
+					cmd->sense_buffer[2] = ABORTED_COMMAND;
+					cmd->result |= (CHECK_CONDITION << 1);
+				}
+			}
+			break;
+
+		case 0x08:	/* ERR_DEST_DRIVE_FAILED, i.e.
+				   SCSI_STATUS_BUSY */
+			cmd->result |= (DID_BUS_BUSY << 16) | status;
+			break;
+
+		default:
+#if MEGA_HAVE_CLUSTERING
+			/*
+			 * If TEST_UNIT_READY fails, we know
+			 * MEGA_RESERVATION_STATUS failed
+			 */
+			if( cmd->cmnd[0] == TEST_UNIT_READY ) {
+				cmd->result |= (DID_ERROR << 16) |
+					(RESERVATION_CONFLICT << 1);
+			}
+			else
+			/*
+			 * Error code returned is 1 if Reserve or Release
+			 * failed or the input parameter is invalid
+			 */
+			if( status == 1 &&
+				(cmd->cmnd[0] == RESERVE ||
+					 cmd->cmnd[0] == RELEASE) ) {
+
+				cmd->result |= (DID_ERROR << 16) |
+					(RESERVATION_CONFLICT << 1);
+			}
+			else
+#endif
+				cmd->result |= (DID_BAD_TARGET << 16)|status;
+		}
+
+		/*
+		 * Only free SCBs for the commands coming down from the
+		 * mid-layer, not for which were issued internally
+		 *
+		 * For internal command, restore the status returned by the
+		 * firmware so that user can interpret it.
+		 */
+		if( cmdid == CMDID_INT_CMDS ) { /* internal command */
+			cmd->result = status;
+
+			/*
+			 * Remove the internal command from the pending list
+			 */
+			list_del_init(&scb->list);
+			scb->state = SCB_FREE;
+		}
+		else {
+			mega_free_scb(adapter, scb);
+		}
+
+		/*
+		 * Call the mid-layer callback for this command
+		 */
+		cmd->scsi_done(cmd);
+	}
+}
+
+
+/*
+ * Free a SCB structure
+ * Note: We assume the scsi commands associated with this scb is not free yet.
+ */
+static void
+mega_free_scb(adapter_t *adapter, scb_t *scb)
+{
+	switch( scb->dma_type ) {
+
+	case MEGA_DMA_TYPE_NONE:
+		break;
+
+	case MEGA_BULK_DATA:
+		pci_unmap_page(adapter->host->pci_dev, scb->dma_h_bulkdata,
+			scb->cmd->request_bufflen, scb->dma_direction);
+
+		if( scb->dma_direction == PCI_DMA_FROMDEVICE ) {
+			pci_dma_sync_single(adapter->host->pci_dev,
+					scb->dma_h_bulkdata,
+					scb->cmd->request_bufflen,
+					PCI_DMA_FROMDEVICE);
+		}
+
+		break;
+
+	case MEGA_SGLIST:
+		pci_unmap_sg(adapter->host->pci_dev, scb->cmd->request_buffer,
+			scb->cmd->use_sg, scb->dma_direction);
+
+		if( scb->dma_direction == PCI_DMA_FROMDEVICE ) {
+			pci_dma_sync_sg(adapter->host->pci_dev,
+					scb->cmd->request_buffer,
+					scb->cmd->use_sg, PCI_DMA_FROMDEVICE);
+		}
+
+		break;
+
+	default:
+		break;
+	}
+
+	/*
+	 * Remove from the pending list
+	 */
+	list_del_init(&scb->list);
+
+	/* Link the scb back into free list */
+	scb->state = SCB_FREE;
+	scb->cmd = NULL;
+
+	list_add(&scb->list, &adapter->free_list);
+}
+
+
+/*
+ * Wait until the controller's mailbox is available
+ */
+static inline int
+mega_busywait_mbox (adapter_t *adapter)
+{
+	if (adapter->mbox->busy)
+		return __mega_busywait_mbox(adapter);
+	return 0;
+}
+
+static int
+__mega_busywait_mbox (adapter_t *adapter)
+{
+	volatile mbox_t *mbox = adapter->mbox;
+	long counter;
+
+	for (counter = 0; counter < 10000; counter++) {
+		if (!mbox->busy)
+			return 0;
+		udelay(100); yield();
+	}
+	return -1;		/* give up after 1 second */
+}
+
+/*
+ * Copies data to SGLIST
+ * Note: For 64 bit cards, we need a minimum of one SG element for read/write
+ */
+static int
+mega_build_sglist(adapter_t *adapter, scb_t *scb, u32 *buf, u32 *len)
+{
+	struct scatterlist	*sgl;
+	struct page	*page;
+	unsigned long	offset;
+	Scsi_Cmnd	*cmd;
+	int	sgcnt;
+	int	idx;
+
+	cmd = scb->cmd;
+
+	/* Scatter-gather not used */
+	if( !cmd->use_sg ) {
+
+		page = virt_to_page(cmd->request_buffer);
+
+		offset = ((unsigned long)cmd->request_buffer & ~PAGE_MASK);
+
+		scb->dma_h_bulkdata = pci_map_page(adapter->host->pci_dev,
+						  page, offset,
+						  cmd->request_bufflen,
+						  scb->dma_direction);
+		scb->dma_type = MEGA_BULK_DATA;
+
+		/*
+		 * We need to handle special 64-bit commands that need a
+		 * minimum of 1 SG
+		 */
+		if( adapter->has_64bit_addr ) {
+			scb->sgl64[0].address = scb->dma_h_bulkdata;
+			scb->sgl64[0].length = cmd->request_bufflen;
+			*buf = (u32)scb->sgl_dma_addr;
+			*len = (u32)cmd->request_bufflen;
+			return 1;
+		}
+		else {
+			*buf = (u32)scb->dma_h_bulkdata;
+			*len = (u32)cmd->request_bufflen;
+		}
+
+		if( scb->dma_direction == PCI_DMA_TODEVICE ) {
+			pci_dma_sync_single(adapter->host->pci_dev,
+					scb->dma_h_bulkdata,
+					cmd->request_bufflen,
+					PCI_DMA_TODEVICE);
+		}
+
+		return 0;
+	}
+
+	sgl = (struct scatterlist *)cmd->request_buffer;
+
+	/*
+	 * Copy Scatter-Gather list info into controller structure.
+	 *
+	 * The number of sg elements returned must not exceed our limit
+	 */
+	sgcnt = pci_map_sg(adapter->host->pci_dev, sgl, cmd->use_sg,
+			scb->dma_direction);
+
+	scb->dma_type = MEGA_SGLIST;
+
+	if( sgcnt > adapter->sglen ) BUG();
+
+	for( idx = 0; idx < sgcnt; idx++, sgl++ ) {
+
+		if( adapter->has_64bit_addr ) {
+			scb->sgl64[idx].address = sg_dma_address(sgl);
+			scb->sgl64[idx].length = sg_dma_len(sgl);
+		}
+		else {
+			scb->sgl[idx].address = sg_dma_address(sgl);
+			scb->sgl[idx].length = sg_dma_len(sgl);
+		}
+	}
+
+	/* Reset pointer and length fields */
+	*buf = scb->sgl_dma_addr;
+
+	/*
+	 * For passthru command, dataxferlen must be set, even for commands
+	 * with a sg list
+	 */
+	*len = (u32)cmd->request_bufflen;
+
+	if( scb->dma_direction == PCI_DMA_TODEVICE ) {
+		pci_dma_sync_sg(adapter->host->pci_dev, sgl, cmd->use_sg,
+				PCI_DMA_TODEVICE);
+	}
+
+	/* Return count of SG requests */
+	return sgcnt;
+}
+
+
+/*
+ * mega_8_to_40ld()
+ *
+ * takes all info in AdapterInquiry structure and puts it into ProductInfo and
+ * Enquiry3 structures for later use
+ */
+static void
+mega_8_to_40ld(mraid_inquiry *inquiry, mega_inquiry3 *enquiry3,
+		mega_product_info *product_info)
+{
+	int i;
+
+	product_info->max_commands = inquiry->adapter_info.max_commands;
+	enquiry3->rebuild_rate = inquiry->adapter_info.rebuild_rate;
+	product_info->nchannels = inquiry->adapter_info.nchannels;
+
+	for (i = 0; i < 4; i++) {
+		product_info->fw_version[i] =
+			inquiry->adapter_info.fw_version[i];
+
+		product_info->bios_version[i] =
+			inquiry->adapter_info.bios_version[i];
+	}
+	enquiry3->cache_flush_interval =
+		inquiry->adapter_info.cache_flush_interval;
+
+	product_info->dram_size = inquiry->adapter_info.dram_size;
+
+	enquiry3->num_ldrv = inquiry->logdrv_info.num_ldrv;
+
+	for (i = 0; i < MAX_LOGICAL_DRIVES_8LD; i++) {
+		enquiry3->ldrv_size[i] = inquiry->logdrv_info.ldrv_size[i];
+		enquiry3->ldrv_prop[i] = inquiry->logdrv_info.ldrv_prop[i];
+		enquiry3->ldrv_state[i] = inquiry->logdrv_info.ldrv_state[i];
+	}
+
+	for (i = 0; i < (MAX_PHYSICAL_DRIVES); i++)
+		enquiry3->pdrv_state[i] = inquiry->pdrv_info.pdrv_state[i];
+}
+
+
+/*
+ * Release the controller's resources
+ */
+static int
+megaraid_release(struct Scsi_Host *host)
+{
+	adapter_t	*adapter;
+	mbox_t	*mbox;
+	u_char	raw_mbox[16];
+#ifdef CONFIG_PROC_FS
+	char	buf[12] = { 0 };
+#endif
+
+	adapter = (adapter_t *)host->hostdata;
+	mbox = (mbox_t *)raw_mbox;
+
+	printk(KERN_NOTICE "megaraid: being unloaded...");
+
+	/* Flush adapter cache */
+	memset(mbox, 0, 16);
+	raw_mbox[0] = FLUSH_ADAPTER;
+
+	irq_disable(adapter);
+	free_irq(adapter->host->irq, adapter);
+
+	/* Issue a blocking (interrupts disabled) command to the card */
+	issue_scb_block(adapter, raw_mbox);
+
+	/* Flush disks cache */
+	memset(mbox, 0, 16);
+	raw_mbox[0] = FLUSH_SYSTEM;
+
+	/* Issue a blocking (interrupts disabled) command to the card */
+	issue_scb_block(adapter, raw_mbox);
+
+
+	/* Free our resources */
+	if( adapter->flag & BOARD_MEMMAP ) {
+		iounmap((void *)adapter->base);
+		release_mem_region(adapter->host->base, 128);
+	}
+	else {
+		release_region(adapter->base, 16);
+	}
+
+	mega_free_sgl(adapter);
+
+#ifdef CONFIG_PROC_FS
+	if( adapter->controller_proc_dir_entry ) {
+		remove_proc_entry("stat", adapter->controller_proc_dir_entry);
+		remove_proc_entry("config",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("mailbox",
+				adapter->controller_proc_dir_entry);
+#if MEGA_HAVE_ENH_PROC
+		remove_proc_entry("rebuild-rate",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("battery-status",
+				adapter->controller_proc_dir_entry);
+
+		remove_proc_entry("diskdrives-ch0",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("diskdrives-ch1",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("diskdrives-ch2",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("diskdrives-ch3",
+				adapter->controller_proc_dir_entry);
+
+		remove_proc_entry("raiddrives-0-9",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("raiddrives-10-19",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("raiddrives-20-29",
+				adapter->controller_proc_dir_entry);
+		remove_proc_entry("raiddrives-30-39",
+				adapter->controller_proc_dir_entry);
+#endif
+
+		sprintf(buf, "hba%d", adapter->host->host_no);
+		remove_proc_entry(buf, mega_proc_dir_entry);
+	}
+#endif
+
+	pci_free_consistent(adapter->dev, MEGA_BUFFER_SIZE,
+			adapter->mega_buffer, adapter->buf_dma_handle);
+	kfree(adapter->scb_list);
+	pci_free_consistent(adapter->dev, sizeof(mbox64_t),
+			(void *)adapter->una_mbox64, adapter->una_mbox64_dma);
+
+	kfree(adapter->ipdev);
+
+	hba_count--;
+
+	if( hba_count == 0 ) {
+
+		/*
+		 * Unregister the character device interface to the driver.
+		 */
+		unregister_chrdev(major, "megadev");
+
+		unregister_reboot_notifier(&mega_notifier);
+
+#ifdef CONFIG_PROC_FS
+		if( adapter->controller_proc_dir_entry ) {
+			remove_proc_entry ("megaraid", &proc_root);
+		}
+#endif
+
+	}
+
+	/*
+	 * Release the controller memory. A word of warning this frees
+	 * hostdata and that includes adapter-> so be careful what you
+	 * dereference beyond this point
+	 */
+	scsi_unregister(host);
+
+
+	printk("ok.\n");
+
+	return 0;
+}
+
+static inline void
+mega_free_sgl(adapter_t *adapter)
+{
+	scb_t	*scb;
+	int	i;
+
+	for(i = 0; i < adapter->max_cmds; i++) {
+
+		scb = &adapter->scb_list[i];
+
+		if( scb->sgl64 ) {
+			pci_free_consistent(adapter->dev,
+				sizeof(mega_sgl64) * adapter->sglen,
+				scb->sgl64,
+				scb->sgl_dma_addr);
+
+			scb->sgl64 = NULL;
+		}
+
+		if( scb->pthru ) {
+			pci_free_consistent(adapter->dev, sizeof(mega_passthru),
+				scb->pthru, scb->pthru_dma_addr);
+
+			scb->pthru = NULL;
+		}
+
+		if( scb->epthru ) {
+			pci_free_consistent(adapter->dev,
+				sizeof(mega_ext_passthru),
+				scb->epthru, scb->epthru_dma_addr);
+
+			scb->epthru = NULL;
+		}
+
+	}
+}
+
+
+/*
+ * Get information about the card/driver
+ */
+const char *
+megaraid_info(struct Scsi_Host *host)
+{
+	static char buffer[512];
+	adapter_t *adapter;
+
+	adapter = (adapter_t *)host->hostdata;
+
+	sprintf (buffer,
+		 "LSI Logic MegaRAID %s %d commands %d targs %d chans %d luns",
+		 adapter->fw_version, adapter->product_info.max_commands,
+		 adapter->host->max_id, adapter->host->max_channel,
+		 adapter->host->max_lun);
+	return buffer;
+}
+
+/* shouldn't be used, but included for completeness */
+static int
+megaraid_command (Scsi_Cmnd *cmd)
+{
+	printk(KERN_WARNING
+	"megaraid critcal error: synchronous interface is not implemented.\n");
+
+	cmd->result = (DID_ERROR << 16);
+	cmd->scsi_done(cmd);
+
+	return 1;
+}
+
+
+/**
+ * megaraid_abort - abort the scsi command
+ * @scp	- command to be aborted
+ *
+ * Abort a previous SCSI request. Only commands on the pending list can be
+ * aborted. All the commands issued to the F/W must complete.
+ */
+static int
+megaraid_abort(Scsi_Cmnd *scp)
+{
+	adapter_t		*adapter;
+	struct list_head	*pos, *next;
+	scb_t			*scb;
+	long			iter;
+	int			rval = SUCCESS;
+
+	adapter = (adapter_t *)scp->host->hostdata;
+
+	ASSERT( spin_is_locked(adapter->host_lock) );
+
+	printk("megaraid: aborting-%ld cmd=%x <c=%d t=%d l=%d>\n",
+		scp->serial_number, scp->cmnd[0], scp->channel, scp->target,
+		scp->lun);
+
+
+	list_for_each_safe( pos, next, &adapter->pending_list ) {
+
+		scb = list_entry(pos, scb_t, list);
+
+		if( scb->cmd == scp ) { /* Found command */
+
+			scb->state |= SCB_ABORT;
+
+			/*
+			 * Check if this command was never issued. If this is
+			 * the case, take it off from the pending list and
+			 * complete.
+			 */
+			if( !(scb->state & SCB_ISSUED) ) {
+
+				printk(KERN_WARNING
+				"megaraid: %ld:%d, driver owner.\n",
+					scp->serial_number, scb->idx);
+
+				scp->result = (DID_ABORT << 16);
+
+				mega_free_scb(adapter, scb);
+
+				scp->scsi_done(scp);
+
+				break;
+			}
+		}
+	}
+
+	/*
+	 * By this time, either all commands are completed or aborted by
+	 * mid-layer. Do not return until all the commands are actually
+	 * completed by the firmware
+	 */
+	iter = 0;
+	while( atomic_read(&adapter->pend_cmds) > 0 ) {
+		/*
+		 * Perform the ack sequence, since interrupts are not
+		 * available right now!
+		 */
+		if( adapter->flag & BOARD_MEMMAP ) {
+			megaraid_memmbox_ack_sequence(adapter);
+		}
+		else {
+			megaraid_iombox_ack_sequence(adapter);
+		}
+
+		/*
+		 * print a message once every second only
+		 */
+		if( !(iter % 1000) ) {
+			printk(
+			"megarid: Waiting for %d commands to flush: iter:%ld\n",
+				atomic_read(&adapter->pend_cmds), iter);
+		}
+
+		if( iter++ < MBOX_ABORT_SLEEP*1000 ) {
+			mdelay(1);
+		}
+		else {
+			printk(KERN_WARNING
+				"megaraid: critical hardware error!\n");
+
+			rval = FAILED;
+
+			break;
+		}
+	}
+
+	if( rval == SUCCESS ) {
+		printk(KERN_INFO
+			"megaraid: abort sequence successfully complete.\n");
+	}
+
+	return rval;
+}
+
+
+static int
+megaraid_reset(Scsi_Cmnd *cmd)
+{
+	adapter_t	*adapter;
+	megacmd_t	mc;
+	long		iter;
+	int		rval = SUCCESS;
+
+	adapter = (adapter_t *)cmd->host->hostdata;
+
+	ASSERT( spin_is_locked(adapter->host_lock) );
+
+	printk("megaraid: reset-%ld cmd=%x <c=%d t=%d l=%d>\n",
+		cmd->serial_number, cmd->cmnd[0], cmd->channel, cmd->target,
+		cmd->lun);
+
+
+#if MEGA_HAVE_CLUSTERING
+	mc.cmd = MEGA_CLUSTER_CMD;
+	mc.opcode = MEGA_RESET_RESERVATIONS;
+
+	spin_unlock_irq(adapter->host_lock);
+	if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+		printk(KERN_WARNING
+				"megaraid: reservation reset failed.\n");
+	}
+	else {
+		printk(KERN_INFO "megaraid: reservation reset.\n");
+	}
+	spin_lock_irq(adapter->host_lock);
+#endif
+
+	/*
+	 * Do not return until all the commands are actually completed by the
+	 * firmware
+	 */
+	iter = 0;
+	while( atomic_read(&adapter->pend_cmds) > 0 ) {
+		/*
+		 * Perform the ack sequence, since interrupts are not
+		 * available right now!
+		 */
+		if( adapter->flag & BOARD_MEMMAP ) {
+			megaraid_memmbox_ack_sequence(adapter);
+		}
+		else {
+			megaraid_iombox_ack_sequence(adapter);
+		}
+
+		/*
+		 * print a message once every second only
+		 */
+		if( !(iter % 1000) ) {
+			printk(
+			"megarid: Waiting for %d commands to flush: iter:%ld\n",
+				atomic_read(&adapter->pend_cmds), iter);
+		}
+
+		if( iter++ < MBOX_RESET_SLEEP*1000 ) {
+			mdelay(1);
+		}
+		else {
+			printk(KERN_WARNING
+				"megaraid: critical hardware error!\n");
+
+			rval = FAILED;
+
+			break;
+		}
+	}
+
+	if( rval == SUCCESS ) {
+		printk(KERN_INFO
+			"megaraid: reset sequence successfully complete.\n");
+	}
+
+	return rval;
+}
+
+
+#ifdef CONFIG_PROC_FS
+/* Following code handles /proc fs  */
+
+#define CREATE_READ_PROC(string, func)	create_proc_read_entry(string,	\
+					S_IRUSR | S_IFREG,		\
+					controller_proc_dir_entry,	\
+					func, adapter)
+
+/**
+ * mega_create_proc_entry()
+ * @index - index in soft state array
+ * @parent - parent node for this /proc entry
+ *
+ * Creates /proc entries for our controllers.
+ */
+static void
+mega_create_proc_entry(int index, struct proc_dir_entry *parent)
+{
+	struct proc_dir_entry	*controller_proc_dir_entry = NULL;
+	u8		string[64] = { 0 };
+	adapter_t	*adapter = hba_soft_state[index];
+
+	sprintf(string, "hba%d", adapter->host->host_no);
+
+	controller_proc_dir_entry =
+		adapter->controller_proc_dir_entry = proc_mkdir(string, parent);
+
+	if(!controller_proc_dir_entry) {
+		printk(KERN_WARNING "\nmegaraid: proc_mkdir failed\n");
+		return;
+	}
+	adapter->proc_read = CREATE_READ_PROC("config", proc_read_config);
+	adapter->proc_stat = CREATE_READ_PROC("stat", proc_read_stat);
+	adapter->proc_mbox = CREATE_READ_PROC("mailbox", proc_read_mbox);
+#if MEGA_HAVE_ENH_PROC
+	adapter->proc_rr = CREATE_READ_PROC("rebuild-rate", proc_rebuild_rate);
+	adapter->proc_battery = CREATE_READ_PROC("battery-status",
+			proc_battery);
+
+	/*
+	 * Display each physical drive on its channel
+	 */
+	adapter->proc_pdrvstat[0] = CREATE_READ_PROC("diskdrives-ch0",
+					proc_pdrv_ch0);
+	adapter->proc_pdrvstat[1] = CREATE_READ_PROC("diskdrives-ch1",
+					proc_pdrv_ch1);
+	adapter->proc_pdrvstat[2] = CREATE_READ_PROC("diskdrives-ch2",
+					proc_pdrv_ch2);
+	adapter->proc_pdrvstat[3] = CREATE_READ_PROC("diskdrives-ch3",
+					proc_pdrv_ch3);
+
+	/*
+	 * Display a set of up to 10 logical drive through each of following
+	 * /proc entries
+	 */
+	adapter->proc_rdrvstat[0] = CREATE_READ_PROC("raiddrives-0-9",
+					proc_rdrv_10);
+	adapter->proc_rdrvstat[1] = CREATE_READ_PROC("raiddrives-10-19",
+					proc_rdrv_20);
+	adapter->proc_rdrvstat[2] = CREATE_READ_PROC("raiddrives-20-29",
+					proc_rdrv_30);
+	adapter->proc_rdrvstat[3] = CREATE_READ_PROC("raiddrives-30-39",
+					proc_rdrv_40);
+#endif
+}
+
+
+/**
+ * proc_read_config()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display configuration information about the controller.
+ */
+static int
+proc_read_config(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+
+	adapter_t *adapter = (adapter_t *)data;
+	int len = 0;
+
+	len += sprintf(page+len, "%s", MEGARAID_VERSION);
+
+	if(adapter->product_info.product_name[0])
+		len += sprintf(page+len, "%s\n",
+				adapter->product_info.product_name);
+
+	len += sprintf(page+len, "Controller Type: ");
+
+	if( adapter->flag & BOARD_MEMMAP ) {
+		len += sprintf(page+len,
+			"438/466/467/471/493/518/520/531/532\n");
+	}
+	else {
+		len += sprintf(page+len,
+			"418/428/434\n");
+	}
+
+	if(adapter->flag & BOARD_40LD) {
+		len += sprintf(page+len,
+				"Controller Supports 40 Logical Drives\n");
+	}
+
+	if(adapter->flag & BOARD_64BIT) {
+		len += sprintf(page+len,
+		"Controller capable of 64-bit memory addressing\n");
+	}
+	if( adapter->has_64bit_addr ) {
+		len += sprintf(page+len,
+			"Controller using 64-bit memory addressing\n");
+	}
+	else {
+		len += sprintf(page+len,
+			"Controller is not using 64-bit memory addressing\n");
+	}
+
+	len += sprintf(page+len, "Base = %08lx, Irq = %d, ", adapter->base,
+			adapter->host->irq);
+
+	len += sprintf(page+len, "Logical Drives = %d, Channels = %d\n",
+			adapter->numldrv, adapter->product_info.nchannels);
+
+	len += sprintf(page+len, "Version =%s:%s, DRAM = %dMb\n",
+			adapter->fw_version, adapter->bios_version,
+			adapter->product_info.dram_size);
+
+	len += sprintf(page+len,
+		"Controller Queue Depth = %d, Driver Queue Depth = %d\n",
+		adapter->product_info.max_commands, adapter->max_cmds);
+
+	len += sprintf(page+len, "support_ext_cdb    = %d\n",
+			adapter->support_ext_cdb);
+	len += sprintf(page+len, "support_random_del = %d\n",
+			adapter->support_random_del);
+	len += sprintf(page+len, "boot_ldrv_enabled  = %d\n",
+			adapter->boot_ldrv_enabled);
+	len += sprintf(page+len, "boot_ldrv          = %d\n",
+			adapter->boot_ldrv);
+	len += sprintf(page+len, "boot_pdrv_enabled  = %d\n",
+			adapter->boot_pdrv_enabled);
+	len += sprintf(page+len, "boot_pdrv_ch       = %d\n",
+			adapter->boot_pdrv_ch);
+	len += sprintf(page+len, "boot_pdrv_tgt      = %d\n",
+			adapter->boot_pdrv_tgt);
+	len += sprintf(page+len, "quiescent          = %d\n",
+			atomic_read(&adapter->quiescent));
+	len += sprintf(page+len, "has_cluster        = %d\n",
+			adapter->has_cluster);
+
+	len += sprintf(page+len, "\nModule Parameters:\n");
+	len += sprintf(page+len, "max_cmd_per_lun    = %d\n",
+			max_cmd_per_lun);
+	len += sprintf(page+len, "max_sectors_per_io = %d\n",
+			max_sectors_per_io);
+
+	*eof = 1;
+
+	return len;
+}
+
+
+
+/**
+ * proc_read_stat()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Diaplay statistical information about the I/O activity.
+ */
+static int
+proc_read_stat(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t	*adapter;
+	int	len;
+	int	i;
+
+	i = 0;	/* avoid compilation warnings */
+	len = 0;
+	adapter = (adapter_t *)data;
+
+	len = sprintf(page, "Statistical Information for this controller\n");
+	len += sprintf(page+len, "pend_cmds = %d\n",
+			atomic_read(&adapter->pend_cmds));
+#if MEGA_HAVE_STATS
+	for(i = 0; i < adapter->numldrv; i++) {
+		len += sprintf(page+len, "Logical Drive %d:\n", i);
+
+		len += sprintf(page+len,
+			"\tReads Issued = %lu, Writes Issued = %lu\n",
+			adapter->nreads[i], adapter->nwrites[i]);
+
+		len += sprintf(page+len,
+			"\tSectors Read = %lu, Sectors Written = %lu\n",
+			adapter->nreadblocks[i], adapter->nwriteblocks[i]);
+
+		len += sprintf(page+len,
+			"\tRead errors = %lu, Write errors = %lu\n\n",
+			adapter->rd_errors[i], adapter->wr_errors[i]);
+	}
+#else
+	len += sprintf(page+len,
+			"IO and error counters not compiled in driver.\n");
+#endif
+
+	*eof = 1;
+
+	return len;
+}
+
+
+/**
+ * proc_read_mbox()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display mailbox information for the last command issued. This information
+ * is good for debugging.
+ */
+static int
+proc_read_mbox(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+
+	adapter_t	*adapter = (adapter_t *)data;
+	volatile mbox_t	*mbox = adapter->mbox;
+	int	len = 0;
+
+	len = sprintf(page, "Contents of Mail Box Structure\n");
+	len += sprintf(page+len, "  Fw Command   = 0x%02x\n", mbox->cmd);
+	len += sprintf(page+len, "  Cmd Sequence = 0x%02x\n", mbox->cmdid);
+	len += sprintf(page+len, "  No of Sectors= %04d\n", mbox->numsectors);
+	len += sprintf(page+len, "  LBA          = 0x%02x\n", mbox->lba);
+	len += sprintf(page+len, "  DTA          = 0x%08x\n", mbox->xferaddr);
+	len += sprintf(page+len, "  Logical Drive= 0x%02x\n", mbox->logdrv);
+	len += sprintf(page+len, "  No of SG Elmt= 0x%02x\n",
+			mbox->numsgelements);
+	len += sprintf(page+len, "  Busy         = %01x\n", mbox->busy);
+	len += sprintf(page+len, "  Status       = 0x%02x\n", mbox->status);
+
+	*eof = 1;
+
+	return len;
+}
+
+
+/**
+ * proc_rebuild_rate()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display current rebuild rate
+ */
+static int
+proc_rebuild_rate(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t	*adapter = (adapter_t *)data;
+	dma_addr_t	dma_handle;
+	caddr_t		inquiry;
+	struct pci_dev	*pdev;
+	int	len = 0;
+
+	pdev = adapter->ipdev;
+
+	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
+		*eof = 1;
+		return len;
+	}
+
+	if( mega_adapinq(adapter, dma_handle) != 0 ) {
+
+		len = sprintf(page, "Adapter inquiry failed.\n");
+
+		printk(KERN_WARNING "megaraid: inquiry failed.\n");
+
+		mega_free_inquiry(inquiry, dma_handle, pdev);
+
+		*eof = 1;
+
+		return len;
+	}
+
+	if( adapter->flag & BOARD_40LD ) {
+		len = sprintf(page, "Rebuild Rate: [%d%%]\n",
+			((mega_inquiry3 *)inquiry)->rebuild_rate);
+	}
+	else {
+		len = sprintf(page, "Rebuild Rate: [%d%%]\n",
+			((mraid_ext_inquiry *)
+			inquiry)->raid_inq.adapter_info.rebuild_rate);
+	}
+
+
+	mega_free_inquiry(inquiry, dma_handle, pdev);
+
+	*eof = 1;
+
+	return len;
+}
+
+
+/**
+ * proc_battery()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display information about the battery module on the controller.
+ */
+static int
+proc_battery(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t	*adapter = (adapter_t *)data;
+	dma_addr_t	dma_handle;
+	caddr_t		inquiry;
+	struct pci_dev	*pdev;
+	u8	battery_status = 0;
+	char	str[256];
+	int	len = 0;
+
+	pdev = adapter->ipdev;
+
+	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
+		*eof = 1;
+		return len;
+	}
+
+	if( mega_adapinq(adapter, dma_handle) != 0 ) {
+
+		len = sprintf(page, "Adapter inquiry failed.\n");
+
+		printk(KERN_WARNING "megaraid: inquiry failed.\n");
+
+		mega_free_inquiry(inquiry, dma_handle, pdev);
+
+		*eof = 1;
+
+		return len;
+	}
+
+	if( adapter->flag & BOARD_40LD ) {
+		battery_status = ((mega_inquiry3 *)inquiry)->battery_status;
+	}
+	else {
+		battery_status = ((mraid_ext_inquiry *)inquiry)->
+			raid_inq.adapter_info.battery_status;
+	}
+
+	/*
+	 * Decode the battery status
+	 */
+	sprintf(str, "Battery Status:[%d]", battery_status);
+
+	if(battery_status == MEGA_BATT_CHARGE_DONE)
+		strcat(str, " Charge Done");
+
+	if(battery_status & MEGA_BATT_MODULE_MISSING)
+		strcat(str, " Module Missing");
+	
+	if(battery_status & MEGA_BATT_LOW_VOLTAGE)
+		strcat(str, " Low Voltage");
+	
+	if(battery_status & MEGA_BATT_TEMP_HIGH)
+		strcat(str, " Temperature High");
+	
+	if(battery_status & MEGA_BATT_PACK_MISSING)
+		strcat(str, " Pack Missing");
+	
+	if(battery_status & MEGA_BATT_CHARGE_INPROG)
+		strcat(str, " Charge In-progress");
+	
+	if(battery_status & MEGA_BATT_CHARGE_FAIL)
+		strcat(str, " Charge Fail");
+	
+	if(battery_status & MEGA_BATT_CYCLES_EXCEEDED)
+		strcat(str, " Cycles Exceeded");
+
+	len = sprintf(page, "%s\n", str);
+
+
+	mega_free_inquiry(inquiry, dma_handle, pdev);
+
+	*eof = 1;
+
+	return len;
+}
+
+
+/**
+ * proc_pdrv_ch0()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display information about the physical drives on physical channel 0.
+ */
+static int
+proc_pdrv_ch0(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_pdrv(adapter, page, 0));
+}
+
+
+/**
+ * proc_pdrv_ch1()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display information about the physical drives on physical channel 1.
+ */
+static int
+proc_pdrv_ch1(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_pdrv(adapter, page, 1));
+}
+
+
+/**
+ * proc_pdrv_ch2()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display information about the physical drives on physical channel 2.
+ */
+static int
+proc_pdrv_ch2(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_pdrv(adapter, page, 2));
+}
+
+
+/**
+ * proc_pdrv_ch3()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display information about the physical drives on physical channel 3.
+ */
+static int
+proc_pdrv_ch3(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_pdrv(adapter, page, 3));
+}
+
+
+/**
+ * proc_pdrv()
+ * @page - buffer to write the data in
+ * @adapter - pointer to our soft state
+ *
+ * Display information about the physical drives.
+ */
+static int
+proc_pdrv(adapter_t *adapter, char *page, int channel)
+{
+	dma_addr_t	dma_handle;
+	char		*scsi_inq;
+	dma_addr_t	scsi_inq_dma_handle;
+	caddr_t		inquiry;
+	struct pci_dev	*pdev;
+	u8	*pdrv_state;
+	u8	state;
+	int	tgt;
+	int	max_channels;
+	int	len = 0;
+	char	str[80];
+	int	i;
+
+	pdev = adapter->ipdev;
+
+	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
+		return len;
+	}
+
+	if( mega_adapinq(adapter, dma_handle) != 0 ) {
+
+		len = sprintf(page, "Adapter inquiry failed.\n");
+
+		printk(KERN_WARNING "megaraid: inquiry failed.\n");
+
+		mega_free_inquiry(inquiry, dma_handle, pdev);
+
+		return len;
+	}
+
+
+	scsi_inq = pci_alloc_consistent(pdev, 256, &scsi_inq_dma_handle);
+
+	if( scsi_inq == NULL ) {
+		len = sprintf(page, "memory not available for scsi inq.\n");
+
+		mega_free_inquiry(inquiry, dma_handle, pdev);
+
+		return len;
+	}
+
+	if( adapter->flag & BOARD_40LD ) {
+		pdrv_state = ((mega_inquiry3 *)inquiry)->pdrv_state;
+	}
+	else {
+		pdrv_state = ((mraid_ext_inquiry *)inquiry)->
+			raid_inq.pdrv_info.pdrv_state;
+	}
+
+	max_channels = adapter->product_info.nchannels;
+
+	if( channel >= max_channels ) return 0;
+
+	for( tgt = 0; tgt <= MAX_TARGET; tgt++ ) {
+
+		i = channel*16 + tgt;
+
+		state = *(pdrv_state + i);
+
+		switch( state & 0x0F ) {
+
+		case PDRV_ONLINE:
+			sprintf(str,
+			"Channel:%2d Id:%2d State: Online",
+				channel, tgt);
+			break;
+
+		case PDRV_FAILED:
+			sprintf(str,
+			"Channel:%2d Id:%2d State: Failed",
+				channel, tgt);
+			break;
+
+		case PDRV_RBLD:
+			sprintf(str,
+			"Channel:%2d Id:%2d State: Rebuild",
+				channel, tgt);
+			break;
+
+		case PDRV_HOTSPARE:
+			sprintf(str,
+			"Channel:%2d Id:%2d State: Hot spare",
+				channel, tgt);
+			break;
+
+		default:
+			sprintf(str,
+			"Channel:%2d Id:%2d State: Un-configured",
+				channel, tgt);
+			break;
+
+		}
+
+		/*
+		 * This interface displays inquiries for disk drives
+		 * only. Inquries for logical drives and non-disk
+		 * devices are available through /proc/scsi/scsi
+		 */
+		memset(scsi_inq, 0, 256);
+		if( mega_internal_dev_inquiry(adapter, channel, tgt,
+				scsi_inq_dma_handle) ||
+				(scsi_inq[0] & 0x1F) != TYPE_DISK ) {
+			continue;
+		}
+
+		/*
+		 * Check for overflow. We print less than 240
+		 * characters for inquiry
+		 */
+		if( (len + 240) >= PAGE_SIZE ) break;
+
+		len += sprintf(page+len, "%s.\n", str);
+
+		len += mega_print_inquiry(page+len, scsi_inq);
+	}
+
+	pci_free_consistent(pdev, 256, scsi_inq, scsi_inq_dma_handle);
+
+	mega_free_inquiry(inquiry, dma_handle, pdev);
+
+	return len;
+}
+
+
+/*
+ * Display scsi inquiry
+ */
+static int
+mega_print_inquiry(char *page, char *scsi_inq)
+{
+	int	len = 0;
+	int	i;
+
+	len = sprintf(page, "  Vendor: ");
+	for( i = 8; i < 16; i++ ) {
+		len += sprintf(page+len, "%c", scsi_inq[i]);
+	}
+
+	len += sprintf(page+len, "  Model: ");
+
+	for( i = 16; i < 32; i++ ) {
+		len += sprintf(page+len, "%c", scsi_inq[i]);
+	}
+
+	len += sprintf(page+len, "  Rev: ");
+
+	for( i = 32; i < 36; i++ ) {
+		len += sprintf(page+len, "%c", scsi_inq[i]);
+	}
+
+	len += sprintf(page+len, "\n");
+
+	i = scsi_inq[0] & 0x1f;
+
+	len += sprintf(page+len, "  Type:   %s ",
+		i < MAX_SCSI_DEVICE_CODE ? scsi_device_types[i] :
+		   "Unknown          ");
+
+	len += sprintf(page+len,
+	"                 ANSI SCSI revision: %02x", scsi_inq[2] & 0x07);
+
+	if( (scsi_inq[2] & 0x07) == 1 && (scsi_inq[3] & 0x0f) == 1 )
+		len += sprintf(page+len, " CCS\n");
+	else
+		len += sprintf(page+len, "\n");
+
+	return len;
+}
+
+
+/**
+ * proc_rdrv_10()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_rdrv_10(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_rdrv(adapter, page, 0, 9));
+}
+
+
+/**
+ * proc_rdrv_20()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_rdrv_20(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_rdrv(adapter, page, 10, 19));
+}
+
+
+/**
+ * proc_rdrv_30()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_rdrv_30(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_rdrv(adapter, page, 20, 29));
+}
+
+
+/**
+ * proc_rdrv_40()
+ * @page - buffer to write the data in
+ * @start - where the actual data has been written in page
+ * @offset - same meaning as the read system call
+ * @count - same meaning as the read system call
+ * @eof - set if no more data needs to be returned
+ * @data - pointer to our soft state
+ *
+ * Display real time information about the logical drives 0 through 9.
+ */
+static int
+proc_rdrv_40(char *page, char **start, off_t offset, int count, int *eof,
+		void *data)
+{
+	adapter_t *adapter = (adapter_t *)data;
+
+	*eof = 1;
+
+	return (proc_rdrv(adapter, page, 30, 39));
+}
+
+
+/**
+ * proc_rdrv()
+ * @page - buffer to write the data in
+ * @adapter - pointer to our soft state
+ * @start - starting logical drive to display
+ * @end - ending logical drive to display
+ *
+ * We do not print the inquiry information since its already available through
+ * /proc/scsi/scsi interface
+ */
+static int
+proc_rdrv(adapter_t *adapter, char *page, int start, int end )
+{
+	dma_addr_t	dma_handle;
+	logdrv_param	*lparam;
+	megacmd_t	mc;
+	char		*disk_array;
+	dma_addr_t	disk_array_dma_handle;
+	caddr_t		inquiry;
+	struct pci_dev	*pdev;
+	u8	*rdrv_state;
+	int	num_ldrv;
+	u32	array_sz;
+	int	len = 0;
+	int	i;
+	u8	span8_flag = 1;
+
+	pdev = adapter->ipdev;
+
+	if( (inquiry = mega_allocate_inquiry(&dma_handle, pdev)) == NULL ) {
+		return len;
+	}
+
+	if( mega_adapinq(adapter, dma_handle) != 0 ) {
+
+		len = sprintf(page, "Adapter inquiry failed.\n");
+
+		printk(KERN_WARNING "megaraid: inquiry failed.\n");
+
+		mega_free_inquiry(inquiry, dma_handle, pdev);
+
+		return len;
+	}
+
+	memset(&mc, 0, sizeof(megacmd_t));
+
+	if( adapter->flag & BOARD_40LD ) {
+		
+		array_sz = sizeof(disk_array_40ld);
+
+		rdrv_state = ((mega_inquiry3 *)inquiry)->ldrv_state;
+
+		num_ldrv = ((mega_inquiry3 *)inquiry)->num_ldrv;
+	}
+	else {
+		/*
+		 * 'array_sz' is either the size of diskarray_span4_t or the
+		 * size of disk_array_span8_t. We use span8_t's size because
+		 * it is bigger of the two.
+		 */
+		array_sz = sizeof( diskarray_span8_t );
+
+		rdrv_state = ((mraid_ext_inquiry *)inquiry)->
+			raid_inq.logdrv_info.ldrv_state;
+
+		num_ldrv = ((mraid_ext_inquiry *)inquiry)->
+			raid_inq.logdrv_info.num_ldrv;
+	}
+
+	disk_array = pci_alloc_consistent(pdev, array_sz,
+			&disk_array_dma_handle);
+
+	if( disk_array == NULL ) {
+		len = sprintf(page, "memory not available.\n");
+
+		mega_free_inquiry(inquiry, dma_handle, pdev);
+
+		return len;
+	}
+
+	mc.xferaddr = (u32)disk_array_dma_handle;
+
+	if( adapter->flag & BOARD_40LD ) {
+		mc.cmd = FC_NEW_CONFIG;
+		mc.opcode = OP_DCMD_READ_CONFIG;
+
+		if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+
+			len = sprintf(page, "40LD read config failed.\n");
+
+			mega_free_inquiry(inquiry, dma_handle, pdev);
+
+			pci_free_consistent(pdev, array_sz, disk_array,
+					disk_array_dma_handle);
+
+			return len;
+		}
+
+	}
+	else {
+		/*
+		 * Try 8-Span "read config" command
+		 */
+		mc.cmd = NEW_READ_CONFIG_8LD;
+
+		if( mega_internal_command(adapter, LOCK_INT, &mc, NULL) ) {
+
+			/*
+			 * 8-Span command failed; try 4-Span command
+			 */
+			span8_flag = 0;
+			mc.cmd = READ_CONFIG_8LD;
+
+			if( mega_internal_command(adapter, LOCK_INT, &mc,
+						NULL) ){
+
+				len = sprintf(page,
+					"8LD read config failed.\n");
+
+				mega_free_inquiry(inquiry, dma_handle, pdev);
+
+				pci_free_consistent(pdev, array_sz,
+						disk_array,
+						disk_array_dma_handle);
+
+				return len;
+			}
+		}
+	}
+
+	for( i = start; i < ( (end+1 < num_ldrv) ? end+1 : num_ldrv ); i++ ) {
+
+		if( adapter->flag & BOARD_40LD ) {
+			lparam =
+			&((disk_array_40ld *)disk_array)->ldrv[i].lparam;
+		}
+		else {
+			if( span8_flag ) {
+				lparam = (logdrv_param*) &((diskarray_span8_t*)
+						(disk_array))->log_drv[i];
+			}
+			else {
+				lparam = (logdrv_param*) &((diskarray_span4_t*)
+						(disk_array))->log_drv[i];
+			}	
+		}
+
+		/*
+		 * Check for overflow. We print less than 240 characters for
+		 * information about each logical drive.
+		 */
+		if( (len + 240) >= PAGE_SIZE ) break;
+
+		len += sprintf(page+len, "Logical drive:%2d:, ", i);
+
+		switch( rdrv_state[i] & 0x0F ) {
+		case RDRV_OFFLINE:
+			len += sprintf(page+len, "state: offline");
+			break;
+
+		case RDRV_DEGRADED:
+			len += sprintf(page+len, "state: degraded");
+			break;
+
+		case RDRV_OPTIMAL:
+			len += sprintf(page+len, "state: optimal");
+			break;
+
+		case RDRV_DELETED:
+			len += sprintf(page+len, "state: deleted");
+			break;
+
+		default:
+			len += sprintf(page+len, "state: unknown");
+			break;
+		}
+
+		/*
+		 * Check if check consistency or initialization is going on
+		 * for this logical drive.
+		 */
+		if( (rdrv_state[i] & 0xF0) == 0x20 ) {
+			len += sprintf(page+len,
+					", check-consistency in progress");
+		}
+		else if( (rdrv_state[i] & 0xF0) == 0x10 ) {
+			len += sprintf(page+len,
+					", initialization in progress");
+		}
+		
+		len += sprintf(page+len, "\n");
+
+		len += sprintf(page+len, "Span depth:%3d, ",
+				lparam->span_depth);
+
+		len += sprintf(page+len, "RAID level:%3d, ",
+				lparam->level);
+
+		len += sprintf(page+len, "Stripe size:%3d, ",
+				lparam->stripe_sz ? lparam->stripe_sz/2: 128);
+
+		len += sprintf(page+len, "Row size:%3d\n",
+				lparam->row_size);
+
+
+		len += sprintf(page+len, "Read Policy: ");
+
+		switch(lparam->read_ahead) {
+
+		case NO_READ_AHEAD:
+			len += sprintf(page+len, "No read ahead, ");
+			break;
+
+		case READ_AHEAD:
+			len += sprintf(page+len, "Read ahead, ");
+			break;
+
+		case ADAP_READ_AHEAD:
+			len += sprintf(page+len, "Adaptive, ");
+			break;
+
+		}
+
+		len += sprintf(page+len, "Write Policy: ");
+
+		switch(lparam->write_mode) {
+
+		case WRMODE_WRITE_THRU:
+			len += sprintf(page+len, "Write thru, ");
+			break;
+
+		case WRMODE_WRITE_BACK:
+			len += sprintf(page+len, "Write back, ");
+			break;
+		}
+
+		len += sprintf(page+len, "Cache Policy: ");
+
+		switch(lparam->direct_io) {
+
+		case CACHED_IO:
+			len += sprintf(page+len, "Cached IO\n\n");
+			break;
+
+		case DIRECT_IO:
+			len += sprintf(page+len, "Direct IO\n\n");
+			break;
+		}
+	}
+
+	mega_free_inquiry(inquiry, dma_handle, pdev);
+
+	pci_free_consistent(pdev, array_sz, disk_array,
+			disk_array_dma_handle);
+
+	return len;
+}
+
+#endif
+
+
+/**
+ * megaraid_biosparam()
+ * @disk
+ * @dev
+ * @geom
+ *
+ * Return the disk geometry for a particular disk
+ * Input:
+ *	Disk *disk - Disk geometry
+ *	kdev_t dev - Device node
+ *	int *geom  - Returns geometry fields
+ *		geom[0] = heads
+ *		geom[1] = sectors
+ *		geom[2] = cylinders
+ */
+static int
+megaraid_biosparam(Disk *disk, kdev_t dev, int *geom)
+{
+	int heads, sectors, cylinders;
+	adapter_t *adapter;
+
+	/* Get pointer to host config structure */
+	adapter = (adapter_t *)disk->device->host->hostdata;
+
+	if (IS_RAID_CH(adapter, disk->device->channel)) {
+			/* Default heads (64) & sectors (32) */
+			heads = 64;
+			sectors = 32;
+			cylinders = disk->capacity / (heads * sectors);
+
+			/*
+			 * Handle extended translation size for logical drives
+			 * > 1Gb
+			 */
+			if (disk->capacity >= 0x200000) {
+				heads = 255;
+				sectors = 63;
+				cylinders = disk->capacity / (heads * sectors);
+			}
+
+			/* return result */
+			geom[0] = heads;
+			geom[1] = sectors;
+			geom[2] = cylinders;
+	}
+	else {
+		if( !mega_partsize(disk, dev, geom) )
+			return 0;
+
+		printk(KERN_WARNING
+		"megaraid: invalid partition on this disk on channel %d\n",
+				disk->device->channel);
+
+		/* Default heads (64) & sectors (32) */
+		heads = 64;
+		sectors = 32;
+		cylinders = disk->capacity / (heads * sectors);
+
+		/* Handle extended translation size for logical drives > 1Gb */
+		if (disk->capacity >= 0x200000) {
+			heads = 255;
+			sectors = 63;
+			cylinders = disk->capacity / (heads * sectors);
+		}
+
+		/* return result */
+		geom[0] = heads;
+		geom[1] = sectors;
+		geom[2] = cylinders;
+	}
+
+	return 0;
+}
+
+/*
+ * mega_partsize()
+ * @disk
+ * @geom
+ *
+ * Purpose : to determine the BIOS mapping used to create the partition
+ *	table, storing the results (cyls, hds, and secs) in geom
+ *
+ * Note:	Code is picked from scsicam.h
+ *
+ * Returns : -1 on failure, 0 on success.
+ */
+static int
+mega_partsize(Disk *disk, kdev_t dev, int *geom)
+{
+	struct buffer_head *bh;
+	struct partition *p, *largest = NULL;
+	int i, largest_cyl;
+	int heads, cyls, sectors;
+	int capacity = disk->capacity;
+
+	int ma = MAJOR(dev);
+	int mi = (MINOR(dev) & ~0xf);
+
+	int block = 1024; 
+
+	if (blksize_size[ma])
+		block = blksize_size[ma][mi];
+		
+	if (!(bh = bread(MKDEV(ma,mi), 0, block)))
+		return -1;
+
+	if (*(unsigned short *)(bh->b_data + 510) == 0xAA55 ) {
+
+		for (largest_cyl = -1,
+			p = (struct partition *)(0x1BE + bh->b_data), i = 0;
+			i < 4; ++i, ++p) {
+
+			if (!p->sys_ind) continue;
+
+			cyls = p->end_cyl + ((p->end_sector & 0xc0) << 2);
+
+			if (cyls >= largest_cyl) {
+				largest_cyl = cyls;
+				largest = p;
+			}
+		}
+	}
+
+	if (largest) {
+		heads = largest->end_head + 1;
+		sectors = largest->end_sector & 0x3f;
+
+		if (!heads || !sectors) {
+			brelse(bh);
+			return -1;
+		}
+
+		cyls = capacity/(heads * sectors);
+
+		geom[0] = heads;
+		geom[1] = sectors;
+		geom[2] = cyls;
+
+		brelse(bh);
+		return 0;
+	}
+
+	brelse(bh);
+	return -1;
+}
+
+
+/**
+ * megaraid_reboot_notify()
+ * @this - unused
+ * @code - shutdown code
+ * @unused - unused
+ *
+ * This routine will be called when the use has done a forced shutdown on the
+ * system. Flush the Adapter and disks cache.
+ */
+static int
+megaraid_reboot_notify (struct notifier_block *this, unsigned long code,
+		void *unused)
+{
+	adapter_t *adapter;
+	struct Scsi_Host *host;
+	u8 raw_mbox[16];
+	mbox_t *mbox;
+	int i;
+
+	/*
+	 * Flush the controller's cache irrespective of the codes coming down.
+	 * SYS_DOWN, SYS_HALT, SYS_RESTART, SYS_POWER_OFF
+	 */
+	for( i = 0; i < hba_count; i++ ) {
+		printk(KERN_INFO "megaraid: flushing adapter %d..", i);
+		host = hba_soft_state[i]->host;
+
+		adapter = (adapter_t *)host->hostdata;
+		mbox = (mbox_t *)raw_mbox;
+
+		/* Flush adapter cache */
+		memset(mbox, 0, 16);
+		raw_mbox[0] = FLUSH_ADAPTER;
+
+		irq_disable(adapter);
+		free_irq(adapter->host->irq, adapter);
+
+		/*
+		 * Issue a blocking (interrupts disabled) command to
+		 * the card
+		 */
+		issue_scb_block(adapter, raw_mbox);
+
+		/* Flush disks cache */
+		memset(mbox, 0, 16);
+		raw_mbox[0] = FLUSH_SYSTEM;
+
+		issue_scb_block(adapter, raw_mbox);
+
+		printk("Done.\n");
+
+		if( atomic_read(&adapter->pend_cmds) > 0 ) {
+			printk(KERN_WARNING "megaraid: pending commands!!\n");
+		}
+	}
+
+	/*
+	 * Have a delibrate delay to make sure all the caches are
+	 * actually flushed.
+	 */
+	printk(KERN_INFO "megaraid: cache flush delay:   ");
+	for( i = 9; i >= 0; i-- ) {
+		printk("\b\b\b[%d]", i);
+		mdelay(1000);
+	}
+	printk("\b\b\b[done]\n");
+	mdelay(1000);
+
+	return NOTIFY_DONE;
+}
+
+/**
+ * mega_init_scb()
+ * @adapter - pointer to our soft state
+ *
+ * Allocate memory for the various pointers in the scb structures:
+ * scatter-gather list pointer, passthru and extended passthru structure
+ * pointers.
+ */
+static int
+mega_init_scb(adapter_t *adapter)
+{
+	scb_t	*scb;
+	int	i;
+
+	for( i = 0; i < adapter->max_cmds; i++ ) {
+
+		scb = &adapter->scb_list[i];
+
+		scb->sgl64 = NULL;
+		scb->sgl = NULL;
+		scb->pthru = NULL;
+		scb->epthru = NULL;
+	}
+
+	for( i = 0; i < adapter->max_cmds; i++ ) {
+
+		scb = &adapter->scb_list[i];
+
+		scb->idx = i;
+
+		scb->sgl64 = pci_alloc_consistent(adapter->dev,
+				sizeof(mega_sgl64) * adapter->sglen,
+				&scb->sgl_dma_addr);
+
+		scb->sgl = (mega_sglist *)scb->sgl64;
+
+		if( !scb->sgl ) {
+			printk(KERN_WARNING "RAID: Can't allocate sglist.\n");
+			mega_free_sgl(adapter);
+			return -1;
+		}
+
+		scb->pthru = pci_alloc_consistent(adapter->dev,
+				sizeof(mega_passthru),
+				&scb->pthru_dma_addr);
+
+		if( !scb->pthru ) {
+			printk(KERN_WARNING "RAID: Can't allocate passthru.\n");
+			mega_free_sgl(adapter);
+			return -1;
+		}
+
+		scb->epthru = pci_alloc_consistent(adapter->dev,
+				sizeof(mega_ext_passthru),
+				&scb->epthru_dma_addr);
+
+		if( !scb->epthru ) {
+			printk(KERN_WARNING
+				"Can't allocate extended passthru.\n");
+			mega_free_sgl(adapter);
+			return -1;
+		}
+
+
+		scb->dma_type = MEGA_DMA_TYPE_NONE;
+
+		/*
+		 * Link to free list
+		 * lock not required since we are loading the driver, so no
+		 * commands possible right now.
+		 */
+		scb->state = SCB_FREE;
+		scb->cmd = NULL;
+		list_add(&scb->list, &adapter->free_list);
+	}
+
+	return 0;
+}
+
+
+/**
+ * megadev_open()
+ * @inode - unused
+ * @filep - unused
+ *
+ * Routines for the character/ioctl interface to the driver. Find out if this
+ * is a valid open. If yes, increment the module use count so that it cannot
+ * be unloaded.
+ */
+static int
+megadev_open (struct inode *inode, struct file *filep)
+{
+	/*
+	 * Only allow superuser to access private ioctl interface
+	 */
+	if( !capable(CAP_SYS_ADMIN) ) return -EACCES;
+
+	MOD_INC_USE_COUNT;
+	return 0;
+}
+
+
+/**
+ * megadev_ioctl()
+ * @inode - Our device inode
+ * @filep - unused
+ * @cmd - ioctl command
+ * @arg - user buffer
+ *
+ * ioctl entry point for our private ioctl interface. We move the data in from
+ * the user space, prepare the command (if necessary, convert the old MIMD
+ * ioctl to new ioctl command), and issue a synchronous command to the
+ * controller.
+ */
+static int
+megadev_ioctl(struct inode *inode, struct file *filep, unsigned int cmd,
+		unsigned long arg)
+{
+	adapter_t	*adapter;
+	nitioctl_t	uioc;
+	int		adapno;
+	int		rval;
+	mega_passthru	*upthru;	/* user address for passthru */
+	mega_passthru	*pthru;		/* copy user passthru here */
+	dma_addr_t	pthru_dma_hndl;
+	void		*data = NULL;	/* data to be transferred */
+	dma_addr_t	data_dma_hndl;	/* dma handle for data xfer area */
+	megacmd_t	mc;
+	megastat_t	*ustats;
+	int		num_ldrv;
+	u32		uxferaddr = 0;
+	struct pci_dev	*pdev;
+
+	ustats = NULL; /* avoid compilation warnings */
+	num_ldrv = 0;
+
+	/*
+	 * Make sure only USCSICMD are issued through this interface.
+	 * MIMD application would still fire different command.
+	 */
+	if( (_IOC_TYPE(cmd) != MEGAIOC_MAGIC) && (cmd != USCSICMD) ) {
+		return -EINVAL;
+	}
+
+	/*
+	 * Check and convert a possible MIMD command to NIT command.
+	 * mega_m_to_n() copies the data from the user space, so we do not
+	 * have to do it here.
+	 * NOTE: We will need some user address to copyout the data, therefore
+	 * the inteface layer will also provide us with the required user
+	 * addresses.
+	 */
+	memset(&uioc, 0, sizeof(nitioctl_t));
+	if( (rval = mega_m_to_n( (void *)arg, &uioc)) != 0 )
+		return rval;
+
+
+	switch( uioc.opcode ) {
+
+	case GET_DRIVER_VER:
+		if( put_user(driver_ver, (u32 *)uioc.uioc_uaddr) )
+			return (-EFAULT);
+
+		break;
+
+	case GET_N_ADAP:
+		if( put_user(hba_count, (u32 *)uioc.uioc_uaddr) )
+			return (-EFAULT);
+
+		/*
+		 * Shucks. MIMD interface returns a positive value for number
+		 * of adapters. TODO: Change it to return 0 when there is no
+		 * applicatio using mimd interface.
+		 */
+		return hba_count;
+
+	case GET_ADAP_INFO:
+
+		/*
+		 * Which adapter
+		 */
+		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
+			return (-ENODEV);
+
+		if( copy_to_user(uioc.uioc_uaddr, mcontroller+adapno,
+				sizeof(struct mcontroller)) )
+			return (-EFAULT);
+		break;
+
+#if MEGA_HAVE_STATS
+
+	case GET_STATS:
+		/*
+		 * Which adapter
+		 */
+		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
+			return (-ENODEV);
+
+		adapter = hba_soft_state[adapno];
+
+		ustats = (megastat_t *)uioc.uioc_uaddr;
+
+		if( copy_from_user(&num_ldrv, &ustats->num_ldrv, sizeof(int)) )
+			return (-EFAULT);
+
+		/*
+		 * Check for the validity of the logical drive number
+		 */
+		if( num_ldrv >= MAX_LOGICAL_DRIVES_40LD ) return -EINVAL;
+
+		if( copy_to_user(ustats->nreads, adapter->nreads,
+					num_ldrv*sizeof(u32)) )
+			return -EFAULT;
+
+		if( copy_to_user(ustats->nreadblocks, adapter->nreadblocks,
+					num_ldrv*sizeof(u32)) )
+			return -EFAULT;
+
+		if( copy_to_user(ustats->nwrites, adapter->nwrites,
+					num_ldrv*sizeof(u32)) )
+			return -EFAULT;
+
+		if( copy_to_user(ustats->nwriteblocks, adapter->nwriteblocks,
+					num_ldrv*sizeof(u32)) )
+			return -EFAULT;
+
+		if( copy_to_user(ustats->rd_errors, adapter->rd_errors,
+					num_ldrv*sizeof(u32)) )
+			return -EFAULT;
+
+		if( copy_to_user(ustats->wr_errors, adapter->wr_errors,
+					num_ldrv*sizeof(u32)) )
+			return -EFAULT;
+
+		return 0;
+
+#endif
+	case MBOX_CMD:
+
+		/*
+		 * Which adapter
+		 */
+		if( (adapno = GETADAP(uioc.adapno)) >= hba_count )
+			return (-ENODEV);
+
+		adapter = hba_soft_state[adapno];
+
+		/*
+		 * Deletion of logical drive is a special case. The adapter
+		 * should be quiescent before this command is issued.
+		 */
+		if( uioc.uioc_rmbox[0] == FC_DEL_LOGDRV &&
+				uioc.uioc_rmbox[2] == OP_DEL_LOGDRV ) {
+
+			/*
+			 * Do we support this feature
+			 */
+			if( !adapter->support_random_del ) {
+				printk(KERN_WARNING "megaraid: logdrv ");
+				printk("delete on non-supporting F/W.\n");
+
+				return (-EINVAL);
+			}
+
+			rval = mega_del_logdrv( adapter, uioc.uioc_rmbox[3] );
+
+			if( rval == 0 ) {
+				memset(&mc, 0, sizeof(megacmd_t));
+
+				mc.status = rval;
+
+				rval = mega_n_to_m((void *)arg, &mc);
+			}
+
+			return rval;
+		}
+		/*
+		 * This interface only support the regular passthru commands.
+		 * Reject extended passthru and 64-bit passthru
+		 */
+		if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU64 ||
+			uioc.uioc_rmbox[0] == MEGA_MBOXCMD_EXTPTHRU ) {
+
+			printk(KERN_WARNING "megaraid: rejected passthru.\n");
+
+			return (-EINVAL);
+		}
+
+		/*
+		 * For all internal commands, the buffer must be allocated in
+		 * <4GB address range
+		 */
+		pdev = adapter->ipdev;
+
+		/* Is it a passthru command or a DCMD */
+		if( uioc.uioc_rmbox[0] == MEGA_MBOXCMD_PASSTHRU ) {
+			/* Passthru commands */
+
+			pthru = pci_alloc_consistent(pdev,
+					sizeof(mega_passthru),
+					&pthru_dma_hndl);
+
+			if( pthru == NULL ) {
+				return (-ENOMEM);
+			}
+
+			/*
+			 * The user passthru structure
+			 */
+			upthru = (mega_passthru *)MBOX(uioc)->xferaddr;
+
+			/*
+			 * Copy in the user passthru here.
+			 */
+			if( copy_from_user(pthru, (char *)upthru,
+						sizeof(mega_passthru)) ) {
+
+				pci_free_consistent(pdev,
+						sizeof(mega_passthru), pthru,
+						pthru_dma_hndl);
+
+				return (-EFAULT);
+			}
+
+			/*
+			 * Is there a data transfer
+			 */
+			if( pthru->dataxferlen ) {
+				data = pci_alloc_consistent(pdev,
+						pthru->dataxferlen,
+						&data_dma_hndl);
+
+				if( data == NULL ) {
+					pci_free_consistent(pdev,
+							sizeof(mega_passthru),
+							pthru,
+							pthru_dma_hndl);
+
+					return (-ENOMEM);
+				}
+
+				/*
+				 * Save the user address and point the kernel
+				 * address at just allocated memory
+				 */
+				uxferaddr = pthru->dataxferaddr;
+				pthru->dataxferaddr = data_dma_hndl;
+			}
+
+
+			/*
+			 * Is data coming down-stream
+			 */
+			if( pthru->dataxferlen && (uioc.flags & UIOC_WR) ) {
+				/*
+				 * Get the user data
+				 */
+				if( copy_from_user(data, (char *)uxferaddr,
+							pthru->dataxferlen) ) {
+					rval = (-EFAULT);
+					goto freemem_and_return;
+				}
+			}
+
+			memset(&mc, 0, sizeof(megacmd_t));
+
+			mc.cmd = MEGA_MBOXCMD_PASSTHRU;
+			mc.xferaddr = (u32)pthru_dma_hndl;
+
+			/*
+			 * Issue the command
+			 */
+			mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+
+			rval = mega_n_to_m((void *)arg, &mc);
+
+			if( rval ) goto freemem_and_return;
+
+
+			/*
+			 * Is data going up-stream
+			 */
+			if( pthru->dataxferlen && (uioc.flags & UIOC_RD) ) {
+				if( copy_to_user((char *)uxferaddr, data,
+							pthru->dataxferlen) ) {
+					rval = (-EFAULT);
+				}
+			}
+
+			/*
+			 * Send the request sense data also, irrespective of
+			 * whether the user has asked for it or not.
+			 */
+			copy_to_user(upthru->reqsensearea,
+					pthru->reqsensearea, 14);
+
+freemem_and_return:
+			if( pthru->dataxferlen ) {
+				pci_free_consistent(pdev,
+						pthru->dataxferlen, data,
+						data_dma_hndl);
+			}
+
+			pci_free_consistent(pdev, sizeof(mega_passthru),
+					pthru, pthru_dma_hndl);
+
+			return rval;
+		}
+		else {
+			/* DCMD commands */
+
+			/*
+			 * Is there a data transfer
+			 */
+			if( uioc.xferlen ) {
+				data = pci_alloc_consistent(pdev,
+						uioc.xferlen, &data_dma_hndl);
+
+				if( data == NULL ) {
+					return (-ENOMEM);
+				}
+
+				uxferaddr = MBOX(uioc)->xferaddr;
+			}
+
+			/*
+			 * Is data coming down-stream
+			 */
+			if( uioc.xferlen && (uioc.flags & UIOC_WR) ) {
+				/*
+				 * Get the user data
+				 */
+				if( copy_from_user(data, (char *)uxferaddr,
+							uioc.xferlen) ) {
+
+					pci_free_consistent(pdev,
+							uioc.xferlen,
+							data, data_dma_hndl);
+
+					return (-EFAULT);
+				}
+			}
+
+			memcpy(&mc, MBOX(uioc), sizeof(megacmd_t));
+
+			mc.xferaddr = (u32)data_dma_hndl;
+
+			/*
+			 * Issue the command
+			 */
+			mega_internal_command(adapter, LOCK_INT, &mc, NULL);
+
+			rval = mega_n_to_m((void *)arg, &mc);
+
+			if( rval ) {
+				if( uioc.xferlen ) {
+					pci_free_consistent(pdev,
+							uioc.xferlen, data,
+							data_dma_hndl);
+				}
+
+				return rval;
+			}
+
+			/*
+			 * Is data going up-stream
+			 */
+			if( uioc.xferlen && (uioc.flags & UIOC_RD) ) {
+				if( copy_to_user((char *)uxferaddr, data,
+							uioc.xferlen) ) {
+
+					rval = (-EFAULT);
+				}
+			}
+
+			if( uioc.xferlen ) {
+				pci_free_consistent(pdev,
+						uioc.xferlen, data,
+						data_dma_hndl);
+			}
+
+			return rval;
+		}
+
+	default:
+		return (-EINVAL);
+	}
+
+	return 0;
+}
+
+/**
+ * mega_m_to_n()
+ * @arg - user address
+ * @uioc - new ioctl structure
+ *
+ * A thin layer to convert older mimd interface ioctl structure to NIT ioctl
+ * structure
+ *
+ * Converts the older mimd ioctl structure to newer NIT structure
+ */
+static int
+mega_m_to_n(void *arg, nitioctl_t *uioc)
+{
+	struct uioctl_t	uioc_mimd;
+	char	signature[8] = {0};
+	u8	opcode;
+	u8	subopcode;
+
+
+	/*
+	 * check is the application conforms to NIT. We do not have to do much
+	 * in that case.
+	 * We exploit the fact that the signature is stored in the very
+	 * begining of the structure.
+	 */
+
+	if( copy_from_user(signature, (char *)arg, 7) )
+		return (-EFAULT);
+
+	if( memcmp(signature, "MEGANIT", 7) == 0 ) {
+
+		/*
+		 * NOTE NOTE: The nit ioctl is still under flux because of
+		 * change of mailbox definition, in HPE. No applications yet
+		 * use this interface and let's not have applications use this
+		 * interface till the new specifitions are in place.
+		 */
+		return -EINVAL;
+#if 0
+		if( copy_from_user(uioc, (char *)arg, sizeof(nitioctl_t)) )
+			return (-EFAULT);
+		return 0;
+#endif
+	}
+
+	/*
+	 * Else assume we have mimd uioctl_t as arg. Convert to nitioctl_t
+	 *
+	 * Get the user ioctl structure
+	 */
+	if( copy_from_user(&uioc_mimd, (char *)arg, sizeof(struct uioctl_t)) )
+		return (-EFAULT);
+
+
+	/*
+	 * Get the opcode and subopcode for the commands
+	 */
+	opcode = uioc_mimd.ui.fcs.opcode;
+	subopcode = uioc_mimd.ui.fcs.subopcode;
+
+	switch (opcode) {
+	case 0x82:
+
+		switch (subopcode) {
+
+		case MEGAIOC_QDRVRVER:	/* Query driver version */
+			uioc->opcode = GET_DRIVER_VER;
+			uioc->uioc_uaddr = uioc_mimd.data;
+			break;
+
+		case MEGAIOC_QNADAP:	/* Get # of adapters */
+			uioc->opcode = GET_N_ADAP;
+			uioc->uioc_uaddr = uioc_mimd.data;
+			break;
+
+		case MEGAIOC_QADAPINFO:	/* Get adapter information */
+			uioc->opcode = GET_ADAP_INFO;
+			uioc->adapno = uioc_mimd.ui.fcs.adapno;
+			uioc->uioc_uaddr = uioc_mimd.data;
+			break;
+
+		default:
+			return(-EINVAL);
+		}
+
+		break;
+
+
+	case 0x81:
+
+		uioc->opcode = MBOX_CMD;
+		uioc->adapno = uioc_mimd.ui.fcs.adapno;
+
+		memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
+
+		uioc->xferlen = uioc_mimd.ui.fcs.length;
+
+		if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
+		if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
+
+		break;
+
+	case 0x80:
+
+		uioc->opcode = MBOX_CMD;
+		uioc->adapno = uioc_mimd.ui.fcs.adapno;
+
+		memcpy(uioc->uioc_rmbox, uioc_mimd.mbox, 18);
+
+		/*
+		 * Choose the xferlen bigger of input and output data
+		 */
+		uioc->xferlen = uioc_mimd.outlen > uioc_mimd.inlen ?
+			uioc_mimd.outlen : uioc_mimd.inlen;
+
+		if( uioc_mimd.outlen ) uioc->flags = UIOC_RD;
+		if( uioc_mimd.inlen ) uioc->flags |= UIOC_WR;
+
+		break;
+
+	default:
+		return (-EINVAL);
+
+	}
+
+	return 0;
+}
+
+/*
+ * mega_n_to_m()
+ * @arg - user address
+ * @mc - mailbox command
+ *
+ * Updates the status information to the application, depending on application
+ * conforms to older mimd ioctl interface or newer NIT ioctl interface
+ */
+static int
+mega_n_to_m(void *arg, megacmd_t *mc)
+{
+	nitioctl_t	*uiocp;
+	megacmd_t	*umc;
+	megacmd_t	kmc;
+	mega_passthru	*upthru;
+	struct uioctl_t	*uioc_mimd;
+	char	signature[8] = {0};
+
+	/*
+	 * check is the application conforms to NIT.
+	 */
+	if( copy_from_user(signature, (char *)arg, 7) )
+		return -EFAULT;
+
+	if( memcmp(signature, "MEGANIT", 7) == 0 ) {
+
+		uiocp = (nitioctl_t *)arg;
+
+		if( put_user(mc->status, (u8 *)&MBOX_P(uiocp)->status) )
+			return (-EFAULT);
+
+		if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
+
+			umc = MBOX_P(uiocp);
+
+			upthru = (mega_passthru *)umc->xferaddr;
+
+			if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
+				return (-EFAULT);
+		}
+	}
+	else {
+		uioc_mimd = (struct uioctl_t *)arg;
+
+		if( put_user(mc->status, (u8 *)&uioc_mimd->mbox[17]) )
+			return (-EFAULT);
+
+		if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
+
+			umc = (megacmd_t *)uioc_mimd->mbox;
+			if (copy_from_user(&kmc, umc, sizeof(megacmd_t)))
+				return -EFAULT;
+
+			upthru = (mega_passthru *)kmc.xferaddr;
+
+			if( put_user(mc->status, (u8 *)&upthru->scsistatus) )
+				return (-EFAULT);
+		}
+	}
+
+	return 0;
+}
+
+
+static int
+megadev_close (struct inode *inode, struct file *filep)
+{
+	MOD_DEC_USE_COUNT;
+	return 0;
+}
+
+
+/*
+ * MEGARAID 'FW' commands.
+ */
+
+/**
+ * mega_is_bios_enabled()
+ * @adapter - pointer to our soft state
+ *
+ * issue command to find out if the BIOS is enabled for this controller
+ */
+static int
+mega_is_bios_enabled(adapter_t *adapter)
+{
+	unsigned char	raw_mbox[16];
+	mbox_t	*mbox;
+	int	ret;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, 16);
+
+	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
+
+	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+
+	raw_mbox[0] = IS_BIOS_ENABLED;
+	raw_mbox[2] = GET_BIOS;
+
+
+	ret = issue_scb_block(adapter, raw_mbox);
+
+	return *(char *)adapter->mega_buffer;
+}
+
+
+/**
+ * mega_enum_raid_scsi()
+ * @adapter - pointer to our soft state
+ *
+ * Find out what channels are RAID/SCSI. This information is used to
+ * differentiate the virtual channels and physical channels and to support
+ * ROMB feature and non-disk devices.
+ */
+static void
+mega_enum_raid_scsi(adapter_t *adapter)
+{
+	unsigned char raw_mbox[16];
+	mbox_t *mbox;
+	int i;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, 16);
+
+	/*
+	 * issue command to find out what channels are raid/scsi
+	 */
+	raw_mbox[0] = CHNL_CLASS;
+	raw_mbox[2] = GET_CHNL_CLASS;
+
+	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
+
+	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+
+	/*
+	 * Non-ROMB firware fail this command, so all channels
+	 * must be shown RAID
+	 */
+	adapter->mega_ch_class = 0xFF;
+
+	if(!issue_scb_block(adapter, raw_mbox)) {
+		adapter->mega_ch_class = *((char *)adapter->mega_buffer);
+
+	}
+
+	for( i = 0; i < adapter->product_info.nchannels; i++ ) { 
+		if( (adapter->mega_ch_class >> i) & 0x01 ) {
+			printk(KERN_INFO "megaraid: channel[%d] is raid.\n",
+					i);
+		}
+		else {
+			printk(KERN_INFO "megaraid: channel[%d] is scsi.\n",
+					i);
+		}
+	}
+
+	return;
+}
+
+
+/**
+ * mega_get_boot_drv()
+ * @adapter - pointer to our soft state
+ *
+ * Find out which device is the boot device. Note, any logical drive or any
+ * phyical device (e.g., a CDROM) can be designated as a boot device.
+ */
+static void
+mega_get_boot_drv(adapter_t *adapter)
+{
+	struct private_bios_data	*prv_bios_data;
+	unsigned char	raw_mbox[16];
+	mbox_t	*mbox;
+	u16	cksum = 0;
+	u8	*cksum_p;
+	u8	boot_pdrv;
+	int	i;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, sizeof(raw_mbox));
+
+	raw_mbox[0] = BIOS_PVT_DATA;
+	raw_mbox[2] = GET_BIOS_PVT_DATA;
+
+	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
+
+	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+
+	adapter->boot_ldrv_enabled = 0;
+	adapter->boot_ldrv = 0;
+
+	adapter->boot_pdrv_enabled = 0;
+	adapter->boot_pdrv_ch = 0;
+	adapter->boot_pdrv_tgt = 0;
+
+	if(issue_scb_block(adapter, raw_mbox) == 0) {
+		prv_bios_data =
+			(struct private_bios_data *)adapter->mega_buffer;
+
+		cksum = 0;
+		cksum_p = (char *)prv_bios_data;
+		for (i = 0; i < 14; i++ ) {
+			cksum += (u16)(*cksum_p++);
+		}
+
+		if (prv_bios_data->cksum == (u16)(0-cksum) ) {
+
+			/*
+			 * If MSB is set, a physical drive is set as boot
+			 * device
+			 */
+			if( prv_bios_data->boot_drv & 0x80 ) {
+				adapter->boot_pdrv_enabled = 1;
+				boot_pdrv = prv_bios_data->boot_drv & 0x7F;
+				adapter->boot_pdrv_ch = boot_pdrv / 16;
+				adapter->boot_pdrv_tgt = boot_pdrv % 16;
+			}
+			else {
+				adapter->boot_ldrv_enabled = 1;
+				adapter->boot_ldrv = prv_bios_data->boot_drv;
+			}
+		}
+	}
+
+}
+
+/**
+ * mega_support_random_del()
+ * @adapter - pointer to our soft state
+ *
+ * Find out if this controller supports random deletion and addition of
+ * logical drives
+ */
+static int
+mega_support_random_del(adapter_t *adapter)
+{
+	unsigned char raw_mbox[16];
+	mbox_t *mbox;
+	int rval;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, 16);
+
+	/*
+	 * issue command
+	 */
+	raw_mbox[0] = FC_DEL_LOGDRV;
+	raw_mbox[2] = OP_SUP_DEL_LOGDRV;
+
+	rval = issue_scb_block(adapter, raw_mbox);
+
+	return !rval;
+}
+
+
+/**
+ * mega_support_ext_cdb()
+ * @adapter - pointer to our soft state
+ *
+ * Find out if this firmware support cdblen > 10
+ */
+static int
+mega_support_ext_cdb(adapter_t *adapter)
+{
+	unsigned char raw_mbox[16];
+	mbox_t *mbox;
+	int rval;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, 16);
+	/*
+	 * issue command to find out if controller supports extended CDBs.
+	 */
+	raw_mbox[0] = 0xA4;
+	raw_mbox[2] = 0x16;
+
+	rval = issue_scb_block(adapter, raw_mbox);
+
+	return !rval;
+}
+
+
+/**
+ * mega_del_logdrv()
+ * @adapter - pointer to our soft state
+ * @logdrv - logical drive to be deleted
+ *
+ * Delete the specified logical drive. It is the responsibility of the user
+ * app to let the OS know about this operation.
+ */
+static int
+mega_del_logdrv(adapter_t *adapter, int logdrv)
+{
+	DECLARE_WAIT_QUEUE_HEAD(wq);
+	unsigned long flags;
+	scb_t *scb;
+	int rval;
+
+	ASSERT( !spin_is_locked(adapter->host_lock) );
+
+	/*
+	 * Stop sending commands to the controller, queue them internally.
+	 * When deletion is complete, ISR will flush the queue.
+	 */
+	atomic_set(&adapter->quiescent, 1);
+
+	/*
+	 * Wait till all the issued commands are complete and there are no
+	 * commands in the pending queue
+	 */
+	while( atomic_read(&adapter->pend_cmds) > 0 ) {
+
+		sleep_on_timeout( &wq, 1*HZ );	/* sleep for 1s */
+	}
+
+	rval = mega_do_del_logdrv(adapter, logdrv);
+
+
+	spin_lock_irqsave(adapter->host_lock, flags);
+
+	/*
+	 * If delete operation was successful, add 0x80 to the logical drive
+	 * ids for commands in the pending queue.
+	 */
+	if (adapter->read_ldidmap) {
+		struct list_head *pos;
+		list_for_each(pos, &adapter->pending_list) {
+			scb = list_entry(pos, scb_t, list);
+			if (((mbox_t *)scb->raw_mbox)->logdrv < 0x80 )
+				((mbox_t *)scb->raw_mbox)->logdrv += 0x80 ;
+		}
+	}
+
+	atomic_set(&adapter->quiescent, 0);
+
+	mega_runpendq(adapter);
+
+	spin_unlock_irqrestore(adapter->host_lock, flags);
+
+	return rval;
+}
+
+
+static int
+mega_do_del_logdrv(adapter_t *adapter, int logdrv)
+{
+	int	rval;
+	u8	raw_mbox[16];
+
+	raw_mbox[0] = FC_DEL_LOGDRV;
+	raw_mbox[2] = OP_DEL_LOGDRV;
+	raw_mbox[3] = logdrv;
+
+	/* Issue a blocking command to the card */
+	rval = issue_scb_block(adapter, raw_mbox);
+
+	/* log this event */
+	if(rval) {
+		printk(KERN_WARNING "megaraid: Delete LD-%d failed.", logdrv);
+		return rval;
+	}
+
+	/*
+	 * After deleting first logical drive, the logical drives must be
+	 * addressed by adding 0x80 to the logical drive id.
+	 */
+	adapter->read_ldidmap = 1;
+
+	return rval;
+}
+
+
+/**
+ * mega_get_max_sgl()
+ * @adapter - pointer to our soft state
+ *
+ * Find out the maximum number of scatter-gather elements supported by this
+ * version of the firmware
+ */
+static void
+mega_get_max_sgl(adapter_t *adapter)
+{
+	unsigned char	raw_mbox[16];
+	mbox_t	*mbox;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, sizeof(raw_mbox));
+
+	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
+
+	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+
+	raw_mbox[0] = MAIN_MISC_OPCODE;
+	raw_mbox[2] = GET_MAX_SG_SUPPORT;
+
+
+	if( issue_scb_block(adapter, raw_mbox) ) {
+		/*
+		 * f/w does not support this command. Choose the default value
+		 */
+		adapter->sglen = MIN_SGLIST;
+	}
+	else {
+		adapter->sglen = *((char *)adapter->mega_buffer);
+		
+		/*
+		 * Make sure this is not more than the resources we are
+		 * planning to allocate
+		 */
+		if ( adapter->sglen > MAX_SGLIST )
+			adapter->sglen = MAX_SGLIST;
+	}
+
+	return;
+}
+
+
+/**
+ * mega_support_cluster()
+ * @adapter - pointer to our soft state
+ *
+ * Find out if this firmware support cluster calls.
+ */
+static int
+mega_support_cluster(adapter_t *adapter)
+{
+	unsigned char	raw_mbox[16];
+	mbox_t	*mbox;
+
+	mbox = (mbox_t *)raw_mbox;
+
+	memset(mbox, 0, sizeof(raw_mbox));
+
+	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
+
+	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+
+	/*
+	 * Try to get the initiator id. This command will succeed iff the
+	 * clustering is available on this HBA.
+	 */
+	raw_mbox[0] = MEGA_GET_TARGET_ID;
+
+	if( issue_scb_block(adapter, raw_mbox) == 0 ) {
+
+		/*
+		 * Cluster support available. Get the initiator target id.
+		 * Tell our id to mid-layer too.
+		 */
+		adapter->this_id = *(u32 *)adapter->mega_buffer;
+		adapter->host->this_id = adapter->this_id;
+
+		return 1;
+	}
+
+	return 0;
+}
+
+
+
+/**
+ * mega_get_ldrv_num()
+ * @adapter - pointer to our soft state
+ * @cmd - scsi mid layer command
+ * @channel - channel on the controller
+ *
+ * Calculate the logical drive number based on the information in scsi command
+ * and the channel number.
+ */
+static inline int
+mega_get_ldrv_num(adapter_t *adapter, Scsi_Cmnd *cmd, int channel)
+{
+	int		tgt;
+	int		ldrv_num;
+
+	tgt = cmd->target;
+	
+	if ( tgt > adapter->this_id )
+		tgt--;	/* we do not get inquires for initiator id */
+
+	ldrv_num = (channel * 15) + tgt;
+
+
+	/*
+	 * If we have a logical drive with boot enabled, project it first
+	 */
+	if( adapter->boot_ldrv_enabled ) {
+		if( ldrv_num == 0 ) {
+			ldrv_num = adapter->boot_ldrv;
+		}
+		else {
+			if( ldrv_num <= adapter->boot_ldrv ) {
+				ldrv_num--;
+			}
+		}
+	}
+
+	/*
+	 * If "delete logical drive" feature is enabled on this controller.
+	 * Do only if at least one delete logical drive operation was done.
+	 *
+	 * Also, after logical drive deletion, instead of logical drive number,
+	 * the value returned should be 0x80+logical drive id.
+	 *
+	 * These is valid only for IO commands.
+	 */
+
+	if (adapter->support_random_del && adapter->read_ldidmap )
+		switch (cmd->cmnd[0]) {
+		case READ_6:	/* fall through */
+		case WRITE_6:	/* fall through */
+		case READ_10:	/* fall through */
+		case WRITE_10:
+			ldrv_num += 0x80;
+		}
+
+	return ldrv_num;
+}
+
+
+/**
+ * mega_reorder_hosts()
+ *
+ * Hack: reorder the scsi hosts in mid-layer so that the controller with the
+ * boot device on it appears first in the list.
+ */
+static void
+mega_reorder_hosts(void)
+{
+	struct Scsi_Host *shpnt;
+	struct Scsi_Host *shone;
+	struct Scsi_Host *shtwo;
+	adapter_t *boot_host;
+	int i;
+
+	/*
+	 * Find the (first) host which has it's BIOS enabled
+	 */
+	boot_host = NULL;
+	for (i = 0; i < MAX_CONTROLLERS; i++) {
+		if (mega_hbas[i].is_bios_enabled) {
+			boot_host = mega_hbas[i].hostdata_addr;
+			break;
+		}
+	}
+
+	if (!boot_host) {
+		printk(KERN_NOTICE "megaraid: no BIOS enabled.\n");
+		return;
+	}
+
+	/*
+	 * Traverse through the list of SCSI hosts for our HBA locations
+	 */
+	shone = shtwo = NULL;
+	for (shpnt = scsi_hostlist; shpnt; shpnt = shpnt->next) {
+		/* Is it one of ours? */
+		for (i = 0; i < MAX_CONTROLLERS; i++) {
+			if ((adapter_t *) shpnt->hostdata ==
+				mega_hbas[i].hostdata_addr) {
+				/* Does this one has BIOS enabled */
+				if (mega_hbas[i].hostdata_addr == boot_host) {
+
+					/* Are we first */
+					if (!shtwo)	/* Yes! */
+						return;
+					else	/* :-( */
+						shone = shpnt;
+				} else {
+					if (!shtwo) {
+						/* were we here before? xchng
+						 * first */
+						shtwo = shpnt;
+					}
+				}
+				break;
+			}
+		}
+		/*
+		 * Have we got the boot host and one which does not have the
+		 * bios enabled.
+		 */
+		if (shone && shtwo)
+			break;
+	}
+	if (shone && shtwo) {
+		mega_swap_hosts (shone, shtwo);
+	}
+
+	return;
+}
+
+
+static void
+mega_swap_hosts (struct Scsi_Host *shone, struct Scsi_Host *shtwo)
+{
+	struct Scsi_Host *prevtoshtwo;
+	struct Scsi_Host *prevtoshone;
+	struct Scsi_Host *save = NULL;
+
+	/* Are these two nodes adjacent */
+	if (shtwo->next == shone) {
+
+		if (shtwo == scsi_hostlist && !shone->next) {
+
+			/* just two nodes */
+			scsi_hostlist = shone;
+			shone->next = shtwo;
+			shtwo->next = NULL;
+		} else if (shtwo == scsi_hostlist) {
+			/* first two nodes of the list */
+
+			scsi_hostlist = shone;
+			shtwo->next = shone->next;
+			scsi_hostlist->next = shtwo;
+		} else if (!shone->next) {
+			/* last two nodes of the list */
+
+			prevtoshtwo = scsi_hostlist;
+
+			while (prevtoshtwo->next != shtwo)
+				prevtoshtwo = prevtoshtwo->next;
+
+			prevtoshtwo->next = shone;
+			shone->next = shtwo;
+			shtwo->next = NULL;
+		} else {
+			prevtoshtwo = scsi_hostlist;
+
+			while (prevtoshtwo->next != shtwo)
+				prevtoshtwo = prevtoshtwo->next;
+
+			prevtoshtwo->next = shone;
+			shtwo->next = shone->next;
+			shone->next = shtwo;
+		}
+
+	} else if (shtwo == scsi_hostlist && !shone->next) {
+		/* shtwo at head, shone at tail, not adjacent */
+
+		prevtoshone = scsi_hostlist;
+
+		while (prevtoshone->next != shone)
+			prevtoshone = prevtoshone->next;
+
+		scsi_hostlist = shone;
+		shone->next = shtwo->next;
+		prevtoshone->next = shtwo;
+		shtwo->next = NULL;
+	} else if (shtwo == scsi_hostlist && shone->next) {
+		/* shtwo at head, shone is not at tail */
+
+		prevtoshone = scsi_hostlist;
+		while (prevtoshone->next != shone)
+			prevtoshone = prevtoshone->next;
+
+		scsi_hostlist = shone;
+		prevtoshone->next = shtwo;
+		save = shtwo->next;
+		shtwo->next = shone->next;
+		shone->next = save;
+	} else if (!shone->next) {
+		/* shtwo not at head, shone at tail */
+
+		prevtoshtwo = scsi_hostlist;
+		prevtoshone = scsi_hostlist;
+
+		while (prevtoshtwo->next != shtwo)
+			prevtoshtwo = prevtoshtwo->next;
+		while (prevtoshone->next != shone)
+			prevtoshone = prevtoshone->next;
+
+		prevtoshtwo->next = shone;
+		shone->next = shtwo->next;
+		prevtoshone->next = shtwo;
+		shtwo->next = NULL;
+
+	} else {
+		prevtoshtwo = scsi_hostlist;
+		prevtoshone = scsi_hostlist;
+		save = NULL;
+
+		while (prevtoshtwo->next != shtwo)
+			prevtoshtwo = prevtoshtwo->next;
+		while (prevtoshone->next != shone)
+			prevtoshone = prevtoshone->next;
+
+		prevtoshtwo->next = shone;
+		save = shone->next;
+		shone->next = shtwo->next;
+		prevtoshone->next = shtwo;
+		shtwo->next = save;
+	}
+	return;
+}
+
+
+
+#ifdef CONFIG_PROC_FS
+/**
+ * mega_adapinq()
+ * @adapter - pointer to our soft state
+ * @dma_handle - DMA address of the buffer
+ *
+ * Issue internal comamnds while interrupts are available.
+ * We only issue direct mailbox commands from within the driver. ioctl()
+ * interface using these routines can issue passthru commands.
+ */
+static int
+mega_adapinq(adapter_t *adapter, dma_addr_t dma_handle)
+{
+	megacmd_t	mc;
+
+	memset(&mc, 0, sizeof(megacmd_t));
+
+	if( adapter->flag & BOARD_40LD ) {
+		mc.cmd = FC_NEW_CONFIG;
+		mc.opcode = NC_SUBOP_ENQUIRY3;
+		mc.subopcode = ENQ3_GET_SOLICITED_FULL;
+	}
+	else {
+		mc.cmd = MEGA_MBOXCMD_ADPEXTINQ;
+	}
+
+	mc.xferaddr = (u32)dma_handle;
+
+	if ( mega_internal_command(adapter, LOCK_INT, &mc, NULL) != 0 ) {
+		return -1;
+	}
+
+	return 0;
+}
+
+
+/**
+ * mega_allocate_inquiry()
+ * @dma_handle - handle returned for dma address
+ * @pdev - handle to pci device
+ *
+ * allocates memory for inquiry structure
+ */
+static inline caddr_t
+mega_allocate_inquiry(dma_addr_t *dma_handle, struct pci_dev *pdev)
+{
+	return pci_alloc_consistent(pdev, sizeof(mega_inquiry3), dma_handle);
+}
+
+
+static inline void
+mega_free_inquiry(caddr_t inquiry, dma_addr_t dma_handle, struct pci_dev *pdev)
+{
+	pci_free_consistent(pdev, sizeof(mega_inquiry3), inquiry, dma_handle);
+}
+
+
+/** mega_internal_dev_inquiry()
+ * @adapter - pointer to our soft state
+ * @ch - channel for this device
+ * @tgt - ID of this device
+ * @buf_dma_handle - DMA address of the buffer
+ *
+ * Issue the scsi inquiry for the specified device.
+ */
+static int
+mega_internal_dev_inquiry(adapter_t *adapter, u8 ch, u8 tgt,
+		dma_addr_t buf_dma_handle)
+{
+	mega_passthru	*pthru;
+	dma_addr_t	pthru_dma_handle;
+	megacmd_t	mc;
+	int		rval;
+	struct pci_dev	*pdev;
+
+
+	/*
+	 * For all internal commands, the buffer must be allocated in <4GB
+	 * address range
+	 */
+	pdev = adapter->ipdev;
+
+	pthru = pci_alloc_consistent(pdev, sizeof(mega_passthru),
+			&pthru_dma_handle);
+
+	if( pthru == NULL ) {
+		return -1;
+	}
+
+	pthru->timeout = 2;
+	pthru->ars = 1;
+	pthru->reqsenselen = 14;
+	pthru->islogical = 0;
+
+	pthru->channel = (adapter->flag & BOARD_40LD) ? 0 : ch;
+
+	pthru->target = (adapter->flag & BOARD_40LD) ? (ch << 4)|tgt : tgt;
+
+	pthru->cdblen = 6;
+
+	pthru->cdb[0] = INQUIRY;
+	pthru->cdb[1] = 0;
+	pthru->cdb[2] = 0;
+	pthru->cdb[3] = 0;
+	pthru->cdb[4] = 255;
+	pthru->cdb[5] = 0;
+
+
+	pthru->dataxferaddr = (u32)buf_dma_handle;
+	pthru->dataxferlen = 256;
+
+	memset(&mc, 0, sizeof(megacmd_t));
+
+	mc.cmd = MEGA_MBOXCMD_PASSTHRU;
+	mc.xferaddr = (u32)pthru_dma_handle;
+
+	rval = mega_internal_command(adapter, LOCK_INT, &mc, pthru);
+
+	pci_free_consistent(pdev, sizeof(mega_passthru), pthru,
+			pthru_dma_handle);
+
+	return rval;
+}
+#endif	// #ifdef CONFIG_PROC_FS
+
+
+/**
+ * mega_internal_command()
+ * @adapter - pointer to our soft state
+ * @ls - the scope of the exclusion lock.
+ * @mc - the mailbox command
+ * @pthru - Passthru structure for DCDB commands
+ *
+ * Issue the internal commands in interrupt mode.
+ * The last argument is the address of the passthru structure if the command
+ * to be fired is a passthru command
+ *
+ * lockscope specifies whether the caller has already acquired the lock. Of
+ * course, the caller must know which lock we are talking about.
+ *
+ * Note: parameter 'pthru' is null for non-passthru commands.
+ */
+static int
+mega_internal_command(adapter_t *adapter, lockscope_t ls, megacmd_t *mc,
+		mega_passthru *pthru )
+{
+	Scsi_Cmnd	*scmd;
+	unsigned long	flags = 0;
+	scb_t	*scb;
+	int	rval;
+
+	/*
+	 * The internal commands share one command id and hence are
+	 * serialized. This is so because we want to reserve maximum number of
+	 * available command ids for the I/O commands.
+	 */
+	down(&adapter->int_mtx);
+
+	scb = &adapter->int_scb;
+	memset(scb, 0, sizeof(scb_t));
+
+	scmd = &adapter->int_scmd;
+	memset(scmd, 0, sizeof(Scsi_Cmnd));
+
+	scmd->host = adapter->host;
+	scmd->buffer = (void *)scb;
+	scmd->cmnd[0] = MEGA_INTERNAL_CMD;
+
+	scb->state |= SCB_ACTIVE;
+	scb->cmd = scmd;
+
+	memcpy(scb->raw_mbox, mc, sizeof(megacmd_t));
+
+	/*
+	 * Is it a passthru command
+	 */
+	if( mc->cmd == MEGA_MBOXCMD_PASSTHRU ) {
+
+		scb->pthru = pthru;
+	}
+
+	scb->idx = CMDID_INT_CMDS;
+
+	scmd->state = 0;
+
+	/*
+	 * Get the lock only if the caller has not acquired it already
+	 */
+	if( ls == LOCK_INT ) spin_lock_irqsave(adapter->host_lock, flags);
+
+	megaraid_queue(scmd, mega_internal_done);
+
+	if( ls == LOCK_INT ) spin_unlock_irqrestore(adapter->host_lock, flags);
+
+	/*
+	 * Wait till this command finishes. Do not use
+	 * wait_event_interruptible(). It causes panic if CTRL-C is hit when
+	 * dumping e.g., physical disk information through /proc interface.
+	 * Catching the return value should solve the issue but for now keep
+	 * the call non-interruptible.
+	 */
+#if 0
+	wait_event_interruptible(adapter->int_waitq, scmd->state);
+#endif
+	wait_event(adapter->int_waitq, scmd->state);
+
+	rval = scmd->result;
+	mc->status = scmd->result;
+
+	/*
+	 * Print a debug message for all failed commands. Applications can use
+	 * this information.
+	 */
+	if( scmd->result && trace_level ) {
+		printk("megaraid: cmd [%x, %x, %x] status:[%x]\n",
+			mc->cmd, mc->opcode, mc->subopcode, scmd->result);
+	}
+
+	up(&adapter->int_mtx);
+
+	return rval;
+}
+
+
+/**
+ * mega_internal_done()
+ * @scmd - internal scsi command
+ *
+ * Callback routine for internal commands.
+ */
+static void
+mega_internal_done(Scsi_Cmnd *scmd)
+{
+	adapter_t	*adapter;
+
+	adapter = (adapter_t *)scmd->host->hostdata;
+
+	scmd->state = 1; /* thread waiting for its command to complete */
+
+	/*
+	 * See comment in mega_internal_command() routine for
+	 * wait_event_interruptible()
+	 */
+#if 0
+	wake_up_interruptible(&adapter->int_waitq);
+#endif
+	wake_up(&adapter->int_waitq);
+
+}
+
+static Scsi_Host_Template driver_template = MEGARAID;
+
+#include "scsi_module.c"
+
+/* vi: set ts=8 sw=8 tw=78: */
diff -urN linux-2.4.23-pre6/drivers/scsi/megaraid2.h linux-2.4.23-pre7/drivers/scsi/megaraid2.h
--- linux-2.4.23-pre6/drivers/scsi/megaraid2.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/scsi/megaraid2.h	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,1187 @@
+#ifndef __MEGARAID_H__
+#define __MEGARAID_H__
+
+#include <linux/version.h>
+#include <linux/spinlock.h>
+
+
+#define MEGARAID_VERSION	\
+	"v2.00.9 (Release Date: Thu Sep  4 17:49:42 EDT 2003)\n"
+
+/*
+ * Driver features - change the values to enable or disable features in the
+ * driver.
+ */
+
+/*
+ * Comand coalescing - This feature allows the driver to be able to combine
+ * two or more commands and issue as one command in order to boost I/O
+ * performance. Useful if the nature of the I/O is sequential. It is not very
+ * useful for random natured I/Os.
+ */
+#define MEGA_HAVE_COALESCING	0
+
+/*
+ * Clustering support - Set this flag if you are planning to use the
+ * clustering services provided by the megaraid controllers and planning to
+ * setup a cluster
+ */
+#define MEGA_HAVE_CLUSTERING	1
+
+/*
+ * Driver statistics - Set this flag if you are interested in statics about
+ * number of I/O completed on each logical drive and how many interrupts
+ * generated. If enabled, this information is available through /proc
+ * interface and through the private ioctl. Setting this flag has a
+ * performance penalty.
+ */
+#define MEGA_HAVE_STATS		0
+
+/*
+ * Enhanced /proc interface - This feature will allow you to have a more
+ * detailed /proc interface for megaraid driver. E.g., a real time update of
+ * the status of the logical drives, battery status, physical drives etc.
+ */
+#define MEGA_HAVE_ENH_PROC	1
+
+#define MAX_DEV_TYPE	32
+
+#ifndef PCI_VENDOR_ID_LSI_LOGIC
+#define PCI_VENDOR_ID_LSI_LOGIC		0x1000
+#endif
+
+#ifndef PCI_VENDOR_ID_AMI
+#define PCI_VENDOR_ID_AMI		0x101E
+#endif
+
+#ifndef PCI_VENDOR_ID_DELL
+#define PCI_VENDOR_ID_DELL		0x1028
+#endif
+
+#ifndef PCI_VENDOR_ID_INTEL
+#define PCI_VENDOR_ID_INTEL		0x8086
+#endif
+
+#ifndef PCI_DEVICE_ID_AMI_MEGARAID
+#define PCI_DEVICE_ID_AMI_MEGARAID	0x9010
+#endif
+
+#ifndef PCI_DEVICE_ID_AMI_MEGARAID2
+#define PCI_DEVICE_ID_AMI_MEGARAID2	0x9060
+#endif
+
+#ifndef PCI_DEVICE_ID_AMI_MEGARAID3
+#define PCI_DEVICE_ID_AMI_MEGARAID3	0x1960
+#endif
+
+#define PCI_DEVICE_ID_DISCOVERY		0x000E
+#define PCI_DEVICE_ID_PERC4_DI		0x000F
+#define PCI_DEVICE_ID_PERC4_QC_VERDE	0x0407
+
+/* Sub-System Vendor IDs */
+#define	AMI_SUBSYS_VID			0x101E
+#define DELL_SUBSYS_VID			0x1028
+#define	HP_SUBSYS_VID			0x103C
+#define LSI_SUBSYS_VID			0x1000
+#define INTEL_SUBSYS_VID		0x8086
+
+#define HBA_SIGNATURE	      		0x3344
+#define HBA_SIGNATURE_471	  	0xCCCC
+#define HBA_SIGNATURE_64BIT		0x0299
+
+#define MBOX_BUSY_WAIT			10	/* wait for up to 10 usec for
+						   mailbox to be free */
+#define DEFAULT_INITIATOR_ID	7
+
+#define MAX_SGLIST		64	/* max supported in f/w */
+#define MIN_SGLIST		26	/* guaranteed to support these many */
+#define MAX_COMMANDS		126
+#define CMDID_INT_CMDS		MAX_COMMANDS+1	/* make sure CMDID_INT_CMDS
+					 	is less than max commands
+						supported by any f/w */
+
+#define MAX_CDB_LEN	     	10
+#define MAX_EXT_CDB_LEN		16	/* we support cdb length up to 16 */
+
+#define DEF_CMD_PER_LUN		63
+#define MAX_CMD_PER_LUN		MAX_COMMANDS
+#define MAX_FIRMWARE_STATUS	46
+#define MAX_XFER_PER_CMD	(64*1024)
+#define MAX_SECTORS_PER_IO	128
+
+#define MAX_LOGICAL_DRIVES_40LD		40
+#define FC_MAX_PHYSICAL_DEVICES		256
+#define MAX_LOGICAL_DRIVES_8LD		8
+#define MAX_CHANNELS			5
+#define MAX_TARGET			15
+#define MAX_PHYSICAL_DRIVES		MAX_CHANNELS*MAX_TARGET
+#define MAX_ROW_SIZE_40LD		32
+#define MAX_ROW_SIZE_8LD		8
+#define MAX_SPAN_DEPTH			8
+
+#define NVIRT_CHAN		4	/* # of virtual channels to represent
+					   up to 60 logical drives */
+
+#define MEGARAID						\
+{								\
+	.name =				"MegaRAID",		\
+	.proc_name =		 	"megaraid",		\
+	.detect =			megaraid_detect,	\
+	.release =			megaraid_release,	\
+	.info =				megaraid_info,		\
+	.command =			megaraid_command,	\
+	.queuecommand =			megaraid_queue,		\
+	.bios_param =			megaraid_biosparam,	\
+	.max_sectors =			MAX_SECTORS_PER_IO,	\
+	.can_queue =			MAX_COMMANDS,		\
+	.this_id =			DEFAULT_INITIATOR_ID,	\
+	.sg_tablesize =			MAX_SGLIST,		\
+	.cmd_per_lun =			DEF_CMD_PER_LUN,	\
+	.present =  			0,			\
+	.unchecked_isa_dma =		0,			\
+	.use_clustering =		ENABLE_CLUSTERING,	\
+	.use_new_eh_code =		1,			\
+	.eh_abort_handler =		megaraid_abort,		\
+	.eh_device_reset_handler =	megaraid_reset,		\
+	.eh_bus_reset_handler =		megaraid_reset,		\
+	.eh_host_reset_handler =	megaraid_reset,		\
+	.highmem_io =			1			\
+}
+
+
+
+typedef struct {
+	/* 0x0 */ u8 cmd;
+	/* 0x1 */ u8 cmdid;
+	/* 0x2 */ u16 numsectors;
+	/* 0x4 */ u32 lba;
+	/* 0x8 */ u32 xferaddr;
+	/* 0xC */ u8 logdrv;
+	/* 0xD */ u8 numsgelements;
+	/* 0xE */ u8 resvd;
+	/* 0xF */ volatile u8 busy;
+	/* 0x10 */ volatile u8 numstatus;
+	/* 0x11 */ volatile u8 status;
+	/* 0x12 */ volatile u8 completed[MAX_FIRMWARE_STATUS];
+	volatile u8 poll;
+	volatile u8 ack;
+} __attribute__ ((packed)) mbox_t;
+
+typedef struct {
+	u32 xfer_segment_lo;
+	u32 xfer_segment_hi;
+	mbox_t mbox;
+} __attribute__ ((packed)) mbox64_t;
+
+
+/*
+ * Passthru definitions
+ */
+#define MAX_REQ_SENSE_LEN       0x20
+
+typedef struct {
+	u8 timeout:3;		/* 0=6sec/1=60sec/2=10min/3=3hrs */
+	u8 ars:1;
+	u8 reserved:3;
+	u8 islogical:1;
+	u8 logdrv;		/* if islogical == 1 */
+	u8 channel;		/* if islogical == 0 */
+	u8 target;		/* if islogical == 0 */
+	u8 queuetag;		/* unused */
+	u8 queueaction;		/* unused */
+	u8 cdb[MAX_CDB_LEN];
+	u8 cdblen;
+	u8 reqsenselen;
+	u8 reqsensearea[MAX_REQ_SENSE_LEN];
+	u8 numsgelements;
+	u8 scsistatus;
+	u32 dataxferaddr;
+	u32 dataxferlen;
+} __attribute__ ((packed)) mega_passthru;
+
+
+/*
+ * Extended passthru: support CDB > 10 bytes
+ */
+typedef struct {
+	u8 timeout:3;		/* 0=6sec/1=60sec/2=10min/3=3hrs */
+	u8 ars:1;
+	u8 rsvd1:1;
+	u8 cd_rom:1;
+	u8 rsvd2:1;
+	u8 islogical:1;
+	u8 logdrv;		/* if islogical == 1 */
+	u8 channel;		/* if islogical == 0 */
+	u8 target;		/* if islogical == 0 */
+	u8 queuetag;		/* unused */
+	u8 queueaction;		/* unused */
+	u8 cdblen;
+	u8 rsvd3;
+	u8 cdb[MAX_EXT_CDB_LEN];
+	u8 numsgelements;
+	u8 status;
+	u8 reqsenselen;
+	u8 reqsensearea[MAX_REQ_SENSE_LEN];
+	u8 rsvd4;
+	u32 dataxferaddr;
+	u32 dataxferlen;
+} __attribute__ ((packed)) mega_ext_passthru;
+
+typedef struct {
+	u64 address;
+	u32 length;
+} __attribute__ ((packed)) mega_sgl64;
+
+typedef struct {
+	u32 address;
+	u32 length;
+} __attribute__ ((packed)) mega_sglist;
+
+
+/* Queued command data */
+typedef struct {
+	int	idx;
+	u32	state;
+	struct list_head	list;
+	u8	raw_mbox[66];
+	u32	dma_type;
+	u32	dma_direction;
+
+	Scsi_Cmnd	*cmd;
+	dma_addr_t	dma_h_bulkdata;
+	dma_addr_t	dma_h_sgdata;
+
+	mega_sglist	*sgl;
+	mega_sgl64	*sgl64;
+	dma_addr_t	sgl_dma_addr;
+
+	mega_passthru		*pthru;
+	dma_addr_t		pthru_dma_addr;
+	mega_ext_passthru	*epthru;
+	dma_addr_t		epthru_dma_addr;
+} scb_t;
+
+/*
+ * Flags to follow the scb as it transitions between various stages
+ */
+#define SCB_FREE	0x0000	/* on the free list */
+#define SCB_ACTIVE	0x0001	/* off the free list */
+#define SCB_PENDQ	0x0002	/* on the pending queue */
+#define SCB_ISSUED	0x0004	/* issued - owner f/w */
+#define SCB_ABORT	0x0008	/* Got an abort for this one */
+#define SCB_RESET	0x0010	/* Got a reset for this one */
+
+/*
+ * Utilities declare this strcture size as 1024 bytes. So more fields can
+ * be added in future.
+ */
+typedef struct {
+	u32	data_size; /* current size in bytes (not including resvd) */
+
+	u32	config_signature;
+		/* Current value is 0x00282008
+		 * 0x28=MAX_LOGICAL_DRIVES,
+		 * 0x20=Number of stripes and
+		 * 0x08=Number of spans */
+
+	u8	fw_version[16];		/* printable ASCI string */
+	u8	bios_version[16];	/* printable ASCI string */
+	u8	product_name[80];	/* printable ASCI string */
+
+	u8	max_commands;		/* Max. concurrent commands supported */
+	u8	nchannels;		/* Number of SCSI Channels detected */
+	u8	fc_loop_present;	/* Number of Fibre Loops detected */
+	u8	mem_type;		/* EDO, FPM, SDRAM etc */
+
+	u32	signature;
+	u16	dram_size;		/* In terms of MB */
+	u16	subsysid;
+
+	u16	subsysvid;
+	u8	notify_counters;
+	u8	pad1k[889];		/* 135 + 889 resvd = 1024 total size */
+} __attribute__ ((packed)) mega_product_info;
+
+struct notify {
+	u32 global_counter;	/* Any change increments this counter */
+
+	u8 param_counter;	/* Indicates any params changed  */
+	u8 param_id;		/* Param modified - defined below */
+	u16 param_val;		/* New val of last param modified */
+
+	u8 write_config_counter;	/* write config occurred */
+	u8 write_config_rsvd[3];
+
+	u8 ldrv_op_counter;	/* Indicates ldrv op started/completed */
+	u8 ldrv_opid;		/* ldrv num */
+	u8 ldrv_opcmd;		/* ldrv operation - defined below */
+	u8 ldrv_opstatus;	/* status of the operation */
+
+	u8 ldrv_state_counter;	/* Indicates change of ldrv state */
+	u8 ldrv_state_id;		/* ldrv num */
+	u8 ldrv_state_new;	/* New state */
+	u8 ldrv_state_old;	/* old state */
+
+	u8 pdrv_state_counter;	/* Indicates change of ldrv state */
+	u8 pdrv_state_id;		/* pdrv id */
+	u8 pdrv_state_new;	/* New state */
+	u8 pdrv_state_old;	/* old state */
+
+	u8 pdrv_fmt_counter;	/* Indicates pdrv format started/over */
+	u8 pdrv_fmt_id;		/* pdrv id */
+	u8 pdrv_fmt_val;		/* format started/over */
+	u8 pdrv_fmt_rsvd;
+
+	u8 targ_xfer_counter;	/* Indicates SCSI-2 Xfer rate change */
+	u8 targ_xfer_id;	/* pdrv Id  */
+	u8 targ_xfer_val;		/* new Xfer params of last pdrv */
+	u8 targ_xfer_rsvd;
+
+	u8 fcloop_id_chg_counter;	/* Indicates loopid changed */
+	u8 fcloopid_pdrvid;		/* pdrv id */
+	u8 fcloop_id0;			/* loopid on fc loop 0 */
+	u8 fcloop_id1;			/* loopid on fc loop 1 */
+
+	u8 fcloop_state_counter;	/* Indicates loop state changed */
+	u8 fcloop_state0;		/* state of fc loop 0 */
+	u8 fcloop_state1;		/* state of fc loop 1 */
+	u8 fcloop_state_rsvd;
+} __attribute__ ((packed));
+
+#define MAX_NOTIFY_SIZE     0x80
+#define CUR_NOTIFY_SIZE     sizeof(struct notify)
+
+typedef struct {
+	u32	data_size; /* current size in bytes (not including resvd) */
+
+	struct notify notify;
+
+	u8	notify_rsvd[MAX_NOTIFY_SIZE - CUR_NOTIFY_SIZE];
+
+	u8	rebuild_rate;		/* Rebuild rate (0% - 100%) */
+	u8	cache_flush_interval;	/* In terms of Seconds */
+	u8	sense_alert;
+	u8	drive_insert_count;	/* drive insertion count */
+
+	u8	battery_status;
+	u8	num_ldrv;		/* No. of Log Drives configured */
+	u8	recon_state[MAX_LOGICAL_DRIVES_40LD / 8];	/* State of
+							   reconstruct */
+	u16	ldrv_op_status[MAX_LOGICAL_DRIVES_40LD / 8]; /* logdrv
+								 Status */
+
+	u32	ldrv_size[MAX_LOGICAL_DRIVES_40LD];/* Size of each log drv */
+	u8	ldrv_prop[MAX_LOGICAL_DRIVES_40LD];
+	u8	ldrv_state[MAX_LOGICAL_DRIVES_40LD];/* State of log drives */
+	u8	pdrv_state[FC_MAX_PHYSICAL_DEVICES];/* State of phys drvs. */
+	u16	pdrv_format[FC_MAX_PHYSICAL_DEVICES / 16];
+
+	u8	targ_xfer[80];	/* phys device transfer rate */
+	u8	pad1k[263];	/* 761 + 263reserved = 1024 bytes total size */
+} __attribute__ ((packed)) mega_inquiry3;
+
+
+/* Structures */
+typedef struct {
+	u8	max_commands;	/* Max concurrent commands supported */
+	u8	rebuild_rate;	/* Rebuild rate - 0% thru 100% */
+	u8	max_targ_per_chan;	/* Max targ per channel */
+	u8	nchannels;	/* Number of channels on HBA */
+	u8	fw_version[4];	/* Firmware version */
+	u16	age_of_flash;	/* Number of times FW has been flashed */
+	u8	chip_set_value;	/* Contents of 0xC0000832 */
+	u8	dram_size;	/* In MB */
+	u8	cache_flush_interval;	/* in seconds */
+	u8	bios_version[4];
+	u8	board_type;
+	u8	sense_alert;
+	u8	write_config_count;	/* Increase with every configuration
+					   change */
+	u8	drive_inserted_count;	/* Increase with every drive inserted
+					 */
+	u8	inserted_drive;	/* Channel:Id of inserted drive */
+	u8	battery_status;	/*
+				 * BIT 0: battery module missing
+				 * BIT 1: VBAD
+				 * BIT 2: temprature high
+				 * BIT 3: battery pack missing
+				 * BIT 4,5:
+				 *   00 - charge complete
+				 *   01 - fast charge in progress
+				 *   10 - fast charge fail
+				 *   11 - undefined
+				 * Bit 6: counter > 1000
+				 * Bit 7: Undefined
+				 */
+	u8	dec_fault_bus_info;
+} __attribute__ ((packed)) mega_adp_info;
+
+
+typedef struct {
+	u8	num_ldrv;	/* Number of logical drives configured */
+	u8	rsvd[3];
+	u32	ldrv_size[MAX_LOGICAL_DRIVES_8LD];
+	u8	ldrv_prop[MAX_LOGICAL_DRIVES_8LD];
+	u8	ldrv_state[MAX_LOGICAL_DRIVES_8LD];
+} __attribute__ ((packed)) mega_ldrv_info;
+
+typedef struct {
+	u8	pdrv_state[MAX_PHYSICAL_DRIVES];
+	u8	rsvd;
+} __attribute__ ((packed)) mega_pdrv_info;
+
+/* RAID inquiry: Mailbox command 0x05*/
+typedef struct {
+	mega_adp_info	adapter_info;
+	mega_ldrv_info	logdrv_info;
+	mega_pdrv_info	pdrv_info;
+} __attribute__ ((packed)) mraid_inquiry;
+
+
+/* RAID extended inquiry: Mailbox command 0x04*/
+typedef struct {
+	mraid_inquiry	raid_inq;
+	u16	phys_drv_format[MAX_CHANNELS];
+	u8	stack_attn;
+	u8	modem_status;
+	u8	rsvd[2];
+} __attribute__ ((packed)) mraid_ext_inquiry;
+
+
+typedef struct {
+	u8	channel;
+	u8	target;
+}__attribute__ ((packed)) adp_device;
+
+typedef struct {
+	u32		start_blk;	/* starting block */
+	u32		num_blks;	/* # of blocks */
+	adp_device	device[MAX_ROW_SIZE_40LD];
+}__attribute__ ((packed)) adp_span_40ld;
+
+typedef struct {
+	u32		start_blk;	/* starting block */
+	u32		num_blks;	/* # of blocks */
+	adp_device	device[MAX_ROW_SIZE_8LD];
+}__attribute__ ((packed)) adp_span_8ld;
+
+typedef struct {
+	u8	span_depth;	/* Total # of spans */
+	u8	level;		/* RAID level */
+	u8	read_ahead;	/* read ahead, no read ahead, adaptive read
+				   ahead */
+	u8	stripe_sz;	/* Encoded stripe size */
+	u8	status;		/* Status of the logical drive */
+	u8	write_mode;	/* write mode, write_through/write_back */
+	u8	direct_io;	/* direct io or through cache */
+	u8	row_size;	/* Number of stripes in a row */
+} __attribute__ ((packed)) logdrv_param;
+
+typedef struct {
+	logdrv_param	lparam;
+	adp_span_40ld	span[MAX_SPAN_DEPTH];
+}__attribute__ ((packed)) logdrv_40ld;
+
+typedef struct {
+	logdrv_param	lparam;
+	adp_span_8ld	span[MAX_SPAN_DEPTH];
+}__attribute__ ((packed)) logdrv_8ld;
+
+typedef struct {
+	u8	type;		/* Type of the device */
+	u8	cur_status;	/* current status of the device */
+	u8	tag_depth;	/* Level of tagging */
+	u8	sync_neg;	/* sync negotiation - ENABLE or DISBALE */
+	u32	size;		/* configurable size in terms of 512 byte
+				   blocks */
+}__attribute__ ((packed)) phys_drv;
+
+typedef struct {
+	u8		nlog_drives;		/* number of logical drives */
+	u8		resvd[3];
+	logdrv_40ld	ldrv[MAX_LOGICAL_DRIVES_40LD];
+	phys_drv	pdrv[MAX_PHYSICAL_DRIVES];
+}__attribute__ ((packed)) disk_array_40ld;
+
+typedef struct {
+	u8		nlog_drives;	/* number of logical drives */
+	u8		resvd[3];
+	logdrv_8ld	ldrv[MAX_LOGICAL_DRIVES_8LD];
+	phys_drv	pdrv[MAX_PHYSICAL_DRIVES];
+}__attribute__ ((packed)) disk_array_8ld;
+
+/*
+ *    FW Definitions & Data Structures for 8LD 4-Span and 8-Span Controllers
+ */
+#define	MAX_STRIPES	8
+#define SPAN4_DEPTH	4
+#define SPAN8_DEPTH	8
+#define MAX_PHYDRVS	5 * 16	/* 5 Channels * 16 Targets */
+
+typedef struct  {
+	unsigned char	channel;
+	unsigned char	target; 
+}__attribute__ ((packed)) device_t;
+
+typedef struct { 
+	unsigned long	start_blk;
+	unsigned long	total_blks;
+	device_t	device[ MAX_STRIPES ];
+}__attribute__ ((packed)) span_t;
+
+typedef struct {
+	unsigned char	type;
+	unsigned char	curr_status;
+	unsigned char	tag_depth;
+	unsigned char	resvd1;
+	unsigned long	size;
+}__attribute__ ((packed)) phydrv_t;
+
+typedef struct { 
+	unsigned char	span_depth;
+	unsigned char	raid;
+	unsigned char	read_ahead;	/* 0=No rdahead,1=RDAHEAD,2=adaptive */ 
+	unsigned char	stripe_sz;
+	unsigned char	status;
+	unsigned char	write_policy;	/* 0=wrthru,1=wrbak */ 
+	unsigned char	direct_io;   	/* 1=directio,0=cached */ 
+	unsigned char	no_stripes;
+	span_t		span[ SPAN4_DEPTH ];
+}__attribute__ ((packed)) ld_span4_t;
+
+typedef struct { 
+	unsigned char	span_depth;
+	unsigned char	raid;
+	unsigned char	read_ahead;	/* 0=No rdahead,1=RDAHEAD,2=adaptive */ 
+	unsigned char	stripe_sz;
+	unsigned char	status;
+	unsigned char	write_policy;	/* 0=wrthru,1=wrbak */ 
+	unsigned char	direct_io;   	/* 1=directio,0=cached */ 
+	unsigned char	no_stripes;
+	span_t		span[ SPAN8_DEPTH ];
+}__attribute__ ((packed)) ld_span8_t;
+
+typedef struct { 
+	unsigned char	no_log_drives;
+	unsigned char	pad[3];
+	ld_span4_t	log_drv[ MAX_LOGICAL_DRIVES_8LD ];
+	phydrv_t	phys_drv[ MAX_PHYDRVS ];
+}__attribute__ ((packed)) diskarray_span4_t;
+
+typedef struct { 
+	unsigned char	no_log_drives;
+	unsigned char	pad[3];
+	ld_span8_t	log_drv[ MAX_LOGICAL_DRIVES_8LD ];
+	phydrv_t	phys_drv[ MAX_PHYDRVS ];
+}__attribute__ ((packed)) diskarray_span8_t;
+
+/*
+ * User ioctl structure.
+ * This structure will be used for Traditional Method ioctl interface
+ * commands (0x80),Alternate Buffer Method (0x81) ioctl commands and the
+ * Driver ioctls.
+ * The Driver ioctl interface handles the commands at the driver level,
+ * without being sent to the card.
+ */
+/* system call imposed limit. Change accordingly */
+#define IOCTL_MAX_DATALEN       4096
+
+struct uioctl_t {
+	u32 inlen;
+	u32 outlen;
+	union {
+		u8 fca[16];
+		struct {
+			u8 opcode;
+			u8 subopcode;
+			u16 adapno;
+#if BITS_PER_LONG == 32
+			u8 *buffer;
+			u8 pad[4];
+#endif
+#if BITS_PER_LONG == 64
+			u8 *buffer;
+#endif
+			u32 length;
+		} __attribute__ ((packed)) fcs;
+	} __attribute__ ((packed)) ui;
+	u8 mbox[18];		/* 16 bytes + 2 status bytes */
+	mega_passthru pthru;
+#if BITS_PER_LONG == 32
+	char *data;		/* buffer <= 4096 for 0x80 commands */
+	char pad[4];
+#endif
+#if BITS_PER_LONG == 64
+	char *data;
+#endif
+} __attribute__ ((packed));
+
+/*
+ * struct mcontroller is used to pass information about the controllers in the
+ * system. Its upto the application how to use the information. We are passing
+ * as much info about the cards as possible and useful. Before issuing the
+ * call to find information about the cards, the applicaiton needs to issue a
+ * ioctl first to find out the number of controllers in the system.
+ */
+#define MAX_CONTROLLERS 32
+
+struct mcontroller {
+	u64 base;
+	u8 irq;
+	u8 numldrv;
+	u8 pcibus;
+	u16 pcidev;
+	u8 pcifun;
+	u16 pciid;
+	u16 pcivendor;
+	u8 pcislot;
+	u32 uid;
+};
+
+/*
+ * mailbox structure used for internal commands
+ */
+typedef struct {
+	u8	cmd;
+	u8	cmdid;
+	u8	opcode;
+	u8	subopcode;
+	u32	lba;
+	u32	xferaddr;
+	u8	logdrv;
+	u8	rsvd[3];
+	u8	numstatus;
+	u8	status;
+} __attribute__ ((packed)) megacmd_t;
+
+/*
+ * Defines for Driver IOCTL interface
+ */
+#define MEGAIOC_MAGIC  	'm'
+
+#define MEGAIOC_QNADAP		'm'	/* Query # of adapters */
+#define MEGAIOC_QDRVRVER	'e'	/* Query driver version */
+#define MEGAIOC_QADAPINFO   	'g'	/* Query adapter information */
+#define MKADAP(adapno)	  	(MEGAIOC_MAGIC << 8 | (adapno) )
+#define GETADAP(mkadap)	 	( (mkadap) ^ MEGAIOC_MAGIC << 8 )
+
+/*
+ * Definition for the new ioctl interface (NIT)
+ */
+
+/*
+ * Vendor specific Group-7 commands
+ */
+#define VENDOR_SPECIFIC_COMMANDS	0xE0
+#define MEGA_INTERNAL_CMD		VENDOR_SPECIFIC_COMMANDS + 0x01
+
+/*
+ * The ioctl command. No other command shall be used for this interface
+ */
+#define USCSICMD	VENDOR_SPECIFIC_COMMANDS
+
+/*
+ * Data direction flags
+ */
+#define UIOC_RD		0x00001
+#define UIOC_WR		0x00002
+
+/*
+ * ioctl opcodes
+ */
+#define MBOX_CMD	0x00000	/* DCMD or passthru command */
+#define GET_DRIVER_VER	0x10000	/* Get driver version */
+#define GET_N_ADAP	0x20000	/* Get number of adapters */
+#define GET_ADAP_INFO	0x30000	/* Get information about a adapter */
+#define GET_CAP		0x40000	/* Get ioctl capabilities */
+#define GET_STATS	0x50000	/* Get statistics, including error info */
+
+
+/*
+ * The ioctl structure.
+ * MBOX macro converts a nitioctl_t structure to megacmd_t pointer and
+ * MBOX_P macro converts a nitioctl_t pointer to megacmd_t pointer.
+ */
+typedef struct {
+	char		signature[8];	/* Must contain "MEGANIT" */
+	u32		opcode;		/* opcode for the command */
+	u32		adapno;		/* adapter number */
+	union {
+		u8	__raw_mbox[18];
+		caddr_t	__uaddr; /* xferaddr for non-mbox cmds */
+	}__ua;
+
+#define uioc_rmbox	__ua.__raw_mbox
+#define MBOX(uioc)	((megacmd_t *)&((uioc).__ua.__raw_mbox[0]))
+#define MBOX_P(uioc)	((megacmd_t *)&((uioc)->__ua.__raw_mbox[0]))
+#define uioc_uaddr	__ua.__uaddr
+
+	u32		xferlen;	/* xferlen for DCMD and non-mbox
+					   commands */
+	u32		flags;		/* data direction flags */
+}nitioctl_t;
+
+
+/*
+ * I/O statistics for some applications like SNMP agent. The caller must
+ * provide the number of logical drives for which status should be reported.
+ */
+typedef struct {
+	int	num_ldrv;	/* Number for logical drives for which the
+				   status should be reported. */
+	u32	nreads[MAX_LOGICAL_DRIVES_40LD];	/* number of reads for
+							each logical drive */
+	u32	nreadblocks[MAX_LOGICAL_DRIVES_40LD];	/* number of blocks
+							read for each logical
+							drive */
+	u32	nwrites[MAX_LOGICAL_DRIVES_40LD];	/* number of writes
+							for each logical
+							drive */
+	u32	nwriteblocks[MAX_LOGICAL_DRIVES_40LD];	/* number of blocks
+							writes for each
+							logical drive */
+	u32	rd_errors[MAX_LOGICAL_DRIVES_40LD];	/* number of read
+							   errors for each
+							   logical drive */
+	u32	wr_errors[MAX_LOGICAL_DRIVES_40LD];	/* number of write
+							   errors for each
+							   logical drive */
+}megastat_t;
+
+
+struct private_bios_data {
+	u8	geometry:4;	/*
+				 * bits 0-3 - BIOS geometry
+				 * 0x0001 - 1GB
+				 * 0x0010 - 2GB
+				 * 0x1000 - 8GB
+				 * Others values are invalid
+							 */
+	u8	unused:4;	/* bits 4-7 are unused */
+	u8	boot_drv;	/*
+				 * logical drive set as boot drive
+				 * 0..7 - for 8LD cards
+				 * 0..39 - for 40LD cards
+				 */
+	u8	rsvd[12];
+	u16	cksum;	/* 0-(sum of first 13 bytes of this structure) */
+} __attribute__ ((packed));
+
+
+
+
+/*
+ * Mailbox and firmware commands and subopcodes used in this driver.
+ */
+
+#define MEGA_MBOXCMD_LREAD	0x01
+#define MEGA_MBOXCMD_LWRITE	0x02
+#define MEGA_MBOXCMD_PASSTHRU	0x03
+#define MEGA_MBOXCMD_ADPEXTINQ	0x04
+#define MEGA_MBOXCMD_ADAPTERINQ	0x05
+#define MEGA_MBOXCMD_LREAD64	0xA7
+#define MEGA_MBOXCMD_LWRITE64	0xA8
+#define MEGA_MBOXCMD_PASSTHRU64	0xC3
+#define MEGA_MBOXCMD_EXTPTHRU	0xE3
+
+#define MAIN_MISC_OPCODE	0xA4	/* f/w misc opcode */
+#define GET_MAX_SG_SUPPORT	0x01	/* get max sg len supported by f/w */
+
+#define FC_NEW_CONFIG		0xA1
+#define NC_SUBOP_PRODUCT_INFO	0x0E
+#define NC_SUBOP_ENQUIRY3	0x0F
+#define ENQ3_GET_SOLICITED_FULL	0x02
+#define OP_DCMD_READ_CONFIG	0x04
+#define NEW_READ_CONFIG_8LD	0x67
+#define READ_CONFIG_8LD		0x07
+#define FLUSH_ADAPTER		0x0A
+#define FLUSH_SYSTEM		0xFE
+
+/*
+ * Command for random deletion of logical drives
+ */
+#define	FC_DEL_LOGDRV		0xA4	/* f/w command */
+#define	OP_SUP_DEL_LOGDRV	0x2A	/* is feature supported */
+#define OP_GET_LDID_MAP		0x18	/* get ldid and logdrv number map */
+#define OP_DEL_LOGDRV		0x1C	/* delete logical drive */
+
+/*
+ * BIOS commands
+ */
+#define IS_BIOS_ENABLED		0x62
+#define GET_BIOS		0x01
+#define CHNL_CLASS		0xA9
+#define GET_CHNL_CLASS		0x00
+#define SET_CHNL_CLASS		0x01
+#define CH_RAID			0x01
+#define CH_SCSI			0x00
+#define BIOS_PVT_DATA		0x40
+#define GET_BIOS_PVT_DATA	0x00
+
+
+/*
+ * Commands to support clustering
+ */
+#define MEGA_GET_TARGET_ID	0x7D
+#define MEGA_CLUSTER_OP		0x70
+#define MEGA_GET_CLUSTER_MODE	0x02
+#define MEGA_CLUSTER_CMD	0x6E
+#define MEGA_RESERVE_LD		0x01
+#define MEGA_RELEASE_LD		0x02
+#define MEGA_RESET_RESERVATIONS	0x03
+#define MEGA_RESERVATION_STATUS	0x04
+#define MEGA_RESERVE_PD		0x05
+#define MEGA_RELEASE_PD		0x06
+
+
+/*
+ * Module battery status
+ */
+#define MEGA_BATT_MODULE_MISSING	0x01
+#define MEGA_BATT_LOW_VOLTAGE		0x02
+#define MEGA_BATT_TEMP_HIGH		0x04
+#define MEGA_BATT_PACK_MISSING		0x08
+#define MEGA_BATT_CHARGE_MASK		0x30
+#define MEGA_BATT_CHARGE_DONE		0x00
+#define MEGA_BATT_CHARGE_INPROG		0x10
+#define MEGA_BATT_CHARGE_FAIL		0x20
+#define MEGA_BATT_CYCLES_EXCEEDED	0x40
+
+/*
+ * Physical drive states.
+ */
+#define PDRV_UNCNF	0
+#define PDRV_ONLINE	3
+#define PDRV_FAILED	4
+#define PDRV_RBLD	5
+#define PDRV_HOTSPARE	6
+
+
+/*
+ * Raid logical drive states.
+ */
+#define RDRV_OFFLINE	0
+#define RDRV_DEGRADED	1
+#define RDRV_OPTIMAL	2
+#define RDRV_DELETED	3
+
+/*
+ * Read, write and cache policies
+ */
+#define NO_READ_AHEAD		0
+#define READ_AHEAD		1
+#define ADAP_READ_AHEAD		2
+#define WRMODE_WRITE_THRU	0
+#define WRMODE_WRITE_BACK	1
+#define CACHED_IO		0
+#define DIRECT_IO		1
+
+
+/*
+ * Each controller's soft state
+ */
+typedef struct {
+	int	this_id;	/* our id, may set to different than 7 if
+				   clustering is available */
+	u32	flag;
+
+	unsigned long	base;
+
+	/* mbox64 with mbox not aligned on 16-byte boundry */
+	mbox64_t	*una_mbox64;
+	dma_addr_t	una_mbox64_dma;
+
+	volatile mbox64_t	*mbox64;/* ptr to 64-bit mailbox */
+	volatile mbox_t		*mbox;	/* ptr to standard mailbox */
+	dma_addr_t		mbox_dma;
+
+	struct pci_dev	*dev;
+	struct pci_dev	*ipdev;		/* for internal allocation */
+
+	struct list_head	free_list;
+	struct list_head	pending_list;
+
+	struct Scsi_Host	*host;
+
+#define MEGA_BUFFER_SIZE (2*1024)
+	u8		*mega_buffer;
+	dma_addr_t	buf_dma_handle;
+
+	mega_product_info	product_info;
+
+	u8		max_cmds;
+	scb_t		*scb_list;
+
+	atomic_t	pend_cmds;	/* maintain a counter for
+					pending commands in firmware */
+
+#if MEGA_HAVE_STATS
+	u32	nreads[MAX_LOGICAL_DRIVES_40LD];
+	u32	nreadblocks[MAX_LOGICAL_DRIVES_40LD];
+	u32	nwrites[MAX_LOGICAL_DRIVES_40LD];
+	u32	nwriteblocks[MAX_LOGICAL_DRIVES_40LD];
+	u32	rd_errors[MAX_LOGICAL_DRIVES_40LD];
+	u32	wr_errors[MAX_LOGICAL_DRIVES_40LD];
+#endif
+
+	/* Host adapter parameters */
+	u8	numldrv;
+	u8	fw_version[7];
+	u8	bios_version[7];
+
+#ifdef CONFIG_PROC_FS
+	struct proc_dir_entry	*controller_proc_dir_entry;
+	struct proc_dir_entry	*proc_read;
+	struct proc_dir_entry	*proc_stat;
+	struct proc_dir_entry	*proc_mbox;
+
+#if MEGA_HAVE_ENH_PROC
+	struct proc_dir_entry	*proc_rr;
+	struct proc_dir_entry	*proc_battery;
+#define MAX_PROC_CHANNELS	4
+	struct proc_dir_entry	*proc_pdrvstat[MAX_PROC_CHANNELS];
+	struct proc_dir_entry	*proc_rdrvstat[MAX_PROC_CHANNELS];
+#endif
+
+#endif
+
+	int	has_64bit_addr;		/* are we using 64-bit addressing */
+	int	support_ext_cdb;
+	int	boot_ldrv_enabled;
+	int	boot_ldrv;
+	int	boot_pdrv_enabled;	/* boot from physical drive */
+	int	boot_pdrv_ch;		/* boot physical drive channel */
+	int	boot_pdrv_tgt;		/* boot physical drive target */
+
+
+	int	support_random_del;	/* Do we support random deletion of
+					   logdrvs */
+	int	read_ldidmap;	/* set after logical drive deltion. The
+				   logical drive number must be read from the
+				   map */
+	atomic_t	quiescent;	/* a stage reached when delete logical
+					   drive needs to be done. Stop
+					   sending requests to the hba till
+					   delete operation is completed */
+	spinlock_t	lock;
+	spinlock_t	*host_lock;	// pointer to appropriate lock
+
+	u8	logdrv_chan[MAX_CHANNELS+NVIRT_CHAN]; /* logical drive are on
+							what channels. */
+	int	mega_ch_class;
+
+	u8	sglen;	/* f/w supported scatter-gather list length */
+
+	scb_t			int_scb;
+	Scsi_Cmnd		int_scmd;
+	struct semaphore	int_mtx;	/* To synchronize the internal
+						commands */
+	wait_queue_head_t	int_waitq;	/* wait queue for internal
+						 cmds */
+
+	int	has_cluster;	/* cluster support on this HBA */
+}adapter_t;
+
+
+struct mega_hbas {
+	int is_bios_enabled;
+	adapter_t *hostdata_addr;
+};
+
+
+/*
+ * For state flag. Do not use LSB(8 bits) which are
+ * reserved for storing info about channels.
+ */
+#define IN_ABORT	0x80000000L
+#define IN_RESET	0x40000000L
+#define BOARD_MEMMAP	0x20000000L
+#define BOARD_IOMAP	0x10000000L
+#define BOARD_40LD   	0x08000000L
+#define BOARD_64BIT	0x04000000L
+
+#define INTR_VALID			0x40
+
+#define PCI_CONF_AMISIG			0xa0
+#define PCI_CONF_AMISIG64		0xa4
+
+
+#define MEGA_DMA_TYPE_NONE		0xFFFF
+#define MEGA_BULK_DATA			0x0001
+#define MEGA_SGLIST			0x0002
+
+/*
+ * lockscope definitions, callers can specify the lock scope with this data
+ * type. LOCK_INT would mean the caller has not acquired the lock before
+ * making the call and LOCK_EXT would mean otherwise.
+ */
+typedef enum { LOCK_INT, LOCK_EXT } lockscope_t;
+
+/*
+ * Parameters for the io-mapped controllers
+ */
+
+/* I/O Port offsets */
+#define CMD_PORT	 	0x00
+#define ACK_PORT	 	0x00
+#define TOGGLE_PORT		0x01
+#define INTR_PORT	  	0x0a
+
+#define MBOX_BUSY_PORT     	0x00
+#define MBOX_PORT0	 	0x04
+#define MBOX_PORT1	 	0x05
+#define MBOX_PORT2	 	0x06
+#define MBOX_PORT3	 	0x07
+#define ENABLE_MBOX_REGION 	0x0B
+
+/* I/O Port Values */
+#define ISSUE_BYTE	 	0x10
+#define ACK_BYTE	   	0x08
+#define ENABLE_INTR_BYTE   	0xc0
+#define DISABLE_INTR_BYTE  	0x00
+#define VALID_INTR_BYTE    	0x40
+#define MBOX_BUSY_BYTE     	0x10
+#define ENABLE_MBOX_BYTE   	0x00
+
+
+/* Setup some port macros here */
+#define issue_command(adapter)	\
+		outb_p(ISSUE_BYTE, (adapter)->base + CMD_PORT)
+
+#define irq_state(adapter)	inb_p((adapter)->base + INTR_PORT)
+
+#define set_irq_state(adapter, value)	\
+		outb_p((value), (adapter)->base + INTR_PORT)
+
+#define irq_ack(adapter)	\
+		outb_p(ACK_BYTE, (adapter)->base + ACK_PORT)
+
+#define irq_enable(adapter)	\
+	outb_p(ENABLE_INTR_BYTE, (adapter)->base + TOGGLE_PORT)
+
+#define irq_disable(adapter)	\
+	outb_p(DISABLE_INTR_BYTE, (adapter)->base + TOGGLE_PORT)
+
+
+/*
+ * This is our SYSDEP area. All kernel specific detail should be placed here -
+ * as much as possible
+ */
+
+/*
+ * End of SYSDEP area
+ */
+
+/*
+ * ASSERT macro for megaraid. This should panic but printk should do for now
+ */
+#ifdef DEBUG
+#define ASSERT( expression )						\
+	if( !(expression) ) {						\
+		panic("assertion failed: %s, file: %s, line: %d\n",	\
+				#expression, __FILE__, __LINE__);	\
+	}
+#else
+#define ASSERT(expression)
+#endif
+
+#define MBOX_ABORT_SLEEP	60
+#define MBOX_RESET_SLEEP	30
+
+const char *megaraid_info (struct Scsi_Host *);
+
+static int megaraid_detect(Scsi_Host_Template *);
+static void mega_find_card(Scsi_Host_Template *, u16, u16);
+static int mega_query_adapter(adapter_t *);
+static inline int issue_scb(adapter_t *, scb_t *);
+static int mega_setup_mailbox(adapter_t *);
+
+static int megaraid_queue (Scsi_Cmnd *, void (*)(Scsi_Cmnd *));
+static scb_t * mega_build_cmd(adapter_t *, Scsi_Cmnd *, int *);
+static inline scb_t *mega_allocate_scb(adapter_t *, Scsi_Cmnd *);
+static void __mega_runpendq(adapter_t *);
+static inline void mega_runpendq(adapter_t *);
+static int issue_scb_block(adapter_t *, u_char *);
+
+static void megaraid_isr_memmapped(int, void *, struct pt_regs *);
+static inline void megaraid_memmbox_ack_sequence(adapter_t *);
+static void megaraid_isr_iomapped(int, void *, struct pt_regs *);
+static inline void megaraid_iombox_ack_sequence(adapter_t *);
+
+static void mega_free_scb(adapter_t *, scb_t *);
+
+static int megaraid_release (struct Scsi_Host *);
+static int megaraid_command (Scsi_Cmnd *);
+static int megaraid_abort(Scsi_Cmnd *);
+static int megaraid_reset(Scsi_Cmnd *);
+static int megaraid_biosparam (Disk *, kdev_t, int *);
+
+static int mega_build_sglist (adapter_t *adapter, scb_t *scb,
+			      u32 *buffer, u32 *length);
+static inline int mega_busywait_mbox (adapter_t *);
+static int __mega_busywait_mbox (adapter_t *);
+static inline void mega_cmd_done(adapter_t *, u8 [], int, int);
+static inline void mega_free_sgl (adapter_t *adapter);
+static void mega_8_to_40ld (mraid_inquiry *inquiry,
+		mega_inquiry3 *enquiry3, mega_product_info *);
+
+static int megaraid_reboot_notify (struct notifier_block *,
+				   unsigned long, void *);
+static int megadev_open (struct inode *, struct file *);
+static int megadev_ioctl (struct inode *, struct file *, unsigned int,
+		unsigned long);
+static int mega_m_to_n(void *, nitioctl_t *);
+static int mega_n_to_m(void *, megacmd_t *);
+static int megadev_close (struct inode *, struct file *);
+
+static int mega_init_scb (adapter_t *);
+
+static int mega_is_bios_enabled (adapter_t *);
+static void mega_reorder_hosts (void);
+static void mega_swap_hosts (struct Scsi_Host *, struct Scsi_Host *);
+
+#ifdef CONFIG_PROC_FS
+static void mega_create_proc_entry(int, struct proc_dir_entry *);
+static int proc_read_config(char *, char **, off_t, int, int *, void *);
+static int proc_read_stat(char *, char **, off_t, int, int *, void *);
+static int proc_read_mbox(char *, char **, off_t, int, int *, void *);
+static int proc_rebuild_rate(char *, char **, off_t, int, int *, void *);
+static int proc_battery(char *, char **, off_t, int, int *, void *);
+static int proc_pdrv_ch0(char *, char **, off_t, int, int *, void *);
+static int proc_pdrv_ch1(char *, char **, off_t, int, int *, void *);
+static int proc_pdrv_ch2(char *, char **, off_t, int, int *, void *);
+static int proc_pdrv_ch3(char *, char **, off_t, int, int *, void *);
+static int proc_pdrv(adapter_t *, char *, int);
+static int proc_rdrv_10(char *, char **, off_t, int, int *, void *);
+static int proc_rdrv_20(char *, char **, off_t, int, int *, void *);
+static int proc_rdrv_30(char *, char **, off_t, int, int *, void *);
+static int proc_rdrv_40(char *, char **, off_t, int, int *, void *);
+static int proc_rdrv(adapter_t *, char *, int, int);
+
+static int mega_adapinq(adapter_t *, dma_addr_t);
+static int mega_internal_dev_inquiry(adapter_t *, u8, u8, dma_addr_t);
+static inline caddr_t mega_allocate_inquiry(dma_addr_t *, struct pci_dev *);
+static inline void mega_free_inquiry(caddr_t, dma_addr_t, struct pci_dev *);
+static int mega_print_inquiry(char *, char *);
+#endif
+
+static int mega_support_ext_cdb(adapter_t *);
+static mega_passthru* mega_prepare_passthru(adapter_t *, scb_t *,
+		Scsi_Cmnd *, int, int);
+static mega_ext_passthru* mega_prepare_extpassthru(adapter_t *,
+		scb_t *, Scsi_Cmnd *, int, int);
+static void mega_enum_raid_scsi(adapter_t *);
+static int mega_partsize(Disk *, kdev_t, int *);
+static void mega_get_boot_drv(adapter_t *);
+static inline int mega_get_ldrv_num(adapter_t *, Scsi_Cmnd *, int);
+static int mega_support_random_del(adapter_t *);
+static int mega_del_logdrv(adapter_t *, int);
+static int mega_do_del_logdrv(adapter_t *, int);
+static void mega_get_max_sgl(adapter_t *);
+static int mega_internal_command(adapter_t *, lockscope_t, megacmd_t *,
+		mega_passthru *);
+static void mega_internal_done(Scsi_Cmnd *);
+static int mega_support_cluster(adapter_t *);
+#endif
+
+/* vi: set ts=8 sw=8 tw=78: */
diff -urN linux-2.4.23-pre6/drivers/scsi/nsp32.c linux-2.4.23-pre7/drivers/scsi/nsp32.c
--- linux-2.4.23-pre6/drivers/scsi/nsp32.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/nsp32.c	2003-10-09 17:48:22.000000000 -0700
@@ -1,8 +1,8 @@
 /*
  * NinjaSCSI-32Bi Cardbus, NinjaSCSI-32UDE PCI/CardBus SCSI driver
- * Copyright (C) 2001, 2002
+ * Copyright (C) 2001, 2002, 2003
  *      YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
- *      GOTO Masanori <gotom@debian.or.jp>
+ *      GOTO Masanori <gotom@debian.or.jp>, <gotom@debian.org>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -13,6 +13,14 @@
  * 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.
+ *
+ *
+ * Revision History:
+ *   1.0: Initial Release.
+ *   1.1: Add /proc SDTR status.
+ *        Remove obsolete error handler nsp32_reset.
+ *        Some clean up.
+ *   1.2: PowerPC (big endian) support.
  */
 
 #include <linux/version.h>
@@ -25,10 +33,12 @@
 #include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/major.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
+#include <linux/interrupt.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/ctype.h>
+#include <linux/interrupt.h>
 
 #include <asm/dma.h>
 #include <asm/system.h>
@@ -39,373 +49,327 @@
 #include <scsi/scsi_ioctl.h>
 #include <scsi/scsi.h>
 
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# include <linux/blk.h>
+#endif
+
 #include "nsp32.h"
 
 
-static int trans_mode = 0;	/* default: BIOS */
-static int auto_param = 0;	/* default: ON */
-MODULE_PARM(trans_mode, "i");
-MODULE_PARM(auto_param, "i");
-MODULE_PARM_DESC(trans_mode, "transfer mode (0: BIOS 1: Async 2: Ultra20M");
-MODULE_PARM_DESC(auto_param, "AutoParameter mode (0: ON 1: OFF)");
+/***********************************************************************
+ * Module parameters
+ */
+static int       trans_mode = 0;	/* default: BIOS */
+MODULE_PARM     (trans_mode, "i");
+MODULE_PARM_DESC(trans_mode, "transfer mode (0: BIOS(default) 1: Async 2: Ultra20M");
 #define ASYNC_MODE    1
 #define ULTRA20M_MODE 2
 
+static int       auto_param = 0;	/* default: ON */
+MODULE_PARM     (auto_param, "i");
+MODULE_PARM_DESC(auto_param, "AutoParameter mode (0: ON(default) 1: OFF)");
+
+static int       disc_priv  = 1;	/* default: OFF */
+MODULE_PARM     (disc_priv,  "i");
+MODULE_PARM_DESC(disc_priv,  "disconnection privilege mode (0: ON 1: OFF(default))");
+
 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>, GOTO Masanori <gotom@debian.or.jp>");
-MODULE_DESCRIPTION("Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI host bus adapter module");
+MODULE_DESCRIPTION("Workbit NinjaSCSI-32Bi/UDE CardBus/PCI SCSI host bus adapter module");
 MODULE_LICENSE("GPL");
 
-static const char *nsp32_release_version = "1.0";
-
-
-/*
- * structure for DMA/Scatter Gather list
- */
-#define AUTOPARAM_SIZE		(sizeof(int)*0x15)	/* 4x15H = 0x60 */
-#define NSP_SG_SIZE		SG_ALL
-#define NSP32_SG_END_SGT	0x80000000		/* Last SGT marker */
-#define NSP32_SG_CNT_MASK	0x1FFFF
-
-struct nsp32_sgtable {
-	unsigned long		addr;		/* transfer address */
-	unsigned long		len;		/* transfer length.
-						   Bit (24-32) is for SGT_END */
-};
-
-struct nsp32_sglun {
-	struct nsp32_sgtable sgt[NSP_SG_SIZE+1];	/* SG table */
-};
-
-
-/*
- * host data structure
- */
-/* message in/out buffer */
-#define MSGOUTBUF_MAX	13  /* 13 is ok ? */
-#define MSGINBUF_MAX	13
-
-/* flag for trans_method */
-#define NSP32_TRANSFER_BUSMASTER	BIT(0)
-#define NSP32_TRANSFER_MMIO		BIT(1)	/* Not supported yet */
-#define NSP32_TRANSFER_PIO		BIT(2)	/* Not supported yet */
-
-
-/*
- * SCSI TARGET/LUN definition
- */
-#define NSP32_HOST_SCSIID	7	/* SCSI initiator is everytime defined as 7 */
-#define MAX_TARGET		8
-#define MAX_LUN			8	/* XXX: In SPI3, max number of LUN is 64. */
-
+static const char *nsp32_release_version = "1.2";
 
-/*
- * structure for synchronous transfer negotiation data
- */
-#define SYNC_NOT_YET	0
-#define SYNC_OK		1
-#define SYNC_NG		2
-
-struct nsp32_sync_table {
-	unsigned char	period_num;	/* period number */
-	unsigned char	ackwidth;	/* ack width designated by period */
-	unsigned char	start_period;	/* search range - start period */
-	unsigned char	end_period;	/* search range - end period */
-};
 
-
-/*
- * structure for target device static data
+/****************************************************************************
+ * Supported hardware
  */
-/* flag for nsp32_target.sync_flag */
-#define SDTR_INITIATOR		BIT(0)	/* sending SDTR from initiator */
-#define SDTR_TARGET		BIT(1)	/* sending SDTR from target */
-#define SDTR_DONE		BIT(2)	/* exchanging SDTR has been processed */
-
-/* syncronous period value for nsp32_target.config_max */
-#define FAST5M			0x32
-#define FAST10M			0x19
-#define ULTRA20M		0x0c
-
-/* flag for nsp32_target.{sync_offset}, period */
-#define ASYNC_OFFSET		0	/* asynchronous transfer */
-#define SYNC_OFFSET		0xf	/* synchronous transfer max offset */
-
-/* syncreg:
-      07 06 05 04 03 02 01 00
-      ---PERIOD-- ---OFFSET--   */
-#define TO_SYNCREG(period, offset)	(period << 4 | offset)
-
-struct nsp32_target {
-	unsigned char	syncreg;	/* value for SYNCREG  */
-	unsigned char	ackwidth;	/* value for ACKWIDTH */
-	unsigned char	offset;		/* sync offset (0-15) */
-	int		sync_flag;	/* SDTR_*, 0 */
-	int		limit_entry;	/* max speed limit entry designated
-					   by EEPROM configuration */
+static struct pci_device_id nsp32_pci_table[] __devinitdata = {
+	{
+		.vendor      = PCI_VENDOR_ID_IODATA,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_IODATA,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32BI_KME,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_KME,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32BI_WBT,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_WORKBIT,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_WORKBIT_STANDARD,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_PCI_WORKBIT,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_LOGITEC,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_PCI_LOGITEC,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_PCI_MELCO,
+	},
+	{
+		.vendor      = PCI_VENDOR_ID_WORKBIT,
+		.device      = PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO_II,
+		.subvendor   = PCI_ANY_ID,
+		.subdevice   = PCI_ANY_ID,
+		.driver_data = MODEL_PCI_MELCO,
+	},
+	{0,0,},
 };
+MODULE_DEVICE_TABLE(pci, nsp32_pci_table);
 
-typedef struct _nsp32_hw_data {
-	int IrqNumber;
-	int BaseAddress;
-	int NumAddress;
-#define NSP32_MMIO_OFFSET 0x0800
-	unsigned long MmioAddress;
-	unsigned long length;
-
-	Scsi_Cmnd *CurrentSC;
-
-	struct pci_dev *Pci;
-	const struct pci_device_id *pci_devid;
-	struct Scsi_Host *Host;
-	spinlock_t Lock;
-
-	char info_str[100];
-
-	/* allocated memory region */
-	struct nsp32_lunt	*lunt_list;	/* kmalloc region for lunt */
-	struct nsp32_sglun	*sg_list;	/* sglist virtual address */
-	dma_addr_t		sgaddr;		/* physical address of hw_sg_table */
-	unsigned char		*autoparam;	/* auto parameter transfer region */
-	dma_addr_t		apaddr;		/* physical address of autoparam */
-	int 			cur_entry;	/* current sgt entry */
-
-	/* target/LUN */
-	struct nsp32_lunt	*curlunt;	/* Current connected LUN table */
-	struct nsp32_lunt	*lunt[MAX_TARGET][MAX_LUN];  /* All LUN table */
-	struct nsp32_target	*curtarget;	/* Current connected SCSI ID */
-	struct nsp32_target	target[MAX_TARGET];	     /* SCSI ID */
-	int			pid;		/* Current connected target ID */
-	int			plun;		/* Current connected target LUN */
-
-	/* behavior setting parameters */
-	int			trans_method;	/* transfer method flag */
-	int			resettime;	/* Reset time */
-	int 			clock;	       	/* clock dividing flag */
-	struct nsp32_sync_table	*synct;		/* sync_table determined by clock */
-	int			syncnum;	/* the max number of synct element */
-
-	/* message buffer */
-        unsigned char	msgoutbuf[MSGOUTBUF_MAX]; /* msgout buffer */
-	char		msgoutlen;		  /* msgoutbuf length */
-	unsigned char	msginbuf[MSGINBUF_MAX];	  /* megin buffer */
-	char		msginlen;		  /* msginbuf length */
-
-
-} nsp32_hw_data;
 static nsp32_hw_data nsp32_data_base;  /* probe <-> detect glue */
 
 
 /*
- * TIME definition
- */
-#define RESET_HOLD_TIME		10000	/* reset time in us (SCSI-2 says the
-					   minimum is 25us) */
-#define SEL_TIMEOUT_TIME	10000	/* 250ms defined in SCSI specification
-					   (25.6us/1unit) */
-#define ARBIT_TIMEOUT_TIME	100	/* 100us */
-#define REQSACK_TIMEOUT_TIME	10000	/* max wait time for REQ/SACK assertion
-					   or negation, 10000us == 10ms */
-
-/*
- * structure for connected LUN dynamic data
- *
- * Note: Currently tagged queuing is disabled, each nsp32_lunt holds
- *       one SCSI command and one state.
- */
-#define DISCPRIV_OK		BIT(0)		/* DISCPRIV Enable mode */
-#define MSGIN03			BIT(1)		/* Auto Msg In 03 Flag */
-
-struct nsp32_lunt {
-	Scsi_Cmnd		*SCpnt;		/* Current Handling Scsi_Cmnd */
-	unsigned long		save_datp;	/* Save Data Pointer - saved position from initial address */
-	int			msgin03;	/* auto msg in 03 flag */
-	unsigned int		sg_num;		/* Total number of SG entries */
-	int			cur_entry;	/* Current SG entry number */
-	struct nsp32_sglun	*sglun;		/* sg table per lun */
-	long			sglun_paddr;	/* sglun physical address */
-};
-
-
-/*
  * Period/AckWidth speed conversion table
  *
  * Note: This period/ackwidth speed table must be in descending order.
  */
-static struct nsp32_sync_table nsp32_sync_table_40M[] = {
-     /* {PNo, AW,  SP,   EP}  Speed(MB/s) Period AckWidth */
-	{0x1, 0, 0x0c, 0x0c},	/*  20.0 :  50ns,  25ns */
-	{0x2, 0, 0x0d, 0x18},	/*  13.3 :  75ns,  25ns */
-	{0x3, 1, 0x19, 0x19},	/*  10.0 : 100ns,  50ns */
-	{0x4, 1, 0x1a, 0x1f},	/*   8.0 : 125ns,  50ns */
-	{0x5, 2, 0x20, 0x25},	/*   6.7 : 150ns,  75ns */
-	{0x6, 2, 0x26, 0x31},	/*   5.7 : 175ns,  75ns */
-	{0x7, 3, 0x32, 0x32},	/*   5.0 : 200ns, 100ns */
-	{0x8, 3, 0x33, 0x38},	/*   4.4 : 225ns, 100ns */
-	{0x9, 3, 0x39, 0x3e},	/*   4.0 : 250ns, 100ns */
+static nsp32_sync_table nsp32_sync_table_40M[] = {
+     /* {PNo, AW,   SP,   EP, SREQ smpl}  Speed(MB/s) Period AckWidth */
+	{0x1,  0, 0x0c, 0x0c, SMPL_40M},  /*  20.0 :  50ns,  25ns */
+	{0x2,  0, 0x0d, 0x18, SMPL_40M},  /*  13.3 :  75ns,  25ns */
+	{0x3,  1, 0x19, 0x19, SMPL_40M},  /*  10.0 : 100ns,  50ns */
+	{0x4,  1, 0x1a, 0x1f, SMPL_20M},  /*   8.0 : 125ns,  50ns */
+	{0x5,  2, 0x20, 0x25, SMPL_20M},  /*   6.7 : 150ns,  75ns */
+	{0x6,  2, 0x26, 0x31, SMPL_20M},  /*   5.7 : 175ns,  75ns */
+	{0x7,  3, 0x32, 0x32, SMPL_20M},  /*   5.0 : 200ns, 100ns */
+	{0x8,  3, 0x33, 0x38, SMPL_10M},  /*   4.4 : 225ns, 100ns */
+	{0x9,  3, 0x39, 0x3e, SMPL_10M},  /*   4.0 : 250ns, 100ns */
+	{0xa,  3, 0x3f, 0x44, SMPL_10M},  /*   3.64: 275ns, 100ns */
+	{0xb,  3, 0x45, 0x4b, SMPL_10M},  /*   3.33: 300ns, 100ns */
+	{0xc,  3, 0x4c, 0x53, SMPL_10M},  /*   3.01: 325ns, 100ns */
+	{0xd,  3, 0x54, 0x57, SMPL_10M},  /*   2.86: 350ns, 100ns */
+	{0xe,  3, 0x58, 0x5d, SMPL_10M},  /*   2.67: 375ns, 100ns */
+	{0xf,  3, 0x5e, 0x64, SMPL_10M},  /*   2.5 : 400ns, 100ns */
 };
-static const int nsp32_table_40M_num =
-		sizeof(nsp32_sync_table_40M)/sizeof(struct nsp32_sync_table);
 
-static struct nsp32_sync_table nsp32_sync_table_20M[] = {
-	{0x1, 0, 0x19, 0x19},	/* 10.0 : 100ns,  50ns */
-	{0x2, 0, 0x1a, 0x25},	/*  6.7 : 150ns,  50ns */
-	{0x3, 1, 0x26, 0x32},	/*  5.0 : 200ns, 100ns */
-	{0x4, 1, 0x33, 0x3e},	/*  4.0 : 250ns, 100ns */
-	{0x5, 2, 0x3f, 0x4b},	/*  3.3 : 300ns, 150ns */
-	{0x6, 2, 0x4c, 0x57},	/*  2.8 : 350ns, 150ns */
-	{0x7, 3, 0x58, 0x64},	/*  2.5 : 400ns, 200ns */
-	{0x8, 3, 0x65, 0x70},	/*  2.2 : 450ns, 200ns */
-	{0x9, 3, 0x71, 0x7d},	/*  2.0 : 500ns, 200ns */
+static nsp32_sync_table nsp32_sync_table_20M[] = {
+	{0x1,  0, 0x19, 0x19, SMPL_40M},  /* 10.0 : 100ns,  50ns */
+	{0x2,  0, 0x1a, 0x25, SMPL_20M},  /*  6.7 : 150ns,  50ns */
+	{0x3,  1, 0x26, 0x32, SMPL_20M},  /*  5.0 : 200ns, 100ns */
+	{0x4,  1, 0x33, 0x3e, SMPL_10M},  /*  4.0 : 250ns, 100ns */
+	{0x5,  2, 0x3f, 0x4b, SMPL_10M},  /*  3.3 : 300ns, 150ns */
+	{0x6,  2, 0x4c, 0x57, SMPL_10M},  /*  2.8 : 350ns, 150ns */
+	{0x7,  3, 0x58, 0x64, SMPL_10M},  /*  2.5 : 400ns, 200ns */
+	{0x8,  3, 0x65, 0x70, SMPL_10M},  /*  2.2 : 450ns, 200ns */
+	{0x9,  3, 0x71, 0x7d, SMPL_10M},  /*  2.0 : 500ns, 200ns */
+	{0xa,  3, 0x7e, 0x89, SMPL_10M},  /*  1.82: 550ns, 200ns */
+	{0xb,  3, 0x8a, 0x95, SMPL_10M},  /*  1.67: 550ns, 200ns */
+	{0xc,  3, 0x96, 0xa2, SMPL_10M},  /*  1.54: 550ns, 200ns */
+	{0xd,  3, 0xa3, 0xae, SMPL_10M},  /*  1.43: 550ns, 200ns */
+	{0xe,  3, 0xaf, 0xbb, SMPL_10M},  /*  1.33: 550ns, 200ns */
+	{0xf,  3, 0xbc, 0xc8, SMPL_10M},  /*  1.25: 550ns, 200ns */
 };
-static const int nsp32_table_20M_num =
-		sizeof(nsp32_sync_table_20M)/sizeof(struct nsp32_sync_table);
 
-static struct nsp32_sync_table nsp32_sync_table_pci[] = {
-	{0x1, 0, 0x0c, 0x0f},	/* 16.6 :  60ns,  30ns */
-	{0x2, 0, 0x10, 0x16},	/* 11.1 :  90ns,  30ns */
-	{0x3, 1, 0x17, 0x1e},	/*  8.3 : 120ns,  60ns */
-	{0x4, 1, 0x1f, 0x25},	/*  6.7 : 150ns,  60ns */
-	{0x5, 2, 0x26, 0x2d},	/*  5.6 : 180ns,  90ns */
-	{0x6, 2, 0x2e, 0x34},	/*  4.8 : 210ns,  90ns */
-	{0x7, 3, 0x35, 0x3c},	/*  4.2 : 240ns, 120ns */
-	{0x8, 3, 0x3d, 0x43},	/*  3.7 : 270ns, 120ns */
-	{0x9, 3, 0x44, 0x4b}, 	/*  3.3 : 300ns, 120ns */
+static nsp32_sync_table nsp32_sync_table_pci[] = {
+	{0x1,  0, 0x0c, 0x0f, SMPL_40M},  /* 16.6 :  60ns,  30ns */
+	{0x2,  0, 0x10, 0x16, SMPL_40M},  /* 11.1 :  90ns,  30ns */
+	{0x3,  1, 0x17, 0x1e, SMPL_20M},  /*  8.3 : 120ns,  60ns */
+	{0x4,  1, 0x1f, 0x25, SMPL_20M},  /*  6.7 : 150ns,  60ns */
+	{0x5,  2, 0x26, 0x2d, SMPL_20M},  /*  5.6 : 180ns,  90ns */
+	{0x6,  2, 0x2e, 0x34, SMPL_10M},  /*  4.8 : 210ns,  90ns */
+	{0x7,  3, 0x35, 0x3c, SMPL_10M},  /*  4.2 : 240ns, 120ns */
+	{0x8,  3, 0x3d, 0x43, SMPL_10M},  /*  3.7 : 270ns, 120ns */
+	{0x9,  3, 0x44, 0x4b, SMPL_10M},  /*  3.3 : 300ns, 120ns */
+	{0xa,  3, 0x4c, 0x53, SMPL_10M},  /*  3.0 : 330ns, 120ns */
+	{0xb,  3, 0x54, 0x59, SMPL_10M},  /*  2.8 : 360ns, 120ns */
+	{0xc,  3, 0x5a, 0x60, SMPL_10M},  /*  2.6 : 390ns, 120ns */
+	{0xd,  3, 0x61, 0x68, SMPL_10M},  /*  2.4 : 420ns, 120ns */
+	{0xe,  3, 0x69, 0x71, SMPL_10M},  /*  2.2 : 450ns, 120ns */
+	{0xf,  3, 0x72, 0x77, SMPL_10M},  /*  2.1 : 480ns, 120ns */
 };
-static const int nsp32_table_pci_num =
-		sizeof(nsp32_sync_table_pci)/sizeof(struct nsp32_sync_table);
 
 /*
  * function declaration
  */
-static int nsp32_detect(Scsi_Host_Template *);
-static int nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static const char *nsp32_info(struct Scsi_Host *);
-static int nsp32_eh_abort(Scsi_Cmnd *);
-static int nsp32_eh_bus_reset(Scsi_Cmnd *);
-static int nsp32_eh_host_reset(Scsi_Cmnd *);
-static int nsp32_reset(Scsi_Cmnd *, unsigned int);
-static int nsp32_release(struct Scsi_Host *);
-static int nsp32_proc_info(char *, char **, off_t, int, int, int);
-static int __devinit nsp32_probe(struct pci_dev *, const struct pci_device_id *);
+/* module entry point */
+static int  __devinit nsp32_probe (struct pci_dev *, const struct pci_device_id *);
 static void __devexit nsp32_remove(struct pci_dev *);
-static int __init init_nsp32(void);
-static void __exit exit_nsp32(void);
+static int  __init    init_nsp32  (void);
+static void __exit    exit_nsp32  (void);
+
+/* struct Scsi_Host_Template */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+static int         nsp32_proc_info   (struct Scsi_Host *, char *, char **, off_t, int, int);
+#else
+static int         nsp32_proc_info   (char *, char **, off_t, int, int, int);
+#endif
 
-static void nsp32_message(char *, int, char *, char *, ...);
-static void nsp32_dmessage(char *, int, int, char *, ...);
-static void nsp32_build_identify(nsp32_hw_data *, Scsi_Cmnd *);
-static void nsp32_build_sdtr(nsp32_hw_data *, unsigned char, unsigned char);
-static void nsp32_build_nop(nsp32_hw_data *);
-static void nsp32_build_reject(nsp32_hw_data *);
-static int nsp32hw_start_selection(Scsi_Cmnd *, nsp32_hw_data *);
-static int nsp32_selection_autoscsi(Scsi_Cmnd *, nsp32_hw_data *);
-static int nsp32_reselection(nsp32_hw_data *, unsigned char);
-static int nsp32hw_setup_sg_table(Scsi_Cmnd *, nsp32_hw_data *);
-static int nsp32hw_init(struct Scsi_Host *);
-static void nsp32_scsi_done(nsp32_hw_data *, Scsi_Cmnd *);
-static int nsp32_busfree_occur(nsp32_hw_data *, unsigned short);
-static void nsp32_adjust_busfree(nsp32_hw_data *, unsigned int);
-static void nsp32_msgout_occur(nsp32_hw_data *);
-static void nsp32_restart_autoscsi(nsp32_hw_data *, unsigned short);
-static void nsp32_msgin_occur(nsp32_hw_data *, unsigned long, unsigned short);
-static void nsp32_analyze_sdtr(nsp32_hw_data *);
-static int nsp32_search_period_entry(nsp32_hw_data *,struct nsp32_target *, unsigned char);
-static void nsp32_set_async(nsp32_hw_data *, struct nsp32_target *);
-static void nsp32_set_max_sync(nsp32_hw_data *, struct nsp32_target *, unsigned char *, unsigned char *);
-static void nsp32_set_sync_entry(nsp32_hw_data *, struct nsp32_target *, int, unsigned char);
-static void nsp32_wait_req(nsp32_hw_data *, int);
-static void nsp32_wait_sack(nsp32_hw_data *, int);
-static void nsp32_sack_assert(nsp32_hw_data *);
-static void nsp32_sack_negate(nsp32_hw_data *);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+static int         nsp32_detect      (struct pci_dev *pdev);
+#else
+static int         nsp32_detect      (Scsi_Host_Template *);
+#endif
+static int         nsp32_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static const char *nsp32_info        (struct Scsi_Host *);
+static int         nsp32_release     (struct Scsi_Host *);
+
+/* SCSI error handler */
+static int         nsp32_eh_abort     (Scsi_Cmnd *);
+static int         nsp32_eh_bus_reset (Scsi_Cmnd *);
+static int         nsp32_eh_host_reset(Scsi_Cmnd *);
+
+/* generate SCSI message */
+static void nsp32_build_identify(Scsi_Cmnd *);
+static void nsp32_build_nop     (Scsi_Cmnd *);
+static void nsp32_build_reject  (Scsi_Cmnd *);
+static void nsp32_build_sdtr    (Scsi_Cmnd *, unsigned char, unsigned char);
+
+/* SCSI message handler */
+static int  nsp32_busfree_occur(Scsi_Cmnd *, unsigned short);
+static void nsp32_msgout_occur (Scsi_Cmnd *);
+static void nsp32_msgin_occur  (Scsi_Cmnd *, unsigned long, unsigned short);
+
+static int           nsp32_setup_sg_table    (Scsi_Cmnd *);
+static unsigned long nsp32_msgout_register   (Scsi_Cmnd *);
+static int           nsp32_selection_autopara(Scsi_Cmnd *);
+static int           nsp32_selection_autoscsi(Scsi_Cmnd *);
+static void          nsp32_scsi_done         (Scsi_Cmnd *);
+static int           nsp32_arbitration       (Scsi_Cmnd *, unsigned int);
+static int           nsp32_reselection       (Scsi_Cmnd *, unsigned char);
+static void          nsp32_adjust_busfree    (Scsi_Cmnd *, unsigned int);
+static void          nsp32_restart_autoscsi  (Scsi_Cmnd *, unsigned short);
+
+/* SCSI SDTR */
+static void nsp32_analyze_sdtr       (Scsi_Cmnd *);
+static int  nsp32_search_period_entry(nsp32_hw_data *, nsp32_target *, unsigned char);
+static void nsp32_set_async          (nsp32_hw_data *, nsp32_target *);
+static void nsp32_set_max_sync       (nsp32_hw_data *, nsp32_target *, unsigned char *, unsigned char *);
+static void nsp32_set_sync_entry     (nsp32_hw_data *, nsp32_target *, int, unsigned char);
+
+/* SCSI bus status handler */
+static void nsp32_wait_req    (nsp32_hw_data *, int);
+static void nsp32_wait_sack   (nsp32_hw_data *, int);
+static void nsp32_sack_assert (nsp32_hw_data *);
+static void nsp32_sack_negate (nsp32_hw_data *);
 static void nsp32_do_bus_reset(nsp32_hw_data *);
-static void do_nsp32_isr(int, void *, struct pt_regs *);
 
-static int nsp32_getprom_param(nsp32_hw_data *);
-static int nsp32_getprom_new(nsp32_hw_data *);
-static int nsp32_getprom_standard(nsp32_hw_data *);
-static int nsp32_prom_read(nsp32_hw_data *, int);
-static void nsp32_prom_start(nsp32_hw_data *);
-static void nsp32_prom_stop(nsp32_hw_data *);
-static void nsp32_prom_write(nsp32_hw_data *, int);
-static int nsp32_prom_fetch(nsp32_hw_data *);
-static inline void nsp32_prom_set(nsp32_hw_data *, int, int);
-static inline int nsp32_prom_get(nsp32_hw_data *, int);
+/* hardware interrupt handler */
+static irqreturn_t do_nsp32_isr(int, void *, struct pt_regs *);
+
+/* initialize hardware */
+static int  nsp32hw_init(nsp32_hw_data *);
+
+/* EEPROM handler */
+static        int  nsp32_getprom_param (nsp32_hw_data *);
+static        int  nsp32_getprom_at24  (nsp32_hw_data *);
+static        int  nsp32_getprom_c16   (nsp32_hw_data *);
+static        void nsp32_prom_start    (nsp32_hw_data *);
+static        void nsp32_prom_stop     (nsp32_hw_data *);
+static        int  nsp32_prom_read     (nsp32_hw_data *, int);
+static        int  nsp32_prom_read_bit (nsp32_hw_data *);
+static        void nsp32_prom_write_bit(nsp32_hw_data *, int);
+static inline void nsp32_prom_set      (nsp32_hw_data *, int, int);
+static inline int  nsp32_prom_get      (nsp32_hw_data *, int);
 
+/* debug/warning/info message */
+static void nsp32_message (const char *, int, char *, char *, ...);
+#ifdef NSP32_DEBUG
+static void nsp32_dmessage(const char *, int, int,    char *, ...);
+#endif
 
 /*
  * max_sectors is currently limited up to 128.
  */
-static Scsi_Host_Template driver_template = {
-	.proc_name =			"nsp32",
-	.name =				"Workbit NinjaSCSI-32Bi/UDE",
-	.proc_info =			nsp32_proc_info,
-	.detect =			nsp32_detect,
-	.info =				nsp32_info,
-	.queuecommand =			nsp32_queuecommand,
-	.can_queue =			1,
-	.sg_tablesize =			NSP_SG_SIZE,
-	.max_sectors =			128,
-	.cmd_per_lun =			1,
-	.this_id =			7,
-	.use_clustering =		DISABLE_CLUSTERING,
-	.eh_abort_handler =       	nsp32_eh_abort,
-	.eh_device_reset_handler =	NULL,
-	.eh_bus_reset_handler =		nsp32_eh_bus_reset,
-	.eh_host_reset_handler =	nsp32_eh_host_reset,
-	.reset =			nsp32_reset,
-	.release =			nsp32_release,
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
-	.use_new_eh_code =        	1,
+static Scsi_Host_Template nsp32_template = {
+	.proc_name			= "nsp32",
+	.name				= "Workbit NinjaSCSI-32Bi/UDE",
+	.proc_info			= nsp32_proc_info,
+	.info				= nsp32_info,
+	.queuecommand			= nsp32_queuecommand,
+	.can_queue			= 1,
+	.sg_tablesize			= NSP32_SG_SIZE,
+	.max_sectors			= 128,
+	.cmd_per_lun			= 1,
+	.this_id			= NSP32_HOST_SCSIID,
+	.use_clustering			= DISABLE_CLUSTERING,
+	.eh_abort_handler       	= nsp32_eh_abort,
+/*	.eh_device_reset_handler	= NULL, */
+	.eh_bus_reset_handler		= nsp32_eh_bus_reset,
+	.eh_host_reset_handler		= nsp32_eh_host_reset,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,74))
+	.detect				= nsp32_detect,
+	.release			= nsp32_release,
+	.use_new_eh_code        	= 1,
 #else
-	/* .highmem_io =		1,	*/
+/*	.highmem_io			= 1, */
 #endif
 };
 
 #include "nsp32_io.h"
 
-/*
+/***********************************************************************
  * debug, error print
  */
-#define nsp32_msg(type, args...) \
-	nsp32_message(__FUNCTION__, __LINE__, (type), ## args)
-#define nsp32_dbg(mask, args...) \
-	nsp32_dmessage(__FUNCTION__, __LINE__, (mask), ## args)
-
 #ifndef NSP32_DEBUG
-# define NSP32_DEBUG_MASK		0x000000
+# define NSP32_DEBUG_MASK	      0x000000
+# define nsp32_msg(type, args...)     nsp32_message ("", 0, (type), args)
+# define nsp32_dbg(mask, args...)     /* */
 #else
-# define NSP32_DEBUG_MASK		0xffffff
+# define NSP32_DEBUG_MASK	      0xffffff
+# define nsp32_msg(type, args...) \
+	nsp32_message (__FUNCTION__, __LINE__, (type), args)
+# define nsp32_dbg(mask, args...) \
+	nsp32_dmessage(__FUNCTION__, __LINE__, (mask), args)
 #endif
 
-#define NSP32_DEBUG_QUEUECOMMAND	0x000001
-#define NSP32_DEBUG_REGISTER		0x000002
-#define NSP32_DEBUG_AUTOSCSI		0x000004
-#define NSP32_DEBUG_INTR		0x000008
-#define NSP32_DEBUG_SGLIST		0x000010
-#define NSP32_DEBUG_BUSFREE		0x000020
-#define NSP32_DEBUG_CDB_CONTENTS	0x000040
-#define NSP32_DEBUG_RESELECTION		0x000080
-#define NSP32_DEBUG_MSGINOCCUR		0x000100
-#define NSP32_DEBUG_EEPROM		0x000200
-#define NSP32_DEBUG_MSGOUTOCCUR		0x000400
-#define NSP32_DEBUG_BUSRESET		0x000800
-#define NSP32_DEBUG_RESTART		0x001000
-#define NSP32_DEBUG_SYNC		0x002000
-#define NSP32_DEBUG_WAIT		0x004000
-#define NSP32_DEBUG_TARGETFLAG		0x008000
-#define NSP32_DEBUG_PROC		0x010000
-#define NSP32_DEBUG_INIT		0x020000
-#define NSP32_SPECIAL_PRINT_REGISTER	0x100000
+#define NSP32_DEBUG_QUEUECOMMAND	BIT(0)
+#define NSP32_DEBUG_REGISTER		BIT(1)
+#define NSP32_DEBUG_AUTOSCSI		BIT(2)
+#define NSP32_DEBUG_INTR		BIT(3)
+#define NSP32_DEBUG_SGLIST		BIT(4)
+#define NSP32_DEBUG_BUSFREE		BIT(5)
+#define NSP32_DEBUG_CDB_CONTENTS	BIT(6)
+#define NSP32_DEBUG_RESELECTION		BIT(7)
+#define NSP32_DEBUG_MSGINOCCUR		BIT(8)
+#define NSP32_DEBUG_EEPROM		BIT(9)
+#define NSP32_DEBUG_MSGOUTOCCUR		BIT(10)
+#define NSP32_DEBUG_BUSRESET		BIT(11)
+#define NSP32_DEBUG_RESTART		BIT(12)
+#define NSP32_DEBUG_SYNC		BIT(13)
+#define NSP32_DEBUG_WAIT		BIT(14)
+#define NSP32_DEBUG_TARGETFLAG		BIT(15)
+#define NSP32_DEBUG_PROC		BIT(16)
+#define NSP32_DEBUG_INIT		BIT(17)
+#define NSP32_SPECIAL_PRINT_REGISTER	BIT(20)
 
 #define NSP32_DEBUG_BUF_LEN		100
 
-static void nsp32_message(char *func, int line, char *type, char *fmt, ...)
+static void nsp32_message(const char *func, int line, char *type, char *fmt, ...)
 {
 	va_list args;
 	char buf[NSP32_DEBUG_BUF_LEN];
 
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
 #ifndef NSP32_DEBUG
@@ -415,19 +379,21 @@
 #endif
 }
 
-static void nsp32_dmessage(char *func, int line, int mask, char *fmt, ...)
+#ifdef NSP32_DEBUG
+static void nsp32_dmessage(const char *func, int line, int mask, char *fmt, ...)
 {
 	va_list args;
 	char buf[NSP32_DEBUG_BUF_LEN];
 
 	va_start(args, fmt);
-	vsprintf(buf, fmt, args);
+	vsnprintf(buf, sizeof(buf), fmt, args);
 	va_end(args);
 
 	if (mask & NSP32_DEBUG_MASK) {
-		printk("Ninja: %d %s (%d): %s\n", mask, func, line, buf);
+		printk("nsp32-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
 	}
 }
+#endif
 
 #ifdef NSP32_DEBUG
 # include "nsp32_debug.c"
@@ -437,56 +403,51 @@
 # define show_autophase(arg) /* */
 #endif
 
-#ifdef NSP32_DEBUG
-static int pc_debug = NSP32_DEBUG;
-MODULE_PARM(pc_debug, "i");
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(/*KERN_DEBUG*/ args)
-#else
-#define DEBUG(n, args...)
-#endif
-
-
 /*
  * IDENTIFY Message
  */
-static void nsp32_build_identify(nsp32_hw_data *data, Scsi_Cmnd *SCpnt)
+static void nsp32_build_identify(Scsi_Cmnd *SCpnt)
 {
-	int pos = data->msgoutlen;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	int pos             = data->msgout_len;
+	int mode            = FALSE;
 
-	data->msgoutbuf[pos++] =
-		0x80 |		/* Identify */
-#if 0
-		/* XXX: Auto DiscPriv detection is progressing... */
-		0x40 |		/* DiscPriv */
-#endif
-		SCpnt->lun;	/* LUNTRN */
+	/* XXX: Auto DiscPriv detection is progressing... */
+	if (disc_priv == 0) {
+		/* mode = TRUE; */
+	}
 
-	data->msgoutlen = pos;
+	data->msgoutbuf[pos] = IDENTIFY(mode, SCpnt->device->lun); pos++;
+
+	data->msgout_len = pos;
 }
 
 /*
  * SDTR Message Routine
  */
-static void nsp32_build_sdtr(nsp32_hw_data *data,
-			     unsigned char period, unsigned char offset)
-{
-	int pos = data->msgoutlen;
+static void nsp32_build_sdtr(Scsi_Cmnd    *SCpnt,
+			     unsigned char period,
+			     unsigned char offset)
+{
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	int pos             = data->msgout_len;
+
+	data->msgoutbuf[pos] = EXTENDED_MESSAGE;  pos++;
+	data->msgoutbuf[pos] = EXTENDED_SDTR_LEN; pos++;
+	data->msgoutbuf[pos] = EXTENDED_SDTR;     pos++;
+	data->msgoutbuf[pos] = period;            pos++;
+	data->msgoutbuf[pos] = offset;            pos++;
 
-	data->msgoutbuf[pos++] = EXTENDED_MESSAGE;
-	data->msgoutbuf[pos++] = EXTENDED_SDTR_LEN;
-	data->msgoutbuf[pos++] = EXTENDED_SDTR;
-	data->msgoutbuf[pos++] = period;
-	data->msgoutbuf[pos++] = offset;
-
-	data->msgoutlen = pos;
+	data->msgout_len = pos;
 }
 
 /*
  * No Operation Message
  */
-static void nsp32_build_nop(nsp32_hw_data *data)
+static void nsp32_build_nop(Scsi_Cmnd *SCpnt)
 {
-	int pos = data->msgoutlen;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	int            pos  = data->msgout_len;
 
 	if (pos != 0) {
 		nsp32_msg(KERN_WARNING,
@@ -494,54 +455,97 @@
 		return;
 	}
 
-	data->msgoutbuf[pos++] = NOP;
-	data->msgoutlen = pos;
+	data->msgoutbuf[pos] = NOP; pos++;
+	data->msgout_len = pos;
 }
 
 /*
  * Reject Message
  */
-static void nsp32_build_reject(nsp32_hw_data *data)
+static void nsp32_build_reject(Scsi_Cmnd *SCpnt)
 {
-	int pos = data->msgoutlen;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	int            pos  = data->msgout_len;
 
-	data->msgoutbuf[pos++] = MESSAGE_REJECT;
-	data->msgoutlen = pos;
+	data->msgoutbuf[pos] = MESSAGE_REJECT; pos++;
+	data->msgout_len = pos;
 }
 	
 /*
- * timer
+ * Start hardware timer
  */
 #if 0
 static void nsp32_start_timer(Scsi_Cmnd *SCpnt, int time)
 {
 	unsigned int base = SCpnt->host->io_port;
 
-	DEBUG(0, __func__ " time=%d\n", time);
+	nsp32_dbg(NSP32_DEBUG_INTR, "timer=%d", time);
 
 	if (time & (~TIMER_CNT_MASK)) {
-		printk("timer set overflow\n");
+		nsp32_dbg(NSP32_DEBUG_INTR, "timer set overflow");
 	}
 
 	nsp32_write2(base, TIMER_SET, time & TIMER_CNT_MASK);
 }
 #endif
 
+/*
+ * Generate msgout register value based on the number of messages.
+ */
+static unsigned long nsp32_msgout_register(Scsi_Cmnd *SCpnt)
+{
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned long  msgout;
+	int            i;
+
+	/*
+	 * message out
+	 *
+	 * Note: If the range of msgout_len is 1 - 3, fill scsi_msgout.
+	 *       over 3 messages needs another routine.
+	 */
+	if (data->msgout_len > 0 && data->msgout_len <= 3) {
+		msgout = 0;
+		for (i = 0; i < data->msgout_len; i++) {
+			/*
+			 * msgout register layout:
+			 *  bit: 31-24 23-16 15-08 07 06-02  01-00
+			 *       MSG#2 MSG#1 MSG#0 MV <void> len
+			 *
+			 * the sending order of the message is:
+			 *  len = 3: MSG#0 -> MSG#1 -> MSG#2
+			 *  len = 2:          MSG#1 -> MSG#2
+			 *  len = 1:                   MSG#2    
+			 */
+			msgout >>= 8;
+			msgout |= ((unsigned int)(data->msgoutbuf[i]) << 24);
+		}
+		msgout |= MSGOUT_VALID;	/* Message out Valid */
+		msgout |= data->msgout_len; /* len */
+	} else {
+		/* data->msgout_len > 3 || data->msgout_len <= 0*/
+		msgout = 0;
+	}
+
+	return msgout;
+}
 
 /*
  * set SCSI command and other parameter to asic, and start selection phase
  */
-static int nsp32hw_start_selection(Scsi_Cmnd *SCpnt, nsp32_hw_data *data)
+static int nsp32_selection_autopara(Scsi_Cmnd *SCpnt)
 {
-	unsigned int   host_id = SCpnt->host->this_id;
-	unsigned int   base    = SCpnt->host->io_port;
-	unsigned char  target  = SCpnt->target;
-	unsigned char  *param  = data->autoparam;
-	unsigned char  phase, arbit;
-	int	       i, time;
-	unsigned int   msgout;
-	unsigned long  l;
-	unsigned short s;
+	nsp32_hw_data  *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int	base    = SCpnt->device->host->io_port;
+	unsigned int	host_id = SCpnt->device->host->this_id;
+	unsigned char	target  = SCpnt->device->id;
+	nsp32_autoparam *param  = data->autoparam;
+	unsigned char	phase;
+	int		i, ret;
+	unsigned long	msgout_reg;
+	unsigned short	transfer_reg;
+
+	nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "in");
 
 	/*
 	 * check bus free
@@ -556,155 +560,106 @@
 
 	/*
 	 * message out
-	 *
-	 * Note: If the range of msgoutlen is 1 - 3, fill scsi_msgout.
-	 *       over 3 messages needs another routine.
 	 */
-	if (data->msgoutlen == 0) {
+	if (data->msgout_len == 0) {
 		nsp32_msg(KERN_ERR, "SCSI MsgOut without any message!");
 		SCpnt->result = DID_ERROR << 16;
 		return FALSE;
-	} else if (data->msgoutlen > 0 && data->msgoutlen <= 3) {
-		msgout = 0;
-		for (i=0; i<data->msgoutlen; i++) {
-			/*
-			 * the sending order of the message is:
-			 *  MCNT 3: MSG#0 -> MSG#1 -> MSG#2
-			 *  MCNT 2:          MSG#1 -> MSG#2
-			 *  MCNT 1:                   MSG#2    
-			 */
-			msgout >>= 8;
-			msgout |= (unsigned int)(data->msgoutbuf[i] << 24);
-		}
-		msgout |= MV_VALID;	/* MV valid */
-		msgout |= (unsigned int)data->msgoutlen; /* len */
 	} else {
-		/* data->msgoutlen > 3 */
-		msgout = 0;
+		msgout_reg = nsp32_msgout_register(SCpnt);
 	}
 
+	// nsp_dbg(NSP32_DEBUG_AUTOSCSI, "sel time out=0x%x\n", nsp32_read2(base, SEL_TIME_OUT));
+	// nsp32_write2(base, SEL_TIME_OUT,   SEL_TIMEOUT_TIME);
+
 	/*
 	 * setup asic parameter
 	 */
-	memset(param, 0, AUTOPARAM_SIZE);
+	memset(param, 0, sizeof(nsp32_autoparam));
 
 	/* cdb */
-	for (i=0; i<SCpnt->cmd_len; i++) {
-		param[4*i] = SCpnt->cmnd[i];
+	for (i = 0; i < SCpnt->cmd_len; i++) {
+		param->cdb[4 * i] = SCpnt->cmnd[i];
 	}
 
-	/* message out */
-	param[4*0x10 +0] = (msgout & 0x000000ff) >> 0;
-	param[4*0x10 +1] = (msgout & 0x0000ff00) >> 8;
-	param[4*0x10 +2] = (msgout & 0x00ff0000) >> 16;
-	param[4*0x10 +3] = (msgout & 0xff000000) >> 24;
-
-	/* syncreg, ackwidth, target id, sampleing rate */
-	param[4*0x11 +0] = data->curtarget->syncreg;
-	param[4*0x11 +1] = data->curtarget->ackwidth;
-	param[4*0x11 +2] = BIT(host_id) | BIT(target);
-	param[4*0x11 +3] = 0;
+	/* outgoing messages */
+	param->msgout = cpu_to_le32(msgout_reg);
+
+	/* syncreg, ackwidth, target id, SREQ sampling rate */
+	param->syncreg    = data->cur_target->syncreg;
+	param->ackwidth   = data->cur_target->ackwidth;
+	param->target_id  = BIT(host_id) | BIT(target);
+	param->sample_reg = data->cur_target->sample_reg;
+
+	// nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "sample rate=0x%x\n", data->cur_target->sample_reg);
 
 	/* command control */
-	s = (CLEAR_CDB_FIFO_POINTER | AUTOSCSI_START |
-	     AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02 | AUTO_ATN);
-	param[4*0x12 +0] = (s & 0x00ff) >> 0;
-	param[4*0x12 +1] = (s & 0xff00) >> 8;
+	param->command_control = cpu_to_le16(CLEAR_CDB_FIFO_POINTER |
+					     AUTOSCSI_START         |
+					     AUTO_MSGIN_00_OR_04    |
+					     AUTO_MSGIN_02          |
+					     AUTO_ATN               );
+
 
 	/* transfer control */
-	s = 0;
+	transfer_reg = 0;
 	switch (data->trans_method) {
 	case NSP32_TRANSFER_BUSMASTER:
-		s |= BM_START;
+		transfer_reg |= BM_START;
 		break;
 	case NSP32_TRANSFER_MMIO:
-		s |= CB_MMIO_MODE;
+		transfer_reg |= CB_MMIO_MODE;
 		break;
 	case NSP32_TRANSFER_PIO:
-		s |= CB_IO_MODE;
+		transfer_reg |= CB_IO_MODE;
 		break;
 	default:
 		nsp32_msg(KERN_ERR, "unknown trans_method");
+		break;
 	}
 	/*
-	 * ORed BLIEND_MODE, FIFO intr is decreased, instead of PCI bus waits.
+	 * OR-ed BLIEND_MODE, FIFO intr is decreased, instead of PCI bus waits.
 	 * For bus master transfer, it's taken off.
 	 */
-	s |= (TRANSFER_GO | ALL_COUNTER_CLR);
-	param[4*0x12 +2] = (s & 0x00ff) >> 0;
-	param[4*0x12 +3] = (s & 0xff00) >> 8;
+	transfer_reg |= (TRANSFER_GO | ALL_COUNTER_CLR);
+	param->transfer_control = cpu_to_le16(transfer_reg);
 
 	/* sg table addr */
-	l = data->curlunt->sglun_paddr;
-	param[4*0x13 +0] = (l & 0x000000ff) >> 0;
-	param[4*0x13 +1] = (l & 0x0000ff00) >> 8;
-	param[4*0x13 +2] = (l & 0x00ff0000) >> 16;
-	param[4*0x13 +3] = (l & 0xff000000) >> 24;
+	param->sgt_pointer = cpu_to_le32(data->cur_lunt->sglun_paddr);
 
 	/*
-	 * transfer parameter to asic
+	 * transfer parameter to ASIC
 	 */
-	nsp32_write4(base, SGT_ADR,         virt_to_bus(param));
+	nsp32_write4(base, SGT_ADR,         data->auto_paddr);
 	nsp32_write2(base, COMMAND_CONTROL, CLEAR_CDB_FIFO_POINTER |
 		                            AUTO_PARAMETER         );
 
 	/*
-	 * Arbitration Status Check
-	 *	
-	 * Note: Arbitration counter is wait during ARBIT_GO is not lifting.
-	 *	 Using udelay(1) consumes CPU time and system time, but 
-	 *	 arbitration delay time is defined minimal 2.4us in SCSI
-	 *	 specification, thus udelay works as coarse grained wait timer.
-	 */
-	time = 0;
-	do {
-		arbit = nsp32_read1(base, ARBIT_STATUS);
-		nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit=0x%x", arbit);
-	} while ((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
-		 (time++ <= 1000));
-
-	nsp32_dbg(NSP32_DEBUG_AUTOSCSI,
-		  "arbit: 0x%x, delay time: %d", arbit, time);
-
-	if (arbit & ARBIT_WIN) {
-		SCpnt->result = DID_OK << 16;
-		/* PCI LED on! */
-		nsp32_index_write1(base, EXT_PORT, LED_ON);
-	} else if (arbit & ARBIT_FAIL) {
-		SCpnt->result = DID_BUS_BUSY << 16;
-		nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR);
-		return FALSE;
-	} else {
-		/* unknown error or ARBIT_GO timeout */
-		nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit fail");
-		SCpnt->result = DID_NO_CONNECT << 16;
-		nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR);
-		return FALSE;
-        }
-
-	/*
-	 * clear Arbit
+	 * Check arbitration
 	 */
-	nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR);
+	ret = nsp32_arbitration(SCpnt, base);
 
-	return TRUE;
+	return ret;
 }
 
 
 /*
  * Selection with AUTO SCSI (without AUTO PARAMETER)
  */
-static int nsp32_selection_autoscsi(Scsi_Cmnd *SCpnt, nsp32_hw_data *data)
+static int nsp32_selection_autoscsi(Scsi_Cmnd *SCpnt)
 {
+	nsp32_hw_data  *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int	base    = SCpnt->device->host->io_port;
+	unsigned int	host_id = SCpnt->device->host->this_id;
+	unsigned char	target  = SCpnt->device->id;
 	unsigned char	phase;
-	unsigned char	arbit;
 	int		status;
-	int		i;
 	unsigned short	command	= 0;
-	int		time = 0;
-	unsigned int	msgout = 0;
+	unsigned long   msgout  = 0;
 	unsigned short	execph;
-	unsigned int	base = data->BaseAddress;
+	int		i;
+
+	nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "in");
 
 	/*
 	 * IRQ disable
@@ -715,8 +670,7 @@
 	 * check bus line
 	 */
 	phase = nsp32_read1(base, SCSI_BUS_MONITOR);
-	if(((phase & BUSMON_BSY) == 1) ||
-	   (phase & BUSMON_SEL) == 1) {
+	if(((phase & BUSMON_BSY) == 1) || (phase & BUSMON_SEL) == 1) {
 		nsp32_msg(KERN_WARNING, "bus busy");
 		SCpnt->result = DID_BUS_BUSY << 16;
 		status = 1;
@@ -736,95 +690,75 @@
 	/*
 	 * set CDB0 - CDB15
 	 */
-	for (i=0; i<SCpnt->cmd_len; i++) {
+	for (i = 0; i < SCpnt->cmd_len; i++) {
 		nsp32_write1(base, COMMAND_DATA, SCpnt->cmnd[i]);
         }
-	nsp32_dbg(NSP32_DEBUG_CDB_CONTENTS, "CDB[0]=[0x%x]", SCpnt->cmnd[i]);
+	nsp32_dbg(NSP32_DEBUG_CDB_CONTENTS, "CDB[0]=[0x%x]", SCpnt->cmnd[0]);
 
 	/*
-	 * set SCSIOUT LATCH(initiator)/TARGET(target) (ORed) ID
+	 * set SCSIOUT LATCH(initiator)/TARGET(target) (OR-ed) ID
 	 */
-	nsp32_write1(base, SCSI_OUT_LATCH_TARGET_ID,
-		((1 << NSP32_HOST_SCSIID) | (1 << SCpnt->target)));
+	nsp32_write1(base, SCSI_OUT_LATCH_TARGET_ID, BIT(host_id) | BIT(target));
 
 	/*
 	 * set SCSI MSGOUT REG
-	 *
-	 * Note: If the range of msgoutlen is 1 - 3, fill scsi_msgout.
-	 *       over 3 messages needs another routine.
 	 */
-	if (data->msgoutlen == 0) {
-		nsp32_msg(KERN_ERR, 
-			  "SCSI MsgOut without any message!");
+	if (data->msgout_len == 0) {
+		nsp32_msg(KERN_ERR, "SCSI MsgOut without any message!");
 		SCpnt->result = DID_ERROR << 16;
 		status = 1;
 		goto out;
-	} else if (data->msgoutlen > 0 && data->msgoutlen <= 3) {
-		msgout = 0;
-		for (i=0; i<data->msgoutlen; i++) {
-			/*
-			 * the sending order of the message is:
-			 *  MCNT 3: MSG#0 -> MSG#1 -> MSG#2
-			 *  MCNT 2:          MSG#1 -> MSG#2
-			 *  MCNT 1:                   MSG#2    
-			 */
-			msgout >>= 8;
-			msgout |= (unsigned int)(data->msgoutbuf[i] << 24);
-		}
-		msgout |= MV_VALID;	/* MV valid */
-		msgout |= (unsigned int)data->msgoutlen; /* len */
-		nsp32_write4(base, SCSI_MSG_OUT, msgout);
 	} else {
-		/* data->msgoutlen > 3 */
-		nsp32_write4(base, SCSI_MSG_OUT, 0);
+		msgout = nsp32_msgout_register(SCpnt);
+		nsp32_write4(base, SCSI_MSG_OUT, msgout);
 	}
 
 	/*
 	 * set selection timeout(= 250ms)
 	 */
-	nsp32_write2(base, SEL_TIME_OUT, SEL_TIMEOUT_TIME);
+	nsp32_write2(base, SEL_TIME_OUT,   SEL_TIMEOUT_TIME);
 
 	/*
-	 * set smpl rate
+	 * set SREQ hazard killer sampling rate
 	 * 
-	 * TODO: smpl_rate (BASE+0F) is 0 when internal clock = 40MHz.
+	 * TODO: sample_rate (BASE+0F) is 0 when internal clock = 40MHz.
 	 *      check other internal clock!
 	 */
-	nsp32_write1(base, SREQ_SMPL_RATE, 0);
+	nsp32_write1(base, SREQ_SMPL_RATE, data->cur_target->sample_reg);
 
 	/*
 	 * clear Arbit
 	 */
-	nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR);
+	nsp32_write1(base, SET_ARBIT,      ARBIT_CLEAR);
 
 	/*
 	 * set SYNCREG
 	 * Don't set BM_START_ADR before setting this register.
 	 */
-	nsp32_write1(base, SYNC_REG, data->curtarget->syncreg);
+	nsp32_write1(base, SYNC_REG,  data->cur_target->syncreg);
 
 	/*
 	 * set ACKWIDTH
 	 */
-	nsp32_write1(base, ACK_WIDTH, data->curtarget->ackwidth);
+	nsp32_write1(base, ACK_WIDTH, data->cur_target->ackwidth);
 
 	nsp32_dbg(NSP32_DEBUG_AUTOSCSI,
 		  "syncreg=0x%x, ackwidth=0x%x, sgtpaddr=0x%x, id=0x%x",
 		  nsp32_read1(base, SYNC_REG), nsp32_read1(base, ACK_WIDTH),
 		  nsp32_read4(base, SGT_ADR), nsp32_read1(base, SCSI_OUT_LATCH_TARGET_ID));
-	nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "msgoutlen=%d, msgout=0x%x",
-		  data->msgoutlen, msgout);
+	nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "msgout_len=%d, msgout=0x%x",
+		  data->msgout_len, msgout);
 
 	/*
 	 * set SGT ADDR (physical address)
 	 */
-	nsp32_write4(base, SGT_ADR, data->curlunt->sglun_paddr);
+	nsp32_write4(base, SGT_ADR, data->cur_lunt->sglun_paddr);
 
 	/*
 	 * set TRANSFER CONTROL REG
 	 */
 	command = 0;
-	command |= ( TRANSFER_GO | ALL_COUNTER_CLR);
+	command |= (TRANSFER_GO | ALL_COUNTER_CLR);
 	if (data->trans_method & NSP32_TRANSFER_BUSMASTER) {
 		if (SCpnt->request_bufflen > 0) {
 			command |= BM_START;
@@ -839,73 +773,75 @@
 	/*
 	 * start AUTO SCSI, kick off arbitration
 	 */
-	command = 0;
-	command |= (CLEAR_CDB_FIFO_POINTER
-		    | AUTOSCSI_START
-		    | AUTO_MSGIN_00_OR_04
-		    | AUTO_MSGIN_02 
-		    | AUTO_ATN);
+	command = (CLEAR_CDB_FIFO_POINTER |
+		   AUTOSCSI_START         |
+		   AUTO_MSGIN_00_OR_04    |
+		   AUTO_MSGIN_02          |
+		   AUTO_ATN                );
 	nsp32_write2(base, COMMAND_CONTROL, command);
 
 	/*
-	 * Arbitration Status Check
-	 *	
-	 * Note: Arbitration counter is wait during ARBIT_GO is not lifting.
-	 *	 Using udelay(1) consumes CPU time and system time, but 
-	 *	 arbitration delay time is defined minimal 2.4us in SCSI
-	 *	 specification, thus udelay works as coarse grained wait timer.
+	 * Check arbitration
 	 */
-	time = 0;
-	while(1) {
-		arbit = nsp32_read1(base, ARBIT_STATUS);
-		if(arbit & ARBIT_GO) {
-			udelay(1);
-			time++;
-			if ( time > ARBIT_TIMEOUT_TIME ) {
-				/* something lock up! guess no connection */
-				SCpnt->result = DID_NO_CONNECT << 16;
-				status = FALSE;
-				goto out;
-			}
-		} else {
-			break;
-		}
-	};
-
-	nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit: 0x%x, delay time: %d", arbit, time);
+	status = nsp32_arbitration(SCpnt, base);
 
+ out:
 	/*
-	 * check Arbitration Status Result
+	 * IRQ enable
 	 */
-	if(arbit & ARBIT_WIN) {
+	nsp32_write2(base, IRQ_CONTROL, 0);
+
+	return status;
+}
+
+
+/*
+ * Arbitration Status Check
+ *	
+ * Note: Arbitration counter is waited during ARBIT_GO is not lifting.
+ *	 Using udelay(1) consumes CPU time and system time, but 
+ *	 arbitration delay time is defined minimal 2.4us in SCSI
+ *	 specification, thus udelay works as coarse grained wait timer.
+ */
+static int nsp32_arbitration(Scsi_Cmnd *SCpnt, unsigned int base)
+{
+	unsigned char arbit;
+	int	      status = TRUE;
+	int	      time   = 0;
+
+	do {
+		arbit = nsp32_read1(base, ARBIT_STATUS);
+		time++;
+	} while ((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
+		 (time <= ARBIT_TIMEOUT_TIME));
+
+	nsp32_dbg(NSP32_DEBUG_AUTOSCSI,
+		  "arbit: 0x%x, delay time: %d", arbit, time);
+
+	if (arbit & ARBIT_WIN) {
 		/* Arbitration succeeded */
-		status = TRUE;
 		SCpnt->result = DID_OK << 16;
-		/* PCI LED on! */
-		nsp32_index_write1(base, EXT_PORT, LED_ON);
-	} else if(arbit & ARBIT_FAIL) {
+		nsp32_index_write1(base, EXT_PORT, LED_ON); /* PCI LED on */
+	} else if (arbit & ARBIT_FAIL) {
 		/* Arbitration failed */
-		status = FALSE;
 		SCpnt->result = DID_BUS_BUSY << 16;
-	} else {
-		/* unknown error? */
 		status = FALSE;
-		SCpnt->result = DID_ERROR << 16;
+	} else {
+		/*
+		 * unknown error or ARBIT_GO timeout,
+		 * something lock up! guess no connection.
+		 */
+		nsp32_dbg(NSP32_DEBUG_AUTOSCSI, "arbit timeout");
 		SCpnt->result = DID_NO_CONNECT << 16;
-	}
+		status = FALSE;
+        }
 
 	/*
 	 * clear Arbit
 	 */
 	nsp32_write1(base, SET_ARBIT, ARBIT_CLEAR);
 
- out:
-	/*
-	 * IRQ enable
-	 */
-	nsp32_write2(base, IRQ_CONTROL, 0);
-
-	return(status);
+	return status;
 }
 
 
@@ -916,10 +852,12 @@
  *	 reselection target id&lun must be already set.
  *	 SCSI-2 says IDENTIFY implies RESTORE_POINTER operation.
  */
-static int nsp32_reselection(nsp32_hw_data *data, unsigned char newlun)
+static int nsp32_reselection(Scsi_Cmnd *SCpnt, unsigned char newlun)
 {
-	unsigned int base = data->BaseAddress;
-	unsigned char tmpid, newid;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int   host_id = SCpnt->device->host->this_id;
+	unsigned int   base    = SCpnt->device->host->io_port;
+	unsigned char  tmpid, newid;
 
 	nsp32_dbg(NSP32_DEBUG_RESELECTION, "enter");
 
@@ -927,7 +865,7 @@
 	 * calculate reselected SCSI ID
 	 */
 	tmpid = nsp32_read1(base, RESELECT_ID);
-	tmpid &= 0x7f;
+	tmpid &= (~BIT(host_id));
 	newid = 0;
 	while (tmpid) {
 		if (tmpid & 1) {
@@ -940,20 +878,20 @@
 	/*
 	 * If reselected New ID:LUN is not existed
 	 * or current nexus is not existed, unexpected
-	 * reselection is occured. Send reject message.
+	 * reselection is occurred. Send reject message.
 	 */
-	if (newid >= MAX_TARGET || newlun >= MAX_LUN) {
+	if (newid >= NUMBER(data->lunt) || newlun >= NUMBER(data->lunt[0])) {
 		nsp32_msg(KERN_WARNING, "unknown id/lun");
 		return FALSE;
-	} else if(data->lunt[newid][newlun]->SCpnt == NULL) {
+	} else if(data->lunt[newid][newlun].SCpnt == NULL) {
 		nsp32_msg(KERN_WARNING, "no SCSI command is processing");
 		return FALSE;
 	}
 
-	data->pid       = newid;
-	data->plun      = newlun;
-	data->curtarget = &data->target[newid];
-	data->curlunt   = data->lunt[newid][newlun];
+	data->cur_id    = newid;
+	data->cur_lun   = newlun;
+	data->cur_target = &(data->target[newid]);
+	data->cur_lunt   = &(data->lunt[newid][newlun]);
 
 	/* reset SACK/SavedACK counter (or ALL clear?) */
 	nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK);
@@ -963,16 +901,18 @@
 
 
 /*
- * nsp32hw_setup_sg_table - build scatter gather list for transfer data
+ * nsp32_setup_sg_table - build scatter gather list for transfer data
  *			    with bus master.
  *
  * Note: NinjaSCSI-32Bi/UDE bus master can not transfer over 64KB at a time.
  */
-static int nsp32hw_setup_sg_table(Scsi_Cmnd *SCpnt, nsp32_hw_data *data)
+static int nsp32_setup_sg_table(Scsi_Cmnd *SCpnt)
 {
-	struct scatterlist *sgl;
-	struct nsp32_sgtable *sgt = data->curlunt->sglun->sgt;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	struct scatterlist   *sgl;
+	nsp32_sgtable *sgt = data->cur_lunt->sglun->sgt;
 	int num, i;
+	u32 l;
 
 	if (SCpnt->request_bufflen == 0) {
 		return TRUE;
@@ -987,7 +927,7 @@
 		sgl = (struct scatterlist *)SCpnt->request_buffer;
 		num = pci_map_sg(data->Pci, sgl, SCpnt->use_sg,
 				 scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
-		for (i=0; i<num; i++) {
+		for (i = 0; i < num; i++) {
 			/*
 			 * Build nsp32_sglist, substitute sg dma addresses.
 			 */
@@ -995,26 +935,38 @@
 			sgt[i].len  = cpu_to_le32(sg_dma_len(sgl));
 			sgl++;
 
-			if (sgt[i].len > 65536) {
+			if (le32_to_cpu(sgt[i].len) > 0x10000) {
 				nsp32_msg(KERN_ERR,
-					"can't transfer over 64KB at a time");
+					"can't transfer over 64KB at a time, size=0x%lx", le32_to_cpu(sgt[i].len));
 				return FALSE;
 			}
 			nsp32_dbg(NSP32_DEBUG_SGLIST,
-				  "num 0x%x : addr 0x%lx len 0x%x",
-				  i, sgt[i].addr, sgt[i].len);
+				  "num 0x%x : addr 0x%lx len 0x%lx",
+				  i,
+				  le32_to_cpu(sgt[i].addr),
+				  le32_to_cpu(sgt[i].len ));
 		}
-		sgt[num-1].len |= NSP32_SG_END_SGT; /* set end mark */
+
+		/* set end mark */
+		l = le32_to_cpu(sgt[num-1].len);
+		sgt[num-1].len = cpu_to_le32(l | SGTEND);
+
 	} else {
 		SCpnt->SCp.have_data_in	= pci_map_single(data->Pci,
 			SCpnt->request_buffer, SCpnt->request_bufflen,
 			scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+
 		sgt[0].addr = cpu_to_le32(SCpnt->SCp.have_data_in);
-		sgt[0].len  = cpu_to_le32(SCpnt->request_bufflen);
-		sgt[0].len |= NSP32_SG_END_SGT; /* set end mark */
+		sgt[0].len  = cpu_to_le32(SCpnt->request_bufflen | SGTEND); /* set end mark */
 
-		nsp32_dbg(NSP32_DEBUG_SGLIST, "single : addr 0x%lx len=0x%x",
-			  sgt[0].addr, sgt[0].len);
+		if (SCpnt->request_bufflen > 0x10000) {
+			nsp32_msg(KERN_ERR,
+				  "can't transfer over 64KB at a time, size=0x%lx", SCpnt->request_bufflen);
+			return FALSE;
+		}
+		nsp32_dbg(NSP32_DEBUG_SGLIST, "single : addr 0x%lx len=0x%lx",
+			  le32_to_cpu(sgt[0].addr),
+			  le32_to_cpu(sgt[0].len ));
 	}
 
 	return TRUE;
@@ -1022,38 +974,40 @@
 
 static int nsp32_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
-	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata;
-	struct nsp32_target *target;
-	struct nsp32_lunt *curlunt;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	nsp32_target *target;
+	nsp32_lunt   *cur_lunt;
 	int ret;
 
 	nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND,
 		  "enter. target: 0x%x LUN: 0x%x cmnd: 0x%x cmndlen: 0x%x "
 		  "use_sg: 0x%x reqbuf: 0x%lx reqlen: 0x%x",
-		  SCpnt->target, SCpnt->lun, SCpnt->cmnd[0], SCpnt->cmd_len,
+		  SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd[0], SCpnt->cmd_len,
 		  SCpnt->use_sg, SCpnt->request_buffer, SCpnt->request_bufflen);
 
-	if (data->CurrentSC != NULL ) {
+	if (data->CurrentSC != NULL) {
 		nsp32_msg(KERN_ERR, "Currentsc != NULL. Cancel this command request");
 		data->CurrentSC = NULL;
 		SCpnt->result   = DID_NO_CONNECT << 16;
 		done(SCpnt);
 
-		return 1;
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* check target ID is not same as this initiator ID */
-	if (SCpnt->target == NSP32_HOST_SCSIID) {
+	if (SCpnt->device->id == SCpnt->device->host->this_id) {
+		nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "terget==host???");
 		SCpnt->result = DID_BAD_TARGET << 16;
 		done(SCpnt);
-		return 1;
+		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
 	/* check target LUN is allowable value */
-	if (SCpnt->lun >= MAX_LUN) {
+	if (SCpnt->device->lun >= MAX_LUN) {
+		nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "no more lun");
 		SCpnt->result = DID_BAD_TARGET << 16;
 		done(SCpnt);
-		return 1;
+		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
 	show_command(SCpnt);
@@ -1062,7 +1016,7 @@
 	data->CurrentSC      = SCpnt;
 	SCpnt->SCp.Status    = CHECK_CONDITION;
 	SCpnt->SCp.Message   = 0;
-	SCpnt->resid         = 0; //SCpnt->request_bufflen;
+	SCpnt->resid         = SCpnt->request_bufflen;
 
 	SCpnt->SCp.ptr		    = (char *) SCpnt->request_buffer;
 	SCpnt->SCp.this_residual    = SCpnt->request_bufflen;
@@ -1070,39 +1024,41 @@
 	SCpnt->SCp.buffers_residual = 0;
 
 	/* initialize data */
-	data->msgoutlen		= 0;
-	data->msginlen		= 0;
-	curlunt			= data->lunt[SCpnt->target][SCpnt->lun];
-	curlunt->SCpnt		= SCpnt;
-	curlunt->save_datp	= 0;
-	curlunt->msgin03	= FALSE;
-	data->curlunt		= curlunt;
-	data->pid		= SCpnt->target;
-	data->plun		= SCpnt->lun;
+	data->msgout_len	= 0;
+	data->msgin_len		= 0;
+	cur_lunt		= &(data->lunt[SCpnt->device->id][SCpnt->device->lun]);
+	cur_lunt->SCpnt		= SCpnt;
+	cur_lunt->save_datp	= 0;
+	cur_lunt->msgin03	= FALSE;
+	data->cur_lunt		= cur_lunt;
+	data->cur_id		= SCpnt->device->id;
+	data->cur_lun		= SCpnt->device->lun;
 
-	ret = nsp32hw_setup_sg_table(SCpnt, data);
+	ret = nsp32_setup_sg_table(SCpnt);
 	if (ret == FALSE) {
+		nsp32_msg(KERN_ERR, "SGT fail");
 		SCpnt->result = DID_ERROR << 16;
-		nsp32_scsi_done(data, SCpnt);
+		nsp32_scsi_done(SCpnt);
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	/* Build IDENTIFY */
-	nsp32_build_identify(data, SCpnt);
+	nsp32_build_identify(SCpnt);
 
 	/* 
 	 * If target is the first time to transfer after the reset
 	 * (target don't have SDTR_DONE and SDTR_INITIATOR), sync
 	 * message SDTR is needed to do synchronous transfer.
 	 */
-	target = &data->target[SCpnt->target];
-	data->curtarget = target;
+	target = &data->target[SCpnt->device->id];
+	data->cur_target = target;
 
 	if (!(target->sync_flag & (SDTR_DONE | SDTR_INITIATOR | SDTR_TARGET))) {
 		unsigned char period, offset;
 
 		if (trans_mode != ASYNC_MODE) {
 			nsp32_set_max_sync(data, target, &period, &offset);
-			nsp32_build_sdtr(data, period, offset);
+			nsp32_build_sdtr(SCpnt, period, offset);
 			target->sync_flag |= SDTR_INITIATOR;
 		} else {
 			nsp32_set_async(data, target);
@@ -1140,32 +1096,32 @@
 
 	nsp32_dbg(NSP32_DEBUG_TARGETFLAG,
 		  "target: %d sync_flag: 0x%x syncreg: 0x%x ackwidth: 0x%x",
-		  SCpnt->target, target->sync_flag, target->syncreg,
+		  SCpnt->device->id, target->sync_flag, target->syncreg,
 		  target->ackwidth);
 
 	/* Selection */
 	if (auto_param == 0) {
-		ret = nsp32hw_start_selection(SCpnt, data);
+		ret = nsp32_selection_autopara(SCpnt);
 	} else {
-		ret = nsp32_selection_autoscsi(SCpnt, data);
+		ret = nsp32_selection_autoscsi(SCpnt);
 	}
 
 	if (ret != TRUE) {
-		nsp32_scsi_done(data, SCpnt);
-		return 1;
+		nsp32_dbg(NSP32_DEBUG_QUEUECOMMAND, "selection fail");
+		nsp32_scsi_done(SCpnt);
+		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
 	return 0;
 }
 
 /* initialize asic */
-static int nsp32hw_init(struct Scsi_Host *host)
+static int nsp32hw_init(nsp32_hw_data *data)
 {
-	unsigned int  base = host->io_port;
+	unsigned int   base = data->BaseAddress;
 	unsigned short irq_stat;
-	unsigned long lc_reg;
-	unsigned char power;
-	nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata;
+	unsigned long  lc_reg;
+	unsigned char  power;
 
 	lc_reg = nsp32_index_read4(base, CFG_LATE_CACHE);
 	if ((lc_reg & 0xff00) == 0) {
@@ -1173,15 +1129,15 @@
 		nsp32_index_write2(base, CFG_LATE_CACHE, lc_reg & 0xffff);
 	}
 
-	nsp32_write2(base, IRQ_CONTROL,      IRQ_CONTROL_ALL_IRQ_MASK);
-	nsp32_write2(base, TRANSFER_CONTROL, 0);
-	nsp32_write4(base, BM_CNT,           0);
+	nsp32_write2(base, IRQ_CONTROL,        IRQ_CONTROL_ALL_IRQ_MASK);
+	nsp32_write2(base, TRANSFER_CONTROL,   0);
+	nsp32_write4(base, BM_CNT,             0);
 	nsp32_write2(base, SCSI_EXECUTE_PHASE, 0);
 
 	do {
 		irq_stat = nsp32_read2(base, IRQ_STATUS);
+		nsp32_dbg(NSP32_DEBUG_INIT, "irq_stat 0x%x", irq_stat);
 	} while (irq_stat & IRQSTATUS_ANY_IRQ);
-	nsp32_dbg(NSP32_DEBUG_INIT, "irq_stat 0x%x", irq_stat);
 
 	/*
 	 * Fill FIFO_FULL_SHLD, FIFO_EMPTY_SHLD. Below parameter is
@@ -1189,22 +1145,25 @@
 	 */
 	if ((data->trans_method & NSP32_TRANSFER_PIO) ||
 	    (data->trans_method & NSP32_TRANSFER_MMIO)) {
-		nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT, 0x40);
+		nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT,  0x40);
+		nsp32_index_write1(base, FIFO_EMPTY_SHLD_COUNT, 0x40);
 	} else if (data->trans_method & NSP32_TRANSFER_BUSMASTER) {
-		nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT, 0x10);
+		nsp32_index_write1(base, FIFO_FULL_SHLD_COUNT,  0x10);
+		nsp32_index_write1(base, FIFO_EMPTY_SHLD_COUNT, 0x60);
+	} else {
+		nsp32_dbg(NSP32_DEBUG_INIT, "unknown transfer mode");
 	}
-	nsp32_index_write1(base, FIFO_EMPTY_SHLD_COUNT, 0x60);
 
 	nsp32_dbg(NSP32_DEBUG_INIT, "full 0x%x emp 0x%x",
 		  nsp32_index_read1(base, FIFO_FULL_SHLD_COUNT),
 		  nsp32_index_read1(base, FIFO_EMPTY_SHLD_COUNT));
 
 	nsp32_index_write1(base, CLOCK_DIV, data->clock);
-	nsp32_index_write1(base, BM_CYCLE, MEMRD_CMD1 | SGT_AUTO_PARA_MEMED_CMD);
+	nsp32_index_write1(base, BM_CYCLE,  MEMRD_CMD1 | SGT_AUTO_PARA_MEMED_CMD);
 	nsp32_write1(base, PARITY_CONTROL, 0);	/* parity check is disable */
 
 	/*
-	 * initialize I_MISC_WRRD register
+	 * initialize MISC_WRRD register
 	 * 
 	 * Note: Designated parameters is obeyed as following:
 	 *	MISC_SCSI_DIRECTION_DETECTOR_SELECT: It must be set.
@@ -1220,10 +1179,10 @@
 	 */
 	nsp32_index_write2(base, MISC_WR,
 			   (SCSI_DIRECTION_DETECTOR_SELECT |
-			    DELAYED_BMSTART |
-			    MASTER_TERMINATION_SELECT |
-			    BMREQ_NEGATE_TIMING_SEL |
-			    AUTOSEL_TIMING_SEL |
+			    DELAYED_BMSTART                |
+			    MASTER_TERMINATION_SELECT      |
+			    BMREQ_NEGATE_TIMING_SEL        |
+			    AUTOSEL_TIMING_SEL             |
 			    BMSTOP_CHANGE2_NONDATA_PHASE));
 
 	nsp32_index_write1(base, TERM_PWR_CONTROL, 0);
@@ -1234,11 +1193,11 @@
 	}
 
 	nsp32_write2(base, TIMER_SET, TIMER_STOP);
-	nsp32_write2(base, TIMER_SET, TIMER_STOP);
+	nsp32_write2(base, TIMER_SET, TIMER_STOP); /* Required 2 times */
 
-	nsp32_write1(base, SYNC_REG,  0);
-	nsp32_write1(base, ACK_WIDTH, 0);
-	nsp32_write2(base, SEL_TIME_OUT, 10000); /* 25us x10000 = 250ms defined in SCSI */
+	nsp32_write1(base, SYNC_REG,     0);
+	nsp32_write1(base, ACK_WIDTH,    0);
+	nsp32_write2(base, SEL_TIME_OUT, SEL_TIMEOUT_TIME);
 
 	/*
 	 * enable to select designated IRQ (except for
@@ -1250,21 +1209,21 @@
 			                     IRQSELECT_RESELECT_IRQ      |
 			                     IRQSELECT_PHASE_CHANGE_IRQ  |
 			                     IRQSELECT_AUTO_SCSI_SEQ_IRQ |
-			                     //IRQSELECT_BMCNTERR_IRQ    |
+			                  //   IRQSELECT_BMCNTERR_IRQ      |
 			                     IRQSELECT_TARGET_ABORT_IRQ  |
 			                     IRQSELECT_MASTER_ABORT_IRQ );
 	nsp32_write2(base, IRQ_CONTROL, 0);
 
 	/* PCI LED off */
 	nsp32_index_write1(base, EXT_PORT_DDR, LED_OFF);
-	nsp32_index_write1(base, EXT_PORT, LED_OFF);
+	nsp32_index_write1(base, EXT_PORT,     LED_OFF);
 
 	return TRUE;
 }
 
 
 /* interrupt routine */
-static void do_nsp32_isr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t do_nsp32_isr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	nsp32_hw_data *data = dev_id;
 	unsigned int base = data->BaseAddress;
@@ -1273,13 +1232,9 @@
 	unsigned char busmon, busphase;
 	unsigned long flags;
 	int ret;
+	int handled = 0;
 
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,5,0)
-	struct Scsi_Host *host = data->Host;
-	spin_lock_irqsave(host->host_lock, flags);
-#else
-	spin_lock_irqsave(&io_request_lock, flags);
-#endif
+	spin_lock_irqsave(HOST_LOCK, flags);
 
 	/*
 	 * IRQ check, then enable IRQ mask
@@ -1289,9 +1244,10 @@
 		  "enter IRQ: %d, IRQstatus: 0x%x", irq, irq_stat);
 	/* is this interrupt comes from Ninja asic? */
 	if ((irq_stat & IRQSTATUS_ANY_IRQ) == 0) {
-		nsp32_msg(KERN_INFO, "spurious interrupt: irq other 0x%x", irq_stat);
+		nsp32_dbg(NSP32_DEBUG_INTR, "shared interrupt: irq other 0x%x", irq_stat);
 		goto out2;
 	}
+	handled = 1;
 	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
 
 	busmon = nsp32_read1(base, SCSI_BUS_MONITOR);
@@ -1303,14 +1259,14 @@
 		if (data->CurrentSC != NULL) {
 			nsp32_msg(KERN_INFO, "clean up current SCSI command");
 			SCpnt->result = DID_BAD_TARGET << 16;
-			nsp32_scsi_done(data, SCpnt);
+			nsp32_scsi_done(SCpnt);
 		}
 		goto out;
 	}
 
 	/* Timer IRQ */
 	if (irq_stat & IRQSTATUS_TIMER_IRQ) {
-		DEBUG(0, "timer stop\n");
+		nsp32_dbg(NSP32_DEBUG_INTR, "timer stop");
 		nsp32_write2(base, TIMER_SET, TIMER_STOP);
 		goto out;
 	}
@@ -1321,20 +1277,20 @@
 		nsp32_do_bus_reset(data);
 		if (SCpnt != NULL) {
 			SCpnt->result = DID_RESET << 16;
-			nsp32_scsi_done(data, SCpnt);
+			nsp32_scsi_done(SCpnt);
 		}
 		goto out;
 	}
-	
+
 	if (SCpnt == NULL) {
-		nsp32_msg(KERN_WARNING, "SCpnt==NULL this can't be happen\n");
-		nsp32_msg(KERN_WARNING, "irq_stat=0x%x trans_stat=0x%x\n", irq_stat, trans_stat);
+		nsp32_msg(KERN_WARNING, "SCpnt==NULL this can't be happened");
+		nsp32_msg(KERN_WARNING, "irq_stat=0x%x trans_stat=0x%x", irq_stat, trans_stat);
 		goto out;
 	}
 
 	/*
 	 * AutoSCSI Interrupt.
-	 * Note: This interrupt is occured when AutoSCSI is finished.  Then
+	 * Note: This interrupt is occurred when AutoSCSI is finished.  Then
 	 * check SCSIEXECUTEPHASE, and do appropriate action.  Each phases are
 	 * recorded when AutoSCSI sequencer has been processed.
 	 */
@@ -1346,10 +1302,10 @@
 		/* Selection Timeout, go busfree phase. */
 		if (auto_stat & SELECTION_TIMEOUT) {
 			nsp32_dbg(NSP32_DEBUG_INTR,
-				  "selection timeout occured");
+				  "selection timeout occurred");
 
 			SCpnt->result = DID_TIME_OUT << 16;
-			nsp32_scsi_done(data, SCpnt);
+			nsp32_scsi_done(SCpnt);
 			goto out;
 		}
 
@@ -1357,17 +1313,17 @@
 			/*
 			 * MsgOut phase was processed.
 			 * If MSG_IN_OCCUER is not set, then MsgOut phase is
-			 * completed. Thus, msgoutlen must reset.  Otherwise,
-			 * nothing to do here. If MSG_OUT_OCCUER is occured,
+			 * completed. Thus, msgout_len must reset.  Otherwise,
+			 * nothing to do here. If MSG_OUT_OCCUER is occurred,
 			 * then we will encounter the condition and check.
 			 */
 			if (!(auto_stat & MSG_IN_OCCUER) &&
-			     (data->msgoutlen <= 3)) {
+			     (data->msgout_len <= 3)) {
 				/*
-				 * !MSG_IN_OCCUER && msgoutlen <=3
+				 * !MSG_IN_OCCUER && msgout_len <=3
 				 *   ---> AutoSCSI with MSGOUTreg is processed.
 				 */
-				data->msgoutlen = 0;
+				data->msgout_len = 0;
 			};
 
 			nsp32_dbg(NSP32_DEBUG_INTR, "MsgOut phase processed");
@@ -1394,28 +1350,29 @@
 				    nsp32_read4(base, SACK_CNT));
 			nsp32_dbg(NSP32_DEBUG_INTR, "SSACK=0x%lx", 
 				    nsp32_read4(base, SAVED_SACK_CNT));
-			
+
+			SCpnt->resid = 0; /* all data transfered! */
 		}
 
 		/*
 		 * MsgIn Occur
 		 */
 		if (auto_stat & MSG_IN_OCCUER) {
-			nsp32_msgin_occur(data, irq_stat, auto_stat);
+			nsp32_msgin_occur(SCpnt, irq_stat, auto_stat);
 		}
 
 		/*
 		 * MsgOut Occur
 		 */
 		if (auto_stat & MSG_OUT_OCCUER) {
-			nsp32_msgout_occur(data);
+			nsp32_msgout_occur(SCpnt);
 		}
 
 		/*
 		 * Bus Free Occur
 		 */
 		if (auto_stat & BUS_FREE_OCCUER) {
-			ret = nsp32_busfree_occur(data, auto_stat);
+			ret = nsp32_busfree_occur(SCpnt, auto_stat);
 			if (ret == TRUE) {
 				goto out;
 			}
@@ -1466,28 +1423,28 @@
 
 		switch(busphase) {
 		case BUSPHASE_DATA_OUT:
-			printk( "write\n");
+			nsp32_dbg(NSP32_DEBUG_INTR, "fifo/write");
 
 			//nsp32_pio_write(SCpnt);
 
 			break;
 
 		case BUSPHASE_DATA_IN:
-			printk( "read\n");
+			nsp32_dbg(NSP32_DEBUG_INTR, "fifo/read");
 
 			//nsp32_pio_read(SCpnt);
 
 			break;
 
 		case BUSPHASE_STATUS:
-			//DEBUG(0, "fifo/status\n");
+			nsp32_dbg(NSP32_DEBUG_INTR, "fifo/status");
 
 			SCpnt->SCp.Status = nsp32_read1(base, SCSI_CSB_IN);
 
 			break;
 		default:
-			printk("fifo/other phase?\n");
-			printk("irq_stat=0x%x trans_stat=0x%x\n", irq_stat, trans_stat);
+			nsp32_dbg(NSP32_DEBUG_INTR, "fifo/other phase");
+			nsp32_dbg(NSP32_DEBUG_INTR, "irq_stat=0x%x trans_stat=0x%x", irq_stat, trans_stat);
 			show_busphase(busphase);
 			break;
 		}
@@ -1502,7 +1459,7 @@
 		switch(busphase) {
 		case BUSPHASE_MESSAGE_IN:
 			nsp32_dbg(NSP32_DEBUG_INTR, "phase chg/msg in");
-			nsp32_msgin_occur(data, irq_stat, 0);
+			nsp32_msgin_occur(SCpnt, irq_stat, 0);
 			break;
 		default:
 			nsp32_msg(KERN_WARNING, "phase chg/other phase?");
@@ -1516,7 +1473,7 @@
 
 	/* PCI_IRQ */
 	if (irq_stat & IRQSTATUS_PCI_IRQ) {
-		nsp32_dbg(NSP32_DEBUG_INTR, "PCI IRQ occured");
+		nsp32_dbg(NSP32_DEBUG_INTR, "PCI IRQ occurred");
 		/* Do nothing */
 	}
 
@@ -1525,13 +1482,14 @@
 		nsp32_msg(KERN_ERR, "Received unexpected BMCNTERR IRQ! ");
 		/*
 		 * TODO: To be implemented improving bus master
-		 * transfer reliablity when BMCNTERR is occured in
+		 * transfer reliablity when BMCNTERR is occurred in
 		 * AutoSCSI phase described in specification.
 		 */
 	}
 
 #if 0
-	printk("irq_stat=0x%x trans_stat=0x%x\n", irq_stat, trans_stat);
+	nsp32_dbg(NSP32_DEBUG_INTR,
+		  "irq_stat=0x%x trans_stat=0x%x", irq_stat, trans_stat);
 	show_busphase(busphase);
 #endif
 
@@ -1540,72 +1498,122 @@
 	nsp32_write2(base, IRQ_CONTROL, 0);
 
  out2:
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
-	spin_unlock_irqrestore(&io_request_lock, flags);
-#else
-	spin_unlock_irqrestore(host->host_lock, flags);
-#endif
+	spin_unlock_irqrestore(HOST_LOCK, flags);
 
 	nsp32_dbg(NSP32_DEBUG_INTR, "exit");
 
-	return;
+	return IRQ_RETVAL(handled);
 }
 
 #undef SPRINTF
 #define SPRINTF(args...) \
-        do { if(pos < buffer + length) pos += sprintf(pos, ## args); } while(0)
-static int nsp32_proc_info(char  *buffer,
-			   char **start,
-			   off_t  offset,
-			   int    length,
-			   int    hostno,
-			   int    inout)
+	do { \
+		if(length > (pos - buffer)) { \
+			pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
+			nsp32_dbg(NSP32_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\
+		} \
+	} while(0)
+static int nsp32_proc_info(
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
+	struct Scsi_Host *host,
+#endif
+	char             *buffer,
+	char            **start,
+	off_t             offset,
+	int               length,
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
+	int               hostno,
+#endif
+	int               inout)
 {
-	char *pos = buffer;
-	int thislength;
-	unsigned long flags;
-	nsp32_hw_data *data;
-	struct Scsi_Host *host = NULL;
-	unsigned int base;
-	unsigned char mode_reg;
+	char             *pos = buffer;
+	int               thislength;
+	unsigned long     flags;
+	nsp32_hw_data    *data;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
+	int               hostno;
+#else
+	struct Scsi_Host *host;
+#endif
+	unsigned int      base;
+	unsigned char     mode_reg;
+	int               id, speed;
+	long              model;
 
 	/* Write is not supported, just return. */
 	if (inout == TRUE) {
 		return -EINVAL;
 	}
 
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) 
+	hostno = host->host_no;
+#else
 	/* search this HBA host */
-	for (host=scsi_hostlist; host; host=host->next) {
-		if (host->host_no == hostno) {
-			break;
-		}
-	}
+	host = scsi_host_hn_get(hostno);
 	if (host == NULL) {
 		return -ESRCH;
 	}
+#endif
 	data = (nsp32_hw_data *)host->hostdata;
 	base = host->io_port;
 
 	SPRINTF("NinjaSCSI-32 status\n\n");
-	SPRINTF("Driver version:        %s\n",		nsp32_release_version);
+	SPRINTF("Driver version:        %s, $Revision: 1.34 $\n", nsp32_release_version);
 	SPRINTF("SCSI host No.:         %d\n",		hostno);
 	SPRINTF("IRQ:                   %d\n",		host->irq);
 	SPRINTF("IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
-	SPRINTF("MMIO(virtual address): 0x%lx\n",	host->base);
+	SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n",	host->base, host->base + data->MmioLength - 1);
 	SPRINTF("sg_tablesize:          %d\n",		host->sg_tablesize);
-	SPRINTF("Chip revision:         %d\n",		(nsp32_read2(base, INDEX_REG) >> 8) - 0x4f);
+	SPRINTF("Chip revision:         0x%x\n",       	(nsp32_read2(base, INDEX_REG) >> 8) & 0xff);
 
 	mode_reg = nsp32_index_read1(base, CHIP_MODE);
+	model    = data->pci_devid->driver_data;
 
 #ifdef CONFIG_PM
-	//SPRINTF("Power Management:      %s\n",          (mode_reg & OPTF) ? "yes" : "no");
+	SPRINTF("Power Management:      %s\n",          (mode_reg & OPTF) ? "yes" : "no");
 #endif
-	SPRINTF("OEM:                   %s\n",          nsp32_model[mode_reg & (OEM0|OEM1)]);
+	SPRINTF("OEM:                   %ld, %s\n",     (mode_reg & (OEM0|OEM1)), nsp32_model[model]);
 
 	spin_lock_irqsave(&(data->Lock), flags);
 	SPRINTF("CurrentSC:             0x%p\n\n",      data->CurrentSC);
 	spin_unlock_irqrestore(&(data->Lock), flags);
 
+
+	SPRINTF("SDTR status\n");
+	for(id = 0; id < NUMBER(data->target); id++) {
+
+                SPRINTF("id %d: ", id);
+
+		if (id == host->this_id) {
+			SPRINTF("----- NinjaSCSI-32 host adapter\n");
+			continue;
+		}
+
+		if (data->target[id].sync_flag == SDTR_DONE) {
+			if (data->target[id].period == 0            &&
+			    data->target[id].offset == ASYNC_OFFSET ) {
+				SPRINTF("async");
+			} else {
+				SPRINTF(" sync");
+			}
+		} else {
+			SPRINTF(" none");
+		}
+
+		if (data->target[id].period != 0) {
+
+			speed = 1000000 / (data->target[id].period * 4);
+
+			SPRINTF(" transfer %d.%dMB/s, offset %d",
+				speed / 1000,
+				speed % 1000,
+				data->target[id].offset
+				);
+		}
+		SPRINTF("\n");
+	}
+
+
 	thislength = pos - (buffer + offset);
 
 	if(thislength < 0) {
@@ -1621,1542 +1629,1452 @@
 }
 #undef SPRINTF
 
+
+
 /*
- * Note: n_io_port is defined as 0x7f because I/O register port is
- *	 assigned as:
- *	0x800-0x8ff: memory mapped I/O port
- *	0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly)
- *	0xc00-0xfff: CardBus status registers
+ * Reset parameters and call scsi_done for data->cur_lunt.
+ * Be careful setting SCpnt->result = DID_* before calling this function.
  */
-static int nsp32_detect(Scsi_Host_Template *sht)
+static void nsp32_scsi_done(Scsi_Cmnd *SCpnt)
 {
-	struct Scsi_Host *host;	/* registered host structure */
-	int ret;
-	nsp32_hw_data *data;
-	int i, j;
-
-	nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int   base = SCpnt->device->host->io_port;
 
 	/*
-	 * register this HBA as SCSI device
+	 * unmap pci
 	 */
-	host = scsi_register(sht, sizeof(nsp32_hw_data));
-	if (host == NULL) {
-		nsp32_msg (KERN_ERR, "failed to scsi register");
-		goto err;
+	if (SCpnt->request_bufflen == 0) {
+		goto skip;
 	}
 
-	/*
-	 * set nsp32_hw_data
-	 */
-	data = (nsp32_hw_data *)host->hostdata;
-	memset(data, 0, sizeof(nsp32_hw_data));
-
-	data->IrqNumber   = nsp32_data_base.IrqNumber;
-	data->BaseAddress = nsp32_data_base.BaseAddress;
-	data->NumAddress  = nsp32_data_base.NumAddress; 
-	data->MmioAddress = nsp32_data_base.MmioAddress;
-	data->Pci         = nsp32_data_base.Pci;
-	data->pci_devid   = nsp32_data_base.pci_devid;
-
-	host->irq         = data->IrqNumber;
-	host->io_port	  = data->BaseAddress;
-	host->unique_id	  = data->BaseAddress;
-	host->n_io_port	  = data->NumAddress;
-	host->base        = data->MmioAddress;
-	scsi_set_pci_device(host, data->Pci);
-
-	data->Host        = host;
-	spin_lock_init(&(data->Lock));
-
-	data->curlunt     = NULL;
-	data->curtarget   = NULL;
+	if (SCpnt->use_sg) {
+		pci_unmap_sg(data->Pci,
+			     (struct scatterlist *)SCpnt->buffer,
+			     SCpnt->use_sg,
+			     scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+	} else {
+		pci_unmap_single(data->Pci,
+				 (u32)SCpnt->SCp.have_data_in,
+				 SCpnt->request_bufflen,
+				 scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+	}
 
+ skip:
 	/*
-	 * Bus master transfer mode is supported currently.
+	 * clear TRANSFERCONTROL_BM_START
 	 */
-	data->trans_method	= NSP32_TRANSFER_BUSMASTER;
+	nsp32_write2(base, TRANSFER_CONTROL, 0);
+	nsp32_write4(base, BM_CNT,           0);
 
 	/*
-	 * Set clock div, CLOCK_4 (HBA has external clock, and
-	 * dividing * 100ns/4).
-	 * Currently CLOCK_4 has only tested, not for CLOCK_2/PCICLK yet.
+	 * call scsi_done
 	 */
-	data->clock = CLOCK_4;
+	(*SCpnt->scsi_done)(SCpnt);
 
 	/*
-	 * Select appropriate nsp32_sync_table and set I_CLOCKDIV.
+	 * reset parameters
 	 */
-	switch (data->clock) {
-	case CLOCK_4:
-		/* If data->clock is CLOCK_4, then select 40M sync table. */
-		data->synct = nsp32_sync_table_40M;
-		data->syncnum = nsp32_table_40M_num;
-		break;
-	case CLOCK_2:
-		/* If data->clock is CLOCK_2, then select 20M sync table. */
-		data->synct = nsp32_sync_table_20M;
-		data->syncnum = nsp32_table_20M_num;
-		break;
-	case PCICLK:
-		/* If data->clock is PCICLK, then select pci sync table. */
-		data->synct = nsp32_sync_table_pci;
-		data->syncnum = nsp32_table_pci_num;
-		break;
-	default:
-		nsp32_msg(KERN_WARNING,
-			  "Invalid clock div is selected, set CLOCK_4.");
-		/* Use default value CLOCK_4 */
-		data->clock = CLOCK_4;
-		data->synct = nsp32_sync_table_40M;
-		data->syncnum = nsp32_table_40M_num;
-	}
+	data->cur_lunt->SCpnt = NULL;
+	data->cur_lunt        = NULL;
+	data->cur_target      = NULL;
+	data->CurrentSC       = NULL;
+}
 
-	/*
-	 * setup nsp32_lunt
-	 */
-	data->lunt_list = (struct nsp32_lunt *)
-		kmalloc(sizeof(struct nsp32_lunt) * MAX_TARGET * MAX_LUN,
-			GFP_KERNEL);
-	if (data->lunt_list == NULL) {
-		nsp32_msg(KERN_ERR, "cannot allocate LUN memory");
-		goto scsi_unregister;
-	}
-	nsp32_dbg(NSP32_DEBUG_REGISTER, "0x%x 0x%x",
-		  data->lunt_list, sizeof(struct nsp32_lunt)*MAX_TARGET*MAX_LUN);
 
-	/*
-	 * setup DMA 
-	 */
-	if (pci_set_dma_mask(data->Pci, 0xffffffffUL)) {
-		nsp32_msg (KERN_ERR, "failed to set PCI DMA mask");
-		goto kfree_lunt;
-	}
+/*
+ * Bus Free Occur
+ *
+ * Current Phase is BUSFREE. AutoSCSI is automatically execute BUSFREE phase
+ * with ACK reply when below condition is matched:
+ *	MsgIn 00: Command Complete.
+ *	MsgIn 02: Save Data Pointer.
+ *	MsgIn 04: Diconnect.
+ * In other case, unexpected BUSFREE is detected.
+ */
+static int nsp32_busfree_occur(Scsi_Cmnd *SCpnt, unsigned short execph)
+{
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int base   = SCpnt->device->host->io_port;
 
-	/*
-	 * allocate autoparam DMA resource.
-	 */
-	data->autoparam = pci_alloc_consistent(data->Pci, AUTOPARAM_SIZE, &data->apaddr);
-	if (data->autoparam == NULL) {
-		nsp32_msg(KERN_ERR, "failed to allocate DMA memory");
-		goto kfree_lunt;
-	}
+	nsp32_dbg(NSP32_DEBUG_BUSFREE, "enter execph=0x%x", execph);
+	show_autophase(execph);
+
+	nsp32_write4(base, BM_CNT,           0);
+	nsp32_write2(base, TRANSFER_CONTROL, 0);
 
 	/*
-	 * allocate scatter-gather DMA resource.
+	 * MsgIn 02: Save Data Pointer
+	 *
+	 * VALID:
+	 *   Save Data Pointer is received. Adjust pointer.
+	 *   
+	 * NO-VALID:
+	 *   SCSI-3 says if Save Data Pointer is not received, then we restart
+	 *   processing and we can't adjust any SCSI data pointer in next data
+	 *   phase.
 	 */
-	data->sg_list = pci_alloc_consistent(data->Pci, 
-			(sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN),
-			 &data->sgaddr);
-	if (data->sg_list == NULL) {
-		nsp32_msg(KERN_ERR, "failed to allocate DMA memory");
-		goto free_autoparam;
-	}
+	if (execph & MSGIN_02_VALID) {
+		nsp32_dbg(NSP32_DEBUG_BUSFREE, "MsgIn02_Valid");
 
-	for (i=0; i<MAX_TARGET; i++) {
-		for (j=0; j<MAX_LUN; j++) {
-			data->lunt[i][j] = data->lunt_list + (i * MAX_LUN + j);
-		}
-	}
+		/*
+		 * Check sack_cnt/saved_sack_cnt, then adjust sg table if
+		 * needed.
+		 */
+		if (!(execph & MSGIN_00_VALID) && 
+		    ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE))) {
+			unsigned int sacklen, s_sacklen;
+
+			/*
+			 * Read SACK count and SAVEDSACK count, then compare.
+			 */
+			sacklen   = nsp32_read4(base, SACK_CNT      );
+			s_sacklen = nsp32_read4(base, SAVED_SACK_CNT);
+
+			/*
+			 * If SAVEDSACKCNT == 0, it means SavedDataPointer is
+			 * come after data transfering.
+			 */
+			if (s_sacklen > 0) {
+				/*
+				 * Comparing between sack and savedsack to
+				 * check the condition of AutoMsgIn03.
+				 *
+				 * If they are same, set msgin03 == TRUE,
+				 * COMMANDCONTROL_AUTO_MSGIN_03 is enabled at
+				 * reselection.  On the other hand, if they
+				 * aren't same, set msgin03 == FALSE, and
+				 * COMMANDCONTROL_AUTO_MSGIN_03 is disabled at
+				 * reselection.
+				 */
+				if (sacklen != s_sacklen) {
+					data->cur_lunt->msgin03 = FALSE;
+				} else {
+					data->cur_lunt->msgin03 = TRUE;
+				}
 
-	for (i=0; i<MAX_TARGET; i++) {
-		for (j=0; j<MAX_LUN; j++) {
-			struct nsp32_lunt *lp = data->lunt[i][j];
-			lp->sglun = (struct nsp32_sglun *)
-				(data->sg_list + (i * MAX_LUN + j));
-			lp->sglun_paddr = data->sgaddr +
-				(long)((i * MAX_LUN + j) 
-				       * sizeof(struct nsp32_sglun));
-			lp->SCpnt = NULL;
-			lp->save_datp = 0;
-			lp->msgin03 = FALSE;
-			lp->sg_num = 0;
-			lp->cur_entry = 0;
+				nsp32_adjust_busfree(SCpnt, s_sacklen);
+			}
 		}
+
+		/* This value has not substitude with valid value yet... */
+		//data->cur_lunt->save_datp = data->cur_datp;
+	} else {
+		/*
+		 * no processing.
+		 */
+	}
+	
+	if (execph & MSGIN_03_VALID) {
+		/* MsgIn03 was valid to be processed. No need processing. */
 	}
 
 	/*
-	 * setup target
+	 * target SDTR check
 	 */
-	for (i=0; i<MAX_TARGET; i++) {
-		struct nsp32_target *target = &data->target[i];
-
-		target->limit_entry  = 0;
-		target->sync_flag    = 0;
-		nsp32_set_async(data, target);
+	if (data->cur_target->sync_flag & SDTR_INITIATOR) {
+		/*
+		 * SDTR negotiation pulled by the initiator has not
+		 * finished yet. Fall back to ASYNC mode.
+		 */
+		nsp32_set_async(data, data->cur_target);
+		data->cur_target->sync_flag &= ~SDTR_INITIATOR;
+		data->cur_target->sync_flag |= SDTR_DONE;
+	} else if (data->cur_target->sync_flag & SDTR_TARGET) {
+		/*
+		 * SDTR negotiation pulled by the target has been
+		 * negotiating.
+		 */
+		if (execph & (MSGIN_00_VALID | MSGIN_04_VALID)) {
+			/* 
+			 * If valid message is received, then
+			 * negotiation is succeeded.
+			 */
+		} else {
+			/*
+			 * On the contrary, if unexpected bus free is
+			 * occurred, then negotiation is failed. Fall
+			 * back to ASYNC mode.
+			 */
+			nsp32_set_async(data, data->cur_target);
+		}
+		data->cur_target->sync_flag &= ~SDTR_TARGET;
+		data->cur_target->sync_flag |= SDTR_DONE;
 	}
 
 	/*
-	 * EEPROM check
+	 * It is always ensured by SCSI standard that initiator
+	 * switches into Bus Free Phase after
+	 * receiving message 00 (Command Complete), 04 (Disconnect).
+	 * It's the reason that processing here is valid.
 	 */
-	ret = nsp32_getprom_param(data);
-	if (ret == FALSE) {
-		data->resettime = 3;	/* default 3 */
+	if (execph & MSGIN_00_VALID) {
+		/* MsgIn 00: Command Complete */
+		nsp32_dbg(NSP32_DEBUG_BUSFREE, "command complete");
+
+		SCpnt->SCp.Status  = nsp32_read1(base, SCSI_CSB_IN);
+		SCpnt->SCp.Message = 0;
+		nsp32_dbg(NSP32_DEBUG_BUSFREE, 
+			  "normal end stat=0x%x resid=0x%x\n",
+			  SCpnt->SCp.Status, SCpnt->resid);
+		SCpnt->result = (DID_OK             << 16) |
+			        (SCpnt->SCp.Message <<  8) |
+			        (SCpnt->SCp.Status  <<  0);
+		nsp32_scsi_done(SCpnt);
+		/* All operation is done */
+		return TRUE;
+	} else if (execph & MSGIN_04_VALID) {
+		/* MsgIn 04: Disconnect */
+		SCpnt->SCp.Status  = nsp32_read1(base, SCSI_CSB_IN);
+		SCpnt->SCp.Message = 4;
+		
+		nsp32_dbg(NSP32_DEBUG_BUSFREE, "disconnect");
+		return TRUE;
+	} else {
+		/* Unexpected bus free */
+		nsp32_msg(KERN_WARNING, "unexpected bus free occurred");
+
+		/* DID_ERROR? */
+		//SCpnt->result   = (DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0);
+		SCpnt->result = DID_ERROR << 16;
+		nsp32_scsi_done(SCpnt);
+		return TRUE;
 	}
+	return FALSE;
+}
 
-	/*
-	 * setup HBA
-	 */
-	nsp32hw_init(host);
 
-	snprintf(data->info_str, sizeof(data->info_str),
-		 "NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x",
-		 host->irq, host->io_port, host->n_io_port);
+/*
+ * nsp32_adjust_busfree - adjusting SG table
+ *
+ * Note: This driver adjust the SG table using SCSI ACK
+ *       counter instead of BMCNT counter!
+ */
+static void nsp32_adjust_busfree(Scsi_Cmnd *SCpnt, unsigned int s_sacklen)
+{
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	int                   old_entry = data->cur_entry;
+	int                   new_entry;
+	int                   sg_num = data->cur_lunt->sg_num;
+	nsp32_sgtable *sgt    = data->cur_lunt->sglun->sgt;
+	unsigned int          restlen, sentlen;
+	u32                   len, addr;
 
-	sht->name = data->info_str;
+	nsp32_dbg(NSP32_DEBUG_SGLIST, "old resid=0x%x", SCpnt->resid);
+
+	/* adjust saved SACK count with 4 byte start address boundary */
+	s_sacklen -= le32_to_cpu(sgt[old_entry].addr) & 3;
 
 	/*
-	 * SCSI bus reset
-	 *
-	 * Note: It's important to reset SCSI bus in initialization phase.
-	 *     NinjaSCSI-32Bi/UDE HBA EEPROM seems to exchange SDTR when system is
-	 *     coming up, so SCSI devices connected to HBA is set as
-	 *     un-asynchronous mode.  It brings the merit that this HBA is
-	 *     ready to start synchronous transfer without any preparation,
-	 *     but we are difficult to control transfer speed.  In addition,
-	 *     it prevents device transfer speed from effecting EEPROM start-up
-	 *     SDTR.  NinjaSCSI-32Bi/UDE has the feature if EEPROM is set as Auto
-	 *     Mode, then FAST-10M is selected when SCSI devices are connected
-	 *     same or more than 4 devices.  It should be avoided depending on
-	 *     this specification Thus, resetting the SCSI bus restores all
-	 *     connected SCSI devices to asynchronous mode, then this driver
-	 *     put SDTR safely later, and we can control all SCSI device
-	 *     transfer mode.
+	 * calculate new_entry from sack count and each sgt[].len 
+	 * calculate the byte which is intent to send
 	 */
-	nsp32_do_bus_reset(data);
+	sentlen = 0;
+	for (new_entry = old_entry; new_entry < sg_num; new_entry++) {
+		sentlen += (le32_to_cpu(sgt[new_entry].len) & ~SGTEND);
+		if (sentlen > s_sacklen) {
+			break;
+		}
+	}
 
-	ret = request_irq(host->irq, do_nsp32_isr, SA_SHIRQ, "nsp32", data);
-	if (ret < 0) {
-		nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NSP32 "
-			  "SCSI PCI controller. Interrupt: %d\n", host->irq);
-		goto free_sg_list;
+	/* all sgt is processed */
+	if (new_entry == sg_num) {
+		goto last;
 	}
 
-        /*
-         * PCI IO register
-         */
-	if(!request_region(host->io_port, host->n_io_port, "nsp32")) {
-		nsp32_msg(KERN_ERR, 
-			  "I/O region 0x%lx+0x%lx is already used",
-			  data->BaseAddress, data->length);
-		goto free_irq;
-        }
+	if (sentlen == s_sacklen) {
+		/* XXX: confirm it's ok or not */
+		/* In this case, it's ok because we are at 
+		   the head element of the sg. restlen is correctly calculated. */
+	}
 
-	return 1;
+	/* calculate the rest length for transfering */
+	restlen = sentlen - s_sacklen;
 
- free_irq:
-	free_irq(host->irq, data);
-
- free_autoparam:
-	pci_free_consistent(data->Pci, AUTOPARAM_SIZE, data->autoparam, data->apaddr);
-	
- free_sg_list:
-	pci_free_consistent(data->Pci,
-		(sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN),
-		data->sg_list, data->sgaddr);
-	
- kfree_lunt:
-	kfree(data->lunt_list);
-
- scsi_unregister:
-	scsi_unregister(host);
-
- err:
-	return 0;
-}
-
-static int nsp32_release(struct Scsi_Host *shpnt)
-{
-	nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata;
-
-	if (data->lunt_list) {
-		kfree(data->lunt_list);
-	}
-
-	if (data->autoparam) {
-		pci_free_consistent(data->Pci, AUTOPARAM_SIZE,
-					data->autoparam, data->apaddr);
-	}
-
-	if (data->sg_list) {
-		pci_free_consistent(data->Pci, 
-			(sizeof(struct nsp32_sgtable) * NSP_SG_SIZE * MAX_TARGET * MAX_LUN),
-			data->sg_list, data->sgaddr);
-	}
-
-	DEBUG(0, "free irq\n");
-	if (shpnt->irq) {
-		free_irq(shpnt->irq, data);
-	}
+	/* update adjusting current SG table entry */
+	len  = le32_to_cpu(sgt[new_entry].len);
+	addr = le32_to_cpu(sgt[new_entry].addr);
+	addr += (len - restlen);
+	sgt[new_entry].addr = cpu_to_le32(addr);
+	sgt[new_entry].len  = cpu_to_le32(restlen);
 
-	DEBUG(0, "free io\n");
-	if (shpnt->io_port && shpnt->n_io_port) {
-		release_region(shpnt->io_port, shpnt->n_io_port);
-	}
+	/* set cur_entry with new_entry */
+	data->cur_entry = new_entry;
+ 
+	return;
 
-	if (data->MmioAddress != 0) {
-		iounmap((void *)(data->MmioAddress));
+ last:
+	if (SCpnt->resid < sentlen) {
+		nsp32_msg(KERN_ERR, "resid underflow");
 	}
 
-	return 0;
-}
+	SCpnt->resid -= sentlen;
+	nsp32_dbg(NSP32_DEBUG_SGLIST, "new resid=0x%x", SCpnt->resid);
 
-static const char *nsp32_info(struct Scsi_Host *shpnt)
-{
-	nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata;
+	/* update hostdata and lun */
 
-	return data->info_str;
+	return;
 }
 
 
 /*
- * error handler
+ * It's called MsgOut phase occur.
+ * NinjaSCSI-32Bi/UDE automatically processes up to 3 messages in
+ * message out phase. It, however, has more than 3 messages,
+ * HBA creates the interrupt and we have to process by hand.
  */
-static int nsp32_reset(Scsi_Cmnd *SCpnt, unsigned int reset_flags)
+static void nsp32_msgout_occur(Scsi_Cmnd *SCpnt)
 {
-	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%p why=%d\n", SCpnt, reset_flags);
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int base   = SCpnt->device->host->io_port;
+	//unsigned short command;
+	long new_sgtp;
+	int i;
+	
+	nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR,
+		  "enter: msgout_len: 0x%x", data->msgout_len);
 
-	nsp32_eh_bus_reset(SCpnt);
+	/*
+	 * If MsgOut phase is occurred without having any
+	 * message, then No_Operation is sent (SCSI-2).
+	 */
+	if (data->msgout_len == 0) {
+		nsp32_build_nop(SCpnt);
+	}
 
-	return SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
-}
+	/*
+	 * Set SGTP ADDR current entry for restarting AUTOSCSI, 
+	 * because SGTP is incremented next point.
+	 * There is few statement in the specification...
+	 */
+ 	new_sgtp = data->cur_lunt->sglun_paddr + 
+		   (data->cur_lunt->cur_entry * sizeof(nsp32_sgtable));
 
-static int nsp32_eh_abort(Scsi_Cmnd *SCpnt)
-{
-	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata;
-	unsigned int base = data->BaseAddress;
+	/*
+	 * send messages
+	 */
+	for (i = 0; i < data->msgout_len; i++) {
+		nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR,
+			  "%d : 0x%x", i, data->msgoutbuf[i]);
 
-	nsp32_msg(KERN_WARNING, "abort");
+		/*
+		 * Check REQ is asserted.
+		 */
+		nsp32_wait_req(data, ASSERT);
 
-	if (data->curlunt->SCpnt == NULL) {
-		return (FAILED);
-	}
+		if (i == (data->msgout_len - 1)) {
+			/*
+			 * If the last message, set the AutoSCSI restart
+			 * before send back the ack message. AutoSCSI
+			 * restart automatically negate ATN signal.
+			 */
+			//command = (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02);
+			//nsp32_restart_autoscsi(SCpnt, command);
+			nsp32_write2(base, COMMAND_CONTROL,
+					 (CLEAR_CDB_FIFO_POINTER |
+					  AUTO_COMMAND_PHASE     |
+					  AUTOSCSI_RESTART       |
+					  AUTO_MSGIN_00_OR_04    |
+					  AUTO_MSGIN_02          ));
+		}
+		/*
+		 * Write data with SACK, then wait sack is
+		 * automatically negated.
+		 */
+		nsp32_write1(base, SCSI_DATA_WITH_ACK, data->msgoutbuf[i]);
+		nsp32_wait_sack(data, NEGATE);
 
-	if (data->curtarget->sync_flag & (SDTR_INITIATOR | SDTR_TARGET)) {
-		/* reset SDTR negotiation */
-		data->curtarget->sync_flag = 0;
-	}
+		nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "bus: 0x%x\n",
+			  nsp32_read1(base, SCSI_BUS_MONITOR));
+	};
 
-	nsp32_write2(base, TRANSFER_CONTROL, 0);
-	nsp32_write2(base, BM_CNT, 0);
+	data->msgout_len = 0;
 
-	return (FAILED);
+	nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "exit");
 }
 
-static int nsp32_eh_bus_reset(Scsi_Cmnd *SCpnt)
+/*
+ * Restart AutoSCSI
+ *
+ * Note: Restarting AutoSCSI needs set:
+ *		SYNC_REG, ACK_WIDTH, SGT_ADR, TRANSFER_CONTROL
+ */
+static void nsp32_restart_autoscsi(Scsi_Cmnd *SCpnt, unsigned short command)
 {
-	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->host->hostdata;
-	unsigned int base = data->BaseAddress;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int   base = data->BaseAddress;
+	unsigned short transfer = 0;
 
-	nsp32_msg(KERN_INFO, "Bus Reset");	
-	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
+	nsp32_dbg(NSP32_DEBUG_RESTART, "enter");
 
-	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
-	nsp32_do_bus_reset(data);
-	nsp32_write2(base, IRQ_CONTROL, 0);
+	if (data->cur_target == NULL || data->cur_lunt == NULL) {
+		nsp32_msg(KERN_ERR, "Target or Lun is invalid");
+	}
 
-	return SUCCESS;	/* SCSI bus reset is succeeded at any time. */
-}
+	/*
+	 * set SYNC_REG
+	 * Don't set BM_START_ADR before setting this register.
+	 */
+	nsp32_write1(base, SYNC_REG, data->cur_target->syncreg);
 
-static void nsp32_do_bus_reset(nsp32_hw_data *data)
-{
-	unsigned int base = data->BaseAddress;
-	unsigned short intrdat;
-	int i;
+	/*
+	 * set ACKWIDTH
+	 */
+	nsp32_write1(base, ACK_WIDTH, data->cur_target->ackwidth);
 
 	/*
-	 * stop all transfer
-	 * clear TRANSFERCONTROL_BM_START
-	 * clear counter
+	 * set SREQ hazard killer sampling rate
 	 */
-	nsp32_write2(base, TRANSFER_CONTROL, 0);
-	nsp32_write4(base, BM_CNT,           0);
-	nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK);
+	nsp32_write1(base, SREQ_SMPL_RATE, data->cur_target->sample_reg);
 
 	/*
-	 * fall back to asynchronous transfer mode
-	 * initialize SDTR negotiation flag
+	 * set SGT ADDR (physical address)
 	 */
-	for (i=0; i<MAX_TARGET; i++) {
-		struct nsp32_target *target = &data->target[i];
+	nsp32_write4(base, SGT_ADR, data->cur_lunt->sglun_paddr);
 
-		target->sync_flag = 0;
-		nsp32_set_async(data, target);
+	/*
+	 * set TRANSFER CONTROL REG
+	 */
+	transfer = 0;
+	transfer |= (TRANSFER_GO | ALL_COUNTER_CLR);
+	if (data->trans_method & NSP32_TRANSFER_BUSMASTER) {
+		if (SCpnt->request_bufflen > 0) {
+			transfer |= BM_START;
+		}
+	} else if (data->trans_method & NSP32_TRANSFER_MMIO) {
+		transfer |= CB_MMIO_MODE;
+	} else if (data->trans_method & NSP32_TRANSFER_PIO) {
+		transfer |= CB_IO_MODE;
 	}
+	nsp32_write2(base, TRANSFER_CONTROL, transfer);
 
 	/*
-	 * reset SCSI bus
+	 * restart AutoSCSI
+	 *
+	 * TODO: COMMANDCONTROL_AUTO_COMMAND_PHASE is needed ?
 	 */
-	nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST);
-	udelay(RESET_HOLD_TIME);
-	nsp32_write1(base, SCSI_BUS_CONTROL, 0);
-	for(i = 0; i < 5; i++) {
-		intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */
-		nsp32_dbg(NSP32_DEBUG_BUSRESET, "irq:1: 0x%x", intrdat);
-        }
+	command |= (CLEAR_CDB_FIFO_POINTER |
+		    AUTO_COMMAND_PHASE     |
+		    AUTOSCSI_RESTART       );
+	nsp32_write2(base, COMMAND_CONTROL, command);
 
-	data->CurrentSC = NULL;
+	nsp32_dbg(NSP32_DEBUG_RESTART, "exit");
 }
 
-static int nsp32_eh_host_reset(Scsi_Cmnd *SCpnt)
-{
-	struct Scsi_Host *host = SCpnt->host;
-	nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata;
-	unsigned int base = data->BaseAddress;
-
-	nsp32_msg(KERN_INFO, "Host Reset");	
-	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
-
-	nsp32hw_init(host);
-	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
-	nsp32_do_bus_reset(data);
-	nsp32_write2(base, IRQ_CONTROL, 0);
-
-	return SUCCESS;	/* Host reset is succeeded at any time. */
-}
 
 /*
- * PCI/Cardbus probe/remove routine
+ * cannot run automatically message in occur
  */
-static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id)
-{
-	int ret;
-	nsp32_hw_data *data = &nsp32_data_base;
-
-	nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
+static void nsp32_msgin_occur(Scsi_Cmnd     *SCpnt,
+			      unsigned long  irq_status,
+			      unsigned short execph)
+{
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int   base = SCpnt->device->host->io_port;
+	unsigned char  msg;
+	unsigned char  msgtype;
+	unsigned char  newlun;
+	unsigned short command  = 0;
+	int            msgclear = TRUE;
+	long           new_sgtp;
+	int            ret;
 
-        ret = pci_enable_device(pdev);
-	if (ret) {
-		nsp32_msg(KERN_ERR, "failed to enable pci device");
-		return ret;
-	}
+	/*
+	 * read first message
+	 *    Use SCSIDATA_W_ACK instead of SCSIDATAIN, because the procedure
+	 *    of Message-In have to be processed before sending back SCSI ACK.
+	 */
+	msg = nsp32_read1(base, SCSI_DATA_IN);
+	data->msginbuf[(unsigned char)data->msgin_len] = msg;
+	msgtype = data->msginbuf[0];
+	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR,
+		  "enter: msglen: 0x%x msgin: 0x%x msgtype: 0x%x",
+		  data->msgin_len, msg, msgtype);
 
-	data->Pci = pdev;
-	data->pci_devid = id;
-	data->IrqNumber = pdev->irq;
-	data->BaseAddress = pci_resource_start(pdev, 0);
-	data->NumAddress = pci_resource_len(pdev, 0);
-	data->MmioAddress = (unsigned long)ioremap_nocache(
-		pci_resource_start(pdev, 1), pci_resource_len(pdev, 1));
+	/*
+	 * TODO: We need checking whether bus phase is message in?
+	 */
 
-	pci_set_master(pdev);
+	/*
+	 * assert SCSI ACK
+	 */
+	nsp32_sack_assert(data);
 
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
-	scsi_register_host(&driver_template);
-#else
-	scsi_register_module(MODULE_SCSI_HA, &driver_template);
-#endif
+	/*
+	 * processing IDENTIFY
+	 */
+	if (msgtype & 0x80) {
+		if (!(irq_status & IRQSTATUS_RESELECT_OCCUER)) {
+			/* Invalid (non reselect) phase */
+			goto reject;
+		}
 
-	nsp32_msg(KERN_INFO, "nsp32 irq: %i mmio: 0x%lx slot: %s model: %s",
-		  pdev->irq, data->MmioAddress, pdev->slot_name,
-		  nsp32_model[id->driver_data]);
+		newlun = msgtype & 0x1f; /* TODO: SPI-3 compliant? */
+		ret = nsp32_reselection(SCpnt, newlun);
+		if (ret == TRUE) {
+			goto restart;
+		} else {
+			goto reject;
+		}
+	}
+	
+	/*
+	 * processing messages except for IDENTIFY
+	 *
+	 * TODO: Messages are all SCSI-2 terminology. SCSI-3 compliance is TODO.
+	 */
+	switch (msgtype) {
+	/*
+	 * 1-byte message
+	 */
+	case COMMAND_COMPLETE:
+	case DISCONNECT:
+		/*
+		 * These messages should not be occurred.
+		 * They should be processed on AutoSCSI sequencer.
+		 */
+		nsp32_msg(KERN_WARNING, 
+			   "unexpected message of AutoSCSI MsgIn: 0x%x", msg);
+		break;
+		
+	case RESTORE_POINTERS:
+		/*
+		 * AutoMsgIn03 is disabled, and HBA gets this message.
+		 */
 
-	nsp32_dbg(NSP32_DEBUG_REGISTER, "exit");
+		if ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE)) {
+			unsigned int s_sacklen;
 
-	return 0;
-}
+			s_sacklen = nsp32_read4(base, SAVED_SACK_CNT);
+			if ((execph & MSGIN_02_VALID) && (s_sacklen > 0)) {
+				nsp32_adjust_busfree(SCpnt, s_sacklen);
+			} else {
+				/* No need to rewrite SGT */
+			}
+		}
+		data->cur_lunt->msgin03 = FALSE;
 
-static void __devexit nsp32_remove(struct pci_dev *pdev)
-{
-	nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
-	
-#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
-	scsi_unregister_host(&driver_template);
-#else
-	scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
-#endif
-}
+		/* Update with the new value */
 
-static struct pci_device_id nsp32_pci_table[] __devinitdata = {
-	{
-		vendor:      PCI_VENDOR_ID_IODATA,
-		device:      PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_IODATA,
-	},
-	{
-		vendor:      PCI_VENDOR_ID_WORKBIT,
-		device:      PCI_DEVICE_ID_NINJASCSI_32BI_KME,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_KME,
-	},
-	{
-		vendor:      PCI_VENDOR_ID_WORKBIT,
-		device:      PCI_DEVICE_ID_NINJASCSI_32BI_WBT,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_WORKBIT,
-	},
-	{
-		vendor:      PCI_VENDOR_ID_WORKBIT,
-		device:      PCI_DEVICE_ID_WORKBIT_STANDARD,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_PCI_WORKBIT,
-	},
-	{
-		vendor:      PCI_VENDOR_ID_WORKBIT,
-		device:      PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_EXT_ROM,
-	},
-	{
-		vendor:      PCI_VENDOR_ID_WORKBIT,
-		device:      PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_PCI_LOGITEC,
-	},
-	{
-		vendor:      PCI_VENDOR_ID_WORKBIT,
-		device:      PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO,
-		subvendor:   PCI_ANY_ID,
-		subdevice:   PCI_ANY_ID,
-		driver_data: MODEL_PCI_MELCO,
-	},
-	{0,0,},
-};
-MODULE_DEVICE_TABLE(pci, nsp32_pci_table);
+		/* reset SACK/SavedACK counter (or ALL clear?) */
+		nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK);
 
-static struct pci_driver nsp32_driver = {
-	.name =		"nsp32",
-	.id_table =	nsp32_pci_table,
-	.probe =	nsp32_probe,
-	.remove =	__devexit_p(nsp32_remove),
-#ifdef CONFIG_PM
-/*	.suspend =	nsp32_suspend,*/
-/*	.resume =	nsp32_resume,*/
-#endif
-};
+		/*
+		 * set new sg pointer
+		 */
+		new_sgtp = data->cur_lunt->sglun_paddr + 
+			(data->cur_lunt->cur_entry * sizeof(nsp32_sgtable));
+		nsp32_write4(base, SGT_ADR, new_sgtp);
 
-static int __init init_nsp32(void) {
-	return pci_module_init(&nsp32_driver);
-}
+		break;
 
-static void __exit exit_nsp32(void) {
-	pci_unregister_driver(&nsp32_driver);
-}
+	case SAVE_POINTERS:
+		/*
+		 * These messages should not be occurred.
+		 * They should be processed on AutoSCSI sequencer.
+		 */
+		nsp32_msg (KERN_WARNING, 
+			   "unexpected message of AutoSCSI MsgIn: SAVE_POINTERS");
+		
+		break;
+		
+	case MESSAGE_REJECT:
+		/* If previous message_out is sending SDTR, and get 
+		   message_reject from target, SDTR negotiation is failed */
+		if (data->cur_target->sync_flag &
+				(SDTR_INITIATOR | SDTR_TARGET)) {
+			/*
+			 * Current target is negotiating SDTR, but it's
+			 * failed.  Fall back to async transfer mode, and set
+			 * SDTR_DONE.
+			 */
+			nsp32_set_async(data, data->cur_target);
+			data->cur_target->sync_flag &= ~SDTR_INITIATOR;
+			data->cur_target->sync_flag |= SDTR_DONE;
 
-module_init(init_nsp32);
-module_exit(exit_nsp32);
+		}
+		break;
 
+	case LINKED_CMD_COMPLETE:
+	case LINKED_FLG_CMD_COMPLETE:
+		/* queue tag is not supported currently */
+		nsp32_msg (KERN_WARNING, 
+			   "unsupported message: 0x%x", msgtype);
+		break;
 
-/*
- * Reset parameters and call scsi_done for data->curlunt.
- * Be careful setting SCpnt->result = DID_* before calling this function.
- */
-static void nsp32_scsi_done(nsp32_hw_data *data, Scsi_Cmnd *SCpnt)
-{
-	unsigned int base = data->BaseAddress;
+	case INITIATE_RECOVERY:
+		/* staring ECA (Extended Contingent Allegiance) state. */
+		/* This message is declined in SPI2 or later. */
+
+		goto reject;
 
 	/*
-	 * unmap pci
+	 * 2-byte message
 	 */
-	if (SCpnt->request_bufflen == 0) {
-		goto skip;
+	case SIMPLE_QUEUE_TAG:
+	case 0x23:
+		/*
+		 * 0x23: Ignore_Wide_Residue is not declared in scsi.h.
+		 * No support is needed.
+		 */
+		if (data->msgin_len >= 1) {
+			goto reject;
+		}
+
+		/* current position is 1-byte of 2 byte */
+		msgclear = FALSE;
+
+		break;
+
+	/*
+	 * extended message
+	 */
+	case EXTENDED_MESSAGE:
+		if (data->msgin_len < 1) {
+			/*
+			 * Current position does not reach 2-byte
+			 * (2-byte is extended message length).
+			 */
+			msgclear = FALSE;
+			break;
+		}
+
+		if ((data->msginbuf[1] + 1) > data->msgin_len) {
+			/*
+			 * Current extended message has msginbuf[1] + 2
+			 * (msgin_len starts counting from 0, so buf[1] + 1).
+			 * If current message position is not finished,
+			 * continue receiving message.
+			 */
+			msgclear = FALSE;
+			break;
+		}
+
+		/*
+		 * Reach here means regular length of each type of 
+		 * extended messages.
+		 */
+		switch (data->msginbuf[2]) {
+		case EXTENDED_MODIFY_DATA_POINTER:
+			/* TODO */
+			goto reject; /* not implemented yet */
+			break;
+
+		case EXTENDED_SDTR:
+			/*
+			 * Exchange this message between initiator and target.
+			 */
+			if (data->msgin_len != EXTENDED_SDTR_LEN + 1) {
+				/*
+				 * received inappropriate message.
+				 */
+				goto reject;
+				break;
+			}
+
+			nsp32_analyze_sdtr(SCpnt);
+
+			break;
+
+		case EXTENDED_EXTENDED_IDENTIFY:
+			/* SCSI-I only, not supported. */
+			goto reject; /* not implemented yet */
+
+			break;
+
+		case EXTENDED_WDTR:
+			goto reject; /* not implemented yet */
+
+			break;
+			
+		default:
+			goto reject;
+		}
+		break;
+		
+	default:
+		goto reject;
 	}
 
-	if (SCpnt->use_sg) {
-		pci_unmap_sg(data->Pci,
-			(struct scatterlist *)SCpnt->buffer,
-			SCpnt->use_sg,
-			scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+ restart:
+	if (msgclear == TRUE) {
+		data->msgin_len = 0;
+
+		/*
+		 * If restarting AutoSCSI, but there are some message to out
+		 * (msgout_len > 0), set AutoATN, and set SCSIMSGOUT as 0
+		 * (MSGOUT_VALID = 0). When commandcontrol is written with
+		 * AutoSCSI restart, at the same time MsgOutOccur should be
+		 * happened (however, such situation is really possible...?).
+		 */
+		if (data->msgout_len > 0) {	
+			nsp32_write4(base, SCSI_MSG_OUT, 0);
+			command |= AUTO_ATN;
+		}
+
+		/*
+		 * restart AutoSCSI
+		 * If it's failed, COMMANDCONTROL_AUTO_COMMAND_PHASE is needed.
+		 */
+		command |= (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02);
+
+		/*
+		 * If current msgin03 is TRUE, then flag on.
+		 */
+		if (data->cur_lunt->msgin03 == TRUE) {
+			command |= AUTO_MSGIN_03;
+		}
+		data->cur_lunt->msgin03 = FALSE;
 	} else {
-		pci_unmap_single(data->Pci,
-			(u32)SCpnt->SCp.have_data_in,
-			SCpnt->request_bufflen,
-			scsi_to_pci_dma_dir(SCpnt->sc_data_direction));
+		data->msgin_len++;
 	}
 
- skip:
 	/*
-	 * clear TRANSFERCONTROL_BM_START
+	 * restart AutoSCSI
 	 */
-	nsp32_write2(base, TRANSFER_CONTROL, 0);
-	nsp32_write4(base, BM_CNT, 0);
+	nsp32_restart_autoscsi(SCpnt, command);
 
 	/*
-	 * call scsi_done
+	 * wait SCSI REQ negate for REQ-ACK handshake
 	 */
-	(*SCpnt->scsi_done)(SCpnt);
+	nsp32_wait_req(data, NEGATE);
 
 	/*
-	 * reset parameters
+	 * negate SCSI ACK
 	 */
-	data->curlunt->SCpnt = NULL;
-	data->curlunt = NULL;
-	data->curtarget = NULL;
-	data->CurrentSC = NULL;
-}
+	nsp32_sack_negate(data);
+
+	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit");
+
+	return;
+
+ reject:
+	nsp32_msg(KERN_WARNING, 
+		  "invalid or unsupported MessageIn, rejected. "
+		  "current msg: 0x%x (len: 0x%x), processing msg: 0x%x",
+		  msg, data->msgin_len, msgtype);
+	nsp32_build_reject(SCpnt);
+	data->msgin_len = 0;
 
+	goto restart;
+}
 
 /*
- * Bus Free Occur
- *
- * Current Phase is BUSFREE. AutoSCSI is automatically execute BUSFREE phase
- * with ACK reply when below condition is matched:
- *	MsgIn 00: Command Complete.
- *	MsgIn 02: Save Data Pointer.
- *	MsgIn 04: Diconnect.
- * In other case, unexpected BUSFREE is detected.
+ * 
  */
-static int nsp32_busfree_occur(nsp32_hw_data *data, unsigned short execph)
+static void nsp32_analyze_sdtr(Scsi_Cmnd *SCpnt)
 {
-	Scsi_Cmnd *SCpnt = data->curlunt->SCpnt;
-	unsigned int base = data->BaseAddress;
+	nsp32_hw_data   *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	nsp32_target     *target     = data->cur_target;
+	nsp32_sync_table *synct;
+	unsigned char     get_period = data->msginbuf[3];
+	unsigned char     get_offset = data->msginbuf[4];
+	int               entry;
+	int               syncnum;
 
-	nsp32_dbg(NSP32_DEBUG_BUSFREE, "enter");
+	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "enter");
 
-	nsp32_write4(base, BM_CNT, 0);
-	nsp32_write2(base, TRANSFER_CONTROL, 0);
+	synct   = data->synct;
+	syncnum = data->syncnum;
 
 	/*
-	 * MsgIn 02: Save Data Pointer
-	 *
-	 * VALID:
-	 *   Save Data Pointer is received. Adjust pointer.
-	 *   
-	 * NO-VALID:
-	 *   SCSI-3 says if Save Data Pointer is not received, then we restart
-	 *   processing and we can't adjust any SCSI data pointer in next data
-	 *   phase.
-	 */
-	if (execph & MSGIN_02_VALID) {
-		nsp32_dbg(NSP32_DEBUG_BUSFREE, "MsgIn02_Valid");
-
+	 * If this inititor sent the SDTR message, then target responds SDTR,
+	 * initiator SYNCREG, ACKWIDTH from SDTR parameter.
+	 * Messages are not appropriate, then send back reject message.
+	 * If initiator did not send the SDTR, but target sends SDTR, 
+	 * initiator calculator the appropriate parameter and send back SDTR.
+	 */	
+	if (target->sync_flag & SDTR_INITIATOR) {
 		/*
-		 * Check sack_cnt/saved_sack_cnt, then adjust sg table if
-		 * needed.
+		 * Initiator sent SDTR, the target responds and
+		 * send back negotiation SDTR.
 		 */
-		if (!(execph & MSGIN_00_VALID) && 
-		    ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE))) {
-			unsigned int sacklen, s_sacklen;
+		nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target responds SDTR");
+	
+		target->sync_flag &= ~SDTR_INITIATOR;
+		target->sync_flag |= SDTR_DONE;
 
+		/*
+		 * offset:
+		 */
+		if (get_offset > MAX_OFFSET) {
 			/*
-			 * Read SACK count and SAVEDSACK count, then compare.
+			 * Negotiation is failed, the target send back
+			 * unexpected offset value.
 			 */
-			sacklen   = nsp32_read4(base, SACK_CNT);
-			s_sacklen = nsp32_read4(base, SAVED_SACK_CNT);
+			goto reject;
+		}
+		
+		if (get_offset == ASYNC_OFFSET) {
+			/*
+			 * Negotiation is succeeded, the target want
+			 * to fall back into asynchronous transfer mode.
+			 */
+			goto async;
+		}
 
+		/*
+		 * period:
+		 *    Check whether sync period is too short. If too short,
+		 *    fall back to async mode. If it's ok, then investigate
+		 *    the received sync period. If sync period is acceptable
+		 *    between sync table start_period and end_period, then
+		 *    set this I_T nexus as sent offset and period.
+		 *    If it's not acceptable, send back reject and fall back
+		 *    to async mode.
+		 */
+		if (get_period < data->synct[0].period_num) {
 			/*
-			 * If SAVEDSACKCNT == 0, it means SavedDataPointer is
-			 * come after data transfering.
+			 * Negotiation is failed, the target send back
+			 * unexpected period value.
 			 */
-			if (s_sacklen > 0) {
-				/*
-				 * Comparing between sack and savedsack to
-				 * check the condition of AutoMsgIn03.
-				 *
-				 * If they are same, set msgin03 == TRUE,
-				 * COMMANDCONTROL_AUTO_MSGIN_03 is enabled at
-				 * reselection.  On the other hand, if they
-				 * aren't same, set msgin03 == FALSE, and
-				 * COMMANDCONTROL_AUTO_MSGIN_03 is disabled at
-				 * reselection.
-				 */
-				if (sacklen != s_sacklen) {
-					data->curlunt->msgin03 = FALSE;
-				} else {
-					data->curlunt->msgin03 = TRUE;
-				}
+			goto reject;
+		}
 
-				nsp32_adjust_busfree(data, s_sacklen);
-			}
+		entry = nsp32_search_period_entry(data, target, get_period);
+
+		if (entry < 0) {
+			/*
+			 * Target want to use long period which is not 
+			 * acceptable NinjaSCSI-32Bi/UDE.
+			 */
+			goto reject;
 		}
 
-		/* This value has not substitude with valid value yet... */
-		//data->curlunt->save_datp = data->cur_datp;
-	} else {
 		/*
-		 * no processing.
+		 * Set new sync table and offset in this I_T nexus.
 		 */
-	}
+		nsp32_set_sync_entry(data, target, entry, get_offset);
+	} else {
+		/* Target send SDTR to initiator. */
+		nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target send SDTR");
 	
-	if (execph & MSGIN_03_VALID) {
-		/* MsgIn03 was valid to be processed. No need processing. */
-	}
+		target->sync_flag |= SDTR_INITIATOR;
 
-	/*
-	 * target SDTR check
-	 */
-	if (data->curtarget->sync_flag & SDTR_INITIATOR) {
-		/*
-		 * SDTR negotiation pulled by the initiator has not
-		 * finished yet. Fall back to ASYNC mode.
-		 */
-		nsp32_set_async(data, data->curtarget);
-		data->curtarget->sync_flag &= ~SDTR_INITIATOR;
-		data->curtarget->sync_flag |= SDTR_DONE;
-	} else if (data->curtarget->sync_flag & SDTR_TARGET) {
-		/*
-		 * SDTR negotiation pulled by the target has been
-		 * negotiating.
-		 */
-		if (execph & (MSGIN_00_VALID | MSGIN_04_VALID)) {
-			/* 
-			 * If valid message is received, then
-			 * negotiation is succeeded.
-			 */
+		/* offset: */
+		if (get_offset > MAX_OFFSET) {
+			/* send back as MAX_OFFSET */
+			get_offset = MAX_OFFSET;
+		}
+
+		/* period: */
+		if (get_period < data->synct[0].period_num) {
+			get_period = data->synct[0].period_num;
+		}
+
+		entry = nsp32_search_period_entry(data, target, get_period);
+
+		if (get_offset == ASYNC_OFFSET || entry < 0) {
+			nsp32_set_async(data, target);
+			nsp32_build_sdtr(SCpnt, 0, ASYNC_OFFSET);
 		} else {
-			/*
-			 * On the contrary, if unexpected bus free is
-			 * occured, then negotiation is failed. Fall
-			 * back to ASYNC mode.
-			 */
-			nsp32_set_async(data, data->curtarget);
+			nsp32_set_sync_entry(data, target, entry, get_offset);
+			nsp32_build_sdtr(SCpnt, get_period, get_offset);
 		}
-		data->curtarget->sync_flag &= ~SDTR_TARGET;
-		data->curtarget->sync_flag |= SDTR_DONE;
 	}
-	
+
+	target->period = get_period;
+	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit");
+	return;
+
+ reject:
 	/*
-	 * It is always ensured by SCSI standard that initiator
-	 * switches into Bus Free Phase after
-	 * receiving message 00 (Command Complete), 04 (Disconnect).
-	 * It's the reason that processing here is valid.
+	 * If the current message is unacceptable, send back to the target
+	 * with reject message.
 	 */
-	if (execph & MSGIN_00_VALID) {
-		/* MsgIn 00: Command Complete */
-		nsp32_dbg(NSP32_DEBUG_BUSFREE, "command complete");
+	nsp32_build_reject(SCpnt);
 
-		SCpnt->SCp.Status  = nsp32_read1(base, SCSI_CSB_IN);
-		SCpnt->SCp.Message = 0;
-		nsp32_dbg(NSP32_DEBUG_BUSFREE, 
-			  "normal end stat=0x%x resid=0x%x\n",
-			  SCpnt->SCp.Status, SCpnt->resid);
-		SCpnt->result = 
-			(DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0);
-		nsp32_scsi_done(data, SCpnt);
-		/* All operation is done */
-		return (TRUE);
-	} else if (execph & MSGIN_04_VALID) {
-		/* MsgIn 04: Disconnect */
-		SCpnt->SCp.Status  = nsp32_read1(base, SCSI_CSB_IN);
-		SCpnt->SCp.Message = 4;
-		
-		nsp32_dbg(NSP32_DEBUG_BUSFREE, "disconnect");
-		return (TRUE);
-	} else {
-		/* Unexpected bus free */
-		nsp32_msg(KERN_WARNING, "unexpected bus free occured");
+ async:
+	nsp32_set_async(data, target);	/* set as ASYNC transfer mode */
 
-		/* DID_ERROR? */
-		//SCpnt->result   = (DID_OK << 16) | (SCpnt->SCp.Message << 8) | (SCpnt->SCp.Status << 0);
-		SCpnt->result = DID_ERROR << 16;
-		nsp32_scsi_done(data, SCpnt);
-		return (TRUE);
-	}
-	return (FALSE);
+	target->period = 0;
+	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit: set async");
+	return;
 }
 
 
 /*
- * nsp32_adjust_busfree - adjusting SG table
- *
- * Note: This driver adjust the SG table using SCSI ACK
- *       counter instead of BMCNT counter!
+ * Search config entry number matched in sync_table from given
+ * target and speed period value. If failed to search, return negative value.
  */
-static void nsp32_adjust_busfree(nsp32_hw_data *data, unsigned int s_sacklen)
+static int nsp32_search_period_entry(nsp32_hw_data *data,
+				     nsp32_target  *target,
+				     unsigned char  period)
 {
-	int old_entry = data->cur_entry;
-	int new_entry;
-	struct nsp32_sgtable *sgt = data->curlunt->sglun->sgt;
-	unsigned int restlen, sentlen;
-	int sg_num = data->curlunt->sg_num;
+	int i;
 
-	/* adjust saved SACK count with 4 byte start address boundary */
-	s_sacklen -= sgt[old_entry].addr & 3;
+	if (target->limit_entry >= data->syncnum) {
+		nsp32_msg(KERN_ERR, "limit_entry exceeds syncnum!");
+		target->limit_entry = 0;
+	}
 
-	/*
-	 * calculate new_entry from sack count and each sgt[].len 
-	 * calculate the byte which is intent to send
-	 */
-	sentlen = 0;
-	for (new_entry = old_entry; new_entry < sg_num; new_entry++) {
-		sentlen += (sgt[new_entry].len & ~NSP32_SG_END_SGT);
-		if (sentlen > s_sacklen) {
-			break;
+	for (i = target->limit_entry; i < data->syncnum; i++) {
+		if (period >= data->synct[i].start_period &&
+		    period <= data->synct[i].end_period) {
+				break;
 		}
 	}
 
-	/* all sgt is processed */
-	if (new_entry == sg_num) {
-		goto last;
+	/*
+	 * Check given period value is over the sync_table value.
+	 * If so, return max value.
+	 */
+	if (i == data->syncnum) {
+		i = -1;
 	}
 
-	if (sentlen == s_sacklen) {
-		/* XXX: confirm it's ok or not */
-		/* In this case, it's ok because we are at 
-		   the head element of the sg. restlen is correctly calculated. */
-	}
+	return i;
+}
 
-	/* calculate the rest length for transfering */
-	restlen = sentlen - s_sacklen;
-	
-	/* update adjusting current SG table entry */
-	sgt[new_entry].addr += (sgt[new_entry].len - restlen);
-	sgt[new_entry].len = restlen;
 
-	/* set cur_entry with new_entry */
-	data->cur_entry = new_entry;
-	
-	return;
+/*
+ * target <-> initiator use ASYNC transfer
+ */
+static void nsp32_set_async(nsp32_hw_data *data, nsp32_target *target)
+{
+	unsigned char period = data->synct[target->limit_entry].period_num;
 
- last:
-	/* update hostdata and lun */
+	target->offset     = ASYNC_OFFSET;
+	target->period     = 0;
+	target->syncreg    = TO_SYNCREG(period, ASYNC_OFFSET);
+	target->ackwidth   = 0;
+	target->sample_reg = 0;
 
-	return;
+	nsp32_dbg(NSP32_DEBUG_SYNC, "set async");
 }
 
 
 /*
- * It's called MsgOut phase occur.
- * NinjaSCSI-32Bi/UDE automatically processes up to 3 messages in
- * message out phase. It, however, has more than 3 messages,
- * HBA creates the interrupt and we have to process by hand.
+ * target <-> initiator use maximum SYNC transfer
  */
-static void nsp32_msgout_occur(nsp32_hw_data *data)
+static void nsp32_set_max_sync(nsp32_hw_data *data,
+			       nsp32_target  *target,
+			       unsigned char *period,
+			       unsigned char *offset)
 {
-	unsigned int base = data->BaseAddress;
-	//unsigned short command;
-	long new_sgtp;
-	int i;
-	
-	nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR,
-		  "enter: msgoutlen: 0x%x", data->msgoutlen);
+	unsigned char period_num, ackwidth;
 
-	/*
-	 * If MsgOut phase is occured without having any
-	 * message, then No_Operation is sent (SCSI-2).
-	 */
-	if (data->msgoutlen == 0) {
-		nsp32_build_nop(data);
-	}
+	period_num = data->synct[target->limit_entry].period_num;
+	*period    = data->synct[target->limit_entry].start_period;
+	ackwidth   = data->synct[target->limit_entry].ackwidth;
+	*offset    = MAX_OFFSET;
 
-	/*
-	 * Set SGTP ADDR current entry for restarting AUTOSCSI, 
-	 * because SGTP is incremented next point.
-	 * There is few statement in the specification...
-	 */
- 	new_sgtp = data->curlunt->sglun_paddr
-		+ data->curlunt->cur_entry * sizeof(struct nsp32_sgtable);
+	target->syncreg    = TO_SYNCREG(period_num, *offset);
+	target->ackwidth   = ackwidth;
+	target->offset     = *offset;
+	target->sample_reg = 0;       /* disable SREQ sampling */
+}
 
-	/*
-	 * send messages
-	 */
-	for (i=0; i<data->msgoutlen; i++) {
-		nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR,
-			  "%d : 0x%x", i, data->msgoutbuf[i]);
 
-		/*
-		 * Check REQ is asserted.
-		 */
-		nsp32_wait_req(data, ASSERT);
+/*
+ * target <-> initiator use entry number speed
+ */
+static void nsp32_set_sync_entry(nsp32_hw_data *data,
+				 nsp32_target  *target,
+				 int            entry,
+				 unsigned char  offset)
+{
+	unsigned char period, ackwidth, sample_rate;
+
+	period      = data->synct[entry].period_num;
+	ackwidth    = data->synct[entry].ackwidth;
+	offset      = offset;
+	sample_rate = data->synct[entry].sample_rate;
+
+	target->syncreg    = TO_SYNCREG(period, offset);
+	target->ackwidth   = ackwidth;
+	target->offset     = offset;
+	target->sample_reg = sample_rate | SAMPLING_ENABLE;
 
-		if (i == (data->msgoutlen - 1)) {
-			/*
-			 * If the last message, set the AutoSCSI restart
-			 * before send back the ack message. AutoSCSI
-			 * restart automatically negate ATN signal.
-			 */
-			//command = (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02);
-			//nsp32_restart_autoscsi(data, command);
-			nsp32_write2(base, COMMAND_CONTROL,
-					 (CLEAR_CDB_FIFO_POINTER |
-					  AUTO_COMMAND_PHASE |
-					  AUTOSCSI_RESTART |
-					  AUTO_MSGIN_00_OR_04 |
-					  AUTO_MSGIN_02 ));
-		}
-		/*
-		 * Write data with SACK, then wait sack is
-		 * automatically negated.
-		 */
-		nsp32_write1(base, SCSI_DATA_WITH_ACK, data->msgoutbuf[i]);
-		nsp32_wait_sack(data, NEGATE);
-
-		nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "bus: 0x%x\n",
-			  nsp32_read1(base, SCSI_BUS_MONITOR));
-	};
-
-	data->msgoutlen = 0;
-
-	nsp32_dbg(NSP32_DEBUG_MSGOUTOCCUR, "exit");
+	nsp32_dbg(NSP32_DEBUG_SYNC, "set sync");
 }
 
+
 /*
- * Restart AutoSCSI
+ * It waits until SCSI REQ becomes assertion or negation state.
  *
- * Note: Restarting AutoSCSI needs set:
- *		SYNC_REG, ACK_WIDTH, SGT_ADR, TRANSFER_CONTROL
+ * Note: If nsp32_msgin_occur is called, we asserts SCSI ACK. Then
+ *     connected target responds SCSI REQ negation.  We have to wait
+ *     SCSI REQ becomes negation in order to negate SCSI ACK signal for
+ *     REQ-ACK handshake.
  */
-static void nsp32_restart_autoscsi(nsp32_hw_data *data, unsigned short command)
+static void nsp32_wait_req(nsp32_hw_data *data, int state)
 {
-	unsigned int base = data->BaseAddress;
-	unsigned short transfer = 0;
-	Scsi_Cmnd *SCpnt = data->curlunt->SCpnt;
+	unsigned int  base      = data->BaseAddress;
+	int           wait_time = 0;
+	unsigned char bus, req_bit;
 
-	nsp32_dbg(NSP32_DEBUG_RESTART, "enter");
-
-	if (data->curtarget == NULL || data->curlunt == NULL) {
-		nsp32_msg(KERN_ERR, "Target or Lun is invalid");
+	if (!((state == ASSERT) || (state == NEGATE))) {
+		nsp32_msg(KERN_ERR, "unknown state designation");
 	}
+	/* REQ is BIT(5) */
+	req_bit = (state == ASSERT ? BUSMON_REQ : 0);
 
-	/*
-	 * set SYNC_REG
-	 * Don't set BM_START_ADR before setting this register.
-	 */
-	nsp32_write1(base, SYNC_REG, data->curtarget->syncreg);
-
-	/*
-	 * set ACKWIDTH
-	 */
-	nsp32_write1(base, ACK_WIDTH, data->curtarget->ackwidth);
-
-	/*
-	 * set SGT ADDR (physical address)
-	 */
-	nsp32_write4(base, SGT_ADR, data->curlunt->sglun_paddr);
-
-	/*
-	 * set TRANSFER CONTROL REG
-	 */
-	transfer = 0;
-	transfer |= (TRANSFER_GO | ALL_COUNTER_CLR);
-	if (data->trans_method & NSP32_TRANSFER_BUSMASTER) {
-		if (SCpnt->request_bufflen > 0) {
-			transfer |= BM_START;
+	do {
+		bus = nsp32_read1(base, SCSI_BUS_MONITOR);
+		if ((bus & BUSMON_REQ) == req_bit) {
+			nsp32_dbg(NSP32_DEBUG_WAIT, 
+				  "wait_time: %d", wait_time);
+			return;
 		}
-	} else if (data->trans_method & NSP32_TRANSFER_MMIO) {
-		transfer |= CB_MMIO_MODE;
-	} else if (data->trans_method & NSP32_TRANSFER_PIO) {
-		transfer |= CB_IO_MODE;
-	}
-	nsp32_write2(base, TRANSFER_CONTROL, transfer);
-
-	/*
-	 * restart AutoSCSI
-	 *
-	 * TODO: COMMANDCONTROL_AUTO_COMMAND_PHASE is needed ?
-	 */
-	command |= (CLEAR_CDB_FIFO_POINTER |
-		    AUTO_COMMAND_PHASE |
-		    AUTOSCSI_RESTART);
-	nsp32_write2(base, COMMAND_CONTROL, command);
+		udelay(1);
+		wait_time++;
+	} while (wait_time < REQSACK_TIMEOUT_TIME);
 
-	nsp32_dbg(NSP32_DEBUG_RESTART, "exit");
+	nsp32_msg(KERN_WARNING, "wait REQ timeout, req_bit: 0x%x", req_bit);
 }
 
-
 /*
- * cannot run automatically message in occur
+ * It waits until SCSI SACK becomes assertion or negation state.
  */
-static void nsp32_msgin_occur(nsp32_hw_data *data, unsigned long irq_status,
-			unsigned short execph)
+static void nsp32_wait_sack(nsp32_hw_data *data, int state)
 {
-	unsigned int base = data->BaseAddress;
-	unsigned char msg;
-	unsigned char msgtype;
-	unsigned char newlun;
-	unsigned short command = 0;
-	int msgclear = TRUE;
-	long new_sgtp;
-	int ret;
+	unsigned int  base      = data->BaseAddress;
+	int           wait_time = 0;
+	unsigned char bus, ack_bit;
 
-	/*
-	 * read first message
-	 *    Use SCSIDATA_W_ACK instead of SCSIDATAIN, because the procedure
-	 *    of Message-In have to be processed before sending back SCSI ACK.
-	 */
-	msg = nsp32_read1(base, SCSI_DATA_IN);
-	data->msginbuf[(unsigned char)data->msginlen] = msg;
-	msgtype = data->msginbuf[0];
-	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR,
-		  "enter: msglen: 0x%x msgin: 0x%x msgtype: 0x%x",
-		  data->msginlen, msg, msgtype);
-
-	/*
-	 * TODO: We need checking whether bus phase is message in?
-	 */
-
-	/*
-	 * assert SCSI ACK
-	 */
-	nsp32_sack_assert(data);
-
-	/*
-	 * processing IDENTIFY
-	 */
-	if (msgtype & 0x80) {
-		if (!(irq_status & IRQSTATUS_RESELECT_OCCUER)) {
-			/* Invalid (non reselect) phase */
-			goto reject;
-		}
-
-		newlun = msgtype & 0x1f; /* TODO: SPI-3 compliant? */
-		ret = nsp32_reselection(data, newlun);
-		if (ret == TRUE) {
-			goto restart;
-		} else {
-			goto reject;
-		}
+	if (!((state == ASSERT) || (state == NEGATE))) {
+		nsp32_msg(KERN_ERR, "unknown state designation");
 	}
-	
-	/*
-	 * processing messages except for IDENTIFY
-	 *
-	 * TODO: Messages are all SCSI-2 terminology. SCSI-3 compliance is TODO.
-	 */
-	switch (msgtype) {
-	/*
-	 * 1-byte message
-	 */
-	case COMMAND_COMPLETE:
-	case DISCONNECT:
-		/*
-		 * These messages should not be occured.
-		 * They should be processed on AutoSCSI sequencer.
-		 */
-		nsp32_msg(KERN_WARNING, 
-			   "unexpected message of AutoSCSI MsgIn: 0x%x", msg);
-		break;
-		
-	case RESTORE_POINTERS:
-		/*
-		 * AutoMsgIn03 is disabled, and HBA gets this message.
-		 */
+	/* ACK is BIT(4) */
+	ack_bit = (state == ASSERT ? BUSMON_ACK : 0);
 
-		if ((execph & DATA_IN_PHASE) || (execph & DATA_OUT_PHASE)) {
-			unsigned int s_sacklen;
-
-			s_sacklen = nsp32_read4(base, SAVED_SACK_CNT);
-			if ((execph & MSGIN_02_VALID) && (s_sacklen > 0)) {
-				nsp32_adjust_busfree(data, s_sacklen);
-			} else {
-				/* No need to rewrite SGT */
-			}
+	do {
+		bus = nsp32_read1(base, SCSI_BUS_MONITOR);
+		if ((bus & BUSMON_ACK) == ack_bit) {
+			nsp32_dbg(NSP32_DEBUG_WAIT,
+				  "wait_time: %d", wait_time);
+			return;
 		}
-		data->curlunt->msgin03 = FALSE;
+		udelay(1);
+		wait_time++;
+	} while (wait_time < REQSACK_TIMEOUT_TIME);
 
-		/* Update with the new value */
+	nsp32_msg(KERN_WARNING, "wait SACK timeout, ack_bit: 0x%x", ack_bit);
+}
 
-		/* reset SACK/SavedACK counter (or ALL clear?) */
-		nsp32_write4(base, CLR_COUNTER, CLRCOUNTER_ALLMASK);
+/*
+ * assert SCSI ACK
+ *
+ * Note: SCSI ACK assertion needs with ACKENB=1, AUTODIRECTION=1.
+ */
+static void nsp32_sack_assert(nsp32_hw_data *data)
+{
+	unsigned int  base = data->BaseAddress;
+	unsigned char busctrl;
 
-		/*
-		 * set new sg pointer
-		 */
-		new_sgtp = data->curlunt->sglun_paddr + 
-			data->curlunt->cur_entry * sizeof(struct nsp32_sgtable);
-		nsp32_write4(base, SGT_ADR, new_sgtp);
+	busctrl  = nsp32_read1(base, SCSI_BUS_CONTROL);
+	busctrl	|= (BUSCTL_ACK | AUTODIRECTION | ACKENB);
+	nsp32_write1(base, SCSI_BUS_CONTROL, busctrl);
+}
 
-		break;
+/*
+ * negate SCSI ACK
+ */
+static void nsp32_sack_negate(nsp32_hw_data *data)
+{
+	unsigned int  base = data->BaseAddress;
+	unsigned char busctrl;
 
-	case SAVE_POINTERS:
-		/*
-		 * These messages should not be occured.
-		 * They should be processed on AutoSCSI sequencer.
-		 */
-		nsp32_msg (KERN_WARNING, 
-			   "unexpected message of AutoSCSI MsgIn: SAVE_POINTERS");
-		
-		break;
-		
-	case MESSAGE_REJECT:
-		/* If previous message_out is sending SDTR, and get 
-		   message_reject from target, SDTR negotiation is failed */
-		if (data->curtarget->sync_flag &
-				(SDTR_INITIATOR | SDTR_TARGET)) {
-			/*
-			 * Current target is negotiating SDTR, but it's
-			 * failed.  Fall back to async transfer mode, and set
-			 * SDTR_DONE.
-			 */
-			nsp32_set_async(data, data->curtarget);
-			data->curtarget->sync_flag &= ~SDTR_INITIATOR;
-			data->curtarget->sync_flag |= SDTR_DONE;
+	busctrl  = nsp32_read1(base, SCSI_BUS_CONTROL);
+	busctrl	&= ~BUSCTL_ACK;
+	nsp32_write1(base, SCSI_BUS_CONTROL, busctrl);
+}
 
-		}
-		break;
 
-	case LINKED_CMD_COMPLETE:
-	case LINKED_FLG_CMD_COMPLETE:
-		/* queue tag is not supported currently */
-		nsp32_msg (KERN_WARNING, 
-			   "unsupported message: 0x%x", msgtype);
-		break;
 
-	case INITIATE_RECOVERY:
-		/* staring ECA (Extended Contingent Allegiance) state. */
-		/* This message is declined in SPI2 or later. */
+/*
+ * Note: n_io_port is defined as 0x7f because I/O register port is
+ *	 assigned as:
+ *	0x800-0x8ff: memory mapped I/O port
+ *	0x900-0xbff: (map same 0x800-0x8ff I/O port image repeatedly)
+ *	0xc00-0xfff: CardBus status registers
+ */
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+#define DETECT_OK 0
+#define DETECT_NG 1
+#define PCIDEV    pdev
+static int nsp32_detect(struct pci_dev *pdev)
+#else
+#define DETECT_OK 1
+#define DETECT_NG 0
+#define PCIDEV    (data->Pci)
+static int nsp32_detect(Scsi_Host_Template *sht)
+#endif
+{
+	struct Scsi_Host *host;	/* registered host structure */
+	struct resource  *res;
+	nsp32_hw_data    *data;
+	int               ret;
+	int               n_target, n_lun, i;
 
-		goto reject;
+	nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
 
 	/*
-	 * 2-byte message
+	 * register this HBA as SCSI device
 	 */
-	case SIMPLE_QUEUE_TAG:
-	case 0x23:
-		/*
-		 * 0x23: Ignore_Wide_Residue is not declared in scsi.h.
-		 * No support is needed.
-		 */
-		if (data->msginlen >= 1) {
-			goto reject;
-		}
-
-		/* current position is 1-byte of 2 byte */
-		msgclear = FALSE;
-
-		break;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	host = scsi_host_alloc(&nsp32_template, sizeof(nsp32_hw_data));
+#else
+	host = scsi_register(sht, sizeof(nsp32_hw_data));
+#endif
+	if (host == NULL) {
+		nsp32_msg (KERN_ERR, "failed to scsi register");
+		goto err;
+	}
 
 	/*
-	 * extended message
+	 * set nsp32_hw_data
 	 */
-	case EXTENDED_MESSAGE:
-		if (data->msginlen < 1) {
-			/*
-			 * Current position does not reach 2-byte
-			 * (2-byte is extended message length).
-			 */
-			msgclear = FALSE;
-			break;
-		}
-
-		if ((data->msginbuf[1] + 1) > data->msginlen) {
-			/*
-			 * Current extended message has msginbuf[1] + 2
-			 * (msginlen starts counting from 0, so buf[1] + 1).
-			 * If current message position is not finished,
-			 * continue receiving message.
-			 */
-			msgclear = FALSE;
-			break;
-		}
-
-		/*
-		 * Reach here means regular length of each type of 
-		 * extended messages.
-		 */
-		switch (data->msginbuf[2]) {
-		case EXTENDED_MODIFY_DATA_POINTER:
-			/* TODO */
-			goto reject; /* not implemented yet */
-			break;
-
-		case EXTENDED_SDTR:
-			/*
-			 * Exchange this message between initiator and target.
-			 */
-			if (data->msginlen != EXTENDED_SDTR_LEN + 1) {
-				/*
-				 * received inappropriate message.
-				 */
-				goto reject;
-				break;
-			}
-
-			nsp32_analyze_sdtr(data);
-
-			break;
-
-		case EXTENDED_EXTENDED_IDENTIFY:
-			/* SCSI-I only, not supported. */
-			goto reject; /* not implemented yet */
-
-			break;
-
-		case EXTENDED_WDTR:
-			goto reject; /* not implemented yet */
-
-			break;
-			
-		default:
-			goto reject;
-		}
-		break;
-		
-	default:
-		goto reject;
-	}
-
- restart:
-	if (msgclear == TRUE) {
-		data->msginlen = 0;
-
-		/*
-		 * If restarting AutoSCSI, but there are some message to out
-		 * (msgoutlen > 0), set AutoATN, and set SCSIMSGOUT as 0
-		 * (MV_VALID = 0). When commandcontrol is written with
-		 * AutoSCSI restart, at the same time MsgOutOccur should be
-		 * happened (however, such situation is really possible...?).
-		 */
-		if (data->msgoutlen > 0) {	
-			nsp32_write4(base, SCSI_MSG_OUT, 0);
-			command |= AUTO_ATN;
-		}
+	data = (nsp32_hw_data *)host->hostdata;
 
-		/*
-		 * restart AutoSCSI
-		 * If it's failed, COMMANDCONTROL_AUTO_COMMAND_PHASE is needed.
-		 */
-		command |= (AUTO_MSGIN_00_OR_04 | AUTO_MSGIN_02);
+	*data = nsp32_data_base;
 
-		/*
-		 * If current msgin03 is TRUE, then flag on.
-		 */
-		if (data->curlunt->msgin03 == TRUE) {
-			command |= AUTO_MSGIN_03;
-		}
-		data->curlunt->msgin03 = FALSE;
-	} else {
-		data->msginlen++;
-	}
+	host->irq       = data->IrqNumber;
+	host->io_port   = data->BaseAddress;
+	host->unique_id = data->BaseAddress;
+	host->n_io_port	= data->NumAddress;
+	host->base      = data->MmioAddress;
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,63))
+	scsi_set_device(host, &PCIDEV->dev);
+#else
+	scsi_set_pci_device(host, PCIDEV);
+#endif
+
+	data->Host      = host;
+	spin_lock_init(&(data->Lock));
+
+	data->cur_lunt   = NULL;
+	data->cur_target = NULL;
 
 	/*
-	 * restart AutoSCSI
+	 * Bus master transfer mode is supported currently.
 	 */
-	nsp32_restart_autoscsi(data, command);
+	data->trans_method = NSP32_TRANSFER_BUSMASTER;
 
 	/*
-	 * wait SCSI REQ negate for REQ-ACK handshake
+	 * Set clock div, CLOCK_4 (HBA has own external clock, and
+	 * dividing * 100ns/4).
+	 * Currently CLOCK_4 has only tested, not for CLOCK_2/PCICLK yet.
 	 */
-	nsp32_wait_req(data, NEGATE);
+	data->clock = CLOCK_4;
 
 	/*
-	 * negate SCSI ACK
+	 * Select appropriate nsp32_sync_table and set I_CLOCKDIV.
 	 */
-	nsp32_sack_negate(data);
-
-	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit");
+	switch (data->clock) {
+	case CLOCK_4:
+		/* If data->clock is CLOCK_4, then select 40M sync table. */
+		data->synct   = nsp32_sync_table_40M;
+		data->syncnum = NUMBER(nsp32_sync_table_40M);
+		break;
+	case CLOCK_2:
+		/* If data->clock is CLOCK_2, then select 20M sync table. */
+		data->synct   = nsp32_sync_table_20M;
+		data->syncnum = NUMBER(nsp32_sync_table_20M);
+		break;
+	case PCICLK:
+		/* If data->clock is PCICLK, then select pci sync table. */
+		data->synct   = nsp32_sync_table_pci;
+		data->syncnum = NUMBER(nsp32_sync_table_pci);
+		break;
+	default:
+		nsp32_msg(KERN_WARNING,
+			  "Invalid clock div is selected, set CLOCK_4.");
+		/* Use default value CLOCK_4 */
+		data->clock   = CLOCK_4;
+		data->synct   = nsp32_sync_table_40M;
+		data->syncnum = NUMBER(nsp32_sync_table_40M);
+	}
 
-	return;
+	/*
+	 * setup nsp32_lunt
+	 */
 
- reject:
-	nsp32_msg(KERN_WARNING, 
-		  "invalid or unsupported MessageIn, rejected. "
-		  "current msg: 0x%x (len: 0x%x), processing msg: 0x%x",
-		  msg, data->msginlen, msgtype);
-	nsp32_build_reject(data);
-	data->msginlen = 0;
+	/*
+	 * setup DMA 
+	 */
+	if (pci_set_dma_mask(PCIDEV, 0xffffffffUL) != 0) {
+		nsp32_msg (KERN_ERR, "failed to set PCI DMA mask");
+		goto scsi_unregister;
+	}
 
-	goto restart;
-}
+	/*
+	 * allocate autoparam DMA resource.
+	 */
+	data->autoparam = pci_alloc_consistent(PCIDEV, sizeof(nsp32_autoparam), &(data->auto_paddr));
+	if (data->autoparam == NULL) {
+		nsp32_msg(KERN_ERR, "failed to allocate DMA memory");
+		goto scsi_unregister;
+	}
 
-/*
- * 
- */
-static void nsp32_analyze_sdtr(nsp32_hw_data *data)
-{
-	struct nsp32_target *target = data->curtarget;
-	struct nsp32_sync_table *synct;
-	unsigned char get_period = data->msginbuf[3];
-	unsigned char get_offset = data->msginbuf[4];
-	int entry;
-	int syncnum;
+	/*
+	 * allocate scatter-gather DMA resource.
+	 */
+	data->sg_list = pci_alloc_consistent(PCIDEV, NSP32_SG_TABLE_SIZE,
+					     &(data->sg_paddr));
+	if (data->sg_list == NULL) {
+		nsp32_msg(KERN_ERR, "failed to allocate DMA memory");
+		goto free_autoparam;
+	}
 
-	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "enter");
+	for (n_target = 0; n_target < NUMBER(data->lunt); n_target++) {
+		for (n_lun = 0; n_lun < NUMBER(data->lunt[0]); n_lun++) {
+			int offset = n_target * NUMBER(data->lunt[0]) + n_lun;
+			nsp32_lunt tmp = {
+				SCpnt:       NULL,
+				save_datp:   0,
+				msgin03:     FALSE,
+				sg_num:      0,
+				cur_entry:   0,
+				sglun:       &(data->sg_list[offset]),
+				sglun_paddr: data->sg_paddr + ARRAY_OFFSET(nsp32_sglun, offset),
+			};
 
-	synct = data->synct;
-	syncnum = data->syncnum;
+			data->lunt[n_target][n_lun] = tmp;
+		}
+	}
 
 	/*
-	 * If this inititor sent the SDTR message, then target responds SDTR,
-	 * initiator SYNCREG, ACKWIDTH from SDTR parameter.
-	 * Messages are not appropriate, then send back reject message.
-	 * If initiator did not send the SDTR, but target sends SDTR, 
-	 * initiator calculator the appropriate parameter and send back SDTR.
-	 */	
-	if (target->sync_flag & SDTR_INITIATOR) {
-		/*
-		 * Initiator sent SDTR, the target responds and
-		 * send back negotiation SDTR.
-		 */
-		nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target responds SDTR");
-	
-		target->sync_flag &= ~SDTR_INITIATOR;
-		target->sync_flag |= SDTR_DONE;
+	 * setup target
+	 */
+	for (i = 0; i < NUMBER(data->target); i++) {
+		nsp32_target *target = &(data->target[i]);
 
-		/*
-		 * offset:
-		 */
-		if (get_offset > SYNC_OFFSET) {
-			/*
-			 * Negotiation is failed, the target send back
-			 * unexpected offset value.
-			 */
-			goto reject;
-		}
-		
-		if (get_offset == ASYNC_OFFSET) {
-			/*
-			 * Negotiation is succeeded, the target want
-			 * to fall back into asynchronous transfer mode.
-			 */
-			goto async;
-		}
+		target->limit_entry  = 0;
+		target->sync_flag    = SDTR_NONE;
+		nsp32_set_async(data, target);
+	}
 
-		/*
-		 * period:
-		 *    Check whether sync period is too short. If too short,
-		 *    fall back to async mode. If it's ok, then investigate
-		 *    the received sync period. If sync period is acceptable
-		 *    between sync table start_period and end_period, then
-		 *    set this I_T nexus as sent offset and period.
-		 *    If it's not acceptable, send back reject and fall back
-		 *    to async mode.
-		 */
-		if (get_period < data->synct[0].period_num) {
-			/*
-			 * Negotiation is failed, the target send back
-			 * unexpected period value.
-			 */
-			goto reject;
-		}
+	/*
+	 * EEPROM check
+	 */
+	ret = nsp32_getprom_param(data);
+	if (ret == FALSE) {
+		data->resettime = 3;	/* default 3 */
+	}
 
-		entry = nsp32_search_period_entry(data, target, get_period);
+	/*
+	 * setup HBA
+	 */
+	nsp32hw_init(data);
 
-		if (entry < 0) {
-			/*
-			 * Target want to use long period which is not 
-			 * acceptable NinjaSCSI-32Bi/UDE.
-			 */
-			goto reject;
-		}
+	snprintf(data->info_str, sizeof(data->info_str),
+		 "NinjaSCSI-32Bi/UDE: irq %d, io 0x%lx+0x%x",
+		 host->irq, host->io_port, host->n_io_port);
 
-		/*
-		 * Set new sync table and offset in this I_T nexus.
-		 */
-		nsp32_set_sync_entry(data, target, entry, get_offset);
-	} else {
-		/* Target send SDTR to initiator. */
-		nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "target send SDTR");
-	
-		target->sync_flag |= SDTR_INITIATOR;
+	/*
+	 * SCSI bus reset
+	 *
+	 * Note: It's important to reset SCSI bus in initialization phase.
+	 *     NinjaSCSI-32Bi/UDE HBA EEPROM seems to exchange SDTR when
+	 *     system is coming up, so SCSI devices connected to HBA is set as
+	 *     un-asynchronous mode.  It brings the merit that this HBA is
+	 *     ready to start synchronous transfer without any preparation,
+	 *     but we are difficult to control transfer speed.  In addition,
+	 *     it prevents device transfer speed from effecting EEPROM start-up
+	 *     SDTR.  NinjaSCSI-32Bi/UDE has the feature if EEPROM is set as
+	 *     Auto Mode, then FAST-10M is selected when SCSI devices are
+	 *     connected same or more than 4 devices.  It should be avoided
+	 *     depending on this specification. Thus, resetting the SCSI bus
+	 *     restores all connected SCSI devices to asynchronous mode, then
+	 *     this driver set SDTR safely later, and we can control all SCSI
+	 *     device transfer mode.
+	 */
+	nsp32_do_bus_reset(data);
 
-		/* offset: */
-		if (get_offset > SYNC_OFFSET) {
-			/* send back as SYNC_OFFSET */
-			get_offset = SYNC_OFFSET;
-		}
+	ret = request_irq(host->irq, do_nsp32_isr,
+			  SA_SHIRQ | SA_SAMPLE_RANDOM, "nsp32", data);
+	if (ret < 0) {
+		nsp32_msg(KERN_ERR, "Unable to allocate IRQ for NinjaSCSI32 "
+			  "SCSI PCI controller. Interrupt: %d", host->irq);
+		goto free_sg_list;
+	}
 
-		/* period: */
-		if (get_period < data->synct[0].period_num) {
-			get_period = data->synct[0].period_num;
-		}
+        /*
+         * PCI IO register
+         */
+	res = request_region(host->io_port, host->n_io_port, "nsp32");
+	if (res == NULL) {
+		nsp32_msg(KERN_ERR, 
+			  "I/O region 0x%lx+0x%lx is already used",
+			  data->BaseAddress, data->NumAddress);
+		goto free_irq;
+        }
 
-		entry = nsp32_search_period_entry(data, target, get_period);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	scsi_add_host (host, &PCIDEV->dev);
+	scsi_scan_host(host);
+#endif
+	pci_set_drvdata(PCIDEV, host);
+	return DETECT_OK;
 
-		if (get_offset == ASYNC_OFFSET || entry < 0) {
-			nsp32_set_async(data, target);
-			nsp32_build_sdtr(data, 0, ASYNC_OFFSET);
-		} else {
-			nsp32_set_sync_entry(data, target, entry, get_offset);
-			nsp32_build_sdtr(data, get_period, get_offset);
-		}
-	}
-	
-	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit");
-	return;
+ free_irq:
+	free_irq(host->irq, data);
 
- reject:
-	/*
-	 * If the current message is unacceptable, send back to the target
-	 * with reject message.
-	 */
-	nsp32_build_reject(data);
+ free_sg_list:
+	pci_free_consistent(PCIDEV, NSP32_SG_TABLE_SIZE,
+			    data->sg_list, data->sg_paddr);
 
- async:
-	nsp32_set_async(data, target);	/* set as ASYNC transfer mode */
+ free_autoparam:
+	pci_free_consistent(PCIDEV, sizeof(nsp32_autoparam),
+			    data->autoparam, data->auto_paddr);
+	
+ scsi_unregister:
+	scsi_host_put(host);
 
-	nsp32_dbg(NSP32_DEBUG_MSGINOCCUR, "exit: set async");
-	return;
+ err:
+	return DETECT_NG;
 }
+#undef DETECT_OK
+#undef DETECT_NG
+#undef PCIDEV
 
-
-/*
- * Search config entry number matched in sync_table from given
- * target and speed period value. If failed to search, return negative value.
- */
-static int nsp32_search_period_entry(nsp32_hw_data *data,
-			      struct nsp32_target *target,
-			      unsigned char period)
+static int nsp32_release(struct Scsi_Host *host)
 {
-	int i;
+	nsp32_hw_data *data = (nsp32_hw_data *)host->hostdata;
 
-	if (target->limit_entry >= data->syncnum) {
-		nsp32_msg(KERN_ERR, "limit_entry exceeds syncnum!");
-		target->limit_entry = 0;
+	if (data->autoparam) {
+		pci_free_consistent(data->Pci, sizeof(nsp32_autoparam),
+				    data->autoparam, data->auto_paddr);
 	}
 
-	for (i=target->limit_entry; i<data->syncnum; i++) {
-		if (period >= data->synct[i].start_period &&
-		    period <= data->synct[i].end_period) {
-				break;
-		}
+	if (data->sg_list) {
+		pci_free_consistent(data->Pci, NSP32_SG_TABLE_SIZE,
+				    data->sg_list, data->sg_paddr);
 	}
 
-	/*
-	 * Check given period value is over the sync_table value.
-	 * If so, return max value.
-	 */
-	if (i == data->syncnum) {
-		i = -1;
+	if (host->irq) {
+		free_irq(host->irq, data);
 	}
 
-	return i;
-}
-
-
-/*
- * target <-> initiator use ASYNC transfer
- */
-static void nsp32_set_async(nsp32_hw_data *data, struct nsp32_target *target)
-{
-	unsigned char period = data->synct[target->limit_entry].period_num;
+	if (host->io_port && host->n_io_port) {
+		release_region(host->io_port, host->n_io_port);
+	}
 
-	target->offset   = ASYNC_OFFSET;
-	target->syncreg  = TO_SYNCREG(period, ASYNC_OFFSET);
-	target->ackwidth = 0;
+	if (data->MmioAddress != 0) {
+		iounmap((void *)(data->MmioAddress));
+	}
 
-	nsp32_dbg(NSP32_DEBUG_SYNC, "set async");
+	return 0;
 }
 
+static const char *nsp32_info(struct Scsi_Host *shpnt)
+{
+	nsp32_hw_data *data = (nsp32_hw_data *)shpnt->hostdata;
 
-/*
- * target <-> initiator use maximum SYNC transfer
- */
-static void nsp32_set_max_sync(nsp32_hw_data *data,
-			       struct nsp32_target *target,
-			       unsigned char *period, unsigned char *offset)
-{
-	unsigned char period_num, ackwidth;
-
-	period_num = data->synct[target->limit_entry].period_num;
-	*period    = data->synct[target->limit_entry].start_period;
-	ackwidth   = data->synct[target->limit_entry].ackwidth;
-	*offset    = SYNC_OFFSET;
-
-	target->syncreg  = TO_SYNCREG(period_num, *offset);
-	target->ackwidth = ackwidth;
-	target->offset   = *offset;
+	return data->info_str;
 }
 
 
-/*
- * target <-> initiator use entry number speed
+/****************************************************************************
+ * error handler
  */
-static void nsp32_set_sync_entry(nsp32_hw_data *data,
-				 struct nsp32_target *target,
-				 int entry, unsigned char offset)
+static int nsp32_eh_abort(Scsi_Cmnd *SCpnt)
 {
-	unsigned char period, ackwidth;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int   base = SCpnt->device->host->io_port;
 
-	period   = data->synct[entry].period_num;
-	ackwidth = data->synct[entry].ackwidth;
-	offset  = offset;
-
-	target->syncreg  = TO_SYNCREG(period, offset);
-	target->ackwidth = ackwidth;
-	target->offset   = offset;
+	nsp32_msg(KERN_WARNING, "abort");
 
-	nsp32_dbg(NSP32_DEBUG_SYNC, "set sync");
-}
+	if (data->cur_lunt->SCpnt == NULL) {
+		nsp32_dbg(NSP32_DEBUG_BUSRESET, "abort failed");
+		return FAILED;
+	}
 
+	if (data->cur_target->sync_flag & (SDTR_INITIATOR | SDTR_TARGET)) {
+		/* reset SDTR negotiation */
+		data->cur_target->sync_flag = SDTR_NONE;
+		nsp32_set_async(data, data->cur_target);
+	}
 
-/*
- * It waits until SCSI REQ becomes assertion or negation state.
- *
- * Note: If nsp32_msgin_occur is called, we asserts SCSI ACK. Then
- *     connected target responds SCSI REQ negation.  We have to wait
- *     SCSI REQ becomes negation in order to negate SCSI ACK signal for
- *     REQ-ACK handshake.
- */
-static void nsp32_wait_req(nsp32_hw_data *data, int state)
+	nsp32_write2(base, TRANSFER_CONTROL, 0);
+	nsp32_write2(base, BM_CNT,           0);
+
+	SCpnt->result = DID_ABORT << 16;
+	nsp32_scsi_done(SCpnt);
+
+	nsp32_dbg(NSP32_DEBUG_BUSRESET, "abort success");
+	return SUCCESS;
+}
+
+static int nsp32_eh_bus_reset(Scsi_Cmnd *SCpnt)
 {
-	unsigned int base = data->BaseAddress;
-	int wait_time = 0;
-	unsigned char bus;
+	nsp32_hw_data *data = (nsp32_hw_data *)SCpnt->device->host->hostdata;
+	unsigned int   base = SCpnt->device->host->io_port;
 
-	if (!((state == ASSERT) || (state == NEGATE))) {
-		nsp32_msg(KERN_ERR, "unknown state designation");
-	}
-	state <<= 5; /* REQ is BIT(5) */
+	nsp32_msg(KERN_INFO, "Bus Reset");	
+	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
 
-	do {
-		bus = nsp32_read1(base, SCSI_BUS_MONITOR);
-		if ((bus & BUSMON_REQ) == state) {
-			nsp32_dbg(NSP32_DEBUG_WAIT, 
-				  "wait_time: %d", wait_time);
-			return;
-		}
-		udelay(1);
-		wait_time++;
-	} while (wait_time < REQSACK_TIMEOUT_TIME);
+	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
+	nsp32_do_bus_reset(data);
+	nsp32_write2(base, IRQ_CONTROL, 0);
 
-	nsp32_msg(KERN_WARNING, "wait REQ timeout, state: %d", state);
+	return SUCCESS;	/* SCSI bus reset is succeeded at any time. */
 }
 
-/*
- * It waits until SCSI SACK becomes assertion or negation state.
- */
-static void nsp32_wait_sack(nsp32_hw_data *data, int state)
+static void nsp32_do_bus_reset(nsp32_hw_data *data)
 {
-	unsigned int base = data->BaseAddress;
-	int wait_time = 0;
-	unsigned char bus;
+	unsigned int   base = data->BaseAddress;
+	unsigned short intrdat;
+	int i;
 
-	if (!((state == ASSERT) || (state == NEGATE))) {
-		nsp32_msg(KERN_ERR, "unknown state designation");
+	nsp32_dbg(NSP32_DEBUG_BUSRESET, "in");
+
+	/*
+	 * stop all transfer
+	 * clear TRANSFERCONTROL_BM_START
+	 * clear counter
+	 */
+	nsp32_write2(base, TRANSFER_CONTROL, 0);
+	nsp32_write4(base, BM_CNT,           0);
+	nsp32_write4(base, CLR_COUNTER,      CLRCOUNTER_ALLMASK);
+
+	/*
+	 * fall back to asynchronous transfer mode
+	 * initialize SDTR negotiation flag
+	 */
+	for (i = 0; i < NUMBER(data->target); i++) {
+		nsp32_target *target = &data->target[i];
+
+		target->sync_flag = SDTR_NONE;
+		nsp32_set_async(data, target);
 	}
-	state <<= 4; /* ACK is BIT(4) */
 
-	do {
-		bus = nsp32_read1(base, SCSI_BUS_MONITOR);
-		if ((bus & BUSMON_ACK) == state) {
-			nsp32_dbg(NSP32_DEBUG_WAIT,
-				  "wait_time: %d", wait_time);
-			return;
-		}
-		udelay(1);
-		wait_time++;
-	} while (wait_time < REQSACK_TIMEOUT_TIME);
+	/*
+	 * reset SCSI bus
+	 */
+	nsp32_write1(base, SCSI_BUS_CONTROL, BUSCTL_RST);
+	udelay(RESET_HOLD_TIME);
+	nsp32_write1(base, SCSI_BUS_CONTROL, 0);
+	for(i = 0; i < 5; i++) {
+		intrdat = nsp32_read2(base, IRQ_STATUS); /* dummy read */
+		nsp32_dbg(NSP32_DEBUG_BUSRESET, "irq:1: 0x%x", intrdat);
+        }
 
-	nsp32_msg(KERN_WARNING, "wait SACK timeout, state: %d", state);
+	data->CurrentSC = NULL;
 }
 
-/*
- * assert SCSI ACK
- *
- * Note: SCSI ACK assertion needs with ACKENB=1, AUTODIRECTION=1.
- */
-static void nsp32_sack_assert(nsp32_hw_data *data)
+static int nsp32_eh_host_reset(Scsi_Cmnd *SCpnt)
 {
-	unsigned char busctrl;
-	unsigned int base = data->BaseAddress;
+	struct Scsi_Host *host = SCpnt->device->host;
+	unsigned int      base = SCpnt->device->host->io_port;
+	nsp32_hw_data    *data = (nsp32_hw_data *)host->hostdata;
 
-	busctrl  = nsp32_read1(base, SCSI_BUS_CONTROL);
-	busctrl	|= (BUSCTL_ACK | AUTODIRECTION | ACKENB);
-	nsp32_write1(base, SCSI_BUS_CONTROL,busctrl);
-}
+	nsp32_msg(KERN_INFO, "Host Reset");	
+	nsp32_dbg(NSP32_DEBUG_BUSRESET, "SCpnt=0x%x", SCpnt);
 
-/*
- * negate SCSI ACK
- */
-static void nsp32_sack_negate(nsp32_hw_data *data)
-{
-	unsigned char busctrl;
-	unsigned int base = data->BaseAddress;
+	nsp32hw_init(data);
+	nsp32_write2(base, IRQ_CONTROL, IRQ_CONTROL_ALL_IRQ_MASK);
+	nsp32_do_bus_reset(data);
+	nsp32_write2(base, IRQ_CONTROL, 0);
 
-	busctrl  = nsp32_read1(base, SCSI_BUS_CONTROL);
-	busctrl	&= ~BUSCTL_ACK;
-	nsp32_write1(base, SCSI_BUS_CONTROL, busctrl);
+	return SUCCESS;	/* Host reset is succeeded at any time. */
 }
 
 
+/**************************************************************************
+ * EEPROM handler
+ */
 
 /*
  * getting EEPROM parameter
@@ -3165,7 +3083,12 @@
 {
 	int vendor = data->pci_devid->vendor;
 	int device = data->pci_devid->device;
-	int ret, val, i;
+	int ret;
+#ifdef NSP32_DEBUG
+	int i;
+#define NSP32_DEBUG_PROM_BUF_SIZE 0x20
+	unsigned char buf[NSP32_DEBUG_PROM_BUF_SIZE];
+#endif
 
 	/*
 	 * EEPROM checking.
@@ -3173,12 +3096,12 @@
 	ret = nsp32_prom_read(data, 0x7e);
 	if (ret != 0x55) {
 		nsp32_msg(KERN_INFO, "No EEPROM detected: 0x%x", ret);
-		return (FALSE);
+		return FALSE;
 	}
 	ret = nsp32_prom_read(data, 0x7f);
 	if (ret != 0xaa) {
 		nsp32_msg(KERN_INFO, "Invalid number: 0x%x", ret);
-		return (FALSE);
+		return FALSE;
 	}
 
 	/*
@@ -3186,27 +3109,30 @@
 	 */
 	if (vendor == PCI_VENDOR_ID_WORKBIT &&
 	    device == PCI_DEVICE_ID_WORKBIT_STANDARD) {
-		ret = nsp32_getprom_standard(data);
+		ret = nsp32_getprom_c16(data);
 	} else if (vendor == PCI_VENDOR_ID_WORKBIT &&
 		   device == PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC) {
-		ret = nsp32_getprom_new(data);
+		ret = nsp32_getprom_at24(data);
 	} else if (vendor == PCI_VENDOR_ID_WORKBIT &&
 		   device == PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO ) {
-		ret = nsp32_getprom_new(data);
+		ret = nsp32_getprom_at24(data);
 	} else {
 		nsp32_msg(KERN_WARNING, "Unknown EEPROM");
 		ret = FALSE;
 	}
 
+#ifdef NSP32_DEBUG
 	/* for debug : SPROM data full checking */
-	for (i=0; i<=0x1f; i++) {
-		val = nsp32_prom_read(data, i);
-		nsp32_dbg(NSP32_DEBUG_EEPROM,
-			  "rom address 0x%x : 0x%x", i, val);
+	nsp32_dbg(NSP32_DEBUG_EEPROM, "rom dump");
+	for (i = 0; i < sizeof(buf); i++) {
+		buf[i] = nsp32_prom_read(data, i);
 	}
+	nsp32_byte_dump(buf, 0, sizeof(buf));
+#endif
 
-	return (ret);
+	return ret;
 }
+#undef NSP32_DEBUG_PROM_BUF_SIZE
 
 
 /*
@@ -3233,15 +3159,15 @@
  *   0x1c        :  Constant? (0x01) (clock div?)
  *   0x1d - 0x7c :  Not Used (0xff)
  *   0x7d	 :  Not Used? (0xff)
- *   0x7e        :  Constant (0x55), HBA chip revision
- *   0x7f        :  Constant (0xaa), HBA value
+ *   0x7e        :  Constant (0x55), Validity signature
+ *   0x7f        :  Constant (0xaa), Validity signature
  */
-static int nsp32_getprom_new(nsp32_hw_data *data)
+static int nsp32_getprom_at24(nsp32_hw_data *data)
 {
-	int ret, i;
-	int auto_sync;
-	struct nsp32_target *target;
-	int entry;
+	int           ret, i;
+	int           auto_sync;
+	nsp32_target *target;
+	int           entry;
 
 	/*
 	 * Reset time which is designated by EEPROM.
@@ -3273,8 +3199,7 @@
 		break;
 	default:
 		nsp32_msg(KERN_WARNING,
-			  "Unsupported Auto Sync mode."
-			  "Fall back to manual mode.");
+			  "Unsupported Auto Sync mode. Fall back to manual mode.");
 		auto_sync = TRUE;
 	}
 
@@ -3285,12 +3210,12 @@
 	/*
 	 * each device Synchronous Transfer Period
 	 */
-	for (i=0; i<NSP32_HOST_SCSIID; i++) {
+	for (i = 0; i < NSP32_HOST_SCSIID; i++) {
 		target = &data->target[i];
 		if (auto_sync == TRUE) {
 			target->limit_entry = 0;   /* set as ULTRA20M */
 		} else {
-			ret = nsp32_prom_read(data, i);
+			ret   = nsp32_prom_read(data, i);
 			entry = nsp32_search_period_entry(data, target, ret);
 			if (entry < 0) {
 				/* search failed... set maximum speed */
@@ -3300,12 +3225,12 @@
 		}
 	}
 
-	return (TRUE);
+	return TRUE;
 }
 
 
 /*
- * ? (I-O Data: SC-NBD) data map:
+ * C16 110 (I-O Data: SC-NBD) data map:
  *
  *   ROMADDR
  *   0x00 - 0x06 :  Device Synchronous Transfer Period (SCSI ID 0 - 6) 
@@ -3321,14 +3246,14 @@
  *			Value 0: Disable, 1: Enable
  *   0x1a - 0x7c :  Not Used? (0)
  *   0x7d	 :  Not Used? (0xf8)
- *   0x7e        :  Constant (0x55), HBA chip revision
- *   0x7f        :  Constant (0xaa), HBA value
+ *   0x7e        :  Constant (0x55), Validity signature
+ *   0x7f        :  Constant (0xaa), Validity signature
  */
-static int nsp32_getprom_standard(nsp32_hw_data *data)
+static int nsp32_getprom_c16(nsp32_hw_data *data)
 {
-	int ret, i;
-	struct nsp32_target *target;
-	int entry, val;
+	int           ret, i;
+	nsp32_target *target;
+	int           entry, val;
 
 	/*
 	 * Reset time which is designated by EEPROM.
@@ -3340,7 +3265,7 @@
 	/*
 	 * each device Synchronous Transfer Period
 	 */
-	for (i=0; i<NSP32_HOST_SCSIID; i++) {
+	for (i = 0; i < NSP32_HOST_SCSIID; i++) {
 		target = &data->target[i];
 		ret = nsp32_prom_read(data, i);
 		switch (ret) {
@@ -3354,10 +3279,11 @@
 			val = 0x32;
 			break;
 		case 3:		/* ASYNC */
-			val = 0x0;
+			val = 0x00;
 			break;
 		default:	/* default 20MB/s */
 			val = 0x0c;
+			break;
 		}
 		entry = nsp32_search_period_entry(data, target, val);
 		if (entry < 0 || trans_mode == ULTRA20M_MODE) {
@@ -3367,7 +3293,7 @@
 		target->limit_entry = entry;
 	}
 
-	return (TRUE);
+	return TRUE;
 }
 
 
@@ -3382,145 +3308,314 @@
 	nsp32_prom_start(data);
 
 	/* device address */
-	nsp32_prom_write(data, 1);	/* 1 */
-	nsp32_prom_write(data, 0);	/* 0 */
-	nsp32_prom_write(data, 1);	/* 1 */
-	nsp32_prom_write(data, 0);	/* 0 */
-	nsp32_prom_write(data, 0);	/* A2: 0 (GND) */
-	nsp32_prom_write(data, 0);	/* A1: 0 (GND) */
-	nsp32_prom_write(data, 0);	/* A0: 0 (GND) */
+	nsp32_prom_write_bit(data, 1);	/* 1 */
+	nsp32_prom_write_bit(data, 0);	/* 0 */
+	nsp32_prom_write_bit(data, 1);	/* 1 */
+	nsp32_prom_write_bit(data, 0);	/* 0 */
+	nsp32_prom_write_bit(data, 0);	/* A2: 0 (GND) */
+	nsp32_prom_write_bit(data, 0);	/* A1: 0 (GND) */
+	nsp32_prom_write_bit(data, 0);	/* A0: 0 (GND) */
 
 	/* R/W: W for dummy write */
-	nsp32_prom_write(data, 0);
+	nsp32_prom_write_bit(data, 0);
 
 	/* ack */
-	nsp32_prom_write(data, 0);
+	nsp32_prom_write_bit(data, 0);
 
 	/* word address */
-	for (i=7; i>=0; i--) {
-		nsp32_prom_write(data, ((romaddr >> i) & 1));
+	for (i = 7; i >= 0; i--) {
+		nsp32_prom_write_bit(data, ((romaddr >> i) & 1));
 	}
 
 	/* ack */
-	nsp32_prom_write(data, 0);
+	nsp32_prom_write_bit(data, 0);
 
 	/* start condition */
 	nsp32_prom_start(data);
 
 	/* device address */
-	nsp32_prom_write(data, 1);	/* 1 */
-	nsp32_prom_write(data, 0);	/* 0 */
-	nsp32_prom_write(data, 1);	/* 1 */
-	nsp32_prom_write(data, 0);	/* 0 */
-	nsp32_prom_write(data, 0);	/* A2: 0 (GND) */
-	nsp32_prom_write(data, 0);	/* A1: 0 (GND) */
-	nsp32_prom_write(data, 0);	/* A0: 0 (GND) */
+	nsp32_prom_write_bit(data, 1);	/* 1 */
+	nsp32_prom_write_bit(data, 0);	/* 0 */
+	nsp32_prom_write_bit(data, 1);	/* 1 */
+	nsp32_prom_write_bit(data, 0);	/* 0 */
+	nsp32_prom_write_bit(data, 0);	/* A2: 0 (GND) */
+	nsp32_prom_write_bit(data, 0);	/* A1: 0 (GND) */
+	nsp32_prom_write_bit(data, 0);	/* A0: 0 (GND) */
 
 	/* R/W: R */
-	nsp32_prom_write(data, 1);
+	nsp32_prom_write_bit(data, 1);
 
 	/* ack */
-	nsp32_prom_write(data, 0);
+	nsp32_prom_write_bit(data, 0);
 
 	/* data... */
 	val = 0;
-	for (i=7; i>=0; i--) {
-		val += (nsp32_prom_fetch(data) << i);
+	for (i = 7; i >= 0; i--) {
+		int bit = nsp32_prom_read_bit(data) ? 1 : 0;
+
+		val |= (bit << i);
 	}
 	
 	/* no ack */
-	nsp32_prom_write(data, 1);
+	nsp32_prom_write_bit(data, 1);
 
 	/* stop condition */
 	nsp32_prom_stop(data);
 
-	return (val);
+	return val;
 }
 
 static void nsp32_prom_start (nsp32_hw_data *data)
 {
 	/* start condition */
-	nsp32_prom_set(data, SCL, 1);
-	nsp32_prom_set(data, SDA, 1);
-	nsp32_prom_set(data, ENA, 1);	/* output mode */
-	nsp32_prom_set(data, SDA, 0);	/* keeping SCL=1 and transiting
-					 * SDA 1->0 is start condition */
-	nsp32_prom_set(data, SCL, 0);
+	nsp32_prom_set(data, SROM_CTL,    1);
+	nsp32_prom_set(data, SROM_DATA,   1);
+	nsp32_prom_set(data, SROM_ENABLE, 1); /* output mode */
+	nsp32_prom_set(data, SROM_DATA,   0); /* keeping SROM_CTL=1 and transiting
+					       * SROM_DATA 1->0 is start condition */
+	nsp32_prom_set(data, SROM_CTL,    0);
 }
 
 static void nsp32_prom_stop (nsp32_hw_data *data)
 {
 	/* stop condition */
-	nsp32_prom_set(data, SCL, 1);
-	nsp32_prom_set(data, SDA, 0);
-	nsp32_prom_set(data, ENA, 1);	/* output mode */
-	nsp32_prom_set(data, SDA, 1);
-	nsp32_prom_set(data, SCL, 0);
+	nsp32_prom_set(data, SROM_CTL,    1);
+	nsp32_prom_set(data, SROM_DATA,   0);
+	nsp32_prom_set(data, SROM_ENABLE, 1);	/* output mode */
+	nsp32_prom_set(data, SROM_DATA,   1);
+	nsp32_prom_set(data, SROM_CTL,    0);
 }
 
-static void nsp32_prom_write (nsp32_hw_data *data, int val)
+static void nsp32_prom_write_bit(nsp32_hw_data *data, int val)
 {
 	/* write */
-	nsp32_prom_set(data, SDA, val);
-	nsp32_prom_set(data, SCL, 1);
-	nsp32_prom_set(data, SCL, 0);
+	nsp32_prom_set(data, SROM_DATA, val);
+	nsp32_prom_set(data, SROM_CTL,  1  );
+	nsp32_prom_set(data, SROM_CTL,  0  );
 }
 
-static int nsp32_prom_fetch (nsp32_hw_data *data)
+static int nsp32_prom_read_bit(nsp32_hw_data *data)
 {
 	int val;
 
 	/* read */
-	nsp32_prom_set(data, ENA, 0);	/* input mode */
-	nsp32_prom_set(data, SCL, 1);
-	val = nsp32_prom_get(data, SDA);
-	nsp32_prom_set(data, SCL, 0);
-	nsp32_prom_set(data, ENA, 1);	/* output mode */
-	return (val);
+	nsp32_prom_set(data, SROM_ENABLE, 0);	/* input mode */
+	nsp32_prom_set(data, SROM_CTL,    1);
+
+	val = nsp32_prom_get(data, SROM_DATA);
+
+	nsp32_prom_set(data, SROM_CTL,    0);
+	nsp32_prom_set(data, SROM_ENABLE, 1);	/* output mode */
+
+	return val;
 }
 
 static inline void nsp32_prom_set(nsp32_hw_data *data, int bit, int val)
 {
-	int cur;
-	int base = data->BaseAddress;
+	unsigned int base = data->BaseAddress;
+	int tmp;
 
-	switch(val) {
-	case 0:
-		cur = nsp32_index_read1(base, SERIAL_ROM_CTL);
-		nsp32_index_write1(base, SERIAL_ROM_CTL, cur & ~bit);
-		break;
-	case 1:
-		cur = nsp32_index_read1(base, SERIAL_ROM_CTL);
-		nsp32_index_write1(base, SERIAL_ROM_CTL, cur | bit);
-		break;
-	default:
-		nsp32_msg(KERN_ERR, "val must be 0 or 1");
-		return;
+	tmp = nsp32_index_read1(base, SERIAL_ROM_CTL);
+
+	if (val == 0) {
+		tmp &= ~bit;
+	} else {
+		tmp |=  bit;
 	}
 
+	nsp32_index_write1(base, SERIAL_ROM_CTL, tmp);
+
 	udelay(10);
 }
 
 static inline int nsp32_prom_get(nsp32_hw_data *data, int bit)
 {
-	int ret;
-	int base = data->BaseAddress;
+	unsigned int base = data->BaseAddress;
+	int tmp, ret;
 
-	ret = nsp32_index_read1(base, SERIAL_ROM_CTL) & bit;
-	switch (ret) {
-	case 0:
+	if (bit != SROM_DATA) {
+		nsp32_msg(KERN_ERR, "return value is not appropriate");
+		return 0;
+	}
+
+
+	tmp = nsp32_index_read1(base, SERIAL_ROM_CTL) & bit;
+
+	if (tmp == 0) {
 		ret = 0;
-		break;
-	case SDA:
+	} else {
 		ret = 1;
-		break;
-	default:
-		nsp32_msg(KERN_ERR, "return value is not appropriate");
 	}
 
 	udelay(10);
 
-	return (ret);
+	return ret;
+}
+
+
+/**************************************************************************
+ * Power Management
+ */
+#ifdef CONFIG_PM
+/* Save Device Context */
+static int nsp32_save_state(struct pci_dev *pdev, u32 state)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+
+	nsp32_msg(KERN_INFO, "pci-save_state: stub, pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host);
+
+	return 0;
+}
+
+/* Device suspended */
+static int nsp32_suspend(struct pci_dev *pdev, u32 state)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	nsp32_hw_data    *data = (nsp32_hw_data *)host->hostdata;
+
+	nsp32_msg(KERN_INFO, "pci-suspend: pdev=0x%p, state=%ld, slot=%s, host=0x%p", pdev, state, pci_name(pdev), host);
+
+	pci_save_state     (pdev, data->PciState);
+	pci_disable_device (pdev);
+	pci_set_power_state(pdev, state);
+
+	return 0;
+}
+
+/* Device woken up */
+static int nsp32_resume(struct pci_dev *pdev)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+	nsp32_hw_data    *data = (nsp32_hw_data *)host->hostdata;
+	unsigned short    reg;
+
+	nsp32_msg(KERN_INFO, "pci-resume: pdev=0x%p, slot=%s, host=0x%p", pdev, pci_name(pdev), host);
+
+	pci_set_power_state(pdev, 0);
+	pci_enable_wake    (pdev, 0, 0);
+	pci_restore_state  (pdev, data->PciState);
+
+	reg = nsp32_read2(data->BaseAddress, INDEX_REG);
+
+	nsp32_msg(KERN_INFO, "io=0x%x reg=0x%x", data->BaseAddress, reg);
+
+	if (reg == 0xffff) {
+		nsp32_msg(KERN_INFO, "missing device. abort resume.");
+		return 0;
+	}
+
+	nsp32hw_init      (data);
+	nsp32_do_bus_reset(data);
+
+	nsp32_msg(KERN_INFO, "resume success");
+
+	return 0;
+}
+
+/* Enable wake event */
+static int nsp32_enable_wake(struct pci_dev *pdev, u32 state, int enable)
+{
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+
+	nsp32_msg(KERN_INFO, "pci-enable_wake: stub, pdev=0x%p, enable=%d, slot=%s, host=0x%p", pdev, enable, pci_name(pdev), host);
+
+	return 0;
+}
+#endif
+
+/************************************************************************
+ * PCI/Cardbus probe/remove routine
+ */
+static int __devinit nsp32_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	int ret;
+	nsp32_hw_data *data = &nsp32_data_base;
+
+	nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
+
+        ret = pci_enable_device(pdev);
+	if (ret) {
+		nsp32_msg(KERN_ERR, "failed to enable pci device");
+		return ret;
+	}
+
+	data->Pci         = pdev;
+	data->pci_devid   = id;
+	data->IrqNumber   = pdev->irq;
+	data->BaseAddress = pci_resource_start(pdev, 0);
+	data->NumAddress  = pci_resource_len  (pdev, 0);
+	data->MmioAddress = 
+		(unsigned long)ioremap_nocache(pci_resource_start(pdev, 1),
+					       pci_resource_len  (pdev, 1));
+	data->MmioLength  = pci_resource_len  (pdev, 1);
+
+	pci_set_master(pdev);
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	ret = nsp32_detect(pdev);
+#else
+	ret = scsi_register_host(&nsp32_template);
+#endif
+
+	nsp32_msg(KERN_INFO, "irq: %i mmio: 0x%lx+0x%lx slot: %s model: %s",
+		  pdev->irq,
+		  data->MmioAddress, data->MmioLength,
+		  pci_name(pdev),
+		  nsp32_model[id->driver_data]);
+
+	nsp32_dbg(NSP32_DEBUG_REGISTER, "exit %d", ret);
+
+	return ret;
+}
+
+static void __devexit nsp32_remove(struct pci_dev *pdev)
+{
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	struct Scsi_Host *host = pci_get_drvdata(pdev);
+#endif
+
+	nsp32_dbg(NSP32_DEBUG_REGISTER, "enter");
+
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+        scsi_remove_host(host);
+
+	nsp32_release(host);
+
+	scsi_host_put(host);
+#else
+	scsi_unregister_host(&nsp32_template);	
+#endif
+}
+
+
+
+static struct pci_driver nsp32_driver = {
+	.name		= "nsp32",
+	.id_table	= nsp32_pci_table,
+	.probe		= nsp32_probe,
+	.remove		= __devexit_p(nsp32_remove),
+#ifdef CONFIG_PM
+	.save_state     = nsp32_save_state,
+	.suspend	= nsp32_suspend, 
+	.resume		= nsp32_resume, 
+	.enable_wake    = nsp32_enable_wake,
+#endif
+};
+
+/*********************************************************************
+ * Moule entry point
+ */
+static int __init init_nsp32(void) {
+	nsp32_msg(KERN_INFO, "loading...");
+	return pci_module_init(&nsp32_driver);
+}
+
+static void __exit exit_nsp32(void) {
+	nsp32_msg(KERN_INFO, "unloading...");
+	pci_unregister_driver(&nsp32_driver);
 }
 
+module_init(init_nsp32);
+module_exit(exit_nsp32);
+
 /* end */
diff -urN linux-2.4.23-pre6/drivers/scsi/nsp32.h linux-2.4.23-pre7/drivers/scsi/nsp32.h
--- linux-2.4.23-pre6/drivers/scsi/nsp32.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/nsp32.h	2003-10-09 17:48:22.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI Host Bus Adapter driver
+ * Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI Host Bus Adapter driver
  * Basic data header
  *
  * This program is free software; you can redistribute it and/or modify
@@ -16,61 +16,68 @@
 #ifndef _NSP32_H
 #define _NSP32_H
 
-
 //#define NSP32_DEBUG 9
 
-
 /*
  * VENDOR/DEVICE ID
  */
 #define PCI_VENDOR_ID_IODATA  0x10fc
 #define PCI_VENDOR_ID_WORKBIT 0x1145
 
-#define PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II  0x0005
-#define PCI_DEVICE_ID_NINJASCSI_32BI_KME      0xf007
-#define PCI_DEVICE_ID_NINJASCSI_32BI_WBT      0x8007
-#define PCI_DEVICE_ID_WORKBIT_STANDARD        0xf010
-#define PCI_DEVICE_ID_WORKBIT_DUALEDGE        0xf011
-#define PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC  0xf012
-#define PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC 0xf013
-#define PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO   0xf015
+#define PCI_DEVICE_ID_NINJASCSI_32BI_CBSC_II   0x0005
+#define PCI_DEVICE_ID_NINJASCSI_32BI_KME       0xf007
+#define PCI_DEVICE_ID_NINJASCSI_32BI_WBT       0x8007
+#define PCI_DEVICE_ID_WORKBIT_STANDARD         0xf010
+#define PCI_DEVICE_ID_WORKBIT_DUALEDGE         0xf011
+#define PCI_DEVICE_ID_NINJASCSI_32BI_LOGITEC   0xf012
+#define PCI_DEVICE_ID_NINJASCSI_32BIB_LOGITEC  0xf013
+#define PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO    0xf015
+#define PCI_DEVICE_ID_NINJASCSI_32UDE_MELCO_II 0x8009
 
 /*
- * MODEL
+ * MODEL NAME
+ *
+ * note: Model number and model string must be same order.
  */
 enum {
 	MODEL_IODATA        = 0,
 	MODEL_KME           = 1,
 	MODEL_WORKBIT       = 2,
-	MODEL_EXT_ROM       = 3,
+	MODEL_LOGITEC       = 3,
 	MODEL_PCI_WORKBIT   = 4,
 	MODEL_PCI_LOGITEC   = 5,
 	MODEL_PCI_MELCO     = 6,
 };
 
 static char * nsp32_model[] = {
-	"I-O DATA CBSC-II",
-	"KME SCSI card",
-	"Workbit duo SCSI card",
-	"External ROM",
-	"Workbit Standard/IO Data PCI card",
-	"Logitec PCI card",
-	"Melco PCI card",
+	"I-O DATA CBSC-II CardBus card",
+	"KME SCSI CardBus card",
+	"Workbit duo SCSI CardBus card",
+	"Logitec CardBus card with external ROM",
+	"Workbit / I-O DATA PCI card",
+	"Logitec PCI card with external ROM",
+	"Melco CardBus/PCI card with external ROM",
 };
 
 
 /*
- * SCSI Generic Definitions
+ * SCSI generic message definitions
  */
 #define EXTENDED_SDTR_LEN	0x03
 
+/* Little Endian */
+typedef u32 u32_le;
+typedef u16 u16_le;
 
 /*
  * MACRO
  */
-#define BIT(x)    (1UL << (x))
+/* from X11/Intrinsic.h */
+#define NUMBER(arr)            ((int) (sizeof(arr) / sizeof(arr[0])))
+#define ARRAY_OFFSET(type,num) ((int) (((type *) 0) + (num)))
+#define BIT(x)                 (1UL << (x))
 #ifndef MIN
-# define MIN(a,b)  ((a) > (b) ? (b) : (a))
+# define MIN(a,b)              ((a) > (b) ? (b) : (a))
 #endif
 
 /*
@@ -111,7 +118,10 @@
 # define TIMER_IRQ_MASK             BIT(13)
 # define FIFO_IRQ_MASK              BIT(14)
 # define SCSI_IRQ_MASK              BIT(15)
-# define IRQ_CONTROL_ALL_IRQ_MASK   0xf000
+# define IRQ_CONTROL_ALL_IRQ_MASK   (PCI_IRQ_MASK   | \
+                                     TIMER_IRQ_MASK | \
+                                     FIFO_IRQ_MASK  | \
+                                     SCSI_IRQ_MASK  )
 # define IRQSTATUS_ANY_IRQ          (IRQSTATUS_RESELECT_OCCUER	| \
 				     IRQSTATUS_PHASE_CHANGE_IRQ	| \
 				     IRQSTATUS_SCSIRESET_IRQ	| \
@@ -121,8 +131,8 @@
 				     IRQSTATUS_BMCNTERR_IRQ	| \
 				     IRQSTATUS_AUTOSCSI_IRQ	)
 
-#define TRANSFER_CONTROL 0x02	/* BASE+02, W, W */
-#define TRANSFER_STATUS  0x02	/* BASE+02, W, R */
+#define TRANSFER_CONTROL	0x02	/* BASE+02, W, W */
+#define TRANSFER_STATUS		0x02	/* BASE+02, W, R */
 # define CB_MMIO_MODE        BIT(0)
 # define CB_IO_MODE          BIT(1)
 # define BM_TEST             BIT(2)
@@ -139,26 +149,29 @@
 # define ALL_COUNTER_CLR     BIT(14)
 # define FIFOTEST            BIT(15)
 
-#define INDEX_REG 0x04		/* BASE+04, Byte(R/W), Word(R) */
+#define INDEX_REG		0x04	/* BASE+04, Byte(R/W), Word(R) */
 
-#define TIMER_SET 0x06		/* BASE+06, W, R/W */
-# define TIMER_CNT_MASK 0xff
+#define TIMER_SET		0x06	/* BASE+06, W, R/W */
+# define TIMER_CNT_MASK (0xff)
 # define TIMER_STOP     BIT(8)
 
-#define DATA_REG_LOW 0x08	/* BASE+08, LowW, R/W */
-#define DATA_REG_HI  0x0a	/* BASE+0a, Hi-W, R/W */
+#define DATA_REG_LOW		0x08	/* BASE+08, LowW, R/W */
+#define DATA_REG_HI		0x0a	/* BASE+0a, Hi-W, R/W */
 
-#define FIFO_REST_CNT 0x0c	/* BASE+0c, W, R/W */
+#define FIFO_REST_CNT		0x0c	/* BASE+0c, W, R/W */
 # define FIFO_REST_MASK       0x1ff
 # define FIFO_EMPTY_SHLD_FLAG BIT(14)
 # define FIFO_FULL_SHLD_FLAG  BIT(15)
 
-#define SREQ_SMPL_RATE 0x0f	/* BASE+0f, B, R/W */
+#define SREQ_SMPL_RATE		0x0f	/* BASE+0f, B, R/W */
 # define SREQSMPLRATE_RATE0 BIT(0)
 # define SREQSMPLRATE_RATE1 BIT(1)
 # define SAMPLING_ENABLE    BIT(2)
+#  define SMPL_40M (0)                   /* 40MHz:   0-100ns/period */
+#  define SMPL_20M (SREQSMPLRATE_RATE0)  /* 20MHz: 100-200ns/period */
+#  define SMPL_10M (SREQSMPLRATE_RATE1)  /* 10Mhz: 200-   ns/period */
 
-#define SCSI_BUS_CONTROL 0x10	/* BASE+10, B, R/W */
+#define SCSI_BUS_CONTROL	0x10	/* BASE+10, B, R/W */
 # define BUSCTL_SEL         BIT(0)
 # define BUSCTL_RST         BIT(1)
 # define BUSCTL_DATAOUT_ENB BIT(2)
@@ -168,16 +181,21 @@
 # define AUTODIRECTION      BIT(6)
 # define ACKENB             BIT(7)
 
-#define CLR_COUNTER 0x12	/* BASE+12, B, W */
+#define CLR_COUNTER		0x12	/* BASE+12, B, W */
 # define ACK_COUNTER_CLR       BIT(0)
 # define SREQ_COUNTER_CLR      BIT(1)
 # define FIFO_HOST_POINTER_CLR BIT(2)
 # define FIFO_REST_COUNT_CLR   BIT(3)
 # define BM_COUNTER_CLR        BIT(4)
 # define SAVED_ACK_CLR         BIT(5)
-# define CLRCOUNTER_ALLMASK    (BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5))
+# define CLRCOUNTER_ALLMASK    (ACK_COUNTER_CLR       | \
+                                SREQ_COUNTER_CLR      | \
+                                FIFO_HOST_POINTER_CLR | \
+                                FIFO_REST_COUNT_CLR   | \
+                                BM_COUNTER_CLR        | \
+                                SAVED_ACK_CLR         )
 
-#define SCSI_BUS_MONITOR 0x12	/* BASE+12, B, R */
+#define SCSI_BUS_MONITOR	0x12	/* BASE+12, B, R */
 # define BUSMON_MSG BIT(0)
 # define BUSMON_IO  BIT(1)
 # define BUSMON_CD  BIT(2)
@@ -187,20 +205,20 @@
 # define BUSMON_SEL BIT(6)
 # define BUSMON_ATN BIT(7)
 
-#define COMMAND_DATA 0x14	/* BASE+14, B, R/W */
+#define COMMAND_DATA		0x14	/* BASE+14, B, R/W */
 
-#define PARITY_CONTROL 0x16	/* BASE+16, B, R/W */
+#define PARITY_CONTROL		0x16	/* BASE+16, B, W */
 # define PARITY_CHECK_ENABLE BIT(0)
 # define PARITY_ERROR_CLEAR  BIT(1)
-#define PARITY_STATUS  0x16
+#define PARITY_STATUS		0x16	/* BASE+16, B, R */
 //# define PARITY_CHECK_ENABLE BIT(0)
 # define PARITY_ERROR_NORMAL BIT(1)
 # define PARITY_ERROR_LSB    BIT(1)
 # define PARITY_ERROR_MSB    BIT(2)
 
-#define RESELECT_ID 0x18	/* BASE+18, B, R */
+#define RESELECT_ID		0x18	/* BASE+18, B, R */
 
-#define COMMAND_CONTROL 0x18	/* BASE+18, W, W */
+#define COMMAND_CONTROL		0x18	/* BASE+18, W, W */
 # define CLEAR_CDB_FIFO_POINTER BIT(0)
 # define AUTO_COMMAND_PHASE     BIT(1)
 # define AUTOSCSI_START         BIT(2)
@@ -211,27 +229,27 @@
 # define AUTO_MSGIN_02          BIT(7)
 # define AUTO_MSGIN_03          BIT(8)
 
-#define SET_ARBIT 0x1a		/* BASE+1a, B, W */
+#define SET_ARBIT		0x1a	/* BASE+1a, B, W */
 # define ARBIT_GO    BIT(0)
 # define ARBIT_CLEAR BIT(1)
 
-#define ARBIT_STATUS 0x1a	/* BASE+1a, B, R */
+#define ARBIT_STATUS		0x1a	/* BASE+1a, B, R */
 //# define ARBIT_GO             BIT(0)
 # define ARBIT_WIN            BIT(1)
 # define ARBIT_FAIL           BIT(2)
 # define AUTO_PARAMETER_VALID BIT(3)
 # define SGT_VALID            BIT(4)
 
-#define SYNC_REG 0x1c	/* BASE+1c, B, R/W */
+#define SYNC_REG		0x1c	/* BASE+1c, B, R/W */
 
-#define ACK_WIDTH 0x1d	/* BASE+1d, B, R/W */
+#define ACK_WIDTH		0x1d	/* BASE+1d, B, R/W */
 
-#define SCSI_DATA_WITH_ACK 0x20	/* BASE+20, B, R/W */
+#define SCSI_DATA_WITH_ACK	0x20	/* BASE+20, B, R/W */
 #define SCSI_OUT_LATCH_TARGET_ID 0x22	/* BASE+22, B, W */
-#define SCSI_DATA_IN 0x22	/* BASE+22, B, R */
+#define SCSI_DATA_IN		0x22	/* BASE+22, B, R */
 
-#define SCAM_CONTROL 0x24	/* BASE+24, B, W */
-#define SCAM_STATUS  0x24	/* BASE+24, B, R */
+#define SCAM_CONTROL		0x24	/* BASE+24, B, W */
+#define SCAM_STATUS		0x24	/* BASE+24, B, R */
 # define SCAM_MSG    BIT(0)
 # define SCAM_IO     BIT(1)
 # define SCAM_CD     BIT(2)
@@ -239,31 +257,31 @@
 # define SCAM_SEL    BIT(4)
 # define SCAM_XFEROK BIT(5)
 
-#define SCAM_DATA 0x26	/* BASE+26, B, R/W */
-# define SD0					BIT(0)
-# define SD1					BIT(1)
-# define SD2					BIT(2)
-# define SD3					BIT(3)
-# define SD4					BIT(4)
-# define SD5					BIT(5)
-# define SD6					BIT(6)
-# define SD7					BIT(7)
-
-#define SACK_CNT 0x28	/* BASE+28, DW, R/W */
-#define SREQ_CNT 0x2c	/* BASE+2c, DW, R/W */
-
-#define FIFO_DATA_LOW 0x30	/* BASE+30, B/W/DW, R/W */
-#define FIFO_DATA_HIGH 0x32	/* BASE+32, B/W, R/W */
-#define BM_START_ADR 0x34	/* BASE+34, DW, R/W */
-
-#define BM_CNT 0x38	/* BASE+38, DW, R/W */
-# define BM_COUNT_MASK 0x0001ffff
-# define SGTEND        BIT(31)
+#define SCAM_DATA		0x26	/* BASE+26, B, R/W */
+# define SD0	BIT(0)
+# define SD1	BIT(1)
+# define SD2	BIT(2)
+# define SD3	BIT(3)
+# define SD4	BIT(4)
+# define SD5	BIT(5)
+# define SD6	BIT(6)
+# define SD7	BIT(7)
+
+#define SACK_CNT		0x28	/* BASE+28, DW, R/W */
+#define SREQ_CNT		0x2c	/* BASE+2c, DW, R/W */
+
+#define FIFO_DATA_LOW		0x30	/* BASE+30, B/W/DW, R/W */
+#define FIFO_DATA_HIGH		0x32	/* BASE+32, B/W, R/W */
+#define BM_START_ADR		0x34	/* BASE+34, DW, R/W */
+
+#define BM_CNT			0x38	/* BASE+38, DW, R/W */
+# define BM_COUNT_MASK 0x0001ffffUL
+# define SGTEND        BIT(31)      /* Last SGT marker */
 
-#define SGT_ADR 0x3c	/* BASE+3c, DW, R/W */
-#define WAIT_REG 0x40	/* Bi only */
+#define SGT_ADR			0x3c	/* BASE+3c, DW, R/W */
+#define WAIT_REG		0x40	/* Bi only */
 
-#define SCSI_EXECUTE_PHASE 0x40	/* BASE+40, W, R */
+#define SCSI_EXECUTE_PHASE	0x40	/* BASE+40, W, R */
 # define COMMAND_PHASE     BIT(0)
 # define DATA_IN_PHASE     BIT(1)
 # define DATA_OUT_PHASE    BIT(2)
@@ -280,14 +298,14 @@
 # define MSGIN_04_VALID    BIT(13)
 # define AUTOSCSI_BUSY     BIT(15)
 
-#define SCSI_CSB_IN 0x42	/* BASE+42, B, R */
+#define SCSI_CSB_IN		0x42	/* BASE+42, B, R */
 
-#define SCSI_MSG_OUT 0x44	/* BASE+44, DW, R/W */
+#define SCSI_MSG_OUT		0x44	/* BASE+44, DW, R/W */
 # define MSGOUT_COUNT_MASK (BIT(0)|BIT(1))
-# define MV_VALID	      BIT(7)
+# define MSGOUT_VALID	    BIT(7)
 
-#define SEL_TIME_OUT 0x48	/* BASE+48, W, R/W */
-#define SAVED_SACK_CNT 0x4c	/* BASE+4c, DW, R */
+#define SEL_TIME_OUT		0x48	/* BASE+48, W, R/W */
+#define SAVED_SACK_CNT		0x4c	/* BASE+4c, DW, R */
 
 #define HTOSDATADELAY		0x50	/* BASE+50, B, R/W */
 #define STOHDATADELAY		0x54	/* BASE+54, B, R/W */
@@ -299,21 +317,21 @@
 /* indexed register */
 /********************/
 
-#define CLOCK_DIV 0x00	/* BASE+08, IDX+00, B, R/W */
-# define CLOCK_2		BIT(0)	/* MCLK/2 */
-# define CLOCK_4		BIT(1)	/* MCLK/4 */
-# define PCICLK			BIT(7)	/* PCICLK (33MHz) */
+#define CLOCK_DIV		0x00	/* BASE+08, IDX+00, B, R/W */
+# define CLOCK_2  BIT(0)	/* MCLK/2 */
+# define CLOCK_4  BIT(1)	/* MCLK/4 */
+# define PCICLK	  BIT(7)	/* PCICLK (33MHz) */
 
-#define TERM_PWR_CONTROL 0x01	/* BASE+08, IDX+01, B, R/W */
+#define TERM_PWR_CONTROL	0x01	/* BASE+08, IDX+01, B, R/W */
 # define BPWR  BIT(0)
 # define SENSE BIT(1)	/* Read Only */
 
-#define EXT_PORT_DDR 0x02	/* BASE+08, IDX+02, B, R/W */
-#define EXT_PORT     0x03	/* BASE+08, IDX+03, B, R/W */
-# define LED_ON	 0
-# define LED_OFF 1
+#define EXT_PORT_DDR		0x02	/* BASE+08, IDX+02, B, R/W */
+#define EXT_PORT		0x03	/* BASE+08, IDX+03, B, R/W */
+# define LED_ON	 (0)
+# define LED_OFF BIT(0)
 
-#define IRQ_SELECT 0x04	/* BASE+08, IDX+04, W, R/W */
+#define IRQ_SELECT		0x04	/* BASE+08, IDX+04, W, R/W */
 # define IRQSELECT_RESELECT_IRQ      BIT(0)
 # define IRQSELECT_PHASE_CHANGE_IRQ  BIT(1)
 # define IRQSELECT_SCSIRESET_IRQ     BIT(2)
@@ -326,32 +344,35 @@
 # define IRQSELECT_BMCNTERR_IRQ      BIT(9)
 # define IRQSELECT_AUTO_SCSI_SEQ_IRQ BIT(10)
 
-#define OLD_SCSI_PHASE 0x05	/* BASE+08, IDX+05, B, R */
+#define OLD_SCSI_PHASE		0x05	/* BASE+08, IDX+05, B, R */
 # define OLD_MSG  BIT(0)
 # define OLD_IO   BIT(1)
 # define OLD_CD   BIT(2)
 # define OLD_BUSY BIT(3)
 
-#define FIFO_FULL_SHLD_COUNT 0x06	/* BASE+08, IDX+06, B, R/W */
-#define FIFO_EMPTY_SHLD_COUNT 0x07	/* BASE+08, IDX+07, B, R/W */
+#define FIFO_FULL_SHLD_COUNT	0x06	/* BASE+08, IDX+06, B, R/W */
+#define FIFO_EMPTY_SHLD_COUNT	0x07	/* BASE+08, IDX+07, B, R/W */
 
-#define EXP_ROM_CONTROL 0x08	/* BASE+08, IDX+08, B, R/W */
+#define EXP_ROM_CONTROL		0x08	/* BASE+08, IDX+08, B, R/W */ /* external ROM control */
+# define ROM_WRITE_ENB BIT(0)
+# define IO_ACCESS_ENB BIT(1)
+# define ROM_ADR_CLEAR BIT(2)
 
-#define EXP_ROM_ADRL		0x09	/* BASE+08, IDX+09, W, R/W */
+#define EXP_ROM_ADR		0x09	/* BASE+08, IDX+09, W, R/W */
 
 #define EXP_ROM_DATA		0x0a	/* BASE+08, IDX+0a, B, R/W */
 
-#define CHIP_MODE 0x0b	/* Bi only */
-# define OEM0 BIT(1)
-# define OEM1 BIT(2)
-# define OPTB BIT(3)
-# define OPTC BIT(4)
-# define OPTD BIT(5)
-# define OPTE BIT(6)
-# define OPTF BIT(7)
+#define CHIP_MODE		0x0b	/* BASE+08, IDX+0b, B, R   */ /* NinjaSCSI-32Bi only */
+# define OEM0 BIT(1)  /* OEM select */ /* 00=I-O DATA, 01=KME, 10=Workbit, 11=Ext ROM */
+# define OEM1 BIT(2)  /* OEM select */
+# define OPTB BIT(3)  /* KME mode select */
+# define OPTC BIT(4)  /* KME mode select */
+# define OPTD BIT(5)  /* KME mode select */
+# define OPTE BIT(6)  /* KME mode select */
+# define OPTF BIT(7)  /* Power management */
 
-#define MISC_WR 0x0c	/* BASE+08, IDX+0c, W, R/W */
-#define MISC_RD 0x0c
+#define MISC_WR			0x0c	/* BASE+08, IDX+0c, W, R/W */
+#define MISC_RD			0x0c
 # define SCSI_DIRECTION_DETECTOR_SELECT BIT(0)
 # define SCSI2_HOST_DIRECTION_VALID	BIT(1)	/* Read only */
 # define HOST2_SCSI_DIRECTION_VALID	BIT(2)	/* Read only */
@@ -362,7 +383,7 @@
 # define MISC_MABORT_MASK		BIT(7)
 # define BMSTOP_CHANGE2_NONDATA_PHASE	BIT(8)
 
-#define BM_CYCLE 0x0d	/* BASE+08, IDX+0d, B, R/W */
+#define BM_CYCLE		0x0d	/* BASE+08, IDX+0d, B, R/W */
 # define BM_CYCLE0		 BIT(0)
 # define BM_CYCLE1		 BIT(1)
 # define BM_FRAME_ASSERT_TIMING	 BIT(2)
@@ -373,20 +394,26 @@
 # define MEMRD_CMD1              BIT(7)
 
 
-#define SREQ_EDGH 0x0e	/* BASE+08, IDX+0e, B, W */
+#define SREQ_EDGH		0x0e	/* BASE+08, IDX+0e, B, W */
 # define SREQ_EDGH_SELECT BIT(0)
 
-#define UP_CNT		0x0f	/* BASE+08, IDX+0f, B, W */
-#define CFG_CMD_STR      0x10	/* BASE+08, IDX+10, W, R */
-#define CFG_LATE_CACHE   0x11	/* BASE+08, IDX+11, W, R/W */
-#define CFG_BASE_ADR_1   0x12	/* BASE+08, IDX+12, W, R */
-#define CFG_BASE_ADR_2   0x13	/* BASE+08, IDX+13, W, R */
-#define CFG_INLINE       0x14	/* BASE+08, IDX+14, W, R */
-
-#define SERIAL_ROM_CTL	0x15	/* BASE+08, IDX+15, B, R */
-# define SCL 					BIT(0)
-# define ENA					BIT(1)
-# define SDA					BIT(2)
+#define UP_CNT			0x0f	/* BASE+08, IDX+0f, B, W */ /* For hardware testing. Don't use it. */
+# define REQCNT_UP  BIT(0)
+# define ACKCNT_UP  BIT(1)
+# define BMADR_UP   BIT(4)
+# define BMCNT_UP   BIT(5)
+# define SGT_CNT_UP BIT(7)
+
+#define CFG_CMD_STR		0x10	/* BASE+08, IDX+10, W, R   */
+#define CFG_LATE_CACHE		0x11	/* BASE+08, IDX+11, W, R/W */
+#define CFG_BASE_ADR_1		0x12	/* BASE+08, IDX+12, W, R   */
+#define CFG_BASE_ADR_2		0x13	/* BASE+08, IDX+13, W, R   */
+#define CFG_INLINE		0x14	/* BASE+08, IDX+14, W, R   */
+
+#define SERIAL_ROM_CTL		0x15	/* BASE+08, IDX+15, B, R */
+# define SROM_CTL     BIT(0)
+# define SROM_ENABLE  BIT(1)
+# define SROM_DATA    BIT(2)
 
 #define FIFO_HST_POINTER	0x16	/* BASE+08, IDX+16, B, R/W */
 #define SREQ_DELAY		0x17	/* BASE+08, IDX+17, B, R/W */
@@ -425,5 +452,237 @@
 #define BUSPHASE_STATUS      ( BUSMON_STATUS      & BUSMON_PHASE_MASK )
 #define BUSPHASE_SELECT      ( BUSMON_SEL | BUSMON_IO )
 
+
+/************************************************************************
+ * structure for DMA/Scatter Gather list
+ */
+#define NSP32_SG_SIZE		SG_ALL
+
+/* All values must be little endian */
+typedef struct _nsp32_sgtable {
+	u32_le addr; /* transfer address */
+	u32_le len;  /* transfer length. BIT(31) is for SGTEND mark */
+} __attribute__ ((packed)) nsp32_sgtable;
+
+/* All values must be little endian */
+typedef struct _nsp32_sglun {
+	nsp32_sgtable sgt[NSP32_SG_SIZE+1];	/* SG table */
+} __attribute__ ((packed)) nsp32_sglun;
+#define NSP32_SG_TABLE_SIZE (sizeof(nsp32_sgtable) * NSP32_SG_SIZE * MAX_TARGET * MAX_LUN)
+
+/* Auto parameter mode memory map.   */
+/* All values must be little endian. */
+typedef struct _nsp32_autoparam {
+	u8     cdb[4 * 0x10];    /* SCSI Command                      */
+	u32_le msgout;           /* outgoing messages                 */
+	u8     syncreg;          /* sync register value               */
+	u8     ackwidth;         /* ack width register value          */
+	u8     target_id;        /* target/host device id             */
+	u8     sample_reg;       /* hazard killer sampling rate       */
+	u16_le command_control;  /* command control register          */
+	u16_le transfer_control; /* transfer control register         */
+	u32_le sgt_pointer;      /* SG table physical address for DMA */
+	u32_le dummy[2];
+} __attribute__ ((packed)) nsp32_autoparam;  /* must be packed struct */
+
+/*
+ * host data structure
+ */
+/* message in/out buffer */
+#define MSGOUTBUF_MAX		20
+#define MSGINBUF_MAX		20
+
+/* flag for trans_method */
+#define NSP32_TRANSFER_BUSMASTER	BIT(0)
+#define NSP32_TRANSFER_MMIO		BIT(1)	/* Not supported yet */
+#define NSP32_TRANSFER_PIO		BIT(2)	/* Not supported yet */
+
+
+/*
+ * structure for connected LUN dynamic data
+ *
+ * Note: Currently tagged queuing is disabled, each nsp32_lunt holds
+ *       one SCSI command and one state.
+ */
+#define DISCPRIV_OK		BIT(0)		/* DISCPRIV Enable mode */
+#define MSGIN03			BIT(1)		/* Auto Msg In 03 Flag  */
+
+typedef struct _nsp32_lunt {
+	Scsi_Cmnd     *SCpnt;	     /* Current Handling Scsi_Cmnd */
+	unsigned long  save_datp;    /* Save Data Pointer - saved position from initial address */
+	int	       msgin03;	     /* auto msg in 03 flag        */
+	unsigned int   sg_num;	     /* Total number of SG entries */
+	int	       cur_entry;    /* Current SG entry number    */
+	nsp32_sglun   *sglun;	     /* sg table per lun           */
+	dma_addr_t     sglun_paddr;  /* sglun physical address     */
+} nsp32_lunt;
+
+
+/*
+ * SCSI TARGET/LUN definition
+ */
+#define NSP32_HOST_SCSIID    7  /* SCSI initiator is everytime defined as 7 */
+#define MAX_TARGET	     8
+#define MAX_LUN		     8	/* XXX: In SPI3, max number of LUN is 64.   */
+
+
+typedef struct _nsp32_sync_table {
+	unsigned char	period_num;	/* period number                  */
+	unsigned char	ackwidth;	/* ack width designated by period */
+	unsigned char	start_period;	/* search range - start period    */
+	unsigned char	end_period;	/* search range - end period      */
+	unsigned char   sample_rate;    /* hazard killer parameter        */
+} nsp32_sync_table;
+
+
+/*
+ * structure for target device static data
+ */
+/* flag for nsp32_target.sync_flag */
+#define SDTR_NONE         0         /* initial state                      */
+#define SDTR_INITIATOR	  BIT(0)    /* sending SDTR from initiator        */
+#define SDTR_TARGET	  BIT(1)    /* sending SDTR from target           */
+#define SDTR_DONE	  BIT(2)    /* exchanging SDTR has been processed */
+
+/* syncronous period value for nsp32_target.config_max */
+#define FAST5M			0x32
+#define FAST10M			0x19
+#define ULTRA20M		0x0c
+
+/* flag for nsp32_target.{sync_offset, period} */
+#define ASYNC_OFFSET		0	/* asynchronous transfer           */
+#define MAX_OFFSET		0xf	/* synchronous transfer max offset */
+
+/* syncreg:
+  bit:07 06 05 04 03 02 01 00
+      ---PERIOD-- ---OFFSET--   */
+#define TO_SYNCREG(period, offset) (((period) & 0x0f) << 4 | ((offset) & 0x0f))
+
+typedef struct _nsp32_target {
+	unsigned char	syncreg;	/* value for SYNCREG   */
+	unsigned char	ackwidth;	/* value for ACKWIDTH  */
+	unsigned char   period;         /* sync period (0-255) */
+	unsigned char	offset;		/* sync offset (0-15)  */
+	int		sync_flag;	/* SDTR_*, 0           */
+	int		limit_entry;	/* max speed limit entry designated
+					   by EEPROM configuration */
+	unsigned char   sample_reg;     /* SREQ hazard killer register */
+} nsp32_target;
+
+typedef struct _nsp32_hw_data {
+	int           IrqNumber;
+	int           BaseAddress;
+	int           NumAddress;
+	unsigned long MmioAddress;
+#define NSP32_MMIO_OFFSET 0x0800
+	unsigned long MmioLength;
+
+	Scsi_Cmnd *CurrentSC;
+
+	struct pci_dev             *Pci;
+	const struct pci_device_id *pci_devid;
+	struct Scsi_Host           *Host;
+	spinlock_t                  Lock;
+
+	char info_str[100];
+
+	/* allocated memory region */
+	nsp32_sglun      *sg_list;	/* sglist virtuxal address         */
+	dma_addr_t	  sg_paddr;     /* physical address of hw_sg_table */
+	nsp32_autoparam  *autoparam;	/* auto parameter transfer region  */
+	dma_addr_t	  auto_paddr;	/* physical address of autoparam   */
+	int 		  cur_entry;	/* current sgt entry               */
+
+	/* target/LUN */
+	nsp32_lunt       *cur_lunt;	/* Current connected LUN table */
+	nsp32_lunt        lunt[MAX_TARGET][MAX_LUN];  /* All LUN table */
+
+	nsp32_target     *cur_target;	/* Current connected SCSI ID    */
+	nsp32_target	  target[MAX_TARGET];	     /* SCSI ID */
+	int		  cur_id;	/* Current connected target ID  */
+	int		  cur_lun;	/* Current connected target LUN */
+
+	/* behavior setting parameters */
+	int		  trans_method;	/* transfer method flag            */
+	int		  resettime;	/* Reset time                      */
+	int 		  clock;       	/* clock dividing flag             */
+	nsp32_sync_table *synct;	/* sync_table determined by clock  */
+	int		  syncnum;	/* the max number of synct element */
+
+	/* message buffer */
+	unsigned char msgoutbuf[MSGOUTBUF_MAX]; /* msgout buffer    */
+	char	      msgout_len;		/* msgoutbuf length */
+	unsigned char msginbuf [MSGINBUF_MAX];	/* megin buffer     */
+	char	      msgin_len;		/* msginbuf length  */
+
+#ifdef CONFIG_PM
+	u32           PciState[16];     /* save PCI state to this area */
+#endif
+} nsp32_hw_data;
+
+/*
+ * TIME definition
+ */
+#define RESET_HOLD_TIME		10000	/* reset time in us (SCSI-2 says the
+					   minimum is 25us) */
+#define SEL_TIMEOUT_TIME	10000	/* 250ms defined in SCSI specification
+					   (25.6us/1unit) */
+#define ARBIT_TIMEOUT_TIME	100	/* 100us */
+#define REQSACK_TIMEOUT_TIME	10000	/* max wait time for REQ/SACK assertion
+					   or negation, 10000us == 10ms */
+
+/**************************************************************************
+ * Compatibility functions
+ */
+
+/* for Kernel 2.4 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# define scsi_register_host(template) 	scsi_register_module(MODULE_SCSI_HA, template)
+# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
+# define scsi_host_put(host)            scsi_unregister(host)
+# define pci_name(pci_dev)              ((pci_dev)->slot_name)
+
+typedef void irqreturn_t;
+# define IRQ_NONE      /* */
+# define IRQ_HANDLED   /* */
+# define IRQ_RETVAL(x) /* */
+
+/* This is ad-hoc version of scsi_host_get_next() */
+static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
+{
+	if (host == NULL) {
+		return scsi_hostlist;
+	} else {
+		return host->next;
+	}
+}
+
+/* This is ad-hoc version of scsi_host_hn_get() */
+static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
+{
+	struct Scsi_Host *host;
+
+	for (host = scsi_host_get_next(NULL); host != NULL;
+	     host = scsi_host_get_next(host)) {
+		if (host->host_no == hostno) {
+			break;
+		}
+	}
+
+	return host;
+}
+
+/* host spin lock */
+# define HOST_LOCK (&io_request_lock)
+#endif
+
+/* for Kernel 2.6 */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+# define __devinitdata /* */
+
+/* host spin lock */
+# define HOST_LOCK (data->Host->host_lock)
+#endif
+
 #endif /* _NSP32_H */
 /* end */
diff -urN linux-2.4.23-pre6/drivers/scsi/nsp32_debug.c linux-2.4.23-pre7/drivers/scsi/nsp32_debug.c
--- linux-2.4.23-pre6/drivers/scsi/nsp32_debug.c	2003-06-13 07:51:36.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/nsp32_debug.c	2003-10-09 17:48:22.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI Host Bus Adapter driver
+ * Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI Host Bus Adapter driver
  * Debug routine
  *
  * This software may be used and distributed according to the terms of
@@ -85,22 +85,22 @@
 
 static void print_commandk (unsigned char *command)
 {
-	int i,s;
+	int i, size;
 //	printk(KERN_DEBUG);
 	print_opcodek(command[0]);
-	/*printk(KERN_DEBUG __func__ " ");*/
+	/*printk(KERN_DEBUG "%s ", __FUNCTION__);*/
 	if ((command[0] >> 5) == 6 ||
 	    (command[0] >> 5) == 7 ) {
-		s = 12; /* vender specific */
+		size = 12; /* vender specific */
 	} else {
-		s = COMMAND_SIZE(command[0]);
+		size = COMMAND_SIZE(command[0]);
 	}
 
 	for ( i = 1; i < s; ++i) {
 		printk("%02x ", command[i]);
 	}
 
-	switch (s) {
+	switch (size) {
 	case 6:
 		printk("LBA=%d len=%d",
 		       (((unsigned int)command[1] & 0x0f) << 16) |
@@ -137,9 +137,9 @@
 	printk("\n");
 }
 
-static void show_command(Scsi_Cmnd *ptr)
+static void show_command(Scsi_Cmnd *SCpnt)
 {
-	print_commandk(ptr->cmnd);
+	print_commandk(SCpnt->cmnd);
 }
 
 static void show_busphase(unsigned char stat)
@@ -260,3 +260,45 @@
 	}
 }
 
+/*
+ * Byte dumper
+ *
+ * ptr:    start address
+ * offset: offset value for address section
+ * size:   dump size in byte
+ */
+static void nsp32_byte_dump(void *ptr, int offset, int size)
+{
+	unsigned char *tmp = ptr;
+	int pos;
+
+	if (size == 0) {
+		return;
+	}
+
+	pos = 0;
+	while(pos < size) {
+		/* address */
+		if (pos % 16 == 0) {
+			printk(/*KERN_DEBUG*/ "%08x:", pos + offset);
+		}
+
+		/* half separator */
+		if (pos % 16 == 8) {
+			printk(" -");
+		}
+
+		printk(" %02x", tmp[pos]);
+
+		/* Don't print "\n" at last line.
+		   Because we can get one more "\n". */
+		if ((pos % 16 == 15) && (pos + 1 != size)) {
+			printk("\n");
+		}
+
+		pos ++;
+	}
+	printk("\n");
+}
+
+/* end */
diff -urN linux-2.4.23-pre6/drivers/scsi/nsp32_io.h linux-2.4.23-pre7/drivers/scsi/nsp32_io.h
--- linux-2.4.23-pre6/drivers/scsi/nsp32_io.h	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/nsp32_io.h	2003-10-09 17:48:22.000000000 -0700
@@ -1,5 +1,5 @@
 /*
- * Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus SCSI Host Bus Adapter driver
+ * Workbit NinjaSCSI-32Bi/UDE PCI/CardBus SCSI Host Bus Adapter driver
  * I/O routine
  *
  * This software may be used and distributed according to the terms of
@@ -22,30 +22,30 @@
 	return inb(base + index);
 }
 
-static inline void nsp32_write2(unsigned int  base,
-				unsigned int  index,
+static inline void nsp32_write2(unsigned int   base,
+				unsigned int   index,
 				unsigned short val)
 {
-	outw(cpu_to_le16(val), (base + index));
+	outw(val, (base + index));
 }
 
 static inline unsigned short nsp32_read2(unsigned int base,
 					 unsigned int index)
 {
-	return le16_to_cpu(inw(base + index));
+	return inw(base + index);
 }
 
 static inline void nsp32_write4(unsigned int  base,
 				unsigned int  index,
 				unsigned long val)
 {
-	outl(cpu_to_le32(val), (base + index));
+	outl(val, (base + index));
 }
 
 static inline unsigned long nsp32_read4(unsigned int base,
 					unsigned int index)
 {
-	return le32_to_cpu(inl(base + index));
+	return inl(base + index);
 }
 
 /*==============================================*/
@@ -58,7 +58,7 @@
 
 	ptr = (unsigned char *)(base + NSP32_MMIO_OFFSET + index);
 
-	*ptr = val;
+	writeb(val, ptr);
 }
 
 static inline unsigned char nsp32_mmio_read1(unsigned long base,
@@ -68,18 +68,18 @@
 
 	ptr = (unsigned char *)(base + NSP32_MMIO_OFFSET + index);
 
-	return *ptr;
+	return readb(ptr);
 }
 
-static inline void nsp32_mmio_write2(unsigned long base,
-				     unsigned int  index,
+static inline void nsp32_mmio_write2(unsigned long  base,
+				     unsigned int   index,
 				     unsigned short val)
 {
 	volatile unsigned short *ptr;
 
 	ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + index);
 
-	*ptr = cpu_to_le16(val);
+	writew(cpu_to_le16(val), ptr);
 }
 
 static inline unsigned short nsp32_mmio_read2(unsigned long base,
@@ -87,11 +87,9 @@
 {
 	volatile unsigned short *ptr;
 
-	//printk(__FUNCTION__ "\n");
-
 	ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + index);
 
-	return le16_to_cpu(*ptr);
+	return le16_to_cpu(readw(ptr));
 }
 
 static inline void nsp32_mmio_write4(unsigned long base,
@@ -102,7 +100,7 @@
 
 	ptr = (unsigned long *)(base + NSP32_MMIO_OFFSET + index);
 
-	*ptr = cpu_to_le32(val);
+	writel(cpu_to_le32(val), ptr);
 }
 
 static inline unsigned long nsp32_mmio_read4(unsigned long base,
@@ -110,16 +108,12 @@
 {
 	volatile unsigned long *ptr;
 
-	//printk(__FUNCTION__ "\n");
-
 	ptr = (unsigned long *)(base + NSP32_MMIO_OFFSET + index);
 
-	return le32_to_cpu(*ptr);
+	return le32_to_cpu(readl(ptr));
 }
 
-
-/*=============================================*/
-
+/*==============================================*/
 
 static inline unsigned char nsp32_index_read1(unsigned int base,
 					      unsigned int reg)
@@ -132,7 +126,7 @@
 				      unsigned int  reg,
 				      unsigned char val)
 {
-	outb(reg, base + INDEX_REG);
+	outb(reg, base + INDEX_REG   );
 	outb(val, base + DATA_REG_LOW);
 }
 
@@ -140,15 +134,15 @@
 					       unsigned int reg)
 {
 	outb(reg, base + INDEX_REG);
-	return le16_to_cpu(inw(base + DATA_REG_LOW));
+	return inw(base + DATA_REG_LOW);
 }
 
-static inline void nsp32_index_write2(unsigned int  base,
-				      unsigned int  reg,
+static inline void nsp32_index_write2(unsigned int   base,
+				      unsigned int   reg,
 				      unsigned short val)
 {
-	outb(reg, base + INDEX_REG);
-	outw(cpu_to_le16(val), base + DATA_REG_LOW);
+	outb(reg, base + INDEX_REG   );
+	outw(val, base + DATA_REG_LOW);
 }
 
 static inline unsigned long nsp32_index_read4(unsigned int base,
@@ -157,8 +151,8 @@
 	unsigned long h,l;
 
 	outb(reg, base + INDEX_REG);
-	l = le16_to_cpu(inw(base + DATA_REG_LOW));
-	h = le16_to_cpu(inw(base + DATA_REG_HI ));
+	l = inw(base + DATA_REG_LOW);
+	h = inw(base + DATA_REG_HI );
 
 	return ((h << 16) | l);
 }
@@ -170,15 +164,14 @@
 	unsigned long h,l;
 
 	h = (val & 0xffff0000) >> 16;
-	l = (val & 0x0000ffff) >> 0;
+	l = (val & 0x0000ffff) >>  0;
 
-	outb(reg, base + INDEX_REG);
-	outw(cpu_to_le16(l), base + DATA_REG_LOW);
-	outw(cpu_to_le16(h), base + DATA_REG_HI);
+	outb(reg, base + INDEX_REG   );
+	outw(l,   base + DATA_REG_LOW);
+	outw(h,   base + DATA_REG_HI );
 }
 
-
-/* ===================================*/
+/*==============================================*/
 
 static inline unsigned char nsp32_mmio_index_read1(unsigned int base,
 						   unsigned int reg)
@@ -188,13 +181,12 @@
 	index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG);
 	data_ptr  = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW);
 
-	*index_ptr = reg;
-
-	return ((*data_ptr) & 0xff);
+	writeb(reg, index_ptr);
+	return readb(data_ptr);
 }
 
-static inline void nsp32_mmio_index_write1(unsigned int base,
-					   unsigned int reg,
+static inline void nsp32_mmio_index_write1(unsigned int  base,
+					   unsigned int  reg,
 					   unsigned char val)
 {
 	volatile unsigned short *index_ptr, *data_ptr;
@@ -202,8 +194,8 @@
 	index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG);
 	data_ptr  = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW);
 
-	*index_ptr = reg;
-	*data_ptr  = (unsigned short)val;
+	writeb(reg, index_ptr);
+	writeb(val, data_ptr );
 }
 
 static inline unsigned short nsp32_mmio_index_read2(unsigned int base,
@@ -214,13 +206,12 @@
 	index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG);
 	data_ptr  = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW);
 
-	*index_ptr = reg;
-
-	return le16_to_cpu(*data_ptr);
+	writeb(reg, index_ptr);
+	return le16_to_cpu(readw(data_ptr));
 }
 
-static inline void nsp32_mmio_index_write2(unsigned int base,
-					   unsigned int reg,
+static inline void nsp32_mmio_index_write2(unsigned int   base,
+					   unsigned int   reg,
 					   unsigned short val)
 {
 	volatile unsigned short *index_ptr, *data_ptr;
@@ -228,34 +219,33 @@
 	index_ptr = (unsigned short *)(base + NSP32_MMIO_OFFSET + INDEX_REG);
 	data_ptr  = (unsigned short *)(base + NSP32_MMIO_OFFSET + DATA_REG_LOW);
 
-	*index_ptr = reg;
-	*data_ptr  = val;
+	writeb(reg,              index_ptr);
+	writew(cpu_to_le16(val), data_ptr );
 }
 
-/*-------------------------------------------------------------------*/
+/*==============================================*/
 
-static inline void nsp32_multi_read4(unsigned int   BaseAddr,
-				     unsigned int   Register,
+static inline void nsp32_multi_read4(unsigned int   base,
+				     unsigned int   reg,
 				     void          *buf,
 				     unsigned long  count)
 {
-	insl(BaseAddr + Register, buf, count);
+	insl(base + reg, buf, count);
 }
 
 static inline void nsp32_fifo_read(unsigned int   base,
 				   void          *buf,
 				   unsigned long  count)
 {
-	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
 	nsp32_multi_read4(base, FIFO_DATA_LOW, buf, count);
 }
 
-static inline void nsp32_multi_write4(unsigned int   BaseAddr,
-				      unsigned int   Register,
+static inline void nsp32_multi_write4(unsigned int   base,
+				      unsigned int   reg,
 				      void          *buf,
 				      unsigned long  count)
 {
-	outsl(BaseAddr + Register, buf, count);
+	outsl(base + reg, buf, count);
 }
 
 static inline void nsp32_fifo_write(unsigned int   base,
diff -urN linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_cs.c linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_cs.c
--- linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_cs.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_cs.c	2003-10-09 17:48:22.000000000 -0700
@@ -1,8 +1,10 @@
 /*======================================================================
 
-    NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI hostadapter card driver
+    NinjaSCSI-3 / NinjaSCSI-32Bi PCMCIA SCSI host adapter card driver
       By: YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>
 
+    Ver.2.8   Support 32bit MMIO mode
+              Support Synchronous Data Transfer Request (SDTR) mode
     Ver.2.0   Support 32bit PIO mode
     Ver.1.1.2 Fix for scatter list buffer exceeds
     Ver.1.1   Support scatter list
@@ -23,34 +25,32 @@
 
 ***********************************************************************/
 
-/* $Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $ */
-
-#ifdef NSP_KERNEL_2_2
-#include <pcmcia/config.h>
-#include <pcmcia/k_compat.h>
-#endif
+/* $Id: nsp_cs.c,v 1.25 2003/09/24 10:38:18 elca Exp $ */
 
+#include <linux/version.h>
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
 #include <linux/string.h>
+#include <linux/timer.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
-#include <linux/tqueue.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/major.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/stat.h>
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# include <linux/blk.h>
+#endif
 
 #include <asm/io.h>
 #include <asm/irq.h>
 
 #include <../drivers/scsi/scsi.h>
 #include <../drivers/scsi/hosts.h>
-#include <../drivers/scsi/sd.h>
 
 #include <scsi/scsi.h>
 #include <scsi/scsi_ioctl.h>
@@ -59,138 +59,192 @@
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
+#include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
 #include "nsp_cs.h"
 
 MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>");
-MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module");
+MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.25 $");
 MODULE_SUPPORTED_DEVICE("sd,sr,sg,st");
 MODULE_LICENSE("GPL");
 
-#ifdef PCMCIA_DEBUG
-static int pc_debug = PCMCIA_DEBUG;
-MODULE_PARM(pc_debug, "i");
-MODULE_PARM_DESC(pc_debug, "set debug level");
-static char *version = "$Id: nsp_cs.c,v 1.42 2001/09/10 10:30:58 elca Exp $";
-#define DEBUG(n, args...) if (pc_debug>(n)) printk(KERN_DEBUG args)
-#else
-#define DEBUG(n, args...) /* */
-#endif
-
 #include "nsp_io.h"
 
 /*====================================================================*/
+/* Parameters that can be set with 'insmod' */
 
-typedef struct scsi_info_t {
-	dev_link_t             link;
-	struct Scsi_Host      *host;
-	int	               ndev;
-	dev_node_t             node[8];
-	int                    stop;
-	struct bus_operations *bus;
-} scsi_info_t;
+static unsigned int irq_mask = 0xffff;
+MODULE_PARM     (irq_mask, "i");
+MODULE_PARM_DESC(irq_mask, "IRQ mask bits (default: 0xffff)");
 
+static int       irq_list[4] = { -1 };
+MODULE_PARM     (irq_list, "1-4i");
+MODULE_PARM_DESC(irq_list, "Use specified IRQ number. (default: auto select)");
+
+static int       nsp_burst_mode = BURST_MEM32;
+MODULE_PARM     (nsp_burst_mode, "i");
+MODULE_PARM_DESC(nsp_burst_mode, "Burst transfer mode (0=io8, 1=io32, 2=mem32(default))");
+
+/* Release IO ports after configuration? */
+static int       free_ports = 0;
+MODULE_PARM     (free_ports, "i");
+MODULE_PARM_DESC(free_ports, "Release IO ports after configuration? (default: 0 (=no))");
 
-/*----------------------------------------------------------------*/
-
-#if (KERNEL_VERSION(2,4,0) > LINUX_VERSION_CODE)
-#define PROC_SCSI_NSP PROC_SCSI_IBMMCA /* bad hack... */
-static struct proc_dir_entry proc_scsi_nsp = {
-	PROC_SCSI_NSP, 6, "nsp_cs",
-	S_IFDIR | S_IRUGO | S_IXUGO, 2
-};
+/* /usr/src/linux/drivers/scsi/hosts.h */
+static Scsi_Host_Template nsp_driver_template = {
+	.proc_name	         = "nsp_cs",
+	.proc_info		 = nsp_proc_info,
+	.name			 = "WorkBit NinjaSCSI-3/32Bi(16bit)",
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+	.detect			 = nsp_detect_old,
+	.release		 = nsp_release_old,
+#endif
+	.info			 = nsp_info,
+	.queuecommand		 = nsp_queuecommand,
+/*	.eh_strategy_handler	 = nsp_eh_strategy,*/
+/*	.eh_abort_handler	 = nsp_eh_abort,*/
+/*	.eh_device_reset_handler = nsp_eh_device_reset,*/
+	.eh_bus_reset_handler	 = nsp_eh_bus_reset,
+	.eh_host_reset_handler	 = nsp_eh_host_reset,
+	.can_queue		 = 1,
+	.this_id		 = NSP_INITIATOR_ID,
+	.sg_tablesize		 = SG_ALL,
+	.cmd_per_lun		 = 1,
+	.use_clustering		 = DISABLE_CLUSTERING,
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2))
+	.use_new_eh_code	 = 1,
 #endif
+};
 
-/*====================================================================*/
-/* Parameters that can be set with 'insmod' */
+static dev_link_t *dev_list = NULL;
+static dev_info_t dev_info  = "nsp_cs";
 
-static unsigned int irq_mask = 0xffff;
-MODULE_PARM(irq_mask, "i");
-MODULE_PARM_DESC(irq_mask, "IRQ mask bits");
+static nsp_hw_data nsp_data_base; /* attach <-> detect glue */
 
-static int irq_list[4] = { -1 };
-MODULE_PARM(irq_list, "1-4i");
-MODULE_PARM_DESC(irq_list, "IRQ number list");
 
-/*----------------------------------------------------------------*/
-/* driver state info, local to driver */
-static char nspinfo[100];     /* description */
 
-/* /usr/src/linux/drivers/scsi/hosts.h */
-static Scsi_Host_Template driver_template = {
-/*	next:			NULL,*/
-#if (KERNEL_VERSION(2,3,99) > LINUX_VERSION_CODE)
-	proc_dir:	       &proc_scsi_nsp, /* kernel 2.2 */
+/******************************************************************
+ * debug, error print
+ */
+#ifdef NSP_DEBUG
+# include "nsp_debug.c"
+#endif	/* NSP_DEBUG */
+
+#ifndef NSP_DEBUG
+# define NSP_DEBUG_MASK		0x000000
+# define nsp_msg(type, args...) nsp_cs_message("", 0, (type), args)
+# define nsp_dbg(mask, args...) /* */
 #else
-	proc_name:	       "nsp_cs",       /* kernel 2.4 */
+# define NSP_DEBUG_MASK		0xffffff
+# define nsp_msg(type, args...) \
+	nsp_cs_message (__FUNCTION__, __LINE__, (type), args)
+# define nsp_dbg(mask, args...) \
+	nsp_cs_dmessage(__FUNCTION__, __LINE__, (mask), args)
 #endif
-/*	proc_info:		NULL,*/
-	name:			"WorkBit NinjaSCSI-3/32Bi",
-	detect:			nsp_detect,
-	release:		nsp_release,
-	info:			nsp_info,
-/*	command:		NULL,*/
-	queuecommand:		nsp_queuecommand,
-/*	eh_strategy_handler:	nsp_eh_strategy,*/
-	eh_abort_handler:	nsp_eh_abort,
-	eh_device_reset_handler: nsp_eh_device_reset,
-	eh_bus_reset_handler:	nsp_eh_bus_reset,
-	eh_host_reset_handler:	nsp_eh_host_reset,
-	abort:			nsp_abort,
-	reset:			nsp_reset,
-/*	slave_attach:		NULL,*/
-/*	bios_param:		NULL,*/
-	can_queue:		1,
-	this_id:		SCSI_INITIATOR_ID,
-	sg_tablesize:		SG_ALL,
-	cmd_per_lun:		1,
-/*	present:		0,*/
-/*	unchecked_isa_dma:	0,*/
-	use_clustering:		DISABLE_CLUSTERING,
-	use_new_eh_code:	0,
-/*	emulated:		0,*/
-};
 
-static dev_link_t *dev_list = NULL;
-static dev_info_t dev_info  = {"nsp_cs"};
+#define NSP_DEBUG_QUEUECOMMAND		BIT(0)
+#define NSP_DEBUG_REGISTER		BIT(1)
+#define NSP_DEBUG_AUTOSCSI		BIT(2)
+#define NSP_DEBUG_INTR			BIT(3)
+#define NSP_DEBUG_SGLIST		BIT(4)
+#define NSP_DEBUG_BUSFREE		BIT(5)
+#define NSP_DEBUG_CDB_CONTENTS		BIT(6)
+#define NSP_DEBUG_RESELECTION		BIT(7)
+#define NSP_DEBUG_MSGINOCCUR		BIT(8)
+#define NSP_DEBUG_EEPROM		BIT(9)
+#define NSP_DEBUG_MSGOUTOCCUR		BIT(10)
+#define NSP_DEBUG_BUSRESET		BIT(11)
+#define NSP_DEBUG_RESTART		BIT(12)
+#define NSP_DEBUG_SYNC			BIT(13)
+#define NSP_DEBUG_WAIT			BIT(14)
+#define NSP_DEBUG_TARGETFLAG		BIT(15)
+#define NSP_DEBUG_PROC			BIT(16)
+#define NSP_DEBUG_INIT			BIT(17)
+#define NSP_DEBUG_DATA_IO      		BIT(18)
+#define NSP_SPECIAL_PRINT_REGISTER	BIT(20)
+
+#define NSP_DEBUG_BUF_LEN		150
+
+static void nsp_cs_message(const char *func, int line, char *type, char *fmt, ...)
+{
+	va_list args;
+	char buf[NSP_DEBUG_BUF_LEN];
+
+	va_start(args, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
 
-static nsp_hw_data nsp_data;
+#ifndef NSP_DEBUG
+	printk("%snsp_cs: %s\n", type, buf);
+#else
+	printk("%snsp_cs: %s (%d): %s\n", type, func, line, buf);
+#endif
+}
+
+#ifdef NSP_DEBUG
+static void nsp_cs_dmessage(const char *func, int line, int mask, char *fmt, ...)
+{
+	va_list args;
+	char buf[NSP_DEBUG_BUF_LEN];
+
+	va_start(args, fmt);
+	vsnprintf(buf, sizeof(buf), fmt, args);
+	va_end(args);
+
+	if (mask & NSP_DEBUG_MASK) {
+		printk("nsp_cs-debug: 0x%x %s (%d): %s\n", mask, func, line, buf);
+	}
+}
+#endif
 
 /***********************************************************/
 
+/*====================================================
+ * Clenaup parameters and call done() functions.
+ * You must be set SCpnt->result before call this function.
+ */
+static void nsp_scsi_done(Scsi_Cmnd *SCpnt)
+{
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+
+	data->CurrentSC = NULL;
+
+	SCpnt->scsi_done(SCpnt);
+}
+
 static int nsp_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
 {
-#ifdef PCMCIA_DEBUG
-	//unsigned int host_id = SCpnt->host->this_id;
-	//unsigned int base    = SCpnt->host->io_port;
-	unsigned char target = SCpnt->target;
-#endif
-	nsp_hw_data *data = &nsp_data;
-
-	DEBUG(0, __FUNCTION__ "() SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d\n",
-	      SCpnt, target, SCpnt->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
-	//DEBUG(0, " before CurrentSC=0x%p\n", data->CurrentSC);
-
-	if(data->CurrentSC != NULL) {
-		printk(KERN_DEBUG " " __FUNCTION__ "() CurrentSC!=NULL this can't be happen\n");
-		data->CurrentSC = NULL;
+#ifdef NSP_DEBUG
+	/*unsigned int host_id = SCpnt->device->host->this_id;*/
+	/*unsigned int base    = SCpnt->device->host->io_port;*/
+	unsigned char target = SCpnt->device->id;
+#endif
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+
+	nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "SCpnt=0x%p target=%d lun=%d buff=0x%p bufflen=%d use_sg=%d",
+		   SCpnt, target, SCpnt->device->lun, SCpnt->request_buffer, SCpnt->request_bufflen, SCpnt->use_sg);
+	//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "before CurrentSC=0x%p", data->CurrentSC);
+
+	SCpnt->scsi_done	= done;
+
+	if (data->CurrentSC != NULL) {
+		nsp_msg(KERN_WARNING, "CurrentSC!=NULL this can't be happen");
 		SCpnt->result   = DID_BAD_TARGET << 16;
-		done(SCpnt);
-		return -1;
+		nsp_scsi_done(SCpnt);
+		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
 	show_command(SCpnt);
 
-	SCpnt->scsi_done	= done;
 	data->CurrentSC		= SCpnt;
-	RESID		        = SCpnt->request_bufflen;
 
-	SCpnt->SCp.Status	= -1;
-	SCpnt->SCp.Message	= -1;
+	SCpnt->SCp.Status	= CHECK_CONDITION;
+	SCpnt->SCp.Message	= 0;
 	SCpnt->SCp.have_data_in = IO_UNKNOWN;
 	SCpnt->SCp.sent_command = 0;
 	SCpnt->SCp.phase	= PH_UNDETERMINED;
+	SCpnt->resid	        = SCpnt->request_bufflen;
 
 	/* setup scratch area
 	   SCp.ptr		: buffer pointer
@@ -200,7 +254,7 @@
 	   SCp.phase		: current state of the command */
 	if (SCpnt->use_sg) {
 		SCpnt->SCp.buffer	    = (struct scatterlist *) SCpnt->request_buffer;
-		SCpnt->SCp.ptr		    = SCpnt->SCp.buffer->address;
+		SCpnt->SCp.ptr		    = SG_ADDRESS(SCpnt->SCp.buffer);
 		SCpnt->SCp.this_residual    = SCpnt->SCp.buffer->length;
 		SCpnt->SCp.buffers_residual = SCpnt->use_sg - 1;
 	} else {
@@ -210,16 +264,18 @@
 		SCpnt->SCp.buffers_residual = 0;
 	}
 
-	if(nsphw_start_selection(SCpnt, data) == FALSE) {
-		DEBUG(0, " selection fail\n");
-		data->CurrentSC = NULL;
-		SCpnt->result   = DID_NO_CONNECT << 16;
-		done(SCpnt);
-		return -1;
+	if (nsphw_start_selection(SCpnt) == FALSE) {
+		nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "selection fail");
+		SCpnt->result   = DID_BUS_BUSY << 16;
+		nsp_scsi_done(SCpnt);
+		return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 
 
-	//DEBUG(0, __FUNCTION__ "() out\n");
+	//nsp_dbg(NSP_DEBUG_QUEUECOMMAND, "out");
+#ifdef NSP_DEBUG
+	data->CmdId++;
+#endif
 	return 0;
 }
 
@@ -231,7 +287,7 @@
 	unsigned int  base = data->BaseAddress;
 	unsigned char transfer_mode_reg;
 
-	//DEBUG(0, __FUNCTION__ "() enabled=%d\n", enabled);
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "enabled=%d", enabled);
 
 	if (enabled != FALSE) {
 		transfer_mode_reg = TRANSFER_GO | BRAIND;
@@ -244,37 +300,45 @@
 	nsp_index_write(base, TRANSFERMODE, transfer_mode_reg);
 }
 
+static void nsphw_init_sync(nsp_hw_data *data)
+{
+	sync_data tmp_sync = { .SyncNegotiation = SYNC_NOT_YET,
+			       .SyncPeriod      = 0,
+			       .SyncOffset      = 0
+	};
+	int i;
+
+	/* setup sync data */
+	for ( i = 0; i < NUMBER(data->Sync); i++ ) {
+		data->Sync[i] = tmp_sync;
+	}
+}
+
 /*
  * Initialize Ninja hardware
  */
 static int nsphw_init(nsp_hw_data *data)
 {
 	unsigned int base     = data->BaseAddress;
-	int	     i, j;
-	sync_data    tmp_sync = { SyncNegotiation: SYNC_NOT_YET,
-				  SyncPeriod:	   0,
-				  SyncOffset:	   0
-	};
 
-	DEBUG(0, __FUNCTION__ "() in base=0x%x\n", base);
+	nsp_dbg(NSP_DEBUG_INIT, "in base=0x%x", base);
 
-	data->ScsiClockDiv = CLOCK_40M;
+	data->ScsiClockDiv = CLOCK_40M | FAST_20;
 	data->CurrentSC    = NULL;
 	data->FifoCount    = 0;
 	data->TransferMode = MODE_IO8;
 
-	/* setup sync data */
-	for ( i = 0; i < N_TARGET; i++ ) {
-		for ( j = 0; j < N_LUN; j++ ) {
-			data->Sync[i][j] = tmp_sync;
-		}
-	}
+	nsphw_init_sync(data);
+
 
 	/* block all interrupts */
-	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLMASK);
+	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALL_CLEAR_AND_MASK);
+
+	nsp_write(base,	      IFSELECT,	    0);
+	data->ChipRev = nsp_read(base, FIFOSTATUS);
 
 	/* setup SCSI interface */
-	nsp_write(base,	      IFSELECT,	    IF_IFSEL);
+	nsp_write(base,	      IFSELECT,	    IF_REGSEL);
 
 	nsp_index_write(base, SCSIIRQMODE,  0);
 
@@ -291,7 +355,7 @@
 	nsp_write(base,	      IFSELECT,	    IF_REGSEL);
 	nsp_index_write(base, TERMPWRCTRL,  0);
 	if ((nsp_index_read(base, OTHERCONTROL) & TPWR_SENSE) == 0) {
-		printk(KERN_INFO "nsp_cs: terminator power on\n");
+		nsp_msg(KERN_INFO, "terminator power on");
 		nsp_index_write(base, TERMPWRCTRL, POWER_ON);
 	}
 
@@ -305,7 +369,7 @@
 	nsp_index_write(base, SCSIIRQMODE,  SCSI_PHASE_CHANGE_EI |
 					    RESELECT_EI		 |
 					    SCSI_RESET_IRQ_EI	 );
-	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALLCLEAR);
+	nsp_write(base,	      IRQCONTROL,   IRQCONTROL_ALL_CLEAR);
 
 	nsp_setup_fifo(data, FALSE);
 
@@ -315,110 +379,147 @@
 /*
  * Start selection phase
  */
-static unsigned int nsphw_start_selection(Scsi_Cmnd   *SCpnt,
-					  nsp_hw_data *data)
+static int nsphw_start_selection(Scsi_Cmnd *SCpnt)
 {
-	unsigned int  host_id	 = SCpnt->host->this_id;
-	unsigned int  base	 = SCpnt->host->io_port;
-	unsigned char target	 = SCpnt->target;
-	int	      wait_count;
+	unsigned int  host_id	 = SCpnt->device->host->this_id;
+	unsigned int  base	 = SCpnt->device->host->io_port;
+	unsigned char target	 = SCpnt->device->id;
+	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	int	      time_out;
 	unsigned char phase, arbit;
 
-	//DEBUG(0, __FUNCTION__ "()in\n");
+	//nsp_dbg(NSP_DEBUG_RESELECTION, "in");
 
 	phase = nsp_index_read(base, SCSIBUSMON);
 	if(phase != BUSMON_BUS_FREE) {
-		//DEBUG(0, " bus busy\n");
+		//nsp_dbg(NSP_DEBUG_RESELECTION, "bus busy");
 		return FALSE;
 	}
 
 	/* start arbitration */
-	//DEBUG(0, " start arbit\n");
+	//nsp_dbg(NSP_DEBUG_RESELECTION, "start arbit");
 	SCpnt->SCp.phase = PH_ARBSTART;
 	nsp_index_write(base, SETARBIT, ARBIT_GO);
 
-	wait_count = jiffies + 10 * HZ;
+	time_out = 1000;
 	do {
 		/* XXX: what a stupid chip! */
 		arbit = nsp_index_read(base, ARBITSTATUS);
-		//DEBUG(0, " arbit=%d, wait_count=%d\n", arbit, wait_count);
+		//nsp_dbg(NSP_DEBUG_RESELECTION, "arbit=%d, wait_count=%d", arbit, wait_count);
 		udelay(1); /* hold 1.2us */
 	} while((arbit & (ARBIT_WIN | ARBIT_FAIL)) == 0 &&
-		time_before(jiffies, wait_count));
+		(time_out-- != 0));
 
-	if((arbit & ARBIT_WIN) == 0) {
-		//DEBUG(0, " arbit fail\n");
+	if (!(arbit & ARBIT_WIN)) {
+		//nsp_dbg(NSP_DEBUG_RESELECTION, "arbit fail");
 		nsp_index_write(base, SETARBIT, ARBIT_FLAG_CLEAR);
 		return FALSE;
 	}
 
 	/* assert select line */
-	//DEBUG(0, " assert SEL line\n");
+	//nsp_dbg(NSP_DEBUG_RESELECTION, "assert SEL line");
 	SCpnt->SCp.phase = PH_SELSTART;
-	udelay(3);
-	nsp_index_write(base, SCSIDATALATCH, (1 << host_id) | (1 << target));
-	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY | SCSI_ATN);
-	udelay(3);
+	udelay(3); /* wait 2.4us */
+	nsp_index_write(base, SCSIDATALATCH, BIT(host_id) | BIT(target));
+	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY                    | SCSI_ATN);
+	udelay(2); /* wait >1.2us */
 	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_BSY | SCSI_DATAOUT_ENB | SCSI_ATN);
 	nsp_index_write(base, SETARBIT,	     ARBIT_FLAG_CLEAR);
-	udelay(3);
-	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL | SCSI_DATAOUT_ENB | SCSI_ATN);
+	/*udelay(1);*/ /* wait >90ns */
+	nsp_index_write(base, SCSIBUSCTRL,   SCSI_SEL            | SCSI_DATAOUT_ENB | SCSI_ATN);
 
 	/* check selection timeout */
-	nsp_start_timer(SCpnt, data, 1000/51);
+	nsp_start_timer(SCpnt, 1000/51);
 	data->SelectionTimeOut = 1;
 
 	return TRUE;
 }
 
+/***********************************************************************
+ * Period/AckWidth speed conversion table
+ *
+ * Note: This period/ackwidth speed table must be in descending order.
+ ***********************************************************************/
 struct nsp_sync_table {
-	unsigned int min_period;
-	unsigned int max_period;
 	unsigned int chip_period;
 	unsigned int ack_width;
+	unsigned int min_period;
+	unsigned int max_period;
 };
 
 static struct nsp_sync_table nsp_sync_table_40M[] = {
-	{0x0c,0x0c,0x1,0},	/* 20MB	 50ns*/
-	{0x19,0x19,0x3,1},	/* 10MB	 100ns*/ 
-	{0x1a,0x25,0x5,2},	/* 7.5MB 150ns*/ 
-	{0x26,0x32,0x7,3},	/* 5MB	 200ns*/
-	{0x0, 0,   0,  0}
+     /* {PNo, AW,   SP,   EP}  Speed(MB/s) Period AckWidth */
+	{0x1,  0, 0x0c, 0x0c},  /*  20.0 :  50ns,  25ns */
+	{0x2,  0, 0x0d, 0x18},  /*  13.3 :  75ns,  25ns */
+	{0x3,  1, 0x19, 0x19},  /*  10.0 : 100ns,  50ns */
+	{0x4,  1, 0x1a, 0x1f},  /*   8.0 : 125ns,  50ns */
+	{0x5,  2, 0x20, 0x25},  /*   7.5 : 150ns,  75ns */
+	{0x6,  2, 0x26, 0x31},  /*   5.71: 175ns,  75ns */
+	{0x7,  3, 0x32, 0x32},  /*   5.0 : 200ns, 100ns */
+	{0x8,  3, 0x33, 0x38},  /*   4.44: 225ns, 100ns */
+	{0x9,  3, 0x39, 0x3e},  /*   4.0 : 250ns, 100ns */
+	{0xa,  3, 0x3f, 0x44},  /*   3.64: 275ns, 100ns */
+	{0xb,  3, 0x45, 0x4b},  /*   3.33: 300ns, 100ns */
+	{0xc,  3, 0x4c, 0x53},  /*   3.01: 325ns, 100ns */
+	{0xd,  3, 0x54, 0x57},  /*   2.86: 350ns, 100ns */
+	{0xe,  3, 0x58, 0x5d},  /*   2.67: 375ns, 100ns */
+	{0xf,  3, 0x5e, 0x64},  /*   2.5 : 400ns, 100ns */
+	{0,0,0,0},
 };
 
 static struct nsp_sync_table nsp_sync_table_20M[] = {
-	{0x19,0x19,0x1,0},	/* 10MB	 100ns*/ 
-	{0x1a,0x25,0x2,0},	/* 7.5MB 150ns*/ 
-	{0x26,0x32,0x3,1},	/* 5MB	 200ns*/
-	{0x0, 0,   0,  0}
+	{0x1,  0, 0x19, 0x19},  /* 10.0 : 100ns,  50ns */
+	{0x2,  0, 0x1a, 0x25},  /*  6.7 : 150ns,  50ns */
+	{0x3,  1, 0x26, 0x32},  /*  5.0 : 200ns, 100ns */
+	{0x4,  1, 0x33, 0x3e},  /*  4.0 : 250ns, 100ns */
+	{0x5,  2, 0x3f, 0x4b},  /*  3.3 : 300ns, 150ns */
+	{0x6,  2, 0x4c, 0x57},  /*  2.8 : 350ns, 150ns */
+	{0x7,  3, 0x58, 0x64},  /*  2.5 : 400ns, 200ns */
+	{0x8,  3, 0x65, 0x70},  /*  2.2 : 450ns, 200ns */
+	{0x9,  3, 0x71, 0x7d},  /*  2.0 : 500ns, 200ns */
+	{0xa,  3, 0x7e, 0x89},  /*  1.82: 550ns, 200ns */
+	{0xb,  3, 0x8a, 0x95},  /*  1.67: 550ns, 200ns */
+	{0xc,  3, 0x96, 0xa2},  /*  1.54: 550ns, 200ns */
+	{0xd,  3, 0xa3, 0xae},  /*  1.43: 550ns, 200ns */
+	{0xe,  3, 0xaf, 0xbb},  /*  1.33: 550ns, 200ns */
+	{0xf,  3, 0xbc, 0xc8},  /*  1.25: 550ns, 200ns */
+	{0,0,0,0},
 };
 
 /*
  * setup synchronous data transfer mode
  */
-static int nsp_msg(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static int nsp_analyze_sdtr(Scsi_Cmnd *SCpnt)
 {
-	unsigned char	       target = SCpnt->target;
-	unsigned char	       lun    = SCpnt->lun;
-	sync_data	      *sync   = &(data->Sync[target][lun]);
+	unsigned char	       target = SCpnt->device->id;
+//	unsigned char	       lun    = SCpnt->device->lun;
+	nsp_hw_data           *data   = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	sync_data	      *sync   = &(data->Sync[target]);
 	struct nsp_sync_table *sync_table;
 	unsigned int	       period, offset;
 	int		       i;
 
 
-	DEBUG(0, __FUNCTION__ "()\n");
-
-/**!**/
+	nsp_dbg(NSP_DEBUG_SYNC, "in");
 
 	period = sync->SyncPeriod;
 	offset = sync->SyncOffset;
 
-	DEBUG(0, " period=0x%x, offset=0x%x\n", period, offset);
+	nsp_dbg(NSP_DEBUG_SYNC, "period=0x%x, offset=0x%x", period, offset);
 
-	if (data->ScsiClockDiv == CLOCK_20M) {
-		sync_table = &nsp_sync_table_20M[0];
-	} else {
-		sync_table = &nsp_sync_table_40M[0];
+	switch (data->ScsiClockDiv) {
+	case CLOCK_20M:
+	case CLOCK_40M:
+		sync_table = nsp_sync_table_20M;
+		break;
+	case CLOCK_40M | FAST_20:
+		sync_table = nsp_sync_table_40M;
+		break;
+	default:
+		nsp_msg(KERN_WARNING,
+			"Invalid clock div is selected, set 20M.");
+		sync_table = nsp_sync_table_20M;
+		break;
 	}
 
 	for ( i = 0; sync_table->max_period != 0; i++, sync_table++) {
@@ -432,13 +533,12 @@
 		/*
 		 * No proper period/offset found
 		 */
-		DEBUG(0, " no proper period/offset\n");
+		nsp_dbg(NSP_DEBUG_SYNC, "no proper period/offset");
 
 		sync->SyncPeriod      = 0;
 		sync->SyncOffset      = 0;
 		sync->SyncRegister    = 0;
 		sync->AckWidth	      = 0;
-		sync->SyncNegotiation = SYNC_OK;
 
 		return FALSE;
 	}
@@ -446,9 +546,8 @@
 	sync->SyncRegister    = (sync_table->chip_period << SYNCREG_PERIOD_SHIFT) |
 		                (offset & SYNCREG_OFFSET_MASK);
 	sync->AckWidth	      = sync_table->ack_width;
-	sync->SyncNegotiation = SYNC_OK;
 
-	DEBUG(0, " sync_reg=0x%x, ack_width=0x%x\n", sync->SyncRegister, sync->AckWidth);
+	nsp_dbg(NSP_DEBUG_SYNC, "sync_reg=0x%x, ack_width=0x%x", sync->SyncRegister, sync->AckWidth);
 
 	return TRUE;
 }
@@ -457,11 +556,12 @@
 /*
  * start ninja hardware timer
  */
-static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time)
+static void nsp_start_timer(Scsi_Cmnd *SCpnt, int time)
 {
-	unsigned int base = SCpnt->host->io_port;
+	unsigned int base = SCpnt->device->host->io_port;
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 
-	//DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p, time=%d\n", SCpnt, time);
+	//nsp_dbg(NSP_DEBUG_INTR, "in SCpnt=0x%p, time=%d", SCpnt, time);
 	data->TimerCount = time;
 	nsp_index_write(base, TIMERCOUNT, time);
 }
@@ -471,23 +571,23 @@
  */
 static int nsp_negate_signal(Scsi_Cmnd *SCpnt, unsigned char mask, char *str)
 {
-	unsigned int  base = SCpnt->host->io_port;
+	unsigned int  base = SCpnt->device->host->io_port;
 	unsigned char reg;
-	int	      count, i = TRUE;
+	int	      time_out;
 
-	//DEBUG(0, __FUNCTION__ "()\n");
+	//nsp_dbg(NSP_DEBUG_INTR, "in");
 
-	count = jiffies + HZ;
+	time_out = 100;
 
 	do {
 		reg = nsp_index_read(base, SCSIBUSMON);
 		if (reg == 0xff) {
 			break;
 		}
-	} while ((i = time_before(jiffies, count)) && (reg & mask) != 0);
+	} while ((time_out-- != 0) && (reg & mask) != 0);
 
-	if (!i) {
-		printk(KERN_DEBUG __FUNCTION__ " %s signal off timeut\n", str);
+	if (time_out == 0) {
+		nsp_msg(KERN_DEBUG, " %s signal off timeut", str);
 	}
 
 	return 0;
@@ -500,51 +600,52 @@
 			     unsigned char  current_phase,
 			     unsigned char  mask)
 {
-	unsigned int  base	 = SCpnt->host->io_port;
-	int	      wait_count;
+	unsigned int  base	 = SCpnt->device->host->io_port;
+	int	      time_out;
 	unsigned char phase, i_src;
 
-	//DEBUG(0, __FUNCTION__ "() current_phase=0x%x, mask=0x%x\n", current_phase, mask);
+	//nsp_dbg(NSP_DEBUG_INTR, "current_phase=0x%x, mask=0x%x", current_phase, mask);
 
-	wait_count = jiffies + HZ;
+	time_out = 100;
 	do {
 		phase = nsp_index_read(base, SCSIBUSMON);
 		if (phase == 0xff) {
-			//DEBUG(0, " ret -1\n");
+			//nsp_dbg(NSP_DEBUG_INTR, "ret -1");
 			return -1;
 		}
 		i_src = nsp_read(base, IRQSTATUS);
 		if (i_src & IRQSTATUS_SCSI) {
-			//DEBUG(0, " ret 0 found scsi signal\n");
+			//nsp_dbg(NSP_DEBUG_INTR, "ret 0 found scsi signal");
 			return 0;
 		}
 		if ((phase & mask) != 0 && (phase & BUSMON_PHASE_MASK) == current_phase) {
-			//DEBUG(0, " ret 1 phase=0x%x\n", phase);
+			//nsp_dbg(NSP_DEBUG_INTR, "ret 1 phase=0x%x", phase);
 			return 1;
 		}
-	} while(time_before(jiffies, wait_count));
+	} while(time_out-- != 0);
 
-	//DEBUG(0, __FUNCTION__ " : " __FUNCTION__ " timeout\n");
+	//nsp_dbg(NSP_DEBUG_INTR, "timeout");
 	return -1;
 }
 
 /*
  * transfer SCSI message
  */
-static int nsp_xfer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int phase)
+static int nsp_xfer(Scsi_Cmnd *SCpnt, int phase)
 {
-	unsigned int  base = SCpnt->host->io_port;
+	unsigned int  base = SCpnt->device->host->io_port;
+	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 	char	     *buf  = data->MsgBuffer;
 	int	      len  = MIN(MSGBUF_SIZE, data->MsgLen);
 	int	      ptr;
 	int	      ret;
 
-	//DEBUG(0, __FUNCTION__ "()\n");
-	for (ptr = 0; len > 0; len --, ptr ++) {
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
+	for (ptr = 0; len > 0; len--, ptr++) {
 
 		ret = nsp_expect_signal(SCpnt, phase, BUSMON_REQ);
 		if (ret <= 0) {
-			DEBUG(0, " xfer quit\n");
+			nsp_dbg(NSP_DEBUG_DATA_IO, "xfer quit");
 			return 0;
 		}
 
@@ -555,10 +656,10 @@
 
 		/* read & write message */
 		if (phase & BUSMON_IO) {
-			DEBUG(0, " read msg\n");
+			nsp_dbg(NSP_DEBUG_DATA_IO, "read msg");
 			buf[ptr] = nsp_index_read(base, SCSIDATAWITHACK);
 		} else {
-			DEBUG(0, " write msg\n");
+			nsp_dbg(NSP_DEBUG_DATA_IO, "write msg");
 			nsp_index_write(base, SCSIDATAWITHACK, buf[ptr]);
 		}
 		nsp_negate_signal(SCpnt, BUSMON_ACK, "xfer<ack>");
@@ -570,11 +671,12 @@
 /*
  * get extra SCSI data from fifo
  */
-static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static int nsp_dataphase_bypass(Scsi_Cmnd *SCpnt)
 {
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 	unsigned int count;
 
-	//DEBUG(0, __FUNCTION__ "()\n");
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "in");
 
 	if (SCpnt->SCp.have_data_in != IO_IN) {
 		return 0;
@@ -582,7 +684,7 @@
 
 	count = nsp_fifo_count(SCpnt);
 	if (data->FifoCount == count) {
-		//DEBUG(0, " not use bypass quirk\n");
+		//nsp_dbg(NSP_DEBUG_DATA_IO, "not use bypass quirk");
 		return 0;
 	}
 
@@ -590,30 +692,49 @@
 	 * XXX: NSP_QUIRK
 	 * data phase skip only occures in case of SCSI_LOW_READ
 	 */
+	nsp_dbg(NSP_DEBUG_DATA_IO, "use bypass quirk");
 	SCpnt->SCp.phase = PH_DATA;
-	nsp_pio_read(SCpnt, data);
+	nsp_pio_read(SCpnt);
 	nsp_setup_fifo(data, FALSE);
 
-	DEBUG(0, " use bypass quirk\n");
 	return 0;
 }
 
 /*
  * accept reselection
  */
-static int nsp_reselected(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static int nsp_reselected(Scsi_Cmnd *SCpnt)
 {
-	unsigned int  base = SCpnt->host->io_port;
-	unsigned char reg;
+	unsigned int  base    = SCpnt->device->host->io_port;
+	unsigned int  host_id = SCpnt->device->host->this_id;
+	//nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	unsigned char bus_reg;
+	unsigned char id_reg, tmp;
+	int target;
+
+	nsp_dbg(NSP_DEBUG_RESELECTION, "in");
+
+	id_reg = nsp_index_read(base, RESELECTID);
+	tmp    = id_reg & (~BIT(host_id));
+	target = 0;
+	while(tmp != 0) {
+		if (tmp & BIT(0)) {
+			break;
+		}
+		tmp >>= 1;
+		target++;
+	}
 
-	//DEBUG(0, __FUNCTION__ "()\n");
+	if (SCpnt->device->id != target) {
+		nsp_msg(KERN_ERR, "XXX: reselect ID must be %d in this implementation.", target);
+	}
 
 	nsp_negate_signal(SCpnt, BUSMON_SEL, "reselect<SEL>");
 
-	nsp_nexus(SCpnt, data);
-	reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
-	nsp_index_write(base, SCSIBUSCTRL, reg);
-	nsp_index_write(base, SCSIBUSCTRL, reg | AUTODIRECTION | ACKENB);
+	nsp_nexus(SCpnt);
+	bus_reg = nsp_index_read(base, SCSIBUSCTRL) & ~(SCSI_BSY | SCSI_ATN);
+	nsp_index_write(base, SCSIBUSCTRL, bus_reg);
+	nsp_index_write(base, SCSIBUSCTRL, bus_reg | AUTODIRECTION | ACKENB);
 
 	return TRUE;
 }
@@ -623,19 +744,20 @@
  */
 static int nsp_fifo_count(Scsi_Cmnd *SCpnt)
 {
-	unsigned int base = SCpnt->host->io_port;
+	unsigned int base = SCpnt->device->host->io_port;
 	unsigned int count;
-	unsigned int l, m, h;
+	unsigned int l, m, h, dummy;
 
-	nsp_index_write(base, POINTERCLR, POINTER_CLEAR);
+	nsp_index_write(base, POINTERCLR, POINTER_CLEAR | ACK_COUNTER);
 
-        l = (unsigned int)nsp_read(base, DATAREG);
-        m = (unsigned int)nsp_read(base, DATAREG);
-        h = (unsigned int)nsp_read(base, DATAREG);
+	l     = nsp_index_read(base, TRANSFERCOUNT);
+	m     = nsp_index_read(base, TRANSFERCOUNT);
+	h     = nsp_index_read(base, TRANSFERCOUNT);
+	dummy = nsp_index_read(base, TRANSFERCOUNT); /* required this! */
 
 	count = (h << 16) | (m << 8) | (l << 0);
 
-	//DEBUG(0, __FUNCTION__ "() =0x%x\n", count);
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "count=0x%x", count);
 
 	return count;
 }
@@ -647,34 +769,37 @@
 /*
  * read data in DATA IN phase
  */
-static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static void nsp_pio_read(Scsi_Cmnd *SCpnt)
 {
-	unsigned int  base     = SCpnt->host->io_port;
-	int	      time_out, i;
+	unsigned int  base      = SCpnt->device->host->io_port;
+	unsigned long mmio_base = SCpnt->device->host->base;
+	nsp_hw_data  *data      = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	long	      time_out;
 	int	      ocount, res;
 	unsigned char stat, fifo_stat;
 
 	ocount = data->FifoCount;
 
-	DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d\n", SCpnt, RESID, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
+	nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p resid=%d ocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d",
+		SCpnt, SCpnt->resid, ocount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual);
 
-	time_out = jiffies + 10 * HZ;
+	time_out = 1000;
 
-	while ((i = time_before(jiffies,time_out)) &&
+	while ((time_out-- != 0) &&
 	       (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0 ) ) {
 
 		stat = nsp_index_read(base, SCSIBUSMON);
 		stat &= BUSMON_PHASE_MASK;
 
-		res = nsp_fifo_count(SCpnt) - ocount;
 
-		//DEBUG(0, " ptr=0x%p this=0x%x ocount=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
+		res = nsp_fifo_count(SCpnt) - ocount;
+		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x ocount=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount, res);
 		if (res == 0) { /* if some data avilable ? */
 			if (stat == BUSPHASE_DATA_IN) { /* phase changed? */
-				//DEBUG(0, " wait for data this=%d\n", SCpnt->SCp.this_residual);
+				//nsp_dbg(NSP_DEBUG_DATA_IO, " wait for data this=%d", SCpnt->SCp.this_residual);
 				continue;
 			} else {
-				DEBUG(0, " phase changed stat=0x%x\n", stat);
+				nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x", stat);
 				break;
 			}
 		}
@@ -695,72 +820,93 @@
 		case MODE_IO8:
 			nsp_fifo8_read (base, SCpnt->SCp.ptr, res     );
 			break;
-		default:
-			DEBUG(0, "unknown read mode\n");
+
+		case MODE_MEM32:
+			res &= ~(BIT(1)|BIT(0)); /* align 4 */
+			nsp_mmio_fifo32_read(mmio_base, SCpnt->SCp.ptr, res >> 2);
 			break;
+
+		default:
+			nsp_dbg(NSP_DEBUG_DATA_IO, "unknown read mode");
+			return;
 		}
 
-		RESID			 -= res;
+		SCpnt->resid	       	 -= res;
 		SCpnt->SCp.ptr		 += res;
 		SCpnt->SCp.this_residual -= res;
 		ocount			 += res;
-		//DEBUG(0, " ptr=0x%p this_residual=0x%x ocount=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
+		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this_residual=0x%x ocount=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, ocount);
 
 		/* go to next scatter list if available */
 		if (SCpnt->SCp.this_residual	== 0 &&
 		    SCpnt->SCp.buffers_residual != 0 ) {
-			//DEBUG(0, " scatterlist next timeout=%d\n", time_out);
+			//nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next timeout=%d", time_out);
 			SCpnt->SCp.buffers_residual--;
 			SCpnt->SCp.buffer++;
-			SCpnt->SCp.ptr		 = SCpnt->SCp.buffer->address;
+			SCpnt->SCp.ptr		 = SG_ADDRESS(SCpnt->SCp.buffer);
 			SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
-		}
+			time_out = 1000;
 
-		time_out = jiffies + 10 * HZ;
+			//nsp_dbg(NSP_DEBUG_DATA_IO, "page: 0x%p, off: 0x%x", SCpnt->SCp.buffer->page, SCpnt->SCp.buffer->offset);
+		}
 	}
 
 	data->FifoCount = ocount;
 
-	if (!i) {
-		printk(KERN_DEBUG __FUNCTION__ "() pio read timeout resid=%d this_residual=%d buffers_residual=%d\n", RESID, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
+	if (time_out == 0) {
+		nsp_msg(KERN_DEBUG, "pio read timeout resid=%d this_residual=%d buffers_residual=%d",
+			SCpnt->resid, SCpnt->SCp.this_residual, SCpnt->SCp.buffers_residual);
 	}
-	DEBUG(0, " read ocount=0x%x\n", ocount);
+	nsp_dbg(NSP_DEBUG_DATA_IO, "read ocount=0x%x", ocount);
+	nsp_dbg(NSP_DEBUG_DATA_IO, "r cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
 }
 
 /*
  * write data in DATA OUT phase
  */
-static void nsp_pio_write(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static void nsp_pio_write(Scsi_Cmnd *SCpnt)
 {
-	unsigned int  base     = SCpnt->host->io_port;
-	int	      time_out, i;
-	unsigned int  ocount, res;
+	unsigned int  base      = SCpnt->device->host->io_port;
+	unsigned long mmio_base = SCpnt->device->host->base;
+	nsp_hw_data  *data      = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	int	      time_out;
+	int           ocount, res;
 	unsigned char stat;
 
 	ocount	 = data->FifoCount;
 
-	DEBUG(0, __FUNCTION__ "() in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x\n", data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, RESID);
+	nsp_dbg(NSP_DEBUG_DATA_IO, "in fifocount=%d ptr=0x%p this_residual=%d buffers=0x%p nbuf=%d resid=0x%x",
+		data->FifoCount, SCpnt->SCp.ptr, SCpnt->SCp.this_residual, SCpnt->SCp.buffer, SCpnt->SCp.buffers_residual, SCpnt->resid);
 
-	time_out = jiffies + 10 * HZ;
+	time_out = 1000;
 
-	while ((i = time_before(jiffies, time_out))                             &&
+	while ((time_out-- != 0) &&
 	       (SCpnt->SCp.this_residual > 0 || SCpnt->SCp.buffers_residual > 0)) {
 		stat = nsp_index_read(base, SCSIBUSMON);
 		stat &= BUSMON_PHASE_MASK;
+
 		if (stat != BUSPHASE_DATA_OUT) {
-			DEBUG(0, " phase changed stat=0x%x\n", stat);
+			res = ocount - nsp_fifo_count(SCpnt);
+
+			nsp_dbg(NSP_DEBUG_DATA_IO, "phase changed stat=0x%x, res=%d\n", stat, res);
+			/* Put back pointer */
+			SCpnt->resid	       	 += res;
+			SCpnt->SCp.ptr		 -= res;
+			SCpnt->SCp.this_residual += res;
+			ocount			 -= res;
+
 			break;
 		}
 
 		res = ocount - nsp_fifo_count(SCpnt);
 		if (res > 0) { /* write all data? */
-			DEBUG(0, " wait for all data out. ocount=0x%x res=%d\n", ocount, res);
+			nsp_dbg(NSP_DEBUG_DATA_IO, "wait for all data out. ocount=0x%x res=%d", ocount, res);
 			continue;
 		}
 
 		res = MIN(SCpnt->SCp.this_residual, WFIFO_CRIT);
 
-		//DEBUG(0, " ptr=0x%p this=0x%x res=0x%x\n", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
+		//nsp_dbg(NSP_DEBUG_DATA_IO, "ptr=0x%p this=0x%x res=0x%x", SCpnt->SCp.ptr, SCpnt->SCp.this_residual, res);
 		switch (data->TransferMode) {
 		case MODE_IO32:
 			res &= ~(BIT(1)|BIT(0)); /* align 4 */
@@ -769,12 +915,18 @@
 		case MODE_IO8:
 			nsp_fifo8_write (base, SCpnt->SCp.ptr, res     );
 			break;
+
+		case MODE_MEM32:
+			res &= ~(BIT(1)|BIT(0)); /* align 4 */
+			nsp_mmio_fifo32_write(mmio_base, SCpnt->SCp.ptr, res >> 2);
+			break;
+
 		default:
-			DEBUG(0, "unknown write mode\n");
+			nsp_dbg(NSP_DEBUG_DATA_IO, "unknown write mode");
 			break;
 		}
 
-		RESID			 -= res;
+		SCpnt->resid	       	 -= res;
 		SCpnt->SCp.ptr		 += res;
 		SCpnt->SCp.this_residual -= res;
 		ocount			 += res;
@@ -782,55 +934,60 @@
 		/* go to next scatter list if available */
 		if (SCpnt->SCp.this_residual	== 0 &&
 		    SCpnt->SCp.buffers_residual != 0 ) {
-			//DEBUG(0, " scatterlist next\n");
+			//nsp_dbg(NSP_DEBUG_DATA_IO, "scatterlist next");
 			SCpnt->SCp.buffers_residual--;
 			SCpnt->SCp.buffer++;
-			SCpnt->SCp.ptr		 = SCpnt->SCp.buffer->address;
+			SCpnt->SCp.ptr		 = SG_ADDRESS(SCpnt->SCp.buffer);
 			SCpnt->SCp.this_residual = SCpnt->SCp.buffer->length;
+			time_out = 1000;
 		}
-
-		time_out = jiffies + 10 * HZ;
 	}
 
 	data->FifoCount = ocount;
 
-	if (!i) {
-		printk(KERN_DEBUG __FUNCTION__ "() pio write timeout resid=%d\n", RESID);
+	if (time_out == 0) {
+		nsp_msg(KERN_DEBUG, "pio write timeout resid=0x%x", SCpnt->resid);
 	}
-	//DEBUG(0, " write ocount=%d\n", ocount);
+	nsp_dbg(NSP_DEBUG_DATA_IO, "write ocount=0x%x", ocount);
+	nsp_dbg(NSP_DEBUG_DATA_IO, "w cmd=%d resid=0x%x\n", data->CmdId, SCpnt->resid);
 }
-
 #undef RFIFO_CRIT
 #undef WFIFO_CRIT
 
 /*
  * setup synchronous/asynchronous data transfer mode
  */
-static int nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static int nsp_nexus(Scsi_Cmnd *SCpnt)
 {
-	unsigned int   base   = SCpnt->host->io_port;
-	unsigned char  target = SCpnt->target;
-	unsigned char  lun    = SCpnt->lun;
-	sync_data     *sync   = &(data->Sync[target][lun]);
+	unsigned int   base   = SCpnt->device->host->io_port;
+	unsigned char  target = SCpnt->device->id;
+//	unsigned char  lun    = SCpnt->device->lun;
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+	sync_data     *sync   = &(data->Sync[target]);
 
-	//DEBUG(0, __FUNCTION__ "() in SCpnt=0x%p\n", SCpnt);
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "in SCpnt=0x%p", SCpnt);
 
 	/* setup synch transfer registers */
 	nsp_index_write(base, SYNCREG,	sync->SyncRegister);
 	nsp_index_write(base, ACKWIDTH, sync->AckWidth);
 
-	if (RESID % 4 != 0   ||
-	    RESID     <= 256 ) {
+	if (SCpnt->use_sg    == 0        ||
+	    SCpnt->resid % 4 != 0        ||
+	    SCpnt->resid     <= PAGE_SIZE ) {
 		data->TransferMode = MODE_IO8;
-	} else {
+	} else if (nsp_burst_mode == BURST_MEM32) {
+		data->TransferMode = MODE_MEM32;
+	} else if (nsp_burst_mode == BURST_IO32) {
 		data->TransferMode = MODE_IO32;
+	} else {
+		data->TransferMode = MODE_IO8;
 	}
 
 	/* setup pdma fifo */
 	nsp_setup_fifo(data, TRUE);
 
 	/* clear ack counter */
-	data->FifoCount = 0;
+ 	data->FifoCount = 0;
 	nsp_index_write(base, POINTERCLR, POINTER_CLEAR	    |
 					  ACK_COUNTER_CLEAR |
 					  REQ_COUNTER_CLEAR |
@@ -843,111 +1000,126 @@
 /*
  * interrupt handler
  */
-static void nspintr(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned int   base;
-	unsigned char  i_src, irq_phase, phase;
+	unsigned char  irq_status, irq_phase, phase;
 	Scsi_Cmnd     *tmpSC;
-	int            len;
 	unsigned char  target, lun;
 	unsigned int  *sync_neg;
 	int            i, tmp;
+	unsigned long  flags;
 	nsp_hw_data   *data;
+	int            handled = 0;
 
-	//printk("&nsp_data=0x%p, dev_id=0x%p\n", &nsp_data, dev_id);
+	//nsp_dbg(NSP_DEBUG_INTR, "dev_id=0x%p", dev_id);
+	//nsp_dbg(NSP_DEBUG_INTR, "host=0x%p", ((scsi_info_t *)dev_id)->host);
 
-	/* sanity check */
-	if (&nsp_data != dev_id) {
-		DEBUG(0, " irq conflict? this can't happen\n");
-		return;
-	}
-	data = dev_id;
-	if (irq != data->IrqNumber) {
-		return;
+	if (                dev_id        != NULL &&
+	    ((scsi_info_t *)dev_id)->host != NULL  ) {
+		scsi_info_t *info = (scsi_info_t *)dev_id;
+
+		data = (nsp_hw_data *)(info->host->hostdata);
+	} else {
+		nsp_dbg(NSP_DEBUG_INTR, "host data wrong");
+		return IRQ_NONE;
 	}
 
+        spin_lock_irqsave(HOST_LOCK, flags);
+
+	//nsp_dbg(NSP_DEBUG_INTR, "&nsp_data_base=0x%p, dev_id=0x%p", &nsp_data_base, dev_id);
+
 	base = data->BaseAddress;
-	//DEBUG(0, " base=0x%x\n", base);
+	//nsp_dbg(NSP_DEBUG_INTR, "base=0x%x", base);
 
 	/*
 	 * interrupt check
 	 */
-	nsp_write(base, IRQCONTROL, IRQCONTROL_IRQDISABLE);
-	i_src = nsp_read(base, IRQSTATUS);
-	if (i_src == 0xff || (i_src & IRQSTATUS_MASK) == 0) {
-		nsp_write(base, IRQCONTROL, 0);
-		//DEBUG(0, " no irq\n");
-		return;
+	nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_MASK);
+	irq_status = nsp_read(base, IRQSTATUS);
+	//nsp_dbg(NSP_DEBUG_INTR, "irq_status=0x%x", irq_status);
+	if ((irq_status == 0xff) || ((irq_status & IRQSTATUS_MASK) == 0)) {
+		//nsp_dbg(NSP_DEBUG_INTR, "no irq/shared irq");
+		goto out;
 	}
-
-	//DEBUG(0, " i_src=0x%x\n", i_src);
+	handled = 1;
 
 	/* XXX: IMPORTANT
 	 * Do not read an irq_phase register if no scsi phase interrupt.
 	 * Unless, you should lose a scsi phase interrupt.
 	 */
 	phase = nsp_index_read(base, SCSIBUSMON);
-	if((i_src & IRQSTATUS_SCSI) != 0) {
+	if((irq_status & IRQSTATUS_SCSI) != 0) {
 		irq_phase = nsp_index_read(base, IRQPHASESENCE);
 	} else {
 		irq_phase = 0;
 	}
 
-	//DEBUG(0, " irq_phase=0x%x\n", irq_phase);
+	//nsp_dbg(NSP_DEBUG_INTR, "irq_phase=0x%x", irq_phase);
 
 	/*
 	 * timer interrupt handler (scsi vs timer interrupts)
 	 */
-	//DEBUG(0, " timercount=%d\n", data->TimerCount);
+	//nsp_dbg(NSP_DEBUG_INTR, "timercount=%d", data->TimerCount);
 	if (data->TimerCount != 0) {
-		//DEBUG(0, " stop timer\n");
+		//nsp_dbg(NSP_DEBUG_INTR, "stop timer");
 		nsp_index_write(base, TIMERCOUNT, 0);
 		nsp_index_write(base, TIMERCOUNT, 0);
 		data->TimerCount = 0;
 	}
 
-	if ((i_src & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
+	if ((irq_status & IRQSTATUS_MASK) == IRQSTATUS_TIMER &&
 	    data->SelectionTimeOut == 0) {
-		//DEBUG(0, " timer start\n");
+		//nsp_dbg(NSP_DEBUG_INTR, "timer start");
 		nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR);
-		return;
+		goto out;
 	}
 
 	nsp_write(base, IRQCONTROL, IRQCONTROL_TIMER_CLEAR | IRQCONTROL_FIFO_CLEAR);
 
+	if ((irq_status & IRQSTATUS_SCSI) &&
+	    (irq_phase  & SCSI_RESET_IRQ)) {
+		nsp_msg(KERN_ERR, "bus reset (power off?)");
+
+		nsphw_init(data);
+		nsp_bus_reset(data);
+
+		if(data->CurrentSC != NULL) {
+			tmpSC = data->CurrentSC;
+			tmpSC->result  = (DID_RESET                   << 16) |
+				         ((tmpSC->SCp.Message & 0xff) <<  8) |
+				         ((tmpSC->SCp.Status  & 0xff) <<  0);
+			nsp_scsi_done(tmpSC);
+		}
+		goto out;
+	}
+
 	if (data->CurrentSC == NULL) {
-		printk(KERN_DEBUG __FUNCTION__ " CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen\n", i_src, phase, irq_phase);
-		return;
-	} else {
-		tmpSC    = data->CurrentSC;
-		target   = tmpSC->target;
-		lun      = tmpSC->lun;
-		sync_neg = &(data->Sync[target][lun].SyncNegotiation);
+		nsp_msg(KERN_ERR, "CurrentSC==NULL irq_status=0x%x phase=0x%x irq_phase=0x%x this can't be happen. reset everything", irq_status, phase, irq_phase);
+		nsphw_init(data);
+		nsp_bus_reset(data);
+		goto out;
 	}
 
+	tmpSC    = data->CurrentSC;
+	target   = tmpSC->device->id;
+	lun      = tmpSC->device->lun;
+	sync_neg = &(data->Sync[target].SyncNegotiation);
+
 	/*
 	 * parse hardware SCSI irq reasons register
 	 */
-	if ((i_src & IRQSTATUS_SCSI) != 0) {
-		if ((irq_phase & SCSI_RESET_IRQ) != 0) {
-			printk(KERN_DEBUG " " __FUNCTION__ "() bus reset (power off?)\n");
-			*sync_neg          = SYNC_NOT_YET;
-			data->CurrentSC    = NULL;
-			tmpSC->result	   = DID_RESET << 16;
-			tmpSC->scsi_done(tmpSC);
-			return;
-		}
-
-		if ((irq_phase & RESELECT_IRQ) != 0) {
-			DEBUG(0, " reselect\n");
+	if (irq_status & IRQSTATUS_SCSI) {
+		if (irq_phase & RESELECT_IRQ) {
+			nsp_dbg(NSP_DEBUG_INTR, "reselect");
 			nsp_write(base, IRQCONTROL, IRQCONTROL_RESELECT_CLEAR);
-			if (nsp_reselected(tmpSC, data) != FALSE) {
-				return;
+			if (nsp_reselected(tmpSC) != FALSE) {
+				goto out;
 			}
 		}
 
 		if ((irq_phase & (PHASE_CHANGE_IRQ | LATCHED_BUS_FREE)) == 0) {
-			return; 
+			goto out;
 		}
 	}
 
@@ -955,50 +1127,48 @@
 
 	switch(tmpSC->SCp.phase) {
 	case PH_SELSTART:
-		*sync_neg = SYNC_NOT_YET;
+		// *sync_neg = SYNC_NOT_YET;
 		if ((phase & BUSMON_BSY) == 0) {
-			//DEBUG(0, " selection count=%d\n", data->SelectionTimeOut);
+			//nsp_dbg(NSP_DEBUG_INTR, "selection count=%d", data->SelectionTimeOut);
 			if (data->SelectionTimeOut >= NSP_SELTIMEOUT) {
-				DEBUG(0, " selection time out\n");
+				nsp_dbg(NSP_DEBUG_INTR, "selection time out");
 				data->SelectionTimeOut = 0;
 				nsp_index_write(base, SCSIBUSCTRL, 0);
 
-				data->CurrentSC = NULL;
-				tmpSC->result   = DID_NO_CONNECT << 16;
-				tmpSC->scsi_done(tmpSC);
+				tmpSC->result   = DID_TIME_OUT << 16;
+				nsp_scsi_done(tmpSC);
 
-				return;
+				goto out;
 			}
 			data->SelectionTimeOut += 1;
-			nsp_start_timer(tmpSC, data, 1000/51);
-			return;
+			nsp_start_timer(tmpSC, 1000/51);
+			goto out;
 		}
 
 		/* attention assert */
-		//DEBUG(0, " attention assert\n");
+		//nsp_dbg(NSP_DEBUG_INTR, "attention assert");
 		data->SelectionTimeOut = 0;
 		tmpSC->SCp.phase       = PH_SELECTED;
 		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN);
 		udelay(1);
 		nsp_index_write(base, SCSIBUSCTRL, SCSI_ATN | AUTODIRECTION | ACKENB);
-		return;
+		goto out;
 
 		break;
 
 	case PH_RESELECT:
-		//DEBUG(0, " phase reselect\n");
-		*sync_neg = SYNC_NOT_YET;
+		//nsp_dbg(NSP_DEBUG_INTR, "phase reselect");
+		// *sync_neg = SYNC_NOT_YET;
 		if ((phase & BUSMON_PHASE_MASK) != BUSPHASE_MESSAGE_IN) {
 
-			data->CurrentSC = NULL;
 			tmpSC->result	= DID_ABORT << 16;
-			tmpSC->scsi_done(tmpSC);
-			return;
+			nsp_scsi_done(tmpSC);
+			goto out;
 		}
 		/* fall thru */
 	default:
-		if ((i_src & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
-			return;
+		if ((irq_status & (IRQSTATUS_SCSI | IRQSTATUS_FIFO)) == 0) {
+			goto out;
 		}
 		break;
 	}
@@ -1006,140 +1176,153 @@
 	/*
 	 * SCSI sequencer
 	 */
-	//DEBUG(0, " start scsi seq\n");
+	//nsp_dbg(NSP_DEBUG_INTR, "start scsi seq");
 
 	/* normal disconnect */
-	if ((irq_phase & LATCHED_BUS_FREE) != 0) {
-		//DEBUG(0, " normal disconnect i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
+	if (((tmpSC->SCp.phase == PH_MSG_IN) || (tmpSC->SCp.phase == PH_MSG_OUT)) &&
+	    (irq_phase & LATCHED_BUS_FREE) != 0 ) {
+		nsp_dbg(NSP_DEBUG_INTR, "normal disconnect irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
+
+		// *sync_neg       = SYNC_NOT_YET;
+
 		if ((tmpSC->SCp.Message == MSG_COMMAND_COMPLETE)) {     /* all command complete and return status */
-			*sync_neg       = SYNC_NOT_YET;
-			data->CurrentSC = NULL;
-			tmpSC->result = (DID_OK		    << 16) |
-					(tmpSC->SCp.Message <<	8) |
-					(tmpSC->SCp.Status  <<	0);
-			DEBUG(0, " command complete result=0x%x\n", tmpSC->result);
-			tmpSC->scsi_done(tmpSC);
-			return;
+			tmpSC->result = (DID_OK		             << 16) |
+					((tmpSC->SCp.Message & 0xff) <<  8) |
+					((tmpSC->SCp.Status  & 0xff) <<  0);
+			nsp_dbg(NSP_DEBUG_INTR, "command complete result=0x%x", tmpSC->result);
+			nsp_scsi_done(tmpSC);
+
+			goto out;
 		}
 
-		return;
+		goto out;
 	}
 
 
 	/* check unexpected bus free state */
 	if (phase == 0) {
-		printk(KERN_DEBUG " " __FUNCTION__ " unexpected bus free. i_src=0x%x, phase=0x%x, irq_phase=0x%x\n", i_src, phase, irq_phase);
+		nsp_msg(KERN_DEBUG, "unexpected bus free. irq_status=0x%x, phase=0x%x, irq_phase=0x%x", irq_status, phase, irq_phase);
 
-		*sync_neg       = SYNC_NOT_YET;
-		data->CurrentSC = NULL;
+		*sync_neg       = SYNC_NG;
 		tmpSC->result   = DID_ERROR << 16;
-		tmpSC->scsi_done(tmpSC);
-		return;
+		nsp_scsi_done(tmpSC);
+		goto out;
 	}
 
 	switch (phase & BUSMON_PHASE_MASK) {
 	case BUSPHASE_COMMAND:
-		DEBUG(0, " BUSPHASE_COMMAND\n");
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_COMMAND");
 		if ((phase & BUSMON_REQ) == 0) {
-			DEBUG(0, " REQ == 0\n");
-			return;
+			nsp_dbg(NSP_DEBUG_INTR, "REQ == 0");
+			goto out;
 		}
 
 		tmpSC->SCp.phase = PH_COMMAND;
 
-		nsp_nexus(tmpSC, data);
+		nsp_nexus(tmpSC);
 
 		/* write scsi command */
+		nsp_dbg(NSP_DEBUG_INTR, "cmd_len=%d", tmpSC->cmd_len);
 		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER);
-		for (len = 0; len < COMMAND_SIZE(tmpSC->cmnd[0]); len++) {
-			nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[len]);
+		for (i = 0; i < tmpSC->cmd_len; i++) {
+			nsp_index_write(base, COMMANDDATA, tmpSC->cmnd[i]);
 		}
 		nsp_index_write(base, COMMANDCTRL, CLEAR_COMMAND_POINTER | AUTO_COMMAND_GO);
 		break;
 
 	case BUSPHASE_DATA_OUT:
-		DEBUG(0, " BUSPHASE_DATA_OUT\n");
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_OUT");
 
-		tmpSC->SCp.phase = PH_DATA;
+		tmpSC->SCp.phase        = PH_DATA;
 		tmpSC->SCp.have_data_in = IO_OUT;
 
-		nsp_pio_write(tmpSC, data);
+		nsp_pio_write(tmpSC);
 
 		break;
 
 	case BUSPHASE_DATA_IN:
-		DEBUG(0, " BUSPHASE_DATA_IN\n");
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_DATA_IN");
 
-		tmpSC->SCp.phase = PH_DATA;
+		tmpSC->SCp.phase        = PH_DATA;
 		tmpSC->SCp.have_data_in = IO_IN;
 
-		nsp_pio_read(tmpSC, data);
+		nsp_pio_read(tmpSC);
 
 		break;
 
 	case BUSPHASE_STATUS:
-		nsp_dataphase_bypass(tmpSC, data);
-		DEBUG(0, " BUSPHASE_STATUS\n");
+		nsp_dataphase_bypass(tmpSC);
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_STATUS");
 
 		tmpSC->SCp.phase = PH_STATUS;
 
 		tmpSC->SCp.Status = nsp_index_read(base, SCSIDATAWITHACK);
-		//DEBUG(0, " message=0x%x status=0x%x\n", tmpSC->SCp.Message, tmpSC->SCp.Status);
+		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x status=0x%x", tmpSC->SCp.Message, tmpSC->SCp.Status);
 
 		break;
 
 	case BUSPHASE_MESSAGE_OUT:
-		DEBUG(0, " BUSPHASE_MESSAGE_OUT\n");
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_OUT");
 		if ((phase & BUSMON_REQ) == 0) {
 			goto timer_out;
 		}
 
 		tmpSC->SCp.phase = PH_MSG_OUT;
 
-		data->MsgLen = len = 0;
+		// *sync_neg = SYNC_NOT_YET;
+
+		data->MsgLen = i = 0;
+		data->MsgBuffer[i] = IDENTIFY(TRUE, lun); i++;
+
 		if (*sync_neg == SYNC_NOT_YET) {
-			data->Sync[target][lun].SyncPeriod = 0;
-			data->Sync[target][lun].SyncOffset = 0;
-			nsp_msg(tmpSC, data);
-
-			data->MsgBuffer[len] = IDENTIFY(TRUE, lun); len++;
-			/*
-			data->MsgBuffer[len] = MSG_EXTENDED;        len++;
-			data->MsgBuffer[len] = 3;                   len++;
-			data->MsgBuffer[len] = MSG_EXT_SDTR;        len++;
-			data->MsgBuffer[len] = 0x0c;                len++;
-			data->MsgBuffer[len] = 15;                  len++;
-			*/
-		}
-		if (len == 0) {
-			data->MsgBuffer[len] = MSG_NO_OPERATION; len++;
+			data->Sync[target].SyncPeriod = 0;
+			data->Sync[target].SyncOffset = 0;
+
+			/**/
+			data->MsgBuffer[i] = MSG_EXTENDED; i++;
+			data->MsgBuffer[i] = 3;            i++;
+			data->MsgBuffer[i] = MSG_EXT_SDTR; i++;
+			data->MsgBuffer[i] = 0x0c;         i++;
+			data->MsgBuffer[i] = 15;           i++;
+			/**/
 		}
-		data->MsgLen = len;
+		data->MsgLen = i;
 
+		nsp_analyze_sdtr(tmpSC);
 		show_message(data);
-		nsp_message_out(tmpSC, data);
+		nsp_message_out(tmpSC);
 		break;
 
 	case BUSPHASE_MESSAGE_IN:
-		nsp_dataphase_bypass(tmpSC, data);
-		DEBUG(0, " BUSPHASE_MESSAGE_IN\n");
+		nsp_dataphase_bypass(tmpSC);
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE_MESSAGE_IN");
 		if ((phase & BUSMON_REQ) == 0) {
 			goto timer_out;
 		}
 
 		tmpSC->SCp.phase = PH_MSG_IN;
-		nsp_message_in(tmpSC, data);
+		nsp_message_in(tmpSC);
 
-		/*
-		if (data->MsgLen       >= 5            &&
-		    data->MsgBuffer[0] == MSG_EXTENDED &&
-		    data->MsgBuffer[1] == 3            &&
-		    data->MsgBuffer[2] == MSG_EXT_SDTR ) {
-			data->Sync[target][lun].SyncPeriod = data->MsgBuffer[3];
-			data->Sync[target][lun].SyncOffset = data->MsgBuffer[4];
-			nsp_msg(tmpSC, data);
+		/**/
+		if (*sync_neg == SYNC_NOT_YET) {
+			//nsp_dbg(NSP_DEBUG_INTR, "sync target=%d,lun=%d",target,lun);
+
+			if (data->MsgLen       >= 5            &&
+			    data->MsgBuffer[0] == MSG_EXTENDED &&
+			    data->MsgBuffer[1] == 3            &&
+			    data->MsgBuffer[2] == MSG_EXT_SDTR ) {
+				data->Sync[target].SyncPeriod = data->MsgBuffer[3];
+				data->Sync[target].SyncOffset = data->MsgBuffer[4];
+				//nsp_dbg(NSP_DEBUG_INTR, "sync ok, %d %d", data->MsgBuffer[3], data->MsgBuffer[4]);
+				*sync_neg = SYNC_OK;
+			} else {
+				data->Sync[target].SyncPeriod = 0;
+				data->Sync[target].SyncOffset = 0;
+				*sync_neg = SYNC_NG;
+			}
+			nsp_analyze_sdtr(tmpSC);
 		}
-		*/
+		/**/
 
 		/* search last messeage byte */
 		tmp = -1;
@@ -1151,134 +1334,291 @@
 		}
 		tmpSC->SCp.Message = tmp;
 
-		DEBUG(0, " message=0x%x len=%d\n", tmpSC->SCp.Message, data->MsgLen);
+		nsp_dbg(NSP_DEBUG_INTR, "message=0x%x len=%d", tmpSC->SCp.Message, data->MsgLen);
 		show_message(data);
 
 		break;
 
 	case BUSPHASE_SELECT:
 	default:
-		DEBUG(0, " BUSPHASE other\n");
+		nsp_dbg(NSP_DEBUG_INTR, "BUSPHASE other");
 
 		break;
 	}
 
-	//DEBUG(0, __FUNCTION__ "() out\n");
-	return;	
+	goto out;
+
 
 timer_out:
-	nsp_start_timer(tmpSC, data, 1000/102);
-	return;
+	nsp_start_timer(tmpSC, 1000/102);
+ out:
+	nsp_write(base, IRQCONTROL, 0); /* clear IRQ mask */
+        spin_unlock_irqrestore(HOST_LOCK, flags);
+	//nsp_dbg(NSP_DEBUG_INTR, "out");
+	return IRQ_RETVAL(handled);
 }
 
-#ifdef PCMCIA_DEBUG
-#include "nsp_debug.c"
-#endif	/* DBG_SHOWCOMMAND */
 
 /*----------------------------------------------------------------*/
 /* look for ninja3 card and init if found			  */
 /*----------------------------------------------------------------*/
-static int nsp_detect(Scsi_Host_Template *sht)
+static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht)
 {
 	struct Scsi_Host *host;	/* registered host structure */
-	nsp_hw_data *data = &nsp_data;
+	nsp_hw_data *data;
 
-	DEBUG(0, __FUNCTION__ " this_id=%d\n", sht->this_id);
+	nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data));
+#else
+	host = scsi_register(sht, sizeof(nsp_hw_data));
+#endif
+	if (host == NULL) {
+		nsp_dbg(NSP_DEBUG_INIT, "host failed");
+		return NULL;
+	}
 
-	request_region(data->BaseAddress, data->NumAddress, "nsp_cs");
-	host		  = scsi_register(sht, 0);
-	host->io_port	  = data->BaseAddress;
-	host->unique_id	  = data->BaseAddress;
-	host->n_io_port	  = data->NumAddress;
-	host->irq	  = data->IrqNumber;
-	host->dma_channel = 0xff;             /* not use dms */
+	/* Copy global variable to driver specific area */
+	data  = (nsp_hw_data *)host->hostdata;
+	*data = nsp_data_base;
+
+	data->ScsiInfo->host = host;
+#ifdef NSP_DEBUG
+	data->CmdId = 0;
+#endif
 
-	sprintf(nspinfo,
-/* Buffer size is 100 bytes */
-/*  0         1         2         3         4         5         6         7         8         9         0*/
-/*  01234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890*/
-   "NinjaSCSI-3/32Bi Driver $Revision: 1.42 $, I/O 0x%04lx-0x%04lx IRQ %2d",
-		host->io_port, host->io_port + host->n_io_port,
-		host->irq);
-	sht->name	  = nspinfo;
+	nsp_dbg(NSP_DEBUG_INIT, "irq base=0x%p,%d data=0x%p,%d", &nsp_data_base, (&nsp_data_base)->IrqNumber, data, data->IrqNumber);
 
-	DEBUG(0, __FUNCTION__ " end\n");
+	host->unique_id	= data->BaseAddress;
+	host->io_port   = data->BaseAddress;
+	host->n_io_port	= data->NumAddress;
+	host->irq       = data->IrqNumber;
+	host->base      = data->MmioAddress;
 
-	return 1; /* detect done. */
+	spin_lock_init(&(data->Lock));
+
+	snprintf(data->nspinfo,
+		 sizeof(data->nspinfo),
+		 "NinjaSCSI-3/32Bi Driver $Revision: 1.25 $ IO:0x%04lx-0x%04lx MMIO(virt addr):0x%04lx IRQ:%02d",
+		 host->io_port, host->io_port + host->n_io_port - 1,
+		 host->base,
+		 host->irq);
+	sht->name = data->nspinfo;
+
+	nsp_dbg(NSP_DEBUG_INIT, "end");
+
+
+	return host; /* detect done. */
 }
 
-/* nsp_cs requires own release handler because its uses dev_id (=data) */
-static int nsp_release(struct Scsi_Host *shpnt)
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+/*----------------------------------------*/
+/* Compatibility functions for 2.4 kernel */
+/*----------------------------------------*/
+static int nsp_detect_old(Scsi_Host_Template *sht)
 {
-	nsp_hw_data *data = &nsp_data;
-
-        if (shpnt->irq) {
-                free_irq(shpnt->irq, data);
-	}
-        if (shpnt->io_port && shpnt->n_io_port) {
-		release_region(shpnt->io_port, shpnt->n_io_port);
+	if (nsp_detect(sht) == NULL) {
+		return 0;
+	} else {
+		return 1; /* detects 1 Ninja host card */
 	}
+}
+
+static int nsp_release_old(struct Scsi_Host *shpnt)
+{
+	//nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
+
+	/* PCMCIA Card Service dose same things below. */
+	/* So we do nothing.                           */
+	//if (shpnt->irq) {
+	//	free_irq(shpnt->irq, data->ScsiInfo);
+	//}
+	//if (shpnt->io_port) {
+	//	release_region(shpnt->io_port, shpnt->n_io_port);
+	//}
+
 	return 0;
 }
+#endif
 
 /*----------------------------------------------------------------*/
 /* return info string						  */
 /*----------------------------------------------------------------*/
 static const char *nsp_info(struct Scsi_Host *shpnt)
 {
-	return nspinfo;
+	nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata;
+
+	return data->nspinfo;
 }
 
-/*---------------------------------------------------------------*/
-/* error handler                                                 */
-/*---------------------------------------------------------------*/
-static int nsp_reset(Scsi_Cmnd *SCpnt, unsigned int why)
+#undef SPRINTF
+#define SPRINTF(args...) \
+        do { \
+		if(length > (pos - buffer)) { \
+			pos += snprintf(pos, length - (pos - buffer) + 1, ## args); \
+			nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length,  length - (pos - buffer));\
+		} \
+	} while(0)
+
+/* Shows Ninja host card information for user. */
+static int
+nsp_proc_info(
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	struct Scsi_Host *host,
+#endif
+	char  *buffer,
+	char **start,
+	off_t  offset,
+	int    length,
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	int    hostno,
+#endif
+	int    inout)
 {
-	DEBUG(0, __FUNCTION__ " SCpnt=0x%p why=%d\n", SCpnt, why);
+	int id;
+	char *pos = buffer;
+	int thislength;
+	int speed;
+	unsigned long flags;
+	nsp_hw_data *data;
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	struct Scsi_Host *host;
+#else
+	int hostno;
+#endif
+	if (inout) {
+		return -EINVAL;
+	}
 
-	nsp_eh_bus_reset(SCpnt);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	hostno = host->host_no;
+#else
+	/* search this HBA host */
+	host = scsi_host_hn_get(hostno);
+	if (host == NULL) {
+		return -ESRCH;
+	}
+#endif
+	data = (nsp_hw_data *)host->hostdata;
 
-	return SCSI_RESET_SUCCESS;
-}
 
-static int nsp_abort(Scsi_Cmnd *SCpnt)
-{
-	DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
+	SPRINTF("NinjaSCSI status\n\n");
+	SPRINTF("Driver version:        $Revision: 1.25 $\n");
+	SPRINTF("SCSI host No.:         %d\n",          hostno);
+	SPRINTF("IRQ:                   %d\n",          host->irq);
+	SPRINTF("IO:                    0x%lx-0x%lx\n", host->io_port, host->io_port + host->n_io_port - 1);
+	SPRINTF("MMIO(virtual address): 0x%lx-0x%lx\n", host->base, host->base + data->MmioLength - 1);
+	SPRINTF("sg_tablesize:          %d\n",          host->sg_tablesize);
+
+	SPRINTF("burst transfer mode:   ");
+	switch (nsp_burst_mode) {
+	case BURST_IO8:
+		SPRINTF("io8");
+		break;
+	case BURST_IO32:
+		SPRINTF("io32");
+		break;
+	case BURST_MEM32:
+		SPRINTF("mem32");
+		break;
+	default:
+		SPRINTF("???");
+		break;
+	}
+	SPRINTF("\n");
+	SPRINTF("Chip ID:               %d\n", data->ChipRev >> 4);
+	SPRINTF("Chip revision:         %d\n", data->ChipRev &  0x0f);
+
+
+	spin_lock_irqsave(&(data->Lock), flags);
+	SPRINTF("CurrentSC:             0x%p\n\n",      data->CurrentSC);
+	spin_unlock_irqrestore(&(data->Lock), flags);
+
+	SPRINTF("SDTR status\n");
+	for(id = 0; id < NUMBER(data->Sync); id++) {
+
+		SPRINTF("id %d: ", id);
+
+		if (id == host->this_id) {
+			SPRINTF("----- NinjaSCSI-3 host adapter\n");
+			continue;
+		}
 
-	nsp_eh_bus_reset(SCpnt);
+		switch(data->Sync[id].SyncNegotiation) {
+		case SYNC_OK:
+			SPRINTF(" sync");
+			break;
+		case SYNC_NG:
+			SPRINTF("async");
+			break;
+		case SYNC_NOT_YET:
+			SPRINTF(" none");
+			break;
+		default:
+			SPRINTF("?????");
+			break;
+		}
+
+		if (data->Sync[id].SyncPeriod != 0) {
+			speed = 1000000 / (data->Sync[id].SyncPeriod * 4);
+
+			SPRINTF(" transfer %d.%dMB/s, offset %d",
+				speed / 1000,
+				speed % 1000,
+				data->Sync[id].SyncOffset
+				);
+		}
+		SPRINTF("\n");
+	}
 
-	return SCSI_ABORT_SUCCESS;
+	thislength = pos - (buffer + offset);
+
+	if(thislength < 0) {
+		*start = 0;
+                return 0;
+        }
+
+
+	thislength = MIN(thislength, length);
+	*start = buffer + offset;
+
+	return thislength;
 }
+#undef SPRINTF
+
+/*---------------------------------------------------------------*/
+/* error handler                                                 */
+/*---------------------------------------------------------------*/
 
 /*static int nsp_eh_strategy(struct Scsi_Host *Shost)
 {
 	return FAILED;
 }*/
 
+/*
 static int nsp_eh_abort(Scsi_Cmnd *SCpnt)
 {
-	DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
-
-	nsp_eh_bus_reset(SCpnt);
+	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
 
-	return SUCCESS;
-}
+	return nsp_eh_bus_reset(SCpnt);
+}*/
 
+/*
 static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt)
 {
-	DEBUG(0, __FUNCTION__ " SCpnt=0x%p\n", SCpnt);
+	nsp_dbg(NSP_DEBUG_BUSRESET, "%s: SCpnt=0x%p", SCpnt);
 
 	return FAILED;
-}
+}*/
 
-static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
+/* Do bus reset. This function uses in low-level initialize functions. */
+static int nsp_bus_reset(nsp_hw_data *data)
 {
-	unsigned int base = SCpnt->host->io_port;
+	unsigned int base = data->BaseAddress;
 	int	     i;
 
-	DEBUG(0, __FUNCTION__ "() SCpnt=0x%p base=0x%x\n", SCpnt, base);
-
-	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLMASK);
+	nsp_msg(KERN_WARNING, "Bus reset");
+	nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_CLEAR_AND_MASK);
 
 	nsp_index_write(base, SCSIBUSCTRL, SCSI_RST);
 	mdelay(100); /* 100ms */
@@ -1287,33 +1627,46 @@
 		nsp_index_read(base, IRQPHASESENCE); /* dummy read */
 	}
 
-	nsp_write(base, IRQCONTROL, IRQCONTROL_ALLCLEAR);
+	nsphw_init_sync(data);
+
+	nsp_write(base, IRQCONTROL, IRQCONTROL_ALL_CLEAR);
+
+	if (data->CurrentSC != NULL) {
+		nsp_msg(KERN_WARNING, "clean up current scsi command.");
+		data->CurrentSC->result = DID_ERROR << 16;
+		nsp_scsi_done(data->CurrentSC);
+	}
 
 	return SUCCESS;
 }
 
+/* Do bus reset. This function uses in high-level SCSI driver. */
+static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt)
+{
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
+
+	nsp_dbg(NSP_DEBUG_BUSRESET, "SCpnt=0x%p", SCpnt);
+
+	return nsp_bus_reset(data);
+}
+
+/* Initialise Ninja host adapter. */
 static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt)
 {
-	nsp_hw_data *data = &nsp_data;
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 
-	DEBUG(0, __FUNCTION__ "\n");
+	nsp_dbg(NSP_DEBUG_BUSRESET, "in");
+	nsp_msg(KERN_DEBUG, "host reset");
 
 	nsphw_init(data);
 
-	return nsp_eh_bus_reset(SCpnt);
+	return SUCCESS;
 }
 
 
 /**********************************************************************
   PCMCIA functions
-  *********************************************************************/
-
-/*====================================================================*/
-static void cs_error(client_handle_t handle, int func, int ret)
-{
-	error_info_t err = { func, ret };
-	CardServices(ReportError, handle, &err);
-}
+**********************************************************************/
 
 /*======================================================================
     nsp_cs_attach() creates an "instance" of the driver, allocating
@@ -1330,15 +1683,19 @@
 	client_reg_t  client_reg;
 	dev_link_t   *link;
 	int	      ret, i;
+	nsp_hw_data  *data = &nsp_data_base;
 
-	DEBUG(0, __FUNCTION__ "()\n");
+	nsp_dbg(NSP_DEBUG_INIT, "in");
 
 	/* Create new SCSI device */
 	info = kmalloc(sizeof(*info), GFP_KERNEL);
-	if (!info) { return NULL; }
+	if (info == NULL) { return NULL; }
 	memset(info, 0, sizeof(*info));
 	link = &info->link;
 	link->priv = info;
+	data->ScsiInfo = info;
+
+	nsp_dbg(NSP_DEBUG_INIT, "info=0x%p", info);
 
 	/* The io structure describes IO port mapping */
 	link->io.NumPorts1	 = 0x10;
@@ -1352,11 +1709,14 @@
 		link->irq.IRQInfo2 = irq_mask;
 	} else {
 		for (i = 0; i < 4; i++) {
-			link->irq.IRQInfo2 |= 1 << irq_list[i];
+			link->irq.IRQInfo2 |= BIT(irq_list[i]);
 		}
 	}
+
+	/* Interrupt handler */
 	link->irq.Handler	 = &nspintr;
-	link->irq.Instance       = &nsp_data;
+	link->irq.Instance       = info;
+	link->irq.Attributes     |= (SA_SHIRQ | SA_SAMPLE_RANDOM);
 
 	/* General socket configuration */
 	link->conf.Attributes	 = CONF_ENABLE_IRQ;
@@ -1384,6 +1744,8 @@
 		return NULL;
 	}
 
+
+	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
 	return link;
 } /* nsp_cs_attach */
 
@@ -1398,8 +1760,8 @@
 {
 	dev_link_t **linkp;
 
-	DEBUG(0, __FUNCTION__ "(0x%p)\n", link);
-    
+	nsp_dbg(NSP_DEBUG_INIT, "in, link=0x%p", link);
+
 	/* Locate device structure */
 	for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) {
 		if (*linkp == link) {
@@ -1411,11 +1773,7 @@
 	}
 
 	if (link->state & DEV_CONFIG) {
-		nsp_cs_release((u_long)link);
-		if (link->state & DEV_STALE_CONFIG) {
-			link->state |= DEV_STALE_LINK;
-			return;
-		}
+		nsp_cs_release(link);
 	}
 
 	/* Break the link with Card Services */
@@ -1426,6 +1784,7 @@
 	/* Unlink device structure, free bits */
 	*linkp = link->next;
 	kfree(link->priv);
+	link->priv = NULL;
 
 } /* nsp_cs_detach */
 
@@ -1440,22 +1799,26 @@
 #define CFG_CHECK(fn, args...) \
 if (CardServices(fn, args) != 0) goto next_entry
 /*====================================================================*/
-
 static void nsp_cs_config(dev_link_t *link)
 {
 	client_handle_t	  handle = link->handle;
 	scsi_info_t	 *info	 = link->priv;
 	tuple_t		  tuple;
 	cisparse_t	  parse;
-	int		  i, last_ret, last_fn;
-	u_char		  tuple_data[64];
+	int		  last_ret, last_fn;
+	unsigned char	  tuple_data[64];
 	config_info_t	  conf;
+	win_req_t         req;
+	memreq_t          map;
+	cistpl_cftable_entry_t dflt = { 0 };
+	struct Scsi_Host *host;
+	nsp_hw_data      *data = &nsp_data_base;
+#if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
 	Scsi_Device	 *dev;
 	dev_node_t	**tail, *node;
-	struct Scsi_Host *host;
-	nsp_hw_data      *data = &nsp_data;
+#endif
 
-	DEBUG(0, __FUNCTION__ "() in\n");
+	nsp_dbg(NSP_DEBUG_INIT, "in");
 
 	tuple.DesiredTuple    = CISTPL_CONFIG;
 	tuple.Attributes      = 0;
@@ -1469,7 +1832,6 @@
 	link->conf.Present    = parse.config.rmask[0];
 
 	/* Configure card */
-	driver_template.module = &__this_module;
 	link->state	      |= DEV_CONFIG;
 
 	/* Look up the current Vcc */
@@ -1479,81 +1841,195 @@
 	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
 	CS_CHECK(GetFirstTuple, handle, &tuple);
 	while (1) {
+		cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
+
 		CFG_CHECK(GetTupleData, handle, &tuple);
 		CFG_CHECK(ParseTuple,	handle, &tuple, &parse);
-		link->conf.ConfigIndex = parse.cftable_entry.index;
-		link->io.BasePort1     = parse.cftable_entry.io.win[0].base;
-		i = CardServices(RequestIO, handle, &link->io);
-		if (i == CS_SUCCESS) {
-			break;
+
+		if (cfg->flags & CISTPL_CFTABLE_DEFAULT) { dflt = *cfg; }
+		if (cfg->index == 0) { goto next_entry; }
+		link->conf.ConfigIndex = cfg->index;
+
+		/* Does this card need audio output? */
+		if (cfg->flags & CISTPL_CFTABLE_AUDIO) {
+			link->conf.Attributes |= CONF_ENABLE_SPKR;
+			link->conf.Status = CCSR_AUDIO_ENA;
+		}
+
+		/* Use power settings for Vcc and Vpp if present */
+		/*  Note that the CIS values need to be rescaled */
+		if (cfg->vcc.present & (1<<CISTPL_POWER_VNOM)) {
+			if (conf.Vcc != cfg->vcc.param[CISTPL_POWER_VNOM]/10000) {
+				goto next_entry;
+			}
+		} else if (dflt.vcc.present & (1<<CISTPL_POWER_VNOM)) {
+			if (conf.Vcc != dflt.vcc.param[CISTPL_POWER_VNOM]/10000) {
+				goto next_entry;
+			}
 		}
+
+		if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+			link->conf.Vpp1 = link->conf.Vpp2 =
+				cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
+		} else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) {
+			link->conf.Vpp1 = link->conf.Vpp2 =
+				dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
+		}
+
+		/* Do we need to allocate an interrupt? */
+		if (cfg->irq.IRQInfo1 || dflt.irq.IRQInfo1) {
+			link->conf.Attributes |= CONF_ENABLE_IRQ;
+		}
+
+		/* IO window settings */
+		link->io.NumPorts1 = link->io.NumPorts2 = 0;
+		if ((cfg->io.nwin > 0) || (dflt.io.nwin > 0)) {
+			cistpl_io_t *io = (cfg->io.nwin) ? &cfg->io : &dflt.io;
+			link->io.Attributes1 = IO_DATA_PATH_WIDTH_AUTO;
+			if (!(io->flags & CISTPL_IO_8BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;
+			if (!(io->flags & CISTPL_IO_16BIT))
+				link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
+			link->io.IOAddrLines = io->flags & CISTPL_IO_LINES_MASK;
+			link->io.BasePort1 = io->win[0].base;
+			link->io.NumPorts1 = io->win[0].len;
+			if (io->nwin > 1) {
+				link->io.Attributes2 = link->io.Attributes1;
+				link->io.BasePort2 = io->win[1].base;
+				link->io.NumPorts2 = io->win[1].len;
+			}
+			/* This reserves IO space but doesn't actually enable it */
+			CFG_CHECK(RequestIO, link->handle, &link->io);
+		}
+
+		if ((cfg->mem.nwin > 0) || (dflt.mem.nwin > 0)) {
+			cistpl_mem_t *mem =
+				(cfg->mem.nwin) ? &cfg->mem : &dflt.mem;
+			req.Attributes = WIN_DATA_WIDTH_16|WIN_MEMORY_TYPE_CM;
+			req.Attributes |= WIN_ENABLE;
+			req.Base = mem->win[0].host_addr;
+			req.Size = mem->win[0].len;
+			if (req.Size < 0x1000) {
+				req.Size = 0x1000;
+			}
+			req.AccessSpeed = 0;
+			link->win = (window_handle_t)link->handle;
+			CFG_CHECK(RequestWindow, &link->win, &req);
+			map.Page = 0; map.CardOffset = mem->win[0].card_addr;
+			CFG_CHECK(MapMemPage, link->win, &map);
+
+			data->MmioAddress = (unsigned long)ioremap_nocache(req.Base, req.Size);
+			data->MmioLength  = req.Size;
+		}
+		/* If we got this far, we're cool! */
+		break;
+
 	next_entry:
-		DEBUG(0, __FUNCTION__ " next\n");
+		nsp_dbg(NSP_DEBUG_INIT, "next");
+
+		if (link->io.NumPorts1) {
+			CardServices(ReleaseIO, link->handle, &link->io);
+		}
 		CS_CHECK(GetNextTuple, handle, &tuple);
 	}
 
-	CS_CHECK(RequestIRQ,	       handle, &link->irq);
+	if (link->conf.Attributes & CONF_ENABLE_IRQ) {
+		CS_CHECK(RequestIRQ, link->handle, &link->irq);
+	}
 	CS_CHECK(RequestConfiguration, handle, &link->conf);
 
-	/* A bad hack... */
-	release_region(link->io.BasePort1, link->io.NumPorts1);
+	if (free_ports) {
+		if (link->io.BasePort1) {
+			release_region(link->io.BasePort1, link->io.NumPorts1);
+		}
+		if (link->io.BasePort2) {
+			release_region(link->io.BasePort2, link->io.NumPorts2);
+		}
+	}
 
 	/* Set port and IRQ */
 	data->BaseAddress = link->io.BasePort1;
 	data->NumAddress  = link->io.NumPorts1;
 	data->IrqNumber   = link->irq.AssignedIRQ;
 
-	DEBUG(0, __FUNCTION__ " I/O[0x%x+0x%x] IRQ %d\n",
-	      data->BaseAddress, data->NumAddress, data->IrqNumber);
+	nsp_dbg(NSP_DEBUG_INIT, "I/O[0x%x+0x%x] IRQ %d",
+		data->BaseAddress, data->NumAddress, data->IrqNumber);
 
 	if(nsphw_init(data) == FALSE) {
 		goto cs_failed;
 	}
 
-	scsi_register_module(MODULE_SCSI_HA, &driver_template);
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2))
+	host = nsp_detect(&nsp_driver_template);
+#else
+	scsi_register_host(&nsp_driver_template);
+	for (host = scsi_host_get_next(NULL); host != NULL;
+	     host = scsi_host_get_next(host)) {
+		if (host->hostt == &nsp_driver_template) {
+			break;
+		}
+	}
+#endif
 
-	DEBUG(0, "GET_SCSI_INFO\n");
+	if (host == NULL) {
+		nsp_dbg(NSP_DEBUG_INIT, "detect failed");
+		goto cs_failed;
+	}
+
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
+	scsi_add_host (host, NULL);
+	scsi_scan_host(host);
+
+	snprintf(info->node.dev_name, sizeof(info->node.dev_name), "scsi%d", host->host_no);
+	link->dev  = &info->node;
+	info->host = host;
+
+#else
+	nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO");
 	tail = &link->dev;
 	info->ndev = 0;
-	for (host = scsi_hostlist; host != NULL; host = host->next) {
-		if (host->hostt == &driver_template) {
-			for (dev = host->host_queue; dev != NULL; dev = dev->next) {
-				u_long arg[2], id;
-				kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
-				id = (arg[0]&0x0f) + ((arg[0]>>4)&0xf0) +
-					((arg[0]>>8)&0xf00) + ((arg[0]>>12)&0xf000);
-				node = &info->node[info->ndev];
-				node->minor = 0;
-				switch (dev->type) {
-				case TYPE_TAPE:
-					node->major = SCSI_TAPE_MAJOR;
-					sprintf(node->dev_name, "st#%04lx", id);
-					break;
-				case TYPE_DISK:
-				case TYPE_MOD:
-					node->major = SCSI_DISK0_MAJOR;
-					sprintf(node->dev_name, "sd#%04lx", id);
-					break;
-				case TYPE_ROM:
-				case TYPE_WORM:
-					node->major = SCSI_CDROM_MAJOR;
-					sprintf(node->dev_name, "sr#%04lx", id);
-					break;
-				default:
-					node->major = SCSI_GENERIC_MAJOR;
-					sprintf(node->dev_name, "sg#%04lx", id);
-					break;
-				}
-				*tail = node; tail = &node->next;
-				info->ndev++;
-				info->host = dev->host;
-			}
+
+	nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
+
+	for (dev = host->host_queue; dev != NULL; dev = dev->next) {
+		unsigned long arg[2], id;
+		kernel_scsi_ioctl(dev, SCSI_IOCTL_GET_IDLUN, arg);
+		id = (arg[0] & 0x0f) + ((arg[0] >> 4) & 0xf0) +
+			((arg[0] >> 8) & 0xf00) + ((arg[0] >> 12) & 0xf000);
+		node = &info->node[info->ndev];
+		node->minor = 0;
+		switch (dev->type) {
+		case TYPE_TAPE:
+			node->major = SCSI_TAPE_MAJOR;
+			snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id);
+			break;
+		case TYPE_DISK:
+		case TYPE_MOD:
+			node->major = SCSI_DISK0_MAJOR;
+			snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id);
+			break;
+		case TYPE_ROM:
+		case TYPE_WORM:
+			node->major = SCSI_CDROM_MAJOR;
+			snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id);
+			break;
+		default:
+			node->major = SCSI_GENERIC_MAJOR;
+			snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id);
+			break;
 		}
+		*tail = node; tail = &node->next;
+		info->ndev++;
+		info->host = dev->host;
 	}
+
 	*tail = NULL;
 	if (info->ndev == 0) {
-		printk(KERN_INFO "nsp_cs: no SCSI devices found\n");
+		nsp_msg(KERN_INFO, "no SCSI devices found");
 	}
+	nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host);
+#endif
 
 	/* Finally, report what we've done */
 	printk(KERN_INFO "nsp_cs: index 0x%02x: Vcc %d.%d",
@@ -1569,47 +2045,60 @@
 		printk(", io 0x%04x-0x%04x", link->io.BasePort1,
 		       link->io.BasePort1+link->io.NumPorts1-1);
 	}
+	if (link->io.NumPorts2)
+		printk(" & 0x%04x-0x%04x", link->io.BasePort2,
+		       link->io.BasePort2+link->io.NumPorts2-1);
+	if (link->win)
+		printk(", mem 0x%06lx-0x%06lx", req.Base,
+		       req.Base+req.Size-1);
 	printk("\n");
 
 	link->state &= ~DEV_CONFIG_PENDING;
 	return;
 
-cs_failed:
+ cs_failed:
+	nsp_dbg(NSP_DEBUG_INIT, "config fail");
 	cs_error(link->handle, last_fn, last_ret);
-	nsp_cs_release((u_long)link);
-	return;
+	nsp_cs_release(link);
 
+	return;
 } /* nsp_cs_config */
 #undef CS_CHECK
 #undef CFG_CHECK
 
+
 /*======================================================================
     After a card is removed, nsp_cs_release() will unregister the net
     device, and release the PCMCIA configuration.  If the device is
     still open, this will be postponed until it is closed.
 ======================================================================*/
-static void nsp_cs_release(u_long arg)
+static void nsp_cs_release(dev_link_t *link)
 {
-	dev_link_t *link = (dev_link_t *)arg;
-
-	DEBUG(0, __FUNCTION__ "(0x%p)\n", link);
+	scsi_info_t *info = link->priv;
+	nsp_hw_data *data = NULL;
 
-	/*
-	 * If the device is currently in use, we won't release until it
-	 * is actually closed.
-	 */
-	if (link->open) {
-		DEBUG(1, "nsp_cs: release postponed, '%s' still open\n",
-		      link->dev->dev_name);
-		link->state |= DEV_STALE_CONFIG;
-		return;
+	if (info->host == NULL) {
+		nsp_msg(KERN_DEBUG, "unexpected card release call.");
+	} else {
+		data = (nsp_hw_data *)info->host->hostdata;
 	}
 
+	nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link);
+
 	/* Unlink the device chain */
-	scsi_unregister_module(MODULE_SCSI_HA, &driver_template);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
+	if (info->host != NULL) {
+		scsi_remove_host(info->host);
+	}
+#else
+	scsi_unregister_host(&nsp_driver_template);
+#endif
 	link->dev = NULL;
 
 	if (link->win) {
+		if (data != NULL) {
+			iounmap((void *)(data->MmioAddress));
+		}
 		CardServices(ReleaseWindow, link->win);
 	}
 	CardServices(ReleaseConfiguration,  link->handle);
@@ -1620,10 +2109,11 @@
 		CardServices(ReleaseIRQ,    link->handle, &link->irq);
 	}
 	link->state &= ~DEV_CONFIG;
-
-	if (link->state & DEV_STALE_LINK) {
-		nsp_cs_detach(link);
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2))
+	if (info->host != NULL) {
+		scsi_host_put(info->host);
 	}
+#endif
 } /* nsp_cs_release */
 
 /*======================================================================
@@ -1637,39 +2127,53 @@
     to block future accesses to this device.  All the functions that
     actually access the device should check this flag to make sure
     the card is still present.
-    
+
 ======================================================================*/
-static int nsp_cs_event(event_t		    event,
-		     int		    priority,
-		     event_callback_args_t *args)
+static int nsp_cs_event(event_t		       event,
+			int		       priority,
+			event_callback_args_t *args)
 {
 	dev_link_t  *link = args->client_data;
 	scsi_info_t *info = link->priv;
+	nsp_hw_data *data;
 
-	DEBUG(1, __FUNCTION__ "(0x%06x)\n", event);
+	nsp_dbg(NSP_DEBUG_INIT, "in, event=0x%08x", event);
 
 	switch (event) {
 	case CS_EVENT_CARD_REMOVAL:
-		DEBUG(0, " event: remove\n");
+		nsp_dbg(NSP_DEBUG_INIT, "event: remove");
 		link->state &= ~DEV_PRESENT;
 		if (link->state & DEV_CONFIG) {
 			((scsi_info_t *)link->priv)->stop = 1;
-			nsp_cs_release((u_long)link);
+			nsp_cs_release(link);
 		}
 		break;
 
 	case CS_EVENT_CARD_INSERTION:
-		DEBUG(0, " event: insert\n");
+		nsp_dbg(NSP_DEBUG_INIT, "event: insert");
 		link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,68))
 		info->bus    =  args->bus;
+#endif
 		nsp_cs_config(link);
 		break;
 
 	case CS_EVENT_PM_SUSPEND:
+		nsp_dbg(NSP_DEBUG_INIT, "event: suspend");
 		link->state |= DEV_SUSPEND;
 		/* Fall through... */
 	case CS_EVENT_RESET_PHYSICAL:
 		/* Mark the device as stopped, to block IO until later */
+		nsp_dbg(NSP_DEBUG_INIT, "event: reset physical");
+
+		if (info->host != NULL) {
+			nsp_msg(KERN_INFO, "clear SDTR status");
+
+			data = (nsp_hw_data *)info->host->hostdata;
+
+			nsphw_init_sync(data);
+		}
+
 		info->stop = 1;
 		if (link->state & DEV_CONFIG) {
 			CardServices(ReleaseConfiguration, link->handle);
@@ -1677,68 +2181,92 @@
 		break;
 
 	case CS_EVENT_PM_RESUME:
+		nsp_dbg(NSP_DEBUG_INIT, "event: resume");
 		link->state &= ~DEV_SUSPEND;
 		/* Fall through... */
 	case CS_EVENT_CARD_RESET:
-		DEBUG(0, " event: reset\n");
+		nsp_dbg(NSP_DEBUG_INIT, "event: reset");
 		if (link->state & DEV_CONFIG) {
-			Scsi_Cmnd tmp;
-
 			CardServices(RequestConfiguration, link->handle, &link->conf);
-			tmp.host = info->host;
-			nsp_eh_host_reset(&tmp);
 		}
 		info->stop = 0;
+
+		if (info->host != NULL) {
+			nsp_msg(KERN_INFO, "reset host and bus");
+
+			data = (nsp_hw_data *)info->host->hostdata;
+
+			nsphw_init   (data);
+			nsp_bus_reset(data);
+		}
+
 		break;
 
 	default:
-		DEBUG(0, " event: unknown\n");
+		nsp_dbg(NSP_DEBUG_INIT, "event: unknown");
 		break;
 	}
-	DEBUG(0, __FUNCTION__ " end\n");
+	nsp_dbg(NSP_DEBUG_INIT, "end");
 	return 0;
 } /* nsp_cs_event */
 
 /*======================================================================*
  *	module entry point
  *====================================================================*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
+static struct pcmcia_driver nsp_driver = {
+	.owner          = THIS_MODULE,
+	.drv            = {
+		.name   = "nsp_cs",
+	},
+	.attach         = nsp_cs_attach,
+	.detach         = nsp_cs_detach,
+};
+#endif
+
 static int __init nsp_cs_init(void)
 {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
+	nsp_msg(KERN_INFO, "loading...");
+
+	return pcmcia_register_driver(&nsp_driver);
+#else
 	servinfo_t serv;
 
-	DEBUG(0, __FUNCTION__ "() in\n");
-	DEBUG(0, "%s\n", version);
+	nsp_msg(KERN_INFO, "loading...");
 	CardServices(GetCardServicesInfo, &serv);
 	if (serv.Revision != CS_RELEASE_CODE) {
-		printk(KERN_DEBUG "nsp_cs: Card Services release "
-		       "does not match!\n");
-		return -1;
+		nsp_msg(KERN_DEBUG, "Card Services release does not match!");
+		return -EINVAL;
 	}
 	register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach);
 
-	DEBUG(0, __FUNCTION__ "() out\n");
+	nsp_dbg(NSP_DEBUG_INIT, "out");
 	return 0;
+#endif
 }
 
-
-static void __exit nsp_cs_cleanup(void)
+static void __exit nsp_cs_exit(void)
 {
-	DEBUG(0, __FUNCTION__ "() unloading\n");
+	nsp_msg(KERN_INFO, "unloading...");
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68))
+	pcmcia_unregister_driver(&nsp_driver);
+#else
 	unregister_pcmcia_driver(&dev_info);
+#endif
+
+	/* XXX: this really needs to move into generic code.. */
 	while (dev_list != NULL) {
 		if (dev_list->state & DEV_CONFIG) {
-			nsp_cs_release((u_long)dev_list);
+			nsp_cs_release(dev_list);
 		}
 		nsp_cs_detach(dev_list);
 	}
 }
 
-module_init(nsp_cs_init);
-module_exit(nsp_cs_cleanup);
 
-/*
- *
- *
- */
+module_init(nsp_cs_init)
+module_exit(nsp_cs_exit)
 
 /* end */
diff -urN linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_cs.h linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_cs.h
--- linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_cs.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_cs.h	2003-10-09 17:48:22.000000000 -0700
@@ -10,13 +10,13 @@
 
 =========================================================*/
 
-/* $Id: nsp_cs.h,v 1.27 2001/09/10 10:31:13 elca Exp $ */
+/* $Id: nsp_cs.h,v 1.20 2003/09/24 10:38:18 elca Exp $ */
 
 #ifndef  __nsp_cs__
 #define  __nsp_cs__
 
 /* for debugging */
-/*#define PCMCIA_DEBUG 9*/
+//#define NSP_DEBUG 9
 
 /*
 #define static
@@ -26,64 +26,83 @@
 /************************************
  * Some useful macros...
  */
-#define Number(arr) ((int) (sizeof(arr) / sizeof(arr[0])))
-#define BIT(x)      (1<<(x))
+#define NUMBER(arr) ((int) (sizeof(arr) / sizeof(arr[0]))) /* from XtNumber() in /usr/X11R6/include/X11/Intrinsic.h */
+#define BIT(x)      (1L << (x))
 #define MIN(a,b)    ((a) > (b) ? (b) : (a))
 
-/* SCSI initiator must be 7 */
-#define SCSI_INITIATOR_ID  7
+/* SCSI initiator must be ID 7 */
+#define NSP_INITIATOR_ID  7
 
 #define NSP_SELTIMEOUT 200
 
-/* base register */
-#define	IRQCONTROL	0x00
+/***************************************************************************
+ * register definitions
+ ***************************************************************************/
+/*========================================================================
+ * base register
+ ========================================================================*/
+#define	IRQCONTROL	0x00  /* R */
 #  define IRQCONTROL_RESELECT_CLEAR     BIT(0)
 #  define IRQCONTROL_PHASE_CHANGE_CLEAR BIT(1)
 #  define IRQCONTROL_TIMER_CLEAR        BIT(2)
 #  define IRQCONTROL_FIFO_CLEAR         BIT(3)
-#  define IRQCONTROL_ALLMASK            0xff
-#  define IRQCONTROL_ALLCLEAR           0x0f
-#  define IRQCONTROL_IRQDISABLE         0xf0
+#  define IRQCONTROL_SCSI_IRQ_MASK      BIT(4)
+#  define IRQCONTROL_EXT_IRQ_MASK       BIT(5)
+#  define IRQCONTROL_TIMER_IRQ_MASK     BIT(6)
+#  define IRQCONTROL_FIFO_IRQ_MASK      BIT(7)
+#  define IRQCONTROL_ALL_MASK           (IRQCONTROL_SCSI_IRQ_MASK  | \
+                                         IRQCONTROL_EXT_IRQ_MASK   | \
+                                         IRQCONTROL_TIMER_IRQ_MASK | \
+                                         IRQCONTROL_FIFO_IRQ_MASK  )
+#  define IRQCONTROL_ALL_CLEAR          (IRQCONTROL_RESELECT_CLEAR     | \
+					 IRQCONTROL_PHASE_CHANGE_CLEAR | \
+					 IRQCONTROL_TIMER_CLEAR        | \
+					 IRQCONTROL_FIFO_CLEAR         )
+#  define IRQCONTROL_ALL_CLEAR_AND_MASK  (IRQCONTROL_ALL_MASK | \
+                                          IRQCONTROL_ALL_CLEAR)
 
-#define	IRQSTATUS	0x00
+#define	IRQSTATUS	0x00  /* W */
 #  define IRQSTATUS_SCSI  BIT(0)
 #  define IRQSTATUS_TIMER BIT(2)
 #  define IRQSTATUS_FIFO  BIT(3)
 #  define IRQSTATUS_MASK  0x0f
 
-#define	IFSELECT	0x01
+#define	IFSELECT	0x01 /* W */
 #  define IF_IFSEL    BIT(0)
 #  define IF_REGSEL   BIT(2)
 
-#define	FIFOSTATUS	0x01
-#  define FIFOSTATUS_CHIP_REVISION 0x0f
-#  define FIFOSTATUS_CHIP_ID       0x70
-#  define FIFOSTATUS_FULL_EMPTY    0x80
-
-#define	INDEXREG	0x02
-#define	DATAREG		0x03
-#define	FIFODATA	0x04
-#define	FIFODATA1	0x05
-#define	FIFODATA2	0x06
-#define	FIFODATA3	0x07
+#define	FIFOSTATUS	0x01 /* R */
+#  define FIFOSTATUS_CHIP_REVISION_MASK 0x0f
+#  define FIFOSTATUS_CHIP_ID_MASK       0x70
+#  define FIFOSTATUS_FULL_EMPTY         BIT(7)
+
+#define	INDEXREG	0x02 /* R/W */
+#define	DATAREG		0x03 /* R/W */
+#define	FIFODATA	0x04 /* R/W */
+#define	FIFODATA1	0x05 /* R/W */
+#define	FIFODATA2	0x06 /* R/W */
+#define	FIFODATA3	0x07 /* R/W */
+
+/*====================================================================
+ * indexed register
+ ====================================================================*/
+#define EXTBUSCTRL	0x10 /* R/W,deleted */
 
-/* indexed register */
-#define EXTBUSCTRL	0x10
-
-#define CLOCKDIV	0x11
+#define CLOCKDIV	0x11 /* R/W */
 #  define CLOCK_40M 0x02
 #  define CLOCK_20M 0x01
+#  define FAST_20   BIT(2)
 
-#define TERMPWRCTRL	0x13
+#define TERMPWRCTRL	0x13 /* R/W */
 #  define POWER_ON BIT(0)
 
-#define SCSIIRQMODE	0x15
+#define SCSIIRQMODE	0x15 /* R/W */
 #  define SCSI_PHASE_CHANGE_EI BIT(0)
 #  define RESELECT_EI          BIT(4)
 #  define FIFO_IRQ_EI          BIT(5)
 #  define SCSI_RESET_IRQ_EI    BIT(6)
 
-#define IRQPHASESENCE	0x16
+#define IRQPHASESENCE	0x16 /* R */
 #  define LATCHED_MSG      BIT(0)
 #  define LATCHED_IO       BIT(1)
 #  define LATCHED_CD       BIT(2)
@@ -93,9 +112,9 @@
 #  define FIFO_IRQ         BIT(6)
 #  define SCSI_RESET_IRQ   BIT(7)
 
-#define TIMERCOUNT	0x17
+#define TIMERCOUNT	0x17 /* R/W */
 
-#define SCSIBUSCTRL	0x18
+#define SCSIBUSCTRL	0x18 /* R/W */
 #  define SCSI_SEL         BIT(0)
 #  define SCSI_RST         BIT(1)
 #  define SCSI_DATAOUT_ENB BIT(2)
@@ -105,13 +124,13 @@
 #  define AUTODIRECTION    BIT(6)
 #  define ACKENB           BIT(7)
 
-#define SCSIBUSMON	0x19
+#define SCSIBUSMON	0x19 /* R */
 
-#define SETARBIT	0x1A
+#define SETARBIT	0x1A /* W */
 #  define ARBIT_GO         BIT(0)
 #  define ARBIT_FLAG_CLEAR BIT(1)
 
-#define ARBITSTATUS	0x1A
+#define ARBITSTATUS	0x1A /* R */
 /*#  define ARBIT_GO        BIT(0)*/
 #  define ARBIT_WIN        BIT(1)
 #  define ARBIT_FAIL       BIT(2)
@@ -124,90 +143,110 @@
 #  define CLEAR_COMMAND_POINTER BIT(0)
 #  define AUTO_COMMAND_GO       BIT(1)
 
-#define RESELECTID	0x1C  /* R */
-#define COMMANDDATA	0x1D
+#define RESELECTID	0x1C  /* R   */
+#define COMMANDDATA	0x1D  /* R/W */
 
-#define POINTERCLR	0x1E  /* W */
+#define POINTERCLR	0x1E  /*   W */
 #  define POINTER_CLEAR      BIT(0)
 #  define ACK_COUNTER_CLEAR  BIT(1)
 #  define REQ_COUNTER_CLEAR  BIT(2)
 #  define HOST_COUNTER_CLEAR BIT(3)
-#  define READ_SOURCE        0x30
-
-#define TRANSFERCOUNT	0x1E  /* R */
-
-#define TRANSFERMODE	0x20
-#   define MODE_MEM8   BIT(0)
-#   define MODE_MEM32  BIT(1)
-#   define MODE_ADR24  BIT(2)
-#   define MODE_ADR32  BIT(3)
-#   define MODE_IO8    BIT(4)
-#   define MODE_IO32   BIT(5)
-#   define TRANSFER_GO BIT(6)
-#   define BRAIND      BIT(7)
+#  define READ_SOURCE        (BIT(4) | BIT(5))
+#    define ACK_COUNTER        (0)
+#    define REQ_COUNTER        (BIT(4))
+#    define HOST_COUNTER       (BIT(5))
+
+#define TRANSFERCOUNT	0x1E  /* R   */
+
+#define TRANSFERMODE	0x20  /* R/W */
+#  define MODE_MEM8   BIT(0)
+#  define MODE_MEM32  BIT(1)
+#  define MODE_ADR24  BIT(2)
+#  define MODE_ADR32  BIT(3)
+#  define MODE_IO8    BIT(4)
+#  define MODE_IO32   BIT(5)
+#  define TRANSFER_GO BIT(6)
+#  define BRAIND      BIT(7)
 
-#define SYNCREG		0x21
+#define SYNCREG		0x21 /* R/W */
 #  define SYNCREG_OFFSET_MASK  0x0f
 #  define SYNCREG_PERIOD_MASK  0xf0
 #  define SYNCREG_PERIOD_SHIFT 4
 
-#define SCSIDATALATCH	0x22
-#define SCSIDATAIN	0x22
-#define SCSIDATAWITHACK	0x23
-#define SCAMCONTROL	0x24
-#define SCAMSTATUS	0x24
-#define SCAMDATA	0x25
+#define SCSIDATALATCH	0x22 /*   W */
+#define SCSIDATAIN	0x22 /* R   */
+#define SCSIDATAWITHACK	0x23 /* R/W */
+#define SCAMCONTROL	0x24 /*   W */
+#define SCAMSTATUS	0x24 /* R   */
+#define SCAMDATA	0x25 /* R/W */
 
-#define OTHERCONTROL	0x26
+#define OTHERCONTROL	0x26 /* R/W */
 #  define TPL_ROM_WRITE_EN BIT(0)
 #  define TPWR_OUT         BIT(1)
 #  define TPWR_SENSE       BIT(2)
 #  define RA8_CONTROL      BIT(3)
 
-#define ACKWIDTH	0x27
-#define CLRTESTPNT	0x28
-#define ACKCNTLD	0x29
-#define REQCNTLD	0x2A
-#define HSTCNTLD	0x2B
-#define CHECKSUM	0x2C
+#define ACKWIDTH	0x27 /* R/W */
+#define CLRTESTPNT	0x28 /*   W */
+#define ACKCNTLD	0x29 /*   W */
+#define REQCNTLD	0x2A /*   W */
+#define HSTCNTLD	0x2B /*   W */
+#define CHECKSUM	0x2C /* R/W */
 
-/*
+/************************************************************************
  * Input status bit definitions.
- */
-#define S_ATN		0x80	/**/
-#define S_SELECT	0x40	/**/
-#define S_REQUEST	0x20    /* Request line from SCSI bus*/
-#define S_ACK		0x10    /* Acknowlege line from SCSI bus*/
-#define S_BUSY		0x08    /* Busy line from SCSI bus*/
-#define S_CD		0x04    /* Command/Data line from SCSI bus*/
-#define S_IO		0x02    /* Input/Output line from SCSI bus*/
-#define S_MESSAGE	0x01    /* Message line from SCSI bus*/
+ ************************************************************************/
+#define S_MESSAGE	BIT(0)    /* Message line from SCSI bus      */
+#define S_IO		BIT(1)    /* Input/Output line from SCSI bus */
+#define S_CD		BIT(2)    /* Command/Data line from SCSI bus */
+#define S_BUSY		BIT(3)    /* Busy line from SCSI bus         */
+#define S_ACK		BIT(4)    /* Acknowlege line from SCSI bus   */
+#define S_REQUEST	BIT(5)    /* Request line from SCSI bus      */
+#define S_SELECT	BIT(6)	  /*                                 */
+#define S_ATN		BIT(7)	  /*                                 */
 
-/*
+/***********************************************************************
  * Useful Bus Monitor status combinations.
- */
+ ***********************************************************************/
 #define BUSMON_SEL         S_SELECT
 #define BUSMON_BSY         S_BUSY
 #define BUSMON_REQ         S_REQUEST
 #define BUSMON_IO          S_IO
 #define BUSMON_ACK         S_ACK
 #define BUSMON_BUS_FREE    0
-#define BUSMON_COMMAND     ( S_BUSY | S_CD | S_REQUEST )
-#define BUSMON_MESSAGE_IN  ( S_BUSY | S_MESSAGE | S_IO | S_CD | S_REQUEST )
-#define BUSMON_MESSAGE_OUT ( S_BUSY | S_MESSAGE | S_CD | S_REQUEST )
-#define BUSMON_DATA_IN     ( S_BUSY | S_IO | S_REQUEST )
-#define BUSMON_DATA_OUT    ( S_BUSY | S_REQUEST )
-#define BUSMON_STATUS      ( S_BUSY | S_IO | S_CD | S_REQUEST )
-#define BUSMON_RESELECT    ( S_SELECT | S_IO )
-#define BUSMON_PHASE_MASK  ( S_SELECT | S_CD | S_MESSAGE | S_IO )
+#define BUSMON_COMMAND     ( S_BUSY | S_CD |                    S_REQUEST )
+#define BUSMON_MESSAGE_IN  ( S_BUSY | S_CD | S_IO | S_MESSAGE | S_REQUEST )
+#define BUSMON_MESSAGE_OUT ( S_BUSY | S_CD |        S_MESSAGE | S_REQUEST )
+#define BUSMON_DATA_IN     ( S_BUSY |        S_IO |             S_REQUEST )
+#define BUSMON_DATA_OUT    ( S_BUSY |                           S_REQUEST )
+#define BUSMON_STATUS      ( S_BUSY | S_CD | S_IO |             S_REQUEST )
+#define BUSMON_SELECT      (                 S_IO |                        S_SELECT )
+#define BUSMON_RESELECT    (                 S_IO |                        S_SELECT )
+#define BUSMON_PHASE_MASK  (          S_CD | S_IO | S_MESSAGE |            S_SELECT )
 
+#define BUSPHASE_SELECT      ( BUSMON_SELECT      & BUSMON_PHASE_MASK )
 #define BUSPHASE_COMMAND     ( BUSMON_COMMAND     & BUSMON_PHASE_MASK )
 #define BUSPHASE_MESSAGE_IN  ( BUSMON_MESSAGE_IN  & BUSMON_PHASE_MASK )
 #define BUSPHASE_MESSAGE_OUT ( BUSMON_MESSAGE_OUT & BUSMON_PHASE_MASK )
 #define BUSPHASE_DATA_IN     ( BUSMON_DATA_IN     & BUSMON_PHASE_MASK )
 #define BUSPHASE_DATA_OUT    ( BUSMON_DATA_OUT    & BUSMON_PHASE_MASK )
 #define BUSPHASE_STATUS      ( BUSMON_STATUS      & BUSMON_PHASE_MASK )
-#define BUSPHASE_SELECT      ( S_SELECT | S_IO )
+
+/*====================================================================*/
+
+typedef struct scsi_info_t {
+	dev_link_t             link;
+	struct Scsi_Host      *host;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74))
+	dev_node_t             node;
+#else
+	int	               ndev;
+	dev_node_t             node[8];
+	struct bus_operations *bus;
+#endif
+	int                    stop;
+} scsi_info_t;
+
 
 /* synchronous transfer negotiation data */
 typedef struct _sync_data {
@@ -222,67 +261,116 @@
 	unsigned char AckWidth;
 } sync_data;
 
-typedef struct _nsp_data {
+typedef struct _nsp_hw_data {
 	unsigned int  BaseAddress;
 	unsigned int  NumAddress;
 	unsigned int  IrqNumber;
 
-	unsigned char ScsiClockDiv;
+	unsigned long MmioAddress;
+#define NSP_MMIO_OFFSET 0x0800
+	unsigned long MmioLength;
 
+	unsigned char ScsiClockDiv;
 	unsigned char TransferMode;
+	unsigned char ChipRev;
 
 	int           TimerCount;
 	int           SelectionTimeOut;
 	Scsi_Cmnd    *CurrentSC;
+	//int           CurrnetTarget;
 
 	int           FifoCount;
-#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,4,0))
-	int           Residual;
-#define RESID data->Residual
-#else
-#define RESID SCpnt->resid
-#endif
 
 #define MSGBUF_SIZE 20
 	unsigned char MsgBuffer[MSGBUF_SIZE];
 	int MsgLen;
 
 #define N_TARGET 8
-#define N_LUN    8
-	sync_data     Sync[N_TARGET][N_LUN];
+	sync_data     Sync[N_TARGET];
+
+	char nspinfo[110];     /* description */
+	spinlock_t Lock;
+
+	scsi_info_t   *ScsiInfo; /* attach <-> detect glue */
+
+
+#ifdef NSP_DEBUG
+	int CmdId; /* Accepted command serial number.
+		      Used for debugging.             */
+#endif
 } nsp_hw_data;
 
 
-static void nsp_cs_release(u_long arg);
-static int nsp_cs_event(event_t event, int priority, event_callback_args_t *args);
-static dev_link_t *nsp_cs_attach(void);
-static void nsp_cs_detach(dev_link_t *);
-
-static unsigned int nsphw_start_selection(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
-static void nsp_start_timer(Scsi_Cmnd *SCpnt, nsp_hw_data *data, int time);
-
-static int nsp_detect(Scsi_Host_Template * );
-static int nsp_release(struct Scsi_Host *shpnt);
-static const char * nsp_info(struct Scsi_Host *shpnt);
-static int nsp_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-
-static int nsp_abort(Scsi_Cmnd *);
-static int nsp_reset(Scsi_Cmnd *, unsigned int);
-
-static int nsp_eh_abort(Scsi_Cmnd * SCpnt);
-static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);
-static int nsp_eh_bus_reset(Scsi_Cmnd *SCpnt);
-static int nsp_eh_host_reset(Scsi_Cmnd *SCpnt);
-
-static int  nsp_fifo_count(Scsi_Cmnd *SCpnt);
-static void nsp_pio_read(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
-static int  nsp_nexus(Scsi_Cmnd *SCpnt, nsp_hw_data *data);
-
-#ifdef PCMCIA_DEBUG
-static void show_command(Scsi_Cmnd *ptr);
-static void show_phase(Scsi_Cmnd *SCpnt);
+/****************************************************************************
+ *
+ */
+
+/* Card service functions */
+static dev_link_t *nsp_cs_attach (void);
+static void        nsp_cs_detach (dev_link_t *link);
+static void        nsp_cs_release(dev_link_t *link);
+static void        nsp_cs_config (dev_link_t *link);
+static int         nsp_cs_event  (event_t event, int priority, event_callback_args_t *args);
+
+/* Linux SCSI subsystem specific functions */
+static struct Scsi_Host *nsp_detect     (Scsi_Host_Template *sht);
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
+static        int        nsp_detect_old (Scsi_Host_Template *sht);
+static        int        nsp_release_old(struct Scsi_Host *shpnt);
+#endif
+static const  char      *nsp_info       (struct Scsi_Host *shpnt);
+static        int        nsp_proc_info  (
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+	                                 struct Scsi_Host *host,
+#endif
+					 char   *buffer,
+					 char  **start,
+					 off_t   offset,
+					 int     length,
+#if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73))
+					 int     hostno,
+#endif
+					 int     inout);
+static        int        nsp_queuecommand(Scsi_Cmnd *SCpnt, void (* done)(Scsi_Cmnd *SCpnt));
+
+/* Error handler */
+/*static int nsp_eh_abort       (Scsi_Cmnd *SCpnt);*/
+/*static int nsp_eh_device_reset(Scsi_Cmnd *SCpnt);*/
+static int nsp_eh_bus_reset    (Scsi_Cmnd *SCpnt);
+static int nsp_eh_host_reset   (Scsi_Cmnd *SCpnt);
+static int nsp_bus_reset       (nsp_hw_data *data);
+
+/* */
+static int  nsphw_init           (nsp_hw_data *data);
+static int  nsphw_start_selection(Scsi_Cmnd *SCpnt);
+static void nsp_start_timer      (Scsi_Cmnd *SCpnt, int time);
+static int  nsp_fifo_count       (Scsi_Cmnd *SCpnt);
+static void nsp_pio_read         (Scsi_Cmnd *SCpnt);
+static void nsp_pio_write        (Scsi_Cmnd *SCpnt);
+static int  nsp_nexus            (Scsi_Cmnd *SCpnt);
+static void nsp_scsi_done        (Scsi_Cmnd *SCpnt);
+static int  nsp_analyze_sdtr     (Scsi_Cmnd *SCpnt);
+static int  nsp_negate_signal    (Scsi_Cmnd *SCpnt, unsigned char mask, char *str);
+static int  nsp_expect_signal    (Scsi_Cmnd *SCpnt, unsigned char current_phase, unsigned char  mask);
+static int  nsp_xfer             (Scsi_Cmnd *SCpnt, int phase);
+static int  nsp_dataphase_bypass (Scsi_Cmnd *SCpnt);
+static int  nsp_reselected       (Scsi_Cmnd *SCpnt);
+static struct Scsi_Host *nsp_detect(Scsi_Host_Template *sht);
+
+/* Interrupt handler */
+//static irqreturn_t nspintr(int irq, void *dev_id, struct pt_regs *regs);
+
+/* Module entry point*/
+static int  __init nsp_cs_init(void);
+static void __exit nsp_cs_exit(void);
+
+
+/* Debug */
+#ifdef NSP_DEBUG
+static void show_command (Scsi_Cmnd *SCpnt);
+static void show_phase   (Scsi_Cmnd *SCpnt);
 static void show_busphase(unsigned char stat);
-static void show_message(nsp_hw_data *data);
+static void show_message (nsp_hw_data *data);
 #else
 # define show_command(ptr)   /* */
 # define show_phase(SCpnt)   /* */
@@ -294,17 +382,19 @@
  * SCSI phase
  */
 enum _scsi_phase {
-	PH_UNDETERMINED,
-	PH_ARBSTART,
-	PH_SELSTART,
-	PH_SELECTED,
-	PH_COMMAND,
-	PH_DATA,
-	PH_STATUS,
-	PH_MSG_IN,
-	PH_MSG_OUT,
-	PH_DISCONNECT,
-	PH_RESELECT
+	PH_UNDETERMINED ,
+	PH_ARBSTART     ,
+	PH_SELSTART     ,
+	PH_SELECTED     ,
+	PH_COMMAND      ,
+	PH_DATA         ,
+	PH_STATUS       ,
+	PH_MSG_IN       ,
+	PH_MSG_OUT      ,
+	PH_DISCONNECT   ,
+	PH_RESELECT     ,
+	PH_ABORT        ,
+	PH_RESET
 };
 
 enum _data_in_out {
@@ -313,12 +403,85 @@
 	IO_OUT
 };
 
+enum _burst_mode {
+	BURST_IO8   = 0,
+	BURST_IO32  = 1,
+	BURST_MEM32 = 2,
+};
 
-/* SCSI messaage */
+
+/**************************************************************************
+ * SCSI messaage
+ */
 #define MSG_COMMAND_COMPLETE 0x00
 #define MSG_EXTENDED         0x01
+#define MSG_ABORT            0x06
 #define MSG_NO_OPERATION     0x08
+#define MSG_BUS_DEVICE_RESET 0x0c
 
 #define MSG_EXT_SDTR         0x01
 
+
+/**************************************************************************
+ * Compatibility functions
+ */
+
+/* for Kernel 2.4 */
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0))
+# define scsi_register_host(template)   scsi_register_module(MODULE_SCSI_HA, template)
+# define scsi_unregister_host(template) scsi_unregister_module(MODULE_SCSI_HA, template)
+# define scsi_host_put(host)            scsi_unregister(host)
+
+# define IRQ_NONE      /* */
+# define IRQ_HANDLED   /* */
+# define IRQ_RETVAL(x) /* */
+
+/* This is ad-hoc version of scsi_host_get_next() */
+static inline struct Scsi_Host *scsi_host_get_next(struct Scsi_Host *host)
+{
+	if (host == NULL) {
+		return scsi_hostlist;
+	} else {
+		return host->next;
+	}
+}
+
+/* This is ad-hoc version of scsi_host_hn_get() */
+static inline struct Scsi_Host *scsi_host_hn_get(unsigned short hostno)
+{
+	struct Scsi_Host *host;
+
+	for (host = scsi_host_get_next(NULL); host != NULL;
+	     host = scsi_host_get_next(host)) {
+		if (host->host_no == hostno) {
+			break;
+		}
+	}
+
+	return host;
+}
+
+static void cs_error(client_handle_t handle, int func, int ret)
+{
+	error_info_t err = { func, ret };
+	CardServices(ReportError, handle, &err);
+}
+
+/* scatter-gather table */
+# define SG_ADDRESS(buffer) ((buffer)->address)
+
+/* host spin lock */
+# define HOST_LOCK          (&io_request_lock)
+#endif
+
+/* for Kernel 2.6 */
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0))
+/* scatter-gather table */
+# define SG_ADDRESS(buffer) ((char *) (page_address((buffer)->page)+(buffer)->offset))
+
+/* host spin lock */
+# define HOST_LOCK          (((scsi_info_t *)dev_id)->host->host_lock)
+#endif
+
 #endif  /*__nsp_cs__*/
+/* end */
diff -urN linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_debug.c linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_debug.c
--- linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_debug.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_debug.c	2003-10-09 17:48:22.000000000 -0700
@@ -6,7 +6,7 @@
     the GNU General Public License.
 =========================================================================*/
 
-/* $Id: nsp_debug.c,v 1.8 2001/09/07 04:32:28 elca Exp $ */
+/* $Id: nsp_debug.c,v 1.3 2003/07/26 14:21:09 elca Exp $ */
 
 /*
  * Show the command data of a command
@@ -87,14 +87,21 @@
 
 static void print_commandk (unsigned char *command)
 {
-	int i,s;
+	int i, s;
 	printk(KERN_DEBUG);
 	print_opcodek(command[0]);
 	/*printk(KERN_DEBUG __FUNCTION__ " ");*/
-	for ( i = 1, s = COMMAND_SIZE(command[0]); i < s; ++i) {
+	if ((command[0] >> 5) == 6 ||
+	    (command[0] >> 5) == 7 ) {
+		s = 12; /* vender specific */
+	} else {
+		s = COMMAND_SIZE(command[0]);
+	}
+	for ( i = 1; i < s; ++i) {
 		printk("%02x ", command[i]);
 	}
-	switch (COMMAND_SIZE(command[0])) {
+
+	switch (s) {
 	case 6:
 		printk("LBA=%d len=%d",
 		       (((unsigned int)command[1] & 0x0f) << 16) |
@@ -131,9 +138,9 @@
 	printk("\n");
 }
 
-static void show_command(Scsi_Cmnd *ptr)
+static void show_command(Scsi_Cmnd *SCpnt)
 {
-	print_commandk(ptr->cmnd);
+	print_commandk(SCpnt->cmnd);
 }
 
 static void show_phase(Scsi_Cmnd *SCpnt)
diff -urN linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_io.h linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_io.h
--- linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_io.h	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_io.h	2003-10-09 17:48:22.000000000 -0700
@@ -7,7 +7,7 @@
 
   */
 
-/* $Id: nsp_io.h,v 1.9 2001/09/07 04:32:42 elca Exp $ */
+/* $Id: nsp_io.h,v 1.3 2003/08/04 21:15:26 elca Exp $ */
 
 #ifndef __NSP_IO_H__
 #define __NSP_IO_H__
@@ -76,7 +76,7 @@
 				  void          *buf,
 				  unsigned long  count)
 {
-	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx\n", buf, count);
+	/*nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx", buf, count);*/
 	nsp_multi_read_1(base, FIFODATA, buf, count);
 }
 
@@ -95,7 +95,7 @@
 				   void          *buf,
 				   unsigned long  count)
 {
-	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*2\n", buf, count);
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*2", buf, count);
 	nsp_multi_read_2(base, FIFODATA, buf, count);
 }
 
@@ -114,7 +114,7 @@
 				   void          *buf,
 				   unsigned long  count)
 {
-	//DEBUG(0, __FUNCTION__ "() buf=0x%p, count=0x%lx*4\n", buf, count);
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*4", buf, count);
 	nsp_multi_read_4(base, FIFODATA, buf, count);
 }
 
@@ -172,5 +172,103 @@
 	nsp_multi_write_4(base, FIFODATA, buf, count);
 }
 
+
+/*====================================================================*/
+
+static inline void nsp_mmio_write(unsigned long base,
+				  unsigned int  index,
+				  unsigned char val)
+{
+	unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index);
+
+	writeb(val, ptr);
+}
+
+static inline unsigned char nsp_mmio_read(unsigned long base,
+					  unsigned int  index)
+{
+	unsigned char *ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + index);
+
+	return readb(ptr);
+}
+
+/*-----------*/
+
+static inline unsigned char nsp_mmio_index_read(unsigned long base,
+						unsigned int  reg)
+{
+	unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG);
+	unsigned char *data_ptr  = (unsigned char *)(base + NSP_MMIO_OFFSET + DATAREG);
+
+	writeb((unsigned char)reg, index_ptr);
+	return readb(data_ptr);
+}
+
+static inline void nsp_mmio_index_write(unsigned long base,
+					unsigned int  reg,
+					unsigned char val)
+{
+	unsigned char *index_ptr = (unsigned char *)(base + NSP_MMIO_OFFSET + INDEXREG);
+	unsigned char *data_ptr  = (unsigned char *)(base + NSP_MMIO_OFFSET + DATAREG);
+
+	writeb((unsigned char)reg, index_ptr);
+	writeb(val,                data_ptr);
+}
+
+/* read 32bit FIFO */
+static inline void nsp_mmio_multi_read_4(unsigned long  base,
+					 unsigned int   Register,
+					 void          *buf,
+					 unsigned long  count)
+{
+	unsigned long *ptr = (unsigned long *)(base + Register);
+	unsigned long *tmp = (unsigned long *)buf;
+	int i;
+
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "base 0x%0lx ptr 0x%p",base,ptr);
+
+	for (i = 0; i < count; i++) {
+		*tmp = readl(ptr);
+		//nsp_dbg(NSP_DEBUG_DATA_IO, "<%d,%p,%p,%lx>", i, ptr, tmp, *tmp);
+		tmp++;
+	}
+}
+
+static inline void nsp_mmio_fifo32_read(unsigned int   base,
+					void          *buf,
+					unsigned long  count)
+{
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*4", buf, count);
+	nsp_mmio_multi_read_4(base, FIFODATA, buf, count);
+}
+
+static inline void nsp_mmio_multi_write_4(unsigned long  base,
+					  unsigned int   Register,
+					  void          *buf,
+					  unsigned long  count)
+{
+	unsigned long *ptr = (unsigned long *)(base + Register);
+	unsigned long *tmp = (unsigned long *)buf;
+	int i;
+
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "base 0x%0lx ptr 0x%p",base,ptr);
+
+	for (i = 0; i < count; i++) {
+		writel(*tmp, ptr);
+		//nsp_dbg(NSP_DEBUG_DATA_IO, "<%d,%p,%p,%lx>", i, ptr, tmp, *tmp);
+		tmp++;
+	}
+}
+
+static inline void nsp_mmio_fifo32_write(unsigned int   base,
+					 void          *buf,
+					 unsigned long  count)
+{
+	//nsp_dbg(NSP_DEBUG_DATA_IO, "buf=0x%p, count=0x%lx*4", buf, count);
+	nsp_mmio_multi_write_4(base, FIFODATA, buf, count);
+}
+
+
+
 #endif
 /* end */
diff -urN linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_message.c linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_message.c
--- linux-2.4.23-pre6/drivers/scsi/pcmcia/nsp_message.c	2001-10-11 09:04:57.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/pcmcia/nsp_message.c	2003-10-09 17:48:22.000000000 -0700
@@ -6,11 +6,12 @@
    the GNU General Public License.
  */
 
-/* $Id: nsp_message.c,v 1.7 2001/09/07 04:33:01 elca Exp $ */
+/* $Id: nsp_message.c,v 1.6 2003/07/26 14:21:09 elca Exp $ */
 
-static void nsp_message_in(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static void nsp_message_in(Scsi_Cmnd *SCpnt)
 {
-	unsigned int  base = SCpnt->host->io_port;
+	unsigned int  base = SCpnt->device->host->io_port;
+	nsp_hw_data  *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 	unsigned char data_reg, control_reg;
 	int           ret, len;
 
@@ -23,7 +24,7 @@
 	ret = 16;
 	len = 0;
 
-	DEBUG(0, " msgin loop\n");
+	nsp_dbg(NSP_DEBUG_MSGINOCCUR, "msgin loop");
 	do {
 		/* read data */
 		data_reg = nsp_index_read(base, SCSIDATAIN);
@@ -49,8 +50,9 @@
 
 }
 
-static void nsp_message_out(Scsi_Cmnd *SCpnt, nsp_hw_data *data)
+static void nsp_message_out(Scsi_Cmnd *SCpnt)
 {
+	nsp_hw_data *data = (nsp_hw_data *)SCpnt->device->host->hostdata;
 	int ret = 1;
 	int len = data->MsgLen;
 
@@ -61,10 +63,10 @@
 	 * the next "msg out" if exists (no scsi phase changes).
 	 */
 
-	DEBUG(0, " msgout loop\n");
+	nsp_dbg(NSP_DEBUG_MSGOUTOCCUR, "msgout loop");
 	do {
-		if (nsp_xfer(SCpnt, data, BUSPHASE_MESSAGE_OUT)) {
-			printk(KERN_DEBUG " " __FUNCTION__ " msgout: xfer short\n");
+		if (nsp_xfer(SCpnt, BUSPHASE_MESSAGE_OUT)) {
+			nsp_msg(KERN_DEBUG, "msgout: xfer short");
 		}
 
 		/* catch a next signal */
diff -urN linux-2.4.23-pre6/drivers/scsi/ql12160_fw.h linux-2.4.23-pre7/drivers/scsi/ql12160_fw.h
--- linux-2.4.23-pre6/drivers/scsi/ql12160_fw.h	2000-02-07 19:45:28.000000000 -0800
+++ linux-2.4.23-pre7/drivers/scsi/ql12160_fw.h	2003-10-09 17:48:22.000000000 -0700
@@ -1,1704 +1,1787 @@
-/*
- ************************************************************************
- *									*
- * 	           --- ISP12160 Initiator Firmware ---               	*
- *			      32 LUN Support				*
- *									*
- ************************************************************************
- *									*
- * Copyright (C) 1999,2000 Qlogic, Corporation
- * All rights reserved.
+/*****************************************************************************
+ *                  QLOGIC LINUX SOFTWARE
  *
- * Redistribution and use in source and binary forms are permitted provided
- * that the following conditions are met:
- * 1. Redistribution of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
+ * QLogic ISP12160 device driver for Linux 2.2.x and 2.4.x
+ * Copyright (C) 2002 Qlogic Corporation (www.qlogic.com)
  *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *									*
- ************************************************************************
- */
+ * 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.
+ *
+ *****************************************************************************/
 
+/************************************************************************
+ * 	           --- ISP12160A Initiator Firmware ---                 *
+ *			      32 LUN Support                            *
+ ************************************************************************/
 
 /*
- *	Firmware Version 10.01.19 (12:38 Oct 12, 1999)
+ *	Firmware Version 10.04.32 (12:03 May 09, 2001)
  */
 
 #ifdef UNIQUE_FW_NAME
-unsigned short fw12160i_version = 10*1024+1;
+unsigned short fw12160i_version = 10*1024+4;
 #else
-unsigned short risc_code_version = 10*1024+1;
+unsigned short risc_code_version = 10*1024+4;
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned char fw12160i_version_str[] = {10,1,19};
+unsigned char fw12160i_version_str[] = {10,4,32};
 #else
-unsigned char firmware_version[] = {10,1,19};
+unsigned char firmware_version[] = {10,4,32};
 #endif
 
 #ifdef UNIQUE_FW_NAME
-#define fw12160i_VERSION_STRING "10.1.19"
+#define fw12160i_VERSION_STRING "10.04.32"
 #else
-#define FW_VERSION_STRING "10.1.19"
+#define FW_VERSION_STRING "10.04.32"
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned short fw12160i_addr01 = 0x1000 ;
+unsigned short fw12160i_addr01 = 0x1000;
 #else
-unsigned short risc_code_addr01 = 0x1000 ;
+unsigned short risc_code_addr01 = 0x1000;
 #endif
 
 #ifdef UNIQUE_FW_NAME
-unsigned short fw12160i_code01[] = { 
+unsigned short fw12160i_code01[] = {
 #else
-unsigned short risc_code01[] = { 
+unsigned short risc_code01[] = {
 #endif
-	0x0804, 0x1041, 0x0000, 0x32f8, 0x0000, 0x2043, 0x4f50, 0x5952,
+	0x0804, 0x1041, 0x0000, 0x35e6, 0x0000, 0x2043, 0x4f50, 0x5952,
 	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
 	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
 	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
 	0x3132, 0x3136, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-	0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3031, 0x2020, 0x2043,
+	0x6572, 0x7369, 0x6f6e, 0x2031, 0x302e, 0x3034, 0x2020, 0x2043,
 	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
 	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-	0x2400, 0x20c9, 0x8cff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
+	0x2400, 0x20c9, 0x8fff, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2001,
 	0x01ff, 0x2004, 0xd0fc, 0x1120, 0x2071, 0x0100, 0x70a0, 0x70a2,
-	0x20c1, 0x0020, 0x2089, 0x1223, 0x2071, 0x0010, 0x70c3, 0x0004,
+	0x20c1, 0x0020, 0x2089, 0x1221, 0x2071, 0x0010, 0x70c3, 0x0004,
 	0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3, 0x000a,
 	0x2001, 0x04fd, 0x2004, 0x70d6, 0x2009, 0xfeff, 0x2130, 0x2128,
-	0xa1a2, 0x4300, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-	0xa192, 0x8d00, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1d83,
-	0x2218, 0x2079, 0x4300, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
+	0xa1a2, 0x4600, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
+	0xa192, 0x9000, 0x2009, 0x0000, 0x2001, 0x0032, 0x080c, 0x1de8,
+	0x2218, 0x2079, 0x4600, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
 	0x0040, 0x42a4, 0x8109, 0x1dd8, 0x2009, 0xff00, 0x3400, 0xa102,
 	0x0218, 0x0110, 0x20a8, 0x42a4, 0x781b, 0x0064, 0x7814, 0xc0cd,
-	0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4340, 0x080c,
-	0x42d8, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4380,
-	0x2071, 0x0100, 0x080c, 0x42d8, 0x7814, 0xc0d4, 0x7816, 0x00de,
+	0xc0d5, 0x7816, 0x2071, 0x0200, 0x00d6, 0x2069, 0x4640, 0x080c,
+	0x459a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1130, 0x2069, 0x4680,
+	0x2071, 0x0100, 0x080c, 0x459a, 0x7814, 0xc0d4, 0x7816, 0x00de,
 	0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802,
 	0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002,
-	0x2009, 0x0002, 0x2069, 0x4340, 0x681b, 0x0003, 0x6823, 0x0007,
-	0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000,
-	0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0500,
-	0x68d3, 0x000a, 0x68c3, 0x43c0, 0x2079, 0x4300, 0x68d7, 0x762d,
-	0x68c7, 0x48c0, 0x68cb, 0x47c0, 0x68cf, 0x88c0, 0x68ab, 0x8b44,
-	0x68af, 0x8b49, 0x68b3, 0x8b44, 0x68b7, 0x8b44, 0x68a7, 0x0001,
-	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4380, 0x0860,
-	0x68d3, 0x000a, 0x68c3, 0x45c0, 0x68d7, 0x7839, 0x68c7, 0x68c0,
-	0x68cb, 0x4840, 0x68cf, 0x89d0, 0x68ab, 0x8b49, 0x68af, 0x8b4e,
-	0x68b3, 0x8b49, 0x68b7, 0x8b49, 0x68a7, 0x0001, 0x00e6, 0x2069,
-	0x47c0, 0x2071, 0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021,
-	0x0009, 0x1120, 0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1cf3,
-	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1188, 0x2069, 0x4840, 0x2071,
-	0x0100, 0x70ec, 0xd0e4, 0x2019, 0x1c09, 0x2021, 0x0009, 0x1120,
-	0x2019, 0x1c0c, 0x2021, 0x000c, 0x080c, 0x1cf3, 0x00ee, 0x2011,
-	0x0002, 0x2069, 0x48c0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837,
-	0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817,
-	0x0100, 0x681f, 0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002,
-	0xade8, 0x0010, 0x1f04, 0x1137, 0x8109, 0x1d38, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x1128, 0x8211, 0x0118, 0x2069, 0x68c0, 0x08d8,
-	0x080c, 0x2254, 0x080c, 0x3e39, 0x080c, 0x1b0f, 0x080c, 0x42a0,
-	0x2091, 0x2200, 0x2079, 0x4300, 0x2071, 0x0050, 0x2091, 0x2400,
-	0x2079, 0x4300, 0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200,
-	0x2071, 0x4340, 0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4380,
-	0x2091, 0x2000, 0x2079, 0x4300, 0x2071, 0x0010, 0x3200, 0xa085,
-	0x303d, 0x2090, 0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118e,
-	0x70c0, 0xa086, 0x0002, 0x1110, 0x080c, 0x13a3, 0x2039, 0x0000,
-	0x080c, 0x129c, 0x78ac, 0xa005, 0x1180, 0x0e04, 0x119c, 0x786c,
-	0xa065, 0x0110, 0x080c, 0x1ffe, 0x080c, 0x1da4, 0x0e04, 0x11b1,
-	0x786c, 0xa065, 0x0110, 0x080c, 0x1ffe, 0x0e04, 0x11b1, 0x2009,
-	0x4347, 0x2011, 0x4387, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c,
-	0x1c21, 0x2071, 0x4340, 0x70a4, 0xa005, 0x01e8, 0x7450, 0xa485,
-	0x0000, 0x01c8, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c,
-	0x303d, 0x2190, 0x080c, 0x260d, 0x2091, 0x8000, 0x2091, 0x303d,
-	0x0e04, 0x11d3, 0x2079, 0x4300, 0x786c, 0xa065, 0x0120, 0x2071,
-	0x0010, 0x080c, 0x1ffe, 0x1d04, 0x11db, 0x2079, 0x4300, 0x2071,
-	0x0010, 0x080c, 0x40ed, 0x2071, 0x4380, 0x70a4, 0xa005, 0x0188,
-	0x7050, 0xa025, 0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4,
-	0xa28c, 0x303d, 0x2190, 0x080c, 0x260d, 0x2091, 0x8000, 0x2091,
-	0x303d, 0x2079, 0x4300, 0x2071, 0x0010, 0x0e04, 0x11fc, 0x786c,
-	0xa065, 0x0110, 0x080c, 0x1ffe, 0x1d04, 0x1190, 0x080c, 0x40ed,
-	0x0804, 0x1190, 0x3c00, 0xa084, 0x0007, 0x0002, 0x120e, 0x120e,
-	0x1210, 0x1210, 0x1215, 0x1215, 0x121a, 0x121a, 0x080c, 0x243b,
-	0x2091, 0x2400, 0x080c, 0x3e9c, 0x0005, 0x2091, 0x2200, 0x080c,
-	0x3e9c, 0x0005, 0x2091, 0x2200, 0x080c, 0x3e9c, 0x2091, 0x2400,
-	0x080c, 0x3e9c, 0x0005, 0x1243, 0x1243, 0x1244, 0x1244, 0x124f,
-	0x124f, 0x124f, 0x124f, 0x1258, 0x1258, 0x1263, 0x1263, 0x124f,
-	0x124f, 0x124f, 0x124f, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272,
-	0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272, 0x1272,
-	0x1272, 0x1272, 0x1272, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091,
-	0x2800, 0x080c, 0x2458, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006,
-	0x0106, 0x0126, 0x080c, 0x1202, 0x012e, 0x010e, 0x000e, 0x000d,
-	0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2458, 0x012e,
-	0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600,
-	0x080c, 0x2458, 0x2091, 0x2800, 0x080c, 0x2458, 0x012e, 0x010e,
-	0x000e, 0x000d, 0x0006, 0x0106, 0x0126, 0x00e6, 0x00f6, 0x2079,
-	0x4300, 0x2071, 0x0200, 0x2069, 0x4340, 0x3d00, 0xd08c, 0x1120,
-	0x2069, 0x4380, 0x2071, 0x0100, 0x080c, 0x42d8, 0x00fe, 0x00ee,
-	0x012e, 0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007,
-	0x0002, 0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897,
-	0x70c3, 0x4002, 0x0804, 0x13a6, 0x0e04, 0x1308, 0x2061, 0x0000,
-	0x6018, 0xd084, 0x1904, 0x1308, 0x7828, 0xa005, 0x1120, 0x0004,
-	0x1309, 0x0804, 0x1308, 0xd0fc, 0x0148, 0x0006, 0x080c, 0x1aa9,
-	0x000e, 0x0168, 0x2001, 0x4007, 0x0804, 0x13a5, 0x0006, 0x080c,
-	0x1a9b, 0x000e, 0x0120, 0x2001, 0x4007, 0x0804, 0x13a5, 0x7910,
-	0xd0fc, 0x1128, 0x2061, 0x4340, 0xc19c, 0xc7fc, 0x0020, 0x2061,
-	0x4380, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x15d0, 0x7912, 0x6083,
-	0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x1120, 0x00c6, 0x080c,
-	0x18c9, 0x00ce, 0x782b, 0x0000, 0x607c, 0xa065, 0x0190, 0x00c6,
-	0x609c, 0x080c, 0x1b76, 0x00ce, 0x609f, 0x0000, 0x080c, 0x19db,
-	0x2009, 0x0018, 0x6087, 0x0103, 0x080c, 0x1ab7, 0x1198, 0x080c,
-	0x1b02, 0x7810, 0xd09c, 0x1118, 0x2061, 0x4340, 0x0020, 0x2061,
-	0x4380, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4, 0xd0c4, 0x0130,
-	0xc0c4, 0x60d6, 0x2001, 0x4005, 0x0804, 0x13a5, 0x0804, 0x13a3,
-	0x0005, 0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0,
-	0xa08a, 0x0040, 0x1a04, 0x1355, 0x0002, 0x13a3, 0x13f1, 0x13bf,
-	0x1425, 0x1459, 0x1459, 0x13b7, 0x19f3, 0x1463, 0x13b1, 0x13c3,
-	0x13c4, 0x13c5, 0x13c6, 0x19f7, 0x13b1, 0x1470, 0x14c5, 0x18e4,
-	0x19ed, 0x13c7, 0x1795, 0x17cb, 0x17fa, 0x183d, 0x1752, 0x175f,
-	0x1772, 0x1784, 0x159a, 0x13b1, 0x14f7, 0x1502, 0x1510, 0x151e,
-	0x1535, 0x1543, 0x1546, 0x1554, 0x1562, 0x156c, 0x1580, 0x158c,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x15a7, 0x15b8, 0x15d2, 0x1606,
-	0x162f, 0x1641, 0x1644, 0x1677, 0x16aa, 0x16bc, 0x1720, 0x1730,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x1742, 0x2100, 0xa08a, 0x0040,
-	0x1a04, 0x13b1, 0x0002, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1,
-	0x1a19, 0x1a1f, 0x13b1, 0x13b1, 0x13b1, 0x1a23, 0x1a63, 0x13b1,
-	0x13b1, 0x13b1, 0x13b1, 0x13ec, 0x1454, 0x146b, 0x14c0, 0x18df,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x1a67, 0x1a0b, 0x1a15, 0x13b1,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1,
-	0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1, 0x13b1,
-	0x13b1, 0x13b1, 0x13b1, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028,
-	0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13a6,
-	0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080,
-	0x0005, 0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099,
-	0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4,
-	0x70c3, 0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091,
-	0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf,
-	0x2020, 0x70d3, 0x000a, 0x2001, 0x0001, 0x70d6, 0x2079, 0x0000,
-	0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a,
-	0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000,
-	0x2091, 0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de,
-	0x0018, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4,
-	0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a,
-	0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13a3,
-	0xa182, 0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012,
-	0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007,
-	0x0002, 0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13a6,
-	0x24a8, 0x53a5, 0x0c10, 0x0804, 0x13a3, 0x2029, 0x0000, 0x2520,
-	0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003,
-	0x0000, 0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021,
-	0x0040, 0x7007, 0x0006, 0x81ff, 0x0904, 0x13a3, 0xa182, 0x0040,
-	0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6,
-	0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48,
-	0x70c3, 0x4002, 0x0804, 0x13a6, 0x75d8, 0x74dc, 0x75da, 0x74de,
-	0x0878, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a,
-	0x72ca, 0x0804, 0x13a2, 0x70c7, 0x000a, 0x70cb, 0x0001, 0x70cf,
-	0x0013, 0x0804, 0x13a3, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018,
-	0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6,
-	0x72ca, 0x73ce, 0x74d2, 0xa005, 0x05f0, 0xa40a, 0x0110, 0x1a04,
-	0x13a5, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085,
-	0x78ae, 0x2001, 0x4005, 0x0804, 0x13a5, 0x7b7e, 0x7a7a, 0x7e86,
-	0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004,
-	0x810c, 0x810c, 0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000,
-	0xa581, 0x0000, 0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291,
-	0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622,
-	0x7026, 0xa605, 0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084,
-	0xfffc, 0x78ae, 0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13a3,
-	0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530,
-	0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6,
-	0xa005, 0x0500, 0xa40a, 0x0110, 0x1a04, 0x13a5, 0x8001, 0x7892,
-	0xa084, 0xfc00, 0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005,
-	0x0804, 0x13a5, 0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505,
-	0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff,
-	0x78ae, 0x0018, 0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13a3, 0x2009,
-	0x0000, 0x786c, 0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4,
-	0x0804, 0x13a1, 0x2009, 0x4348, 0x210c, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1904, 0x13a2, 0x2011, 0x4388, 0x2214, 0x0804, 0x13a1,
-	0x2009, 0x4349, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-	0x13a2, 0x2011, 0x4389, 0x2214, 0x0804, 0x13a1, 0x2061, 0x4340,
-	0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1148, 0x2061, 0x4380, 0x6328, 0x73da, 0x632c, 0x831c,
-	0x831c, 0x831c, 0x73de, 0x0804, 0x13a1, 0x2009, 0x434c, 0x210c,
-	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x438c,
-	0x2214, 0x0804, 0x13a1, 0x7918, 0x0804, 0x13a2, 0x2009, 0x434d,
-	0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011,
-	0x438d, 0x2214, 0x0804, 0x13a1, 0x2009, 0x434e, 0x210c, 0x2001,
-	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2011, 0x438e, 0x2214,
-	0x0804, 0x13a1, 0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-	0x13a2, 0x7a24, 0x0804, 0x13a1, 0x2011, 0x4840, 0x71c4, 0xd1fc,
-	0x1110, 0x2011, 0x47c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-	0x8003, 0xa268, 0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13a0,
-	0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091,
-	0x8001, 0x2708, 0x0804, 0x13a0, 0x2061, 0x4340, 0x6118, 0x2001,
-	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13a2, 0x2061, 0x4380, 0x6218,
-	0x0804, 0x13a1, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6908,
-	0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0804, 0x13a0, 0x71c4,
-	0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x1a04, 0x139c, 0x080c,
-	0x230e, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13a0,
-	0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x1a04, 0x139c, 0xd1bc,
-	0x1120, 0x2011, 0x4348, 0x2204, 0x0020, 0x2011, 0x4388, 0x2204,
-	0xc0bd, 0x0006, 0x2100, 0xc0bc, 0x2012, 0x080c, 0x22b4, 0x001e,
-	0x0804, 0x13a2, 0x71c4, 0x2021, 0x4349, 0x2404, 0x70c6, 0x2019,
-	0x0000, 0x0030, 0x71c8, 0x2021, 0x4389, 0x2404, 0x70ca, 0xc3fd,
-	0x2011, 0x15fe, 0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210,
-	0x1f04, 0x15e4, 0x71c4, 0x72c8, 0x0804, 0x139b, 0xa292, 0x15fe,
-	0x0026, 0x2122, 0x001e, 0x080c, 0x22c6, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1110, 0xd3fc, 0x09f0, 0x0804, 0x13a3, 0x03e8, 0x00fa,
-	0x01f4, 0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4340,
-	0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8,
-	0x8003, 0x8003, 0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-	0x11a0, 0x0026, 0x0016, 0x2061, 0x4380, 0x6128, 0x622c, 0x8214,
-	0x8214, 0x8214, 0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003,
-	0x602e, 0x71da, 0x72de, 0x001e, 0x002e, 0x0804, 0x13a1, 0x2061,
-	0x4340, 0x6130, 0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc,
-	0x1904, 0x13a2, 0x2061, 0x4380, 0x6230, 0x70c8, 0x6032, 0x0804,
-	0x13a1, 0x7918, 0x0804, 0x13a2, 0x71c4, 0xa184, 0xffcf, 0x0148,
-	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x139c, 0x72c8, 0x0804,
-	0x139b, 0x2011, 0x434d, 0x2204, 0x2112, 0x0006, 0x2019, 0x0000,
-	0x080c, 0x2302, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x001e,
-	0x0804, 0x13a2, 0x71c8, 0xa184, 0xffcf, 0x0128, 0x0006, 0x2110,
-	0x71c4, 0x0804, 0x139b, 0x2011, 0x438d, 0x2204, 0x2112, 0x0006,
-	0xc3fd, 0x080c, 0x2302, 0x002e, 0x001e, 0x0804, 0x13a1, 0x71c4,
-	0xa182, 0x0010, 0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
-	0x139c, 0x72c8, 0x0804, 0x139b, 0x2011, 0x434e, 0x2204, 0x0006,
-	0x2112, 0x2019, 0x0000, 0x080c, 0x22ef, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x0118, 0x001e, 0x0804, 0x13a2, 0x71c8, 0xa182, 0x0010,
-	0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x139b, 0x2011, 0x438e,
-	0x2204, 0x0006, 0x2112, 0xc3fd, 0x080c, 0x22ef, 0x002e, 0x001e,
-	0x0804, 0x13a1, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x1904, 0x139b,
-	0xa284, 0xfffd, 0x1904, 0x139b, 0x2100, 0x7920, 0x7822, 0x2200,
-	0x7a24, 0x7826, 0x0804, 0x13a1, 0x2011, 0x4840, 0x71c4, 0xd1fc,
-	0x1110, 0x2011, 0x47c0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-	0x8003, 0xa268, 0x72c8, 0x73cc, 0x74d8, 0x71c6, 0x6800, 0x70ca,
-	0x73ce, 0x74da, 0x2091, 0x8000, 0x6a02, 0xd2ac, 0x1118, 0x2021,
-	0x0000, 0x0078, 0xa484, 0x00ff, 0xa082, 0x0002, 0x16e8, 0x843f,
-	0xa7bc, 0x00ff, 0x0130, 0xa786, 0x0002, 0x15b0, 0xa484, 0x00ff,
-	0x0598, 0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029,
-	0x0009, 0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307,
-	0xa084, 0x00ff, 0x1110, 0xa73d, 0x11f8, 0x2041, 0x001d, 0x8307,
-	0xa084, 0x00ff, 0x0150, 0xa842, 0x02b8, 0xa3bc, 0x00ff, 0x2500,
-	0xa702, 0x0290, 0x2600, 0xa702, 0x1278, 0x2039, 0x003a, 0x6804,
-	0xa705, 0x6806, 0x6b0a, 0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e,
-	0x2091, 0x8001, 0x0804, 0x13a3, 0x2091, 0x8001, 0x0804, 0x139d,
-	0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091,
-	0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0804, 0x13a0,
-	0x70c4, 0x2061, 0x4340, 0x6118, 0x601a, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1904, 0x13a2, 0x70c8, 0x2061, 0x4380, 0x6218, 0x601a,
-	0x0804, 0x13a1, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04,
-	0x139c, 0x080c, 0x2332, 0xa384, 0x4000, 0x0110, 0xa295, 0x0020,
-	0x0804, 0x13a0, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08,
-	0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0804, 0x13a1, 0x77c4,
-	0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a,
-	0x6804, 0xa005, 0x0110, 0x080c, 0x2233, 0x2091, 0x8001, 0x2708,
-	0x0804, 0x13a1, 0x77c4, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6a08,
-	0xc295, 0x6a0a, 0x6804, 0xa005, 0x0110, 0x080c, 0x2233, 0x2091,
-	0x8001, 0x2708, 0x0804, 0x13a1, 0x77c4, 0x2041, 0x0001, 0x2049,
-	0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b35, 0x2091,
-	0x8001, 0x2708, 0x6a08, 0x0804, 0x13a1, 0x77c4, 0xd7fc, 0x0128,
-	0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110,
-	0x0804, 0x13a5, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c,
-	0x1bad, 0x11e8, 0x6818, 0xa005, 0x01a0, 0x2708, 0x0076, 0x080c,
-	0x2351, 0x007e, 0x1170, 0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061,
-	0x4340, 0x0018, 0xc0fd, 0x2061, 0x4380, 0x782a, 0x2091, 0x8001,
-	0x0005, 0x2091, 0x8001, 0x2001, 0x4005, 0x0804, 0x13a5, 0x2091,
-	0x8001, 0x0804, 0x13a3, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1aa9,
-	0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110, 0x0804, 0x13a5,
-	0x77c6, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091,
-	0x8000, 0x080c, 0x1b35, 0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061,
-	0x4340, 0x0018, 0x2061, 0x4380, 0xc1fd, 0x6067, 0x0003, 0x607f,
-	0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x080c, 0x2233, 0x2091,
+	0x2009, 0x0002, 0x2069, 0x4640, 0x681b, 0x0003, 0x6823, 0x0007,
+	0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0006,
+	0x6833, 0x0008, 0x683b, 0x0000, 0x8109, 0x0500, 0x68cf, 0x000a,
+	0x68bf, 0x46c0, 0x2079, 0x4600, 0x68d3, 0x762d, 0x68c3, 0x4bc0,
+	0x68c7, 0x4ac0, 0x68cb, 0x8bc0, 0x68a7, 0x8e44, 0x68ab, 0x8e49,
+	0x68af, 0x8e44, 0x68b3, 0x8e44, 0x68a3, 0x0001, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x11c8, 0x2069, 0x4680, 0x0870, 0x68cf, 0x000a,
+	0x68bf, 0x48c0, 0x68d3, 0x7839, 0x68c3, 0x6bc0, 0x68c7, 0x4b40,
+	0x68cb, 0x8cd0, 0x68a7, 0x8e49, 0x68ab, 0x8e4e, 0x68af, 0x8e49,
+	0x68b3, 0x8e49, 0x68a3, 0x0001, 0x00e6, 0x2069, 0x4ac0, 0x2071,
+	0x0200, 0x70ec, 0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120,
+	0x2019, 0x180c, 0x2021, 0x000c, 0x080c, 0x1d58, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x1188, 0x2069, 0x4b40, 0x2071, 0x0100, 0x70ec,
+	0xd0e4, 0x2019, 0x1809, 0x2021, 0x0009, 0x1120, 0x2019, 0x180c,
+	0x2021, 0x000c, 0x080c, 0x1d58, 0x00ee, 0x2011, 0x0002, 0x2069,
+	0x4bc0, 0x2009, 0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b,
+	0x0040, 0x7bc8, 0xa386, 0xfeff, 0x1128, 0x6817, 0x0100, 0x681f,
+	0x0064, 0x0020, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
+	0x1f04, 0x1135, 0x8109, 0x1d38, 0x2001, 0x01ff, 0x2004, 0xd0fc,
+	0x1128, 0x8211, 0x0118, 0x2069, 0x6bc0, 0x08d8, 0x080c, 0x22cf,
+	0x080c, 0x4015, 0x080c, 0x1b6d, 0x080c, 0x4553, 0x2091, 0x2200,
+	0x2079, 0x4600, 0x2071, 0x0050, 0x2091, 0x2400, 0x2079, 0x4600,
+	0x2071, 0x0020, 0x2091, 0x2600, 0x2079, 0x0200, 0x2071, 0x4640,
+	0x2091, 0x2800, 0x2079, 0x0100, 0x2071, 0x4680, 0x2091, 0x2000,
+	0x2079, 0x4600, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
+	0x2071, 0x0010, 0x70c3, 0x0000, 0x1004, 0x118c, 0x70c0, 0xa086,
+	0x0002, 0x1110, 0x080c, 0x13ba, 0x2039, 0x0000, 0x080c, 0x12ab,
+	0x78ac, 0xa005, 0x1180, 0x0e04, 0x119a, 0x786c, 0xa065, 0x0110,
+	0x080c, 0x207a, 0x080c, 0x1e09, 0x0e04, 0x11af, 0x786c, 0xa065,
+	0x0110, 0x080c, 0x207a, 0x0e04, 0x11af, 0x2009, 0x4647, 0x2011,
+	0x4687, 0x2104, 0x220c, 0xa105, 0x0110, 0x080c, 0x1c7c, 0x2071,
+	0x4640, 0x70a0, 0xa005, 0x01e8, 0x744c, 0xa485, 0x0000, 0x01c8,
+	0x2079, 0x0200, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d, 0x2190,
+	0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x0e04, 0x11d1,
+	0x2079, 0x4600, 0x786c, 0xa065, 0x0120, 0x2071, 0x0010, 0x080c,
+	0x207a, 0x1d04, 0x11d9, 0x2079, 0x4600, 0x2071, 0x0010, 0x080c,
+	0x4370, 0x2071, 0x4680, 0x70a0, 0xa005, 0x0188, 0x704c, 0xa025,
+	0x0170, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d0, 0xa28c, 0x303d,
+	0x2190, 0x080c, 0x2720, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079,
+	0x4600, 0x2071, 0x0010, 0x0e04, 0x11fa, 0x786c, 0xa065, 0x0110,
+	0x080c, 0x207a, 0x1d04, 0x118e, 0x080c, 0x4370, 0x0804, 0x118e,
+	0x3c00, 0xa084, 0x0007, 0x0002, 0x120c, 0x120c, 0x120e, 0x120e,
+	0x1213, 0x1213, 0x1218, 0x1218, 0x080c, 0x254c, 0x2091, 0x2400,
+	0x080c, 0x40ad, 0x0005, 0x2091, 0x2200, 0x080c, 0x40ad, 0x0005,
+	0x2091, 0x2200, 0x080c, 0x40ad, 0x2091, 0x2400, 0x080c, 0x40ad,
+	0x0005, 0x1241, 0x1241, 0x1242, 0x1242, 0x124d, 0x124d, 0x124d,
+	0x124d, 0x1256, 0x1256, 0x1261, 0x1261, 0x124d, 0x124d, 0x124d,
+	0x124d, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
+	0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270, 0x1270,
+	0x1270, 0x0cf8, 0x0006, 0x0106, 0x0126, 0x2091, 0x2800, 0x080c,
+	0x2569, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106, 0x0126,
+	0x080c, 0x1200, 0x012e, 0x010e, 0x000e, 0x000d, 0x0006, 0x0106,
+	0x0126, 0x2091, 0x2600, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e,
+	0x000d, 0x0006, 0x0106, 0x0126, 0x2091, 0x2600, 0x080c, 0x2569,
+	0x2091, 0x2800, 0x080c, 0x2569, 0x012e, 0x010e, 0x000e, 0x000d,
+	0x0006, 0x0106, 0x0126, 0x00d6, 0x00e6, 0x00f6, 0x2079, 0x4600,
+	0x2071, 0x0200, 0x2069, 0x4640, 0x3d00, 0xd08c, 0x0130, 0x70ec,
+	0xa084, 0x1c00, 0x78e2, 0x080c, 0x459a, 0x3d00, 0xd084, 0x0150,
+	0x2069, 0x4680, 0x2071, 0x0100, 0x70ec, 0xa084, 0x1c00, 0x78e6,
+	0x080c, 0x459a, 0x080c, 0x24fd, 0x00fe, 0x00ee, 0x00de, 0x012e,
+	0x010e, 0x000e, 0x000d, 0x7008, 0x800b, 0x1240, 0x7007, 0x0002,
+	0xa08c, 0x01e0, 0x1120, 0xd09c, 0x0108, 0x0887, 0x0897, 0x70c3,
+	0x4002, 0x0804, 0x13bd, 0x0e04, 0x131e, 0x2061, 0x0000, 0x6018,
+	0xd084, 0x1904, 0x131e, 0x7828, 0xa005, 0x1120, 0x0004, 0x131f,
+	0x0804, 0x131e, 0xd0fc, 0x0130, 0x0006, 0x080c, 0x1b0a, 0x000e,
+	0x0150, 0x0028, 0x0006, 0x080c, 0x1aff, 0x000e, 0x0120, 0x2001,
+	0x4007, 0x0804, 0x13bc, 0x7910, 0xd0fc, 0x1128, 0x2061, 0x4640,
+	0xc19c, 0xc7fc, 0x0020, 0x2061, 0x4680, 0xc19d, 0xc7fd, 0x6060,
+	0xa005, 0x1904, 0x131e, 0x7912, 0x607e, 0x7828, 0xc0fc, 0xa086,
+	0x0018, 0x1120, 0x00c6, 0x080c, 0x1916, 0x00ce, 0x782b, 0x0000,
+	0x6078, 0xa065, 0x01e0, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce,
+	0x609f, 0x0000, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103,
+	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
+	0x080c, 0x1b15, 0x000e, 0x7812, 0x1198, 0x080c, 0x1b60, 0x7810,
+	0xd09c, 0x1118, 0x2061, 0x4640, 0x0020, 0x2061, 0x4680, 0xc09c,
+	0x7812, 0x607b, 0x0000, 0x60d0, 0xd0c4, 0x0130, 0xc0c4, 0x60d2,
+	0x2001, 0x4005, 0x0804, 0x13bc, 0x0804, 0x13ba, 0x0005, 0xa006,
+	0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a,
+	0x0040, 0x1a04, 0x136c, 0x0002, 0x13ba, 0x1408, 0x13d6, 0x143c,
+	0x1470, 0x1470, 0x13ce, 0x1a59, 0x147a, 0x13c8, 0x13da, 0x13db,
+	0x13dc, 0x13dd, 0x1a5d, 0x13c8, 0x1487, 0x14db, 0x1931, 0x1a53,
+	0x13de, 0x17ba, 0x17f0, 0x1822, 0x1868, 0x1777, 0x1784, 0x1797,
+	0x17a9, 0x15b0, 0x13c8, 0x150d, 0x1518, 0x1526, 0x1534, 0x154b,
+	0x1559, 0x155c, 0x156a, 0x1578, 0x1582, 0x1596, 0x15a2, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x15bd, 0x15ce, 0x15e8, 0x161c, 0x1645,
+	0x1657, 0x165a, 0x1685, 0x16be, 0x16d0, 0x1745, 0x1755, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x1767, 0x2100, 0xa08a, 0x0040, 0x1a04,
+	0x13c8, 0x0002, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x1a7f,
+	0x1a85, 0x13c8, 0x13c8, 0x13c8, 0x1a89, 0x1ac9, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x1403, 0x146b, 0x1482, 0x14d6, 0x192c, 0x13c8,
+	0x13c8, 0x18fb, 0x13c8, 0x1acd, 0x1a71, 0x1a7b, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8, 0x13c8,
+	0x13c8, 0x13c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0028, 0x73ce,
+	0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0e04, 0x13bd, 0x2061,
+	0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x0005,
+	0x70c3, 0x4001, 0x0c90, 0x70c3, 0x4006, 0x0c78, 0x2099, 0x0041,
+	0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0c20, 0x70c4, 0x70c3,
+	0x0004, 0x0807, 0x08f8, 0x08f0, 0x08e8, 0x08e0, 0x2091, 0x8000,
+	0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020,
+	0x70d3, 0x000a, 0x2001, 0x0004, 0x70d6, 0x2079, 0x0000, 0x781b,
+	0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051,
+	0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091,
+	0x4080, 0x0804, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0018,
+	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
+	0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
+	0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0904, 0x13ba, 0xa182,
+	0x0040, 0x1210, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x7007,
+	0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002,
+	0xa084, 0x01e0, 0x0120, 0x70c3, 0x4002, 0x0804, 0x13bd, 0x24a8,
+	0x53a5, 0x0c10, 0x0804, 0x13ba, 0x2029, 0x0000, 0x2520, 0x71d0,
+	0x72c8, 0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000,
+	0x7007, 0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040,
+	0x7007, 0x0006, 0x81ff, 0x0904, 0x13ba, 0xa182, 0x0040, 0x1210,
+	0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007,
+	0x0001, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x0d48, 0x70c3,
+	0x4002, 0x0804, 0x13bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0878,
+	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x1108, 0x200a, 0x72ca,
+	0x0804, 0x13b9, 0x70c7, 0x000a, 0x70cb, 0x0004, 0x70cf, 0x0020,
+	0x0804, 0x13ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0018, 0x2029,
+	0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca,
+	0x73ce, 0x74d2, 0xa005, 0x05e8, 0xa40a, 0x0108, 0x1240, 0x8001,
+	0x7872, 0xa084, 0xfc00, 0x0138, 0x78ac, 0xc085, 0x78ae, 0x2001,
+	0x4005, 0x0804, 0x13bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76,
+	0xa48c, 0xff00, 0x0170, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c,
+	0x810f, 0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000,
+	0x0050, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
+	0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
+	0x0118, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae,
+	0x0018, 0x78ac, 0xc085, 0x78ae, 0x0804, 0x13ba, 0x75d8, 0x76dc,
+	0x75da, 0x76de, 0x0018, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8,
+	0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005, 0x0500,
+	0xa40a, 0x0110, 0x1a04, 0x13bc, 0x8001, 0x7892, 0xa084, 0xfc00,
+	0x0138, 0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0804, 0x13bc,
+	0x7a9a, 0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0118, 0x7a10,
+	0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0018,
+	0x78ac, 0xc0c5, 0x78ae, 0x0804, 0x13ba, 0x2009, 0x0000, 0x786c,
+	0xa065, 0x0118, 0x8108, 0x6000, 0x0cd8, 0x7ac4, 0x0804, 0x13b8,
+	0x2009, 0x4648, 0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
+	0x13b9, 0x2011, 0x4688, 0x2214, 0x0804, 0x13b8, 0x2009, 0x4649,
+	0x210c, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011,
+	0x4689, 0x2214, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6128, 0x622c,
+	0x8214, 0x8214, 0x8214, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1148,
+	0x2061, 0x4680, 0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c,
+	0x73de, 0x0804, 0x13b8, 0x2009, 0x464c, 0x210c, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468c, 0x2214, 0x0804,
+	0x13b8, 0x7918, 0x0804, 0x13b9, 0x2009, 0x0202, 0x210c, 0x2001,
+	0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x2011, 0x0102, 0x2214,
+	0x0804, 0x13b8, 0x2009, 0x464d, 0x210c, 0x2001, 0x01ff, 0x2004,
+	0xd0fc, 0x1904, 0x13b9, 0x2011, 0x468d, 0x2214, 0x0804, 0x13b8,
+	0x7920, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9, 0x7a24,
+	0x0804, 0x13b8, 0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011,
+	0x4ac0, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268,
+	0x6a00, 0x6b08, 0x6c1c, 0x74da, 0x0804, 0x13b7, 0x77c4, 0x080c,
+	0x1b7b, 0x2091, 0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708,
+	0x0804, 0x13b7, 0x2061, 0x4640, 0x6118, 0x2001, 0x01ff, 0x2004,
+	0xd0fc, 0x1904, 0x13b9, 0x2061, 0x4680, 0x6218, 0x0804, 0x13b8,
+	0x77c4, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6908, 0x6a18, 0x6b10,
+	0x77da, 0x2091, 0x8001, 0x0804, 0x13b7, 0x71c4, 0x2110, 0xa294,
+	0x000f, 0xa282, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x238b, 0xa384,
+	0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x71c4, 0x2100,
+	0xc0bc, 0xa082, 0x0010, 0x1a04, 0x13b3, 0xd1bc, 0x1120, 0x2011,
+	0x4648, 0x2204, 0x0020, 0x2011, 0x4688, 0x2204, 0xc0bd, 0x0006,
+	0x2100, 0xc0bc, 0x2012, 0x080c, 0x2331, 0x001e, 0x0804, 0x13b9,
+	0x71c4, 0x2021, 0x4649, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0030,
+	0x71c8, 0x2021, 0x4689, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1614,
+	0x20a9, 0x0008, 0x2204, 0xa106, 0x0138, 0x8210, 0x1f04, 0x15fa,
+	0x71c4, 0x72c8, 0x0804, 0x13b2, 0xa292, 0x1614, 0x0026, 0x2122,
+	0x001e, 0x080c, 0x2343, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1110,
+	0xd3fc, 0x09f0, 0x0804, 0x13ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
+	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4640, 0x6128, 0x622c,
+	0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
+	0x8003, 0x602e, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x11a0, 0x0026,
+	0x0016, 0x2061, 0x4680, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
+	0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da,
+	0x72de, 0x001e, 0x002e, 0x0804, 0x13b8, 0x2061, 0x4640, 0x6130,
+	0x70c4, 0x6032, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9,
+	0x2061, 0x4680, 0x6230, 0x70c8, 0x6032, 0x0804, 0x13b8, 0x7918,
+	0x0804, 0x13b9, 0x71c4, 0xa184, 0xf0cf, 0x0148, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8, 0x0804, 0x13b2, 0x0006,
+	0x2019, 0x0000, 0x080c, 0x237f, 0x2001, 0x01ff, 0x2004, 0xd0fc,
+	0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa184, 0xf0cf, 0x0128,
+	0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x0006, 0xc3fd, 0x080c,
+	0x237f, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0xa182, 0x0010,
+	0x0248, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b3, 0x72c8,
+	0x0804, 0x13b2, 0x2011, 0x464d, 0x2204, 0x0006, 0x8104, 0x1208,
+	0x8108, 0x2112, 0x2019, 0x0000, 0x080c, 0x236c, 0x2001, 0x01ff,
+	0x2004, 0xd0fc, 0x0118, 0x001e, 0x0804, 0x13b9, 0x71c8, 0xa182,
+	0x0010, 0x0228, 0x0006, 0x2110, 0x71c4, 0x0804, 0x13b2, 0x2011,
+	0x468d, 0x2204, 0x0006, 0x8104, 0x1208, 0x8108, 0x2112, 0xc3fd,
+	0x080c, 0x236c, 0x002e, 0x001e, 0x0804, 0x13b8, 0x71c4, 0x72c8,
+	0xa184, 0xfffd, 0x1904, 0x13b2, 0xa284, 0xfffd, 0x1904, 0x13b2,
+	0x2100, 0x7920, 0x7822, 0x2200, 0x7a24, 0x7826, 0x0804, 0x13b8,
+	0x2011, 0x4b40, 0x71c4, 0xd1fc, 0x1110, 0x2011, 0x4ac0, 0x8107,
+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x72c8, 0x73cc,
+	0x74d8, 0x71c6, 0x6800, 0x70ca, 0x73ce, 0x74da, 0x2091, 0x8000,
+	0x6a02, 0xd2ac, 0x1118, 0x2021, 0x0000, 0x0090, 0xa484, 0x00ff,
+	0xa082, 0x0002, 0x1a04, 0x1741, 0x843f, 0xa7bc, 0x00ff, 0x0140,
+	0xa786, 0x0002, 0x1904, 0x1741, 0xa484, 0x00ff, 0x0904, 0x1741,
+	0x2061, 0x0200, 0xd1fc, 0x0110, 0x2061, 0x0100, 0x2029, 0x0009,
+	0x2031, 0x0062, 0x843f, 0xa7bc, 0x00ff, 0x0130, 0x8307, 0xa084,
+	0x00ff, 0x1110, 0xa73d, 0x1138, 0x2041, 0x0019, 0xa384, 0x00ff,
+	0xa082, 0x001a, 0x0210, 0xa4a4, 0x00ff, 0x8307, 0xa084, 0x00ff,
+	0x0188, 0xa842, 0x02f0, 0xa086, 0x0010, 0x1120, 0xa39c, 0x00ff,
+	0xa39d, 0x0f00, 0xa3bc, 0x00ff, 0x2500, 0xa702, 0x0290, 0x2600,
+	0xa702, 0x1278, 0x2039, 0x003a, 0x6804, 0xa705, 0x6806, 0x6b0a,
+	0x6b0c, 0x73ce, 0x681c, 0x70da, 0x6c1e, 0x2091, 0x8001, 0x0804,
+	0x13ba, 0x2091, 0x8001, 0x0804, 0x13b4, 0x77c4, 0x080c, 0x1b7b,
+	0x2091, 0x8000, 0x6a14, 0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816,
+	0x70cc, 0x681e, 0x2708, 0x0804, 0x13b7, 0x70c4, 0x2061, 0x4640,
+	0x6118, 0x601a, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x13b9,
+	0x70c8, 0x2061, 0x4680, 0x6218, 0x601a, 0x0804, 0x13b8, 0x71c4,
+	0x72c8, 0x73cc, 0xa182, 0x0010, 0x1a04, 0x13b3, 0x080c, 0x23af,
+	0xa384, 0x4000, 0x0110, 0xa295, 0x0020, 0x0804, 0x13b7, 0x77c4,
+	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc28d, 0x6a0a, 0x2091,
+	0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4, 0x080c, 0x1b7b, 0x2091,
+	0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a, 0x6804, 0xa005, 0x0110,
+	0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804, 0x13b8, 0x77c4,
+	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804,
+	0xa005, 0x0110, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2708, 0x0804,
+	0x13b8, 0x77c4, 0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020,
+	0x2091, 0x8000, 0x080c, 0x1b93, 0x2091, 0x8001, 0x2708, 0x6a08,
+	0x0804, 0x13b8, 0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138,
+	0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x73c8,
+	0x72cc, 0x77c6, 0x73ca, 0x72ce, 0x080c, 0x1c0b, 0x11e8, 0x6818,
+	0xa005, 0x01a0, 0x2708, 0x0076, 0x080c, 0x23ce, 0x007e, 0x1170,
+	0x2001, 0x0015, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0xc0fd,
+	0x2061, 0x4680, 0x782a, 0x2091, 0x8001, 0x0005, 0x2091, 0x8001,
+	0x2001, 0x4005, 0x0804, 0x13bc, 0x2091, 0x8001, 0x0804, 0x13ba,
+	0x77c4, 0xd7fc, 0x0128, 0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc,
+	0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x77c6, 0x2041, 0x0021,
+	0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x080c, 0x1b93,
+	0x2009, 0x0016, 0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061,
+	0x4680, 0xc1fd, 0x6063, 0x0003, 0x607b, 0x0000, 0x6772, 0x607f,
+	0x000f, 0x792a, 0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091,
 	0x8001, 0x0005, 0x77c8, 0x77ca, 0x77c4, 0x77c6, 0xd7fc, 0x0128,
-	0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110,
-	0x0804, 0x13a5, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017,
-	0xd7fc, 0x1118, 0x2061, 0x4340, 0x0018, 0x2061, 0x4380, 0xc1fd,
-	0x607f, 0x0000, 0x6067, 0x0002, 0x6776, 0x6083, 0x000f, 0x792a,
-	0x080c, 0x2233, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005,
-	0x2051, 0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0118, 0x60d4,
-	0xc0fd, 0x60d6, 0x080c, 0x1b35, 0x70c8, 0x6836, 0x8738, 0xa784,
-	0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005, 0x72c8, 0xd284, 0x0128,
-	0x080c, 0x1aa9, 0x0138, 0x0804, 0x13a5, 0x080c, 0x1a9b, 0x0110,
-	0x0804, 0x13a5, 0x72c8, 0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508,
-	0x2039, 0x0000, 0xd284, 0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049,
-	0x0004, 0x2051, 0x0008, 0x080c, 0x1b1d, 0x2091, 0x8000, 0x6808,
-	0xc0d4, 0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f,
-	0x1d90, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
-	0x1d50, 0x2091, 0x8000, 0x72c8, 0x2069, 0x0100, 0xd284, 0x1110,
-	0x2069, 0x0200, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4,
-	0x01b0, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110,
-	0x1f04, 0x1885, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084,
-	0x0110, 0x1f04, 0x188e, 0x20a9, 0x00fa, 0x1f04, 0x1895, 0x2079,
-	0x4300, 0x2009, 0x0018, 0x72c8, 0xd284, 0x1118, 0x2061, 0x4340,
-	0x0018, 0x2061, 0x4380, 0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083,
-	0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4,
-	0x0160, 0xc0b4, 0x60d6, 0x00c6, 0x60b8, 0xa065, 0x6008, 0xc0d4,
-	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x60d4, 0xa084, 0x7eff,
-	0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x681b, 0x0054, 0x2091, 0x8001,
-	0x0005, 0xd7fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, 0x4380,
-	0x71c4, 0x71c6, 0x6916, 0x81ff, 0x1110, 0x68a7, 0x0001, 0x78ac,
-	0xc08c, 0x78ae, 0xd084, 0x1110, 0x080c, 0x1c00, 0x0005, 0x75d8,
-	0x74dc, 0x75da, 0x74de, 0x0018, 0x2029, 0x0000, 0x2520, 0x71c4,
-	0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4300, 0x7dde,
-	0x7cda, 0x7bd6, 0x7ad2, 0x080c, 0x1afa, 0x0904, 0x19d7, 0x20a9,
-	0x0005, 0x20a1, 0x4314, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001,
-	0x2009, 0x0040, 0x080c, 0x1cbf, 0x0120, 0x080c, 0x1b02, 0x0804,
-	0x19d7, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x1120, 0x0006,
-	0x080c, 0x1fe3, 0x000e, 0xa084, 0xff00, 0x8007, 0x8009, 0x0904,
-	0x1981, 0x00c6, 0x2c68, 0x080c, 0x1afa, 0x05a8, 0x2c00, 0x689e,
-	0x8109, 0x1dc0, 0x609f, 0x0000, 0x00ce, 0x00c6, 0x7ddc, 0x7cd8,
-	0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000,
-	0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c,
-	0xa065, 0x0904, 0x1980, 0x2009, 0x0040, 0x080c, 0x1cbf, 0x1550,
-	0x6004, 0xa084, 0x00ff, 0xa086, 0x0002, 0x1168, 0x6004, 0xa084,
-	0x00ff, 0xa086, 0x000a, 0x1120, 0x0016, 0x080c, 0x1fe0, 0x001e,
-	0x2d00, 0x6002, 0x0898, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1b76,
-	0x00ce, 0x609f, 0x0000, 0x080c, 0x19db, 0x2009, 0x0018, 0x6008,
-	0xc0cd, 0x600a, 0x6004, 0x6086, 0x080c, 0x1ab7, 0x080c, 0x1b02,
-	0x0804, 0x19d7, 0x00ce, 0x00c6, 0x609c, 0x080c, 0x1b76, 0x00ce,
-	0x609f, 0x0000, 0x080c, 0x19db, 0x2009, 0x0018, 0x6087, 0x0103,
-	0x601b, 0x0003, 0x080c, 0x1ab7, 0x080c, 0x1b02, 0x0804, 0x19d7,
-	0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1aa9, 0x01b8, 0x0018,
-	0x080c, 0x1a9b, 0x0198, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018,
-	0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x080c, 0x1ab7,
-	0x080c, 0x1b02, 0x2001, 0x4007, 0x0804, 0x13a5, 0x74c4, 0x73c8,
-	0x72cc, 0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc,
-	0x1118, 0x2071, 0x4340, 0x0018, 0x2071, 0x4380, 0xc1fd, 0x792a,
-	0x7067, 0x0005, 0x71d4, 0xa18c, 0xfe7f, 0x71d6, 0x736a, 0x726e,
-	0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530,
-	0x611c, 0xa184, 0x0060, 0x0110, 0x080c, 0x3de5, 0x00ee, 0x6596,
-	0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714,
-	0x6023, 0x0000, 0x080c, 0x2233, 0x2091, 0x8001, 0x0005, 0x70c3,
-	0x4005, 0x0804, 0x13a6, 0x20a9, 0x0005, 0x2099, 0x4314, 0x2091,
-	0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000,
-	0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000,
-	0x791e, 0x0804, 0x13a3, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069,
-	0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8,
-	0xa285, 0x0000, 0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003,
-	0x70ca, 0x0804, 0x13a6, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003,
-	0x1a04, 0x139c, 0x7966, 0x0804, 0x13a3, 0x7964, 0x71c6, 0x0804,
-	0x13a3, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0804, 0x13a3, 0x7900,
-	0x71c6, 0x0804, 0x13a3, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d,
-	0x0160, 0x810c, 0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210,
-	0x810c, 0x81ff, 0x1904, 0x139d, 0x8210, 0x7a0e, 0xd28c, 0x0538,
-	0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284,
-	0x01c0, 0x8108, 0x2019, 0x0041, 0x2011, 0x8b4e, 0x2312, 0x2019,
-	0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019,
-	0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019,
-	0x0006, 0x2011, 0x8b53, 0x2112, 0x2011, 0x8b73, 0x2312, 0x7904,
-	0x7806, 0x0804, 0x13a2, 0x7804, 0x70c6, 0x0804, 0x13a3, 0x71c4,
-	0xd1fc, 0x1118, 0x2011, 0x47c0, 0x0010, 0x2011, 0x4840, 0x8107,
-	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000,
-	0x6814, 0xd0fc, 0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295,
-	0x0001, 0x6b0c, 0x0804, 0x13a0, 0x0016, 0x7814, 0xd0f4, 0x0138,
-	0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0050, 0xd0fc,
-	0x0138, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0008,
-	0xa006, 0x001e, 0x0005, 0x0016, 0x7814, 0xd0f4, 0x0138, 0x2001,
-	0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e,
-	0x0005, 0x0016, 0x7814, 0xd0fc, 0x0138, 0x2001, 0x4007, 0x70db,
-	0x0001, 0xa18d, 0x0001, 0x0008, 0xa006, 0x001e, 0x0005, 0x7112,
-	0x721a, 0x731e, 0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80,
-	0x0001, 0x8108, 0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003,
-	0x0000, 0x6084, 0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184,
-	0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-	0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
-	0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80,
-	0xa421, 0x7008, 0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006,
-	0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084,
-	0x01e0, 0x0005, 0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063,
-	0x0000, 0x0005, 0x00f6, 0x2079, 0x4300, 0x7848, 0x2062, 0x2c00,
-	0xa005, 0x1110, 0x080c, 0x243b, 0x784a, 0x00fe, 0x0005, 0x2011,
-	0x8d00, 0x7a4a, 0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012,
-	0x2010, 0x0cc8, 0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc,
-	0x1118, 0x2011, 0x48c0, 0x0010, 0x2011, 0x68c0, 0xa784, 0x0f00,
-	0x800b, 0xa784, 0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003,
-	0xa105, 0xa268, 0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a,
-	0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6,
-	0xd7fc, 0x1128, 0x2009, 0x4353, 0x2071, 0x4340, 0x0020, 0x2009,
-	0x4393, 0x2071, 0x4380, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116,
-	0x1138, 0x2060, 0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018,
-	0x2009, 0x0000, 0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806,
-	0x0421, 0x080c, 0x1d30, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001,
-	0x6812, 0x1d88, 0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906,
-	0x2d00, 0x2060, 0x080c, 0x2580, 0x00ee, 0x0005, 0xa065, 0x0160,
-	0x2008, 0x609c, 0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065,
-	0x0cc0, 0x7848, 0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f,
-	0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000,
-	0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc,
-	0x1128, 0x2071, 0x4340, 0x2031, 0x43c0, 0x0020, 0x2071, 0x4380,
-	0x2031, 0x45c0, 0x7050, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a,
-	0x8000, 0x7052, 0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118,
-	0x2079, 0x4340, 0x0010, 0x2079, 0x4380, 0x080c, 0x1b1d, 0x2091,
-	0x8000, 0x6804, 0x780a, 0xa065, 0x0904, 0x1bfe, 0x0030, 0x2c00,
-	0x780a, 0x2060, 0x6000, 0xa065, 0x05c8, 0x6010, 0xa306, 0x1db8,
-	0x600c, 0xa206, 0x1da0, 0x2c28, 0x784c, 0xac06, 0x1108, 0x0458,
-	0x6804, 0xac06, 0x1140, 0x6000, 0x2060, 0x6806, 0xa005, 0x1118,
-	0x6803, 0x0000, 0x0048, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486,
-	0x0000, 0x1110, 0x2c00, 0x6802, 0x2560, 0x00fe, 0x080c, 0x1b85,
-	0x00f6, 0x601b, 0x0005, 0x6023, 0x0020, 0x00fe, 0x080c, 0x1d30,
-	0x00f6, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812, 0x1118,
-	0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005, 0x00fe, 0x0005,
-	0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0108, 0xc7fd, 0x2041,
-	0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x080c,
-	0x1b35, 0x8738, 0xa784, 0x001f, 0x1dd0, 0xa7bc, 0xff00, 0x873f,
-	0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90, 0x2091, 0x8001, 0x007e,
-	0x0005, 0x786c, 0x2009, 0x8b74, 0x210c, 0xa10d, 0x0118, 0xa065,
-	0x0804, 0x1ffe, 0x2061, 0x0000, 0x6018, 0xd084, 0x11b8, 0x7810,
-	0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4340, 0x0028,
-	0xc08d, 0x7812, 0x2069, 0x4380, 0xc7fd, 0x2091, 0x8000, 0x681c,
-	0x681f, 0x0000, 0x2091, 0x8001, 0xa005, 0x1108, 0x0005, 0xa08c,
-	0xfff0, 0x0110, 0x080c, 0x243b, 0x0002, 0x1c5d, 0x1c60, 0x1c66,
-	0x1c6a, 0x1c5e, 0x1c6e, 0x1c5e, 0x1c5e, 0x1c5e, 0x1c73, 0x1c9f,
-	0x1ca2, 0x1ca7, 0x1c5e, 0x1c5e, 0x1c5e, 0x0005, 0x080c, 0x243b,
-	0x080c, 0x1c00, 0x2001, 0x8001, 0x0804, 0x1cb0, 0x2001, 0x8003,
-	0x0804, 0x1cb0, 0x2001, 0x8004, 0x0804, 0x1cb0, 0x080c, 0x1c00,
-	0x2001, 0x8006, 0x04e8, 0x2091, 0x8000, 0x0076, 0xd7fc, 0x1128,
-	0x2069, 0x4340, 0x2039, 0x0009, 0x0020, 0x2069, 0x4380, 0x2039,
-	0x0009, 0x6800, 0xa086, 0x0000, 0x0128, 0x000e, 0x6f1e, 0x2091,
-	0x8001, 0x0005, 0x6874, 0x007e, 0xa0bc, 0xff00, 0x2041, 0x0021,
-	0x2049, 0x0004, 0x2051, 0x0010, 0x080c, 0x1b35, 0x8738, 0xa784,
-	0x001f, 0x1dd0, 0x2091, 0x8001, 0x2001, 0x800a, 0x0088, 0x2001,
-	0x800c, 0x0070, 0x080c, 0x1c00, 0x2001, 0x800d, 0x0048, 0xd7fc,
-	0x0110, 0x78ec, 0x0008, 0x78e4, 0x70c6, 0x2001, 0x800e, 0x0000,
-	0x70c2, 0xd7fc, 0x1118, 0x70db, 0x0000, 0x0010, 0x70db, 0x0001,
-	0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x0005, 0xac80,
-	0x0001, 0x81ff, 0x0518, 0x2099, 0x0030, 0x20a0, 0x700c, 0xa084,
-	0x07ff, 0x0100, 0x7018, 0x0006, 0x701c, 0x0006, 0x7020, 0x0006,
-	0x7024, 0x0006, 0x7112, 0x81ac, 0x721a, 0x731e, 0x7422, 0x7526,
-	0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007,
-	0x0002, 0xa08c, 0x01e0, 0x1110, 0x53a5, 0xa006, 0x7003, 0x0000,
-	0x7007, 0x0004, 0x000e, 0x7026, 0x000e, 0x7022, 0x000e, 0x701e,
-	0x000e, 0x701a, 0x0005, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a,
-	0x6c0e, 0x681f, 0x0201, 0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a,
-	0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109, 0x1d80, 0x0005,
-	0x70ec, 0xd0dc, 0x1520, 0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160,
-	0x70ec, 0xd0e4, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019,
-	0x0c0c, 0x2021, 0x000c, 0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019,
-	0x1c0c, 0x2021, 0x000c, 0x0030, 0x2019, 0x1c09, 0x2021, 0x0009,
-	0xa5ad, 0x0200, 0x6b0a, 0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005,
-	0x6004, 0x6086, 0x2c08, 0x2063, 0x0000, 0x7868, 0xa005, 0x796a,
-	0x0110, 0x2c02, 0x0008, 0x796e, 0x0005, 0x00c6, 0x2061, 0x4300,
-	0x6887, 0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a,
-	0x0110, 0x2d02, 0x0008, 0x616e, 0x00ce, 0x0005, 0x2091, 0x8000,
-	0x2c04, 0x786e, 0xa005, 0x1108, 0x786a, 0x2091, 0x8001, 0x609c,
-	0xa005, 0x0188, 0x00c6, 0x2060, 0x2008, 0x609c, 0xa005, 0x0138,
-	0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848,
-	0x794a, 0x2062, 0x00ce, 0x7848, 0x2062, 0x609f, 0x0000, 0xac85,
-	0x0000, 0x1110, 0x080c, 0x243b, 0x784a, 0x0005, 0x20a9, 0x0010,
-	0xa006, 0x8004, 0x8086, 0x818e, 0x1208, 0xa200, 0x1f04, 0x1d7a,
-	0x8086, 0x818e, 0x0005, 0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8,
-	0xa11a, 0x12a8, 0x8213, 0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04,
-	0x1d8a, 0x0028, 0xa11a, 0x2308, 0x8210, 0x1f04, 0x1d8a, 0x0006,
-	0x3200, 0xa084, 0xefff, 0x2080, 0x000e, 0x015e, 0x0005, 0x0006,
-	0x3200, 0xa085, 0x1000, 0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904,
-	0x1e5b, 0x7810, 0x2050, 0x7800, 0xd08c, 0x0100, 0x080c, 0x1afa,
-	0x0904, 0x1e5b, 0xa046, 0x7970, 0x2500, 0x8000, 0xa112, 0x2009,
-	0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118, 0x8840, 0x2009,
-	0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9,
-	0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0110,
-	0x080c, 0x1afa, 0x7008, 0xd0fc, 0x0de8, 0x7007, 0x0002, 0x2091,
-	0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff, 0x1120, 0x88ff,
-	0x0904, 0x1e48, 0x0050, 0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80,
-	0x0001, 0x20a0, 0x53a5, 0x0804, 0x1e48, 0xa046, 0x7218, 0x731c,
-	0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000,
-	0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0118,
-	0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904, 0x1e48, 0x8cff,
-	0x0110, 0x080c, 0x1b02, 0x00ce, 0x080c, 0x1b02, 0xa046, 0x7888,
-	0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c, 0x7b78, 0xdac4,
-	0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210,
-	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e,
-	0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014, 0xd0fc, 0x1118,
-	0x2069, 0x4340, 0x0010, 0x2069, 0x4380, 0x2091, 0x8000, 0x681f,
-	0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060, 0x0c70, 0x788b,
-	0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0098,
-	0x00ce, 0x788b, 0x0000, 0x080c, 0x1fb9, 0x6004, 0xa084, 0x000f,
-	0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004, 0xa084, 0x000f,
-	0x0019, 0x0804, 0x1da4, 0x0005, 0x0002, 0x1e6d, 0x1e88, 0x1ea1,
-	0x1e6d, 0x1eae, 0x1e7e, 0x1e6d, 0x1e6d, 0x1e6d, 0x1e86, 0x1e9f,
-	0x1e6d, 0x1e6d, 0x1e6d, 0x1e6d, 0x1e6d, 0x2039, 0x0400, 0x78bc,
-	0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c, 0x1eea, 0x609c,
-	0x78ba, 0x609f, 0x0000, 0x080c, 0x1fa5, 0x0005, 0x78bc, 0xd0c4,
-	0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030, 0x080c, 0x1fe3,
-	0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000, 0x6004, 0x8007,
-	0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c, 0x1eea, 0x0120,
-	0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f05, 0x0005, 0x080c,
-	0x1fe0, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4, 0x1108, 0x0828,
-	0x080c, 0x1eea, 0x1110, 0x0804, 0x1f05, 0x0005, 0x78bc, 0xd0c4,
-	0x0110, 0x0804, 0x1e6d, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001,
-	0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188, 0xa7bc, 0xff00,
-	0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc, 0x8000, 0x2011,
-	0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108, 0x00c0, 0x080c,
-	0x1b1d, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000,
-	0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001,
-	0x1f04, 0x1ed2, 0x8211, 0x0118, 0x20a9, 0x0100, 0x0c58, 0x080c,
-	0x1b02, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6,
-	0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06,
-	0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130, 0x78bc, 0xc0c4,
-	0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6, 0xa02e, 0x2530,
-	0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2, 0x2048, 0xa984,
-	0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c, 0x3de5, 0x6596,
-	0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4380, 0xd7fc, 0x1110,
-	0x2071, 0x4340, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0120,
-	0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700,
-	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100,
-	0x60c2, 0x2091, 0x8000, 0x6e08, 0xd684, 0x0170, 0xd9fc, 0x1160,
-	0x2091, 0x8001, 0x080c, 0x1b85, 0x2091, 0x8000, 0x080c, 0x1d30,
-	0x2091, 0x8001, 0x0804, 0x1fa3, 0x6024, 0xa096, 0x0001, 0x1110,
-	0x8000, 0x6026, 0x6a10, 0x6814, 0xa202, 0x0268, 0x0160, 0x2091,
-	0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c,
-	0x1fa5, 0x0804, 0x1fa3, 0x2c08, 0xd9fc, 0x01f0, 0x6800, 0xa065,
-	0x01d8, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0168, 0x704c, 0xa206,
-	0x1150, 0x6b04, 0x2160, 0x2304, 0x6002, 0xa005, 0x1108, 0x6902,
-	0x2260, 0x6102, 0x0098, 0x2d00, 0x2060, 0x080c, 0x2580, 0x6e08,
-	0x2160, 0x6202, 0x6906, 0x0050, 0x6800, 0x6902, 0xa065, 0x0110,
-	0x6102, 0x0008, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160, 0xd9fc,
-	0x0118, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a,
-	0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0128, 0xa6b6, 0x0040,
-	0x6e0a, 0x080c, 0x1b96, 0x00ee, 0x0005, 0x6008, 0xa705, 0x600a,
-	0x2091, 0x8000, 0x080c, 0x1d30, 0x2091, 0x8001, 0x78b8, 0xa065,
-	0x0128, 0x609c, 0x78ba, 0x609f, 0x0000, 0x0c78, 0x78b6, 0x78ba,
-	0x0005, 0x7970, 0x7874, 0x2818, 0xd384, 0x0118, 0x8000, 0xa112,
-	0x0220, 0x8000, 0xa112, 0x1278, 0xc384, 0x7a7c, 0x721a, 0x7a78,
-	0x721e, 0xdac4, 0x0120, 0x7a84, 0x7222, 0x7a80, 0x7226, 0xa006,
-	0xd384, 0x0108, 0x8000, 0x7876, 0x70d2, 0x781c, 0xa005, 0x0138,
-	0x8001, 0x781e, 0x1120, 0x0e04, 0x1fdf, 0x2091, 0x4080, 0x0005,
-	0x2039, 0x1ff5, 0x0010, 0x2039, 0x1ffb, 0x2704, 0xa005, 0x0160,
-	0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814,
-	0x6916, 0x680e, 0x8738, 0x0c88, 0x0005, 0x0003, 0x0009, 0x000f,
-	0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000,
-	0x780c, 0x0002, 0x21a7, 0x2182, 0x2006, 0x2076, 0x2039, 0x8b74,
-	0x2734, 0x7d10, 0x00c0, 0x6084, 0xa086, 0x0103, 0x1904, 0x2060,
-	0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, 0x11d8, 0x0804, 0x2060,
-	0x8603, 0xa080, 0x8b55, 0x620c, 0x2202, 0x8000, 0x6210, 0x2202,
-	0x080c, 0x1d4e, 0x8630, 0xa68e, 0x000f, 0x0904, 0x20e1, 0x786c,
-	0xa065, 0x1d08, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a,
-	0x0005, 0xa682, 0x0003, 0x1a04, 0x20e1, 0x2091, 0x8000, 0x2069,
-	0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8b55, 0x2204, 0x70c6,
-	0x8210, 0x2204, 0x70ca, 0xd684, 0x1130, 0x8210, 0x2204, 0x70da,
-	0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001,
-	0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001,
-	0x203b, 0x0000, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x0804, 0x20e1,
-	0x263a, 0x080c, 0x21ad, 0x1904, 0x21c9, 0x786c, 0xa065, 0x1904,
-	0x200b, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108,
-	0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804, 0x21c9, 0x2039, 0x8b74,
-	0x2734, 0x7d10, 0x00a0, 0x6084, 0xa086, 0x0103, 0x1904, 0x20cb,
-	0x6114, 0x6018, 0xa105, 0x0120, 0x86ff, 0x11b8, 0x0804, 0x20cb,
-	0xa680, 0x8b55, 0x620c, 0x2202, 0x080c, 0x1d4e, 0x8630, 0xa68e,
-	0x001e, 0x0904, 0x20e1, 0x786c, 0xa065, 0x1d28, 0x7808, 0xa602,
-	0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0006, 0x1a04,
-	0x20e1, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8,
-	0x2011, 0x8b55, 0x2009, 0x8b4e, 0x26a8, 0x211c, 0x2204, 0x201a,
-	0x8108, 0x8210, 0x1f04, 0x20ad, 0xa685, 0x8030, 0x70c2, 0x681b,
-	0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091,
-	0x8001, 0xa006, 0x2009, 0x8b75, 0x200a, 0x203a, 0x0005, 0x7810,
-	0xc0ad, 0x7812, 0x00b0, 0x263a, 0x080c, 0x21ad, 0x1904, 0x21c9,
-	0x786c, 0xa065, 0x1904, 0x207b, 0x2091, 0x8000, 0x7810, 0xa084,
-	0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0804,
-	0x21c9, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994, 0x70d4, 0xa102,
-	0x0228, 0x0168, 0x7b90, 0xa302, 0x1150, 0x0010, 0x8002, 0x1138,
-	0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0005, 0xa184,
-	0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-	0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210, 0x721a,
-	0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0130, 0x7aa4, 0xa211,
-	0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030, 0x7003, 0x0000,
-	0x2009, 0x8b54, 0x260a, 0x8109, 0x2198, 0x2104, 0xd084, 0x0108,
-	0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6, 0x8603, 0x7012, 0x7007,
-	0x0001, 0x7990, 0x7894, 0x8000, 0xa10a, 0x1208, 0xa006, 0x2028,
-	0x7974, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004,
-	0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x797c,
-	0xa108, 0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0120, 0x7b84, 0xa319,
-	0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0de8, 0xa084, 0x01e0, 0x01d0,
-	0x7d10, 0x2031, 0x8b54, 0x2634, 0x78a8, 0x8000, 0x78aa, 0xd08c,
-	0x1138, 0x7007, 0x0006, 0x7004, 0xd094, 0x1de8, 0x0804, 0x20e3,
-	0x2069, 0x4347, 0x206b, 0x0003, 0x78ac, 0xa085, 0x0300, 0x78ae,
-	0xa006, 0x0048, 0x2030, 0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10,
-	0xa5ac, 0xffcf, 0x7d12, 0x2091, 0x8001, 0x78aa, 0x7007, 0x0006,
-	0x263a, 0x7003, 0x0001, 0x711a, 0x721e, 0xd5c4, 0x0110, 0x7322,
-	0x7426, 0x0005, 0x6084, 0xa086, 0x0103, 0x11d8, 0x6114, 0x6018,
-	0xa105, 0x11b8, 0x2069, 0x0000, 0x6818, 0xd084, 0x1190, 0x600c,
-	0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091,
-	0x4080, 0x080c, 0x1d4e, 0x0e04, 0x21a0, 0x786c, 0xa065, 0x1d10,
-	0x0005, 0x0059, 0x1530, 0x786c, 0xa065, 0x19e0, 0x0410, 0x0029,
-	0x1500, 0x786c, 0xa065, 0x1dd8, 0x00e0, 0x6084, 0xa086, 0x0103,
-	0x1168, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004, 0x1138, 0x7804,
-	0xd0a4, 0x0120, 0x080c, 0x1d4e, 0xa006, 0x0005, 0x0079, 0x1118,
-	0xa085, 0x0001, 0x0005, 0x00b9, 0x1110, 0x2041, 0x0001, 0x7d10,
-	0x0005, 0x88ff, 0x0110, 0x2091, 0x4080, 0x0005, 0x7b90, 0x7994,
-	0x70d4, 0xa102, 0x1118, 0xa385, 0x0000, 0x0005, 0x0210, 0xa302,
-	0x0005, 0x8002, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c,
+	0x080c, 0x1b0a, 0x0138, 0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110,
+	0x0804, 0x13bc, 0xa7bc, 0xff00, 0x2091, 0x8000, 0x2009, 0x0017,
+	0xd7fc, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680, 0xc1fd,
+	0x607b, 0x0000, 0x6063, 0x0002, 0x6772, 0x607f, 0x000f, 0x792a,
+	0x61d0, 0xc1c4, 0x61d2, 0x080c, 0x22ae, 0x2091, 0x8001, 0x2041,
+	0x0021, 0x2049, 0x0005, 0x2051, 0x0030, 0x2091, 0x8000, 0x70c8,
+	0xa005, 0x0118, 0x60d0, 0xc0fd, 0x60d2, 0x080c, 0x1b93, 0x70c8,
+	0x6836, 0x8738, 0xa784, 0x001f, 0x1dc0, 0x2091, 0x8001, 0x0005,
+	0x2019, 0x0000, 0x72c8, 0xd284, 0x0128, 0x080c, 0x1b0a, 0x0138,
+	0x0804, 0x13bc, 0x080c, 0x1aff, 0x0110, 0x0804, 0x13bc, 0x72c8,
+	0x72ca, 0x78ac, 0xa084, 0x0003, 0x1508, 0x2039, 0x0000, 0xd284,
+	0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
+	0x080c, 0x1b7b, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a,
+	0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x1d90, 0xa7bc, 0xff00,
+	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d50, 0x2091, 0x8000,
+	0x72c8, 0x2069, 0x0100, 0xd284, 0x1110, 0x2069, 0x0200, 0x6808,
+	0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004,
+	0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x18b2, 0x684b,
+	0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x18bb,
+	0x20a9, 0x00fa, 0x1f04, 0x18c2, 0x2079, 0x4600, 0x2009, 0x0018,
+	0x72c8, 0xd284, 0x1118, 0x2061, 0x4640, 0x0018, 0x2061, 0x4680,
+	0xc1fd, 0x607b, 0x0000, 0x792a, 0x6063, 0x0001, 0x607f, 0x000f,
+	0x60a3, 0x0000, 0x60a4, 0x60ae, 0x60b2, 0x60d0, 0xd0b4, 0x0160,
+	0xc0b4, 0x60d2, 0x00c6, 0x60b4, 0xa065, 0x6008, 0xc0d4, 0x600a,
+	0x6018, 0x8001, 0x601a, 0x00ce, 0x60d0, 0xa084, 0x7eff, 0x60d2,
+	0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0108, 0x0005, 0x681b, 0x0054,
+	0x2091, 0x8001, 0x0005, 0x73cc, 0x080c, 0x186a, 0x69ec, 0x6a48,
+	0xa185, 0x1800, 0x684a, 0xa185, 0x0040, 0x68ee, 0x73cc, 0x2021,
+	0x0004, 0x20a9, 0x09ff, 0x1f04, 0x190b, 0x8421, 0x1dd0, 0x8319,
+	0x1db0, 0x69ee, 0x6a4a, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118,
+	0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x71c4, 0x71c6, 0x6916,
+	0x81ff, 0x1110, 0x68a3, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
+	0x1110, 0x080c, 0x1c5b, 0x0005, 0x75d8, 0x74dc, 0x75da, 0x74de,
+	0x0010, 0xa02e, 0x2520, 0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca,
+	0x72ce, 0x2079, 0x4600, 0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x080c,
+	0x1b58, 0x0904, 0x1a3d, 0x20a9, 0x0005, 0x20a1, 0x4614, 0x2091,
+	0x8000, 0x41a1, 0x2091, 0x8001, 0x2009, 0x0040, 0x080c, 0x1d24,
+	0x0120, 0x080c, 0x1b60, 0x0804, 0x1a3d, 0x6004, 0xa08c, 0x00ff,
+	0xa18e, 0x0009, 0x1120, 0x0006, 0x080c, 0x205f, 0x000e, 0xa084,
+	0xff00, 0x8007, 0x8009, 0x0904, 0x19e1, 0x00c6, 0x2c68, 0x080c,
+	0x1b58, 0x05a8, 0x2c00, 0x689e, 0x8109, 0x1dc0, 0x609f, 0x0000,
+	0x00ce, 0x00c6, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040,
+	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda,
+	0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0904, 0x19e0, 0x2009,
+	0x0040, 0x080c, 0x1d24, 0x15a0, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0002, 0x1168, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a, 0x1120,
+	0x0016, 0x080c, 0x205c, 0x001e, 0x2d00, 0x6002, 0x0898, 0x00ce,
+	0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000, 0x080c,
+	0x1a41, 0x2009, 0x0018, 0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086,
+	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
+	0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d,
+	0x00ce, 0x00c6, 0x609c, 0x080c, 0x1bd4, 0x00ce, 0x609f, 0x0000,
+	0x080c, 0x1a41, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b, 0x0003,
+	0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff, 0x0110, 0xc0c5, 0x7812,
+	0x080c, 0x1b15, 0x000e, 0x7812, 0x080c, 0x1b60, 0x0804, 0x1a3d,
+	0x00ce, 0x6114, 0xd1fc, 0x0120, 0x080c, 0x1b0a, 0x01f0, 0x0018,
+	0x080c, 0x1aff, 0x01d0, 0x080c, 0x1a41, 0x2009, 0x0018, 0x6087,
+	0x0103, 0x601b, 0x0021, 0x7810, 0x0006, 0x84ff, 0x1110, 0x85ff,
+	0x0110, 0xc0c5, 0x7812, 0x080c, 0x1b15, 0x000e, 0x7812, 0x080c,
+	0x1b60, 0x2001, 0x4007, 0x0804, 0x13bc, 0x74c4, 0x73c8, 0x72cc,
+	0x6014, 0x2091, 0x8000, 0x00e6, 0x2009, 0x0012, 0xd0fc, 0x1118,
+	0x2071, 0x4640, 0x0018, 0x2071, 0x4680, 0xc1fd, 0x792a, 0x7063,
+	0x0005, 0x71d0, 0xc1c4, 0x71d2, 0x7366, 0x726a, 0x746e, 0x7072,
+	0x7077, 0x0000, 0x2c00, 0x707a, 0xa02e, 0x2530, 0x611c, 0xa184,
+	0x0060, 0x0110, 0x080c, 0x3fc1, 0x00ee, 0x6596, 0x65a6, 0x669a,
+	0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000,
+	0x080c, 0x22ae, 0x2091, 0x8001, 0x0005, 0x70c3, 0x4005, 0x0804,
+	0x13bd, 0x20a9, 0x0005, 0x2099, 0x4614, 0x2091, 0x8000, 0x530a,
+	0x2091, 0x8001, 0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000,
+	0xa5a9, 0x0000, 0x0005, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0804,
+	0x13ba, 0x71c4, 0x71c6, 0x2168, 0x0010, 0x2069, 0x1000, 0x690c,
+	0xa016, 0x2d04, 0xa210, 0x8d68, 0x8109, 0x1dd8, 0xa285, 0x0000,
+	0x1118, 0x70c3, 0x4000, 0x0010, 0x70c3, 0x4003, 0x70ca, 0x0804,
+	0x13bd, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x1a04, 0x13b3,
+	0x7966, 0x0804, 0x13ba, 0x7964, 0x71c6, 0x0804, 0x13ba, 0x7900,
+	0x71c6, 0x71c4, 0x7902, 0x0804, 0x13ba, 0x7900, 0x71c6, 0x0804,
+	0x13ba, 0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0160, 0x810c,
+	0x0230, 0x8210, 0x810c, 0x810c, 0x0210, 0x8210, 0x810c, 0x81ff,
+	0x1904, 0x13b4, 0x8210, 0x7a0e, 0xd28c, 0x0538, 0x7910, 0xc1cd,
+	0x7912, 0x2009, 0x0021, 0x2019, 0x0003, 0xd284, 0x01c0, 0x8108,
+	0x2019, 0x0041, 0x2011, 0x8e4e, 0x2312, 0x2019, 0x0042, 0x8210,
+	0x2312, 0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210,
+	0x2312, 0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011,
+	0x8e53, 0x2112, 0x2011, 0x8e73, 0x2312, 0x7904, 0x7806, 0x0804,
+	0x13b9, 0x7804, 0x70c6, 0x0804, 0x13ba, 0x71c4, 0xd1fc, 0x1118,
+	0x2011, 0x4ac0, 0x0010, 0x2011, 0x4b40, 0x8107, 0xa084, 0x000f,
+	0x8003, 0x8003, 0x8003, 0xa268, 0x2011, 0x0000, 0x6814, 0xd0fc,
+	0x0110, 0xa295, 0x0200, 0xd0b4, 0x0110, 0xa295, 0x0001, 0x6b0c,
+	0x6800, 0x70da, 0x0804, 0x13b7, 0x7814, 0xd0f4, 0x0130, 0x2001,
+	0x4007, 0x70db, 0x0000, 0xa005, 0x0048, 0xd0fc, 0x0130, 0x2001,
+	0x4007, 0x70db, 0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7814,
+	0xd0f4, 0x0130, 0x2001, 0x4007, 0x70db, 0x0000, 0xa005, 0x0008,
+	0xa006, 0x0005, 0x7814, 0xd0fc, 0x0130, 0x2001, 0x4007, 0x70db,
+	0x0001, 0xa005, 0x0008, 0xa006, 0x0005, 0x7112, 0x721a, 0x731e,
+	0x7810, 0xd0c4, 0x0110, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108,
+	0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084,
+	0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0140,
+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018,
+	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
+	0x7d10, 0xd5c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008,
+	0xd0fc, 0x0de8, 0x7003, 0x0001, 0x7007, 0x0006, 0x711a, 0x721e,
+	0x7d10, 0xd5c4, 0x0110, 0x7322, 0x7426, 0xa084, 0x01e0, 0x0005,
+	0x7848, 0xa065, 0x0120, 0x2c04, 0x784a, 0x2063, 0x0000, 0x0005,
+	0x00f6, 0x2079, 0x4600, 0x7848, 0x2062, 0x2c00, 0xa005, 0x1110,
+	0x080c, 0x254c, 0x784a, 0x00fe, 0x0005, 0x2011, 0x9000, 0x7a4a,
+	0x7bc4, 0x8319, 0x0128, 0xa280, 0x0032, 0x2012, 0x2010, 0x0cc8,
+	0x2013, 0x0000, 0x0005, 0x0016, 0x0026, 0xd7fc, 0x1118, 0x2011,
+	0x4bc0, 0x0010, 0x2011, 0x6bc0, 0xa784, 0x0f00, 0x800b, 0xa784,
+	0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xa268,
+	0x002e, 0x001e, 0x0005, 0x0c39, 0x2900, 0x682a, 0x2a00, 0x682e,
+	0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a, 0x00e6, 0xd7fc, 0x1128,
+	0x2009, 0x4652, 0x2071, 0x4640, 0x0020, 0x2009, 0x4692, 0x2071,
+	0x4680, 0x210c, 0x6804, 0xa005, 0x0148, 0xa116, 0x1138, 0x2060,
+	0x6000, 0x6806, 0x0016, 0x200b, 0x0000, 0x0018, 0x2009, 0x0000,
+	0x0016, 0x6804, 0xa065, 0x0178, 0x6000, 0x6806, 0x0421, 0x080c,
+	0x1d95, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x6812, 0x1d88,
+	0x7910, 0xc1a5, 0x7912, 0x001e, 0x6902, 0x6906, 0x2d00, 0x2060,
+	0x080c, 0x2693, 0x00ee, 0x0005, 0xa065, 0x0160, 0x2008, 0x609c,
+	0xa005, 0x0128, 0x2062, 0x609f, 0x0000, 0xa065, 0x0cc0, 0x7848,
+	0x794a, 0x2062, 0x0005, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
+	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
+	0x601a, 0x682c, 0x6022, 0x0005, 0x00e6, 0xd7fc, 0x1128, 0x2071,
+	0x4640, 0x2031, 0x46c0, 0x0020, 0x2071, 0x4680, 0x2031, 0x48c0,
+	0x704c, 0xa08c, 0x0200, 0x1128, 0xa608, 0x2d0a, 0x8000, 0x704e,
+	0xa006, 0x00ee, 0x0005, 0x00f6, 0xd7fc, 0x1118, 0x2079, 0x4640,
+	0x0010, 0x2079, 0x4680, 0x080c, 0x1b7b, 0x2091, 0x8000, 0x6804,
+	0x780a, 0xa065, 0x05f0, 0x0030, 0x2c00, 0x780a, 0x2060, 0x6000,
+	0xa065, 0x05b8, 0x6010, 0xa306, 0x1db8, 0x600c, 0xa206, 0x1da0,
+	0x2c28, 0x7848, 0xac06, 0x1108, 0x0448, 0x6804, 0xac06, 0x1140,
+	0x6000, 0x2060, 0x6806, 0xa005, 0x1118, 0x6803, 0x0000, 0x0048,
+	0x6400, 0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x1110, 0x2c00,
+	0x6802, 0x2560, 0x080c, 0x1be3, 0x601b, 0x0005, 0x6023, 0x0020,
+	0x00fe, 0x080c, 0x1d95, 0x00f6, 0x7908, 0x8109, 0x790a, 0x6810,
+	0x8001, 0x6812, 0x1118, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff,
+	0xa005, 0x00fe, 0x0005, 0x0076, 0x2700, 0x2039, 0x0000, 0xd0fc,
+	0x0108, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
+	0x2091, 0x8000, 0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0,
+	0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x1d90,
+	0x2091, 0x8001, 0x007e, 0x0005, 0x786c, 0x2009, 0x8e74, 0x210c,
+	0xa10d, 0x0118, 0xa065, 0x0804, 0x207a, 0x2061, 0x0000, 0x6018,
+	0xd084, 0x11b8, 0x7810, 0xd08c, 0x0130, 0xc08c, 0x7812, 0xc7fc,
+	0x2069, 0x4640, 0x0028, 0xc08d, 0x7812, 0x2069, 0x4680, 0xc7fd,
+	0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091, 0x8001, 0xa005,
+	0x1108, 0x0005, 0xa08c, 0xfff0, 0x0110, 0x080c, 0x254c, 0x0002,
+	0x1cb8, 0x1cbb, 0x1cc1, 0x1cc5, 0x1cb9, 0x1cc9, 0x1cb9, 0x1cb9,
+	0x1cb9, 0x1ccf, 0x1cfb, 0x1cfe, 0x1d03, 0x1d0c, 0x1cb9, 0x1cb9,
+	0x0005, 0x080c, 0x254c, 0x080c, 0x1c5b, 0x2001, 0x8001, 0x0804,
+	0x1d15, 0x2001, 0x8003, 0x0804, 0x1d15, 0x2001, 0x8004, 0x0804,
+	0x1d15, 0x080c, 0x1c5b, 0x2001, 0x8006, 0x0804, 0x1d15, 0x2091,
+	0x8000, 0x0076, 0xd7fc, 0x1128, 0x2069, 0x4640, 0x2039, 0x0009,
+	0x0020, 0x2069, 0x4680, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000,
+	0x0128, 0x000e, 0x6f1e, 0x2091, 0x8001, 0x0005, 0x6870, 0x007e,
+	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
+	0x080c, 0x1b93, 0x8738, 0xa784, 0x001f, 0x1dd0, 0x2091, 0x8001,
+	0x2001, 0x800a, 0x00d0, 0x2001, 0x800c, 0x00b8, 0x080c, 0x1c5b,
+	0x2001, 0x800d, 0x0090, 0xd7fc, 0x0110, 0x78e4, 0x0008, 0x78e0,
+	0x70c6, 0x2001, 0x800e, 0x0048, 0xd7fc, 0x0110, 0x78ec, 0x0008,
+	0x78e8, 0x70c6, 0x2001, 0x800f, 0x0000, 0x70c2, 0xd7fc, 0x1118,
+	0x70db, 0x0000, 0x0010, 0x70db, 0x0001, 0x2061, 0x0000, 0x601b,
+	0x0001, 0x2091, 0x4080, 0x0005, 0xac80, 0x0001, 0x81ff, 0x0518,
+	0x2099, 0x0030, 0x20a0, 0x700c, 0xa084, 0x07ff, 0x0100, 0x7018,
+	0x0006, 0x701c, 0x0006, 0x7020, 0x0006, 0x7024, 0x0006, 0x7112,
+	0x81ac, 0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007,
+	0x0001, 0x7008, 0x800b, 0x1ee8, 0x7007, 0x0002, 0xa08c, 0x01e0,
+	0x1110, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x000e,
+	0x7026, 0x000e, 0x7022, 0x000e, 0x701e, 0x000e, 0x701a, 0x0005,
+	0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x681f, 0x0201,
+	0x6803, 0xfd20, 0x6807, 0x0038, 0x6a1a, 0x2d00, 0xa0e8, 0x0008,
+	0xa290, 0x0004, 0x8109, 0x1d80, 0x0005, 0x70ec, 0xd0dc, 0x1520,
+	0x2029, 0x0001, 0x7814, 0xd0cc, 0x1160, 0x70ec, 0xd0e4, 0x2019,
+	0x0c0a, 0x2021, 0x000a, 0x1120, 0x2019, 0x0c0c, 0x2021, 0x000c,
+	0x0070, 0x70ec, 0xd0e4, 0x1128, 0x2019, 0x180c, 0x2021, 0x000c,
+	0x0030, 0x2019, 0x1809, 0x2021, 0x0009, 0xa5ad, 0x0200, 0x6b0a,
+	0x6c0e, 0x6d1e, 0x6807, 0x0038, 0x0005, 0x6004, 0x6086, 0x2c08,
+	0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0110, 0x2c02, 0x0008,
+	0x796e, 0x0005, 0x00c6, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08,
+	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008,
+	0x616e, 0x00ce, 0x0005, 0x2091, 0x8000, 0x2c04, 0x786e, 0xa005,
+	0x1108, 0x786a, 0x2091, 0x8001, 0x609c, 0xa005, 0x0188, 0x00c6,
+	0x2060, 0x2008, 0x609c, 0xa005, 0x0138, 0x2062, 0x609f, 0x0000,
+	0xa065, 0x609c, 0xa005, 0x1dc8, 0x7848, 0x794a, 0x2062, 0x00ce,
+	0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x1110, 0x080c,
+	0x254c, 0x784a, 0x0005, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086,
+	0x818e, 0x1208, 0xa200, 0x1f04, 0x1ddf, 0x8086, 0x818e, 0x0005,
+	0x0156, 0x20a9, 0x0010, 0xa005, 0x01b8, 0xa11a, 0x12a8, 0x8213,
+	0x818d, 0x0228, 0xa11a, 0x1220, 0x1f04, 0x1def, 0x0028, 0xa11a,
+	0x2308, 0x8210, 0x1f04, 0x1def, 0x0006, 0x3200, 0xa084, 0xefff,
+	0x2080, 0x000e, 0x015e, 0x0005, 0x0006, 0x3200, 0xa085, 0x1000,
+	0x0cb8, 0x7d74, 0x70d0, 0xa506, 0x0904, 0x1ebd, 0x7810, 0x2050,
+	0x080c, 0x1b58, 0x0904, 0x1ebd, 0xa046, 0x7970, 0x2500, 0x8000,
+	0xa112, 0x2009, 0x0040, 0x1208, 0x0030, 0x72d0, 0xa206, 0x0118,
+	0x8840, 0x2009, 0x0080, 0x00c6, 0x7112, 0x7007, 0x0001, 0x2099,
+	0x0030, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000,
+	0x88ff, 0x0110, 0x080c, 0x1b58, 0x7008, 0xd0fc, 0x0de8, 0x7007,
+	0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x1538, 0x53a5, 0x8cff,
+	0x1120, 0x88ff, 0x0904, 0x1eaa, 0x0050, 0x2c00, 0x788e, 0x20a9,
+	0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0804, 0x1eaa, 0xa046,
+	0x7218, 0x731c, 0xdac4, 0x0110, 0x7420, 0x7524, 0xa292, 0x0040,
+	0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000, 0x721a, 0x731e,
+	0xdac4, 0x0118, 0x7422, 0x7526, 0xa006, 0x7007, 0x0004, 0x0904,
+	0x1eaa, 0x8cff, 0x0110, 0x080c, 0x1b60, 0x00ce, 0x080c, 0x1b60,
+	0xa046, 0x7888, 0x8000, 0x788a, 0xa086, 0x0002, 0x01c0, 0x7a7c,
+	0x7b78, 0xdac4, 0x0110, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004,
+	0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
+	0x721a, 0x731e, 0xdac4, 0x0588, 0x7422, 0x7526, 0x0470, 0x6014,
+	0xd0fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091,
+	0x8000, 0x681f, 0x0002, 0x88ff, 0x0120, 0xa046, 0x788c, 0x2060,
+	0x0c70, 0x788b, 0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091,
+	0x8001, 0x0098, 0x00ce, 0x788b, 0x0000, 0x080c, 0x2035, 0x6004,
+	0xa084, 0x000f, 0x0059, 0x88ff, 0x0130, 0x788c, 0x2060, 0x6004,
+	0xa084, 0x000f, 0x0019, 0x0804, 0x1e09, 0x0005, 0x0002, 0x1ecf,
+	0x1eea, 0x1f03, 0x1ecf, 0x1f10, 0x1ee0, 0x1ecf, 0x1ecf, 0x1ecf,
+	0x1ee8, 0x1f01, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x1ecf, 0x2039,
+	0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a, 0x080c,
+	0x1f4c, 0x609c, 0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0005,
+	0x78bc, 0xd0c4, 0x0108, 0x0c58, 0x601c, 0xc0bd, 0x601e, 0x0030,
+	0x080c, 0x205f, 0x78bc, 0xd0c4, 0x0108, 0x0c08, 0x78bf, 0x0000,
+	0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0138, 0x080c,
+	0x1f4c, 0x0120, 0x78bc, 0xc0c5, 0x78be, 0x0010, 0x0804, 0x1f67,
+	0x0005, 0x080c, 0x205c, 0x78bc, 0xa08c, 0x0e00, 0x1110, 0xd0c4,
+	0x1108, 0x0828, 0x080c, 0x1f4c, 0x1110, 0x0804, 0x1f67, 0x0005,
+	0x78bc, 0xd0c4, 0x0110, 0x0804, 0x1ecf, 0x78bf, 0x0000, 0x6714,
+	0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0188,
+	0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0150, 0xa7bc,
+	0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0108,
+	0x00c0, 0x080c, 0x1b7b, 0x2d00, 0x2091, 0x8000, 0x682b, 0x0000,
+	0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a, 0xade8, 0x0010,
+	0x2091, 0x8001, 0x1f04, 0x1f34, 0x8211, 0x0118, 0x20a9, 0x0100,
+	0x0c58, 0x080c, 0x1b60, 0x0005, 0x609f, 0x0000, 0x78b4, 0xa06d,
+	0x2c00, 0x78b6, 0x1110, 0x78ba, 0x0038, 0x689e, 0x2d00, 0x6002,
+	0x78b8, 0xad06, 0x1108, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x1130,
+	0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x0005, 0x00e6,
+	0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2,
+	0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0110, 0x080c,
+	0x3fc1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071, 0x4680,
+	0xd7fc, 0x1110, 0x2071, 0x4640, 0xa784, 0x0f00, 0x800b, 0xa784,
+	0x001f, 0x0120, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0x71c0,
+	0xa168, 0x2700, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
+	0x71c4, 0xa100, 0x60c2, 0x2091, 0x8000, 0x7814, 0xd0c4, 0x0138,
+	0xd7fc, 0x1118, 0xd0f4, 0x1140, 0x0010, 0xd0fc, 0x1128, 0x6e08,
+	0xd684, 0x01f0, 0xd9fc, 0x11e0, 0x2091, 0x8001, 0x080c, 0x1be3,
+	0x2091, 0x8000, 0x080c, 0x1d95, 0x2091, 0x8001, 0x7814, 0xd0c4,
+	0x0904, 0x201f, 0xd7fc, 0x1120, 0xd0f4, 0x1130, 0x0804, 0x201f,
+	0xd0fc, 0x1110, 0x0804, 0x201f, 0x601b, 0x0021, 0x0804, 0x201f,
+	0x6024, 0xa096, 0x0001, 0x1110, 0x8000, 0x6026, 0x6a10, 0x6814,
+	0xa202, 0x0268, 0x0160, 0x2091, 0x8001, 0x2039, 0x0200, 0x609c,
+	0x78ba, 0x609f, 0x0000, 0x080c, 0x2021, 0x0804, 0x201f, 0x2c08,
+	0xd9fc, 0x01f0, 0x6800, 0xa065, 0x01d8, 0x6a04, 0x7000, 0xa084,
+	0x0002, 0x0168, 0x7048, 0xa206, 0x1150, 0x6b04, 0x2160, 0x2304,
+	0x6002, 0xa005, 0x1108, 0x6902, 0x2260, 0x6102, 0x0098, 0x2d00,
+	0x2060, 0x080c, 0x2693, 0x6e08, 0x2160, 0x6202, 0x6906, 0x0050,
+	0x6800, 0x6902, 0xa065, 0x0110, 0x6102, 0x0008, 0x6906, 0x2160,
+	0x6003, 0x0000, 0x2160, 0xd9fc, 0x0118, 0xa6b4, 0xfffc, 0x6e0a,
+	0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001,
+	0xd6b4, 0x0128, 0xa6b6, 0x0040, 0x6e0a, 0x080c, 0x1bf4, 0x00ee,
+	0x0005, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x080c, 0x1d95,
+	0x2091, 0x8001, 0x78b8, 0xa065, 0x0128, 0x609c, 0x78ba, 0x609f,
+	0x0000, 0x0c78, 0x78b6, 0x78ba, 0x0005, 0x7970, 0x7874, 0x2818,
+	0xd384, 0x0118, 0x8000, 0xa112, 0x0220, 0x8000, 0xa112, 0x1278,
+	0xc384, 0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0120, 0x7a84,
+	0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0108, 0x8000, 0x7876,
+	0x70d2, 0x781c, 0xa005, 0x0138, 0x8001, 0x781e, 0x1120, 0x0e04,
+	0x205b, 0x2091, 0x4080, 0x0005, 0x2039, 0x2071, 0x0010, 0x2039,
+	0x2077, 0x2704, 0xa005, 0x0160, 0xac00, 0x2068, 0x6908, 0x6810,
+	0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e, 0x8738, 0x0c88,
+	0x0005, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015,
+	0x001b, 0x0000, 0x2041, 0x0000, 0x780c, 0x0002, 0x2223, 0x21fe,
+	0x2082, 0x20f2, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00c0, 0x6084,
+	0xa086, 0x0103, 0x1904, 0x20dc, 0x6114, 0x6018, 0xa105, 0x0120,
+	0x86ff, 0x11d8, 0x0804, 0x20dc, 0x8603, 0xa080, 0x8e55, 0x620c,
+	0x2202, 0x8000, 0x6210, 0x2202, 0x080c, 0x1db3, 0x8630, 0xa68e,
+	0x000f, 0x0904, 0x215d, 0x786c, 0xa065, 0x1d08, 0x7808, 0xa602,
+	0x1220, 0xd5ac, 0x1110, 0x263a, 0x0005, 0xa682, 0x0003, 0x1a04,
+	0x215d, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x11f8,
+	0x2011, 0x8e55, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca, 0xd684,
+	0x1130, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204, 0x70de, 0xa685,
+	0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084,
+	0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000, 0x0005, 0x7810,
+	0xc0ad, 0x7812, 0x0804, 0x215d, 0x263a, 0x080c, 0x2229, 0x1904,
+	0x2245, 0x786c, 0xa065, 0x1904, 0x2087, 0x2091, 0x8000, 0x7810,
+	0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad, 0x7812, 0x2091, 0x8001,
+	0x0804, 0x2245, 0x2039, 0x8e74, 0x2734, 0x7d10, 0x00a0, 0x6084,
+	0xa086, 0x0103, 0x1904, 0x2147, 0x6114, 0x6018, 0xa105, 0x0120,
+	0x86ff, 0x11b8, 0x0804, 0x2147, 0xa680, 0x8e55, 0x620c, 0x2202,
+	0x080c, 0x1db3, 0x8630, 0xa68e, 0x001e, 0x0904, 0x215d, 0x786c,
+	0xa065, 0x1d28, 0x7808, 0xa602, 0x1220, 0xd5ac, 0x1110, 0x263a,
+	0x0005, 0xa682, 0x0006, 0x1a04, 0x215d, 0x2091, 0x8000, 0x2069,
+	0x0000, 0x6818, 0xd084, 0x11f8, 0x2011, 0x8e55, 0x2009, 0x8e4e,
+	0x26a8, 0x211c, 0x2204, 0x201a, 0x8108, 0x8210, 0x1f04, 0x2129,
+	0xa685, 0x8030, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080, 0x7810,
+	0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0xa006, 0x2009, 0x8e75,
+	0x200a, 0x203a, 0x0005, 0x7810, 0xc0ad, 0x7812, 0x00b0, 0x263a,
+	0x080c, 0x2229, 0x1904, 0x2245, 0x786c, 0xa065, 0x1904, 0x20f7,
+	0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0108, 0xc0ad,
+	0x7812, 0x2091, 0x8001, 0x0804, 0x2245, 0x2091, 0x8000, 0x7007,
+	0x0004, 0x7994, 0x70d4, 0xa102, 0x0228, 0x0168, 0x7b90, 0xa302,
+	0x1150, 0x0010, 0x8002, 0x1138, 0x263a, 0x7810, 0xc0ad, 0x7812,
+	0x2091, 0x8001, 0x0005, 0xa184, 0xff00, 0x0140, 0x810f, 0x810c,
 	0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018, 0x8107, 0x8004,
-	0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319,
-	0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005, 0x0110, 0x2009,
-	0x0040, 0x080c, 0x1ab7, 0x01d0, 0x78a8, 0x8000, 0x78aa, 0xd08c,
-	0x1510, 0x6014, 0xd0fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069,
-	0x4380, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac,
-	0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0068, 0x78ab, 0x0000,
-	0x080c, 0x1d4e, 0x7990, 0x7894, 0x8000, 0xa10a, 0x1208, 0xa006,
-	0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001, 0x0005,
-	0x2138, 0xd7fc, 0x1118, 0x2009, 0x4359, 0x0010, 0x2009, 0x4399,
-	0x2091, 0x8000, 0x200a, 0x00f6, 0x2009, 0x4380, 0x2079, 0x0100,
-	0xd7fc, 0x1120, 0x2009, 0x4340, 0x2079, 0x0200, 0x2104, 0xa086,
-	0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009, 0x4345, 0x0010, 0x2009,
-	0x4385, 0x2104, 0xa005, 0x1130, 0x7830, 0xa084, 0x00c0, 0x1110,
-	0x781b, 0x0052, 0x00fe, 0x0005, 0x2009, 0x0002, 0x2069, 0x4300,
-	0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904, 0x22a9, 0x2071, 0x4380,
-	0x2079, 0x0100, 0x2021, 0x45bf, 0x784b, 0x000f, 0x2001, 0x01ff,
-	0x2004, 0xd0fc, 0x0118, 0x2019, 0x3c3b, 0x0030, 0x20a1, 0x012b,
-	0x2019, 0x3c3b, 0xd184, 0x0110, 0x20a1, 0x022b, 0x2304, 0xa005,
-	0x0140, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318,
-	0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af,
-	0x0000, 0x78af, 0x2020, 0x1f04, 0x2287, 0x7003, 0x0000, 0x0016,
-	0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd, 0x080c, 0x23bd, 0x001e,
-	0x7020, 0xa084, 0x000f, 0xa085, 0x6300, 0x7806, 0x780f, 0x9000,
-	0x7843, 0x00d8, 0x7853, 0x0090, 0x780b, 0x0308, 0x7456, 0x7053,
-	0x0000, 0x8109, 0x0140, 0x2071, 0x4340, 0x2079, 0x0200, 0x2021,
-	0x43bf, 0x0804, 0x2264, 0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc,
-	0x1110, 0x2011, 0x0201, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0,
-	0xa105, 0x2012, 0x001e, 0x080c, 0x23bd, 0x0005, 0x2011, 0x0101,
-	0xd3fc, 0x1110, 0x2011, 0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04,
-	0x22ce, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012,
-	0x0005, 0x2019, 0x0002, 0x2009, 0x0101, 0x20a9, 0x0005, 0x8213,
-	0x1f04, 0x22df, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205,
-	0x200a, 0x8319, 0x0118, 0x2009, 0x0201, 0x0c78, 0x0005, 0x2011,
-	0x0101, 0xd3fc, 0x1110, 0x2011, 0x0201, 0x20a9, 0x000c, 0x810b,
-	0x1f04, 0x22f7, 0xa18c, 0xf000, 0x2204, 0xa084, 0x0fff, 0xa105,
-	0x2012, 0x0005, 0x2011, 0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202,
-	0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x0005, 0x00c6, 0x2061,
-	0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003,
-	0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6,
+	0x8004, 0x7a9c, 0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e,
+	0xd4c4, 0x0130, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226,
+	0x20a1, 0x0030, 0x7003, 0x0000, 0x2009, 0x8e54, 0x260a, 0x8109,
+	0x2198, 0x2104, 0xd084, 0x0108, 0x8633, 0xa6b0, 0x0002, 0x26a8,
+	0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000,
+	0xa10a, 0x1208, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0140,
+	0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0018,
+	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
+	0xd4c4, 0x0120, 0x7b84, 0xa319, 0x7c80, 0xa421, 0x7008, 0xd0fc,
+	0x0de8, 0xa084, 0x01e0, 0x01d0, 0x7d10, 0x2031, 0x8e54, 0x2634,
+	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1138, 0x7007, 0x0006, 0x7004,
+	0xd094, 0x1de8, 0x0804, 0x215f, 0x2069, 0x4647, 0x206b, 0x0003,
+	0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0048, 0x2030, 0x75d6,
+	0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091,
+	0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a,
+	0x721e, 0xd5c4, 0x0110, 0x7322, 0x7426, 0x0005, 0x6084, 0xa086,
+	0x0103, 0x11d8, 0x6114, 0x6018, 0xa105, 0x11b8, 0x2069, 0x0000,
+	0x6818, 0xd084, 0x1190, 0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3,
+	0x8020, 0x681b, 0x0001, 0x2091, 0x4080, 0x080c, 0x1db3, 0x0e04,
+	0x221c, 0x786c, 0xa065, 0x1d10, 0x0005, 0x0059, 0x1530, 0x786c,
+	0xa065, 0x19e0, 0x0410, 0x0029, 0x1500, 0x786c, 0xa065, 0x1dd8,
+	0x00e0, 0x6084, 0xa086, 0x0103, 0x1168, 0x6018, 0xc0fc, 0x601a,
+	0xa086, 0x0004, 0x1138, 0x7804, 0xd0a4, 0x0120, 0x080c, 0x1db3,
+	0xa006, 0x0005, 0x0079, 0x1118, 0xa085, 0x0001, 0x0005, 0x00b9,
+	0x1110, 0x2041, 0x0001, 0x7d10, 0x0005, 0x88ff, 0x0110, 0x2091,
+	0x4080, 0x0005, 0x7b90, 0x7994, 0x70d4, 0xa102, 0x1118, 0xa385,
+	0x0000, 0x0005, 0x0210, 0xa302, 0x0005, 0x8002, 0x0005, 0xa184,
+	0xff00, 0x0140, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
+	0xa100, 0x0018, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4,
+	0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018,
+	0x6028, 0xa005, 0x0110, 0x2009, 0x0040, 0x080c, 0x1b15, 0x01d0,
+	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x1510, 0x6014, 0xd0fc, 0x1118,
+	0x2069, 0x4640, 0x0010, 0x2069, 0x4680, 0x2091, 0x8000, 0x681f,
+	0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091,
+	0x8001, 0x0068, 0x78ab, 0x0000, 0x080c, 0x1db3, 0x7990, 0x7894,
+	0x8000, 0xa10a, 0x1208, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071,
+	0x0010, 0x2091, 0x8001, 0x0005, 0xd7fc, 0x1118, 0x2009, 0x4658,
+	0x0010, 0x2009, 0x4698, 0x2091, 0x8000, 0x200a, 0x00f6, 0x2009,
+	0x4680, 0x2079, 0x0100, 0xd7fc, 0x1120, 0x2009, 0x4640, 0x2079,
+	0x0200, 0x2104, 0xa086, 0x0000, 0x1180, 0xd7fc, 0x1118, 0x2009,
+	0x4645, 0x0010, 0x2009, 0x4685, 0x2104, 0xa005, 0x1130, 0x7830,
+	0xa084, 0x00c0, 0x1110, 0x781b, 0x0052, 0x00fe, 0x0005, 0x2009,
+	0x0002, 0x2069, 0x4600, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1904,
+	0x2324, 0x2071, 0x4680, 0x2079, 0x0100, 0x2021, 0x48bf, 0x784b,
+	0x000f, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x0118, 0x2019, 0x3e0f,
+	0x0030, 0x20a1, 0x012b, 0x2019, 0x3e0f, 0xd184, 0x0110, 0x20a1,
+	0x022b, 0x2304, 0xa005, 0x0140, 0x789a, 0x8318, 0x23ac, 0x8318,
+	0x2398, 0x53a6, 0x3318, 0x0ca8, 0x789b, 0x0000, 0x789b, 0x0020,
+	0x20a9, 0x0010, 0x78af, 0x0000, 0x78af, 0x2020, 0x1f04, 0x2302,
+	0x7003, 0x0000, 0x0016, 0xd18c, 0x2009, 0x0000, 0x0108, 0xc1bd,
+	0x080c, 0x2443, 0x001e, 0x7020, 0xa084, 0x000f, 0xa085, 0x6300,
+	0x7806, 0x780f, 0x9000, 0x7843, 0x00d8, 0x7853, 0x0090, 0x780b,
+	0x2f08, 0x7452, 0x704f, 0x0000, 0x8109, 0x0140, 0x2071, 0x4640,
+	0x2079, 0x0200, 0x2021, 0x46bf, 0x0804, 0x22df, 0x080c, 0x24fd,
+	0x0005, 0x0016, 0x2011, 0x0101, 0xd1bc, 0x1110, 0x2011, 0x0201,
+	0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105, 0x2012, 0x001e,
+	0x080c, 0x2443, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110, 0x2011,
+	0x0201, 0x20a9, 0x0009, 0x810b, 0x1f04, 0x234b, 0xa18c, 0x0e00,
+	0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x0005, 0x2019, 0x0002,
+	0x2009, 0x0101, 0x20a9, 0x0005, 0x8213, 0x1f04, 0x235c, 0xa294,
+	0x00e0, 0x2104, 0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0118,
+	0x2009, 0x0201, 0x0c78, 0x0005, 0x2011, 0x0101, 0xd3fc, 0x1110,
+	0x2011, 0x0201, 0x20a9, 0x000c, 0x810b, 0x1f04, 0x2374, 0xa18c,
+	0xf000, 0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x0005, 0x2011,
+	0x0102, 0xd3fc, 0x1110, 0x2011, 0x0202, 0x2204, 0xa084, 0xf0cf,
+	0xa105, 0x2012, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110,
+	0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a,
+	0x62ac, 0x63ac, 0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc,
+	0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022,
+	0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x00ce, 0x0005, 0x00c6,
 	0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061, 0x0200, 0xc1bc, 0x8103,
-	0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae,
-	0x00ce, 0x0005, 0x00c6, 0x2061, 0x0100, 0xd1bc, 0x1110, 0x2061,
-	0x0200, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4,
-	0xa28c, 0x0020, 0x0118, 0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4,
-	0x1108, 0xc3ed, 0x62ae, 0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce,
-	0x0005, 0x2091, 0x8000, 0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904,
-	0x23a1, 0xd1fc, 0x0118, 0x2061, 0x8ad0, 0x0010, 0x2061, 0x89c0,
-	0x080c, 0x23a9, 0x0538, 0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061,
-	0x89d0, 0x0010, 0x2061, 0x88c0, 0x00c6, 0x04d9, 0x0128, 0x00ce,
-	0x8c60, 0x1f04, 0x236c, 0x0468, 0x000e, 0xd1fc, 0x0128, 0xa082,
-	0x89d0, 0x2071, 0x4380, 0x0020, 0xa082, 0x88c0, 0x2071, 0x4340,
-	0x707a, 0x7176, 0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x080c,
-	0x2228, 0x00a0, 0xd1fc, 0x1118, 0x2071, 0x4340, 0x0010, 0x2071,
-	0x4380, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e, 0x2001,
-	0x0006, 0x7066, 0x7083, 0x000f, 0x080c, 0x2228, 0x2001, 0x0000,
-	0x0010, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce,
-	0x0005, 0x2c04, 0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140,
-	0x600c, 0xa206, 0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020,
-	0x6000, 0x0c80, 0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016,
-	0x2079, 0x4380, 0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4340,
-	0x2071, 0x0200, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110,
-	0x001e, 0x0060, 0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d,
-	0x0800, 0xd0bc, 0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe,
-	0x0005, 0x00e6, 0x2001, 0x4301, 0x2004, 0xd0ac, 0x1904, 0x2439,
-	0x68e4, 0xd0ac, 0x0904, 0x2439, 0xa084, 0x0006, 0x1904, 0x2439,
-	0x6014, 0xd0fc, 0x1118, 0x2071, 0x47c0, 0x0010, 0x2071, 0x4840,
-	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004,
-	0xa084, 0x000a, 0x15b0, 0x7108, 0xa194, 0xff00, 0x0590, 0xa18c,
-	0x00ff, 0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106,
-	0x01a0, 0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106,
-	0x0190, 0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106,
-	0x0180, 0x0090, 0x2009, 0x000c, 0x0088, 0x2009, 0x0012, 0x0070,
-	0x2009, 0x0014, 0x0058, 0x2009, 0x0019, 0x0040, 0x2009, 0x0020,
-	0x0028, 0x2009, 0x003f, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205,
-	0x700a, 0x00ee, 0x0005, 0x0e04, 0x243b, 0x2091, 0x8000, 0x2071,
-	0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071, 0x0010,
-	0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a01, 0x70df,
-	0x0013, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080, 0x0cf8,
-	0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e, 0x7592, 0x7496,
-	0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc, 0x1128,
-	0xa784, 0x007d, 0x1904, 0x3ace, 0x0871, 0xa49c, 0x000f, 0xa382,
-	0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507, 0xa084,
-	0x000f, 0x0002, 0x2a4f, 0x2b10, 0x2b38, 0x2d71, 0x30cc, 0x3112,
-	0x31a7, 0x3220, 0x32db, 0x33a6, 0x248d, 0x248a, 0x285b, 0x295c,
-	0x30a0, 0x248a, 0x080c, 0x243b, 0x0005, 0xa006, 0x0038, 0x7808,
-	0xc08d, 0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060,
-	0xa005, 0x1904, 0x25d9, 0x7064, 0xa084, 0x0007, 0x0002, 0x24a7,
-	0x2513, 0x251b, 0x2524, 0x252d, 0x25bf, 0x2536, 0x2513, 0x7830,
-	0xd0bc, 0x1d10, 0x71d4, 0xd1b4, 0x1904, 0x24f0, 0x70a4, 0xa086,
-	0x0001, 0x09d0, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b,
-	0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d,
-	0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0,
-	0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804, 0x270a, 0x7060, 0xa005,
-	0x1904, 0x248c, 0x00c6, 0x00d6, 0x70b4, 0xa06d, 0x6800, 0xa065,
-	0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10,
-	0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc, 0x7daa,
-	0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0804, 0x270a,
-	0x080c, 0x3a8d, 0x1904, 0x248c, 0x781b, 0x0068, 0x70bc, 0xa06d,
-	0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
-	0x7808, 0xc08d, 0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8,
-	0xa065, 0x68c0, 0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80,
-	0x0009, 0x7046, 0x0005, 0x080c, 0x3a8d, 0x1120, 0x781b, 0x0054,
-	0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, 0x2011, 0x000c,
-	0x0419, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128, 0x2011,
-	0x0006, 0x00d1, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d, 0x1128,
-	0x2011, 0x000d, 0x0089, 0x7003, 0x0004, 0x0005, 0x080c, 0x3a8d,
-	0x1150, 0x2011, 0x0006, 0x0041, 0x707c, 0x707f, 0x0000, 0x2068,
-	0x704e, 0x7003, 0x0001, 0x0005, 0x7174, 0xc1fc, 0x8107, 0x7882,
-	0x789b, 0x0080, 0xa286, 0x000c, 0x1120, 0x7aaa, 0x2001, 0x0001,
-	0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d,
-	0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038, 0x78ab, 0x0020, 0x7178,
-	0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa, 0x785b,
-	0x0004, 0x781b, 0x0113, 0x080c, 0x3aa0, 0x7083, 0x000f, 0x70d4,
-	0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, 0x70b8, 0xa065, 0x6008,
-	0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005,
-	0x7014, 0xa005, 0x1138, 0x70d4, 0xd0b4, 0x0128, 0x70b8, 0xac06,
-	0x1110, 0x0c29, 0x0005, 0x0016, 0x71a4, 0xa186, 0x0001, 0x0528,
-	0x00d6, 0x0026, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068,
-	0x6800, 0xac06, 0x0120, 0x8211, 0x01b0, 0x00c9, 0x0cc8, 0x00c6,
-	0x2100, 0x2011, 0x0001, 0xa212, 0x70b4, 0x2068, 0x6800, 0x2060,
-	0x6008, 0xa084, 0xfbef, 0x600a, 0x8211, 0x0110, 0x0041, 0x0cb0,
-	0x70a7, 0x0001, 0x00ce, 0x002e, 0x00de, 0x001e, 0x0005, 0xade8,
-	0x0005, 0x70ac, 0xad06, 0x1110, 0x70a8, 0x2068, 0x0005, 0x080c,
-	0x3a8d, 0x1904, 0x248c, 0x707c, 0x2068, 0x7774, 0x080c, 0x396d,
-	0x2c50, 0x080c, 0x3b28, 0x789b, 0x0080, 0x6814, 0xa084, 0x001f,
-	0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004, 0x0804,
-	0x270f, 0x080c, 0x3a8d, 0x1904, 0x248c, 0x789b, 0x0080, 0x7060,
-	0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6,
-	0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-	0x601a, 0x00ce, 0x080c, 0x396d, 0x2c50, 0x080c, 0x3b28, 0x6824,
-	0xa005, 0x0130, 0xa082, 0x0006, 0x0208, 0x0010, 0x6827, 0x0005,
-	0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041,
-	0x0001, 0x2001, 0x0003, 0x0804, 0x270f, 0xc28d, 0x72d6, 0x72c0,
-	0xa200, 0xa015, 0x7154, 0x8108, 0xa12a, 0x0208, 0x71c0, 0x2164,
-	0x6504, 0x85ff, 0x1170, 0x7156, 0x8421, 0x1da8, 0x70d4, 0xd08c,
-	0x0128, 0x70d0, 0xa005, 0x1110, 0x70d3, 0x000a, 0x0005, 0x2200,
-	0x0c90, 0x70d4, 0xc08c, 0x70d6, 0x70d3, 0x0000, 0x6034, 0xa005,
-	0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0, 0xd7d4, 0x1d80, 0xa784,
-	0x0021, 0x1d68, 0xa784, 0x0002, 0x0130, 0xa784, 0x0004, 0x0d38,
-	0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x1d08, 0xa784, 0x0100,
-	0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc, 0xfeff, 0x670a, 0x2568,
-	0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e, 0x6318, 0x0128, 0x601c,
-	0xa302, 0x0220, 0x0118, 0x0858, 0x83ff, 0x1948, 0x2d58, 0x2c50,
-	0x7156, 0xd7bc, 0x1110, 0x7028, 0x6022, 0xc7bc, 0x670a, 0x68c0,
-	0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c,
-	0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c,
-	0xffbf, 0xd6a4, 0x0110, 0xa39d, 0x0020, 0xa684, 0x000e, 0x1904,
-	0x26c1, 0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001,
-	0x1178, 0x70d4, 0xd0b4, 0x1160, 0x7000, 0xa082, 0x0002, 0x1240,
-	0x7830, 0xd0bc, 0x1128, 0x789b, 0x0080, 0x7baa, 0x0804, 0x2708,
-	0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005, 0x70ac, 0xa606,
-	0x1108, 0x76a8, 0x76b2, 0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a,
-	0x8738, 0x233a, 0x8738, 0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091,
-	0x8000, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000,
-	0x2090, 0xaad5, 0x0000, 0x0120, 0x8421, 0x2200, 0x1904, 0x2612,
-	0x0005, 0xd1dc, 0x0904, 0x35d5, 0x2029, 0x0020, 0xd69c, 0x1120,
-	0x8528, 0xd68c, 0x1108, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108,
-	0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014,
-	0xa706, 0x1dd0, 0x60b8, 0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008,
-	0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x1904, 0x2612, 0x0005,
-	0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5,
-	0x600a, 0x77a4, 0xa786, 0x0001, 0x1904, 0x2698, 0x70d4, 0xd0b4,
-	0x1904, 0x2698, 0x7000, 0xa082, 0x0002, 0x1a04, 0x2698, 0x7830,
-	0xd0bc, 0x1904, 0x2698, 0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa,
-	0x2001, 0x0002, 0x0006, 0x6018, 0x8000, 0x601a, 0x0008, 0x0006,
-	0x2960, 0x6104, 0x2a60, 0x080c, 0x3b3b, 0x1590, 0xa184, 0x0018,
-	0x0180, 0xa184, 0x0010, 0x0118, 0x080c, 0x3776, 0x1548, 0xa184,
-	0x0008, 0x0138, 0x69a0, 0xa184, 0x0600, 0x1118, 0x080c, 0x3696,
-	0x00f8, 0x69a0, 0xa184, 0x1e00, 0x0528, 0xa184, 0x0800, 0x0178,
-	0x00c6, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d,
-	0x0010, 0x6106, 0x00ce, 0x080c, 0x3776, 0x1150, 0x69a0, 0xa184,
-	0x0200, 0x0118, 0x080c, 0x36d9, 0x0018, 0xa184, 0x0400, 0x19f0,
-	0x69a0, 0xa184, 0x1000, 0x0130, 0x6914, 0xa18c, 0xff00, 0x810f,
-	0x080c, 0x231f, 0x002e, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128,
-	0xa086, 0x0060, 0x1110, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6,
-	0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc,
-	0x0168, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a,
-	0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa, 0x3518,
-	0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b,
-	0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0,
-	0xa286, 0x0020, 0x1508, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba,
-	0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002,
-	0x0904, 0x27e0, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa498, 0x0005,
-	0x70ac, 0xa306, 0x1108, 0x73a8, 0x73b6, 0xa286, 0x0010, 0x0904,
-	0x248c, 0x00de, 0x00ce, 0x0005, 0x7000, 0xa005, 0x19e0, 0xa286,
-	0x0002, 0x1904, 0x27f7, 0x080c, 0x3a8d, 0x19a8, 0x6814, 0xc0fc,
-	0x8007, 0x7882, 0x2091, 0x8000, 0x781b, 0x0068, 0x68b4, 0x785a,
-	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001,
-	0x7808, 0xc08d, 0x780a, 0x0126, 0x00d6, 0x00c6, 0x70d4, 0xa084,
-	0x2e00, 0x2090, 0x00ce, 0x00de, 0x012e, 0x2900, 0x705a, 0x68bc,
-	0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046,
-	0x7830, 0xd0bc, 0x0140, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d,
-	0x2091, 0x8000, 0x2090, 0x70a4, 0xa005, 0x1108, 0x0005, 0x8421,
-	0x0de8, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0804, 0x2612, 0xa286,
-	0x0010, 0x1560, 0x080c, 0x3a8d, 0x1904, 0x278b, 0x6814, 0xc0fc,
-	0x8007, 0x7882, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x70a4,
-	0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206, 0x1108,
-	0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002,
-	0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, 0x6bb4, 0xa39d,
-	0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6,
-	0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x0068, 0x2900, 0x705a,
-	0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605, 0x0170, 0x70d4,
-	0xa084, 0x2e00, 0xa086, 0x2600, 0x1118, 0x2009, 0x0000, 0x0010,
-	0x2009, 0x0001, 0xa284, 0x000f, 0x0023, 0xad80, 0x0009, 0x7046,
-	0x0005, 0x2859, 0x3fb8, 0x3fb8, 0x3fa6, 0x3fb8, 0x2859, 0x2859,
-	0x2859, 0x080c, 0x243b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6,
-	0x2079, 0x4300, 0x78ac, 0x00fe, 0xd084, 0x01c0, 0x7064, 0xa086,
-	0x0001, 0x1118, 0x7066, 0x0804, 0x293a, 0x7064, 0xa086, 0x0005,
-	0x1158, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817, 0x0000, 0x6820,
-	0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000,
-	0x70a8, 0x70b2, 0x70b6, 0x080c, 0x256f, 0x0156, 0x2011, 0x0004,
-	0x7164, 0xa186, 0x0001, 0x0170, 0xa186, 0x0007, 0x1118, 0x701f,
-	0x0005, 0x0040, 0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0c5,
-	0x70d6, 0x0010, 0x7067, 0x0000, 0x2001, 0x430a, 0x2004, 0xa084,
-	0x00ff, 0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110,
-	0x70a7, 0x0001, 0x0066, 0x080c, 0x3d52, 0x20a9, 0x0010, 0x2039,
-	0x0000, 0x080c, 0x3861, 0xa7b8, 0x0100, 0x1f04, 0x28b1, 0x006e,
-	0x7000, 0x0002, 0x28ee, 0x28cc, 0x28cc, 0x28c4, 0x28ee, 0x28ee,
-	0x28ee, 0x28c2, 0x080c, 0x243b, 0x7060, 0xa005, 0x0538, 0xad06,
-	0x1118, 0x6800, 0x7062, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14,
-	0x080c, 0x396d, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x35ab, 0x0020,
-	0x705c, 0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818,
-	0xd0fc, 0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820,
-	0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d3d, 0xb284, 0x0800,
-	0x0118, 0x2021, 0x8ad0, 0x0010, 0x2021, 0x89c0, 0x080c, 0x293f,
-	0xb284, 0x0800, 0x0118, 0x2021, 0x4398, 0x0010, 0x2021, 0x4358,
-	0x04f1, 0x20a9, 0x0101, 0xb284, 0x0800, 0x0118, 0x2021, 0x89d0,
-	0x0010, 0x2021, 0x88c0, 0x0499, 0x8420, 0x1f04, 0x290b, 0xb284,
-	0x0600, 0x0118, 0x2061, 0x48c0, 0x0010, 0x2061, 0x68c0, 0x2021,
+	0x8003, 0xa080, 0x0020, 0x609a, 0x60a4, 0xa28c, 0x0020, 0x0118,
+	0xc2ac, 0xa39d, 0x4000, 0xc3ec, 0xd3b4, 0x1108, 0xc3ed, 0x62ae,
+	0x2010, 0x60a4, 0x63ae, 0x2018, 0x00ce, 0x0005, 0x2091, 0x8000,
+	0x00c6, 0x00e6, 0x6818, 0xa005, 0x0904, 0x2427, 0xd1fc, 0x0118,
+	0x2061, 0x8dd0, 0x0010, 0x2061, 0x8cc0, 0x080c, 0x242f, 0x0560,
+	0x20a9, 0x0101, 0xd1fc, 0x0118, 0x2061, 0x8cd0, 0x0010, 0x2061,
+	0x8bc0, 0x00c6, 0x080c, 0x242f, 0x0128, 0x00ce, 0x8c60, 0x1f04,
+	0x23e9, 0x04a8, 0x000e, 0xd1fc, 0x0128, 0xa082, 0x8cd0, 0x2071,
+	0x4680, 0x0020, 0xa082, 0x8bc0, 0x2071, 0x4640, 0x7076, 0x7172,
+	0x2138, 0x2001, 0x0004, 0x7062, 0x707f, 0x000f, 0x71d0, 0xc1c4,
+	0x71d2, 0x080c, 0x22a4, 0x00c0, 0xd1fc, 0x1118, 0x2071, 0x4640,
+	0x0010, 0x2071, 0x4680, 0x6020, 0xc0dd, 0x6022, 0x7172, 0x2138,
+	0x2c00, 0x707a, 0x2001, 0x0006, 0x7062, 0x707f, 0x000f, 0x71d0,
+	0xc1c4, 0x71d2, 0x080c, 0x22a4, 0x2001, 0x0000, 0x0010, 0x2001,
+	0x0001, 0x2091, 0x8001, 0xa005, 0x00ee, 0x00ce, 0x0005, 0x2c04,
+	0xa005, 0x0170, 0x2060, 0x6010, 0xa306, 0x1140, 0x600c, 0xa206,
+	0x1128, 0x6014, 0xa106, 0x1110, 0xa006, 0x0020, 0x6000, 0x0c80,
+	0xa085, 0x0001, 0x0005, 0x00f6, 0x00e6, 0x0016, 0x2079, 0x4680,
+	0x2071, 0x0100, 0xd1bc, 0x1120, 0x2079, 0x4640, 0x2071, 0x0200,
+	0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x1110, 0x001e, 0x0060,
+	0x810b, 0x810b, 0x810b, 0x810b, 0x000e, 0xa18d, 0x0800, 0xd0bc,
+	0x1110, 0xa18d, 0x0f00, 0x2104, 0x00ee, 0x00fe, 0x0005, 0x2001,
+	0x4601, 0x2004, 0xd0ac, 0x1138, 0x68e4, 0xd0ac, 0x0120, 0xa084,
+	0x0006, 0x1108, 0x0009, 0x0005, 0x6014, 0x00e6, 0x0036, 0x2018,
+	0x2071, 0x4b40, 0xd0fc, 0x1110, 0x2071, 0x4ac0, 0x8007, 0xa084,
+	0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004, 0xa084, 0x000a,
+	0x1904, 0x24fa, 0x7108, 0xa194, 0xff00, 0x0904, 0x24fa, 0xa18c,
+	0x00ff, 0x701c, 0xa084, 0xff00, 0x01c0, 0x7004, 0xa085, 0x003a,
+	0x7006, 0x2001, 0x0009, 0xa102, 0x16d8, 0x2001, 0x000a, 0xa102,
+	0x16d0, 0x2001, 0x000c, 0xa102, 0x16c8, 0x701c, 0xa084, 0x00ff,
+	0x701e, 0x7004, 0xa084, 0xffdf, 0x7006, 0x2001, 0x000a, 0xa106,
+	0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0, 0x2001, 0x0012, 0xa106,
+	0x0198, 0x2001, 0x0014, 0xa106, 0x0190, 0x2001, 0x0019, 0xa106,
+	0x0188, 0x2001, 0x0032, 0xa106, 0x0180, 0x00d8, 0x2009, 0x000c,
+	0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009, 0x0014, 0x00a0, 0x2009,
+	0x0019, 0x0088, 0x2009, 0x0020, 0x0070, 0x2009, 0x003f, 0x0058,
+	0x2009, 0x000a, 0x0040, 0x2009, 0x000c, 0x0028, 0x2009, 0x0019,
+	0x0010, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a, 0x7004, 0xa085,
+	0x000a, 0x7006, 0x2071, 0x4600, 0x7004, 0xd0bc, 0x0158, 0xd3fc,
+	0x1120, 0x73ea, 0x2071, 0x4640, 0x0018, 0x73ee, 0x2071, 0x4680,
+	0x701f, 0x000d, 0x003e, 0x00ee, 0x0005, 0x2001, 0x01ff, 0x2004,
+	0xd0fc, 0x11d0, 0x2001, 0x04fd, 0x2004, 0xa082, 0x0005, 0x12a0,
+	0x2071, 0x0200, 0x71ec, 0xa18c, 0x1c00, 0x810f, 0x810c, 0x810c,
+	0x2079, 0x0100, 0x78ec, 0xa084, 0x1c00, 0x8007, 0x8004, 0x8004,
+	0xa105, 0xa08a, 0x0007, 0x0208, 0x0005, 0x0002, 0x254b, 0x2532,
+	0x254b, 0x2532, 0x2525, 0x253f, 0x2525, 0x7008, 0xa084, 0xc3ff,
+	0xa085, 0x3000, 0x700a, 0x7808, 0xa084, 0xc3ff, 0xa085, 0x3000,
+	0x780a, 0x0005, 0x7008, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x700a,
+	0x7808, 0xa084, 0xc3ff, 0xa085, 0x2000, 0x780a, 0x0005, 0x7008,
+	0xa084, 0xc3ff, 0xa085, 0x0c00, 0x700a, 0x7808, 0xa084, 0xc3ff,
+	0xa085, 0x0c00, 0x780a, 0x0005, 0x0e04, 0x254c, 0x2091, 0x8000,
+	0x2071, 0x0000, 0x0006, 0x7018, 0xd084, 0x1de8, 0x000e, 0x2071,
+	0x0010, 0x70ca, 0x000e, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x0a04,
+	0x70df, 0x0020, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+	0x0cf8, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708a, 0x758e,
+	0x7492, 0x7696, 0x779a, 0xa594, 0x003f, 0xd4f4, 0x0138, 0xd7bc,
+	0x1128, 0xa784, 0x007d, 0x1904, 0x3c74, 0x0871, 0xa49c, 0x000f,
+	0xa382, 0x0004, 0x0320, 0xa3a6, 0x0007, 0x1930, 0x2418, 0x8507,
+	0xa084, 0x000f, 0x0002, 0x2b49, 0x2c34, 0x2c72, 0x2ed8, 0x3256,
+	0x32ad, 0x3353, 0x33e2, 0x34b6, 0x3588, 0x259e, 0x259b, 0x2970,
+	0x2a56, 0x322a, 0x259b, 0x080c, 0x254c, 0x0005, 0xa006, 0x0038,
+	0x7808, 0xc08d, 0x780a, 0xa006, 0x7002, 0x704a, 0x7042, 0x70ce,
+	0x705c, 0xa005, 0x1904, 0x26ec, 0x7060, 0xa084, 0x0007, 0x0002,
+	0x25b8, 0x2626, 0x262e, 0x2637, 0x2640, 0x26d2, 0x2649, 0x2626,
+	0x7830, 0xd0bc, 0x1d10, 0x71d0, 0xd1bc, 0x19f8, 0xd1b4, 0x1904,
+	0x2603, 0x70a0, 0xa086, 0x0001, 0x09c0, 0x70b0, 0xa06d, 0x6800,
+	0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa, 0x6808, 0xa045,
+	0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0118, 0x69bc,
+	0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0804,
+	0x281f, 0x705c, 0xa005, 0x1904, 0x259d, 0x00c6, 0x00d6, 0x70b0,
+	0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0080, 0x6b0c, 0x7baa,
+	0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001,
+	0x0118, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001,
+	0x0020, 0x0804, 0x281f, 0x080c, 0x3c33, 0x1904, 0x259d, 0x781b,
+	0x0068, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
+	0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc, 0x703e,
+	0xc1b4, 0x71d2, 0x70b4, 0xa065, 0x68c0, 0x7056, 0x7003, 0x0002,
+	0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005, 0x080c, 0x3c33,
+	0x1120, 0x781b, 0x0054, 0x7003, 0x0004, 0x0005, 0x080c, 0x3c33,
+	0x1128, 0x2011, 0x000c, 0x0419, 0x7003, 0x0004, 0x0005, 0x080c,
+	0x3c33, 0x1128, 0x2011, 0x0006, 0x00d1, 0x7003, 0x0004, 0x0005,
+	0x080c, 0x3c33, 0x1128, 0x2011, 0x000d, 0x0089, 0x7003, 0x0004,
+	0x0005, 0x080c, 0x3c33, 0x1150, 0x2011, 0x0006, 0x0041, 0x7078,
+	0x707b, 0x0000, 0x2068, 0x704a, 0x7003, 0x0004, 0x0005, 0x7170,
+	0xc1fc, 0x8107, 0x7882, 0x789b, 0x0080, 0xa286, 0x000c, 0x1120,
+	0x7aaa, 0x2001, 0x0001, 0x0098, 0xa18c, 0x001f, 0xa18d, 0x00c0,
+	0x79aa, 0xa286, 0x000d, 0x0120, 0x7aaa, 0x2001, 0x0002, 0x0038,
+	0x78ab, 0x0020, 0x7174, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b,
+	0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0113, 0x080c, 0x3c46,
+	0x707f, 0x000f, 0x70d0, 0xd0b4, 0x0168, 0xc0b4, 0x70d2, 0x00c6,
+	0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
+	0x601a, 0x00ce, 0x0005, 0x7014, 0xa005, 0x1138, 0x70d0, 0xd0b4,
+	0x0128, 0x70b4, 0xac06, 0x1110, 0x0c29, 0x0005, 0x0016, 0x71a0,
+	0xa186, 0x0001, 0x0528, 0x00d6, 0x0026, 0x2100, 0x2011, 0x0001,
+	0xa212, 0x70b0, 0x2068, 0x6800, 0xac06, 0x0120, 0x8211, 0x01b0,
+	0x00c9, 0x0cc8, 0x00c6, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b0,
+	0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef, 0x600a, 0x8211,
+	0x0110, 0x0041, 0x0cb0, 0x70a3, 0x0001, 0x00ce, 0x002e, 0x00de,
+	0x001e, 0x0005, 0xade8, 0x0005, 0x70a8, 0xad06, 0x1110, 0x70a4,
+	0x2068, 0x0005, 0x080c, 0x3c33, 0x1904, 0x259d, 0x7078, 0x2068,
+	0x7770, 0x080c, 0x3b6f, 0x2c50, 0x080c, 0x3cce, 0x789b, 0x0080,
+	0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001,
+	0x2001, 0x0004, 0x0804, 0x2824, 0x080c, 0x3c33, 0x1904, 0x259d,
+	0x789b, 0x0080, 0x705c, 0x2068, 0x6f14, 0x70d0, 0xd0b4, 0x0168,
+	0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x080c, 0x3b6f, 0x2c50,
+	0x080c, 0x3cce, 0x6824, 0xa005, 0x0130, 0xa082, 0x0006, 0x0208,
+	0x0010, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa,
+	0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003, 0x0804, 0x2824,
+	0xc28d, 0x72d2, 0x72bc, 0xa200, 0xa015, 0x7150, 0x8108, 0xa12a,
+	0x0208, 0x71bc, 0x2164, 0x6504, 0x85ff, 0x1170, 0x7152, 0x8421,
+	0x1da8, 0x70d0, 0xd08c, 0x0128, 0x70cc, 0xa005, 0x1110, 0x70cf,
+	0x000a, 0x0005, 0x2200, 0x0c90, 0x70d0, 0xc08c, 0x70d2, 0x70cf,
+	0x0000, 0x6034, 0xa005, 0x1db0, 0x6708, 0xa784, 0x073f, 0x01d0,
+	0xd7d4, 0x1d80, 0xa784, 0x0021, 0x1d68, 0xa784, 0x0002, 0x0130,
+	0xa784, 0x0004, 0x0d38, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218,
+	0x1d08, 0xa784, 0x0100, 0x0130, 0x6018, 0xa005, 0x19d8, 0xa7bc,
+	0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684, 0x000e,
+	0x6318, 0x0128, 0x601c, 0xa302, 0x0220, 0x0118, 0x0858, 0x83ff,
+	0x1948, 0x2d58, 0x2c50, 0x7152, 0xd7bc, 0x1120, 0x7028, 0x6022,
+	0x603a, 0x0010, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100,
+	0x2a60, 0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0,
+	0xd1fc, 0x0110, 0xd684, 0x0110, 0xa39c, 0xffbf, 0xd6a4, 0x0110,
+	0xa39d, 0x0020, 0xa684, 0x000e, 0x1904, 0x27d6, 0xc7a5, 0x670a,
+	0x2c00, 0x68c6, 0x77a0, 0xa786, 0x0001, 0x1178, 0x70d0, 0xd0b4,
+	0x1160, 0x7000, 0xa082, 0x0002, 0x1240, 0x7830, 0xd0bc, 0x1128,
+	0x789b, 0x0080, 0x7baa, 0x0804, 0x281d, 0x8739, 0x77a2, 0x2750,
+	0x77ac, 0xa7b0, 0x0005, 0x70a8, 0xa606, 0x1108, 0x76a4, 0x76ae,
+	0x2c3a, 0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738,
+	0x253a, 0x7830, 0xd0bc, 0x0150, 0x2091, 0x8000, 0x2091, 0x303d,
+	0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000,
+	0x0120, 0x8421, 0x2200, 0x1904, 0x2725, 0x0005, 0xd1dc, 0x0904,
+	0x37ce, 0x2029, 0x0020, 0xd69c, 0x1120, 0x8528, 0xd68c, 0x1108,
+	0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c, 0x00ff, 0x70c8,
+	0xa160, 0x2c64, 0x8cff, 0x0188, 0x6014, 0xa706, 0x1dd0, 0x60b8,
+	0x8001, 0x60ba, 0x1d88, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a,
+	0x2200, 0x8421, 0x1904, 0x2725, 0x0005, 0x2a60, 0x610e, 0x69be,
+	0x2c00, 0x68c6, 0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a0, 0xa786,
+	0x0001, 0x1904, 0x27ad, 0x70d0, 0xd0b4, 0x1904, 0x27ad, 0x7000,
+	0xa082, 0x0002, 0x1a04, 0x27ad, 0x7830, 0xd0bc, 0x1904, 0x27ad,
+	0x789b, 0x0080, 0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x0006,
+	0x6018, 0x8000, 0x601a, 0x0008, 0x0006, 0x2960, 0x6104, 0x2a60,
+	0x080c, 0x3ce1, 0x1590, 0xa184, 0x0018, 0x0180, 0xa184, 0x0010,
+	0x0118, 0x080c, 0x3977, 0x1548, 0xa184, 0x0008, 0x0138, 0x69a0,
+	0xa184, 0x0600, 0x1118, 0x080c, 0x3895, 0x00f8, 0x69a0, 0xa184,
+	0x1e00, 0x0528, 0xa184, 0x0800, 0x0178, 0x00c6, 0x2960, 0x6000,
+	0xa085, 0x2000, 0x6002, 0x6104, 0xa18d, 0x0010, 0x6106, 0x00ce,
+	0x080c, 0x3977, 0x1150, 0x69a0, 0xa184, 0x0200, 0x0118, 0x080c,
+	0x38da, 0x0018, 0xa184, 0x0400, 0x19f0, 0x69a0, 0xa184, 0x1000,
+	0x0130, 0x6914, 0xa18c, 0xff00, 0x810f, 0x080c, 0x239c, 0x002e,
+	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0128, 0xa086, 0x0060, 0x1110,
+	0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b, 0x0060, 0x2800,
+	0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0168, 0xc0fc, 0x7083,
+	0x0000, 0xa08a, 0x000d, 0x0328, 0xa08a, 0x000c, 0x7182, 0x2001,
+	0x000c, 0x800c, 0x7186, 0x78aa, 0x3518, 0x3340, 0x3428, 0x8000,
+	0x80ac, 0xaf80, 0x002b, 0x20a0, 0x789b, 0x0000, 0xad80, 0x000b,
+	0x2098, 0x53a6, 0x23a8, 0x2898, 0x25a0, 0xa286, 0x0020, 0x1508,
+	0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00, 0x70ba, 0x6814,
+	0xc0fc, 0x8007, 0x7882, 0xa286, 0x0002, 0x0904, 0x28f5, 0x70a0,
+	0x8000, 0x70a2, 0x74b0, 0xa498, 0x0005, 0x70a8, 0xa306, 0x1108,
+	0x73a4, 0x73b2, 0xa286, 0x0010, 0x0904, 0x259d, 0x00de, 0x00ce,
+	0x0005, 0x7000, 0xa005, 0x19e0, 0xa286, 0x0002, 0x1904, 0x290c,
+	0x080c, 0x3c33, 0x19a8, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091,
+	0x8000, 0x781b, 0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
+	0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a,
+	0x0126, 0x00d6, 0x00c6, 0x70d0, 0xa084, 0x2e00, 0x2090, 0x00ce,
+	0x00de, 0x012e, 0x2900, 0x7056, 0x68bc, 0x703e, 0x7003, 0x0002,
+	0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x7830, 0xd0bc, 0x0140,
+	0x2091, 0x303d, 0x70d0, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090,
+	0x70a0, 0xa005, 0x1108, 0x0005, 0x8421, 0x0de8, 0x724c, 0x70bc,
+	0xa200, 0xa015, 0x0804, 0x2725, 0xa286, 0x0010, 0x1560, 0x080c,
+	0x3c33, 0x1904, 0x28a0, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b,
+	0x0068, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
+	0x78da, 0x7808, 0xc08d, 0x780a, 0x70a0, 0x8000, 0x70a2, 0x74b0,
+	0xa490, 0x0005, 0x70a8, 0xa206, 0x1108, 0x72a4, 0x72b2, 0x2900,
+	0x7056, 0x68bc, 0x703e, 0x7003, 0x0002, 0x2d00, 0x704a, 0xad80,
+	0x0009, 0x7042, 0x0005, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814,
+	0xc0fc, 0x8007, 0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2,
+	0x7eda, 0x781b, 0x0068, 0x2900, 0x7056, 0x7202, 0x7808, 0xc08d,
+	0x780a, 0x2300, 0xa605, 0x0170, 0x70d0, 0xa084, 0x2e00, 0xa086,
+	0x2600, 0x1118, 0x2009, 0x0000, 0x0010, 0x2009, 0x0001, 0xa284,
+	0x000f, 0x0023, 0xad80, 0x0009, 0x7042, 0x0005, 0x296e, 0x41d9,
+	0x41d9, 0x41c7, 0x41d9, 0x296e, 0x296e, 0x296e, 0x080c, 0x254c,
+	0x7808, 0xa084, 0xfffd, 0x780a, 0x00f6, 0x2079, 0x4600, 0x78ac,
+	0x00fe, 0xd084, 0x01b0, 0x7060, 0xa086, 0x0001, 0x0904, 0x2a32,
+	0x7060, 0xa086, 0x0005, 0x1158, 0x7078, 0x2068, 0x681b, 0x0004,
+	0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7063,
+	0x0000, 0x70a3, 0x0000, 0x70a4, 0x70ae, 0x70b2, 0x080c, 0x2682,
+	0x0156, 0x2011, 0x0004, 0x7160, 0xa186, 0x0001, 0x0160, 0xa186,
+	0x0007, 0x1118, 0x701f, 0x0005, 0x0030, 0x701f, 0x0001, 0x70d0,
+	0xc0c5, 0x70d2, 0x0000, 0x2001, 0x460a, 0x2004, 0xa084, 0x00ff,
+	0xa086, 0x0018, 0x0130, 0x7018, 0x7016, 0xa005, 0x1110, 0x70a3,
+	0x0001, 0x0066, 0x080c, 0x3f26, 0x20a9, 0x0010, 0x2039, 0x0000,
+	0x080c, 0x3a66, 0xa7b8, 0x0100, 0x1f04, 0x29c0, 0x006e, 0x7000,
+	0x0002, 0x29fd, 0x29db, 0x29db, 0x29d3, 0x29fd, 0x29fd, 0x29fd,
+	0x29d1, 0x080c, 0x254c, 0x705c, 0xa005, 0x0538, 0xad06, 0x1118,
+	0x6800, 0x705e, 0x0080, 0x6820, 0xd084, 0x1148, 0x6f14, 0x080c,
+	0x3b6f, 0x6008, 0xc0d4, 0x600a, 0x080c, 0x37a4, 0x0020, 0x7058,
+	0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc,
+	0x0108, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820, 0xa084,
+	0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2, 0x2011, 0x0004, 0x74c8,
+	0xa4a0, 0x0100, 0x04b1, 0xaea0, 0x0017, 0x0499, 0x20a9, 0x0101,
+	0x74c8, 0x0479, 0x8420, 0x1f04, 0x2a09, 0x70c0, 0x2060, 0x2021,
 	0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0198, 0x6018, 0x0016,
-	0x0006, 0x2011, 0x4302, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e,
-	0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4304, 0x2204, 0xc0a5,
-	0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x291b, 0x8421,
-	0x1d00, 0x015e, 0x7003, 0x0000, 0x704f, 0x0000, 0x0005, 0x0046,
-	0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006, 0x6a1a, 0x6817,
-	0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820,
-	0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1d3d, 0x000e, 0x0c48,
-	0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003, 0x0310, 0x080c,
-	0x243b, 0x2300, 0x0002, 0x2966, 0x29e3, 0x29fd, 0xa282, 0x0002,
-	0x0110, 0x080c, 0x243b, 0x7064, 0x7067, 0x0000, 0x7083, 0x0000,
-	0x0022, 0x77d4, 0xc7c5, 0x77d6, 0x0002, 0x297d, 0x297d, 0x297f,
-	0x29b7, 0x35df, 0x297d, 0x29b7, 0x297d, 0x080c, 0x243b, 0x7774,
-	0x080c, 0x3861, 0x7774, 0xa7bc, 0x8f00, 0x080c, 0x396d, 0x6018,
-	0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x89c0, 0x0010, 0x2021,
-	0x8ad0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c, 0x2a17, 0x01b8,
-	0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021, 0x88c0, 0x0010,
-	0x2021, 0x89d0, 0x0046, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c,
-	0x2a17, 0x004e, 0x0118, 0x8420, 0x1f04, 0x29a2, 0x015e, 0x8738,
-	0xa784, 0x001f, 0x1990, 0x0804, 0x248f, 0x0804, 0x248f, 0x7774,
-	0x080c, 0x396d, 0x6018, 0xa005, 0x0520, 0xd7fc, 0x1118, 0x2021,
-	0x89c0, 0x0010, 0x2021, 0x8ad0, 0x2009, 0x0005, 0x2011, 0x0020,
-	0x080c, 0x2a17, 0x01b0, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118,
-	0x2021, 0x88c0, 0x0010, 0x2021, 0x89d0, 0x0046, 0x2009, 0x0005,
-	0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420, 0x1f04, 0x29d5,
-	0x015e, 0x0804, 0x248f, 0x2200, 0x0002, 0x29e8, 0x29ea, 0x29ea,
-	0x080c, 0x243b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0110,
-	0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a, 0x7067, 0x0000,
-	0x70d4, 0xc0c5, 0x70d6, 0x0804, 0x3a3f, 0x2200, 0x0002, 0x2a04,
-	0x29ea, 0x2a02, 0x080c, 0x243b, 0x080c, 0x3d52, 0x7000, 0xa086,
-	0x0002, 0x1904, 0x356d, 0x080c, 0x35c5, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x080c, 0x355f, 0x0904, 0x356d, 0x0804, 0x248f, 0x2404,
-	0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814, 0xa706, 0x0118,
-	0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a, 0x6817, 0x0000,
-	0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
-	0x00ff, 0xa205, 0x6822, 0x080c, 0x1d3d, 0x2021, 0x4302, 0x241c,
-	0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128, 0x2021, 0x4304,
-	0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x080c,
-	0x258b, 0x080c, 0x35c5, 0x0005, 0xa085, 0x0001, 0x0ce0, 0x2300,
-	0x0002, 0x2a56, 0x2a54, 0x2abc, 0x080c, 0x243b, 0x78e4, 0xa005,
-	0x1708, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x248c, 0x0010,
-	0x0304, 0x248c, 0x2008, 0xa084, 0x0030, 0x1110, 0x0804, 0x30a0,
-	0x78ec, 0xa084, 0x0003, 0x0dd0, 0x2100, 0xa084, 0x0007, 0x0002,
-	0x2a9f, 0x2aa8, 0x2a95, 0x2a78, 0x3a83, 0x3a83, 0x2a78, 0x2ab2,
-	0x080c, 0x243b, 0x7000, 0xa086, 0x0004, 0x1190, 0x7064, 0xa086,
-	0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x295c,
-	0x7064, 0xa086, 0x0006, 0x0db0, 0x7064, 0xa086, 0x0004, 0x0d90,
-	0x79e4, 0x2001, 0x0003, 0x0804, 0x2daa, 0x6818, 0xd0fc, 0x0110,
-	0x681b, 0x001d, 0x080c, 0x3837, 0x781b, 0x006e, 0x0005, 0x6818,
-	0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3837, 0x0804, 0x3a61,
-	0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3837, 0x781b,
-	0x00fa, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c,
-	0x3837, 0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000,
-	0x0002, 0x248f, 0x2ac9, 0x2acb, 0x356d, 0x356d, 0x356d, 0x2ac9,
-	0x2ac9, 0x080c, 0x243b, 0x080c, 0x35c5, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x080c, 0x355f, 0x0904, 0x356d, 0x0804, 0x248f, 0x78e4,
-	0xa005, 0x1b04, 0x2a7a, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104,
-	0x2a7a, 0x0010, 0x0304, 0x2a7a, 0x2008, 0xa084, 0x0030, 0x1118,
-	0x781b, 0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x2100,
-	0xa184, 0x0007, 0x0002, 0x2b02, 0x2b06, 0x2afd, 0x2afb, 0x3a83,
-	0x3a83, 0x2afb, 0x3a7d, 0x080c, 0x243b, 0x080c, 0x383d, 0x781b,
-	0x006e, 0x0005, 0x080c, 0x383d, 0x0804, 0x3a61, 0x080c, 0x383d,
-	0x781b, 0x00fa, 0x0005, 0x080c, 0x383d, 0x781b, 0x00cb, 0x0005,
-	0x2300, 0x0002, 0x2b17, 0x2b15, 0x2b19, 0x080c, 0x243b, 0x0804,
-	0x3220, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030,
-	0x0904, 0x3220, 0x78ec, 0xa084, 0x0003, 0x0904, 0x3220, 0xa184,
-	0x0100, 0x0d98, 0xa184, 0x0007, 0x0002, 0x2b35, 0x2b06, 0x2a95,
-	0x3a3f, 0x3a83, 0x3a83, 0x3a3f, 0x3a7d, 0x080c, 0x3a4b, 0x0005,
-	0xa282, 0x0005, 0x0310, 0x080c, 0x243b, 0x7898, 0x2040, 0x2300,
-	0x0002, 0x2b44, 0x2d41, 0x2d4b, 0x2200, 0x0002, 0x2b60, 0x2b4d,
-	0x2b60, 0x2b4b, 0x2d25, 0x080c, 0x243b, 0x789b, 0x0018, 0x78a8,
-	0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04, 0x3809, 0xa08a,
-	0x0004, 0x1a04, 0x3809, 0x0002, 0x3809, 0x3809, 0x3809, 0x37bf,
-	0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148, 0x0804, 0x3809,
-	0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804, 0x33b2, 0xa184,
-	0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3809, 0x0002, 0x2b88, 0x2b86,
-	0x2b9a, 0x2b9e, 0x2c3c, 0x3809, 0x3809, 0x2c3e, 0x3809, 0x3809,
-	0x2d21, 0x2d21, 0x3809, 0x3809, 0x3809, 0x2d23, 0x080c, 0x243b,
-	0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a, 0x781b,
-	0x00c6, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b, 0x001d, 0x0c90,
-	0x0804, 0x3a3f, 0x681b, 0x001d, 0x0804, 0x3831, 0x6920, 0x6922,
-	0xa684, 0x1800, 0x15e0, 0x6820, 0xd084, 0x1904, 0x2be7, 0x6818,
-	0xa086, 0x0008, 0x1110, 0x681b, 0x0000, 0xd6d4, 0x0568, 0xd6bc,
-	0x0558, 0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d,
-	0x0718, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a,
-	0x789b, 0x0061, 0x78aa, 0x0156, 0x0136, 0x0146, 0x0016, 0x3208,
-	0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b,
-	0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098,
-	0x53a6, 0x014e, 0x013e, 0x015e, 0x781b, 0x0071, 0x0005, 0xd6e4,
-	0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083, 0x0005, 0xa684,
-	0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0, 0xc6fc, 0x7e5a,
-	0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084, 0x007f, 0xa108,
-	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-	0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000,
-	0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3d52, 0x080c, 0x3fb8,
-	0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c, 0x4083, 0x6ab0,
-	0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120, 0x2200, 0xa422,
-	0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde,
-	0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b, 0x0080,
-	0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118, 0x080c, 0x3fb8,
-	0x0005, 0x080c, 0x3fe5, 0x0005, 0x080c, 0x243b, 0x0804, 0x2cbd,
-	0x00c6, 0x7058, 0x2060, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004,
-	0x11d8, 0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000,
-	0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x36f6, 0x080c, 0x379a,
-	0x0804, 0x2cb1, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd,
-	0x6106, 0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104,
-	0xa18c, 0x0010, 0x0548, 0x080c, 0x3969, 0x080c, 0x3776, 0x88ff,
-	0x0518, 0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695,
-	0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082,
-	0x0005, 0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000,
-	0xc0ec, 0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000,
-	0xa006, 0x2010, 0x080c, 0x379a, 0xa286, 0x0001, 0x0158, 0x6104,
-	0xa18c, 0x0008, 0x01b0, 0x080c, 0x3969, 0x080c, 0x3696, 0x88ff,
-	0x1980, 0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922,
-	0x6000, 0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c,
-	0x36f6, 0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005,
-	0x781b, 0x0083, 0x0005, 0x0804, 0x382d, 0x2808, 0x789b, 0x0080,
-	0x2019, 0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x1188,
-	0x7ca8, 0xa4a4, 0x00ff, 0xa480, 0x0002, 0xa300, 0x2018, 0xa102,
-	0x0a04, 0x2c40, 0x0904, 0x2c40, 0x24a8, 0x7aa8, 0x1f04, 0x2cd5,
-	0x0c48, 0xa284, 0x00f0, 0xa082, 0x0020, 0x06b8, 0x2200, 0xa082,
-	0x0021, 0x1698, 0x7aa8, 0x8318, 0x8318, 0x2100, 0xa302, 0x0ad0,
-	0xa286, 0x0023, 0x0980, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
-	0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a,
-	0x78a0, 0x8001, 0x0904, 0x2cb1, 0x20a8, 0x7998, 0x789b, 0x0060,
-	0x78aa, 0x2011, 0x0080, 0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa,
-	0x7a98, 0x1f04, 0x2d03, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
-	0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x8318, 0x2100, 0xa302,
-	0x0a04, 0x2cc2, 0xa284, 0x0080, 0x1904, 0x3831, 0x78a0, 0xa005,
-	0x08c8, 0x0804, 0x3831, 0x0804, 0x3809, 0x7058, 0xa04d, 0x789b,
-	0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c,
-	0x243b, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a,
-	0x0005, 0x1a04, 0x3809, 0x0002, 0x3809, 0x3615, 0x3809, 0x3726,
-	0x3b83, 0xa282, 0x0000, 0x1110, 0x080c, 0x243b, 0x080c, 0x3837,
-	0x781b, 0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x243b,
-	0xd4fc, 0x11d0, 0x7064, 0xa005, 0x0110, 0x080c, 0x243b, 0x6f14,
-	0x7776, 0xa7bc, 0x8f00, 0x080c, 0x396d, 0x6008, 0xa085, 0x0021,
-	0x600a, 0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x383a, 0x7067,
-	0x0002, 0x701f, 0x0009, 0x0010, 0x080c, 0x3846, 0x781b, 0x0082,
-	0x0005, 0xa282, 0x0004, 0x0310, 0x080c, 0x243b, 0x2300, 0x0002,
-	0x2d7b, 0x2eff, 0x2f3b, 0xa286, 0x0003, 0x0560, 0x7200, 0x7cd8,
-	0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x00f0, 0x7868, 0xa084, 0x00ff,
-	0x11d0, 0xa282, 0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b,
-	0x0059, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-	0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x00de,
-	0x2001, 0x0000, 0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001,
-	0x0000, 0x0020, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0,
-	0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002,
-	0x2ee0, 0x2dc5, 0x2dc2, 0x3012, 0x3085, 0x248f, 0x2dc0, 0x2dc0,
-	0x080c, 0x243b, 0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7048,
-	0xa086, 0x0014, 0x11e8, 0x080c, 0x3d52, 0x2009, 0x0000, 0x6818,
-	0xd0fc, 0x0108, 0x7048, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086,
-	0x0008, 0x1904, 0x2ea2, 0x7858, 0xd09c, 0x0904, 0x2ea2, 0x6820,
-	0xd0ac, 0x0904, 0x2ea2, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8,
-	0x7868, 0xa08c, 0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008,
-	0xc0a4, 0x600a, 0x080c, 0x355f, 0x0540, 0x080c, 0x35c5, 0x080c,
-	0x3d52, 0x0060, 0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78,
-	0x8001, 0x0d68, 0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084,
-	0x0904, 0x248f, 0xc084, 0x6822, 0x080c, 0x2580, 0x705c, 0x00c6,
-	0x2060, 0x6800, 0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00,
-	0x1108, 0x6002, 0x6006, 0x0804, 0x248f, 0x0016, 0x81ff, 0x15e0,
-	0x7000, 0xa086, 0x0030, 0x05c0, 0x71d4, 0xd1b4, 0x11e8, 0x7060,
-	0xa005, 0x1590, 0x70a4, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000,
-	0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x24b2,
-	0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d4, 0xd1b4,
-	0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3a8d, 0x11a8, 0x781b,
-	0x0068, 0x00d6, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030,
-	0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x2f63, 0x001e, 0x81ff,
-	0x0904, 0x2ea2, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14,
-	0xa186, 0x0002, 0x15c0, 0x6818, 0xa086, 0x0014, 0x1130, 0x2008,
-	0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3850, 0x080c,
-	0x258b, 0x6820, 0xd0dc, 0x1538, 0x8717, 0xa294, 0x000f, 0x8213,
-	0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x47c0, 0x0010,
-	0xa290, 0x4840, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0130, 0x8210,
-	0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138, 0x68a0,
-	0xd0c4, 0x1120, 0x080c, 0x2fcb, 0x0804, 0x248f, 0x6008, 0xc08d,
-	0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7048,
-	0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168, 0x2009,
-	0x4302, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021,
-	0x4304, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118, 0x8001,
-	0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x1130,
-	0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x705c, 0x2060,
-	0x6800, 0x6002, 0x2061, 0x4300, 0x6887, 0x0103, 0x2d08, 0x206b,
-	0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008, 0x616e,
-	0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904, 0x248f,
-	0x7003, 0x0002, 0x704c, 0x2068, 0x68c4, 0x2060, 0x0005, 0x7003,
-	0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0,
-	0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005, 0xa282,
-	0x0004, 0x0210, 0x080c, 0x243b, 0x2200, 0x0002, 0x2f0a, 0x2f19,
-	0x2f25, 0x2f19, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300, 0x1d90,
-	0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3837, 0x781b,
-	0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007, 0x8001,
-	0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
-	0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804, 0x3809,
-	0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff, 0x1118,
-	0x080c, 0x3837, 0x0030, 0x8211, 0x0110, 0x080c, 0x243b, 0x080c,
-	0x3846, 0x781b, 0x0082, 0x0005, 0x080c, 0x3aa0, 0x7830, 0xa084,
-	0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e, 0x0118,
-	0x0104, 0x2f60, 0x0010, 0x0304, 0x2f60, 0x791a, 0xa006, 0x0005,
-	0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f, 0x0000,
-	0x6833, 0x0000, 0x0804, 0x2fca, 0xd6dc, 0x1198, 0x68b4, 0xd0dc,
-	0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x1130,
-	0x2200, 0xa105, 0x0904, 0x3d52, 0x704b, 0x0015, 0x0804, 0x3d52,
-	0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833,
-	0x0000, 0x0804, 0x3d52, 0x68b4, 0xa084, 0x4000, 0xa635, 0xd6f4,
-	0x1da0, 0x7048, 0xa005, 0x1110, 0x704b, 0x0015, 0xd6dc, 0x1128,
-	0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0804,
-	0x3d52, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000, 0x0804,
-	0x3d52, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0, 0x7048,
-	0xa005, 0x1110, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700, 0x8007,
-	0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32, 0x2100,
-	0xa205, 0x1110, 0x0804, 0x3d52, 0x7000, 0xa086, 0x0006, 0x0110,
-	0x0804, 0x3d52, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0108,
-	0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000,
-	0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003,
-	0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020,
-	0x7000, 0x0002, 0x248f, 0x2ffa, 0x2ff4, 0x2ff2, 0x2ff2, 0x2ff2,
-	0x2ff2, 0x2ff2, 0x080c, 0x243b, 0x6820, 0xd084, 0x1118, 0x080c,
-	0x35ab, 0x0030, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60,
-	0x3208, 0xa18c, 0x0600, 0x0118, 0x2021, 0x4358, 0x0010, 0x2021,
-	0x4398, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8, 0x2d22, 0x206b,
-	0x0000, 0x0005, 0x080c, 0x35b1, 0x080c, 0x35c5, 0x6008, 0xc0cc,
-	0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a,
-	0x6944, 0x6916, 0x3208, 0xa18c, 0x0600, 0x0118, 0x2009, 0x0000,
-	0x0010, 0x2009, 0x0001, 0x080c, 0x40b1, 0xd6dc, 0x0118, 0x691c,
-	0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0148, 0x7868, 0xa08c, 0x00ff,
-	0x0118, 0x681b, 0x001e, 0x0010, 0x681b, 0x0000, 0xb284, 0x0600,
-	0x1118, 0x2021, 0x4398, 0x0010, 0x2021, 0x4358, 0x6800, 0x2022,
-	0x6a3c, 0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4,
-	0x0580, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6,
-	0x00f6, 0x0156, 0x0146, 0x2079, 0x4300, 0x080c, 0x1b35, 0x014e,
-	0x015e, 0x00fe, 0x70cc, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204,
-	0xa06d, 0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820,
-	0xc0d5, 0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7067,
-	0x0003, 0x707f, 0x0000, 0x7776, 0x7083, 0x000f, 0x71d4, 0xc1c4,
-	0x71d6, 0x080c, 0x1d3d, 0x0804, 0x248f, 0x7cd8, 0x7ddc, 0x7fd0,
-	0x080c, 0x2f63, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x080c,
-	0x3aa4, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0110, 0x7048,
-	0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0804, 0x248f,
-	0x7000, 0xa005, 0x1110, 0x0804, 0x248f, 0xa006, 0x080c, 0x3d52,
-	0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e,
-	0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0002,
-	0x248f, 0x30c2, 0x30c2, 0x30c5, 0x30c5, 0x30c5, 0x30c0, 0x30c0,
-	0x080c, 0x243b, 0x6818, 0x0804, 0x2daa, 0x6008, 0xc0a4, 0x600a,
-	0x6817, 0x0000, 0x0804, 0x357a, 0x2300, 0x0002, 0x30d1, 0x30d3,
-	0x3110, 0x080c, 0x243b, 0xd6fc, 0x1904, 0x2bee, 0x7000, 0xa00d,
-	0x0002, 0x248f, 0x30e3, 0x30e3, 0x3104, 0x30e3, 0x310d, 0x30e1,
-	0x30e1, 0x080c, 0x243b, 0xa684, 0x0060, 0xa086, 0x0060, 0x11d0,
-	0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac, 0x681e, 0xa186,
-	0x0002, 0x0110, 0x080c, 0x3d52, 0x080c, 0x3fb8, 0x781b, 0x0083,
-	0x71d4, 0xd1b4, 0x1904, 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904,
-	0x24ce, 0x0005, 0xd6ec, 0x0d30, 0x6818, 0xd0fc, 0x0130, 0x681b,
-	0x0015, 0xd6f4, 0x0110, 0x681b, 0x0007, 0x080c, 0x3a4b, 0x0005,
-	0x080c, 0x243b, 0x2300, 0x0002, 0x3119, 0x3134, 0x3182, 0x080c,
-	0x243b, 0x7000, 0x0002, 0x3123, 0x3125, 0x3125, 0x3123, 0x3123,
-	0x3123, 0x3123, 0x3123, 0x080c, 0x243b, 0x080c, 0x3fb8, 0x681c,
-	0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x1904, 0x248c, 0x70a4, 0xa086,
-	0x0001, 0x1904, 0x24ce, 0x0005, 0xd6fc, 0x15e0, 0x7000, 0xa00d,
-	0x0002, 0x248f, 0x3149, 0x3143, 0x316a, 0x3149, 0x316f, 0x3141,
-	0x3141, 0x080c, 0x243b, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
-	0x78da, 0xa684, 0x0060, 0xa086, 0x0060, 0x11d0, 0xa6b4, 0xbfbf,
-	0xc6ed, 0x7e5a, 0xa186, 0x0002, 0x0110, 0x080c, 0x3d52, 0x080c,
-	0x3fb8, 0x781b, 0x0083, 0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4,
-	0x1904, 0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, 0x24ce, 0x0005,
-	0xd6ec, 0x0d30, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0007, 0x781b,
-	0x00fb, 0x0005, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100,
-	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b,
-	0x0083, 0x0005, 0xd6dc, 0x0130, 0x782b, 0x3009, 0x781b, 0x0083,
-	0x0804, 0x248c, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008,
-	0x1150, 0xa484, 0x0200, 0x0108, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b,
-	0x0083, 0x0804, 0x248c, 0x6820, 0xc095, 0x6822, 0x080c, 0x39ca,
-	0xc6dd, 0x080c, 0x3837, 0x781b, 0x0082, 0x0804, 0x248c, 0x2300,
-	0x0002, 0x31ac, 0x31ae, 0x31b0, 0x080c, 0x243b, 0x0804, 0x3831,
-	0x7d98, 0xd6d4, 0x11f8, 0x79e4, 0xd1ac, 0x0130, 0x78ec, 0xa084,
-	0x0003, 0x0110, 0x782b, 0x3009, 0x789b, 0x0060, 0x78ab, 0x0000,
-	0xa684, 0xfffb, 0x785a, 0x7d9a, 0x79e4, 0xd1ac, 0x0120, 0x78ec,
-	0xa084, 0x0003, 0x1120, 0x2001, 0x0014, 0x0804, 0x2daa, 0xa184,
-	0x0007, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8,
-	0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384, 0x0001, 0x11d0,
-	0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009, 0xffdf, 0x0058,
-	0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028, 0xa386, 0x0003,
-	0x1148, 0x2009, 0xffef, 0x00c6, 0x7058, 0x2060, 0x6004, 0xa104,
-	0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
-	0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff, 0x6922, 0x7d9a,
-	0x0804, 0x3a3f, 0x2a9f, 0x2aa8, 0x3214, 0x321a, 0x3212, 0x3212,
-	0x3a3f, 0x3a3f, 0x080c, 0x243b, 0x6920, 0xa18c, 0xfcff, 0x6922,
-	0x0804, 0x3a45, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0804, 0x3a3f,
-	0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1558,
-	0x7000, 0xa086, 0x0004, 0x1190, 0x7064, 0xa086, 0x0002, 0x1130,
-	0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x295c, 0x7064, 0xa086,
-	0x0006, 0x0db0, 0x7064, 0xa086, 0x0004, 0x0d90, 0x7000, 0xa086,
-	0x0000, 0x0904, 0x248c, 0x6920, 0xa184, 0x0420, 0x0128, 0xc1d4,
-	0x6922, 0x6818, 0x0804, 0x2daa, 0x6818, 0xc0fd, 0x681a, 0x2001,
-	0x0014, 0x0804, 0x2daa, 0xa184, 0x0007, 0x0002, 0x3a3f, 0x3a3f,
-	0x325e, 0x3a3f, 0x3a83, 0x3a83, 0x3a3f, 0x3a3f, 0xd6bc, 0x0570,
-	0x7184, 0x81ff, 0x0558, 0xa182, 0x000d, 0x1318, 0x7087, 0x0000,
-	0x0028, 0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061,
-	0x79aa, 0x0156, 0x0136, 0x0146, 0x7088, 0x8114, 0xa210, 0x728a,
-	0xa080, 0x000b, 0xad00, 0x2098, 0xb284, 0x0600, 0x0118, 0x20a1,
-	0x022b, 0x0010, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108, 0x81ac,
-	0x53a6, 0x014e, 0x013e, 0x015e, 0x0804, 0x3a45, 0xd6d4, 0x1904,
-	0x32d1, 0x6820, 0xd084, 0x0904, 0x3a45, 0xa68c, 0x0060, 0xa684,
-	0x0060, 0x0120, 0xa086, 0x0060, 0x1108, 0xc1f5, 0xc194, 0x795a,
-	0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818,
-	0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c, 0x0904, 0x35da, 0xa18c,
-	0x00f8, 0x1904, 0x35da, 0x0156, 0x0136, 0x0146, 0x0016, 0x20a1,
-	0x012b, 0x3208, 0xa18c, 0x0600, 0x0110, 0x20a1, 0x022b, 0x001e,
-	0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6,
-	0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0804,
-	0x3a45, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x0008, 0x080c, 0x3837,
-	0x781b, 0x00ed, 0x0005, 0x2300, 0x0002, 0x32e2, 0x3398, 0x32e0,
-	0x080c, 0x243b, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x11f0, 0x7200,
-	0xa286, 0x0003, 0x0904, 0x2d7f, 0x71d4, 0xd1b4, 0x00c0, 0x00d6,
-	0x783b, 0x8800, 0x781b, 0x0059, 0x70bc, 0xa06d, 0x68b4, 0xc0a5,
-	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
-	0x71d6, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200, 0x0020, 0x783b,
-	0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002, 0x3383, 0x3344,
-	0x3318, 0x2da7, 0x3316, 0x3383, 0x3316, 0x3316, 0x080c, 0x243b,
-	0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185,
-	0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002, 0x6008, 0xc0d4,
-	0x600a, 0x681c, 0xa084, 0x000e, 0x1148, 0xb284, 0x0600, 0x0118,
-	0x2009, 0x89c0, 0x0040, 0x2009, 0x8ad0, 0x0028, 0x7030, 0x68ba,
-	0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e, 0xd6dc,
-	0x1118, 0xc6fc, 0x6eb6, 0x04f8, 0x6eb6, 0xa684, 0x0060, 0x05d8,
-	0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898,
-	0x68aa, 0x080c, 0x3d52, 0x0478, 0xd6ac, 0x0140, 0xa006, 0x080c,
-	0x3d52, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068, 0x2408, 0x2510,
-	0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x69aa,
-	0x6aa6, 0x080c, 0x3d52, 0xd6fc, 0x01b0, 0xa684, 0x7fff, 0x68b6,
-	0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007, 0xa084, 0x007f,
-	0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94,
-	0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030, 0x1904, 0x248f,
-	0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065,
-	0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x0005,
-	0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a,
-	0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3831, 0x7047, 0x0000,
-	0xa282, 0x0006, 0x0310, 0x080c, 0x243b, 0x2300, 0x0002, 0x33b2,
-	0x33e4, 0x340f, 0x2200, 0x0002, 0x33ba, 0x3831, 0x33bc, 0x33ba,
-	0x343f, 0x349d, 0x080c, 0x243b, 0x7003, 0x0005, 0xb284, 0x0600,
-	0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12, 0x2068, 0x704e,
-	0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x33cb,
-	0x015e, 0xb284, 0x0600, 0x0118, 0x6817, 0x0000, 0x0010, 0x6817,
-	0x8000, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
-	0x6827, 0x0003, 0x0804, 0x3809, 0x7000, 0xa086, 0x0002, 0x1150,
-	0x080c, 0x35c5, 0x0010, 0x080c, 0x3d52, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8, 0x7003, 0x0005,
-	0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12,
-	0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0002, 0x3831,
-	0x340d, 0x340d, 0x343f, 0x340d, 0x3831, 0x080c, 0x243b, 0x7000,
-	0xa086, 0x0002, 0x1150, 0x080c, 0x35c5, 0x0010, 0x080c, 0x3d52,
-	0x6008, 0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003,
-	0x0da8, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0,
-	0x0010, 0x2001, 0x8b12, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046,
-	0x2200, 0x0002, 0x343a, 0x3438, 0x3438, 0x343a, 0x3438, 0x343a,
-	0x080c, 0x243b, 0x080c, 0x3846, 0x781b, 0x0082, 0x0005, 0x7000,
-	0xa086, 0x0002, 0x1158, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba,
-	0x2d00, 0x70be, 0x0038, 0x080c, 0x3d52, 0x0020, 0x7000, 0xa086,
-	0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b,
-	0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x89c0, 0xb284,
-	0x0600, 0x1118, 0xc2fd, 0x2069, 0x8ad0, 0x2d04, 0x2d08, 0x715e,
-	0xa06d, 0x0128, 0x6814, 0xa206, 0x0500, 0x6800, 0x0cb8, 0x7003,
-	0x0005, 0xd2fc, 0x1118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12,
-	0x2068, 0x704e, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000,
-	0x1f04, 0x347d, 0x015e, 0xad80, 0x0009, 0x7046, 0x6a16, 0x68b7,
-	0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x7e5a, 0x6920,
-	0xa184, 0x0c00, 0x0904, 0x3507, 0x681b, 0x0005, 0xc1ad, 0xc1d4,
-	0x6922, 0x080c, 0x383d, 0x0804, 0x3507, 0x7200, 0xa286, 0x0002,
-	0x1158, 0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be,
-	0x0030, 0x080c, 0x3d52, 0x0018, 0xa286, 0x0003, 0x0dd0, 0x7003,
-	0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484,
-	0x001f, 0xa215, 0xb284, 0x0600, 0x1108, 0xc2fd, 0x79a8, 0x79a8,
-	0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d,
-	0x0128, 0x6814, 0xa206, 0x0538, 0x6800, 0x0cb8, 0x7003, 0x0005,
-	0xb284, 0x0600, 0x0118, 0x2001, 0x8ae0, 0x0010, 0x2001, 0x8b12,
-	0x2068, 0x704e, 0x0156, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000,
-	0x1f04, 0x34dd, 0x015e, 0xb284, 0x0600, 0x0110, 0xc2fc, 0x0008,
-	0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823,
-	0x0800, 0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0178,
-	0xd0dc, 0x0118, 0x080c, 0x3843, 0x0050, 0x681b, 0x0005, 0xc1ad,
-	0xc1d4, 0x6922, 0x080c, 0x383d, 0x707f, 0x0000, 0x0000, 0xa6ac,
-	0x0060, 0x05c8, 0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x11c0,
-	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4, 0xb7ff, 0xa586, 0x0060,
-	0x0550, 0xc6ed, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0128, 0x2009,
-	0x0082, 0x2019, 0x0000, 0x2320, 0x791a, 0x080c, 0x3fb8, 0x0418,
-	0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01a0, 0x7bd2,
-	0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xc6f4, 0x7e5a, 0x2011, 0x0083,
-	0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000, 0x2320, 0x7a1a,
-	0x080c, 0x3fe5, 0x0040, 0x7e5a, 0x2009, 0x0083, 0xd69c, 0x0110,
-	0x2009, 0x0082, 0x791a, 0x68c0, 0x705a, 0x2d00, 0x704e, 0x68c4,
-	0x2060, 0x71d4, 0xd1b4, 0x1904, 0x248c, 0x2300, 0xa405, 0x0904,
-	0x248c, 0x70a4, 0xa086, 0x0001, 0x1904, 0x24ce, 0x0005, 0x6020,
+	0x0006, 0x2011, 0x4602, 0x220c, 0xa102, 0x2012, 0x000e, 0x001e,
+	0xa102, 0x0338, 0x6012, 0x1128, 0x2011, 0x4604, 0x2204, 0xc0a5,
+	0x2012, 0x601b, 0x0000, 0xace0, 0x0010, 0x1f04, 0x2a13, 0x8421,
+	0x1d00, 0x015e, 0x7063, 0x0000, 0x7003, 0x0000, 0x704b, 0x0000,
+	0x0005, 0x0046, 0x2404, 0xa005, 0x01a8, 0x2068, 0x6800, 0x0006,
+	0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00,
+	0x681e, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x080c, 0x1da2,
+	0x000e, 0x0c48, 0x004e, 0x2023, 0x0000, 0x0005, 0xa282, 0x0003,
+	0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2a60, 0x2add, 0x2af7,
+	0xa282, 0x0002, 0x0110, 0x080c, 0x254c, 0x7060, 0x7063, 0x0000,
+	0x707f, 0x0000, 0x0022, 0x77d0, 0xc7c5, 0x77d2, 0x0002, 0x2a77,
+	0x2a77, 0x2a79, 0x2ab1, 0x37d8, 0x2a77, 0x2ab1, 0x2a77, 0x080c,
+	0x254c, 0x7770, 0x080c, 0x3a66, 0x7770, 0xa7bc, 0x8f00, 0x080c,
+	0x3b6f, 0x6018, 0xa005, 0x0528, 0xd7fc, 0x1118, 0x2021, 0x8cc0,
+	0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005, 0x2011, 0x0010, 0x080c,
+	0x2b11, 0x01b8, 0x0156, 0x20a9, 0x0101, 0xd7fc, 0x1118, 0x2021,
+	0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046, 0x2009, 0x0005, 0x2011,
+	0x0010, 0x080c, 0x2b11, 0x004e, 0x0118, 0x8420, 0x1f04, 0x2a9c,
+	0x015e, 0x8738, 0xa784, 0x001f, 0x1990, 0x0804, 0x25a0, 0x0804,
+	0x25a0, 0x7770, 0x080c, 0x3b6f, 0x6018, 0xa005, 0x0520, 0xd7fc,
+	0x1118, 0x2021, 0x8cc0, 0x0010, 0x2021, 0x8dd0, 0x2009, 0x0005,
+	0x2011, 0x0020, 0x080c, 0x2b11, 0x01b0, 0x0156, 0x20a9, 0x0101,
+	0xd7fc, 0x1118, 0x2021, 0x8bc0, 0x0010, 0x2021, 0x8cd0, 0x0046,
+	0x2009, 0x0005, 0x2011, 0x0020, 0x04e1, 0x004e, 0x0118, 0x8420,
+	0x1f04, 0x2acf, 0x015e, 0x0804, 0x25a0, 0x2200, 0x0002, 0x2ae2,
+	0x2ae4, 0x2ae4, 0x080c, 0x254c, 0x2009, 0x0012, 0x7060, 0xa086,
+	0x0002, 0x0110, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0108, 0x691a,
+	0x7063, 0x0000, 0x70d0, 0xc0c5, 0x70d2, 0x0804, 0x3be5, 0x2200,
+	0x0002, 0x2afe, 0x2ae4, 0x2afc, 0x080c, 0x254c, 0x080c, 0x3f26,
+	0x7000, 0xa086, 0x0002, 0x1904, 0x375d, 0x080c, 0x37be, 0x6008,
+	0xa084, 0xfbef, 0x600a, 0x080c, 0x374f, 0x0904, 0x375d, 0x0804,
+	0x25a0, 0x2404, 0xa005, 0x0590, 0x2068, 0x2d04, 0x0006, 0x6814,
+	0xa706, 0x0118, 0x2d20, 0x000e, 0x0ca8, 0x000e, 0x2022, 0x691a,
+	0x6817, 0x0000, 0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e,
+	0x6820, 0xa084, 0x00ff, 0xa205, 0x6822, 0x080c, 0x1da2, 0x2021,
+	0x4602, 0x241c, 0x8319, 0x2322, 0x6010, 0x8001, 0x6012, 0x1128,
+	0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef,
+	0x600a, 0x080c, 0x269e, 0x080c, 0x37be, 0x0005, 0xa085, 0x0001,
+	0x0ce0, 0x2300, 0x0002, 0x2b50, 0x2b4e, 0x2bcb, 0x080c, 0x254c,
+	0x78e4, 0xa005, 0x17b0, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104,
+	0x259d, 0x0010, 0x0304, 0x259d, 0x2008, 0xa084, 0x0030, 0x1110,
+	0x0804, 0x322a, 0x78ec, 0xa084, 0x0003, 0x0dd0, 0x7884, 0xd0fc,
+	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
+	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2bae,
+	0x2bb7, 0x2ba4, 0x2b87, 0x3c29, 0x3c29, 0x2b87, 0x2bc1, 0x080c,
+	0x254c, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086, 0x0002,
+	0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56, 0x7060,
+	0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90, 0x79e4,
+	0x2001, 0x0003, 0x0804, 0x2f18, 0x6818, 0xd0fc, 0x0110, 0x681b,
+	0x001d, 0x080c, 0x3a3c, 0x781b, 0x006e, 0x0005, 0x6818, 0xd0fc,
+	0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x0804, 0x3c07, 0x6818,
+	0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c, 0x781b, 0x00fa,
+	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x080c, 0x3a3c,
+	0x781b, 0x00cb, 0x0005, 0xa584, 0x000f, 0x11c0, 0x7000, 0x0002,
+	0x25a0, 0x2bd8, 0x2bda, 0x375d, 0x375d, 0x375d, 0x2bd8, 0x2bd8,
+	0x080c, 0x254c, 0x080c, 0x37be, 0x6008, 0xa084, 0xfbef, 0x600a,
+	0x080c, 0x374f, 0x0904, 0x375d, 0x0804, 0x25a0, 0x78e4, 0xa005,
+	0x1b04, 0x2b89, 0x3208, 0xa18c, 0x0800, 0x0118, 0x0104, 0x2b89,
+	0x0010, 0x0304, 0x2b89, 0x2008, 0xa084, 0x0030, 0x1118, 0x781b,
+	0x0068, 0x0005, 0x78ec, 0xa084, 0x0003, 0x0dc8, 0x7884, 0xd0fc,
+	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
+	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c26,
+	0x2c2a, 0x2c21, 0x2c1f, 0x3c29, 0x3c29, 0x2c1f, 0x3c23, 0x080c,
+	0x254c, 0x080c, 0x3a42, 0x781b, 0x006e, 0x0005, 0x080c, 0x3a42,
+	0x0804, 0x3c07, 0x080c, 0x3a42, 0x781b, 0x00fa, 0x0005, 0x080c,
+	0x3a42, 0x781b, 0x00cb, 0x0005, 0x2300, 0x0002, 0x2c3b, 0x2c39,
+	0x2c3d, 0x080c, 0x254c, 0x0804, 0x33e2, 0x681b, 0x0016, 0x78a3,
+	0x0000, 0x79e4, 0xa184, 0x0030, 0x0904, 0x33e2, 0x78ec, 0xa084,
+	0x0003, 0x0904, 0x33e2, 0xa184, 0x0100, 0x0d98, 0x7884, 0xd0fc,
+	0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007, 0xa086, 0x0004,
+	0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007, 0xa086, 0x0005,
+	0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001, 0x0002, 0x2c6f,
+	0x2c2a, 0x2ba4, 0x3be5, 0x3c29, 0x3c29, 0x3be5, 0x3c23, 0x080c,
+	0x3bf1, 0x0005, 0xa282, 0x0005, 0x0310, 0x080c, 0x254c, 0x7898,
+	0x2040, 0x2300, 0x0002, 0x2c7e, 0x2ea8, 0x2eb2, 0x2200, 0x0002,
+	0x2c9a, 0x2c87, 0x2c9a, 0x2c85, 0x2e8a, 0x080c, 0x254c, 0x789b,
+	0x0018, 0x78a8, 0x2010, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0a04,
+	0x3a0b, 0xa08a, 0x0004, 0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x3a0b,
+	0x3a0b, 0x39c1, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0148,
+	0x0804, 0x3a0b, 0x7000, 0xa005, 0x1dd8, 0x2011, 0x0004, 0x0804,
+	0x3594, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x1a04, 0x3a0b, 0x0002,
+	0x2cc2, 0x2cc0, 0x2cd4, 0x2cd8, 0x2d86, 0x3a0b, 0x3a0b, 0x2d88,
+	0x3a0b, 0x3a0b, 0x2e86, 0x2e86, 0x3a0b, 0x3a0b, 0x3a0b, 0x2e88,
+	0x080c, 0x254c, 0xd6e4, 0x0140, 0x2001, 0x0300, 0x8000, 0x8000,
+	0x783a, 0x781b, 0x00c7, 0x0005, 0x6818, 0xd0fc, 0x0118, 0x681b,
+	0x001d, 0x0c90, 0x0804, 0x3be5, 0x681b, 0x001d, 0x0804, 0x3a36,
+	0x6920, 0x6922, 0xa684, 0x1800, 0x1904, 0x2d29, 0x6820, 0xd084,
+	0x1904, 0x2d31, 0x6818, 0xa086, 0x0008, 0x1110, 0x681b, 0x0000,
+	0xd6d4, 0x0568, 0xd6bc, 0x0558, 0x7083, 0x0000, 0x6818, 0xa084,
+	0x003f, 0xa08a, 0x000d, 0x0718, 0xa08a, 0x000c, 0x7182, 0x2001,
+	0x000c, 0x800c, 0x7186, 0x789b, 0x0061, 0x78aa, 0x0156, 0x0136,
+	0x0146, 0x0016, 0x3208, 0xa18c, 0x0600, 0x0118, 0x20a1, 0x022b,
+	0x0010, 0x20a1, 0x012b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac,
+	0xad80, 0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6038,
+	0xa005, 0x1150, 0x681c, 0xa084, 0x000e, 0x0904, 0x3a36, 0x080c,
+	0x3a48, 0x782b, 0x3008, 0x0010, 0x8001, 0x603a, 0x781b, 0x0071,
+	0x0005, 0xd6e4, 0x0130, 0x781b, 0x0083, 0x0005, 0x781b, 0x0083,
+	0x0005, 0xa684, 0x0060, 0x0dd0, 0xd6dc, 0x0dc0, 0xd6fc, 0x01a0,
+	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x8007, 0xa084,
+	0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
+	0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4, 0x0118, 0xc6f4, 0x7e5a,
+	0x6eb6, 0x7000, 0xa086, 0x0003, 0x1148, 0x0006, 0x080c, 0x3f26,
+	0x080c, 0x41d9, 0x000e, 0x781b, 0x0080, 0x0005, 0xa006, 0x080c,
+	0x42b5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0120,
+	0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6,
+	0x7bd6, 0x7bde, 0x2300, 0xa405, 0x1130, 0xc6f5, 0x7e5a, 0x6eb6,
+	0x781b, 0x0080, 0x0005, 0x781b, 0x0080, 0x2200, 0xa115, 0x1118,
+	0x080c, 0x41d9, 0x0005, 0x080c, 0x4206, 0x0005, 0x080c, 0x254c,
+	0x0804, 0x2e1c, 0x00c6, 0x7054, 0x2060, 0x6920, 0xa18c, 0xecff,
+	0x6922, 0x6000, 0xa084, 0xcfdf, 0x6002, 0x080c, 0x38f4, 0xa006,
+	0x2040, 0x2038, 0x080c, 0x399c, 0x0804, 0x2e10, 0x00c6, 0x7054,
+	0x2060, 0x2c48, 0x7aa8, 0xa294, 0x00ff, 0xa286, 0x0004, 0x11d8,
+	0x6920, 0xd1e4, 0x1170, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031,
+	0x0000, 0xa006, 0x2010, 0x080c, 0x38f7, 0x080c, 0x399c, 0x0804,
+	0x2e10, 0xa18c, 0xecff, 0x6922, 0x6104, 0xa18c, 0xffdd, 0x6106,
+	0x6000, 0xc0ac, 0x6002, 0xa286, 0x0003, 0x01d0, 0x6104, 0xa184,
+	0x0010, 0x0548, 0x080c, 0x3b6b, 0x080c, 0x3977, 0x88ff, 0x0518,
+	0x00ce, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
+	0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005,
+	0x6920, 0xd1cc, 0x0130, 0xa18c, 0xfdff, 0x6922, 0x6000, 0xc0ec,
+	0x6002, 0x2039, 0x0000, 0x2041, 0x0000, 0x2031, 0x0000, 0xa006,
+	0x2010, 0x080c, 0x399c, 0xa286, 0x0001, 0x0158, 0x6104, 0xa184,
+	0x0008, 0x01b0, 0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x1980,
+	0x0078, 0x6920, 0xd1c4, 0x0130, 0xa18c, 0xfeff, 0x6922, 0x6000,
+	0xc0e4, 0x6002, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7,
+	0x00ce, 0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b,
+	0x0083, 0x0005, 0x0804, 0x3a32, 0x2808, 0x789b, 0x0080, 0x2019,
+	0x0080, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x11b8, 0x2300,
+	0xa102, 0xa086, 0x0001, 0x0904, 0x2d8a, 0x7ca8, 0xa4a4, 0x00ff,
+	0xa480, 0x0002, 0xa300, 0x2018, 0xa102, 0x0a04, 0x2d9e, 0x0904,
+	0x2d9e, 0x24a8, 0x7aa8, 0x1f04, 0x2e3a, 0x0c18, 0xa284, 0x00f0,
+	0xa082, 0x0020, 0x06b8, 0x2200, 0xa082, 0x0021, 0x1698, 0x7aa8,
+	0x8318, 0x8318, 0x2100, 0xa302, 0x0aa0, 0xa286, 0x0023, 0x0950,
+	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
+	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x78a0, 0x8001, 0x0904,
+	0x2e10, 0x20a8, 0x7998, 0x789b, 0x0060, 0x78aa, 0x2011, 0x0080,
+	0x799a, 0x78a8, 0x7998, 0x7a9a, 0x78aa, 0x7a98, 0x1f04, 0x2e68,
+	0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005, 0x781b,
+	0x0082, 0x0005, 0x8318, 0x2100, 0xa302, 0x0a04, 0x2e21, 0xa284,
+	0x0080, 0x1904, 0x3a36, 0x78a0, 0xa005, 0x08c8, 0x0804, 0x3a36,
+	0x0804, 0x3a0b, 0x7054, 0xa04d, 0x789b, 0x0018, 0x78a8, 0xa084,
+	0x00ff, 0xa08e, 0x0001, 0x0110, 0x080c, 0x254c, 0x7aa8, 0xa294,
+	0x00ff, 0x784b, 0x0008, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0005,
+	0x1a04, 0x3a0b, 0x0002, 0x3a0b, 0x380c, 0x3a0b, 0x3927, 0x3d31,
+	0xa282, 0x0000, 0x1110, 0x080c, 0x254c, 0x080c, 0x3a3c, 0x781b,
+	0x0082, 0x0005, 0xa282, 0x0003, 0x1110, 0x080c, 0x254c, 0xd4fc,
+	0x11d0, 0x7060, 0xa005, 0x0110, 0x080c, 0x254c, 0x6f14, 0x7772,
+	0xa7bc, 0x8f00, 0x080c, 0x3b6f, 0x6008, 0xa085, 0x0021, 0x600a,
+	0x8738, 0xa784, 0x001f, 0x1db0, 0x080c, 0x3a3f, 0x7063, 0x0002,
+	0x701f, 0x0009, 0x0010, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005,
+	0xa282, 0x0004, 0x0310, 0x080c, 0x254c, 0x2300, 0x0002, 0x2ee2,
+	0x3078, 0x30b4, 0xa286, 0x0003, 0x0598, 0x7200, 0x7cd8, 0x7ddc,
+	0x7fd0, 0x71d0, 0xd1b4, 0x0528, 0xd1bc, 0x1518, 0x2001, 0x4601,
+	0x2004, 0xd0c4, 0x11f0, 0x7868, 0xa084, 0x00ff, 0x11d0, 0xa282,
+	0x0002, 0x12b8, 0x00d6, 0x783b, 0x8300, 0x781b, 0x0059, 0x70b8,
+	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
+	0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x2001, 0x0000,
+	0x0058, 0x783b, 0x1300, 0x781b, 0x0057, 0x2001, 0x0000, 0x0020,
+	0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x7046, 0x68a0, 0xd0ec, 0x0118,
+	0x6008, 0xc08d, 0x600a, 0xa284, 0x000f, 0x0002, 0x3059, 0x2f33,
+	0x2f30, 0x3184, 0x320f, 0x25a0, 0x2f2e, 0x2f2e, 0x080c, 0x254c,
+	0x6008, 0xc0d4, 0x600a, 0xd6e4, 0x0120, 0x7044, 0xa086, 0x0014,
+	0x11e8, 0x080c, 0x3f26, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0108,
+	0x7044, 0xa086, 0x0014, 0x0168, 0x6818, 0xa086, 0x0008, 0x1904,
+	0x301b, 0x7858, 0xd09c, 0x0904, 0x301b, 0x6820, 0xd0ac, 0x0904,
+	0x301b, 0x681b, 0x0014, 0x2009, 0x0002, 0x04a8, 0x7868, 0xa08c,
+	0x00ff, 0x0588, 0xa186, 0x0008, 0x1158, 0x6008, 0xc0a4, 0x600a,
+	0x080c, 0x374f, 0x0540, 0x080c, 0x37be, 0x080c, 0x3f26, 0x0060,
+	0xa186, 0x0028, 0x1500, 0x6018, 0xa005, 0x0d78, 0x8001, 0x0d68,
+	0x8001, 0x0d58, 0x601e, 0x0c48, 0x6820, 0xd084, 0x0904, 0x25a0,
+	0xc084, 0x6822, 0x080c, 0x2693, 0x7058, 0x00c6, 0x2060, 0x6800,
+	0x6002, 0x00ce, 0x6004, 0x6802, 0xa005, 0x2d00, 0x1108, 0x6002,
+	0x6006, 0x0804, 0x25a0, 0x0016, 0x81ff, 0x15f0, 0x7000, 0xa086,
+	0x0030, 0x05d0, 0x71d0, 0xd1bc, 0x15b8, 0xd1b4, 0x11e8, 0x705c,
+	0xa005, 0x1590, 0x70a0, 0xa086, 0x0001, 0x0570, 0x7003, 0x0000,
+	0x0046, 0x0056, 0x0076, 0x0066, 0x00c6, 0x00d6, 0x080c, 0x25c5,
+	0x00de, 0x00ce, 0x006e, 0x007e, 0x005e, 0x004e, 0x71d0, 0xd1b4,
+	0x11d8, 0x7003, 0x0040, 0x00c0, 0x080c, 0x3c33, 0x11a8, 0x781b,
+	0x0068, 0x00d6, 0x70b8, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
+	0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030,
+	0x7808, 0xc08d, 0x780a, 0x00de, 0x080c, 0x30dc, 0x001e, 0x81ff,
+	0x0904, 0x301b, 0xa684, 0xdf00, 0x681e, 0x682b, 0x0000, 0x6f14,
+	0xa186, 0x0002, 0x1904, 0x301c, 0x6818, 0xa086, 0x0014, 0x1130,
+	0x2008, 0xd6e4, 0x0118, 0x7868, 0xa08c, 0x00ff, 0x080c, 0x3a55,
+	0x080c, 0x269e, 0x6820, 0xd0dc, 0x1578, 0x8717, 0xa294, 0x000f,
+	0x8213, 0x8213, 0x8213, 0xb284, 0x0600, 0x0118, 0xa290, 0x4ac0,
+	0x0010, 0xa290, 0x4b40, 0xa290, 0x0000, 0x221c, 0xd3c4, 0x0170,
+	0x6820, 0xd0e4, 0x0128, 0xa084, 0xefff, 0x6822, 0xc3ac, 0x2312,
+	0x8210, 0x2204, 0xa085, 0x0038, 0x2012, 0x8211, 0xd3d4, 0x0138,
+	0x68a0, 0xd0c4, 0x1120, 0x080c, 0x3144, 0x0804, 0x25a0, 0x6008,
+	0xc08d, 0x600a, 0x0008, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0110,
+	0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0168,
+	0x2009, 0x4602, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x1128,
+	0x2021, 0x4604, 0x2404, 0xc0a5, 0x2022, 0x6018, 0xa005, 0x0118,
+	0x8001, 0x601a, 0x1118, 0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084,
+	0x1130, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006, 0x0020, 0x7058,
+	0x2060, 0x6800, 0x6002, 0x2061, 0x4600, 0x6887, 0x0103, 0x2d08,
+	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0110, 0x2d02, 0x0008,
+	0x616e, 0x7200, 0xa286, 0x0030, 0x0158, 0xa286, 0x0040, 0x1904,
+	0x25a0, 0x7003, 0x0002, 0x7048, 0x2068, 0x68c4, 0x2060, 0x0005,
+	0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e, 0x70b4, 0xa065,
+	0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009, 0x7042, 0x0005,
+	0xa282, 0x0004, 0x0210, 0x080c, 0x254c, 0x2200, 0x0002, 0x3083,
+	0x3092, 0x309e, 0x3092, 0xa586, 0x1300, 0x0160, 0xa586, 0x8300,
+	0x1d90, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084,
+	0xfbef, 0x600a, 0x7000, 0xa086, 0x0005, 0x0128, 0x080c, 0x3a3c,
+	0x781b, 0x0082, 0x0005, 0x781b, 0x0083, 0x0005, 0x7890, 0x8007,
+	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
+	0x00ff, 0xa186, 0x0003, 0x0128, 0xa186, 0x0000, 0x0110, 0x0804,
+	0x3a0b, 0x781b, 0x0083, 0x0005, 0x6820, 0xc095, 0x6822, 0x82ff,
+	0x1118, 0x080c, 0x3a3c, 0x0030, 0x8211, 0x0110, 0x080c, 0x254c,
+	0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x080c, 0x3c46, 0x7830,
+	0xa084, 0x00c0, 0x1170, 0x0016, 0x3208, 0xa18c, 0x0800, 0x001e,
+	0x0118, 0x0104, 0x30d9, 0x0010, 0x0304, 0x30d9, 0x791a, 0xa006,
+	0x0005, 0xa085, 0x0001, 0x0005, 0xa684, 0x0060, 0x1130, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x0804, 0x3143, 0xd6dc, 0x1198, 0x68b4,
+	0xd0dc, 0x1180, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7044, 0xa005,
+	0x1130, 0x2200, 0xa105, 0x0904, 0x3f26, 0x7047, 0x0015, 0x0804,
+	0x3f26, 0x0005, 0xd6ac, 0x01f0, 0xd6f4, 0x0130, 0x682f, 0x0000,
+	0x6833, 0x0000, 0x0804, 0x3f26, 0x68b4, 0xa084, 0x4000, 0xa635,
+	0xd6f4, 0x1da0, 0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0xd6dc,
+	0x1128, 0x68b4, 0xd0dc, 0x0110, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32,
+	0x0804, 0x3f26, 0xd6f4, 0x0130, 0x682f, 0x0000, 0x6833, 0x0000,
+	0x0804, 0x3f26, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x1da0,
+	0x7044, 0xa005, 0x1110, 0x7047, 0x0015, 0x2408, 0x2510, 0x2700,
+	0x8007, 0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x692e, 0x6a32,
+	0x2100, 0xa205, 0x1110, 0x0804, 0x3f26, 0x7000, 0xa086, 0x0006,
+	0x0110, 0x0804, 0x3f26, 0x0005, 0x6946, 0x6008, 0xc0cd, 0xd3cc,
+	0x0108, 0xc08d, 0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f,
+	0x0000, 0x6893, 0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f,
+	0x0003, 0x6833, 0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b,
+	0x0020, 0x7000, 0x0002, 0x25a0, 0x3173, 0x316d, 0x316b, 0x316b,
+	0x316b, 0x316b, 0x316b, 0x080c, 0x254c, 0x6820, 0xd084, 0x1118,
+	0x080c, 0x37a4, 0x0030, 0x7058, 0x2c50, 0x2060, 0x6800, 0x6002,
+	0x2a60, 0xaea0, 0x0017, 0x2404, 0xa005, 0x0110, 0x2020, 0x0cd8,
+	0x2d22, 0x206b, 0x0000, 0x0005, 0x080c, 0x37aa, 0x080c, 0x37be,
+	0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14,
+	0x6938, 0x691a, 0x6944, 0x6916, 0x2009, 0x0000, 0xae86, 0x4640,
+	0x0110, 0x2009, 0x0001, 0x080c, 0x42ec, 0xd6dc, 0x01c8, 0x691c,
+	0xc1ed, 0x691e, 0x6828, 0xa082, 0x000e, 0x0290, 0x6848, 0xa084,
+	0x000f, 0xa086, 0x000b, 0x1160, 0x685c, 0xa086, 0x0047, 0x1140,
+	0x2001, 0x4601, 0x2004, 0xd0ac, 0x1118, 0x2700, 0x080c, 0x2475,
+	0x6818, 0xd0fc, 0x0140, 0x681b, 0x0000, 0x7868, 0xa08c, 0x00ff,
+	0x0110, 0x681b, 0x001e, 0xaea0, 0x0017, 0x6800, 0x2022, 0x6a3c,
+	0x6940, 0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0580,
+	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x00d6, 0x00f6,
+	0x0156, 0x0146, 0x2079, 0x4600, 0x080c, 0x1b93, 0x014e, 0x015e,
+	0x00fe, 0x70c8, 0x2010, 0x2009, 0x0101, 0x0026, 0x2204, 0xa06d,
+	0x0140, 0x6814, 0xa706, 0x0110, 0x6800, 0x0cc8, 0x6820, 0xc0d5,
+	0x6822, 0x002e, 0x8210, 0x8109, 0x1d80, 0x00de, 0x7063, 0x0003,
+	0x707b, 0x0000, 0x7772, 0x707f, 0x000f, 0x71d0, 0xc1c4, 0x71d2,
+	0x6818, 0xa086, 0x0002, 0x1138, 0x6817, 0x0000, 0x682b, 0x0000,
+	0x681c, 0xc0ec, 0x681e, 0x080c, 0x1da2, 0x0804, 0x25a0, 0x7cd8,
+	0x7ddc, 0x7fd0, 0x080c, 0x30dc, 0x682b, 0x0000, 0x789b, 0x000e,
+	0x6f14, 0x080c, 0x3c4a, 0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc,
+	0x0110, 0x7044, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x7063, 0x0000,
+	0x0804, 0x25a0, 0x7000, 0xa005, 0x1110, 0x0804, 0x25a0, 0xa006,
+	0x080c, 0x3f26, 0x6920, 0xd1ac, 0x1110, 0x681b, 0x0014, 0xa68c,
+	0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822,
+	0x7000, 0x0002, 0x25a0, 0x324c, 0x324c, 0x324f, 0x324f, 0x324f,
+	0x324a, 0x324a, 0x080c, 0x254c, 0x6818, 0x0804, 0x2f18, 0x6008,
+	0xc0a4, 0x600a, 0x6817, 0x0000, 0x0804, 0x3772, 0x2300, 0x0002,
+	0x325b, 0x325d, 0x32ab, 0x080c, 0x254c, 0xd6fc, 0x1904, 0x2d38,
+	0x7000, 0xa00d, 0x0002, 0x25a0, 0x326d, 0x326d, 0x3297, 0x326d,
+	0x32a8, 0x326b, 0x326b, 0x080c, 0x254c, 0xa684, 0x0060, 0x0538,
+	0xa086, 0x0060, 0x1510, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6,
+	0x681c, 0xc0ac, 0x681e, 0xa186, 0x0002, 0x0148, 0x080c, 0x3f26,
+	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c,
+	0x41d9, 0x781b, 0x0083, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0,
+	0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818,
+	0xd0fc, 0x0170, 0xd6f4, 0x1130, 0x681b, 0x0015, 0x781b, 0x0083,
+	0x0804, 0x259d, 0x681b, 0x0007, 0x682f, 0x0000, 0x6833, 0x0000,
+	0x080c, 0x3bf1, 0x0005, 0x080c, 0x254c, 0x2300, 0x0002, 0x32b4,
+	0x32d6, 0x332e, 0x080c, 0x254c, 0x7000, 0x0002, 0x32be, 0x32c0,
+	0x32c7, 0x32be, 0x32be, 0x32be, 0x32be, 0x32be, 0x080c, 0x254c,
+	0x69ac, 0x68b0, 0xa115, 0x0118, 0x080c, 0x4206, 0x0010, 0x080c,
+	0x41d9, 0x681c, 0xc0b4, 0x681e, 0x70d0, 0xd0b4, 0x1904, 0x259d,
+	0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0xd6fc, 0x1904,
+	0x331e, 0x7000, 0xa00d, 0x0002, 0x25a0, 0x32ec, 0x32e6, 0x3316,
+	0x32ec, 0x331b, 0x32e4, 0x32e4, 0x080c, 0x254c, 0x6894, 0x78d6,
+	0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0538, 0xa086,
+	0x0060, 0x1510, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0x6eb6, 0xa186,
+	0x0002, 0x0148, 0x080c, 0x3f26, 0x69ac, 0x68b0, 0xa115, 0x0118,
+	0x080c, 0x4206, 0x0010, 0x080c, 0x41d9, 0x781b, 0x0083, 0x681c,
+	0xc0b4, 0x681e, 0x71d0, 0xd1b4, 0x1904, 0x259d, 0x70a0, 0xa086,
+	0x0001, 0x1904, 0x25e1, 0x0005, 0xd6ec, 0x09f0, 0x6818, 0xd0fc,
+	0x0110, 0x681b, 0x0007, 0x781b, 0x00fb, 0x0005, 0xc6fc, 0x7e5a,
+	0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
+	0xa303, 0x68ae, 0x79d2, 0x781b, 0x0083, 0x0005, 0xd6dc, 0x0130,
+	0x782b, 0x3009, 0x781b, 0x0083, 0x0804, 0x259d, 0x7884, 0xc0ac,
+	0x7886, 0x78e4, 0xa084, 0x0008, 0x1150, 0xa484, 0x0200, 0x0108,
+	0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0083, 0x0804, 0x259d, 0x6820,
+	0xc095, 0x6822, 0x080c, 0x3bdc, 0xc6dd, 0x080c, 0x3a3c, 0x781b,
+	0x0082, 0x0804, 0x259d, 0x2300, 0x0002, 0x3358, 0x335a, 0x335c,
+	0x080c, 0x254c, 0x0804, 0x3a36, 0x7d98, 0xd6d4, 0x15a8, 0x79e4,
+	0xd1ac, 0x0130, 0x78ec, 0xa084, 0x0003, 0x0110, 0x782b, 0x3009,
+	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x7d9a,
+	0x79e4, 0xd1ac, 0x0120, 0x78ec, 0xa084, 0x0003, 0x1120, 0x2001,
+	0x0014, 0x0804, 0x2f18, 0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007,
+	0x0090, 0xa184, 0x0007, 0xa086, 0x0004, 0x1118, 0x2001, 0x0000,
+	0x0050, 0xa184, 0x0007, 0xa086, 0x0005, 0x0118, 0xa184, 0x0007,
+	0x0010, 0x2001, 0x0001, 0x04c2, 0x7a90, 0xa294, 0x0007, 0x789b,
+	0x0060, 0x79a8, 0x81ff, 0x0568, 0x789b, 0x0080, 0x7ba8, 0xa384,
+	0x0001, 0x11d0, 0x7ba8, 0x7ba8, 0xa386, 0x0004, 0x1118, 0x2009,
+	0xffdf, 0x0058, 0xa386, 0x0001, 0x1118, 0x2009, 0xfff7, 0x0028,
+	0xa386, 0x0003, 0x1148, 0x2009, 0xffef, 0x00c6, 0x7054, 0x2060,
+	0x6004, 0xa104, 0x6006, 0x00ce, 0x789b, 0x0060, 0x78ab, 0x0000,
+	0xa684, 0xfffb, 0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xecff,
+	0x6922, 0x7d9a, 0x0804, 0x3be5, 0x2bae, 0x2bb7, 0x33d6, 0x33dc,
+	0x33d4, 0x33d4, 0x3be5, 0x3be5, 0x080c, 0x254c, 0x6920, 0xa18c,
+	0xfcff, 0x6922, 0x0804, 0x3beb, 0x6920, 0xa18c, 0xfcff, 0x6922,
+	0x0804, 0x3be5, 0x79e4, 0xa184, 0x0030, 0x0120, 0x78ec, 0xa084,
+	0x0003, 0x1570, 0x7000, 0xa086, 0x0004, 0x1190, 0x7060, 0xa086,
+	0x0002, 0x1130, 0x2011, 0x0002, 0x2019, 0x0000, 0x0804, 0x2a56,
+	0x7060, 0xa086, 0x0006, 0x0db0, 0x7060, 0xa086, 0x0004, 0x0d90,
+	0x7000, 0xa086, 0x0000, 0x0904, 0x259d, 0x6920, 0xa184, 0x0420,
+	0x0128, 0xc1d4, 0x6922, 0x6818, 0x0804, 0x2f18, 0x6818, 0xa08e,
+	0x0002, 0x0120, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0804, 0x2f18,
+	0x7884, 0xd0fc, 0x1118, 0xa184, 0x0007, 0x0090, 0xa184, 0x0007,
+	0xa086, 0x0004, 0x1118, 0x2001, 0x0000, 0x0050, 0xa184, 0x0007,
+	0xa086, 0x0005, 0x0118, 0xa184, 0x0007, 0x0010, 0x2001, 0x0001,
+	0x0002, 0x3be5, 0x3be5, 0x3439, 0x3be5, 0x3c29, 0x3c29, 0x3be5,
+	0x3be5, 0xd6bc, 0x0570, 0x7180, 0x81ff, 0x0558, 0xa182, 0x000d,
+	0x1318, 0x7083, 0x0000, 0x0028, 0xa182, 0x000c, 0x7082, 0x2009,
+	0x000c, 0x789b, 0x0061, 0x79aa, 0x0156, 0x0136, 0x0146, 0x7084,
+	0x8114, 0xa210, 0x7286, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284,
+	0x0600, 0x0118, 0x20a1, 0x022b, 0x0010, 0x20a1, 0x012b, 0x789b,
+	0x0000, 0x8108, 0x81ac, 0x53a6, 0x014e, 0x013e, 0x015e, 0x0804,
+	0x3beb, 0xd6d4, 0x1904, 0x34ac, 0x6820, 0xd084, 0x0904, 0x3beb,
+	0xa68c, 0x0060, 0xa684, 0x0060, 0x0120, 0xa086, 0x0060, 0x1108,
+	0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000,
+	0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c,
+	0x0904, 0x37d3, 0xa18c, 0x00f8, 0x1904, 0x37d3, 0x0156, 0x0136,
+	0x0146, 0x0016, 0x20a1, 0x012b, 0x3208, 0xa18c, 0x0600, 0x0110,
+	0x20a1, 0x022b, 0x001e, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
+	0x000b, 0x2098, 0x53a6, 0x014e, 0x013e, 0x015e, 0x6814, 0xc0fc,
+	0x8007, 0x7882, 0x0804, 0x3beb, 0x6818, 0xd0fc, 0x0110, 0x681b,
+	0x0008, 0x080c, 0x3a3c, 0x781b, 0x00ed, 0x0005, 0x2300, 0x0002,
+	0x34bd, 0x357a, 0x34bb, 0x080c, 0x254c, 0x7cd8, 0x7ddc, 0x7fd0,
+	0x82ff, 0x1528, 0x7200, 0xa286, 0x0003, 0x0904, 0x2ee6, 0x71d0,
+	0xd1bc, 0x11f8, 0xd1b4, 0x01e8, 0x2001, 0x4601, 0x2004, 0xd0c4,
+	0x11c0, 0x00d6, 0x783b, 0x8800, 0x781b, 0x0059, 0x70b8, 0xa06d,
+	0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
+	0x78da, 0xc1b4, 0x71d2, 0x7003, 0x0030, 0x00de, 0x0030, 0x7200,
+	0x0020, 0x783b, 0x1800, 0x781b, 0x0057, 0xa284, 0x000f, 0x0002,
+	0x3565, 0x3522, 0x34fa, 0x2f15, 0x34f8, 0x3565, 0x34f8, 0x34f8,
+	0x080c, 0x254c, 0x681c, 0xd0ec, 0x0118, 0x6008, 0xc08d, 0x600a,
+	0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005, 0x1108, 0x6002,
+	0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084, 0x000e, 0x1120, 0x71c8,
+	0xa188, 0x0100, 0x0028, 0x7030, 0x68ba, 0x713c, 0x70c8, 0xa108,
+	0x2104, 0x6802, 0x2d0a, 0x715a, 0xd6dc, 0x1120, 0xc6fc, 0x6eb6,
+	0x0804, 0x3565, 0x6eb6, 0xa684, 0x0060, 0x1120, 0xa684, 0x7fff,
+	0x68b6, 0x04d8, 0xd6dc, 0x1150, 0xa684, 0x7fff, 0x68b6, 0x6894,
+	0x68a6, 0x6898, 0x68aa, 0x080c, 0x3f26, 0x0478, 0xd6ac, 0x0140,
+	0xa006, 0x080c, 0x3f26, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0068,
+	0x2408, 0x2510, 0x2700, 0x8007, 0xa084, 0x007f, 0xa108, 0xa291,
+	0x0000, 0x69aa, 0x6aa6, 0x080c, 0x3f26, 0xd6fc, 0x01b0, 0xa684,
+	0x7fff, 0x68b6, 0x2510, 0x2408, 0xd6ac, 0x1138, 0x2700, 0x8007,
+	0xa084, 0x007f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302,
+	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086, 0x0030,
+	0x1904, 0x25a0, 0x7003, 0x0002, 0x70b8, 0xa06d, 0x68bc, 0x703e,
+	0x70b4, 0xa065, 0x68c0, 0x7056, 0x2d00, 0x704a, 0xad80, 0x0009,
+	0x7042, 0x0005, 0xa586, 0x8800, 0x1148, 0x7003, 0x0000, 0x6018,
+	0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0804, 0x3a36,
+	0x7043, 0x0000, 0xa282, 0x0006, 0x0310, 0x080c, 0x254c, 0x2300,
+	0x0002, 0x3594, 0x35a5, 0x35af, 0x2200, 0x0002, 0x359c, 0x3a36,
+	0x359e, 0x359c, 0x35e0, 0x362e, 0x080c, 0x254c, 0x7a80, 0xa294,
+	0x0f00, 0x080c, 0x3682, 0x0804, 0x3a0b, 0x00c1, 0x0002, 0x3a36,
+	0x35ad, 0x35ad, 0x35e0, 0x35ad, 0x3a36, 0x080c, 0x254c, 0x0071,
+	0x0002, 0x35b9, 0x35b7, 0x35b7, 0x35b9, 0x35b7, 0x35b9, 0x080c,
+	0x254c, 0x080c, 0x3a4b, 0x781b, 0x0082, 0x0005, 0x7000, 0xa086,
+	0x0002, 0x1150, 0x080c, 0x37be, 0x0010, 0x080c, 0x3f26, 0x6008,
+	0xa084, 0xfbef, 0x600a, 0x0020, 0x7000, 0xa086, 0x0003, 0x0da8,
+	0x7003, 0x0005, 0x2001, 0x8de0, 0xae8e, 0x4640, 0x0110, 0x2001,
+	0x8e12, 0x2068, 0x704a, 0xad80, 0x0009, 0x7042, 0x2200, 0x0005,
+	0x7000, 0xa086, 0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00,
+	0x70b6, 0x2d00, 0x70ba, 0x0038, 0x080c, 0x3f26, 0x0020, 0x7000,
+	0xa086, 0x0003, 0x0dc8, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00,
+	0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x8cc0,
+	0xb284, 0x0600, 0x1118, 0xc2fd, 0x2069, 0x8dd0, 0x2d04, 0x2d08,
+	0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0120, 0x6800, 0x0cb8,
+	0x080c, 0x3682, 0x6eb4, 0x7e5a, 0x6920, 0xa184, 0x0c00, 0x0904,
+	0x36a8, 0x7060, 0xa086, 0x0006, 0x1128, 0x7070, 0xa206, 0x1110,
+	0x7062, 0x707a, 0x681b, 0x0005, 0xc1ad, 0x681b, 0x0005, 0xc1ad,
+	0xc1d4, 0x6922, 0x080c, 0x3a42, 0x0804, 0x36a8, 0x7200, 0xa286,
+	0x0002, 0x1158, 0x70d0, 0xc0b5, 0x70d2, 0x2c00, 0x70b6, 0x2d00,
+	0x70ba, 0x0030, 0x080c, 0x3f26, 0x0018, 0xa286, 0x0003, 0x0dd0,
+	0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8,
+	0xa484, 0x001f, 0xa215, 0xae86, 0x4640, 0x0108, 0xc2fd, 0x79a8,
+	0x79a8, 0xa18c, 0x00ff, 0x2118, 0x70c8, 0xa168, 0x2d04, 0x2d08,
+	0x715a, 0xa06d, 0x0128, 0x6814, 0xa206, 0x0118, 0x6800, 0x0cb8,
+	0x0409, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0904, 0x36a8, 0xd0dc,
+	0x0178, 0x7060, 0xa086, 0x0004, 0x1140, 0x7070, 0xa206, 0x1128,
+	0x7074, 0xa306, 0x1110, 0x7062, 0x707a, 0x080c, 0x3a48, 0x0480,
+	0x681b, 0x0005, 0xc1ad, 0xc1d4, 0x6922, 0x080c, 0x3a42, 0x707b,
+	0x0000, 0x0430, 0x7003, 0x0005, 0xb284, 0x0600, 0x0118, 0x2001,
+	0x8de0, 0x0010, 0x2001, 0x8e12, 0x2068, 0x704a, 0x0156, 0x20a9,
+	0x0032, 0x2003, 0x0000, 0x8000, 0x1f04, 0x3691, 0x015e, 0xb284,
+	0x0600, 0x0110, 0xc2fc, 0x0008, 0xc2fd, 0x6a16, 0xad80, 0x0009,
+	0x7042, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0005,
+	0xc6ec, 0xa6ac, 0x0060, 0x0904, 0x36ef, 0x6b98, 0x6c94, 0x69ac,
+	0x68b0, 0xa105, 0x11e0, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa586,
+	0x0060, 0x05c8, 0xd6f4, 0x1108, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a,
+	0x2009, 0x0083, 0xd69c, 0x0128, 0x2009, 0x0082, 0x2019, 0x0000,
+	0x2320, 0x791a, 0xd6ec, 0x0588, 0x080c, 0x41d9, 0x0470, 0x68b0,
+	0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x01f8, 0x7bd2, 0x7bda,
+	0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x1108, 0xc6ed, 0xc6f4, 0x7e5a,
+	0x2011, 0x0083, 0xd69c, 0x0128, 0x2011, 0x0082, 0x2019, 0x0000,
+	0x2320, 0x7a1a, 0xd6ec, 0x0188, 0x080c, 0x4206, 0x0070, 0x2019,
+	0x0000, 0x2320, 0x0010, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0083,
+	0xd69c, 0x0110, 0x2009, 0x0082, 0x791a, 0x68c0, 0x7056, 0x2d00,
+	0x704a, 0x68c4, 0x2060, 0x71d0, 0x2001, 0x4601, 0x2004, 0xd0c4,
+	0x15c8, 0x70d4, 0xa02d, 0x01b8, 0xd1bc, 0x0548, 0x7a80, 0xa294,
+	0x0f00, 0x70d8, 0xa206, 0x0118, 0x78e0, 0xa504, 0x1558, 0x70d6,
+	0xc1bc, 0x71d2, 0x0438, 0x2031, 0x0001, 0x852c, 0x0218, 0x8633,
+	0x8210, 0x0cd8, 0x0005, 0x7de0, 0xa594, 0xff00, 0x0130, 0x2011,
+	0x0008, 0x852f, 0x0c81, 0x8637, 0x0008, 0x0c69, 0x8217, 0x7880,
+	0xa084, 0x0f00, 0xa206, 0x0170, 0x72da, 0x76d6, 0x0058, 0x7a80,
+	0xa294, 0x0f00, 0x70d8, 0xa236, 0x0dc0, 0x78e0, 0xa534, 0x0da8,
+	0xc1bd, 0x71d2, 0xd1b4, 0x1904, 0x259d, 0x2300, 0xa405, 0x0904,
+	0x259d, 0x70a0, 0xa086, 0x0001, 0x1904, 0x25e1, 0x0005, 0x6020,
 	0xa005, 0x0150, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008, 0x600a,
-	0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3d52,
+	0x700f, 0x0100, 0x702c, 0x6026, 0x0005, 0xa006, 0x080c, 0x3f26,
+	0x7000, 0xa086, 0x0002, 0x0120, 0x7060, 0xa086, 0x0005, 0x1150,
 	0x682b, 0x0000, 0x6817, 0x0000, 0x681b, 0x0001, 0x6823, 0x0040,
-	0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x248f, 0x358b,
-	0x3588, 0x35a7, 0x3594, 0x248f, 0x3586, 0x3586, 0x080c, 0x243b,
-	0x0441, 0x0409, 0x0028, 0x0429, 0x705c, 0x2060, 0x6800, 0x6002,
-	0x080c, 0x1d3d, 0x0804, 0x248f, 0x7064, 0x7067, 0x0000, 0x7083,
-	0x0000, 0x0002, 0x35a3, 0x35a3, 0x35a2, 0x35a2, 0x35a2, 0x35a3,
-	0x35a2, 0x35a3, 0x2971, 0x7067, 0x0000, 0x0804, 0x248f, 0x681b,
-	0x0000, 0x0804, 0x3012, 0x6800, 0xa005, 0x1108, 0x6002, 0x6006,
-	0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4302, 0x2104, 0x8001,
-	0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4304, 0x2404, 0xc0a5,
-	0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005, 0x0110,
-	0x8001, 0x601a, 0x0005, 0x080c, 0x3aa0, 0x681b, 0x0018, 0x04a0,
-	0x080c, 0x3aa0, 0x681b, 0x0019, 0x0478, 0x080c, 0x3aa0, 0x681b,
-	0x001a, 0x0450, 0x080c, 0x3aa0, 0x681b, 0x0003, 0x0428, 0x7774,
-	0x080c, 0x396d, 0x7178, 0xa18c, 0x00ff, 0x3210, 0xa294, 0x0600,
-	0x0118, 0xa1e8, 0x88c0, 0x0010, 0xa1e8, 0x89d0, 0x2d04, 0x2d08,
-	0x2068, 0xa005, 0x1118, 0x707e, 0x0804, 0x248f, 0x6814, 0xc0fc,
-	0x7274, 0xc2fc, 0xa206, 0x0110, 0x6800, 0x0c88, 0x6800, 0x200a,
-	0x681b, 0x0005, 0x707f, 0x0000, 0x080c, 0x35b1, 0x6820, 0xd084,
-	0x1110, 0x080c, 0x35ab, 0x080c, 0x35c5, 0x681f, 0x0000, 0x6823,
-	0x0020, 0x080c, 0x1d3d, 0x0804, 0x248f, 0xa282, 0x0003, 0x1904,
-	0x380d, 0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920,
-	0xc1bd, 0x6922, 0xd1c4, 0x0590, 0xc1c4, 0x6922, 0xa6b4, 0x00ff,
-	0x0510, 0xa682, 0x001c, 0x0218, 0x0110, 0x2031, 0x001c, 0x852b,
-	0x852b, 0x2041, 0x0000, 0x080c, 0x38c6, 0x0118, 0x080c, 0x36f6,
-	0x00a0, 0x080c, 0x3892, 0x080c, 0x36f3, 0x6920, 0xc1c5, 0x6922,
-	0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e, 0x0005,
-	0x781b, 0x0082, 0x0005, 0x080c, 0x36f3, 0x7e58, 0xd6d4, 0x1118,
-	0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x00c6, 0x7058,
-	0x2060, 0x6100, 0xd1e4, 0x0578, 0x6208, 0x8217, 0xa294, 0x00ff,
-	0xa282, 0x001c, 0x0218, 0x0110, 0x2011, 0x001c, 0x2600, 0xa202,
-	0x1208, 0x2230, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130,
-	0xa282, 0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c,
-	0x1210, 0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c,
-	0x3896, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x38c6, 0x0118,
-	0x080c, 0x36f6, 0x0020, 0x080c, 0x3892, 0x080c, 0x36f3, 0x7858,
-	0xc095, 0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960,
-	0x6000, 0xd0e4, 0x1178, 0x6010, 0xa084, 0x000f, 0x1130, 0x6104,
-	0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032, 0x2019,
-	0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294, 0x00ff,
-	0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011, 0x000a,
-	0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308, 0x831f,
-	0xa39c, 0x00ff, 0xa382, 0x001c, 0x0218, 0x0110, 0x2019, 0x001c,
-	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
-	0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3850, 0x00ce,
-	0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106, 0x2011,
-	0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0003,
-	0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5,
-	0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6, 0x7158,
-	0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86, 0x6018,
-	0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c, 0x000f,
-	0xa105, 0x2029, 0x4305, 0x252c, 0xd5cc, 0x0140, 0xd3a4, 0x0110,
-	0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6, 0x6016,
-	0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605, 0x600e,
-	0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282, 0x0002,
-	0x1904, 0x3816, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0568,
-	0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04, 0x3809,
-	0x080c, 0x379c, 0x080c, 0x36f3, 0xa980, 0x0001, 0x200c, 0x080c,
-	0x3969, 0x080c, 0x3696, 0x88ff, 0x0178, 0x789b, 0x0060, 0x2800,
-	0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b, 0x006e,
-	0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118, 0x781b,
-	0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002, 0x1218,
-	0xa284, 0x0001, 0x0140, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec,
-	0x1110, 0x2011, 0x0000, 0x080c, 0x3883, 0x0471, 0x080c, 0x36f3,
-	0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6, 0x0026,
-	0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1150, 0x6014, 0xa084,
-	0x0040, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088, 0x2011, 0x0000,
-	0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0,
-	0x0004, 0x080c, 0x3850, 0x6820, 0xa085, 0x0200, 0x6822, 0x002e,
-	0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009, 0x0000, 0x7058,
-	0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018, 0xa080, 0x0002,
-	0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec, 0xd0b4, 0x1108,
-	0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020, 0x78a6, 0x6016,
-	0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce, 0x0005, 0x0006,
-	0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010, 0x000e, 0x0488,
-	0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558, 0x7bb8, 0x8307,
-	0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff, 0xa09e, 0x0001,
-	0x1904, 0x382d, 0xd6f4, 0x11d0, 0x79d8, 0x7adc, 0xa108, 0xa291,
-	0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c, 0x4083, 0x781b,
-	0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001,
-	0x0001, 0x080c, 0x3f50, 0x0005, 0x080c, 0x243b, 0x781b, 0x0080,
-	0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000, 0x2041, 0x0000,
-	0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x36f6, 0x080c, 0x379a,
-	0x7e58, 0x04f9, 0x781b, 0x0082, 0x0005, 0x0cd9, 0x6820, 0xc0c4,
-	0x6822, 0x00c6, 0x7058, 0x2060, 0x0804, 0x3720, 0x0c91, 0x6820,
-	0xc0cc, 0x6822, 0x00c6, 0x7058, 0x2060, 0x0804, 0x37b9, 0x0c49,
-	0x6820, 0xa084, 0xecff, 0x6822, 0x00c6, 0x7058, 0x2060, 0x6004,
-	0xa084, 0xffc5, 0x6006, 0x00ce, 0x0005, 0x0049, 0x781b, 0x0082,
-	0x0005, 0x6827, 0x0002, 0x0049, 0x781b, 0x0082, 0x0005, 0x2001,
-	0x0005, 0x0088, 0x2001, 0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822,
-	0x2001, 0x0006, 0x0040, 0x2001, 0x000d, 0x0028, 0x2001, 0x0009,
-	0x0010, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a,
-	0x70d4, 0xd0b4, 0x0168, 0xc0b4, 0x70d6, 0x00c6, 0x70b8, 0xa065,
-	0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x00ce,
-	0x0005, 0x0076, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703,
-	0xb28c, 0x0600, 0x0118, 0xa0e0, 0x47c0, 0x0010, 0xa0e0, 0x4840,
-	0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184, 0x7fe0, 0x78ae, 0x6012,
-	0x79a4, 0xa184, 0x773f, 0x78a6, 0x6016, 0x6004, 0xa085, 0x0038,
-	0x6006, 0x007e, 0x0005, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab,
-	0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab, 0x0004,
-	0x0804, 0x3850, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b, 0x0080,
-	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa, 0x7eaa,
-	0x789b, 0x0060, 0x78ab, 0x0005, 0x0804, 0x3850, 0x0156, 0x8007,
-	0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a, 0x79a4,
-	0xa18c, 0xffe0, 0x2021, 0x3952, 0x2019, 0x0011, 0x20a9, 0x000e,
-	0x2011, 0x0032, 0x2404, 0xa084, 0xffe0, 0xa106, 0x0128, 0x8420,
-	0x2300, 0xa210, 0x1f04, 0x38ba, 0x015e, 0x0005, 0x0156, 0x0804,
-	0x3908, 0x2021, 0x3960, 0x20a9, 0x0009, 0x2011, 0x0029, 0xa582,
-	0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033, 0xa582, 0x0033,
-	0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0065, 0x2200,
-	0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04, 0x38df, 0x015e,
-	0x0088, 0x2021, 0x3952, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
-	0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300, 0xa210, 0x1f04,
-	0x38f1, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e, 0xa582, 0x0064,
-	0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x0005,
-	0xa886, 0x0002, 0x01e8, 0x2021, 0x393e, 0x20a9, 0x000d, 0x2011,
-	0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019, 0x0019, 0x2011,
-	0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300, 0xa210, 0x1f04,
-	0x3919, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185, 0x0ab0, 0x0890,
-	0x2021, 0x394d, 0x20a9, 0x0003, 0x2011, 0x0024, 0xa586, 0x0024,
-	0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028, 0x0930, 0x8420,
-	0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x38f1, 0x1021, 0x2202,
-	0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610, 0x4612, 0x5812,
-	0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021, 0xb002, 0xe204,
-	0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403, 0x5404,
-	0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07, 0x0e07,
-	0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07, 0x7e07,
-	0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784, 0x0f00, 0x800b,
-	0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105, 0xd7fc,
-	0x0118, 0xa0e0, 0x68c0, 0x0010, 0xa0e0, 0x48c0, 0x0005, 0x00e6,
-	0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009, 0x4380, 0x2071,
-	0x4380, 0x0030, 0x2009, 0x4340, 0x2079, 0x0200, 0x2071, 0x4340,
-	0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002, 0x39c5, 0x39a0,
-	0x39a0, 0x39a0, 0x39a0, 0x39a0, 0x399e, 0x399e, 0x080c, 0x243b,
-	0x784b, 0x0004, 0x7848, 0xa084, 0x0004, 0x1de0, 0x784b, 0x0008,
-	0x7848, 0xa084, 0x0008, 0x1de0, 0x68b4, 0xc0f5, 0x68b6, 0x7858,
-	0xc0f5, 0x785a, 0x7830, 0xd0bc, 0x1180, 0xb284, 0x0800, 0x0118,
-	0x0104, 0x39c5, 0x0010, 0x0304, 0x39c5, 0x681c, 0xd0ac, 0x1118,
-	0x080c, 0x3a4b, 0x0010, 0x781b, 0x00fb, 0x2091, 0x8001, 0x00fe,
-	0x00ee, 0x0005, 0x00c6, 0x2001, 0x4301, 0x2004, 0xd0ac, 0x1904,
-	0x3a3d, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xb28c, 0x0600, 0x0118, 0xa0e0, 0x47c0, 0x0010, 0xa0e0, 0x4840,
-	0x6004, 0xa084, 0x000a, 0x1904, 0x3a3d, 0x6108, 0xa194, 0xff00,
-	0x0904, 0x3a3d, 0xa18c, 0x00ff, 0x601c, 0xa084, 0xff00, 0x0180,
-	0x2001, 0x0009, 0xa102, 0x16b8, 0x2001, 0x000a, 0xa102, 0x16b0,
-	0x2001, 0x000c, 0xa102, 0x16a8, 0x601c, 0xa084, 0x00ff, 0x601e,
-	0x2001, 0x000a, 0xa106, 0x01a8, 0x2001, 0x000c, 0xa106, 0x01a0,
-	0x2001, 0x0012, 0xa106, 0x0198, 0x2001, 0x0014, 0xa106, 0x0190,
-	0x2001, 0x0019, 0xa106, 0x0188, 0x2001, 0x0032, 0xa106, 0x0180,
-	0x00d8, 0x2009, 0x000c, 0x00d0, 0x2009, 0x0012, 0x00b8, 0x2009,
-	0x0014, 0x00a0, 0x2009, 0x0019, 0x0088, 0x2009, 0x0020, 0x0070,
-	0x2009, 0x003f, 0x0058, 0x2009, 0x000a, 0x0040, 0x2009, 0x000c,
-	0x0028, 0x2009, 0x0019, 0x0010, 0x2011, 0x0000, 0x2100, 0xa205,
-	0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x00ce, 0x0005, 0x781b,
-	0x0083, 0x0005, 0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005,
-	0x781b, 0x006e, 0x0005, 0x2009, 0x4319, 0x210c, 0xa186, 0x0000,
-	0x0150, 0xa186, 0x0001, 0x0150, 0x701f, 0x000b, 0x7067, 0x0001,
-	0x781b, 0x0054, 0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a,
-	0x0005, 0x2009, 0x4319, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186,
-	0x0001, 0x0138, 0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0054,
-	0x0005, 0x701f, 0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b,
-	0x00fb, 0x0005, 0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005,
-	0x781b, 0x00cb, 0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d,
-	0x7067, 0x0001, 0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0,
-	0x1170, 0x7808, 0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000,
-	0x78ec, 0xa084, 0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005,
-	0x7808, 0xc08d, 0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0,
-	0xb284, 0x0800, 0x0118, 0x1104, 0x3ab2, 0x0010, 0x1304, 0x3ab2,
-	0x78ac, 0x0005, 0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000,
-	0xe000, 0xe000, 0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800,
-	0x0118, 0x1104, 0x3ac1, 0x0010, 0x1304, 0x3ac4, 0x78ac, 0x0006,
-	0x7808, 0xa085, 0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001,
-	0x1904, 0x30a0, 0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68,
-	0x080c, 0x23e1, 0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148,
-	0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x248f, 0x0804,
-	0x3a3f, 0xa784, 0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8,
-	0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x248f, 0x78e4,
-	0xa084, 0x0007, 0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800,
-	0x2030, 0x7e5a, 0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140,
-	0x7884, 0xd0fc, 0x0128, 0x080c, 0x382d, 0x681b, 0x0022, 0x0005,
-	0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000,
-	0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904,
-	0x2a7a, 0xb284, 0x0800, 0x0110, 0x0104, 0x248c, 0x0304, 0x248c,
-	0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc,
-	0x0118, 0xa080, 0x4840, 0x0010, 0xa080, 0x47c0, 0x2060, 0x2048,
-	0x705a, 0x2a60, 0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904,
-	0x3b81, 0xd1ac, 0x05e0, 0x6108, 0x8117, 0xa18c, 0x00ff, 0x631c,
-	0x832f, 0x68a0, 0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec,
-	0xd0e4, 0x0110, 0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c,
-	0x1290, 0x78ec, 0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182,
-	0x000b, 0x1248, 0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011,
-	0x0000, 0x2029, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
-	0x0004, 0x79aa, 0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0,
-	0x0008, 0x6820, 0xa085, 0x1000, 0x6822, 0x080c, 0x3850, 0xa085,
-	0x0001, 0x00ce, 0x0005, 0xa282, 0x0006, 0x1904, 0x381f, 0x7da8,
-	0x7eac, 0x8637, 0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747,
-	0xa7bc, 0x00ff, 0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4,
-	0x05c8, 0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x37fc,
-	0xa6b4, 0x00ff, 0x0560, 0xa682, 0x0039, 0x1a04, 0x37fc, 0xa582,
-	0x0009, 0x0a04, 0x37fc, 0xa882, 0x0003, 0x1a04, 0x37fc, 0xa886,
-	0x0002, 0x0128, 0xa886, 0x0000, 0x0138, 0x0804, 0x37fc, 0xa786,
-	0x0000, 0x0904, 0x37fc, 0x8634, 0x852b, 0x852b, 0x080c, 0x38c6,
-	0x0904, 0x37fc, 0x080c, 0x36f6, 0x080c, 0x379a, 0x7e58, 0xd6d4,
-	0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0x080c,
-	0x36f3, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7158, 0xa188,
-	0x0000, 0x210c, 0xd1ac, 0x0904, 0x37fc, 0xd1ec, 0x1120, 0x2039,
-	0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000, 0x2041,
-	0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff, 0xa706,
-	0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f, 0xa39c,
-	0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705, 0xa086,
-	0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000, 0x2041,
-	0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284, 0xff00,
-	0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128, 0x852b,
-	0x852b, 0x080c, 0x38c6, 0x0d58, 0x080c, 0x36f6, 0x080c, 0x379a,
-	0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004,
-	0x78ab, 0x0000, 0x7daa, 0x7eaa, 0x7faa, 0x2800, 0x78aa, 0x789b,
-	0x0060, 0x78ab, 0x0005, 0x080c, 0x3850, 0x7858, 0xc095, 0x785a,
-	0x781b, 0x0082, 0x0005, 0x0020, 0x0020, 0x0000, 0x0020, 0x0000,
+	0x681f, 0x0100, 0x7000, 0xa084, 0x000f, 0x0002, 0x25a0, 0x3783,
+	0x3780, 0x37a0, 0x378c, 0x25a0, 0x377e, 0x377e, 0x080c, 0x254c,
+	0x0449, 0x0411, 0x0028, 0x0431, 0x7058, 0x2060, 0x6800, 0x6002,
+	0x080c, 0x1da2, 0x0804, 0x25a0, 0x7060, 0x7063, 0x0000, 0x707f,
+	0x0000, 0x0002, 0x379c, 0x379c, 0x379a, 0x379a, 0x379a, 0x379c,
+	0x379a, 0x379c, 0x0804, 0x2a6b, 0x7063, 0x0000, 0x0804, 0x25a0,
+	0x681b, 0x0000, 0x0804, 0x3184, 0x6800, 0xa005, 0x1108, 0x6002,
+	0x6006, 0x0005, 0x6410, 0x84ff, 0x0168, 0x2009, 0x4602, 0x2104,
+	0x8001, 0x200a, 0x8421, 0x6412, 0x1128, 0x2021, 0x4604, 0x2404,
+	0xc0a5, 0x2022, 0x6008, 0xc0a4, 0x600a, 0x0005, 0x6018, 0xa005,
+	0x0110, 0x8001, 0x601a, 0x0005, 0x080c, 0x3c46, 0x681b, 0x0018,
+	0x0490, 0x080c, 0x3c46, 0x681b, 0x0019, 0x0468, 0x080c, 0x3c46,
+	0x681b, 0x001a, 0x0440, 0x080c, 0x3c46, 0x681b, 0x0003, 0x0418,
+	0x7770, 0x080c, 0x3b6f, 0x7174, 0xa18c, 0x00ff, 0x3210, 0xa294,
+	0x0600, 0x0118, 0xa1e8, 0x8bc0, 0x0010, 0xa1e8, 0x8cd0, 0x2d04,
+	0x2d08, 0x2068, 0xa005, 0x1118, 0x707a, 0x0804, 0x25a0, 0x6814,
+	0x7270, 0xa206, 0x0110, 0x6800, 0x0c98, 0x6800, 0x200a, 0x681b,
+	0x0005, 0x707b, 0x0000, 0x080c, 0x37aa, 0x6820, 0xd084, 0x1110,
+	0x080c, 0x37a4, 0x080c, 0x37be, 0x681f, 0x0000, 0x6823, 0x0020,
+	0x080c, 0x1da2, 0x0804, 0x25a0, 0xa282, 0x0003, 0x1904, 0x3a10,
+	0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd,
+	0x6922, 0xd1c4, 0x05b0, 0xc1c4, 0x6922, 0xa6b4, 0x00ff, 0x0530,
+	0xa682, 0x0018, 0x0218, 0x0110, 0x2031, 0x0018, 0xa686, 0x0010,
+	0x1108, 0x8630, 0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9,
+	0x0118, 0x080c, 0x38f7, 0x00a0, 0x080c, 0x3a95, 0x080c, 0x38f4,
+	0x6920, 0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118,
+	0x781b, 0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x080c, 0x38f4,
+	0x7e58, 0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083,
+	0x0005, 0x00c6, 0x7054, 0x2060, 0x6100, 0xd1e4, 0x0598, 0x6208,
+	0x8217, 0xa294, 0x00ff, 0xa282, 0x0018, 0x0218, 0x0110, 0x2011,
+	0x0018, 0x2600, 0xa202, 0x1208, 0x2230, 0xa686, 0x0010, 0x1108,
+	0x8630, 0x6208, 0xa294, 0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282,
+	0x000a, 0x1240, 0x2011, 0x000a, 0x0028, 0xa282, 0x000c, 0x1210,
+	0x2011, 0x000c, 0x2200, 0xa502, 0x1208, 0x2228, 0x080c, 0x3a99,
+	0x852b, 0x852b, 0x2041, 0x0000, 0x080c, 0x3ac9, 0x0118, 0x080c,
+	0x38f7, 0x0020, 0x080c, 0x3a95, 0x080c, 0x38f4, 0x7858, 0xc095,
+	0x785a, 0x00ce, 0x781b, 0x0082, 0x0005, 0x00c6, 0x2960, 0x6000,
+	0xd0e4, 0x1188, 0xd0b4, 0x1150, 0x6010, 0xa084, 0x000f, 0x1130,
+	0x6104, 0xa18c, 0xfff5, 0x6106, 0x00ce, 0x0005, 0x2011, 0x0032,
+	0x2019, 0x0000, 0x00f0, 0x68a0, 0xd0cc, 0x1dc0, 0x6208, 0xa294,
+	0x00ff, 0x78ec, 0xd0e4, 0x0130, 0xa282, 0x000b, 0x1218, 0x2011,
+	0x000a, 0x0028, 0xa282, 0x000c, 0x1210, 0x2011, 0x000c, 0x6308,
+	0x831f, 0xa39c, 0x00ff, 0xa382, 0x0018, 0x0218, 0x0110, 0x2019,
+	0x0018, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa,
+	0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x080c, 0x3a55,
+	0x00ce, 0x0005, 0x00c6, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106,
+	0x2011, 0x0032, 0x2019, 0x0000, 0x0000, 0x78ab, 0x0001, 0x78ab,
+	0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820,
+	0xc0c5, 0x6822, 0x00ce, 0x0005, 0xa006, 0x2030, 0x2010, 0x00c6,
+	0x7154, 0x2160, 0x2018, 0x2008, 0xa084, 0xffe0, 0xa635, 0x7e86,
+	0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4, 0xa084, 0x7770, 0xa18c,
+	0x000f, 0xa105, 0x2029, 0x4605, 0x252c, 0xd5cc, 0x0140, 0xd3a4,
+	0x0110, 0xa085, 0x0800, 0xd3fc, 0x0110, 0xa085, 0x8080, 0x78a6,
+	0x6016, 0x788a, 0xa6b4, 0x001f, 0x8637, 0x8204, 0x8004, 0xa605,
+	0x600e, 0x6004, 0xa084, 0xffd5, 0x6006, 0x00ce, 0x0005, 0xa282,
+	0x0002, 0x1904, 0x3a1a, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc,
+	0x0568, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x1a04,
+	0x3a0b, 0x080c, 0x399e, 0x080c, 0x38f4, 0xa980, 0x0001, 0x200c,
+	0x080c, 0x3b6b, 0x080c, 0x3895, 0x88ff, 0x0178, 0x789b, 0x0060,
+	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x1118, 0x781b,
+	0x006e, 0x0005, 0x781b, 0x0082, 0x0005, 0x7e58, 0xd6d4, 0x1118,
+	0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005, 0xa282, 0x0002,
+	0x1218, 0xa284, 0x0001, 0x0140, 0x7154, 0xa188, 0x0000, 0x210c,
+	0xd1ec, 0x1110, 0x2011, 0x0000, 0x080c, 0x3a87, 0x0479, 0x080c,
+	0x38f4, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x00c6,
+	0x0026, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x1158, 0xd0bc,
+	0x1138, 0x6014, 0xd0b4, 0x1120, 0xc1a4, 0x6106, 0xa006, 0x0088,
+	0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003,
+	0x7aaa, 0xa8c0, 0x0004, 0x080c, 0x3a55, 0x6820, 0xa085, 0x0200,
+	0x6822, 0x002e, 0x00ce, 0x0005, 0x8807, 0xa715, 0x00c6, 0x2009,
+	0x0000, 0x7054, 0x2060, 0x82ff, 0x0110, 0x2009, 0x0040, 0x6018,
+	0xa080, 0x0002, 0x789a, 0x78a4, 0xa084, 0xff9f, 0xa105, 0xc0ec,
+	0xd0b4, 0x1108, 0xc0ed, 0x6100, 0xd1f4, 0x0110, 0xa085, 0x0020,
+	0x78a6, 0x6016, 0x788a, 0x6004, 0xa084, 0xffef, 0x6006, 0x00ce,
+	0x0005, 0x0006, 0x7000, 0xa086, 0x0003, 0x0110, 0x000e, 0x0010,
+	0x000e, 0x0488, 0xd6ac, 0x0578, 0x7888, 0xa084, 0x0040, 0x0558,
+	0x7bb8, 0x8307, 0xa084, 0x007f, 0x1508, 0x8207, 0xa084, 0x00ff,
+	0xa09e, 0x0001, 0x1904, 0x3a32, 0xd6f4, 0x11d0, 0x79d8, 0x7adc,
+	0xa108, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x080c,
+	0x42b5, 0x781b, 0x0080, 0xb284, 0x0600, 0x0118, 0x2001, 0x0000,
+	0x0010, 0x2001, 0x0001, 0x080c, 0x4172, 0x0005, 0x080c, 0x254c,
+	0x781b, 0x0080, 0x0005, 0x781b, 0x0083, 0x0005, 0x2039, 0x0000,
+	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x080c, 0x38f7,
+	0x080c, 0x399c, 0x7e58, 0x080c, 0x3a4e, 0x781b, 0x0082, 0x0005,
+	0x0cd1, 0x6820, 0xc0c4, 0x6822, 0x00c6, 0x7054, 0x2060, 0x080c,
+	0x3921, 0x00b0, 0x0c81, 0x6820, 0xc0cc, 0x6822, 0x00c6, 0x7054,
+	0x2060, 0x080c, 0x39bb, 0x0060, 0x0c31, 0x6820, 0xa084, 0xecff,
+	0x6822, 0x00c6, 0x7054, 0x2060, 0x6004, 0xa084, 0xffc5, 0x6006,
+	0x00ce, 0x0005, 0x0049, 0x781b, 0x0082, 0x0005, 0x6827, 0x0002,
+	0x0049, 0x781b, 0x0082, 0x0005, 0x2001, 0x0005, 0x0088, 0x2001,
+	0x000c, 0x0070, 0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0040,
+	0x2001, 0x000d, 0x0028, 0x2001, 0x0009, 0x0010, 0x2001, 0x0007,
+	0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d0, 0xd0b4, 0x0168,
+	0xc0b4, 0x70d2, 0x00c6, 0x70b4, 0xa065, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x6018, 0x8001, 0x601a, 0x00ce, 0x0005, 0x0076, 0x873f,
+	0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0xa0e0, 0x4ac0, 0xae8e,
+	0x4640, 0x0110, 0xa0e0, 0x4b40, 0xa7b8, 0x0020, 0x7f9a, 0x79a4,
+	0xa184, 0x7fe0, 0x78ae, 0x6012, 0x79a4, 0xa184, 0x773f, 0x78a6,
+	0x6016, 0x6004, 0xa085, 0x0038, 0x6006, 0x007e, 0x0005, 0x789b,
+	0x0080, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
+	0x789b, 0x0060, 0x78ab, 0x0004, 0x0800, 0x2031, 0x0000, 0x2029,
+	0x0032, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab,
+	0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x0804,
+	0x3a55, 0x0156, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080,
+	0x0020, 0x789a, 0x79a4, 0xa18c, 0xffe0, 0x2021, 0x3b54, 0x2019,
+	0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xffe0,
+	0xa106, 0x0128, 0x8420, 0x2300, 0xa210, 0x1f04, 0x3abd, 0x015e,
+	0x0005, 0x0156, 0x04f8, 0x2021, 0x3b62, 0x20a9, 0x0009, 0x2011,
+	0x0029, 0xa582, 0x0028, 0x0550, 0x8420, 0x95a9, 0x2011, 0x0033,
+	0xa582, 0x0033, 0x0618, 0x8420, 0x95a9, 0x2019, 0x000a, 0x2011,
+	0x0065, 0x2200, 0xa502, 0x02d0, 0x8420, 0x2300, 0xa210, 0x1f04,
+	0x3ae1, 0x015e, 0x0088, 0x2021, 0x3b54, 0x2019, 0x0011, 0x20a9,
+	0x000e, 0x2011, 0x0033, 0x2200, 0xa502, 0x0240, 0x8420, 0x2300,
+	0xa210, 0x1f04, 0x3af3, 0x015e, 0xa006, 0x0005, 0x8211, 0x015e,
+	0xa582, 0x0064, 0x1220, 0x7808, 0xa085, 0x0070, 0x780a, 0x2404,
+	0xa005, 0x0005, 0xa886, 0x0002, 0x01e8, 0x2021, 0x3b40, 0x20a9,
+	0x000d, 0x2011, 0x0028, 0xa582, 0x0028, 0x0d48, 0x8420, 0x2019,
+	0x0019, 0x2011, 0x0033, 0x2200, 0xa502, 0x0e00, 0x8420, 0x2300,
+	0xa210, 0x1f04, 0x3b1b, 0x015e, 0x2011, 0x0184, 0xa582, 0x0185,
+	0x0ab0, 0x0890, 0x2021, 0x3b4f, 0x20a9, 0x0003, 0x2011, 0x0024,
+	0xa586, 0x0024, 0x0960, 0x8420, 0x2011, 0x0028, 0xa586, 0x0028,
+	0x0930, 0x8420, 0x2019, 0x0019, 0x2011, 0x0033, 0x0804, 0x3af3,
+	0x1021, 0x2202, 0x3403, 0x4604, 0x5805, 0x6a06, 0x7c07, 0x4610,
+	0x4612, 0x5812, 0x5a12, 0x6a14, 0x6c14, 0x6e14, 0x7e17, 0x9021,
+	0xb002, 0xe204, 0xe210, 0xe210, 0x1209, 0x3002, 0x3202, 0x4203,
+	0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07,
+	0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06,
+	0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0080, 0xa046, 0x0005, 0xa784,
+	0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003,
+	0xa105, 0xd7fc, 0x0118, 0xa0e0, 0x6bc0, 0x0010, 0xa0e0, 0x4bc0,
+	0x0005, 0x00e6, 0x00f6, 0xd084, 0x0138, 0x2079, 0x0100, 0x2009,
+	0x4680, 0x2071, 0x4680, 0x0030, 0x2009, 0x4640, 0x2079, 0x0200,
+	0x2071, 0x4640, 0x2091, 0x8000, 0x2104, 0xa084, 0x000f, 0x0002,
+	0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba2, 0x3ba0, 0x3ba0,
+	0x080c, 0x254c, 0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005,
+	0x0580, 0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828,
+	0xa086, 0x1814, 0x1530, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
+	0x1de0, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x1de0, 0x7830,
+	0xd0bc, 0x11b8, 0xb284, 0x0800, 0x0118, 0x0104, 0x3bd9, 0x0010,
+	0x0304, 0x3bd9, 0x79e4, 0xa184, 0x0030, 0x0158, 0x78ec, 0xa084,
+	0x0003, 0x0138, 0x681c, 0xd0ac, 0x1110, 0x00d9, 0x0010, 0x781b,
+	0x00fb, 0x00fe, 0x00ee, 0x0005, 0x2001, 0x4601, 0x2004, 0xd0ac,
+	0x1118, 0x6814, 0x080c, 0x2475, 0x0005, 0x781b, 0x0083, 0x0005,
+	0x781b, 0x0082, 0x0005, 0x781b, 0x0071, 0x0005, 0x781b, 0x006e,
+	0x0005, 0x2009, 0x4619, 0x210c, 0xa186, 0x0000, 0x0150, 0xa186,
+	0x0001, 0x0150, 0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054,
+	0x0005, 0x781b, 0x00f3, 0x0005, 0x701f, 0x000a, 0x0005, 0x2009,
+	0x4619, 0x210c, 0xa186, 0x0000, 0x0168, 0xa186, 0x0001, 0x0138,
+	0x701f, 0x000b, 0x7063, 0x0001, 0x781b, 0x0054, 0x0005, 0x701f,
+	0x000a, 0x0005, 0x781b, 0x00f2, 0x0005, 0x781b, 0x00fb, 0x0005,
+	0x781b, 0x00fa, 0x0005, 0x781b, 0x00cc, 0x0005, 0x781b, 0x00cb,
+	0x0005, 0x6818, 0xd0fc, 0x0110, 0x681b, 0x001d, 0x7063, 0x0001,
+	0x781b, 0x0054, 0x0005, 0x7830, 0xa084, 0x00c0, 0x1170, 0x7808,
+	0xc08c, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000, 0x78ec, 0xa084,
+	0x0021, 0x0118, 0x7808, 0xc08d, 0x780a, 0x0005, 0x7808, 0xc08d,
+	0x780a, 0x0005, 0x7830, 0xa084, 0x0040, 0x1de0, 0xb284, 0x0800,
+	0x0118, 0x1104, 0x3c58, 0x0010, 0x1304, 0x3c58, 0x78ac, 0x0005,
+	0x7808, 0xa084, 0xfffd, 0x780a, 0xe000, 0xe000, 0xe000, 0xe000,
+	0x78ec, 0xa084, 0x0021, 0x0140, 0xb284, 0x0800, 0x0118, 0x1104,
+	0x3c67, 0x0010, 0x1304, 0x3c6a, 0x78ac, 0x0006, 0x7808, 0xa085,
+	0x0002, 0x780a, 0x000e, 0x0005, 0xa784, 0x0001, 0x1904, 0x322a,
+	0xa784, 0x0070, 0x0140, 0x00c6, 0x2d60, 0x2f68, 0x080c, 0x2467,
+	0x2d78, 0x2c68, 0x00ce, 0xa784, 0x0008, 0x0148, 0x784b, 0x0008,
+	0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x0804, 0x3be5, 0xa784,
+	0x0004, 0x01c8, 0x78b8, 0xa084, 0x8000, 0x01a8, 0x784b, 0x0008,
+	0x78ec, 0xa084, 0x0003, 0x0904, 0x322a, 0x78e4, 0xa084, 0x0007,
+	0xa086, 0x0001, 0x1140, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a,
+	0x781b, 0x00fb, 0x0005, 0xa784, 0x0080, 0x0140, 0x7884, 0xd0fc,
+	0x0128, 0x080c, 0x3a32, 0x681b, 0x0022, 0x0005, 0x681b, 0x0003,
+	0x7858, 0xa084, 0x5f00, 0x681e, 0x682f, 0x0000, 0x6833, 0x0000,
+	0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0904, 0x2b89, 0xb284,
+	0x0800, 0x0110, 0x0104, 0x259d, 0x0304, 0x259d, 0x6b14, 0x8307,
+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc, 0x0118, 0xa080,
+	0x4b40, 0x0010, 0xa080, 0x4ac0, 0x2060, 0x2048, 0x7056, 0x2a60,
+	0x0005, 0x00c6, 0x2960, 0x6000, 0xd0ac, 0x0904, 0x3d2f, 0x68a0,
+	0xd1ac, 0x1120, 0xa084, 0x0e00, 0x0904, 0x3d2d, 0x6108, 0x8117,
+	0xa18c, 0x00ff, 0x631c, 0x832f, 0xd0dc, 0x0110, 0xa39d, 0x0001,
+	0xd0cc, 0x11c8, 0xa584, 0x00ff, 0x0138, 0x78ec, 0xd0e4, 0x0110,
+	0x8213, 0x00b8, 0x2029, 0x0000, 0xa182, 0x000c, 0x1290, 0x78ec,
+	0xd0e4, 0x1118, 0x2009, 0x000c, 0x0060, 0xa182, 0x000b, 0x1248,
+	0x2009, 0x000a, 0x0030, 0x2009, 0x0032, 0x2011, 0x0000, 0x2029,
+	0x0000, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab, 0x0004, 0x79aa,
+	0x78ab, 0x0000, 0x7aaa, 0x7baa, 0x7daa, 0xa8c0, 0x0008, 0x6820,
+	0xa085, 0x1000, 0x6822, 0x080c, 0x3a55, 0xa085, 0x0001, 0x00ce,
+	0x0005, 0xa282, 0x0006, 0x1904, 0x3a24, 0x7da8, 0x7eac, 0x8637,
+	0xa5ac, 0x00ff, 0xa6b4, 0x00ff, 0x7fac, 0x8747, 0xa7bc, 0x00ff,
+	0xa8c4, 0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1e4, 0x0904, 0x3da3,
+	0xa18c, 0xecff, 0x6922, 0xa782, 0x0002, 0x1a04, 0x39fe, 0xa6b4,
+	0x00ff, 0x0904, 0x3da0, 0xa682, 0x0031, 0x1a04, 0x39fe, 0xa582,
+	0x0009, 0x0a04, 0x39fe, 0xa882, 0x0003, 0x1a04, 0x39fe, 0xa886,
+	0x0002, 0x01d0, 0xa886, 0x0000, 0x1904, 0x39fe, 0x2001, 0x000c,
+	0x79ec, 0xd1e4, 0x0110, 0x2001, 0x000a, 0xa502, 0x1290, 0x080c,
+	0x39fe, 0x00c6, 0x2960, 0x6004, 0xa085, 0x001a, 0x6006, 0x6000,
+	0xc0ac, 0x6002, 0x00ce, 0x0005, 0xa786, 0x0000, 0x0904, 0x39fe,
+	0x8634, 0xa682, 0x0018, 0x0228, 0x0120, 0x2031, 0x0018, 0x0804,
+	0x3df1, 0xa686, 0x0010, 0x1108, 0x8630, 0x852b, 0x852b, 0x080c,
+	0x3ac9, 0x0904, 0x39fe, 0x080c, 0x38f7, 0x080c, 0x399c, 0x7e58,
+	0xd6d4, 0x1118, 0x781b, 0x0071, 0x0005, 0x781b, 0x0083, 0x0005,
+	0x080c, 0x38f4, 0x0c90, 0xa886, 0x0002, 0x1108, 0x8634, 0x7154,
+	0xa188, 0x0000, 0x210c, 0xd1ac, 0x0904, 0x39fe, 0xd1ec, 0x1120,
+	0x2039, 0x0000, 0x2041, 0x0000, 0xd1e4, 0x1120, 0x2031, 0x0000,
+	0x2041, 0x0000, 0xa782, 0x0002, 0x12c8, 0x621c, 0xa284, 0x00ff,
+	0xa706, 0x0110, 0x2039, 0x0000, 0xa605, 0x0190, 0x6108, 0x811f,
+	0xa39c, 0x00ff, 0x0168, 0xa302, 0x1208, 0x2330, 0x8807, 0xa705,
+	0xa086, 0x0201, 0x0160, 0xa886, 0x0000, 0x0168, 0x2039, 0x0000,
+	0x2041, 0x0000, 0x2031, 0x0000, 0xa006, 0x2010, 0x0070, 0xa284,
+	0xff00, 0x1108, 0x2040, 0xa184, 0x00ff, 0xa502, 0x0108, 0x2128,
+	0x852b, 0x852b, 0x080c, 0x3ac9, 0x0d58, 0x080c, 0x38f7, 0x080c,
+	0x399c, 0x789b, 0x0080, 0x78ab, 0x0001, 0x78ab, 0x0006, 0x78ab,
+	0x0004, 0x7daa, 0x78ab, 0x0000, 0x7eaa, 0x7faa, 0x2800, 0x78aa,
+	0x789b, 0x0060, 0x78ab, 0x0008, 0x6820, 0xc0e5, 0x6822, 0x080c,
+	0x3a55, 0x7858, 0xc095, 0x785a, 0x781b, 0x0082, 0x0005, 0x0020,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062, 0x0009, 0x0014,
-	0x0014, 0x9855, 0x984d, 0x0014, 0x9911, 0x98ff, 0x0014, 0x0014,
-	0x0090, 0x00e7, 0x0100, 0x0402, 0x2008, 0xf880, 0x0018, 0x0017,
-	0x840f, 0xd8c1, 0x0014, 0x0016, 0xa20a, 0x0014, 0x300b, 0xa20c,
-	0x0014, 0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010,
+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
+	0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9855, 0x984d, 0x0014,
+	0x9911, 0x98ff, 0x0014, 0x0014, 0x0090, 0x00e7, 0x0100, 0x0402,
+	0x2008, 0xf880, 0x0018, 0x0017, 0x840f, 0xd8c1, 0x0014, 0x0016,
+	0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013, 0x2500,
 	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
-	0x0010, 0x0010, 0xa200, 0x3806, 0x8839, 0x20c4, 0x0864, 0xa84f,
-	0x3008, 0x28c1, 0x9d18, 0xa201, 0x300c, 0x2847, 0x8161, 0x846a,
-	0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2, 0x9cce, 0xa8f3,
-	0x0864, 0xa83d, 0x300c, 0xa801, 0x3008, 0x28e1, 0x9cce, 0x2021,
-	0xa818, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4,
-	0x6c80, 0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027,
-	0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa814, 0x883e,
-	0xa812, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x1814,
-	0x883b, 0x7027, 0x8576, 0x8677, 0xa806, 0x796d, 0xa8da, 0x796b,
-	0xa8f1, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d18, 0x2044, 0x2103,
-	0x20b4, 0x2095, 0xa8ca, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203,
-	0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208,
-	0x856e, 0x866f, 0x7121, 0x0014, 0x0704, 0x3008, 0x9cce, 0x0014,
-	0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e,
-	0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881,
-	0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532,
-	0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008,
-	0x8000, 0x2849, 0x1011, 0xa8fc, 0x3008, 0x8000, 0xa000, 0x2081,
-	0x2802, 0x1011, 0xa8fc, 0xa889, 0x3008, 0x20a1, 0x283c, 0x1011,
-	0xa8fc, 0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1,
-	0x0014, 0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2,
-	0x26e0, 0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210,
-	0x9d22, 0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823,
-	0x0016, 0x6042, 0x8008, 0xa8fa, 0x8160, 0x842a, 0x8180, 0xf021,
-	0x3008, 0x84a8, 0x11d7, 0x7042, 0x20dd, 0x0011, 0x20d5, 0x8822,
-	0x0016, 0x0000, 0x0126, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090,
-	0x7204, 0x7008, 0xc09c, 0xa205, 0x1178, 0x720c, 0x82ff, 0x0128,
-	0x8aff, 0x1150, 0x7200, 0xd284, 0x1138, 0x7007, 0x0004, 0x7003,
-	0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003, 0x7002,
-	0xc69c, 0xd084, 0x05b8, 0x2001, 0x4301, 0x2004, 0xd0b4, 0x0904,
-	0x3dcf, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184, 0x0003,
-	0x0904, 0x3dcf, 0xa184, 0x01e0, 0x1904, 0x3dcf, 0xd1f4, 0x1d88,
-	0xa184, 0x3000, 0xa086, 0x1000, 0x0d60, 0x2011, 0x0180, 0x710c,
-	0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20, 0x700c, 0xa106, 0x0dc0,
-	0x7007, 0x0012, 0x7108, 0xe000, 0x7008, 0xa106, 0x1dd8, 0xa184,
-	0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4, 0x0548, 0x7007, 0x0002,
-	0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130, 0x080c, 0x3e9e, 0x8aff,
-	0x0904, 0x3d58, 0x0cb8, 0x700c, 0xa08c, 0x07ff, 0x01e8, 0x7004,
-	0xd084, 0x0178, 0x7014, 0xa005, 0x1148, 0x7010, 0x7310, 0xa306,
-	0x1de0, 0x2300, 0xa005, 0x0128, 0xa102, 0x1e20, 0x7007, 0x0010,
-	0x0030, 0x8aff, 0x0148, 0x080c, 0x4046, 0x1de8, 0x09d8, 0x080c,
-	0x3e58, 0x012e, 0x2000, 0x0005, 0x7204, 0x7108, 0xc19c, 0x8103,
-	0x1218, 0x080c, 0x3e9e, 0x0cc0, 0xa205, 0x1d88, 0x7007, 0x0004,
-	0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x6428, 0x84ff, 0x0508,
-	0x2c70, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb,
-	0x1148, 0x0210, 0x080c, 0x243b, 0x609c, 0xa075, 0x0190, 0x0c88,
-	0x2039, 0x3e0e, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c, 0xa529,
-	0x8421, 0x0138, 0x8738, 0x2704, 0xa005, 0x1da8, 0x709c, 0xa075,
-	0x1d00, 0x0005, 0x0000, 0x0005, 0x0009, 0x000d, 0x0011, 0x0015,
-	0x0019, 0x001d, 0x0000, 0x0003, 0x0009, 0x000f, 0x0015, 0x001b,
-	0x0000, 0x0000, 0x3e0e, 0x3e0b, 0x0000, 0x0000, 0x8000, 0x0000,
-	0x3e0e, 0x0000, 0x3e16, 0x3e13, 0x0000, 0x0000, 0x0000, 0x0000,
-	0x3e16, 0x0000, 0x3e11, 0x3e11, 0x0000, 0x0000, 0x8000, 0x0000,
-	0x3e11, 0x0000, 0x3e17, 0x3e17, 0x0000, 0x0000, 0x0000, 0x0000,
-	0x3e17, 0x2079, 0x4300, 0x2071, 0x0010, 0x7007, 0x000a, 0x7007,
-	0x0002, 0x7003, 0x0001, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007,
-	0x000a, 0x7007, 0x0002, 0x7003, 0x0000, 0x2001, 0x01ff, 0x2004,
-	0xd0fc, 0x1128, 0x8109, 0x0118, 0x2071, 0x0020, 0x0c80, 0x0005,
-	0x7004, 0x8004, 0x1690, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
-	0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110, 0x080c, 0x243b,
-	0xa19c, 0x300c, 0xa386, 0x2004, 0x0130, 0xa386, 0x0008, 0x0160,
-	0xa386, 0x200c, 0x1d60, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384,
-	0x07ff, 0x0110, 0x080c, 0x243b, 0x7007, 0x0012, 0x7000, 0xd084,
-	0x1160, 0x7008, 0xa084, 0x01e0, 0x1140, 0x7310, 0x7014, 0xa305,
-	0x0120, 0x710c, 0xa184, 0x07ff, 0x1958, 0x7007, 0x0012, 0x7007,
-	0x0008, 0x7004, 0xd09c, 0x1de8, 0x7007, 0x0012, 0x7108, 0x8103,
-	0x0ed8, 0x7003, 0x0008, 0x0005, 0x7108, 0x0000, 0xa184, 0x01e0,
-	0x1550, 0x7108, 0xa184, 0x01e0, 0x1530, 0xa184, 0x0007, 0x0002,
-	0x3eb2, 0x3ec0, 0x3eb0, 0x3ec0, 0x3eb0, 0x3f06, 0x3eb0, 0x3f05,
-	0x080c, 0x243b, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
-	0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x4046, 0x1de8, 0x0005,
-	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0118, 0x080c,
-	0x4046, 0x1de8, 0x0005, 0x7007, 0x0012, 0x7108, 0x1d04, 0x3ece,
-	0x2091, 0x6000, 0x1d04, 0x3ed2, 0x2091, 0x6000, 0x7007, 0x0012,
-	0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8, 0x7007, 0x0012, 0x7108,
-	0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000, 0xa005, 0x1130, 0x7004,
-	0xa005, 0x1118, 0x700c, 0xa005, 0x0108, 0x0c40, 0x2049, 0x0000,
-	0xb284, 0x0200, 0x0118, 0x2001, 0x0000, 0x0010, 0x2001, 0x0001,
-	0x080c, 0x397f, 0x6818, 0xa084, 0x8000, 0x0110, 0x681b, 0x0002,
-	0x0005, 0x080c, 0x243b, 0x080c, 0x243b, 0x04b9, 0x7210, 0x7114,
-	0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
-	0x0461, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c,
-	0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238, 0x8412, 0x8210,
-	0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60, 0x8a07, 0x0006,
-	0x6004, 0xa084, 0x0008, 0x0118, 0xa7ba, 0x3e13, 0x0010, 0xa7ba,
-	0x3e0b, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e,
-	0x7007, 0x0012, 0x080c, 0x3e58, 0x0005, 0x8a50, 0x8739, 0x2704,
-	0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60, 0x6004, 0xa084,
-	0x000f, 0xa080, 0x3e29, 0x203c, 0x87fb, 0x090c, 0x243b, 0x0005,
-	0x0126, 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
-	0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff,
-	0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008, 0x000e, 0x0118,
-	0xa0b8, 0x3e13, 0x0010, 0xa0b8, 0x3e0b, 0xb284, 0x0200, 0x0110,
-	0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0108,
-	0xc685, 0x2400, 0xa305, 0x0520, 0x2c58, 0x2704, 0x6104, 0xac60,
-	0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184, 0x0008,
-	0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081, 0x0000,
-	0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300, 0xa203,
-	0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4067, 0x0010,
-	0x080c, 0x4046, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x00d6,
-	0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007, 0x0004,
-	0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000, 0x0005,
-	0x0126, 0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
-	0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c, 0x681c,
-	0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050, 0x2d60,
-	0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, 0x1138,
-	0x0210, 0x080c, 0x243b, 0x689c, 0xa065, 0x0120, 0x0c88, 0x080c,
-	0x4046, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006, 0x0016,
-	0x00d6, 0x70d4, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20, 0xb284,
-	0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5, 0x000c,
-	0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
-	0x2049, 0x3fe5, 0x6828, 0xa055, 0x05f0, 0x2d70, 0x2e60, 0x7004,
-	0xa0bc, 0x000f, 0xa7b8, 0x3e19, 0x273c, 0x87fb, 0x1140, 0x0210,
-	0x080c, 0x243b, 0x709c, 0xa075, 0x2060, 0x0568, 0x0c80, 0x2704,
-	0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0268, 0x8a51, 0x1110,
-	0x080c, 0x243b, 0x8738, 0x2704, 0xa005, 0x1d90, 0x709c, 0xa075,
-	0x2060, 0x01c8, 0x08e0, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000,
-	0x6908, 0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x1210, 0x080c,
-	0x243b, 0xb284, 0x0200, 0x0118, 0x2071, 0x0050, 0x0010, 0x2071,
-	0x0020, 0x0804, 0x3f79, 0x012e, 0x2000, 0x0005, 0x7008, 0xa084,
-	0x0003, 0xa086, 0x0003, 0x1108, 0x0005, 0x2704, 0xac78, 0x7800,
-	0x701a, 0x7804, 0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004,
-	0xa084, 0x0008, 0x0120, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602,
-	0x7004, 0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4300, 0x8a51,
-	0x01b0, 0x8738, 0x2704, 0xa005, 0x1168, 0x609c, 0xa005, 0x0180,
-	0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x3e19, 0x203c, 0x87fb,
-	0x090c, 0x243b, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003, 0x0005,
-	0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6, 0x70d4, 0xa084,
-	0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108, 0xa184, 0x0003,
-	0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3d6c, 0x7108, 0xd1fc,
-	0x0118, 0x080c, 0x3e9e, 0x0c88, 0x7007, 0x0010, 0x7108, 0xd1fc,
-	0x0de8, 0x080c, 0x3e9e, 0x7008, 0xa086, 0x0008, 0x1d30, 0x7000,
-	0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000, 0x012e, 0x2000,
-	0x0005, 0x0126, 0x0146, 0x0136, 0x0156, 0x00c6, 0x00d6, 0x70d4,
-	0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x2049, 0x40b1, 0xad80,
-	0x0011, 0x20a0, 0xb284, 0x0200, 0x0118, 0x2099, 0x0032, 0x0010,
-	0x2099, 0x0031, 0x700c, 0xa084, 0x07ff, 0x682a, 0x7007, 0x0008,
-	0x7007, 0x0002, 0x7003, 0x0001, 0x0118, 0x8000, 0x80ac, 0x53a5,
-	0x700c, 0xa084, 0x07ff, 0x0130, 0x7007, 0x0004, 0x7004, 0xa084,
-	0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000, 0x7003, 0x0000, 0x015e,
-	0x013e, 0x014e, 0x012e, 0x2000, 0x0005, 0x2091, 0x8000, 0x2091,
-	0x6000, 0x78ac, 0xa005, 0x1168, 0x7974, 0x70d0, 0xa106, 0x1148,
-	0x781c, 0xa005, 0x0130, 0x781f, 0x0000, 0x0e04, 0x4101, 0x2091,
-	0x4080, 0x7830, 0x8001, 0x7832, 0x1904, 0x416b, 0x7834, 0x7832,
-	0x2061, 0x68c0, 0x2069, 0x4380, 0xc7fd, 0x68d0, 0xa005, 0x0128,
-	0x8001, 0x68d2, 0x1110, 0x080c, 0x42c4, 0x6800, 0xa084, 0x000f,
-	0x0168, 0xa086, 0x0001, 0x0150, 0x6844, 0xa00d, 0x0138, 0x2104,
-	0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x425f, 0x6814, 0xa005,
-	0x01a8, 0x8001, 0x6816, 0x1190, 0x68a7, 0x0001, 0x00f6, 0xd7fc,
-	0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3aa0,
-	0x00fe, 0x6864, 0xa005, 0x0110, 0x080c, 0x2233, 0x6880, 0xa005,
-	0x0140, 0x8001, 0x6882, 0x1128, 0x6867, 0x0000, 0x68d4, 0xc0c5,
-	0x68d6, 0x68d4, 0xd0fc, 0x01b0, 0xc0fc, 0x68d6, 0x20a9, 0x0200,
-	0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d4, 0xc0fd, 0x68d6,
-	0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x2233, 0xace0, 0x0010,
-	0x1f04, 0x4150, 0xd7fc, 0x0138, 0x2061, 0x48c0, 0x2069, 0x4340,
-	0xc7fc, 0x0804, 0x410d, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0,
-	0x783c, 0x783a, 0x2061, 0x48c0, 0x2069, 0x4340, 0xc7fc, 0x680c,
-	0xa005, 0x0110, 0x080c, 0x41c9, 0xd7fc, 0x1130, 0x2061, 0x68c0,
-	0x2069, 0x4380, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac,
+	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200, 0x3806,
+	0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d18, 0xa201,
+	0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a,
+	0xa808, 0x28e2, 0x9cce, 0xa8f3, 0x0864, 0xa83e, 0x300c, 0xa801,
+	0x3008, 0x28e1, 0x9cce, 0x28a2, 0x7163, 0xa831, 0x2021, 0xa818,
+	0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x67a4, 0x6c80,
+	0x0212, 0xa205, 0x883d, 0x882b, 0x1814, 0x883b, 0x7027, 0x85f2,
+	0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa813, 0x883e, 0xa811,
+	0x2882, 0x7162, 0xa814, 0x280a, 0xa204, 0x64c0, 0x6de0, 0x67a0,
+	0x6fc0, 0x1814, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861,
+	0x883e, 0x206a, 0x28c1, 0x9d18, 0x2042, 0x2101, 0xa8ca, 0x2902,
+	0xa20e, 0xa80b, 0xa207, 0x0014, 0xa203, 0x8000, 0x85a4, 0x1872,
+	0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x7121, 0x0014,
+	0x0704, 0x3008, 0x9cce, 0x0014, 0xa202, 0x8000, 0x85a4, 0x3009,
+	0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861,
+	0xa8eb, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532,
+	0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8,
+	0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x2849, 0x1011, 0xa8fc,
+	0x3008, 0x8000, 0xa000, 0x2081, 0x2802, 0x1011, 0xa8fc, 0xa889,
+	0x3008, 0x20a1, 0x283c, 0x1011, 0xa8fc, 0xa209, 0x0017, 0x300c,
+	0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014, 0x0210, 0xa801, 0x0014,
+	0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0, 0x18f2, 0x0014, 0xa20b,
+	0x0014, 0xa20d, 0x3806, 0x0210, 0x9d22, 0x0704, 0xa206, 0x6865,
+	0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016, 0x6042, 0x8008, 0xa8fa,
+	0x8160, 0x842a, 0x8180, 0xf021, 0x3008, 0x84a8, 0x11d7, 0x7042,
+	0x20dd, 0x0011, 0x20d5, 0x8822, 0x0016, 0x0000, 0x0126, 0x70d0,
+	0xa084, 0x4c00, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
+	0x11a0, 0x720c, 0x82ff, 0x0128, 0x8aff, 0x1178, 0x7200, 0xd284,
+	0x1160, 0x7804, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x7007, 0x0008,
+	0x7003, 0x0008, 0x012e, 0x2000, 0x0005, 0x7000, 0xa084, 0x0003,
+	0x7002, 0xc69c, 0xd084, 0x0588, 0x7108, 0xe000, 0x7008, 0xa106,
+	0x1dd8, 0xa184, 0x0003, 0x0904, 0x3fa2, 0xa184, 0x01e0, 0x1904,
+	0x3fa2, 0xd1f4, 0x1d88, 0xa184, 0x3000, 0xa086, 0x1000, 0x0d60,
+	0x2011, 0x0180, 0x710c, 0x8211, 0x0130, 0x7008, 0xd0f4, 0x1d20,
+	0x700c, 0xa106, 0x0dc0, 0x7007, 0x0012, 0x7108, 0xe000, 0x7008,
+	0xa106, 0x1dd8, 0xa184, 0x0003, 0x0568, 0xd194, 0x0db0, 0xd1f4,
+	0x0548, 0x7007, 0x0002, 0x0880, 0x0428, 0x7108, 0xd1fc, 0x0130,
+	0x080c, 0x40ae, 0x8aff, 0x0904, 0x3f2c, 0x0cb8, 0x700c, 0xa08c,
+	0x07ff, 0x01e8, 0x7004, 0xd084, 0x0178, 0x7014, 0xa005, 0x1148,
+	0x7010, 0x7310, 0xa306, 0x1de0, 0x2300, 0xa005, 0x0128, 0xa102,
+	0x1e20, 0x7007, 0x0010, 0x0030, 0x8aff, 0x0148, 0x080c, 0x426b,
+	0x1de8, 0x09d8, 0x080c, 0x4034, 0x012e, 0x2000, 0x0005, 0x7204,
+	0x7108, 0xc19c, 0x8103, 0x1218, 0x7007, 0x0002, 0x0cc0, 0xa205,
+	0x1d88, 0x7007, 0x0008, 0x7003, 0x0008, 0x0006, 0x2001, 0x4601,
+	0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328, 0x000e, 0x012e, 0x2000,
+	0x0005, 0x6428, 0x84ff, 0x0508, 0x2c70, 0x7004, 0xa0bc, 0x000f,
+	0xa7b8, 0x3ff5, 0x273c, 0x87fb, 0x1148, 0x0210, 0x080c, 0x254c,
+	0x609c, 0xa075, 0x0190, 0x0c88, 0x2039, 0x3fea, 0x2704, 0xae68,
+	0x6808, 0xa630, 0x680c, 0xa529, 0x8421, 0x0138, 0x8738, 0x2704,
+	0xa005, 0x1da8, 0x709c, 0xa075, 0x1d00, 0x0005, 0x0000, 0x0005,
+	0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
+	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x3fea, 0x3fe7,
+	0x0000, 0x0000, 0x8000, 0x0000, 0x3fea, 0x0000, 0x3ff2, 0x3fef,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x3ff2, 0x0000, 0x3fed, 0x3fed,
+	0x0000, 0x0000, 0x8000, 0x0000, 0x3fed, 0x0000, 0x3ff3, 0x3ff3,
+	0x0000, 0x0000, 0x0000, 0x0000, 0x3ff3, 0x2079, 0x4600, 0x2071,
+	0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x2009,
+	0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003,
+	0x0000, 0x2001, 0x01ff, 0x2004, 0xd0fc, 0x1128, 0x8109, 0x0118,
+	0x2071, 0x0020, 0x0c80, 0x0005, 0x7004, 0x8004, 0x1a04, 0x408a,
+	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c,
+	0x40e6, 0x0804, 0x40aa, 0x7007, 0x0012, 0x2019, 0x0000, 0x7108,
+	0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0120, 0x080c, 0x40e6,
+	0x0804, 0x40aa, 0xa19c, 0x300c, 0xa386, 0x2004, 0x0190, 0xa386,
+	0x0008, 0x01c0, 0x7004, 0xd084, 0x1148, 0x7108, 0x7008, 0xa106,
+	0x1de0, 0xa184, 0x0003, 0x0110, 0x0804, 0x40e6, 0xa386, 0x200c,
+	0x19f0, 0x7200, 0x8204, 0x0230, 0x730c, 0xa384, 0x07ff, 0x0110,
+	0x080c, 0x254c, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
+	0x0118, 0x080c, 0x40e6, 0x0470, 0x7007, 0x0012, 0x7000, 0xd084,
+	0x1148, 0x7310, 0x7014, 0xa305, 0x0128, 0x710c, 0xa184, 0x07ff,
+	0x1904, 0x4034, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0,
+	0x0118, 0x080c, 0x40e6, 0x00b0, 0x7007, 0x0012, 0x7007, 0x0008,
+	0x7004, 0xd09c, 0x1de8, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184,
+	0x01e0, 0x0118, 0x080c, 0x40e6, 0x0028, 0x7007, 0x0012, 0x7108,
+	0x8103, 0x0e88, 0x7003, 0x0008, 0x0005, 0x7108, 0xa184, 0x01e0,
+	0x15a8, 0x7108, 0xa184, 0x01e0, 0x1588, 0xa184, 0x0007, 0x0002,
+	0x40c2, 0x40d0, 0x40c0, 0x40d0, 0x40c0, 0x4120, 0x40c0, 0x411e,
+	0x080c, 0x254c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff,
+	0x1118, 0x2049, 0x0000, 0x0005, 0x080c, 0x426b, 0x1de8, 0x0005,
+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x1140,
+	0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x0003, 0x0108, 0x0030,
+	0x8aff, 0x0118, 0x080c, 0x426b, 0x1de8, 0x0005, 0x7007, 0x0012,
+	0x7108, 0x1d04, 0x40e9, 0x2091, 0x6000, 0x1d04, 0x40ed, 0x2091,
+	0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x1de8,
+	0x7007, 0x0012, 0x7108, 0xd1fc, 0x1dd8, 0x7003, 0x0000, 0x7000,
+	0xa005, 0x1130, 0x7004, 0xa005, 0x1118, 0x700c, 0xa005, 0x0108,
+	0x0c40, 0x2049, 0x0000, 0xb284, 0x0200, 0x0118, 0x2001, 0x0000,
+	0x0010, 0x2001, 0x0001, 0x080c, 0x3b81, 0x681b, 0x0002, 0x2051,
+	0x0000, 0x0005, 0x080c, 0x254c, 0x080c, 0x254c, 0x080c, 0x415f,
+	0x7210, 0x7114, 0x700c, 0xa09c, 0x07ff, 0x2800, 0xa300, 0xa211,
+	0xa189, 0x0000, 0x04a1, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200,
+	0xa322, 0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0140, 0x1238,
+	0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0c58, 0x2b60,
+	0x8a07, 0x0006, 0x6004, 0xd09c, 0x0118, 0xa7ba, 0x3fef, 0x0010,
+	0xa7ba, 0x3fe7, 0x000e, 0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92,
+	0x6b8e, 0x7108, 0x7008, 0xa106, 0x1de0, 0xa184, 0x01e0, 0x0110,
+	0x080c, 0x40e6, 0x7007, 0x0012, 0x080c, 0x4034, 0x0005, 0x8a50,
+	0x8739, 0x2704, 0xa004, 0x1168, 0x6000, 0xa064, 0x1108, 0x2d60,
+	0x6004, 0xa084, 0x000f, 0xa080, 0x4005, 0x203c, 0x87fb, 0x090c,
+	0x254c, 0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004,
+	0x2090, 0x00de, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90, 0x8057,
+	0xaad4, 0x00ff, 0xa084, 0x00ff, 0x0006, 0x6804, 0xa084, 0x0008,
+	0x000e, 0x0118, 0xa0b8, 0x3fef, 0x0010, 0xa0b8, 0x3fe7, 0xb284,
+	0x0200, 0x0110, 0x7e20, 0x0008, 0x7e24, 0xa6b5, 0x000c, 0x681c,
+	0xd0b4, 0x0108, 0xc685, 0x2400, 0xa305, 0x0518, 0x2c58, 0x2704,
+	0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e,
+	0xd19c, 0x0140, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014, 0xa081,
+	0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c, 0x2300,
+	0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x080c, 0x4292,
+	0x0010, 0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126,
+	0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x7007,
+	0x0004, 0x7004, 0xd094, 0x1de8, 0x7003, 0x0008, 0x012e, 0x2000,
+	0x0005, 0x0126, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090,
+	0x00de, 0x7e20, 0xb284, 0x0200, 0x1108, 0x7e24, 0xa6b5, 0x000c,
+	0x681c, 0xd0ac, 0x1118, 0xc685, 0x7003, 0x0000, 0x6828, 0x2050,
+	0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c, 0x87fb,
+	0x1138, 0x0210, 0x080c, 0x254c, 0x689c, 0xa065, 0x0120, 0x0c88,
+	0x080c, 0x426b, 0x1de8, 0x012e, 0x2000, 0x0005, 0x0126, 0x0006,
+	0x0016, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x7e20,
+	0xb284, 0x0200, 0x1108, 0x7e24, 0x00de, 0x003e, 0x004e, 0xa6b5,
+	0x000c, 0x681c, 0xd0b4, 0x0128, 0xc685, 0x7003, 0x0000, 0x7007,
+	0x0004, 0x2049, 0x4206, 0x6828, 0xa055, 0x00d6, 0x0904, 0x4267,
+	0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x3ff5, 0x273c,
+	0x87fb, 0x1140, 0x0210, 0x080c, 0x254c, 0x709c, 0xa075, 0x2060,
+	0x0570, 0x0c80, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b,
+	0x0268, 0x8a51, 0x1110, 0x080c, 0x254c, 0x8738, 0x2704, 0xa005,
+	0x1d90, 0x709c, 0xa075, 0x2060, 0x01d0, 0x08e0, 0x8422, 0x8420,
+	0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c, 0x2300,
+	0xa11b, 0x1210, 0x080c, 0x254c, 0xb284, 0x0200, 0x0118, 0x2071,
+	0x0050, 0x0010, 0x2071, 0x0020, 0x00de, 0x0804, 0x419b, 0x00de,
+	0x012e, 0x2000, 0x0005, 0x7008, 0x0006, 0xa084, 0x01e0, 0x000e,
+	0x0110, 0xa006, 0x0005, 0xa084, 0x0003, 0xa086, 0x0003, 0x1108,
+	0x0005, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808,
+	0x7012, 0x780c, 0x7016, 0x6004, 0xd09c, 0x0120, 0x7810, 0x7022,
+	0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085, 0x7006,
+	0x2079, 0x4600, 0x8a51, 0x01e8, 0x8738, 0x2704, 0xa005, 0x1168,
+	0x609c, 0xa005, 0x01b8, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080,
+	0x3ff5, 0x203c, 0x87fb, 0x090c, 0x254c, 0x7008, 0x0006, 0xa084,
+	0x01e0, 0x000e, 0x0110, 0xa006, 0x0028, 0xa084, 0x0003, 0xa086,
+	0x0003, 0x0005, 0x2051, 0x0000, 0x0005, 0x0126, 0x0006, 0x00d6,
+	0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de, 0x008e, 0x7108,
+	0xa184, 0x0003, 0x1128, 0x6828, 0xa005, 0x0178, 0x0804, 0x3f45,
+	0x7108, 0xd1fc, 0x0118, 0x080c, 0x40ae, 0x0c88, 0x7007, 0x0010,
+	0x7108, 0xd1fc, 0x0de8, 0x080c, 0x40ae, 0x7008, 0xa086, 0x0008,
+	0x1d30, 0x7000, 0xa005, 0x1d18, 0x7003, 0x0000, 0x2049, 0x0000,
+	0x0006, 0x2001, 0x4601, 0x2004, 0xd0cc, 0x0110, 0x080c, 0x4328,
+	0x000e, 0x012e, 0x2000, 0x0005, 0x0126, 0x0146, 0x0136, 0x0156,
+	0x00c6, 0x00d6, 0x70d0, 0xa084, 0x4c00, 0x8004, 0x2090, 0x00de,
+	0x2049, 0x42ec, 0xad80, 0x0011, 0x20a0, 0xb284, 0x0200, 0x0118,
+	0x2099, 0x0032, 0x0010, 0x2099, 0x0031, 0x700c, 0xa084, 0x07ff,
+	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0118,
+	0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x07ff, 0x0130, 0x7007,
+	0x0004, 0x7004, 0xa084, 0x0004, 0x1de0, 0x00ce, 0x2049, 0x0000,
+	0x7003, 0x0000, 0x015e, 0x013e, 0x014e, 0x012e, 0x2000, 0x0005,
+	0x6814, 0xd0fc, 0x0904, 0x436b, 0x7000, 0xd084, 0x05e0, 0x7e24,
+	0xa6b5, 0x0004, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x1de0,
+	0x7118, 0x0016, 0x711c, 0x0016, 0x7120, 0x0016, 0x7124, 0x0016,
+	0x701b, 0x0000, 0x701f, 0x3fff, 0x7023, 0x0000, 0x7027, 0x0000,
+	0x7013, 0x0004, 0x7017, 0x0000, 0x7602, 0x7007, 0x0001, 0x2001,
+	0xffff, 0x2009, 0x0031, 0x200a, 0x200a, 0x7108, 0x7008, 0xa106,
+	0x1de0, 0xd1fc, 0x0dd0, 0x002e, 0x7226, 0x002e, 0x7222, 0x002e,
+	0x721e, 0x002e, 0x721a, 0x7007, 0x0002, 0x7008, 0xa086, 0x0008,
+	0x0110, 0x0804, 0x40e6, 0x7007, 0x0004, 0x7003, 0x0000, 0x0005,
+	0x2091, 0x8000, 0x2091, 0x6000, 0x78ac, 0xa005, 0x1168, 0x7974,
+	0x70d0, 0xa106, 0x1148, 0x781c, 0xa005, 0x0130, 0x781f, 0x0000,
+	0x0e04, 0x4384, 0x2091, 0x4080, 0x2069, 0x4680, 0xd7fc, 0x1110,
+	0x2069, 0x4640, 0x6800, 0xa084, 0x000f, 0x1198, 0x68d0, 0xd0b4,
+	0x0180, 0xd0bc, 0x1170, 0x00f6, 0x2079, 0x0100, 0xd7fc, 0x1110,
+	0x2079, 0x0200, 0x7830, 0xa084, 0x00c0, 0x1110, 0x080c, 0x22ae,
+	0x00fe, 0x7830, 0x8001, 0x7832, 0x1904, 0x440b, 0x7834, 0x7832,
+	0x2061, 0x6bc0, 0x2069, 0x4680, 0xc7fd, 0x68cc, 0xa005, 0x0128,
+	0x8001, 0x68ce, 0x1110, 0x080c, 0x4577, 0x6800, 0xa084, 0x000f,
+	0x0168, 0xa086, 0x0001, 0x0150, 0x6840, 0xa00d, 0x0138, 0x2104,
+	0xa005, 0x0120, 0x8001, 0x200a, 0x0904, 0x4514, 0x6814, 0xa005,
+	0x01a8, 0x8001, 0x6816, 0x1190, 0x68a3, 0x0001, 0x00f6, 0xd7fc,
+	0x1118, 0x2079, 0x0200, 0x0010, 0x2079, 0x0100, 0x080c, 0x3c46,
+	0x00fe, 0x6860, 0xa005, 0x0110, 0x080c, 0x22ae, 0x687c, 0xa005,
+	0x0140, 0x8001, 0x687e, 0x1128, 0x6863, 0x0000, 0x68d0, 0xc0c5,
+	0x68d2, 0x68d0, 0xd0fc, 0x01b0, 0xc0fc, 0x68d2, 0x20a9, 0x0200,
+	0x6034, 0xa005, 0x0158, 0x8001, 0x6036, 0x68d0, 0xc0fd, 0x68d2,
+	0x1128, 0x6010, 0xa005, 0x0110, 0x080c, 0x22ae, 0xace0, 0x0010,
+	0x1f04, 0x43f0, 0xd7fc, 0x0138, 0x2061, 0x4bc0, 0x2069, 0x4640,
+	0xc7fc, 0x0804, 0x43ad, 0x0459, 0x7838, 0x8001, 0x783a, 0x11a0,
+	0x783c, 0x783a, 0x2061, 0x4bc0, 0x2069, 0x4640, 0xc7fc, 0x680c,
+	0xa005, 0x0110, 0x080c, 0x4487, 0xd7fc, 0x1130, 0x2061, 0x6bc0,
+	0x2069, 0x4680, 0xc7fd, 0x0c98, 0x7810, 0xd0cc, 0x0168, 0xd0ac,
 	0x1120, 0xd0a4, 0x0148, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0e04,
-	0x4193, 0x080c, 0x1ffe, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840,
-	0x8001, 0x7842, 0x1568, 0x7844, 0x7842, 0x2091, 0x8000, 0x2061,
-	0x48c0, 0x2069, 0x4340, 0xc7fc, 0x6810, 0xa005, 0x1110, 0x2001,
-	0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118, 0xa080, 0x89d0, 0x0010,
-	0xa080, 0x88c0, 0x2040, 0x2004, 0xa065, 0x0150, 0x6024, 0xa005,
-	0x0120, 0x8001, 0x6026, 0x0904, 0x4207, 0x6000, 0x2c40, 0x0ca0,
-	0xd7fc, 0x1130, 0x2061, 0x68c0, 0x2069, 0x4380, 0xc7fd, 0x08e0,
-	0x0005, 0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0540,
-	0x6024, 0xa005, 0x0118, 0x8001, 0x6026, 0x0400, 0x6008, 0xc09c,
-	0xd084, 0x1110, 0xd0ac, 0x01a8, 0x600a, 0x6004, 0xa06d, 0x01c0,
-	0x00c6, 0x0016, 0x6010, 0x8001, 0x6012, 0x080c, 0x35ab, 0x2d00,
-	0x2c68, 0x2060, 0x080c, 0x1b85, 0x080c, 0x1d30, 0x001e, 0x00ce,
-	0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d, 0x0100,
-	0xace0, 0x0010, 0x1f04, 0x41cd, 0xa184, 0x0001, 0x0130, 0xa18c,
-	0xfffe, 0x690e, 0x080c, 0x2233, 0x0008, 0x690e, 0x0005, 0x6800,
-	0xa005, 0x0120, 0x684c, 0xac06, 0x0904, 0x425f, 0x6864, 0xa005,
-	0x0120, 0x6027, 0x0001, 0x0804, 0x425c, 0x2c00, 0x687e, 0x6714,
-	0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006, 0x60b4,
-	0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0060,
-	0x6022, 0x6000, 0x2042, 0x080c, 0x1b1d, 0x6818, 0xa005, 0x0110,
+	0x4433, 0x080c, 0x207a, 0x0005, 0x2091, 0x8001, 0x0005, 0x7840,
+	0x8001, 0x7842, 0x1904, 0x4486, 0x7844, 0x7842, 0x2069, 0x4640,
+	0xc7fc, 0x2079, 0x0200, 0x68d4, 0xa005, 0x0138, 0x7de0, 0xa504,
+	0x1120, 0x68d6, 0x68d0, 0xc0bc, 0x68d2, 0x2079, 0x4600, 0x6810,
+	0xa005, 0x1110, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0118,
+	0xa080, 0x8cd0, 0x0010, 0xa080, 0x8bc0, 0x2040, 0x2004, 0xa065,
+	0x01e0, 0x6024, 0xa005, 0x01b0, 0x8001, 0x6026, 0x1198, 0x6800,
+	0xa005, 0x0130, 0x6848, 0xac06, 0x1118, 0x080c, 0x4514, 0x0068,
+	0x6860, 0xa005, 0x0118, 0x6027, 0x0001, 0x0020, 0x080c, 0x44c8,
+	0x2804, 0x0c28, 0x6000, 0x2c40, 0x0c10, 0xd7fc, 0x1138, 0x2069,
+	0x4680, 0xc7fd, 0x2079, 0x0100, 0x0804, 0x4443, 0x0005, 0x2009,
+	0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0558, 0x6024, 0xa005,
+	0x0118, 0x8001, 0x6026, 0x0418, 0x6008, 0xc09c, 0xd084, 0x1110,
+	0xd0ac, 0x01c0, 0x600a, 0x6004, 0xa005, 0x01d8, 0x00d6, 0x00c6,
+	0x0016, 0x2068, 0x6010, 0x8001, 0x6012, 0x080c, 0x37a4, 0x2d00,
+	0x2c68, 0x2060, 0x080c, 0x1be3, 0x080c, 0x1d95, 0x001e, 0x00ce,
+	0x00de, 0x0038, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0010, 0xa18d,
+	0x0100, 0xace0, 0x0010, 0x1f04, 0x448b, 0xa184, 0x0001, 0x0130,
+	0xa18c, 0xfffe, 0x690e, 0x080c, 0x22ae, 0x0008, 0x690e, 0x0005,
+	0x2c00, 0x687a, 0x6714, 0x6f72, 0x6017, 0x0000, 0x602b, 0x0000,
+	0x601b, 0x0006, 0x60b4, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
+	0x00ff, 0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6858, 0xac06,
+	0x1110, 0x2800, 0x685a, 0x080c, 0x1b7b, 0x6818, 0xa005, 0x0110,
 	0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109,
-	0x790a, 0x8001, 0x1310, 0x080c, 0x243b, 0x6812, 0x1118, 0x7910,
+	0x790a, 0x8001, 0x1310, 0x080c, 0x254c, 0x6812, 0x1118, 0x7910,
 	0xc1a5, 0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x080c,
-	0x1d3d, 0xd7fc, 0x1118, 0x2069, 0x4340, 0x0010, 0x2069, 0x4380,
-	0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x697a, 0x2001,
-	0x0004, 0x2708, 0x080c, 0x2228, 0x2091, 0x8001, 0x0005, 0x00d6,
-	0x694c, 0x2160, 0xd7fc, 0x1118, 0x2069, 0x0200, 0x0010, 0x2069,
-	0x0100, 0x080c, 0x23e1, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00,
-	0x601e, 0x6020, 0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f,
-	0x0000, 0x6033, 0x0000, 0x6830, 0xd0b4, 0x01b0, 0x684b, 0x0004,
-	0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x4282, 0x684b,
-	0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04, 0x428b,
-	0x20a9, 0x00fa, 0x1f04, 0x4292, 0x6808, 0xa084, 0xfffd, 0x680a,
-	0x681b, 0x0054, 0x00de, 0x6867, 0x0007, 0x2091, 0x8001, 0x0005,
-	0x2079, 0x4300, 0x00e1, 0x0089, 0x00a9, 0x2009, 0x0002, 0x2069,
-	0x4380, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817, 0x0000, 0x8109,
-	0x0118, 0x2069, 0x4340, 0x0ca8, 0x0005, 0x2019, 0x00a3, 0x7b3a,
-	0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42, 0x7b46, 0x0005, 0x2019,
-	0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6950, 0xa185, 0x0000, 0x0178,
-	0x00c6, 0x6ac0, 0x2264, 0x602b, 0x0000, 0x602f, 0x0000, 0x6008,
-	0xc0b5, 0x600a, 0x8210, 0x8109, 0x1da8, 0x6952, 0x00ce, 0x0005,
-	0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0180, 0x0088, 0xae8e, 0x0100,
-	0x0130, 0x7814, 0xc0f5, 0x7816, 0xd0d4, 0x1170, 0x0050, 0x7814,
-	0xc0fd, 0x7816, 0xd0d4, 0x1140, 0x0020, 0xd0e4, 0x0138, 0x70a0,
-	0x70a2, 0x7804, 0xd08c, 0x0110, 0x681f, 0x000c, 0x0005, 0xaf67
+	0x1da2, 0xd7fc, 0x1118, 0x2069, 0x4640, 0x0010, 0x2069, 0x4680,
+	0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x1118, 0x6976, 0x2001,
+	0x0004, 0x080c, 0x22a4, 0x0005, 0x00d6, 0x6948, 0x2160, 0xd7fc,
+	0x1118, 0x2069, 0x0200, 0x0010, 0x2069, 0x0100, 0x080c, 0x2467,
+	0x601b, 0x0006, 0x6858, 0xa084, 0x5f00, 0x601e, 0x6020, 0xa084,
+	0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000,
+	0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x01b0, 0x684b,
+	0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0110, 0x1f04, 0x453b,
+	0x684b, 0x0009, 0x20a9, 0x0014, 0x6848, 0xd084, 0x0110, 0x1f04,
+	0x4544, 0x20a9, 0x00fa, 0x1f04, 0x454b, 0x681b, 0x0054, 0x00de,
+	0x6863, 0x0007, 0x0005, 0x2079, 0x4600, 0x00e1, 0x0089, 0x00a9,
+	0x2009, 0x0002, 0x2069, 0x4680, 0x680f, 0x0000, 0x6813, 0x0000,
+	0x6817, 0x0000, 0x8109, 0x0118, 0x2069, 0x4640, 0x0ca8, 0x0005,
+	0x2019, 0x00a3, 0x7b3a, 0x7b3e, 0x0005, 0x2019, 0x0033, 0x7b42,
+	0x7b46, 0x0005, 0x2019, 0x32dd, 0x7b32, 0x7b36, 0x0005, 0x6a4c,
+	0xa285, 0x0000, 0x01f0, 0x6950, 0x6bbc, 0xa300, 0x00c6, 0x2164,
+	0x6304, 0x83ff, 0x1138, 0x8211, 0x0148, 0x8108, 0xa11a, 0x0eb8,
+	0x69bc, 0x0ca8, 0x68cf, 0x000a, 0x00ce, 0x0005, 0x694c, 0x6abc,
+	0x2264, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109, 0x1dc8, 0x694e,
+	0x00ce, 0x0005, 0x1d04, 0x459a, 0x2091, 0x6000, 0x1d04, 0x459e,
+	0x2091, 0x6000, 0x70ec, 0xd0dc, 0x1118, 0xd0d4, 0x0190, 0x0098,
+	0xae8e, 0x0100, 0x0138, 0x7814, 0xc0f5, 0xc0c5, 0x7816, 0xd0d4,
+	0x1578, 0x0458, 0x7814, 0xc0fd, 0xc0c5, 0x7816, 0xd0d4, 0x1540,
+	0x0420, 0xd0e4, 0x0538, 0x1d04, 0x45bb, 0x2091, 0x6000, 0x2009,
+	0x000c, 0x1d04, 0x45c1, 0x2091, 0x6000, 0x8109, 0x1dd0, 0x70e4,
+	0xa084, 0x01ff, 0xa086, 0x01ff, 0x1110, 0x70ec, 0x08c8, 0xae8e,
+	0x0100, 0x0128, 0x7814, 0xc0f4, 0xd0fc, 0x1130, 0x0020, 0x7814,
+	0xc0fc, 0xd0f4, 0x1108, 0xc0c4, 0x7816, 0x7804, 0xd08c, 0x0110,
+	0x681f, 0x000c, 0x70a0, 0x70a2, 0x0005, 0x7c12
 };
 #ifdef UNIQUE_FW_NAME
-unsigned short   fw12160i_length01 = 0x32f8;
+unsigned short   fw12160i_length01 = 0x35e6;
 #else
-unsigned short   risc_code_length01 = 0x32f8;
+unsigned short   risc_code_length01 = 0x35e6;
 #endif
-
diff -urN linux-2.4.23-pre6/drivers/scsi/ql1280_fw.h linux-2.4.23-pre7/drivers/scsi/ql1280_fw.h
--- linux-2.4.23-pre6/drivers/scsi/ql1280_fw.h	2000-02-07 19:45:28.000000000 -0800
+++ linux-2.4.23-pre7/drivers/scsi/ql1280_fw.h	2003-10-09 17:48:22.000000000 -0700
@@ -1,59 +1,74 @@
+/*****************************************************************************
+ *                  QLOGIC LINUX SOFTWARE
+ *
+ * QLogic ISP1280/ device driver for Linux 2.2.x and 2.4.x
+ * Copyright (C) 2001 Qlogic Corporation (www.qlogic.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, 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.
+ *
+ *****************************************************************************/
+
 /************************************************************************
- *									*
  * 	         --- ISP1240/1080/1280 Initiator Firmware ---           *
  *			      32 LUN Support				*
- *									*
- ************************************************************************
- * Copyright (C) 1999,2000 Qlogic, Corporation.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted provided
- * that the following conditions are met:
- * 1. Redistribution of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *									*
- ************************************************************************
- */
+ ************************************************************************/
 
 
 /*
- *	Firmware Version 8.09.00 (18:29 Apr 16, 1999)
+ *	Firmware Version 8.15.00 (14:35 Aug 22, 2000)
  */
 
-unsigned short fw1280ei_version = 8*1024+9;
+#ifdef UNIQUE_FW_NAME
+unsigned short fw1280ei_version = 8*1024+15;
+#else
+unsigned short risc_code_version = 8*1024+15;
+#endif
+
+#ifdef UNIQUE_FW_NAME
+unsigned char fw1280ei_version_str[] = {8,15,0};
+#else
+unsigned char firmware_version[] = {8,15,0};
+#endif
 
-unsigned char fw1280ei_version_str[] = {8,9,0};
+#ifdef UNIQUE_FW_NAME
+#define fw1280ei_VERSION_STRING "8.15.00"
+#else
+#define FW_VERSION_STRING "8.15.00"
+#endif
 
-unsigned short fw1280ei_addr01 = 0x1000 ;
+#ifdef UNIQUE_FW_NAME
+unsigned short fw1280ei_addr01 = 0x1000;
+#else
+unsigned short risc_code_addr01 = 0x1000;
+#endif
 
-unsigned short fw1280ei_code01[] = { 
-	0x0078, 0x1041, 0x0000, 0x39e3, 0x0000, 0x2043, 0x4f50, 0x5952,
+#ifdef UNIQUE_FW_NAME
+unsigned short fw1280ei_code01[] = {
+#else
+unsigned short risc_code01[] = {
+#endif
+	0x0078, 0x1041, 0x0000, 0x3d3b, 0x0000, 0x2043, 0x4f50, 0x5952,
 	0x4947, 0x4854, 0x2031, 0x3939, 0x312c, 0x3139, 0x3932, 0x2c31,
 	0x3939, 0x332c, 0x3139, 0x3934, 0x2051, 0x4c4f, 0x4749, 0x4320,
 	0x434f, 0x5250, 0x4f52, 0x4154, 0x494f, 0x4e00, 0x2049, 0x5350,
 	0x3132, 0x3430, 0x2046, 0x6972, 0x6d77, 0x6172, 0x6520, 0x2056,
-	0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3039, 0x2020, 0x2043,
+	0x6572, 0x7369, 0x6f6e, 0x2030, 0x382e, 0x3135, 0x2020, 0x2043,
 	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
 	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
-	0x2400, 0x20c9, 0x93ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
+	0x2400, 0x20c9, 0x97ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
 	0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010,
-	0x2089, 0x136a, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086,
+	0x2089, 0x1374, 0x0078, 0x106d, 0x2001, 0x04fc, 0x2004, 0xa086,
 	0x1280, 0x00c0, 0x1069, 0x2071, 0x0200, 0x70a0, 0x70a2, 0x2071,
-	0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13ea, 0x0078,
-	0x106d, 0x20c1, 0x0020, 0x2089, 0x1312, 0x2071, 0x0010, 0x70c3,
+	0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010, 0x2089, 0x13f8, 0x0078,
+	0x106d, 0x20c1, 0x0020, 0x2089, 0x131c, 0x2071, 0x0010, 0x70c3,
 	0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
 	0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000,
 	0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64,
@@ -61,1838 +76,1948 @@
 	0xa286, 0xa5a5, 0x0040, 0x10a4, 0xa386, 0x000f, 0x0040, 0x10a0,
 	0x2c6a, 0x2a5a, 0x20c1, 0x0020, 0x2019, 0x000f, 0x0078, 0x1080,
 	0x2c6a, 0x2a5a, 0x0078, 0x10a2, 0x2c6a, 0x2a5a, 0x2130, 0x2128,
-	0xa1a2, 0x4a00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
-	0xa192, 0x9400, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x2078,
-	0x2218, 0x2079, 0x4a00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
-	0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2001, 0x04fc, 0x2004,
-	0xa086, 0x1080, 0x00c0, 0x10db, 0x2071, 0x0100, 0x0d7e, 0x2069,
-	0x4a40, 0x1078, 0x49ae, 0x0d7f, 0x7810, 0xc0ed, 0x7812, 0x781b,
-	0x0064, 0x0078, 0x1100, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1280,
-	0x00c0, 0x10fb, 0x7814, 0xc0ed, 0xc0d5, 0x7816, 0x781b, 0x0064,
-	0x2071, 0x0200, 0x0d7e, 0x2069, 0x4a40, 0x1078, 0x49ae, 0x2069,
-	0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae, 0x7814, 0xc0d4, 0x7816,
-	0x0d7f, 0x0078, 0x1100, 0x7814, 0xc0e5, 0x7816, 0x781b, 0x003c,
-	0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800, 0xc08d, 0x7802,
-	0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002, 0x7827, 0x0002,
-	0x2009, 0x0002, 0x2069, 0x4a40, 0x681b, 0x0003, 0x6823, 0x0007,
-	0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028, 0x6837, 0x0000,
-	0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000, 0x8109, 0x0040,
-	0x1154, 0x68d3, 0x000a, 0x68c3, 0x4ac0, 0x2079, 0x4a00, 0x7814,
-	0xd0e4, 0x00c0, 0x113a, 0xd0ec, 0x00c0, 0x113e, 0x68d7, 0x7329,
-	0x0078, 0x1140, 0x68d7, 0x730d, 0x0078, 0x1140, 0x68d7, 0x7329,
-	0x68c7, 0x4fc0, 0x68cb, 0x4ec0, 0x68cf, 0x8fc0, 0x68ab, 0x9244,
-	0x68af, 0x9249, 0x68b3, 0x9244, 0x68b7, 0x9244, 0x68a7, 0x0001,
-	0x2069, 0x4a80, 0x0078, 0x1114, 0x68d3, 0x000a, 0x68c3, 0x4cc0,
-	0x7814, 0xd0e4, 0x00c0, 0x1160, 0x68d7, 0x7439, 0x0078, 0x1162,
-	0x68d7, 0x7419, 0x68c7, 0x6fc0, 0x68cb, 0x4f40, 0x68cf, 0x90d0,
-	0x68ab, 0x9249, 0x68af, 0x924e, 0x68b3, 0x9249, 0x68b7, 0x9249,
-	0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11b8, 0x7814, 0xd0e4,
-	0x00c0, 0x11aa, 0x0e7e, 0x2069, 0x4ec0, 0x2071, 0x0200, 0x70ec,
-	0xd0e4, 0x00c0, 0x118b, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
-	0x2007, 0x0078, 0x1191, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
-	0x2007, 0x2069, 0x4f40, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0,
-	0x11a1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0078,
-	0x11a7, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007, 0x0e7f,
-	0x0078, 0x11d1, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x2069, 0x4ec0,
-	0x1078, 0x2007, 0x2069, 0x4f40, 0x1078, 0x2007, 0x0078, 0x11d1,
-	0x2069, 0x4ec0, 0x0e7e, 0x2071, 0x0100, 0x70ec, 0xd0e4, 0x00c0,
-	0x11ca, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078, 0x2007, 0x0e7f,
-	0x0078, 0x11d1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078, 0x2007,
-	0x0e7f, 0x2011, 0x0002, 0x2069, 0x4fc0, 0x2009, 0x0002, 0x20a9,
-	0x0100, 0x683f, 0x0000, 0x680b, 0x0040, 0x7bc8, 0xa386, 0xfeff,
-	0x00c0, 0x11e8, 0x6817, 0x0100, 0x681f, 0x0064, 0x0078, 0x11ec,
-	0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010, 0x00f0, 0x11d9,
-	0x8109, 0x00c0, 0x11d7, 0x8211, 0x0040, 0x11fa, 0x2069, 0x6fc0,
-	0x0078, 0x11d5, 0x1078, 0x2611, 0x1078, 0x441d, 0x1078, 0x1df2,
-	0x1078, 0x4957, 0x2091, 0x2100, 0x2079, 0x4a00, 0x7810, 0xd0ec,
-	0x0040, 0x120e, 0x2071, 0x0020, 0x0078, 0x1210, 0x2071, 0x0050,
-	0x2091, 0x2200, 0x2079, 0x4a00, 0x2071, 0x0020, 0x2091, 0x2300,
-	0x2079, 0x4a00, 0x7810, 0xd0ec, 0x0040, 0x1222, 0x2079, 0x0100,
-	0x0078, 0x1224, 0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x2400,
-	0x2079, 0x0100, 0x2071, 0x4a80, 0x2091, 0x2000, 0x2079, 0x4a00,
-	0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090, 0x2071, 0x0010,
-	0x70c3, 0x0000, 0x0090, 0x1243, 0x70c0, 0xa086, 0x0002, 0x00c0,
-	0x1243, 0x1078, 0x159d, 0x2039, 0x0000, 0x7810, 0xd0ec, 0x00c0,
-	0x12c5, 0x1078, 0x1472, 0x78ac, 0xa005, 0x00c0, 0x1261, 0x0068,
-	0x1257, 0x786c, 0xa065, 0x0040, 0x1257, 0x1078, 0x2368, 0x1078,
-	0x209f, 0x0068, 0x126e, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078,
-	0x2368, 0x0068, 0x126e, 0x2009, 0x4a47, 0x2011, 0x4a87, 0x2104,
-	0x220c, 0xa105, 0x0040, 0x126e, 0x1078, 0x1f1e, 0x2071, 0x4a40,
-	0x70a4, 0xa005, 0x0040, 0x1293, 0x7450, 0xa485, 0x0000, 0x0040,
-	0x1293, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d,
-	0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d, 0x0068,
-	0x1293, 0x2079, 0x4a00, 0x786c, 0xa065, 0x0040, 0x1293, 0x2071,
-	0x0010, 0x1078, 0x2368, 0x00e0, 0x129b, 0x2079, 0x4a00, 0x2071,
-	0x0010, 0x1078, 0x4765, 0x2071, 0x4a80, 0x70a4, 0xa005, 0x0040,
-	0x12b3, 0x7050, 0xa025, 0x0040, 0x12b3, 0x2079, 0x0100, 0x2091,
-	0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091,
-	0x8000, 0x2091, 0x303d, 0x2079, 0x4a00, 0x2071, 0x0010, 0x0068,
-	0x12bf, 0x786c, 0xa065, 0x0040, 0x12bf, 0x1078, 0x2368, 0x00e0,
-	0x1249, 0x1078, 0x4765, 0x0078, 0x1249, 0x1078, 0x1472, 0x78ac,
-	0xa005, 0x00c0, 0x12dd, 0x0068, 0x12d3, 0x786c, 0xa065, 0x0040,
-	0x12d3, 0x1078, 0x2368, 0x1078, 0x209f, 0x0068, 0x12e7, 0x786c,
-	0xa065, 0x0040, 0x12dd, 0x1078, 0x2368, 0x0068, 0x12e7, 0x2009,
-	0x4a47, 0x2104, 0xa005, 0x0040, 0x12e7, 0x1078, 0x1f1e, 0x2071,
-	0x4a40, 0x70a4, 0xa005, 0x0040, 0x1302, 0x7450, 0xa485, 0x0000,
-	0x0040, 0x1302, 0x2079, 0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c,
-	0x303d, 0x2190, 0x1078, 0x2a9c, 0x2091, 0x8000, 0x2091, 0x303d,
-	0x2079, 0x4a00, 0x2071, 0x0010, 0x0068, 0x130c, 0x786c, 0xa065,
-	0x0040, 0x130c, 0x1078, 0x2368, 0x00e0, 0x12c5, 0x1078, 0x4765,
-	0x0078, 0x12c5, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341,
-	0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341,
-	0x1341, 0x1341, 0x1332, 0x1332, 0x1334, 0x1334, 0x1341, 0x1341,
-	0x1341, 0x1341, 0x134c, 0x134c, 0x1359, 0x1359, 0x1341, 0x1341,
-	0x1341, 0x1341, 0x0078, 0x1332, 0x007e, 0x107e, 0x127e, 0x2091,
-	0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-	0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f,
-	0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091,
-	0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-	0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b,
-	0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091,
-	0x8001, 0x007c, 0x138a, 0x138a, 0x138c, 0x138c, 0x1399, 0x1399,
-	0x1399, 0x1399, 0x13a4, 0x13a4, 0x138c, 0x138c, 0x1399, 0x1399,
-	0x1399, 0x1399, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5,
-	0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5, 0x13a5,
-	0x13a5, 0x13a5, 0x0078, 0x138a, 0x007e, 0x107e, 0x127e, 0x2091,
-	0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-	0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c7, 0x127f, 0x107f,
-	0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e, 0x127e, 0x0d7e,
-	0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069, 0x4a40, 0x2079,
-	0x4a00, 0x1078, 0x49ae, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
-	0x107f, 0x007c, 0x3c00, 0xa084, 0x0007, 0x0079, 0x13bf, 0x13d0,
-	0x13d0, 0x13d2, 0x13d2, 0x13d7, 0x13d7, 0x13dc, 0x13dc, 0x3c00,
-	0xa084, 0x0003, 0x0079, 0x13cc, 0x13d0, 0x13d0, 0x13e5, 0x13e5,
-	0x1078, 0x28ec, 0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091,
-	0x2100, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078, 0x44b7,
-	0x2091, 0x2200, 0x1078, 0x44b7, 0x007c, 0x2091, 0x2100, 0x1078,
-	0x44b7, 0x007c, 0x140a, 0x140a, 0x140c, 0x140c, 0x1419, 0x1419,
-	0x1419, 0x1419, 0x1424, 0x1424, 0x1431, 0x1431, 0x1419, 0x1419,
-	0x1419, 0x1419, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442,
-	0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442, 0x1442,
-	0x1442, 0x1442, 0x0078, 0x140a, 0x007e, 0x107e, 0x127e, 0x2091,
-	0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-	0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13ba, 0x127f, 0x107f,
-	0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091,
-	0x2300, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001,
-	0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x290b,
-	0x2091, 0x2400, 0x1078, 0x290b, 0x127f, 0x107f, 0x007f, 0x2091,
-	0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e,
-	0x2079, 0x4a00, 0x2071, 0x0200, 0x2069, 0x4a40, 0x3d00, 0xd08c,
-	0x00c0, 0x1456, 0x2069, 0x4a80, 0x2071, 0x0100, 0x1078, 0x49ae,
-	0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007f, 0x007c, 0x7008,
-	0x800b, 0x00c8, 0x146d, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0,
-	0x146e, 0xd09c, 0x0040, 0x146d, 0x087a, 0x097a, 0x70c3, 0x4002,
-	0x0078, 0x15a0, 0x0068, 0x14f7, 0x2061, 0x0000, 0x6018, 0xd084,
-	0x00c0, 0x14f7, 0x7828, 0xa005, 0x00c0, 0x1482, 0x0010, 0x14f8,
-	0x0078, 0x14f7, 0x7910, 0xd1f4, 0x0040, 0x148a, 0x2001, 0x4007,
-	0x0078, 0x159f, 0x7914, 0xd1ec, 0x0040, 0x14a5, 0xd0fc, 0x0040,
-	0x149b, 0x007e, 0x1078, 0x1d82, 0x007f, 0x0040, 0x14a5, 0x2001,
-	0x4007, 0x0078, 0x159f, 0x007e, 0x1078, 0x1d72, 0x007f, 0x0040,
-	0x14a5, 0x2001, 0x4007, 0x0078, 0x159f, 0x7910, 0xd0fc, 0x00c0,
-	0x14af, 0x2061, 0x4a40, 0xc19c, 0xc7fc, 0x0078, 0x14b3, 0x2061,
-	0x4a80, 0xc19d, 0xc7fd, 0x6064, 0xa005, 0x00c0, 0x14f7, 0x7912,
-	0x6083, 0x0000, 0x7828, 0xc0fc, 0xa086, 0x0018, 0x00c0, 0x14c4,
-	0x0c7e, 0x1078, 0x1b13, 0x0c7f, 0x782b, 0x0000, 0x607c, 0xa065,
-	0x0040, 0x14dd, 0x0c7e, 0x609c, 0x1078, 0x1e5d, 0x0c7f, 0x609f,
-	0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087, 0x0103, 0x1078,
-	0x1d92, 0x00c0, 0x14f1, 0x1078, 0x1de4, 0x7810, 0xd09c, 0x00c0,
-	0x14e5, 0x2061, 0x4a40, 0x0078, 0x14e9, 0x2061, 0x4a80, 0xc09c,
-	0x7812, 0x607f, 0x0000, 0x60d4, 0xd0dc, 0x0040, 0x14f5, 0xc0dc,
-	0x60d6, 0x2001, 0x4005, 0x0078, 0x159f, 0x0078, 0x159d, 0x007c,
-	0x7810, 0xd0f4, 0x0040, 0x1500, 0x2001, 0x4007, 0x0078, 0x159f,
-	0xa006, 0x70c2, 0x70c6, 0x70ca, 0x70ce, 0x70da, 0x70c0, 0xa08a,
-	0x0040, 0x00c8, 0x150d, 0x0079, 0x1514, 0x2100, 0xa08a, 0x0040,
-	0x00c8, 0x15ab, 0x0079, 0x1554, 0x159d, 0x15f3, 0x15bc, 0x162b,
-	0x1663, 0x1663, 0x15b3, 0x1c57, 0x166e, 0x15ab, 0x15c0, 0x15c2,
-	0x15c4, 0x15c6, 0x1c5c, 0x15ab, 0x167c, 0x16d4, 0x1b35, 0x1c51,
-	0x15c8, 0x19a7, 0x19e9, 0x1a1f, 0x1a6b, 0x1962, 0x196f, 0x1983,
-	0x1996, 0x17a4, 0x1cdc, 0x1706, 0x1713, 0x171f, 0x172b, 0x1741,
-	0x174d, 0x1750, 0x175c, 0x1768, 0x1770, 0x178c, 0x1798, 0x15ab,
-	0x15ab, 0x15ab, 0x15ab, 0x17b1, 0x17c3, 0x17df, 0x1815, 0x183d,
-	0x184d, 0x1850, 0x1881, 0x18b2, 0x18c4, 0x1931, 0x1941, 0x1d32,
-	0x15ab, 0x15ab, 0x15ab, 0x1951, 0x15ab, 0x15ab, 0x15ab, 0x15ab,
-	0x15ab, 0x1c81, 0x1c87, 0x15ab, 0x15ab, 0x15ab, 0x1c8b, 0x1cd8,
-	0x15ab, 0x15ab, 0x1ce8, 0x1cf7, 0x15ed, 0x165d, 0x1676, 0x16ce,
-	0x1b2f, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x1d39, 0x1c73, 0x1c7d,
-	0x15ab, 0x15ab, 0x1d02, 0x1d1b, 0x15ab, 0x15ab, 0x15ab, 0x15ab,
-	0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab,
-	0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab,
-	0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x15ab,
-	0x15ab, 0x15ab, 0x15ab, 0x15ab, 0x72ca, 0x71c6, 0x2001, 0x4006,
-	0x0078, 0x159f, 0x73ce, 0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2,
-	0x0068, 0x15a0, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x5000,
-	0x2091, 0x4080, 0x007c, 0x70c3, 0x4001, 0x0078, 0x15a0, 0x70c3,
-	0x4006, 0x0078, 0x15a0, 0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9,
-	0x0005, 0x53a3, 0x0078, 0x159d, 0x70c4, 0x70c3, 0x0004, 0x007a,
-	0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d, 0x0078, 0x159d,
-	0x2091, 0x8000, 0x70c3, 0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020,
-	0x70cf, 0x2020, 0x70d3, 0x0008, 0x2001, 0x0009, 0x70d6, 0x2079,
-	0x0000, 0x781b, 0x0001, 0x2031, 0x0030, 0x2059, 0x1000, 0x2029,
-	0x041a, 0x2051, 0x0445, 0x2061, 0x0447, 0x20c1, 0x0020, 0x2091,
-	0x5000, 0x2091, 0x4080, 0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da,
-	0x74de, 0x0078, 0x15f6, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8,
-	0x73cc, 0x70c4, 0x20a0, 0x2099, 0x0030, 0x7003, 0x0001, 0x7007,
-	0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x81ff,
-	0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x1610, 0x2120, 0xa006,
-	0x2008, 0x8403, 0x7012, 0x7007, 0x0004, 0x7007, 0x0001, 0x7008,
-	0xd0fc, 0x0040, 0x1617, 0x7007, 0x0002, 0xa084, 0x01e0, 0x0040,
-	0x1625, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x24a8, 0x53a5, 0x0078,
-	0x1607, 0x0078, 0x159d, 0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8,
-	0x73cc, 0x70c4, 0x2098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x7007,
-	0x0006, 0x731a, 0x721e, 0x7422, 0x7526, 0x2021, 0x0040, 0x7007,
-	0x0006, 0x81ff, 0x0040, 0x159d, 0xa182, 0x0040, 0x00c8, 0x164a,
-	0x2120, 0xa006, 0x2008, 0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007,
-	0x0001, 0x7008, 0xd0fc, 0x0040, 0x1651, 0xa084, 0x01e0, 0x0040,
-	0x163f, 0x70c3, 0x4002, 0x0078, 0x15a0, 0x75d8, 0x74dc, 0x75da,
-	0x74de, 0x0078, 0x162e, 0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004,
-	0x00c0, 0x166b, 0x200a, 0x72ca, 0x0078, 0x159c, 0x70c7, 0x0008,
-	0x70cb, 0x0009, 0x70cf, 0x0000, 0x0078, 0x159d, 0x75d8, 0x76dc,
-	0x75da, 0x76de, 0x0078, 0x167f, 0x2029, 0x0000, 0x2530, 0x70c4,
-	0x72c8, 0x73cc, 0x74d0, 0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005,
-	0x0040, 0x16c9, 0x8001, 0x7872, 0xa084, 0xfc00, 0x0040, 0x1697,
-	0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7b7e,
-	0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00, 0x0040, 0x16af,
-	0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f, 0xa118, 0xa291,
-	0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078, 0x16b9, 0x8407,
-	0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581,
-	0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605, 0x0040, 0x16c3,
-	0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc, 0x78ae, 0x0078,
-	0x16cc, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x159d, 0x75d8, 0x76dc,
-	0x75da, 0x76de, 0x0078, 0x16d7, 0x2029, 0x0000, 0x2530, 0x70c4,
-	0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce, 0x74d6, 0xa005,
-	0x0040, 0x1701, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x16ef,
-	0x78ac, 0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x159f, 0x7a9a,
-	0x7b9e, 0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x16fa, 0x7a10,
-	0xc2c5, 0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078,
-	0x1704, 0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x159d, 0x2009, 0x0000,
-	0x786c, 0xa065, 0x0040, 0x1710, 0x8108, 0x6000, 0x0078, 0x1709,
-	0x7ac4, 0x0078, 0x159b, 0x2009, 0x4a48, 0x210c, 0x7810, 0xd0ec,
-	0x00c0, 0x159c, 0x2011, 0x4a88, 0x2214, 0x0078, 0x159b, 0x2009,
-	0x4a49, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a89,
-	0x2214, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6128, 0x622c, 0x8214,
-	0x8214, 0x8214, 0x7810, 0xd0ec, 0x00c0, 0x173f, 0x2061, 0x4a80,
-	0x6328, 0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078,
-	0x159b, 0x2009, 0x4a4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c,
-	0x2011, 0x4a8c, 0x2214, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c,
-	0x2009, 0x4a4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2011,
-	0x4a8d, 0x2214, 0x0078, 0x159b, 0x2009, 0x4a4e, 0x210c, 0x7810,
-	0xd0ec, 0x00c0, 0x159c, 0x2011, 0x4a8e, 0x2214, 0x0078, 0x159b,
-	0x7920, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x7a24, 0x0078, 0x159b,
-	0x71c4, 0xd1fc, 0x00c0, 0x1778, 0x2011, 0x4ec0, 0x0078, 0x177a,
-	0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xa268, 0x6a00, 0x6804, 0xd09c, 0x0040, 0x1789, 0x6b08, 0x0078,
-	0x178a, 0x6b0c, 0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091,
-	0x8000, 0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x159a,
-	0x2061, 0x4a40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061,
-	0x4a80, 0x6218, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091,
-	0x8000, 0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078,
-	0x159a, 0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8,
-	0x1595, 0x1078, 0x2729, 0xa384, 0x4000, 0x0040, 0x17c1, 0xa295,
-	0x0020, 0x0078, 0x159a, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010,
-	0x00c8, 0x1595, 0xd1bc, 0x00c0, 0x17d2, 0x2011, 0x4a48, 0x2204,
-	0x0078, 0x17d6, 0x2011, 0x4a88, 0x2204, 0xc0bd, 0x007e, 0x2100,
-	0xc0bc, 0x2012, 0x1078, 0x2686, 0x017f, 0x0078, 0x159c, 0x71c4,
-	0x2021, 0x4a49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x17ee,
-	0x71c8, 0x2021, 0x4a89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x180d,
-	0x20a9, 0x0008, 0x2204, 0xa106, 0x0040, 0x17fd, 0x8210, 0x00f0,
-	0x17f2, 0x71c4, 0x72c8, 0x0078, 0x1594, 0xa292, 0x180d, 0x027e,
-	0x2122, 0x017f, 0x1078, 0x26a7, 0x7810, 0xd0ec, 0x00c0, 0x180b,
-	0xd3fc, 0x0040, 0x17e8, 0x0078, 0x159d, 0x03e8, 0x00fa, 0x01f4,
-	0x02ee, 0x0064, 0x0019, 0x0032, 0x004b, 0x2061, 0x4a40, 0x6128,
-	0x622c, 0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003,
-	0x8003, 0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x183b, 0x027e,
-	0x017e, 0x2061, 0x4a80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214,
-	0x70d8, 0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da,
-	0x72de, 0x017f, 0x027f, 0x0078, 0x159b, 0x2061, 0x4a40, 0x6130,
-	0x70c4, 0x6032, 0x7810, 0xd0ec, 0x00c0, 0x159c, 0x2061, 0x4a80,
-	0x6230, 0x70c8, 0x6032, 0x0078, 0x159b, 0x7918, 0x0078, 0x159c,
-	0x71c4, 0xa184, 0xffcf, 0x0040, 0x185c, 0x7810, 0xd0ec, 0x00c0,
-	0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4d, 0x2204, 0x2112,
-	0x007e, 0x2019, 0x0000, 0x1078, 0x270e, 0x7810, 0xd0ec, 0x0040,
-	0x186c, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa184, 0xffcf, 0x0040,
-	0x1875, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8d, 0x2204,
-	0x2112, 0x007e, 0xc3fd, 0x1078, 0x270e, 0x027f, 0x017f, 0x0078,
-	0x159b, 0x71c4, 0xa182, 0x0010, 0x0048, 0x188d, 0x7810, 0xd0ec,
-	0x00c0, 0x1595, 0x72c8, 0x0078, 0x1594, 0x2011, 0x4a4e, 0x2204,
-	0x007e, 0x2112, 0x2019, 0x0000, 0x1078, 0x26ec, 0x7810, 0xd0ec,
-	0x0040, 0x189d, 0x017f, 0x0078, 0x159c, 0x71c8, 0xa182, 0x0010,
-	0x0048, 0x18a6, 0x2110, 0x71c4, 0x0078, 0x1594, 0x2011, 0x4a8e,
-	0x2204, 0x007e, 0x2112, 0xc3fd, 0x1078, 0x26ec, 0x027f, 0x017f,
-	0x0078, 0x159b, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x1594,
-	0xa284, 0xfffd, 0x00c0, 0x1594, 0x2100, 0x7920, 0x7822, 0x2200,
-	0x7a24, 0x7826, 0x0078, 0x159b, 0x71c4, 0xd1fc, 0x00c0, 0x18cc,
-	0x2011, 0x4ec0, 0x0078, 0x18ce, 0x2011, 0x4f40, 0x8107, 0xa084,
-	0x000f, 0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8,
-	0xa284, 0x0080, 0x0040, 0x18e2, 0x6c14, 0x84ff, 0x00c0, 0x18e2,
-	0x6817, 0x0040, 0xa284, 0x0040, 0x0040, 0x18ec, 0x6c10, 0x84ff,
-	0x00c0, 0x18ec, 0x6813, 0x0001, 0x6800, 0x007e, 0xa226, 0x0040,
-	0x1909, 0x6a02, 0xd4ec, 0x0040, 0x18f6, 0xc3a5, 0xd4e4, 0x0040,
-	0x18fa, 0xc39d, 0xd4f4, 0x0040, 0x1909, 0x810f, 0xd2f4, 0x0040,
-	0x1905, 0x1078, 0x276b, 0x0078, 0x1909, 0x1078, 0x2749, 0x0078,
-	0x1909, 0x72cc, 0x6808, 0xa206, 0x0040, 0x1929, 0xa2a4, 0x00ff,
-	0x7814, 0xd0e4, 0x00c0, 0x191c, 0xa482, 0x0028, 0x0048, 0x1926,
-	0x0040, 0x1926, 0x0078, 0x1920, 0xa482, 0x0043, 0x0048, 0x1926,
-	0x71c4, 0x71c6, 0x027f, 0x72ca, 0x0078, 0x1596, 0x6a0a, 0xa39d,
-	0x000a, 0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x0078,
-	0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a14, 0x6b1c,
-	0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708, 0x0078,
-	0x159a, 0x70c4, 0x2061, 0x4a40, 0x6118, 0x601a, 0x7810, 0xd0ec,
-	0x00c0, 0x159c, 0x70c8, 0x2061, 0x4a80, 0x6218, 0x601a, 0x0078,
-	0x159b, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8, 0x1595,
-	0x1078, 0x278d, 0xa384, 0x4000, 0x0040, 0x1960, 0xa295, 0x0020,
-	0x0078, 0x159a, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08,
-	0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4,
-	0x1078, 0x1e02, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9, 0x6a0a,
-	0x6804, 0xa005, 0x0040, 0x197e, 0x1078, 0x25de, 0x2091, 0x8001,
-	0x2708, 0x0078, 0x159b, 0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000,
-	0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x1991, 0x1078,
-	0x25de, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4, 0x2041,
-	0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
-	0x1e1d, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x159b, 0x77c4,
-	0x7814, 0xd0e4, 0x00c0, 0x19bb, 0xd7fc, 0x0040, 0x19b5, 0x1078,
-	0x1d82, 0x0040, 0x19bb, 0x0078, 0x159f, 0x1078, 0x1d72, 0x0040,
-	0x19bb, 0x0078, 0x159f, 0x73c8, 0x72cc, 0x77c6, 0x73ca, 0x72ce,
-	0x1078, 0x1e9a, 0x00c0, 0x19e5, 0x6818, 0xa005, 0x0040, 0x19df,
-	0x2708, 0x077e, 0x1078, 0x27bd, 0x077f, 0x00c0, 0x19df, 0x2001,
-	0x0015, 0xd7fc, 0x00c0, 0x19d8, 0x2061, 0x4a40, 0x0078, 0x19db,
-	0xc0fd, 0x2061, 0x4a80, 0x782a, 0x2091, 0x8001, 0x007c, 0x2091,
-	0x8001, 0x2001, 0x4005, 0x0078, 0x159f, 0x2091, 0x8001, 0x0078,
-	0x159d, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19fd, 0xd7fc, 0x0040,
-	0x19f7, 0x1078, 0x1d82, 0x0040, 0x19fd, 0x0078, 0x159f, 0x1078,
-	0x1d72, 0x0040, 0x19fd, 0x0078, 0x159f, 0x77c6, 0x2041, 0x0021,
-	0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078, 0x1e1d,
-	0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a11, 0x2061, 0x4a40, 0x0078,
-	0x1a14, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0003, 0x6776, 0x6083,
-	0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001, 0x007c, 0x77c8,
-	0x77ca, 0x77c4, 0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a36, 0xd7fc,
-	0x0040, 0x1a30, 0x1078, 0x1d82, 0x0040, 0x1a36, 0x0078, 0x159f,
-	0x1078, 0x1d72, 0x0040, 0x1a36, 0x0078, 0x159f, 0xa7bc, 0xff00,
-	0x2091, 0x8000, 0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a43, 0x2061,
-	0x4a40, 0x0078, 0x1a46, 0x2061, 0x4a80, 0xc1fd, 0x6067, 0x0002,
-	0x6776, 0x6083, 0x000f, 0x792a, 0x1078, 0x25de, 0x2091, 0x8001,
-	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0010, 0x2091, 0x8000,
-	0x70c8, 0xa005, 0x0040, 0x1a5f, 0x60d4, 0xc0fd, 0x60d6, 0x1078,
-	0x1e1d, 0x70c8, 0x683e, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1a5f,
-	0x2091, 0x8001, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x1a7f, 0x72c8,
-	0xd284, 0x0040, 0x1a79, 0x1078, 0x1d82, 0x0040, 0x1a7f, 0x0078,
-	0x159f, 0x1078, 0x1d72, 0x0040, 0x1a7f, 0x0078, 0x159f, 0x72c8,
-	0x72ca, 0x78ac, 0xa084, 0x0003, 0x00c0, 0x1aaa, 0x2039, 0x0000,
-	0xd284, 0x0040, 0x1a8c, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004,
-	0x2051, 0x0008, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6808, 0xc0d4,
-	0xa80d, 0x690a, 0x2091, 0x8001, 0x8738, 0xa784, 0x001f, 0x00c0,
-	0x1a92, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
-	0x00c0, 0x1a92, 0x2091, 0x8000, 0x72c8, 0xd284, 0x00c0, 0x1abc,
-	0x7810, 0xd0ec, 0x0040, 0x1ab8, 0x2069, 0x0100, 0x0078, 0x1abe,
-	0x2069, 0x0200, 0x0078, 0x1abe, 0x2069, 0x0100, 0x6830, 0xd0b4,
-	0x0040, 0x1ada, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094,
-	0x0040, 0x1acc, 0x00f0, 0x1ac6, 0x684b, 0x0009, 0x20a9, 0x0014,
-	0x6848, 0xd084, 0x0040, 0x1ad6, 0x00f0, 0x1ad0, 0x20a9, 0x00fa,
-	0x00f0, 0x1ad8, 0x2079, 0x4a00, 0x2009, 0x0018, 0x72c8, 0xd284,
-	0x00c0, 0x1ae6, 0x2061, 0x4a40, 0x0078, 0x1ae9, 0x2061, 0x4a80,
-	0xc1fd, 0x792a, 0x6067, 0x0001, 0x6083, 0x000f, 0x60a7, 0x0000,
-	0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4, 0x0040, 0x1b03, 0xc0b4,
-	0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008, 0xc0d4, 0x600a, 0x6018,
-	0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084, 0x77ff, 0x60d6, 0x78ac,
-	0xc08d, 0x78ae, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b, 0x0047,
-	0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b1a, 0x2069, 0x4a40,
-	0x0078, 0x1b1c, 0x2069, 0x4a80, 0x78ac, 0xc08c, 0x78ae, 0xd084,
-	0x00c0, 0x1b26, 0x0d7e, 0x1078, 0x1efa, 0x0d7f, 0x71c4, 0x71c6,
-	0x6916, 0x81ff, 0x00c0, 0x1b2e, 0x68a7, 0x0001, 0x007c, 0x75d8,
-	0x74dc, 0x75da, 0x74de, 0x0078, 0x1b38, 0x2029, 0x0000, 0x2520,
-	0x71c4, 0x73c8, 0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4a00,
-	0x7dde, 0x7cda, 0x7bd6, 0x7ad2, 0x1078, 0x1ddb, 0x0040, 0x1c3b,
-	0x20a9, 0x0005, 0x20a1, 0x4a14, 0x2091, 0x8000, 0x41a1, 0x2091,
-	0x8001, 0x2009, 0x0040, 0x1078, 0x1fcf, 0x0040, 0x1b5b, 0x1078,
-	0x1de4, 0x0078, 0x1c3b, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009,
-	0x00c0, 0x1b66, 0x007e, 0x1078, 0x234b, 0x007f, 0xa084, 0xff00,
-	0x8007, 0x8009, 0x0040, 0x1bda, 0x0c7e, 0x2c68, 0x1078, 0x1ddb,
-	0x0040, 0x1bac, 0x2c00, 0x689e, 0x8109, 0x00c0, 0x1b6d, 0x609f,
-	0x0000, 0x0c7f, 0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290,
-	0x0040, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde,
-	0x7cda, 0x7bd6, 0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1bd9,
-	0x2009, 0x0040, 0x1078, 0x1fcf, 0x00c0, 0x1bc3, 0x6004, 0xa084,
-	0x00ff, 0xa086, 0x0002, 0x00c0, 0x1bac, 0x6004, 0xa084, 0x00ff,
-	0xa086, 0x000a, 0x00c0, 0x1ba8, 0x017e, 0x1078, 0x2347, 0x017f,
-	0x2d00, 0x6002, 0x0078, 0x1b7b, 0x0c7f, 0x0c7e, 0x609c, 0x1078,
-	0x1e5d, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018,
-	0x6008, 0xc0cd, 0x600a, 0x6004, 0x6086, 0x1078, 0x1d92, 0x1078,
-	0x1de4, 0x0078, 0x1c3b, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e5d,
-	0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c3f, 0x2009, 0x0018, 0x6087,
-	0x0103, 0x601b, 0x0003, 0x1078, 0x1d92, 0x1078, 0x1de4, 0x0078,
-	0x1c3b, 0x0c7f, 0x7814, 0xd0e4, 0x00c0, 0x1bff, 0x6114, 0xd1fc,
-	0x0040, 0x1be8, 0x1078, 0x1d82, 0x0040, 0x1bff, 0x0078, 0x1bec,
-	0x1078, 0x1d72, 0x0040, 0x1bff, 0x2029, 0x0000, 0x2520, 0x2009,
-	0x0018, 0x73c8, 0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078,
-	0x1d92, 0x1078, 0x1de4, 0x2001, 0x4007, 0x0078, 0x159f, 0x74c4,
-	0x73c8, 0x72cc, 0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012,
-	0xd0fc, 0x00c0, 0x1c0f, 0x2071, 0x4a40, 0x0078, 0x1c12, 0x2071,
-	0x4a80, 0xc1fd, 0x792a, 0x7067, 0x0005, 0x71d4, 0xa18c, 0xf77f,
-	0x71d6, 0x736a, 0x726e, 0x7472, 0x7076, 0x707b, 0x0000, 0x2c00,
-	0x707e, 0xa02e, 0x2530, 0x611c, 0xa184, 0x0060, 0x0040, 0x1c2a,
-	0x1078, 0x43c1, 0x0e7f, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af,
-	0x0000, 0x60b3, 0x0000, 0x6714, 0x6023, 0x0000, 0x1078, 0x25de,
-	0x2091, 0x8001, 0x007c, 0x70c3, 0x4005, 0x0078, 0x15a0, 0x20a9,
-	0x0005, 0x2099, 0x4a14, 0x2091, 0x8000, 0x530a, 0x2091, 0x8001,
-	0x2100, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
-	0x007c, 0x71c4, 0x70c7, 0x0000, 0x791e, 0x0078, 0x159d, 0x71c4,
-	0x71c6, 0x2168, 0x0078, 0x1c5e, 0x2069, 0x1000, 0x690c, 0xa016,
-	0x2d04, 0xa210, 0x8d68, 0x8109, 0x00c0, 0x1c60, 0xa285, 0x0000,
-	0x00c0, 0x1c6e, 0x70c3, 0x4000, 0x0078, 0x1c70, 0x70c3, 0x4003,
-	0x70ca, 0x0078, 0x15a0, 0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003,
-	0x00c8, 0x1595, 0x7966, 0x0078, 0x159d, 0x7964, 0x71c6, 0x0078,
-	0x159d, 0x7900, 0x71c6, 0x71c4, 0x7902, 0x0078, 0x159d, 0x7900,
-	0x71c6, 0x0078, 0x159d, 0x70c4, 0xd08c, 0x0040, 0x1c94, 0x7a10,
-	0xd2ec, 0x00c0, 0x1c94, 0xc08c, 0x2011, 0x0000, 0xa08c, 0x000d,
-	0x0040, 0x1ca8, 0x810c, 0x0048, 0x1ca4, 0x8210, 0x810c, 0x810c,
-	0x0048, 0x1ca4, 0x8210, 0x810c, 0x81ff, 0x00c0, 0x1596, 0x8210,
-	0x7a0e, 0xd28c, 0x0040, 0x1cd4, 0x7910, 0xc1cd, 0x7912, 0x2009,
-	0x0021, 0x2019, 0x0003, 0xd284, 0x0040, 0x1cce, 0x8108, 0x2019,
-	0x0041, 0x2011, 0x924e, 0x2312, 0x2019, 0x0042, 0x8210, 0x2312,
-	0x2019, 0x0043, 0x8210, 0x2312, 0x2019, 0x0046, 0x8210, 0x2312,
-	0x2019, 0x0047, 0x8210, 0x2312, 0x2019, 0x0006, 0x2011, 0x9253,
-	0x2112, 0x2011, 0x9273, 0x2312, 0x7904, 0x7806, 0x0078, 0x159c,
-	0x7804, 0x70c6, 0x0078, 0x159d, 0x2091, 0x8000, 0x2019, 0x0000,
-	0x2011, 0x0000, 0x2009, 0x0000, 0x2091, 0x8001, 0x0078, 0x159a,
-	0x77c4, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6830, 0xa084, 0xff00,
-	0x8007, 0x2010, 0x2091, 0x8001, 0x2708, 0x0078, 0x159b, 0x77c4,
-	0x1078, 0x1e02, 0x2091, 0x8000, 0x6a34, 0x2091, 0x8001, 0x2708,
-	0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9, 0x0008,
-	0x72c8, 0x8217, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c30, 0x6a32,
-	0x2091, 0x8001, 0x8738, 0x00f0, 0x1d0a, 0x077f, 0x2708, 0x8427,
-	0x2410, 0x0078, 0x159b, 0x77c4, 0x077e, 0xa7bc, 0xff00, 0x20a9,
-	0x0008, 0x72c8, 0x1078, 0x1e02, 0x2091, 0x8000, 0x6c34, 0x6a36,
-	0x2091, 0x8001, 0x8738, 0x00f0, 0x1d22, 0x077f, 0x2708, 0x2410,
-	0x0078, 0x159b, 0x2011, 0x4a3c, 0x220c, 0x70c4, 0x2012, 0x0078,
-	0x159c, 0x71c4, 0xd1fc, 0x00c0, 0x1d41, 0x2011, 0x4ec0, 0x0078,
-	0x1d43, 0x2011, 0x4f40, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
-	0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d52, 0x2011, 0x0001,
-	0x0078, 0x1d54, 0x2011, 0x0000, 0x6b0c, 0x0078, 0x159a, 0x017e,
-	0x7814, 0xd0f4, 0x0040, 0x1d64, 0x2001, 0x4007, 0x70db, 0x0000,
-	0xa18d, 0x0001, 0x0078, 0x1d70, 0xd0fc, 0x0040, 0x1d6f, 0x2001,
-	0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d70, 0xa006,
-	0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d7f, 0x2001,
-	0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d80, 0xa006,
-	0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040, 0x1d8f, 0x2001,
-	0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078, 0x1d90, 0xa006,
-	0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810, 0xd0c4, 0x0040,
-	0x1d9b, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108, 0x810c, 0x81a9,
-	0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084, 0x20a2, 0x53a6,
-	0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040, 0x1db8, 0x810f,
-	0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x1dbb,
-	0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78, 0xa006, 0xa211,
-	0x7d10, 0xd5c4, 0x0040, 0x1dc8, 0x7b84, 0xa319, 0x7c80, 0xa421,
-	0x7008, 0xd0fc, 0x0040, 0x1dc8, 0x7003, 0x0001, 0x7007, 0x0006,
-	0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dd8, 0x7322, 0x7426,
-	0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040, 0x1de3, 0x2c04,
-	0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079, 0x4a00, 0x7848,
-	0x2062, 0x2c00, 0xa005, 0x00c0, 0x1def, 0x1078, 0x28ec, 0x784a,
-	0x0f7f, 0x007c, 0x2011, 0x9400, 0x7a4a, 0x7bc4, 0x8319, 0x0040,
-	0x1dff, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078, 0x1df6, 0x2013,
-	0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0, 0x1e0b, 0x2011,
-	0x4fc0, 0x0078, 0x1e0d, 0x2011, 0x6fc0, 0xa784, 0x0f00, 0x800b,
-	0xa784, 0x001f, 0x0040, 0x1e18, 0x8003, 0x8003, 0x8003, 0x8003,
-	0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078, 0x1e02, 0x2900,
-	0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef, 0xa80d, 0x690a,
-	0xd7fc, 0x00c0, 0x1e2f, 0x2009, 0x4a53, 0x0078, 0x1e31, 0x2009,
-	0x4a93, 0x210c, 0x6804, 0xa005, 0x0040, 0x1e41, 0xa116, 0x00c0,
-	0x1e41, 0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078,
-	0x1e44, 0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e59,
-	0x6000, 0x6806, 0x1078, 0x1e6f, 0x1078, 0x201b, 0x6810, 0x7908,
-	0x8109, 0x790a, 0x8001, 0x6812, 0x00c0, 0x1e44, 0x7910, 0xc1a5,
-	0x7912, 0x017f, 0x6902, 0x6906, 0x007c, 0xa065, 0x0040, 0x1e6e,
-	0x2008, 0x609c, 0xa005, 0x0040, 0x1e6b, 0x2062, 0x609f, 0x0000,
-	0xa065, 0x0078, 0x1e61, 0x7848, 0x794a, 0x2062, 0x007c, 0x6007,
-	0x0103, 0x608f, 0x0000, 0x20a9, 0x001c, 0xac80, 0x0005, 0x20a0,
-	0x2001, 0x0000, 0x40a4, 0x6828, 0x601a, 0x682c, 0x6022, 0x007c,
-	0x0e7e, 0xd7fc, 0x00c0, 0x1e8a, 0x2071, 0x4a40, 0x2031, 0x4ac0,
-	0x0078, 0x1e8e, 0x2071, 0x4a80, 0x2031, 0x4cc0, 0x7050, 0xa08c,
-	0x0200, 0x00c0, 0x1e98, 0xa608, 0x2d0a, 0x8000, 0x7052, 0xa006,
-	0x0e7f, 0x007c, 0x0f7e, 0xd7fc, 0x00c0, 0x1ea2, 0x2079, 0x4a40,
-	0x0078, 0x1ea4, 0x2079, 0x4a80, 0x1078, 0x1e02, 0x2091, 0x8000,
-	0x6804, 0x780a, 0xa065, 0x0040, 0x1ef8, 0x0078, 0x1eb6, 0x2c00,
-	0x780a, 0x2060, 0x6000, 0xa065, 0x0040, 0x1ef8, 0x6010, 0xa306,
-	0x00c0, 0x1eaf, 0x600c, 0xa206, 0x00c0, 0x1eaf, 0x2c28, 0x784c,
-	0xac06, 0x00c0, 0x1ec5, 0x0078, 0x1ef5, 0x6804, 0xac06, 0x00c0,
-	0x1ed3, 0x6000, 0x2060, 0x6806, 0xa005, 0x00c0, 0x1ed3, 0x6803,
-	0x0000, 0x0078, 0x1edd, 0x6400, 0x7808, 0x2060, 0x6402, 0xa486,
-	0x0000, 0x00c0, 0x1edd, 0x2c00, 0x6802, 0x2560, 0x0f7f, 0x1078,
-	0x1e6f, 0x0f7e, 0x601b, 0x0005, 0x6023, 0x0020, 0x0f7f, 0x1078,
-	0x201b, 0x0f7e, 0x7908, 0x8109, 0x790a, 0x6810, 0x8001, 0x6812,
-	0x00c0, 0x1ef5, 0x7810, 0xc0a5, 0x7812, 0x2001, 0xffff, 0xa005,
-	0x0f7f, 0x007c, 0x077e, 0x2700, 0x2039, 0x0000, 0xd0fc, 0x0040,
-	0x1f02, 0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008,
-	0x2091, 0x8000, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0,
-	0x1f0a, 0xa7bc, 0xff00, 0x873f, 0x8738, 0x873f, 0xa784, 0x0f00,
-	0x00c0, 0x1f0a, 0x2091, 0x8001, 0x077f, 0x007c, 0x2061, 0x0000,
-	0x6018, 0xd084, 0x00c0, 0x1f3e, 0x7810, 0xd08c, 0x0040, 0x1f2f,
-	0xc08c, 0x7812, 0xc7fc, 0x2069, 0x4a40, 0x0078, 0x1f34, 0xc08d,
-	0x7812, 0x2069, 0x4a80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f,
-	0x0000, 0x2091, 0x8001, 0xa005, 0x00c0, 0x1f3f, 0x007c, 0xa08c,
-	0xfff0, 0x0040, 0x1f45, 0x1078, 0x28ec, 0x0079, 0x1f47, 0x1f57,
-	0x1f5a, 0x1f60, 0x1f64, 0x1f58, 0x1f68, 0x1f58, 0x1f58, 0x1f58,
-	0x1f6e, 0x1f9f, 0x1fa3, 0x1fa9, 0x1f58, 0x1f58, 0x1f58, 0x007c,
-	0x1078, 0x28ec, 0x1078, 0x1efa, 0x2001, 0x8001, 0x0078, 0x1fbe,
-	0x2001, 0x8003, 0x0078, 0x1fbe, 0x2001, 0x8004, 0x0078, 0x1fbe,
-	0x1078, 0x1efa, 0x2001, 0x8006, 0x0078, 0x1fbe, 0x2091, 0x8000,
-	0x077e, 0xd7fc, 0x00c0, 0x1f7a, 0x2069, 0x4a40, 0x2039, 0x0009,
-	0x0078, 0x1f7e, 0x2069, 0x4a80, 0x2039, 0x0009, 0x6800, 0xa086,
-	0x0000, 0x0040, 0x1f88, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c,
-	0x6874, 0x077f, 0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004,
-	0x2051, 0x0010, 0x1078, 0x1e1d, 0x8738, 0xa784, 0x001f, 0x00c0,
-	0x1f92, 0x2091, 0x8001, 0x2001, 0x800a, 0x0078, 0x1fbe, 0x2001,
-	0x800c, 0x0078, 0x1fbe, 0x1078, 0x1efa, 0x2001, 0x800d, 0x0078,
-	0x1fbe, 0x7814, 0xd0e4, 0x00c0, 0x1fbc, 0xd0ec, 0x0040, 0x1fb6,
-	0xd7fc, 0x0040, 0x1fb6, 0x78ec, 0x0078, 0x1fb7, 0x78e4, 0x70c6,
-	0x2001, 0x800e, 0x0078, 0x1fbe, 0x0078, 0x1f58, 0x70c2, 0xd7fc,
-	0x00c0, 0x1fc6, 0x70db, 0x0000, 0x0078, 0x1fc8, 0x70db, 0x0001,
-	0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080, 0x007c, 0xac80,
-	0x0001, 0x81ff, 0x0040, 0x1ffa, 0x2099, 0x0030, 0x20a0, 0x700c,
-	0xa084, 0x03ff, 0x0040, 0x1fdc, 0x7018, 0x007e, 0x701c, 0x007e,
-	0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac, 0x721a, 0x731e,
-	0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001, 0x7008, 0x800b,
-	0x00c8, 0x1fee, 0x7007, 0x0002, 0xa08c, 0x01e0, 0x00c0, 0x1ffa,
-	0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004, 0x007f, 0x7026,
-	0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a, 0x007c, 0x2011,
-	0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803, 0xfd00, 0x6807,
-	0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290, 0x0004, 0x8109,
-	0x00c0, 0x200b, 0x007c, 0x6004, 0x6086, 0x2c08, 0x2063, 0x0000,
-	0x7868, 0xa005, 0x796a, 0x0040, 0x2028, 0x2c02, 0x0078, 0x2029,
-	0x796e, 0x007c, 0x0c7e, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08,
-	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x203a, 0x2d02,
-	0x0078, 0x203b, 0x616e, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x2c04,
-	0x786e, 0xa005, 0x00c0, 0x2045, 0x786a, 0x2091, 0x8001, 0x609c,
-	0xa005, 0x0040, 0x205e, 0x0c7e, 0x2060, 0x2008, 0x609c, 0xa005,
-	0x0040, 0x205a, 0x2062, 0x609f, 0x0000, 0xa065, 0x609c, 0xa005,
-	0x00c0, 0x2052, 0x7848, 0x794a, 0x2062, 0x0c7f, 0x7848, 0x2062,
-	0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x2068, 0x1078, 0x28ec,
-	0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004, 0x8086, 0x818e,
-	0x00c8, 0x2073, 0xa200, 0x00f0, 0x206e, 0x8086, 0x818e, 0x007c,
-	0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x2099, 0xa11a, 0x00c8,
-	0x2099, 0x8213, 0x818d, 0x0048, 0x208c, 0xa11a, 0x00c8, 0x208d,
-	0x00f0, 0x2081, 0x0078, 0x2091, 0xa11a, 0x2308, 0x8210, 0x00f0,
-	0x2081, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080, 0x007f, 0x157f,
-	0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078, 0x2095, 0x7d74,
-	0x70d0, 0xa506, 0x0040, 0x2185, 0x7810, 0x2050, 0x7800, 0xd08c,
-	0x0040, 0x20c1, 0xdaec, 0x0040, 0x20c1, 0x0e7e, 0x2091, 0x8000,
-	0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20be, 0x7008, 0x0e7f,
-	0xa086, 0x0008, 0x0040, 0x20c1, 0x0078, 0x2185, 0x0e7f, 0x0078,
-	0x2185, 0x1078, 0x1ddb, 0x0040, 0x2185, 0xa046, 0x7970, 0x2500,
-	0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d0, 0x0078, 0x20d7,
-	0x72d0, 0xa206, 0x0040, 0x20d7, 0x8840, 0x2009, 0x0080, 0x0c7e,
-	0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9, 0x0020, 0xac80,
-	0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040, 0x20e9, 0x1078,
-	0x1ddb, 0x7008, 0xd0fc, 0x0040, 0x20e9, 0x7007, 0x0002, 0x2091,
-	0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2120, 0x53a5, 0x8cff, 0x00c0,
-	0x20fe, 0x88ff, 0x0040, 0x216f, 0x0078, 0x2108, 0x2c00, 0x788e,
-	0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5, 0x0078, 0x216f,
-	0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2110, 0x7420, 0x7524,
-	0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000, 0xa5ab, 0x0000,
-	0x721a, 0x731e, 0xdac4, 0x0040, 0x2120, 0x7422, 0x7526, 0xa006,
-	0x7007, 0x0004, 0x0040, 0x216f, 0x8cff, 0x0040, 0x2129, 0x1078,
-	0x1de4, 0x0c7f, 0x1078, 0x1de4, 0xa046, 0x7888, 0x8000, 0x788a,
-	0xa086, 0x0002, 0x0040, 0x214f, 0x7a7c, 0x7b78, 0xdac4, 0x0040,
-	0x213b, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004, 0x8004, 0xa210,
-	0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x721a, 0x731e,
-	0xdac4, 0x0040, 0x2185, 0x7422, 0x7526, 0x0078, 0x2185, 0x6014,
-	0xd0fc, 0x00c0, 0x2157, 0x2069, 0x4a40, 0x0078, 0x2159, 0x2069,
-	0x4a80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff, 0x0040, 0x2165,
-	0xa046, 0x788c, 0x2060, 0x0078, 0x214f, 0x788b, 0x0000, 0x78ac,
-	0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078, 0x2185, 0x0c7f,
-	0x788b, 0x0000, 0x1078, 0x2319, 0x6004, 0xa084, 0x000f, 0x1078,
-	0x2186, 0x88ff, 0x0040, 0x2183, 0x788c, 0x2060, 0x6004, 0xa084,
-	0x000f, 0x1078, 0x2186, 0x0078, 0x209f, 0x007c, 0x0079, 0x2188,
-	0x2198, 0x21b6, 0x21d4, 0x2198, 0x21e5, 0x21a9, 0x2198, 0x2198,
-	0x2198, 0x21b4, 0x21d2, 0x2198, 0x2198, 0x2198, 0x2198, 0x2198,
-	0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008, 0xa705, 0x600a,
-	0x1078, 0x2228, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078, 0x2303,
-	0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21af, 0x0078, 0x2198, 0x601c,
-	0xc0bd, 0x601e, 0x0078, 0x21bc, 0x1078, 0x234b, 0x78bc, 0xd0c4,
-	0x0040, 0x21bc, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6004, 0x8007,
-	0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21cf, 0x1078, 0x2228,
-	0x0040, 0x21cf, 0x78bc, 0xc0c5, 0x78be, 0x0078, 0x21d1, 0x0078,
-	0x2247, 0x007c, 0x1078, 0x2347, 0x78bc, 0xa08c, 0x0e00, 0x00c0,
-	0x21dc, 0xd0c4, 0x00c0, 0x21de, 0x0078, 0x2198, 0x1078, 0x2228,
-	0x00c0, 0x21e4, 0x0078, 0x2247, 0x007c, 0x78bc, 0xd0c4, 0x0040,
-	0x21eb, 0x0078, 0x2198, 0x78bf, 0x0000, 0x6714, 0x2011, 0x0001,
-	0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040, 0x220b, 0xa7bc,
-	0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040, 0x220b, 0xa7bc,
-	0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e, 0x0002, 0x0040,
-	0x220b, 0x0078, 0x2225, 0x1078, 0x1e02, 0x2d00, 0x2091, 0x8000,
-	0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084, 0xffde, 0x680a,
-	0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x220e, 0x8211, 0x0040,
-	0x2225, 0x20a9, 0x0100, 0x0078, 0x220e, 0x1078, 0x1de4, 0x007c,
-	0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6, 0x00c0, 0x2233,
-	0x78ba, 0x0078, 0x223b, 0x689e, 0x2d00, 0x6002, 0x78b8, 0xad06,
-	0x00c0, 0x223b, 0x6002, 0x78b0, 0x8001, 0x78b2, 0x00c0, 0x2246,
-	0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006, 0x007c, 0x0e7e,
-	0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2, 0x601c, 0x60a2,
-	0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060, 0x0040, 0x225a,
-	0x1078, 0x43c1, 0x6596, 0x65a6, 0x669a, 0x66aa, 0x6714, 0x2071,
-	0x4a80, 0xd7fc, 0x00c0, 0x2266, 0x2071, 0x4a40, 0xa784, 0x0f00,
-	0x800b, 0xa784, 0x001f, 0x0040, 0x2271, 0x8003, 0x8003, 0x8003,
-	0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007, 0xa084, 0x000f,
-	0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2, 0x2091, 0x8000,
-	0x7810, 0xd0f4, 0x00c0, 0x228b, 0x6e08, 0xd684, 0x0040, 0x22a1,
-	0xd9fc, 0x00c0, 0x22a1, 0x2091, 0x8001, 0x1078, 0x1e6f, 0x2091,
-	0x8000, 0x1078, 0x201b, 0x2091, 0x8001, 0x7814, 0xd0e4, 0x00c0,
-	0x2301, 0x7810, 0xd0f4, 0x0040, 0x2301, 0x601b, 0x0021, 0x0078,
-	0x2301, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22a8, 0x8000, 0x6026,
-	0x6a10, 0x6814, 0xa202, 0x0048, 0x22bb, 0x0040, 0x22bb, 0x2091,
+	0xa1a2, 0x4e00, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424, 0x8424,
+	0xa192, 0x9800, 0x2009, 0x0000, 0x2001, 0x0032, 0x1078, 0x207a,
+	0x2218, 0x2079, 0x4e00, 0x2fa0, 0x2408, 0x2011, 0x0000, 0x20a9,
+	0x0040, 0x42a4, 0x8109, 0x00c0, 0x10bf, 0x2009, 0xff00, 0x3400,
+	0xa102, 0x0048, 0x10cf, 0x0040, 0x10cf, 0x20a8, 0x42a4, 0x2001,
+	0x04fc, 0x2004, 0xa086, 0x1080, 0x00c0, 0x10e5, 0x2071, 0x0100,
+	0x0d7e, 0x2069, 0x4e40, 0x1078, 0x4cdd, 0x0d7f, 0x7810, 0xc0ed,
+	0x7812, 0x781b, 0x0064, 0x0078, 0x110a, 0x2001, 0x04fc, 0x2004,
+	0xa086, 0x1280, 0x00c0, 0x1105, 0x7814, 0xc0ed, 0xc0d5, 0x7816,
+	0x781b, 0x0064, 0x2071, 0x0200, 0x0d7e, 0x2069, 0x4e40, 0x1078,
+	0x4cdd, 0x2069, 0x4e80, 0x2071, 0x0100, 0x1078, 0x4cdd, 0x7814,
+	0xc0d4, 0x7816, 0x0d7f, 0x0078, 0x110a, 0x7814, 0xc0e5, 0x7816,
+	0x781b, 0x003c, 0x7eca, 0x7cc2, 0x7bc6, 0x7867, 0x0000, 0x7800,
+	0xc08d, 0x7802, 0x2031, 0x0030, 0x78af, 0x0101, 0x7823, 0x0002,
+	0x7827, 0x0002, 0x2009, 0x0002, 0x2069, 0x4e40, 0x681b, 0x0003,
+	0x6823, 0x0007, 0x6827, 0x00fa, 0x682b, 0x0008, 0x682f, 0x0028,
+	0x6837, 0x0000, 0x683b, 0x0006, 0x6833, 0x0008, 0x683f, 0x0000,
+	0x8109, 0x0040, 0x115e, 0x68d3, 0x000a, 0x68c3, 0x4ec0, 0x2079,
+	0x4e00, 0x7814, 0xd0e4, 0x00c0, 0x1144, 0xd0ec, 0x00c0, 0x1148,
+	0x68d7, 0x7329, 0x0078, 0x114a, 0x68d7, 0x730d, 0x0078, 0x114a,
+	0x68d7, 0x732d, 0x68c7, 0x53c0, 0x68cb, 0x52c0, 0x68cf, 0x93c0,
+	0x68ab, 0x9644, 0x68af, 0x9649, 0x68b3, 0x9644, 0x68b7, 0x9644,
+	0x68a7, 0x0001, 0x2069, 0x4e80, 0x0078, 0x111e, 0x68d3, 0x000a,
+	0x68c3, 0x50c0, 0x7814, 0xd0e4, 0x00c0, 0x116a, 0x68d7, 0x7439,
+	0x0078, 0x116c, 0x68d7, 0x7419, 0x68c7, 0x73c0, 0x68cb, 0x5340,
+	0x68cf, 0x94d0, 0x68ab, 0x9649, 0x68af, 0x964e, 0x68b3, 0x9649,
+	0x68b7, 0x9649, 0x68a7, 0x0001, 0x7810, 0xd0ec, 0x00c0, 0x11c2,
+	0x7814, 0xd0e4, 0x00c0, 0x11b4, 0x0e7e, 0x2069, 0x52c0, 0x2071,
+	0x0200, 0x70ec, 0xd0e4, 0x00c0, 0x1195, 0x2019, 0x0c0c, 0x2021,
+	0x000c, 0x1078, 0x2009, 0x0078, 0x119b, 0x2019, 0x0c0a, 0x2021,
+	0x000a, 0x1078, 0x2009, 0x2069, 0x5340, 0x2071, 0x0100, 0x70ec,
+	0xd0e4, 0x00c0, 0x11ab, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
+	0x2009, 0x0078, 0x11b1, 0x2019, 0x0c0a, 0x2021, 0x000a, 0x1078,
+	0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0c, 0x2021, 0x000c,
+	0x2069, 0x52c0, 0x1078, 0x2009, 0x2069, 0x5340, 0x1078, 0x2009,
+	0x0078, 0x11db, 0x2069, 0x52c0, 0x0e7e, 0x2071, 0x0100, 0x70ec,
+	0xd0e4, 0x00c0, 0x11d4, 0x2019, 0x0c0c, 0x2021, 0x000c, 0x1078,
+	0x2009, 0x0e7f, 0x0078, 0x11db, 0x2019, 0x0c0a, 0x2021, 0x000a,
+	0x1078, 0x2009, 0x0e7f, 0x2011, 0x0002, 0x2069, 0x53c0, 0x2009,
+	0x0002, 0x20a9, 0x0100, 0x6837, 0x0000, 0x680b, 0x0040, 0x7bc8,
+	0xa386, 0xfeff, 0x00c0, 0x11f2, 0x6817, 0x0100, 0x681f, 0x0064,
+	0x0078, 0x11f6, 0x6817, 0x0064, 0x681f, 0x0002, 0xade8, 0x0010,
+	0x00f0, 0x11e3, 0x8109, 0x00c0, 0x11e1, 0x8211, 0x0040, 0x1204,
+	0x2069, 0x73c0, 0x0078, 0x11df, 0x1078, 0x265b, 0x1078, 0x468e,
+	0x1078, 0x1dd4, 0x1078, 0x4c6f, 0x2091, 0x2100, 0x2079, 0x4e00,
+	0x7810, 0xd0ec, 0x0040, 0x1218, 0x2071, 0x0020, 0x0078, 0x121a,
+	0x2071, 0x0050, 0x2091, 0x2200, 0x2079, 0x4e00, 0x2071, 0x0020,
+	0x2091, 0x2300, 0x2079, 0x4e00, 0x7810, 0xd0ec, 0x0040, 0x122c,
+	0x2079, 0x0100, 0x0078, 0x122e, 0x2079, 0x0200, 0x2071, 0x4e40,
+	0x2091, 0x2400, 0x2079, 0x0100, 0x2071, 0x4e80, 0x2091, 0x2000,
+	0x2079, 0x4e00, 0x2071, 0x0010, 0x3200, 0xa085, 0x303d, 0x2090,
+	0x2071, 0x0010, 0x70c3, 0x0000, 0x0090, 0x124d, 0x70c0, 0xa086,
+	0x0002, 0x00c0, 0x124d, 0x1078, 0x15ba, 0x2039, 0x0000, 0x7810,
+	0xd0ec, 0x00c0, 0x12cf, 0x1078, 0x148e, 0x78ac, 0xa005, 0x00c0,
+	0x126b, 0x0068, 0x1261, 0x786c, 0xa065, 0x0040, 0x1261, 0x1078,
+	0x2395, 0x1078, 0x20a1, 0x0068, 0x1278, 0x786c, 0xa065, 0x0040,
+	0x126b, 0x1078, 0x2395, 0x0068, 0x1278, 0x2009, 0x4e47, 0x2011,
+	0x4e87, 0x2104, 0x220c, 0xa105, 0x0040, 0x1278, 0x1078, 0x1f0a,
+	0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x129d, 0x7450, 0xa485,
+	0x0000, 0x0040, 0x129d, 0x2079, 0x0200, 0x2091, 0x8000, 0x72d4,
+	0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000, 0x2091,
+	0x303d, 0x0068, 0x129d, 0x2079, 0x4e00, 0x786c, 0xa065, 0x0040,
+	0x129d, 0x2071, 0x0010, 0x1078, 0x2395, 0x00e0, 0x12a5, 0x2079,
+	0x4e00, 0x2071, 0x0010, 0x1078, 0x4a43, 0x2071, 0x4e80, 0x70a4,
+	0xa005, 0x0040, 0x12bd, 0x7050, 0xa025, 0x0040, 0x12bd, 0x2079,
+	0x0100, 0x2091, 0x8000, 0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078,
+	0x2b6a, 0x2091, 0x8000, 0x2091, 0x303d, 0x2079, 0x4e00, 0x2071,
+	0x0010, 0x0068, 0x12c9, 0x786c, 0xa065, 0x0040, 0x12c9, 0x1078,
+	0x2395, 0x00e0, 0x1253, 0x1078, 0x4a43, 0x0078, 0x1253, 0x1078,
+	0x148e, 0x78ac, 0xa005, 0x00c0, 0x12e7, 0x0068, 0x12dd, 0x786c,
+	0xa065, 0x0040, 0x12dd, 0x1078, 0x2395, 0x1078, 0x20a1, 0x0068,
+	0x12f1, 0x786c, 0xa065, 0x0040, 0x12e7, 0x1078, 0x2395, 0x0068,
+	0x12f1, 0x2009, 0x4e47, 0x2104, 0xa005, 0x0040, 0x12f1, 0x1078,
+	0x1f0a, 0x2071, 0x4e40, 0x70a4, 0xa005, 0x0040, 0x130c, 0x7450,
+	0xa485, 0x0000, 0x0040, 0x130c, 0x2079, 0x0100, 0x2091, 0x8000,
+	0x72d4, 0xa28c, 0x303d, 0x2190, 0x1078, 0x2b6a, 0x2091, 0x8000,
+	0x2091, 0x303d, 0x2079, 0x4e00, 0x2071, 0x0010, 0x0068, 0x1316,
+	0x786c, 0xa065, 0x0040, 0x1316, 0x1078, 0x2395, 0x00e0, 0x12cf,
+	0x1078, 0x4a43, 0x0078, 0x12cf, 0x133c, 0x133c, 0x133e, 0x133e,
+	0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
+	0x134b, 0x134b, 0x134b, 0x134b, 0x133c, 0x133c, 0x133e, 0x133e,
+	0x134b, 0x134b, 0x134b, 0x134b, 0x1356, 0x1356, 0x1363, 0x1363,
+	0x134b, 0x134b, 0x134b, 0x134b, 0x0078, 0x133c, 0x007e, 0x107e,
+	0x127e, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13c8,
+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e, 0x107e,
+	0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300,
+	0x1078, 0x298a, 0x2091, 0x2400, 0x1078, 0x298a, 0x127f, 0x107f,
+	0x007f, 0x2091, 0x8001, 0x007c, 0x1394, 0x1394, 0x1396, 0x1396,
+	0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13ae, 0x13ae, 0x1396, 0x1396,
+	0x13a3, 0x13a3, 0x13a3, 0x13a3, 0x13af, 0x13af, 0x13af, 0x13af,
+	0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af, 0x13af,
+	0x13af, 0x13af, 0x13af, 0x13af, 0x0078, 0x1394, 0x007e, 0x107e,
+	0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x127f, 0x107f, 0x007f,
+	0x2091, 0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x1078, 0x13d5,
+	0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007c, 0x107e,
+	0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x007e, 0x2071, 0x0100, 0x2069,
+	0x4e40, 0x2079, 0x4e00, 0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078,
+	0x4cdd, 0x007f, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f, 0x107f, 0x007c,
+	0x3c00, 0xa084, 0x0007, 0x0079, 0x13cd, 0x13de, 0x13de, 0x13e0,
+	0x13e0, 0x13e5, 0x13e5, 0x13ea, 0x13ea, 0x3c00, 0xa084, 0x0003,
+	0x0079, 0x13da, 0x13de, 0x13de, 0x13f3, 0x13f3, 0x1078, 0x296b,
+	0x2091, 0x2200, 0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078,
+	0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x2091, 0x2200,
+	0x1078, 0x4768, 0x007c, 0x2091, 0x2100, 0x1078, 0x4768, 0x007c,
+	0x1418, 0x1418, 0x141a, 0x141a, 0x1427, 0x1427, 0x1427, 0x1427,
+	0x1432, 0x1432, 0x143f, 0x143f, 0x1427, 0x1427, 0x1427, 0x1427,
+	0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
+	0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450, 0x1450,
+	0x0078, 0x1418, 0x007e, 0x107e, 0x127e, 0x2091, 0x2400, 0x1078,
+	0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
+	0x107e, 0x127e, 0x1078, 0x13c8, 0x127f, 0x107f, 0x007f, 0x2091,
+	0x8001, 0x007c, 0x007e, 0x107e, 0x127e, 0x2091, 0x2300, 0x1078,
+	0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c, 0x007e,
+	0x107e, 0x127e, 0x2091, 0x2300, 0x1078, 0x298a, 0x2091, 0x2400,
+	0x1078, 0x298a, 0x127f, 0x107f, 0x007f, 0x2091, 0x8001, 0x007c,
+	0x007e, 0x107e, 0x127e, 0x0d7e, 0x0e7e, 0x0f7e, 0x2079, 0x4e00,
+	0x2071, 0x0200, 0x2069, 0x4e40, 0x3d00, 0xd08c, 0x0040, 0x1466,
+	0x70ec, 0xa084, 0x1c00, 0x78e2, 0x1078, 0x4cdd, 0x3d00, 0xd084,
+	0x0040, 0x1474, 0x2069, 0x4e80, 0x2071, 0x0100, 0x70ec, 0xa084,
+	0x1c00, 0x78e6, 0x1078, 0x4cdd, 0x0f7f, 0x0e7f, 0x0d7f, 0x127f,
+	0x107f, 0x007f, 0x007c, 0x7008, 0x800b, 0x00c8, 0x1489, 0x7007,
+	0x0002, 0xa08c, 0x01e0, 0x00c0, 0x148a, 0xd09c, 0x0040, 0x1489,
+	0x087a, 0x097a, 0x70c3, 0x4002, 0x0078, 0x15bd, 0x0068, 0x1513,
+	0x2061, 0x0000, 0x6018, 0xd084, 0x00c0, 0x1513, 0x7828, 0xa005,
+	0x00c0, 0x149e, 0x0010, 0x1514, 0x0078, 0x1513, 0x7910, 0xd1f4,
+	0x0040, 0x14a6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x7914, 0xd1ec,
+	0x0040, 0x14c1, 0xd0fc, 0x0040, 0x14b7, 0x007e, 0x1078, 0x1d64,
+	0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078, 0x15bc, 0x007e,
+	0x1078, 0x1d54, 0x007f, 0x0040, 0x14c1, 0x2001, 0x4007, 0x0078,
+	0x15bc, 0x7910, 0xd0fc, 0x00c0, 0x14cb, 0x2061, 0x4e40, 0xc19c,
+	0xc7fc, 0x0078, 0x14cf, 0x2061, 0x4e80, 0xc19d, 0xc7fd, 0x6064,
+	0xa005, 0x00c0, 0x1513, 0x7912, 0x6083, 0x0000, 0x7828, 0xc0fc,
+	0xa086, 0x0018, 0x00c0, 0x14e0, 0x0c7e, 0x1078, 0x1b5b, 0x0c7f,
+	0x782b, 0x0000, 0x607c, 0xa065, 0x0040, 0x14f9, 0x0c7e, 0x609c,
+	0x1078, 0x1e49, 0x0c7f, 0x609f, 0x0000, 0x1078, 0x1c84, 0x2009,
+	0x0018, 0x6087, 0x0103, 0x1078, 0x1d74, 0x00c0, 0x150d, 0x1078,
+	0x1dc6, 0x7810, 0xd09c, 0x00c0, 0x1501, 0x2061, 0x4e40, 0x0078,
+	0x1505, 0x2061, 0x4e80, 0xc09c, 0x7812, 0x607f, 0x0000, 0x60d4,
+	0xd0dc, 0x0040, 0x1511, 0xc0dc, 0x60d6, 0x2001, 0x4005, 0x0078,
+	0x15bc, 0x0078, 0x15ba, 0x007c, 0x7810, 0xd0f4, 0x0040, 0x151c,
+	0x2001, 0x4007, 0x0078, 0x15bc, 0xa006, 0x70c2, 0x70c6, 0x70ca,
+	0x70ce, 0x70da, 0x70c0, 0xa03d, 0xa08a, 0x0040, 0x00c8, 0x152a,
+	0x0079, 0x1531, 0x2100, 0xa08a, 0x0040, 0x00c8, 0x15c8, 0x0079,
+	0x1571, 0x15ba, 0x1610, 0x15d9, 0x1648, 0x1680, 0x1680, 0x15d0,
+	0x1c9c, 0x168b, 0x15c8, 0x15dd, 0x15df, 0x15e1, 0x15e3, 0x1ca1,
+	0x15c8, 0x1699, 0x16f6, 0x1b7b, 0x1c96, 0x15e5, 0x19c0, 0x1a02,
+	0x1a3d, 0x1a8e, 0x197b, 0x1988, 0x199c, 0x19af, 0x17cb, 0x15c8,
+	0x172d, 0x173a, 0x1746, 0x1752, 0x1768, 0x1774, 0x1777, 0x1783,
+	0x178f, 0x1797, 0x17b3, 0x17bf, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
+	0x17d8, 0x17ea, 0x1806, 0x183c, 0x1864, 0x1874, 0x1877, 0x18a8,
+	0x18d9, 0x18eb, 0x194a, 0x195a, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
+	0x196a, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x1cc6, 0x1ccc,
+	0x15c8, 0x15c8, 0x15c8, 0x1cd0, 0x1d15, 0x15c8, 0x15c8, 0x15c8,
+	0x15c8, 0x160a, 0x167a, 0x1693, 0x16f0, 0x1b75, 0x15c8, 0x15c8,
+	0x1b3e, 0x15c8, 0x1d19, 0x1cb8, 0x1cc2, 0x15c8, 0x15c8, 0x15c8,
+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
+	0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8, 0x15c8,
+	0x15c8, 0x72ca, 0x71c6, 0x2001, 0x4006, 0x0078, 0x15bc, 0x73ce,
+	0x72ca, 0x71c6, 0x2001, 0x4000, 0x70c2, 0x0068, 0x15bd, 0x2061,
+	0x0000, 0x601b, 0x0001, 0x2091, 0x5000, 0x2091, 0x4080, 0x007c,
+	0x70c3, 0x4001, 0x0078, 0x15bd, 0x70c3, 0x4006, 0x0078, 0x15bd,
+	0x2099, 0x0041, 0x20a1, 0x0041, 0x20a9, 0x0005, 0x53a3, 0x0078,
+	0x15ba, 0x70c4, 0x70c3, 0x0004, 0x007a, 0x0078, 0x15ba, 0x0078,
+	0x15ba, 0x0078, 0x15ba, 0x0078, 0x15ba, 0x2091, 0x8000, 0x70c3,
+	0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
+	0x0008, 0x2001, 0x000f, 0x70d6, 0x2079, 0x0000, 0x781b, 0x0001,
+	0x2031, 0x0030, 0x2059, 0x1000, 0x2029, 0x041a, 0x2051, 0x0445,
+	0x2061, 0x0447, 0x20c1, 0x0020, 0x2091, 0x5000, 0x2091, 0x4080,
+	0x0078, 0x0418, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x1613,
+	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x20a0,
+	0x2099, 0x0030, 0x7003, 0x0001, 0x7007, 0x0006, 0x731a, 0x721e,
+	0x7422, 0x7526, 0x2021, 0x0040, 0x81ff, 0x0040, 0x15ba, 0xa182,
+	0x0040, 0x00c8, 0x162d, 0x2120, 0xa006, 0x2008, 0x8403, 0x7012,
+	0x7007, 0x0004, 0x7007, 0x0001, 0x7008, 0xd0fc, 0x0040, 0x1634,
+	0x7007, 0x0002, 0xa084, 0x01e0, 0x0040, 0x1642, 0x70c3, 0x4002,
+	0x0078, 0x15bd, 0x24a8, 0x53a5, 0x0078, 0x1624, 0x0078, 0x15ba,
+	0x2029, 0x0000, 0x2520, 0x71d0, 0x72c8, 0x73cc, 0x70c4, 0x2098,
+	0x20a1, 0x0030, 0x7003, 0x0000, 0x7007, 0x0006, 0x731a, 0x721e,
+	0x7422, 0x7526, 0x2021, 0x0040, 0x7007, 0x0006, 0x81ff, 0x0040,
+	0x15ba, 0xa182, 0x0040, 0x00c8, 0x1667, 0x2120, 0xa006, 0x2008,
+	0x8403, 0x7012, 0x24a8, 0x53a6, 0x7007, 0x0001, 0x7008, 0xd0fc,
+	0x0040, 0x166e, 0xa084, 0x01e0, 0x0040, 0x165c, 0x70c3, 0x4002,
+	0x0078, 0x15bd, 0x75d8, 0x74dc, 0x75da, 0x74de, 0x0078, 0x164b,
+	0x71c4, 0x70c8, 0x2114, 0xa79e, 0x0004, 0x00c0, 0x1688, 0x200a,
+	0x72ca, 0x0078, 0x15b9, 0x70c7, 0x0008, 0x70cb, 0x000f, 0x70cf,
+	0x0000, 0x0078, 0x15ba, 0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078,
+	0x169c, 0x2029, 0x0000, 0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d0,
+	0x70c6, 0x72ca, 0x73ce, 0x74d2, 0xa005, 0x0040, 0x16eb, 0xa40a,
+	0x0040, 0x16ac, 0x00c8, 0x16b5, 0x8001, 0x7872, 0xa084, 0xfc00,
+	0x0040, 0x16b9, 0x78ac, 0xc085, 0x78ae, 0x2001, 0x4005, 0x0078,
+	0x15bc, 0x7b7e, 0x7a7a, 0x7e86, 0x7d82, 0x7c76, 0xa48c, 0xff00,
+	0x0040, 0x16d1, 0x8407, 0x8004, 0x8004, 0x810c, 0x810c, 0x810f,
+	0xa118, 0xa291, 0x0000, 0xa6b1, 0x0000, 0xa581, 0x0000, 0x0078,
+	0x16db, 0x8407, 0x8004, 0x8004, 0xa318, 0xa291, 0x0000, 0xa6b1,
+	0x0000, 0xa581, 0x0000, 0x731a, 0x721e, 0x7622, 0x7026, 0xa605,
+	0x0040, 0x16e5, 0x7a10, 0xc2c5, 0x7a12, 0x78ac, 0xa084, 0xfffc,
+	0x78ae, 0x0078, 0x16ee, 0x78ac, 0xc085, 0x78ae, 0x0078, 0x15ba,
+	0x75d8, 0x76dc, 0x75da, 0x76de, 0x0078, 0x16f9, 0x2029, 0x0000,
+	0x2530, 0x70c4, 0x72c8, 0x73cc, 0x74d4, 0x70c6, 0x72ca, 0x73ce,
+	0x74d6, 0xa005, 0x0040, 0x1728, 0xa40a, 0x0040, 0x1709, 0x00c8,
+	0x15bc, 0x8001, 0x7892, 0xa084, 0xfc00, 0x0040, 0x1716, 0x78ac,
+	0xc0c5, 0x78ae, 0x2001, 0x4005, 0x0078, 0x15bc, 0x7a9a, 0x7b9e,
+	0x7da2, 0x7ea6, 0x2600, 0xa505, 0x0040, 0x1721, 0x7a10, 0xc2c5,
+	0x7a12, 0x7c96, 0x78ac, 0xa084, 0xfcff, 0x78ae, 0x0078, 0x172b,
+	0x78ac, 0xc0c5, 0x78ae, 0x0078, 0x15ba, 0x2009, 0x0000, 0x786c,
+	0xa065, 0x0040, 0x1737, 0x8108, 0x6000, 0x0078, 0x1730, 0x7ac4,
+	0x0078, 0x15b8, 0x2009, 0x4e48, 0x210c, 0x7810, 0xd0ec, 0x00c0,
+	0x15b9, 0x2011, 0x4e88, 0x2214, 0x0078, 0x15b8, 0x2009, 0x4e49,
+	0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e89, 0x2214,
+	0x0078, 0x15b8, 0x2061, 0x4e40, 0x6128, 0x622c, 0x8214, 0x8214,
+	0x8214, 0x7810, 0xd0ec, 0x00c0, 0x1766, 0x2061, 0x4e80, 0x6328,
+	0x73da, 0x632c, 0x831c, 0x831c, 0x831c, 0x73de, 0x0078, 0x15b8,
+	0x2009, 0x4e4c, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011,
+	0x4e8c, 0x2214, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x2009,
+	0x4e4d, 0x210c, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2011, 0x4e8d,
+	0x2214, 0x0078, 0x15b8, 0x2009, 0x4e4e, 0x210c, 0x7810, 0xd0ec,
+	0x00c0, 0x15b9, 0x2011, 0x4e8e, 0x2214, 0x0078, 0x15b8, 0x7920,
+	0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x7a24, 0x0078, 0x15b8, 0x71c4,
+	0xd1fc, 0x00c0, 0x179f, 0x2011, 0x52c0, 0x0078, 0x17a1, 0x2011,
+	0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xa268,
+	0x6a00, 0x6804, 0xd09c, 0x0040, 0x17b0, 0x6b08, 0x0078, 0x17b1,
+	0x6b0c, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
+	0x6b1c, 0x6a14, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b7, 0x2061,
+	0x4e40, 0x6118, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80,
+	0x6218, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
+	0x6908, 0x6a18, 0x6b10, 0x77da, 0x2091, 0x8001, 0x0078, 0x15b7,
+	0x71c4, 0x2110, 0xa294, 0x000f, 0xa282, 0x0010, 0x00c8, 0x15b2,
+	0x1078, 0x277f, 0xa384, 0x4000, 0x0040, 0x17e8, 0xa295, 0x0020,
+	0x0078, 0x15b7, 0x71c4, 0x2100, 0xc0bc, 0xa082, 0x0010, 0x00c8,
+	0x15b2, 0xd1bc, 0x00c0, 0x17f9, 0x2011, 0x4e48, 0x2204, 0x0078,
+	0x17fd, 0x2011, 0x4e88, 0x2204, 0xc0bd, 0x007e, 0x2100, 0xc0bc,
+	0x2012, 0x1078, 0x26dc, 0x017f, 0x0078, 0x15b9, 0x71c4, 0x2021,
+	0x4e49, 0x2404, 0x70c6, 0x2019, 0x0000, 0x0078, 0x1815, 0x71c8,
+	0x2021, 0x4e89, 0x2404, 0x70ca, 0xc3fd, 0x2011, 0x1834, 0x20a9,
+	0x0008, 0x2204, 0xa106, 0x0040, 0x1824, 0x8210, 0x00f0, 0x1819,
+	0x71c4, 0x72c8, 0x0078, 0x15b1, 0xa292, 0x1834, 0x027e, 0x2122,
+	0x017f, 0x1078, 0x26fd, 0x7810, 0xd0ec, 0x00c0, 0x1832, 0xd3fc,
+	0x0040, 0x180f, 0x0078, 0x15ba, 0x03e8, 0x00fa, 0x01f4, 0x02ee,
+	0x0004, 0x0001, 0x0002, 0x0003, 0x2061, 0x4e40, 0x6128, 0x622c,
+	0x8214, 0x8214, 0x8214, 0x70c4, 0x602a, 0x70c8, 0x8003, 0x8003,
+	0x8003, 0x602e, 0x7810, 0xd0ec, 0x00c0, 0x1862, 0x027e, 0x017e,
+	0x2061, 0x4e80, 0x6128, 0x622c, 0x8214, 0x8214, 0x8214, 0x70d8,
+	0x602a, 0x70dc, 0x8003, 0x8003, 0x8003, 0x602e, 0x71da, 0x72de,
+	0x017f, 0x027f, 0x0078, 0x15b8, 0x2061, 0x4e40, 0x6130, 0x70c4,
+	0x6032, 0x7810, 0xd0ec, 0x00c0, 0x15b9, 0x2061, 0x4e80, 0x6230,
+	0x70c8, 0x6032, 0x0078, 0x15b8, 0x7918, 0x0078, 0x15b9, 0x71c4,
+	0xa184, 0xffcf, 0x0040, 0x1883, 0x7810, 0xd0ec, 0x00c0, 0x15b2,
+	0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4d, 0x2204, 0x2112, 0x007e,
+	0x2019, 0x0000, 0x1078, 0x2764, 0x7810, 0xd0ec, 0x0040, 0x1893,
+	0x017f, 0x0078, 0x15b9, 0x71c8, 0xa184, 0xffcf, 0x0040, 0x189c,
+	0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8d, 0x2204, 0x2112,
+	0x007e, 0xc3fd, 0x1078, 0x2764, 0x027f, 0x017f, 0x0078, 0x15b8,
+	0x71c4, 0xa182, 0x0010, 0x0048, 0x18b4, 0x7810, 0xd0ec, 0x00c0,
+	0x15b2, 0x72c8, 0x0078, 0x15b1, 0x2011, 0x4e4e, 0x2204, 0x007e,
+	0x2112, 0x2019, 0x0000, 0x1078, 0x2742, 0x7810, 0xd0ec, 0x0040,
+	0x18c4, 0x017f, 0x0078, 0x15b9, 0x71c8, 0xa182, 0x0010, 0x0048,
+	0x18cd, 0x2110, 0x71c4, 0x0078, 0x15b1, 0x2011, 0x4e8e, 0x2204,
+	0x007e, 0x2112, 0xc3fd, 0x1078, 0x2742, 0x027f, 0x017f, 0x0078,
+	0x15b8, 0x71c4, 0x72c8, 0xa184, 0xfffd, 0x00c0, 0x15b1, 0xa284,
+	0xfffd, 0x00c0, 0x15b1, 0x2100, 0x7920, 0x7822, 0x2200, 0x7a24,
+	0x7826, 0x0078, 0x15b8, 0x71c4, 0xd1fc, 0x00c0, 0x18f3, 0x2011,
+	0x52c0, 0x0078, 0x18f5, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f,
+	0x8003, 0x8003, 0x8003, 0xa268, 0x2019, 0x0000, 0x72c8, 0x2091,
+	0x8000, 0x6800, 0x007e, 0xa226, 0x0040, 0x191e, 0x6a02, 0xd4ec,
+	0x0040, 0x190b, 0xc3a5, 0xd4e4, 0x0040, 0x190f, 0xc39d, 0xd4f4,
+	0x0040, 0x191e, 0x810f, 0xd2f4, 0x0040, 0x191a, 0x1078, 0x27c1,
+	0x0078, 0x191e, 0x1078, 0x279f, 0x0078, 0x191e, 0x72cc, 0x6808,
+	0xa206, 0x0040, 0x1940, 0xa2a4, 0x00ff, 0x7814, 0xd0e4, 0x00c0,
+	0x1931, 0xa482, 0x0028, 0x0048, 0x193d, 0x0040, 0x193d, 0x0078,
+	0x1935, 0xa482, 0x0043, 0x0048, 0x193d, 0x71c4, 0x71c6, 0x027f,
+	0x72ca, 0x2091, 0x8001, 0x0078, 0x15b3, 0x6a0a, 0xa39d, 0x000a,
+	0x6804, 0xa305, 0x6806, 0x027f, 0x6b0c, 0x71c4, 0x2091, 0x8001,
+	0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a14,
+	0x6b1c, 0x2091, 0x8001, 0x70c8, 0x6816, 0x70cc, 0x681e, 0x2708,
+	0x0078, 0x15b7, 0x70c4, 0x2061, 0x4e40, 0x6118, 0x601a, 0x7810,
+	0xd0ec, 0x00c0, 0x15b9, 0x70c8, 0x2061, 0x4e80, 0x6218, 0x601a,
+	0x0078, 0x15b8, 0x71c4, 0x72c8, 0x73cc, 0xa182, 0x0010, 0x00c8,
+	0x15b2, 0x1078, 0x27e3, 0xa384, 0x4000, 0x0040, 0x1979, 0xa295,
+	0x0020, 0x0078, 0x15b7, 0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000,
+	0x6a08, 0xc28d, 0x6a0a, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8,
+	0x77c4, 0x1078, 0x1de4, 0x2091, 0x8000, 0x6a08, 0xa294, 0xfff9,
+	0x6a0a, 0x6804, 0xa005, 0x0040, 0x1997, 0x1078, 0x2628, 0x2091,
+	0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4, 0x1078, 0x1de4, 0x2091,
+	0x8000, 0x6a08, 0xc295, 0x6a0a, 0x6804, 0xa005, 0x0040, 0x19aa,
+	0x1078, 0x2628, 0x2091, 0x8001, 0x2708, 0x0078, 0x15b8, 0x77c4,
+	0x2041, 0x0001, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000,
+	0x1078, 0x1dff, 0x2091, 0x8001, 0x2708, 0x6a08, 0x0078, 0x15b8,
+	0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x19d4, 0xd7fc, 0x0040, 0x19ce,
+	0x1078, 0x1d64, 0x0040, 0x19d4, 0x0078, 0x15bc, 0x1078, 0x1d54,
+	0x0040, 0x19d4, 0x0078, 0x15bc, 0x73c8, 0x72cc, 0x77c6, 0x73ca,
+	0x72ce, 0x1078, 0x1e86, 0x00c0, 0x19fe, 0x6818, 0xa005, 0x0040,
+	0x19f8, 0x2708, 0x077e, 0x1078, 0x2813, 0x077f, 0x00c0, 0x19f8,
+	0x2001, 0x0015, 0xd7fc, 0x00c0, 0x19f1, 0x2061, 0x4e40, 0x0078,
+	0x19f4, 0xc0fd, 0x2061, 0x4e80, 0x782a, 0x2091, 0x8001, 0x007c,
+	0x2091, 0x8001, 0x2001, 0x4005, 0x0078, 0x15bc, 0x2091, 0x8001,
+	0x0078, 0x15ba, 0x77c4, 0x7814, 0xd0e4, 0x00c0, 0x1a16, 0xd7fc,
+	0x0040, 0x1a10, 0x1078, 0x1d64, 0x0040, 0x1a16, 0x0078, 0x15bc,
+	0x1078, 0x1d54, 0x0040, 0x1a16, 0x0078, 0x15bc, 0x77c6, 0x2041,
+	0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x2091, 0x8000, 0x1078,
+	0x1dff, 0x2009, 0x0016, 0xd7fc, 0x00c0, 0x1a2a, 0x2061, 0x4e40,
+	0x0078, 0x1a2d, 0x2061, 0x4e80, 0xc1fd, 0x6067, 0x0003, 0x607f,
+	0x0000, 0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6,
+	0x1078, 0x2628, 0x2091, 0x8001, 0x007c, 0x77c8, 0x77ca, 0x77c4,
+	0x77c6, 0x7814, 0xd0e4, 0x00c0, 0x1a54, 0xd7fc, 0x0040, 0x1a4e,
+	0x1078, 0x1d64, 0x0040, 0x1a54, 0x0078, 0x15bc, 0x1078, 0x1d54,
+	0x0040, 0x1a54, 0x0078, 0x15bc, 0xa7bc, 0xff00, 0x2091, 0x8000,
+	0x2009, 0x0017, 0xd7fc, 0x00c0, 0x1a61, 0x2061, 0x4e40, 0x0078,
+	0x1a64, 0x2061, 0x4e80, 0xc1fd, 0x607f, 0x0000, 0x6067, 0x0002,
+	0x6776, 0x6083, 0x000f, 0x792a, 0x61d4, 0xc1dc, 0x61d6, 0x1078,
+	0x2628, 0x2091, 0x8001, 0x2041, 0x0021, 0x2049, 0x0005, 0x2051,
+	0x0010, 0x2091, 0x8000, 0x70c8, 0xa005, 0x0040, 0x1a82, 0x60d4,
+	0xc0fd, 0x60d6, 0x1078, 0x1dff, 0x70c8, 0x6836, 0x8738, 0xa784,
+	0x001f, 0x00c0, 0x1a82, 0x2091, 0x8001, 0x007c, 0x2019, 0x0000,
+	0x7814, 0xd0e4, 0x00c0, 0x1aa4, 0x72c8, 0xd284, 0x0040, 0x1a9e,
+	0x1078, 0x1d64, 0x0040, 0x1aa4, 0x0078, 0x15bc, 0x1078, 0x1d54,
+	0x0040, 0x1aa4, 0x0078, 0x15bc, 0x72c8, 0x72ca, 0x78ac, 0xa084,
+	0x0003, 0x00c0, 0x1acf, 0x2039, 0x0000, 0xd284, 0x0040, 0x1ab1,
+	0xc7fd, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0008, 0x1078,
+	0x1de4, 0x2091, 0x8000, 0x6808, 0xc0d4, 0xa80d, 0x690a, 0x2091,
+	0x8001, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1ab7, 0xa7bc, 0xff00,
+	0x873f, 0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ab7, 0x2091,
+	0x8000, 0x72c8, 0xd284, 0x00c0, 0x1ae1, 0x7810, 0xd0ec, 0x0040,
+	0x1add, 0x2069, 0x0100, 0x0078, 0x1ae3, 0x2069, 0x0200, 0x0078,
+	0x1ae3, 0x2069, 0x0100, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830,
+	0xd0b4, 0x0040, 0x1b03, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
+	0xd094, 0x0040, 0x1af5, 0x00f0, 0x1aef, 0x684b, 0x0009, 0x20a9,
+	0x0014, 0x6848, 0xd084, 0x0040, 0x1aff, 0x00f0, 0x1af9, 0x20a9,
+	0x00fa, 0x00f0, 0x1b01, 0x2079, 0x4e00, 0x2009, 0x0018, 0x72c8,
+	0xd284, 0x00c0, 0x1b0f, 0x2061, 0x4e40, 0x0078, 0x1b12, 0x2061,
+	0x4e80, 0xc1fd, 0x607f, 0x0000, 0x792a, 0x6067, 0x0001, 0x6083,
+	0x000f, 0x60a7, 0x0000, 0x60a8, 0x60b2, 0x60b6, 0x60d4, 0xd0b4,
+	0x0040, 0x1b2e, 0xc0b4, 0x60d6, 0x0c7e, 0x60b8, 0xa065, 0x6008,
+	0xc0d4, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x60d4, 0xa084,
+	0x77ff, 0x60d6, 0x78ac, 0xc08d, 0x78ae, 0x83ff, 0x0040, 0x1b39,
+	0x007c, 0x681b, 0x0047, 0x2091, 0x8001, 0x007c, 0x73cc, 0x1078,
+	0x1a90, 0x69ec, 0x6a48, 0xa185, 0x1800, 0x684a, 0xa185, 0x0040,
+	0x68ee, 0x73cc, 0x2021, 0x0004, 0x20a9, 0x09ff, 0x00f0, 0x1b4e,
+	0x8421, 0x00c0, 0x1b4c, 0x8319, 0x00c0, 0x1b4a, 0x69ee, 0x6a4a,
+	0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x1b62, 0x2069, 0x4e40,
+	0x0078, 0x1b64, 0x2069, 0x4e80, 0x71c4, 0x71c6, 0x6916, 0x81ff,
+	0x00c0, 0x1b6c, 0x68a7, 0x0001, 0x78ac, 0xc08c, 0x78ae, 0xd084,
+	0x00c0, 0x1b74, 0x1078, 0x1ee6, 0x007c, 0x75d8, 0x74dc, 0x75da,
+	0x74de, 0x0078, 0x1b7e, 0x2029, 0x0000, 0x2520, 0x71c4, 0x73c8,
+	0x72cc, 0x71c6, 0x73ca, 0x72ce, 0x2079, 0x4e00, 0x7dde, 0x7cda,
+	0x7bd6, 0x7ad2, 0x1078, 0x1dbd, 0x0040, 0x1c80, 0x20a9, 0x0005,
+	0x20a1, 0x4e14, 0x2091, 0x8000, 0x41a1, 0x2091, 0x8001, 0x2009,
+	0x0040, 0x1078, 0x1fd1, 0x0040, 0x1ba1, 0x1078, 0x1dc6, 0x0078,
+	0x1c80, 0x6004, 0xa08c, 0x00ff, 0xa18e, 0x0009, 0x00c0, 0x1bac,
+	0x007e, 0x1078, 0x2378, 0x007f, 0xa084, 0xff00, 0x8007, 0x8009,
+	0x0040, 0x1c20, 0x0c7e, 0x2c68, 0x1078, 0x1dbd, 0x0040, 0x1bf2,
+	0x2c00, 0x689e, 0x8109, 0x00c0, 0x1bb3, 0x609f, 0x0000, 0x0c7f,
+	0x0c7e, 0x7ddc, 0x7cd8, 0x7bd4, 0x7ad0, 0xa290, 0x0040, 0xa399,
+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x7dde, 0x7cda, 0x7bd6,
+	0x7ad2, 0x2c68, 0x689c, 0xa065, 0x0040, 0x1c1f, 0x2009, 0x0040,
+	0x1078, 0x1fd1, 0x00c0, 0x1c09, 0x6004, 0xa084, 0x00ff, 0xa086,
+	0x0002, 0x00c0, 0x1bf2, 0x6004, 0xa084, 0x00ff, 0xa086, 0x000a,
+	0x00c0, 0x1bee, 0x017e, 0x1078, 0x2374, 0x017f, 0x2d00, 0x6002,
+	0x0078, 0x1bc1, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f,
+	0x609f, 0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6008, 0xc0cd,
+	0x600a, 0x6004, 0x6086, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078,
+	0x1c80, 0x0c7f, 0x0c7e, 0x609c, 0x1078, 0x1e49, 0x0c7f, 0x609f,
+	0x0000, 0x1078, 0x1c84, 0x2009, 0x0018, 0x6087, 0x0103, 0x601b,
+	0x0003, 0x1078, 0x1d74, 0x1078, 0x1dc6, 0x0078, 0x1c80, 0x0c7f,
+	0x7814, 0xd0e4, 0x00c0, 0x1c45, 0x6114, 0xd1fc, 0x0040, 0x1c2e,
+	0x1078, 0x1d64, 0x0040, 0x1c45, 0x0078, 0x1c32, 0x1078, 0x1d54,
+	0x0040, 0x1c45, 0x2029, 0x0000, 0x2520, 0x2009, 0x0018, 0x73c8,
+	0x72cc, 0x6087, 0x0103, 0x601b, 0x0021, 0x1078, 0x1d74, 0x1078,
+	0x1dc6, 0x2001, 0x4007, 0x0078, 0x15bc, 0x74c4, 0x73c8, 0x72cc,
+	0x6014, 0x2091, 0x8000, 0x0e7e, 0x2009, 0x0012, 0xd0fc, 0x00c0,
+	0x1c55, 0x2071, 0x4e40, 0x0078, 0x1c58, 0x2071, 0x4e80, 0xc1fd,
+	0x792a, 0x7067, 0x0005, 0x71d4, 0xc1dc, 0x71d6, 0x736a, 0x726e,
+	0x7472, 0x7076, 0x707b, 0x0000, 0x2c00, 0x707e, 0xa02e, 0x2530,
+	0x611c, 0xa184, 0x0060, 0x0040, 0x1c6f, 0x1078, 0x4632, 0x0e7f,
+	0x6596, 0x65a6, 0x669a, 0x66aa, 0x60af, 0x0000, 0x60b3, 0x0000,
+	0x6714, 0x6023, 0x0000, 0x1078, 0x2628, 0x2091, 0x8001, 0x007c,
+	0x70c3, 0x4005, 0x0078, 0x15bd, 0x20a9, 0x0005, 0x2099, 0x4e14,
+	0x2091, 0x8000, 0x530a, 0x2091, 0x8001, 0x2100, 0xa210, 0xa399,
+	0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000, 0x007c, 0x71c4, 0x70c7,
+	0x0000, 0x791e, 0x0078, 0x15ba, 0x71c4, 0x71c6, 0x2168, 0x0078,
+	0x1ca3, 0x2069, 0x1000, 0x690c, 0xa016, 0x2d04, 0xa210, 0x8d68,
+	0x8109, 0x00c0, 0x1ca5, 0xa285, 0x0000, 0x00c0, 0x1cb3, 0x70c3,
+	0x4000, 0x0078, 0x1cb5, 0x70c3, 0x4003, 0x70ca, 0x0078, 0x15bd,
+	0x7964, 0x71c6, 0x71c4, 0xa182, 0x0003, 0x00c8, 0x15b2, 0x7966,
+	0x0078, 0x15ba, 0x7964, 0x71c6, 0x0078, 0x15ba, 0x7900, 0x71c6,
+	0x71c4, 0x7902, 0x0078, 0x15ba, 0x7900, 0x71c6, 0x0078, 0x15ba,
+	0x70c4, 0x2011, 0x0000, 0xa08c, 0x000d, 0x0040, 0x1ce5, 0x810c,
+	0x0048, 0x1ce1, 0x8210, 0x810c, 0x810c, 0x0048, 0x1ce1, 0x8210,
+	0x810c, 0x81ff, 0x00c0, 0x15b3, 0x8210, 0x7a0e, 0xd28c, 0x0040,
+	0x1d11, 0x7910, 0xc1cd, 0x7912, 0x2009, 0x0021, 0x2019, 0x0003,
+	0xd284, 0x0040, 0x1d0b, 0x8108, 0x2019, 0x0041, 0x2011, 0x964e,
+	0x2312, 0x2019, 0x0042, 0x8210, 0x2312, 0x2019, 0x0043, 0x8210,
+	0x2312, 0x2019, 0x0046, 0x8210, 0x2312, 0x2019, 0x0047, 0x8210,
+	0x2312, 0x2019, 0x0006, 0x2011, 0x9653, 0x2112, 0x2011, 0x9673,
+	0x2312, 0x7904, 0x7806, 0x0078, 0x15b9, 0x7804, 0x70c6, 0x0078,
+	0x15ba, 0x71c4, 0xd1fc, 0x00c0, 0x1d21, 0x2011, 0x52c0, 0x0078,
+	0x1d23, 0x2011, 0x5340, 0x8107, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xa268, 0x6a14, 0xd2b4, 0x0040, 0x1d32, 0x2011, 0x0001,
+	0x0078, 0x1d34, 0x2011, 0x0000, 0x6b0c, 0x6800, 0x70da, 0x0078,
+	0x15b7, 0x017e, 0x7814, 0xd0f4, 0x0040, 0x1d46, 0x2001, 0x4007,
+	0x70db, 0x0000, 0xa18d, 0x0001, 0x0078, 0x1d52, 0xd0fc, 0x0040,
+	0x1d51, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078,
+	0x1d52, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0f4, 0x0040,
+	0x1d61, 0x2001, 0x4007, 0x70db, 0x0000, 0xa18d, 0x0001, 0x0078,
+	0x1d62, 0xa006, 0x017f, 0x007c, 0x017e, 0x7814, 0xd0fc, 0x0040,
+	0x1d71, 0x2001, 0x4007, 0x70db, 0x0001, 0xa18d, 0x0001, 0x0078,
+	0x1d72, 0xa006, 0x017f, 0x007c, 0x7112, 0x721a, 0x731e, 0x7810,
+	0xd0c4, 0x0040, 0x1d7d, 0x7422, 0x7526, 0xac80, 0x0001, 0x8108,
+	0x810c, 0x81a9, 0x8098, 0x20a1, 0x0030, 0x7003, 0x0000, 0x6084,
+	0x20a2, 0x53a6, 0x7007, 0x0001, 0x7974, 0xa184, 0xff00, 0x0040,
+	0x1d9a, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
+	0x0078, 0x1d9d, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
+	0xa006, 0xa211, 0x7d10, 0xd5c4, 0x0040, 0x1daa, 0x7b84, 0xa319,
+	0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x1daa, 0x7003, 0x0001,
+	0x7007, 0x0006, 0x711a, 0x721e, 0x7d10, 0xd5c4, 0x0040, 0x1dba,
+	0x7322, 0x7426, 0xa084, 0x01e0, 0x007c, 0x7848, 0xa065, 0x0040,
+	0x1dc5, 0x2c04, 0x784a, 0x2063, 0x0000, 0x007c, 0x0f7e, 0x2079,
+	0x4e00, 0x7848, 0x2062, 0x2c00, 0xa005, 0x00c0, 0x1dd1, 0x1078,
+	0x296b, 0x784a, 0x0f7f, 0x007c, 0x2011, 0x9800, 0x7a4a, 0x7bc4,
+	0x8319, 0x0040, 0x1de1, 0xa280, 0x0032, 0x2012, 0x2010, 0x0078,
+	0x1dd8, 0x2013, 0x0000, 0x007c, 0x017e, 0x027e, 0xd7fc, 0x00c0,
+	0x1ded, 0x2011, 0x53c0, 0x0078, 0x1def, 0x2011, 0x73c0, 0xa784,
+	0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x1dfa, 0x8003, 0x8003,
+	0x8003, 0x8003, 0xa105, 0xa268, 0x027f, 0x017f, 0x007c, 0x1078,
+	0x1de4, 0x2900, 0x682a, 0x2a00, 0x682e, 0x6808, 0xa084, 0xf9ef,
+	0xa80d, 0x690a, 0x0e7e, 0xd7fc, 0x00c0, 0x1e14, 0x2009, 0x4e53,
+	0x2071, 0x4e40, 0x0078, 0x1e18, 0x2009, 0x4e93, 0x2071, 0x4e80,
+	0x210c, 0x6804, 0xa005, 0x0040, 0x1e28, 0xa116, 0x00c0, 0x1e28,
+	0x2060, 0x6000, 0x6806, 0x017e, 0x200b, 0x0000, 0x0078, 0x1e2b,
+	0x2009, 0x0000, 0x017e, 0x6804, 0xa065, 0x0040, 0x1e40, 0x6000,
+	0x6806, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x6810, 0x7908, 0x8109,
+	0x790a, 0x8001, 0x6812, 0x00c0, 0x1e2b, 0x7910, 0xc1a5, 0x7912,
+	0x017f, 0x6902, 0x6906, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x0e7f,
+	0x007c, 0xa065, 0x0040, 0x1e5a, 0x2008, 0x609c, 0xa005, 0x0040,
+	0x1e57, 0x2062, 0x609f, 0x0000, 0xa065, 0x0078, 0x1e4d, 0x7848,
+	0x794a, 0x2062, 0x007c, 0x6007, 0x0103, 0x608f, 0x0000, 0x20a9,
+	0x001c, 0xac80, 0x0005, 0x20a0, 0x2001, 0x0000, 0x40a4, 0x6828,
+	0x601a, 0x682c, 0x6022, 0x007c, 0x0e7e, 0xd7fc, 0x00c0, 0x1e76,
+	0x2071, 0x4e40, 0x2031, 0x4ec0, 0x0078, 0x1e7a, 0x2071, 0x4e80,
+	0x2031, 0x50c0, 0x7050, 0xa08c, 0x0200, 0x00c0, 0x1e84, 0xa608,
+	0x2d0a, 0x8000, 0x7052, 0xa006, 0x0e7f, 0x007c, 0x0f7e, 0xd7fc,
+	0x00c0, 0x1e8e, 0x2079, 0x4e40, 0x0078, 0x1e90, 0x2079, 0x4e80,
+	0x1078, 0x1de4, 0x2091, 0x8000, 0x6804, 0x780a, 0xa065, 0x0040,
+	0x1ee4, 0x0078, 0x1ea2, 0x2c00, 0x780a, 0x2060, 0x6000, 0xa065,
+	0x0040, 0x1ee4, 0x6010, 0xa306, 0x00c0, 0x1e9b, 0x600c, 0xa206,
+	0x00c0, 0x1e9b, 0x2c28, 0x784c, 0xac06, 0x00c0, 0x1eb1, 0x0078,
+	0x1ee1, 0x6804, 0xac06, 0x00c0, 0x1ebf, 0x6000, 0x2060, 0x6806,
+	0xa005, 0x00c0, 0x1ebf, 0x6803, 0x0000, 0x0078, 0x1ec9, 0x6400,
+	0x7808, 0x2060, 0x6402, 0xa486, 0x0000, 0x00c0, 0x1ec9, 0x2c00,
+	0x6802, 0x2560, 0x0f7f, 0x1078, 0x1e5b, 0x0f7e, 0x601b, 0x0005,
+	0x6023, 0x0020, 0x0f7f, 0x1078, 0x201d, 0x0f7e, 0x7908, 0x8109,
+	0x790a, 0x6810, 0x8001, 0x6812, 0x00c0, 0x1ee1, 0x7810, 0xc0a5,
+	0x7812, 0x2001, 0xffff, 0xa005, 0x0f7f, 0x007c, 0x077e, 0x2700,
+	0x2039, 0x0000, 0xd0fc, 0x0040, 0x1eee, 0xc7fd, 0x2041, 0x0021,
+	0x2049, 0x0004, 0x2051, 0x0008, 0x2091, 0x8000, 0x1078, 0x1dff,
+	0x8738, 0xa784, 0x001f, 0x00c0, 0x1ef6, 0xa7bc, 0xff00, 0x873f,
+	0x8738, 0x873f, 0xa784, 0x0f00, 0x00c0, 0x1ef6, 0x2091, 0x8001,
+	0x077f, 0x007c, 0x786c, 0x2009, 0x9674, 0x210c, 0xa10d, 0x0040,
+	0x1f14, 0xa065, 0x0078, 0x2395, 0x2061, 0x0000, 0x6018, 0xd084,
+	0x00c0, 0x1f34, 0x7810, 0xd08c, 0x0040, 0x1f25, 0xc08c, 0x7812,
+	0xc7fc, 0x2069, 0x4e40, 0x0078, 0x1f2a, 0xc08d, 0x7812, 0x2069,
+	0x4e80, 0xc7fd, 0x2091, 0x8000, 0x681c, 0x681f, 0x0000, 0x2091,
+	0x8001, 0xa005, 0x00c0, 0x1f35, 0x007c, 0xa08c, 0xfff0, 0x0040,
+	0x1f3b, 0x1078, 0x296b, 0x0079, 0x1f3d, 0x1f4d, 0x1f50, 0x1f56,
+	0x1f5a, 0x1f4e, 0x1f5e, 0x1f4e, 0x1f4e, 0x1f4e, 0x1f64, 0x1f95,
+	0x1f99, 0x1f9f, 0x1fb4, 0x1f4e, 0x1f4e, 0x007c, 0x1078, 0x296b,
+	0x1078, 0x1ee6, 0x2001, 0x8001, 0x0078, 0x1fc0, 0x2001, 0x8003,
+	0x0078, 0x1fc0, 0x2001, 0x8004, 0x0078, 0x1fc0, 0x1078, 0x1ee6,
+	0x2001, 0x8006, 0x0078, 0x1fc0, 0x2091, 0x8000, 0x077e, 0xd7fc,
+	0x00c0, 0x1f70, 0x2069, 0x4e40, 0x2039, 0x0009, 0x0078, 0x1f74,
+	0x2069, 0x4e80, 0x2039, 0x0009, 0x6800, 0xa086, 0x0000, 0x0040,
+	0x1f7e, 0x007f, 0x6f1e, 0x2091, 0x8001, 0x007c, 0x6874, 0x077f,
+	0xa0bc, 0xff00, 0x2041, 0x0021, 0x2049, 0x0004, 0x2051, 0x0010,
+	0x1078, 0x1dff, 0x8738, 0xa784, 0x001f, 0x00c0, 0x1f88, 0x2091,
+	0x8001, 0x2001, 0x800a, 0x0078, 0x1fc0, 0x2001, 0x800c, 0x0078,
+	0x1fc0, 0x1078, 0x1ee6, 0x2001, 0x800d, 0x0078, 0x1fc0, 0x7814,
+	0xd0e4, 0x00c0, 0x1fb2, 0xd0ec, 0x0040, 0x1fac, 0xd7fc, 0x0040,
+	0x1fac, 0x78e4, 0x0078, 0x1fad, 0x78e0, 0x70c6, 0x2001, 0x800e,
+	0x0078, 0x1fc0, 0x0078, 0x1f4e, 0xd7fc, 0x0040, 0x1fba, 0x78ec,
+	0x0078, 0x1fbb, 0x78e8, 0x70c6, 0x2001, 0x800f, 0x0078, 0x1fc0,
+	0x70c2, 0xd7fc, 0x00c0, 0x1fc8, 0x70db, 0x0000, 0x0078, 0x1fca,
+	0x70db, 0x0001, 0x2061, 0x0000, 0x601b, 0x0001, 0x2091, 0x4080,
+	0x007c, 0xac80, 0x0001, 0x81ff, 0x0040, 0x1ffc, 0x2099, 0x0030,
+	0x20a0, 0x700c, 0xa084, 0x03ff, 0x0040, 0x1fde, 0x7018, 0x007e,
+	0x701c, 0x007e, 0x7020, 0x007e, 0x7024, 0x007e, 0x7112, 0x81ac,
+	0x721a, 0x731e, 0x7422, 0x7526, 0x7003, 0x0001, 0x7007, 0x0001,
+	0x7008, 0x800b, 0x00c8, 0x1ff0, 0x7007, 0x0002, 0xa08c, 0x01e0,
+	0x00c0, 0x1ffc, 0x53a5, 0xa006, 0x7003, 0x0000, 0x7007, 0x0004,
+	0x007f, 0x7026, 0x007f, 0x7022, 0x007f, 0x701e, 0x007f, 0x701a,
+	0x007c, 0x2011, 0x0020, 0x2009, 0x0010, 0x6b0a, 0x6c0e, 0x6803,
+	0xfd00, 0x6807, 0x0018, 0x6a1a, 0x2d00, 0xa0e8, 0x0008, 0xa290,
+	0x0004, 0x8109, 0x00c0, 0x200d, 0x007c, 0x6004, 0x6086, 0x2c08,
+	0x2063, 0x0000, 0x7868, 0xa005, 0x796a, 0x0040, 0x202a, 0x2c02,
+	0x0078, 0x202b, 0x796e, 0x007c, 0x0c7e, 0x2061, 0x4e00, 0x6887,
+	0x0103, 0x2d08, 0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040,
+	0x203c, 0x2d02, 0x0078, 0x203d, 0x616e, 0x0c7f, 0x007c, 0x2091,
+	0x8000, 0x2c04, 0x786e, 0xa005, 0x00c0, 0x2047, 0x786a, 0x2091,
+	0x8001, 0x609c, 0xa005, 0x0040, 0x2060, 0x0c7e, 0x2060, 0x2008,
+	0x609c, 0xa005, 0x0040, 0x205c, 0x2062, 0x609f, 0x0000, 0xa065,
+	0x609c, 0xa005, 0x00c0, 0x2054, 0x7848, 0x794a, 0x2062, 0x0c7f,
+	0x7848, 0x2062, 0x609f, 0x0000, 0xac85, 0x0000, 0x00c0, 0x206a,
+	0x1078, 0x296b, 0x784a, 0x007c, 0x20a9, 0x0010, 0xa006, 0x8004,
+	0x8086, 0x818e, 0x00c8, 0x2075, 0xa200, 0x00f0, 0x2070, 0x8086,
+	0x818e, 0x007c, 0x157e, 0x20a9, 0x0010, 0xa005, 0x0040, 0x209b,
+	0xa11a, 0x00c8, 0x209b, 0x8213, 0x818d, 0x0048, 0x208e, 0xa11a,
+	0x00c8, 0x208f, 0x00f0, 0x2083, 0x0078, 0x2093, 0xa11a, 0x2308,
+	0x8210, 0x00f0, 0x2083, 0x007e, 0x3200, 0xa084, 0xf7ff, 0x2080,
+	0x007f, 0x157f, 0x007c, 0x007e, 0x3200, 0xa085, 0x0800, 0x0078,
+	0x2097, 0x7d74, 0x70d0, 0xa506, 0x0040, 0x2187, 0x7810, 0x2050,
+	0x7800, 0xd08c, 0x0040, 0x20c3, 0xdaec, 0x0040, 0x20c3, 0x0e7e,
+	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x20c0,
+	0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x20c3, 0x0078, 0x2187,
+	0x0e7f, 0x0078, 0x2187, 0x1078, 0x1dbd, 0x0040, 0x2187, 0xa046,
+	0x7970, 0x2500, 0x8000, 0xa112, 0x2009, 0x0040, 0x00c8, 0x20d2,
+	0x0078, 0x20d9, 0x72d0, 0xa206, 0x0040, 0x20d9, 0x8840, 0x2009,
+	0x0080, 0x0c7e, 0x7112, 0x7007, 0x0001, 0x2099, 0x0030, 0x20a9,
+	0x0020, 0xac80, 0x0001, 0x20a0, 0x2061, 0x0000, 0x88ff, 0x0040,
+	0x20eb, 0x1078, 0x1dbd, 0x7008, 0xd0fc, 0x0040, 0x20eb, 0x7007,
+	0x0002, 0x2091, 0x8001, 0xa08c, 0x01e0, 0x00c0, 0x2122, 0x53a5,
+	0x8cff, 0x00c0, 0x2100, 0x88ff, 0x0040, 0x2171, 0x0078, 0x210a,
+	0x2c00, 0x788e, 0x20a9, 0x0020, 0xac80, 0x0001, 0x20a0, 0x53a5,
+	0x0078, 0x2171, 0xa046, 0x7218, 0x731c, 0xdac4, 0x0040, 0x2112,
+	0x7420, 0x7524, 0xa292, 0x0040, 0xa39b, 0x0000, 0xa4a3, 0x0000,
+	0xa5ab, 0x0000, 0x721a, 0x731e, 0xdac4, 0x0040, 0x2122, 0x7422,
+	0x7526, 0xa006, 0x7007, 0x0004, 0x0040, 0x2171, 0x8cff, 0x0040,
+	0x212b, 0x1078, 0x1dc6, 0x0c7f, 0x1078, 0x1dc6, 0xa046, 0x7888,
+	0x8000, 0x788a, 0xa086, 0x0002, 0x0040, 0x2151, 0x7a7c, 0x7b78,
+	0xdac4, 0x0040, 0x213d, 0x7c84, 0x7d80, 0x7974, 0x8107, 0x8004,
+	0x8004, 0xa210, 0xa399, 0x0000, 0xa4a1, 0x0000, 0xa5a9, 0x0000,
+	0x721a, 0x731e, 0xdac4, 0x0040, 0x2187, 0x7422, 0x7526, 0x0078,
+	0x2187, 0x6014, 0xd0fc, 0x00c0, 0x2159, 0x2069, 0x4e40, 0x0078,
+	0x215b, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0002, 0x88ff,
+	0x0040, 0x2167, 0xa046, 0x788c, 0x2060, 0x0078, 0x2151, 0x788b,
+	0x0000, 0x78ac, 0xa085, 0x0003, 0x78ae, 0x2091, 0x8001, 0x0078,
+	0x2187, 0x0c7f, 0x788b, 0x0000, 0x1078, 0x2346, 0x6004, 0xa084,
+	0x000f, 0x1078, 0x2188, 0x88ff, 0x0040, 0x2185, 0x788c, 0x2060,
+	0x6004, 0xa084, 0x000f, 0x1078, 0x2188, 0x0078, 0x20a1, 0x007c,
+	0x0079, 0x218a, 0x219a, 0x21b8, 0x21d6, 0x219a, 0x21e7, 0x21ab,
+	0x219a, 0x219a, 0x219a, 0x21b6, 0x21d4, 0x219a, 0x219a, 0x219a,
+	0x219a, 0x219a, 0x2039, 0x0400, 0x78bc, 0xa705, 0x78be, 0x6008,
+	0xa705, 0x600a, 0x1078, 0x222a, 0x609c, 0x78ba, 0x609f, 0x0000,
+	0x1078, 0x2330, 0x007c, 0x78bc, 0xd0c4, 0x0040, 0x21b1, 0x0078,
+	0x219a, 0x601c, 0xc0bd, 0x601e, 0x0078, 0x21be, 0x1078, 0x2378,
+	0x78bc, 0xd0c4, 0x0040, 0x21be, 0x0078, 0x219a, 0x78bf, 0x0000,
+	0x6004, 0x8007, 0xa084, 0x00ff, 0x78b2, 0x8001, 0x0040, 0x21d1,
+	0x1078, 0x222a, 0x0040, 0x21d1, 0x78bc, 0xc0c5, 0x78be, 0x0078,
+	0x21d3, 0x0078, 0x2249, 0x007c, 0x1078, 0x2374, 0x78bc, 0xa08c,
+	0x0e00, 0x00c0, 0x21de, 0xd0c4, 0x00c0, 0x21e0, 0x0078, 0x219a,
+	0x1078, 0x222a, 0x00c0, 0x21e6, 0x0078, 0x2249, 0x007c, 0x78bc,
+	0xd0c4, 0x0040, 0x21ed, 0x0078, 0x219a, 0x78bf, 0x0000, 0x6714,
+	0x2011, 0x0001, 0x22a8, 0x6018, 0xa084, 0x00ff, 0xa005, 0x0040,
+	0x220d, 0xa7bc, 0xff00, 0x20a9, 0x0020, 0xa08e, 0x0001, 0x0040,
+	0x220d, 0xa7bc, 0x8000, 0x2011, 0x0002, 0x20a9, 0x0100, 0xa08e,
+	0x0002, 0x0040, 0x220d, 0x0078, 0x2227, 0x1078, 0x1de4, 0x2d00,
+	0x2091, 0x8000, 0x682b, 0x0000, 0x682f, 0x0000, 0x6808, 0xa084,
+	0xffde, 0x680a, 0xade8, 0x0010, 0x2091, 0x8001, 0x00f0, 0x2210,
+	0x8211, 0x0040, 0x2227, 0x20a9, 0x0100, 0x0078, 0x2210, 0x1078,
+	0x1dc6, 0x007c, 0x609f, 0x0000, 0x78b4, 0xa06d, 0x2c00, 0x78b6,
+	0x00c0, 0x2235, 0x78ba, 0x0078, 0x223d, 0x689e, 0x2d00, 0x6002,
+	0x78b8, 0xad06, 0x00c0, 0x223d, 0x6002, 0x78b0, 0x8001, 0x78b2,
+	0x00c0, 0x2248, 0x78bc, 0xc0c4, 0x78be, 0x78b8, 0x2060, 0xa006,
+	0x007c, 0x0e7e, 0xa02e, 0x2530, 0x7dba, 0x7db6, 0x65ae, 0x65b2,
+	0x601c, 0x60a2, 0x2048, 0xa984, 0xe1ff, 0x601e, 0xa984, 0x0060,
+	0x0040, 0x225c, 0x1078, 0x4632, 0x6596, 0x65a6, 0x669a, 0x66aa,
+	0x6714, 0x2071, 0x4e80, 0xd7fc, 0x00c0, 0x2268, 0x2071, 0x4e40,
+	0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x0040, 0x2273, 0x8003,
+	0x8003, 0x8003, 0x8003, 0xa105, 0x71c4, 0xa168, 0x2700, 0x8007,
+	0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0x71c8, 0xa100, 0x60c2,
+	0x2091, 0x8000, 0x7814, 0xd0c4, 0x0040, 0x2298, 0xd0ec, 0x0040,
+	0x2294, 0xd7fc, 0x00c0, 0x2291, 0xd0f4, 0x00c0, 0x229f, 0x0078,
+	0x2298, 0xd0fc, 0x00c0, 0x229f, 0x7810, 0xd0f4, 0x00c0, 0x229f,
+	0x6e08, 0xd684, 0x0040, 0x22c9, 0xd9fc, 0x00c0, 0x22c9, 0x2091,
+	0x8001, 0x1078, 0x1e5b, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091,
+	0x8001, 0x7814, 0xd0e4, 0x00c0, 0x232e, 0x7814, 0xd0c4, 0x0040,
+	0x232e, 0xd0ec, 0x0040, 0x22c1, 0xd7fc, 0x00c0, 0x22bc, 0xd0f4,
+	0x00c0, 0x22c5, 0x0078, 0x232e, 0xd0fc, 0x00c0, 0x22c5, 0x0078,
+	0x232e, 0x7810, 0xd0f4, 0x0040, 0x232e, 0x601b, 0x0021, 0x0078,
+	0x232e, 0x6024, 0xa096, 0x0001, 0x00c0, 0x22d0, 0x8000, 0x6026,
+	0x6a10, 0x6814, 0xa202, 0x0048, 0x22e3, 0x0040, 0x22e3, 0x2091,
 	0x8001, 0x2039, 0x0200, 0x609c, 0x78ba, 0x609f, 0x0000, 0x1078,
-	0x2303, 0x0078, 0x2301, 0x2c08, 0xd9fc, 0x0040, 0x22de, 0x6800,
-	0xa065, 0x0040, 0x22de, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040,
-	0x22d9, 0x704c, 0xa206, 0x00c0, 0x22d9, 0x6b04, 0x2160, 0x2304,
-	0x6002, 0xa005, 0x00c0, 0x22d5, 0x6902, 0x2260, 0x6102, 0x0078,
-	0x22ea, 0x2160, 0x6202, 0x6906, 0x0078, 0x22ea, 0x6800, 0x6902,
-	0xa065, 0x0040, 0x22e6, 0x6102, 0x0078, 0x22e7, 0x6906, 0x2160,
-	0x6003, 0x0000, 0x2160, 0xd9fc, 0x0040, 0x22f1, 0xa6b4, 0xfffc,
-	0x6e0a, 0x6810, 0x7d08, 0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091,
-	0x8001, 0xd6b4, 0x0040, 0x2301, 0xa6b6, 0x0040, 0x6e0a, 0x1078,
-	0x1e80, 0x0e7f, 0x007c, 0x6008, 0xa705, 0x600a, 0x2091, 0x8000,
-	0x1078, 0x201b, 0x2091, 0x8001, 0x78b8, 0xa065, 0x0040, 0x2316,
-	0x609c, 0x78ba, 0x609f, 0x0000, 0x0078, 0x2303, 0x78b6, 0x78ba,
-	0x007c, 0x7970, 0x7874, 0x2818, 0xd384, 0x0040, 0x2323, 0x8000,
-	0xa112, 0x0048, 0x2328, 0x8000, 0xa112, 0x00c8, 0x2338, 0xc384,
-	0x7a7c, 0x721a, 0x7a78, 0x721e, 0xdac4, 0x0040, 0x2333, 0x7a84,
-	0x7222, 0x7a80, 0x7226, 0xa006, 0xd384, 0x0040, 0x2338, 0x8000,
-	0x7876, 0x70d2, 0x781c, 0xa005, 0x0040, 0x2346, 0x8001, 0x781e,
-	0x00c0, 0x2346, 0x0068, 0x2346, 0x2091, 0x4080, 0x007c, 0x2039,
-	0x235f, 0x0078, 0x234d, 0x2039, 0x2365, 0x2704, 0xa005, 0x0040,
-	0x235e, 0xac00, 0x2068, 0x6908, 0x6810, 0x6912, 0x680a, 0x690c,
-	0x6814, 0x6916, 0x680e, 0x8738, 0x0078, 0x234d, 0x007c, 0x0003,
-	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0015, 0x001b, 0x0000,
-	0x2041, 0x0000, 0x780c, 0x0079, 0x236d, 0x2535, 0x2508, 0x2371,
-	0x23e5, 0x2039, 0x9274, 0x2734, 0x7d10, 0x0078, 0x238c, 0x6084,
-	0xa086, 0x0103, 0x00c0, 0x23ce, 0x6114, 0x6018, 0xa105, 0x00c0,
-	0x23ce, 0x8603, 0xa080, 0x9255, 0x620c, 0x2202, 0x8000, 0x6210,
-	0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x000f, 0x0040, 0x2454,
-	0x786c, 0xa065, 0x00c0, 0x2377, 0x7808, 0xa602, 0x00c8, 0x239d,
-	0xd5ac, 0x00c0, 0x239d, 0x263a, 0x007c, 0xa682, 0x0003, 0x00c8,
-	0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0,
-	0x23c9, 0x2011, 0x9255, 0x2204, 0x70c6, 0x8210, 0x2204, 0x70ca,
-	0xd684, 0x00c0, 0x23b9, 0x8210, 0x2204, 0x70da, 0x8210, 0x2204,
-	0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001, 0x2091, 0x4080,
-	0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001, 0x203b, 0x0000,
-	0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078,
-	0x253f, 0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x2377, 0x2091,
-	0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x23e0, 0xc0ad,
-	0x7812, 0x2091, 0x8001, 0x0078, 0x254e, 0x2039, 0x9274, 0x2734,
-	0x7d10, 0x0078, 0x23fc, 0x6084, 0xa086, 0x0103, 0x00c0, 0x243d,
-	0x6114, 0x6018, 0xa105, 0x00c0, 0x243d, 0xa680, 0x9255, 0x620c,
-	0x2202, 0x1078, 0x203d, 0x8630, 0xa68e, 0x001e, 0x0040, 0x2454,
-	0x786c, 0xa065, 0x00c0, 0x23eb, 0x7808, 0xa602, 0x00c8, 0x240d,
-	0xd5ac, 0x00c0, 0x240d, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8,
-	0x2454, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0,
-	0x2438, 0x2011, 0x9255, 0x2009, 0x924e, 0x26a8, 0x211c, 0x2204,
-	0x201a, 0x8108, 0x8210, 0x00f0, 0x241e, 0xa685, 0x8030, 0x70c2,
-	0x681b, 0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812,
-	0x2091, 0x8001, 0xa006, 0x2009, 0x9275, 0x200a, 0x203a, 0x007c,
-	0x7810, 0xc0ad, 0x7812, 0x0078, 0x2454, 0x263a, 0x1078, 0x253f,
-	0x00c0, 0x254e, 0x786c, 0xa065, 0x00c0, 0x23eb, 0x2091, 0x8000,
-	0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040, 0x244f, 0xc0ad, 0x7812,
-	0x2091, 0x8001, 0x0078, 0x254e, 0x2091, 0x8000, 0x7007, 0x0004,
-	0x7994, 0x70d4, 0xa102, 0x0048, 0x2465, 0x0040, 0x246f, 0x7b90,
-	0xa302, 0x00c0, 0x246f, 0x0078, 0x2468, 0x8002, 0x00c0, 0x246f,
-	0x263a, 0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184,
-	0xff00, 0x0040, 0x247c, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004,
-	0x8007, 0xa100, 0x0078, 0x247f, 0x8107, 0x8004, 0x8004, 0x7a9c,
-	0xa210, 0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040,
-	0x248f, 0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1,
-	0x0030, 0x7003, 0x0000, 0x2009, 0x9254, 0x260a, 0x8109, 0x2198,
-	0x2104, 0xd084, 0x0040, 0x249d, 0x8633, 0xa6b0, 0x0002, 0x26a8,
-	0x53a6, 0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000,
-	0xa10a, 0x00c8, 0x24ac, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00,
-	0x0040, 0x24bb, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
-	0xa100, 0x0078, 0x24be, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108,
-	0x7a78, 0xa006, 0xa211, 0xd4c4, 0x0040, 0x24ca, 0x7b84, 0xa319,
-	0x7c80, 0xa421, 0x7008, 0xd0fc, 0x0040, 0x24ca, 0xa084, 0x01e0,
-	0x0040, 0x24ef, 0x7d10, 0x2031, 0x9254, 0x2634, 0x78a8, 0x8000,
-	0x78aa, 0xd08c, 0x00c0, 0x24e4, 0x7007, 0x0006, 0x7004, 0xd094,
-	0x00c0, 0x24de, 0x0078, 0x2456, 0x2069, 0x4a47, 0x206b, 0x0003,
-	0x78ac, 0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x24f8, 0x2030,
-	0x75d6, 0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12,
-	0x2091, 0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001,
-	0x711a, 0x721e, 0xd5c4, 0x0040, 0x2507, 0x7322, 0x7426, 0x007c,
-	0x6084, 0xa086, 0x0103, 0x00c0, 0x252b, 0x6114, 0x6018, 0xa105,
-	0x00c0, 0x252b, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x252b,
-	0x600c, 0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001,
-	0x2091, 0x4080, 0x1078, 0x203d, 0x0068, 0x252a, 0x786c, 0xa065,
-	0x00c0, 0x2508, 0x007c, 0x1078, 0x253f, 0x00c0, 0x254e, 0x786c,
-	0xa065, 0x00c0, 0x2508, 0x0078, 0x254e, 0x1078, 0x253f, 0x00c0,
-	0x254e, 0x786c, 0xa065, 0x00c0, 0x2535, 0x0078, 0x254e, 0x1078,
-	0x2554, 0x00c0, 0x2546, 0xa085, 0x0001, 0x007c, 0x1078, 0x2563,
-	0x00c0, 0x254c, 0x2041, 0x0001, 0x7d10, 0x007c, 0x88ff, 0x0040,
-	0x2553, 0x2091, 0x4080, 0x007c, 0x7b90, 0x7994, 0x70d4, 0xa102,
-	0x00c0, 0x255d, 0xa385, 0x0000, 0x007c, 0x0048, 0x2561, 0xa302,
-	0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec, 0x0040, 0x257b, 0x0e7e,
-	0x2091, 0x8000, 0x2071, 0x0020, 0x7004, 0xa005, 0x00c0, 0x2578,
-	0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040, 0x257b, 0x0078, 0x25cc,
-	0x0e7f, 0x0078, 0x25cc, 0xa184, 0xff00, 0x0040, 0x2588, 0x810f,
-	0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100, 0x0078, 0x258b,
-	0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98, 0x7ca4, 0x7da0, 0xa210,
-	0xa006, 0xa319, 0xa421, 0xa529, 0x2009, 0x0018, 0x6028, 0xa005,
-	0x0040, 0x259c, 0x2009, 0x0040, 0x1078, 0x1d92, 0x0040, 0x25be,
-	0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0, 0x25cc, 0x6014, 0xd0fc,
-	0x00c0, 0x25ae, 0x2069, 0x4a40, 0x0078, 0x25b0, 0x2069, 0x4a80,
-	0x2091, 0x8000, 0x681f, 0x0003, 0x78ab, 0x0000, 0x78ac, 0xa085,
-	0x0300, 0x78ae, 0x2091, 0x8001, 0x0078, 0x25cc, 0x78ab, 0x0000,
-	0x1078, 0x203d, 0x7990, 0x7894, 0x8000, 0xa10a, 0x00c8, 0x25c9,
-	0xa006, 0x7896, 0x70d6, 0xa006, 0x2071, 0x0010, 0x2091, 0x8001,
-	0x007c, 0x2138, 0xd7fc, 0x00c0, 0x25d9, 0x2009, 0x4a59, 0x0078,
-	0x25db, 0x2009, 0x4a99, 0x2091, 0x8000, 0x200a, 0x0f7e, 0xd7fc,
-	0x00c0, 0x25f2, 0x2009, 0x4a40, 0x2001, 0x4a04, 0x2004, 0xd0ec,
-	0x0040, 0x25ee, 0x2079, 0x0100, 0x0078, 0x25f6, 0x2079, 0x0200,
-	0x0078, 0x25f6, 0x2009, 0x4a80, 0x2079, 0x0100, 0x2104, 0xa086,
-	0x0000, 0x00c0, 0x260f, 0xd7fc, 0x00c0, 0x2602, 0x2009, 0x4a45,
-	0x0078, 0x2604, 0x2009, 0x4a85, 0x2104, 0xa005, 0x00c0, 0x260f,
-	0x7830, 0xa084, 0x00c0, 0x00c0, 0x260f, 0x781b, 0x0045, 0x0f7f,
-	0x007c, 0x2009, 0x0002, 0x2069, 0x4a00, 0x6810, 0xd0ec, 0x00c0,
-	0x2672, 0x2071, 0x4a80, 0x2079, 0x0100, 0x2021, 0x4cbf, 0x784b,
-	0x000f, 0x2019, 0x4205, 0xd184, 0x0040, 0x2632, 0x6810, 0xd0ec,
-	0x0040, 0x262e, 0x20a1, 0x012b, 0x0078, 0x2634, 0x20a1, 0x022b,
-	0x0078, 0x2634, 0x20a1, 0x012b, 0x2304, 0xa005, 0x0040, 0x2641,
-	0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6, 0x3318, 0x0078,
-	0x2634, 0x789b, 0x0020, 0x20a9, 0x0010, 0x78af, 0x0000, 0x78af,
-	0x8020, 0x00f0, 0x2645, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009,
-	0x0000, 0x0040, 0x2654, 0xc1bd, 0x1078, 0x283d, 0x017f, 0x7020,
-	0xa084, 0x000f, 0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x2664,
-	0xa085, 0x6340, 0x0078, 0x2666, 0xa085, 0x62c0, 0x7806, 0x780f,
-	0x9200, 0x7843, 0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456,
-	0x7053, 0x0000, 0x8109, 0x0040, 0x2685, 0x2071, 0x4a40, 0x6810,
-	0xd0ec, 0x0040, 0x267f, 0x2079, 0x0100, 0x0078, 0x2681, 0x2079,
-	0x0200, 0x2021, 0x4abf, 0x0078, 0x261f, 0x007c, 0x017e, 0xd1bc,
-	0x00c0, 0x269a, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f,
-	0x0040, 0x2696, 0x2011, 0x0101, 0x0078, 0x269c, 0x2011, 0x0201,
-	0x0078, 0x269c, 0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084,
-	0xfff0, 0xa105, 0x2012, 0x017f, 0x1078, 0x283d, 0x007c, 0xd3fc,
-	0x00c0, 0x26ba, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f,
-	0x0040, 0x26b6, 0x2011, 0x0101, 0x0078, 0x26bc, 0x2011, 0x0201,
-	0x0078, 0x26bc, 0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0,
-	0x26be, 0xa18c, 0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012,
-	0x007c, 0x2019, 0x0002, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040,
-	0x26d6, 0x8319, 0x2009, 0x0101, 0x0078, 0x26d8, 0x2009, 0x0101,
-	0x20a9, 0x0005, 0x8213, 0x00f0, 0x26da, 0xa294, 0x00e0, 0x2104,
-	0xa084, 0xff1f, 0xa205, 0x200a, 0x8319, 0x0040, 0x26eb, 0x2009,
-	0x0201, 0x0078, 0x26d8, 0x007c, 0xd3fc, 0x00c0, 0x26ff, 0x007e,
-	0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26fb, 0x2011,
-	0x0101, 0x0078, 0x2701, 0x2011, 0x0201, 0x0078, 0x2701, 0x2011,
-	0x0101, 0x20a9, 0x000c, 0x810b, 0x00f0, 0x2703, 0xa18c, 0xf000,
-	0x2204, 0xa084, 0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0,
-	0x2721, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040,
-	0x271d, 0x2011, 0x0102, 0x0078, 0x2723, 0x2011, 0x0202, 0x0078,
-	0x2723, 0x2011, 0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012,
-	0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x273d, 0x007e, 0x2001, 0x4a04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x2739, 0x2061, 0x0100, 0x0078,
-	0x273f, 0x2061, 0x0200, 0x0078, 0x273f, 0x2061, 0x0100, 0xc1bc,
-	0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f,
-	0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x275d, 0x007e, 0x2001, 0x4a04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x2759, 0x2061, 0x0100, 0x0078,
-	0x275f, 0x2061, 0x0200, 0x0078, 0x275f, 0x2061, 0x0100, 0xc1bc,
-	0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf,
-	0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x277f, 0x007e,
-	0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x277b, 0x2061,
-	0x0100, 0x0078, 0x2781, 0x2061, 0x0200, 0x0078, 0x2781, 0x2061,
-	0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4,
-	0xa085, 0x0020, 0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0,
-	0x27a1, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040,
-	0x279d, 0x2061, 0x0100, 0x0078, 0x27a3, 0x2061, 0x0200, 0x0078,
-	0x27a3, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020,
-	0x609a, 0x60a4, 0xa28c, 0x0020, 0x0040, 0x27b1, 0xc2ac, 0xa39d,
-	0x4000, 0xc3fc, 0xd3b4, 0x00c0, 0x27b6, 0xc3fd, 0x62ae, 0x2010,
-	0x60a4, 0x63ae, 0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e,
-	0x0e7e, 0x6818, 0xa005, 0x0040, 0x281b, 0xd1fc, 0x0040, 0x27cc,
-	0x2061, 0x91d0, 0x0078, 0x27ce, 0x2061, 0x90c0, 0x1078, 0x2823,
-	0x0040, 0x2801, 0x20a9, 0x0101, 0xd1fc, 0x0040, 0x27db, 0x2061,
-	0x90d0, 0x0078, 0x27dd, 0x2061, 0x8fc0, 0x0c7e, 0x1078, 0x2823,
-	0x0040, 0x27e8, 0x0c7f, 0x8c60, 0x00f0, 0x27dd, 0x0078, 0x281b,
-	0x007f, 0xd1fc, 0x0040, 0x27f2, 0xa082, 0x90d0, 0x2071, 0x4a80,
-	0x0078, 0x27f6, 0xa082, 0x8fc0, 0x2071, 0x4a40, 0x707a, 0x7176,
-	0x2001, 0x0004, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x0078,
-	0x2817, 0xd1fc, 0x00c0, 0x2808, 0x2071, 0x4a40, 0x0078, 0x280a,
-	0x2071, 0x4a80, 0x6020, 0xc0dd, 0x6022, 0x7176, 0x2c00, 0x707e,
-	0x2001, 0x0006, 0x7066, 0x7083, 0x000f, 0x1078, 0x25d1, 0x2001,
-	0x0000, 0x0078, 0x281d, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005,
-	0x0e7f, 0x0c7f, 0x007c, 0x2c04, 0xa005, 0x0040, 0x283a, 0x2060,
-	0x6010, 0xa306, 0x00c0, 0x2837, 0x600c, 0xa206, 0x00c0, 0x2837,
-	0x6014, 0xa106, 0x00c0, 0x2837, 0xa006, 0x0078, 0x283c, 0x6000,
-	0x0078, 0x2824, 0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e,
-	0xd1bc, 0x00c0, 0x2855, 0x2079, 0x4a40, 0x007e, 0x2001, 0x4a04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x2851, 0x2071, 0x0100, 0x0078,
-	0x2859, 0x2071, 0x0200, 0x0078, 0x2859, 0x2079, 0x4a80, 0x2071,
-	0x0100, 0x7920, 0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x2863,
-	0x017f, 0x0078, 0x287e, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f,
-	0xd0bc, 0x00c0, 0x287b, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x2877, 0xa18d, 0x0f00, 0x0078, 0x287d, 0xa18d,
-	0x0f00, 0x0078, 0x287d, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f,
-	0x007c, 0x0e7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0, 0x28ea,
-	0x68e4, 0xd0ac, 0x0040, 0x28ea, 0xa084, 0x0006, 0x00c0, 0x28ea,
-	0x6014, 0xd0fc, 0x00c0, 0x2898, 0x2071, 0x4ec0, 0x0078, 0x289a,
-	0x2071, 0x4f40, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xae70, 0x7004, 0xa084, 0x000a, 0x00c0, 0x28ea, 0x7108, 0xa194,
-	0xff00, 0x0040, 0x28ea, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106,
-	0x0040, 0x28cd, 0x2001, 0x000c, 0xa106, 0x0040, 0x28d1, 0x2001,
-	0x0012, 0xa106, 0x0040, 0x28d5, 0x2001, 0x0014, 0xa106, 0x0040,
-	0x28d9, 0x2001, 0x0019, 0xa106, 0x0040, 0x28dd, 0x2001, 0x0032,
-	0xa106, 0x0040, 0x28e1, 0x0078, 0x28e5, 0x2009, 0x000c, 0x0078,
-	0x28e7, 0x2009, 0x0012, 0x0078, 0x28e7, 0x2009, 0x0014, 0x0078,
-	0x28e7, 0x2009, 0x0019, 0x0078, 0x28e7, 0x2009, 0x0020, 0x0078,
-	0x28e7, 0x2009, 0x003f, 0x0078, 0x28e7, 0x2011, 0x0000, 0x2100,
-	0xa205, 0x700a, 0x0e7f, 0x007c, 0x0068, 0x28ec, 0x2091, 0x8000,
-	0x2071, 0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x28f3, 0x007f,
-	0x2071, 0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db,
-	0x0809, 0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091,
-	0x4080, 0x0078, 0x2909, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0,
-	0x708e, 0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4,
-	0x0040, 0x2920, 0xa784, 0x007d, 0x00c0, 0x417b, 0x1078, 0x28ec,
-	0xa49c, 0x000f, 0xa382, 0x0004, 0x0050, 0x292b, 0xa3a6, 0x0007,
-	0x00c0, 0x28ec, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x2930,
-	0x2f45, 0x3035, 0x3060, 0x32c1, 0x363b, 0x36a1, 0x3741, 0x37bd,
-	0x38a1, 0x398a, 0x2943, 0x2940, 0x2d2a, 0x2e43, 0x360e, 0x2940,
-	0x1078, 0x28ec, 0x007c, 0xa006, 0x0078, 0x294d, 0x7808, 0xc08d,
-	0x780a, 0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005,
-	0x00c0, 0x2a64, 0x7064, 0xa084, 0x0007, 0x0079, 0x2957, 0x295f,
-	0x29cf, 0x29d8, 0x29e3, 0x29ee, 0x2a4a, 0x29f9, 0x29cf, 0x7830,
-	0xd0bc, 0x00c0, 0x2942, 0x71d4, 0xd1b4, 0x00c0, 0x29ac, 0x70a4,
-	0xa086, 0x0001, 0x0040, 0x2942, 0x70b4, 0xa06d, 0x6800, 0xa065,
-	0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10,
-	0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040, 0x2982, 0x69bc,
-	0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001, 0x0010, 0x0078,
-	0x2bbd, 0x7060, 0xa005, 0x00c0, 0x2942, 0x0c7e, 0x0d7e, 0x70b4,
-	0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa,
-	0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001,
-	0x0040, 0x29a5, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c,
-	0x2001, 0x0020, 0x0078, 0x2bbd, 0x1078, 0x411c, 0x00c0, 0x2942,
-	0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a, 0x68bc,
-	0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x7003,
-	0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0x1078,
-	0x411c, 0x00c0, 0x29d7, 0x781b, 0x0047, 0x7003, 0x0004, 0x007c,
-	0x1078, 0x411c, 0x00c0, 0x29e2, 0x2011, 0x000c, 0x1078, 0x2a09,
-	0x7003, 0x0004, 0x007c, 0x1078, 0x411c, 0x00c0, 0x29ed, 0x2011,
-	0x0006, 0x1078, 0x2a09, 0x7003, 0x0004, 0x007c, 0x1078, 0x411c,
-	0x00c0, 0x29f8, 0x2011, 0x000d, 0x1078, 0x2a09, 0x7003, 0x0004,
-	0x007c, 0x1078, 0x411c, 0x00c0, 0x2a08, 0x2011, 0x0006, 0x1078,
-	0x2a09, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e, 0x7003, 0x0001,
-	0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b, 0x0010, 0xa286,
-	0x000c, 0x00c0, 0x2a18, 0x7aaa, 0x2001, 0x0001, 0x0078, 0x2a2d,
-	0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286, 0x000d, 0x0040,
-	0x2a26, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2a2d, 0x78ab, 0x0020,
-	0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b, 0x0060, 0x78aa,
-	0x785b, 0x0004, 0x781b, 0x0108, 0x1078, 0x4131, 0x7083, 0x000f,
-	0x70d4, 0xd0b4, 0x0040, 0x2a49, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8,
-	0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
-	0x0c7f, 0x007c, 0x1078, 0x411c, 0x00c0, 0x2942, 0x707c, 0x2068,
-	0x7774, 0x1078, 0x3fe1, 0x2c50, 0x1078, 0x41f0, 0x789b, 0x0010,
-	0x6814, 0xa084, 0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001,
-	0x2001, 0x0004, 0x0078, 0x2bc3, 0x1078, 0x411c, 0x00c0, 0x2942,
-	0x789b, 0x0010, 0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040,
-	0x2a7e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
-	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x3fe1,
-	0x2c50, 0x1078, 0x41f0, 0x6824, 0xa005, 0x0040, 0x2a8f, 0xa082,
-	0x0006, 0x0048, 0x2a8d, 0x0078, 0x2a8f, 0x6827, 0x0005, 0x6814,
-	0xa084, 0x001f, 0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001,
-	0x2001, 0x0003, 0x0078, 0x2bc3, 0xc28d, 0x72d6, 0x72c0, 0xa200,
-	0xa015, 0x7154, 0x8108, 0xa12a, 0x0048, 0x2aa7, 0x71c0, 0x2164,
-	0x6504, 0x85ff, 0x00c0, 0x2abe, 0x7156, 0x8421, 0x00c0, 0x2aa2,
-	0x70d4, 0xd08c, 0x0040, 0x2aba, 0x70d0, 0xa005, 0x00c0, 0x2aba,
-	0x70d3, 0x000a, 0x007c, 0x2200, 0x0078, 0x2aac, 0x70d4, 0xc08c,
-	0x70d6, 0x70d3, 0x0000, 0x603c, 0xa005, 0x00c0, 0x2abb, 0x6708,
-	0xa784, 0x073f, 0x0040, 0x2aed, 0xd7d4, 0x00c0, 0x2abb, 0xa784,
-	0x0021, 0x00c0, 0x2abb, 0xa784, 0x0002, 0x0040, 0x2ade, 0xa784,
-	0x0004, 0x0040, 0x2abb, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218,
-	0x00c0, 0x2abb, 0xa784, 0x0100, 0x0040, 0x2aed, 0x6018, 0xa005,
-	0x00c0, 0x2abb, 0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000,
-	0x6e1c, 0xa684, 0x000e, 0x6318, 0x0040, 0x2afe, 0x601c, 0xa302,
-	0x0048, 0x2b01, 0x0040, 0x2b01, 0x0078, 0x2abb, 0x83ff, 0x00c0,
-	0x2abb, 0x2d58, 0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2b09, 0x7028,
-	0x6022, 0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60,
-	0x2041, 0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc,
-	0x0040, 0x2b1d, 0xd684, 0x0040, 0x2b1f, 0xa39c, 0xffbf, 0xd6a4,
-	0x0040, 0x2b24, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2b6f,
-	0xc7a5, 0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0,
-	0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002,
-	0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010,
-	0x7baa, 0x0078, 0x2bbb, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0,
-	0x0005, 0x70ac, 0xa606, 0x00c0, 0x2b4e, 0x76a8, 0x76b2, 0x2c3a,
-	0x8738, 0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a,
-	0x7830, 0xd0bc, 0x0040, 0x2b66, 0x2091, 0x8000, 0x2091, 0x303d,
-	0x70d4, 0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000,
-	0x0040, 0x2b6e, 0x8421, 0x2200, 0x00c0, 0x2aa1, 0x007c, 0xd1dc,
-	0x0040, 0x3be5, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2b7c, 0x8528,
-	0xd68c, 0x00c0, 0x2b7c, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108,
-	0xa18c, 0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2b9b,
-	0x6014, 0xa706, 0x00c0, 0x2b84, 0x60b8, 0x8001, 0x60ba, 0x00c0,
-	0x2b7f, 0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421,
-	0x00c0, 0x2aa1, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6,
-	0x8840, 0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0,
-	0x2b43, 0x70d4, 0xd0b4, 0x00c0, 0x2b43, 0x7000, 0xa082, 0x0002,
-	0x00c8, 0x2b43, 0x7830, 0xd0bc, 0x00c0, 0x2b43, 0x789b, 0x0010,
-	0x7baa, 0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000,
-	0x601a, 0x0078, 0x2bc4, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184,
-	0x0018, 0x0040, 0x2be0, 0xa184, 0x0010, 0x0040, 0x2bd3, 0x1078,
-	0x3df6, 0x00c0, 0x2c05, 0xa184, 0x0008, 0x0040, 0x2be0, 0x69a0,
-	0xa184, 0x0600, 0x00c0, 0x2be0, 0x1078, 0x3cda, 0x0078, 0x2c05,
-	0x69a0, 0xa184, 0x1e00, 0x0040, 0x2c10, 0xa184, 0x0800, 0x0040,
-	0x2bf9, 0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104,
-	0xa18d, 0x0010, 0x6106, 0x0c7f, 0x1078, 0x3df6, 0x00c0, 0x2c05,
-	0x69a0, 0xa184, 0x0200, 0x0040, 0x2c01, 0x1078, 0x3d3a, 0x0078,
-	0x2c05, 0xa184, 0x0400, 0x00c0, 0x2bdc, 0x69a0, 0xa184, 0x1000,
-	0x0040, 0x2c10, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x2749,
-	0x027f, 0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2c1d, 0xa086,
-	0x0060, 0x00c0, 0x2c1d, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6,
-	0x789b, 0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc,
-	0x0040, 0x2c38, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050,
-	0x2c36, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a,
-	0x78aa, 0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b,
-	0x20a0, 0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8,
-	0x2898, 0x25a0, 0xa286, 0x0020, 0x00c0, 0x2c70, 0x70d4, 0xc0b5,
-	0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007,
-	0x7882, 0xa286, 0x0002, 0x0040, 0x2ca6, 0x70a4, 0x8000, 0x70a6,
-	0x74b4, 0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2c68, 0x73a8,
-	0x73b6, 0xa286, 0x0010, 0x0040, 0x2942, 0x0d7f, 0x0c7f, 0x007c,
-	0x7000, 0xa005, 0x00c0, 0x2c4e, 0xa286, 0x0002, 0x00c0, 0x2cc0,
-	0x1078, 0x411c, 0x00c0, 0x2c4e, 0x6814, 0xc0fc, 0x8007, 0x7882,
-	0x2091, 0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d,
-	0x780a, 0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090,
-	0x0c7f, 0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003,
-	0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc,
-	0x0040, 0x2cb2, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091,
-	0x8000, 0x2090, 0x70a4, 0xa005, 0x00c0, 0x2cb7, 0x007c, 0x8421,
-	0x0040, 0x2cb6, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2aa1,
-	0xa286, 0x0010, 0x00c0, 0x2cf1, 0x1078, 0x411c, 0x00c0, 0x2c4e,
-	0x6814, 0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a,
+	0x2330, 0x0078, 0x232e, 0x2c08, 0xd9fc, 0x0040, 0x230b, 0x6800,
+	0xa065, 0x0040, 0x230b, 0x6a04, 0x7000, 0xa084, 0x0002, 0x0040,
+	0x2301, 0x704c, 0xa206, 0x00c0, 0x2301, 0x6b04, 0x2160, 0x2304,
+	0x6002, 0xa005, 0x00c0, 0x22fd, 0x6902, 0x2260, 0x6102, 0x0078,
+	0x2317, 0x2d00, 0x2060, 0x1078, 0x2acc, 0x6e08, 0x2160, 0x6202,
+	0x6906, 0x0078, 0x2317, 0x6800, 0x6902, 0xa065, 0x0040, 0x2313,
+	0x6102, 0x0078, 0x2314, 0x6906, 0x2160, 0x6003, 0x0000, 0x2160,
+	0xd9fc, 0x0040, 0x231e, 0xa6b4, 0xfffc, 0x6e0a, 0x6810, 0x7d08,
+	0x8528, 0x7d0a, 0x8000, 0x6812, 0x2091, 0x8001, 0xd6b4, 0x0040,
+	0x232e, 0xa6b6, 0x0040, 0x6e0a, 0x1078, 0x1e6c, 0x0e7f, 0x007c,
+	0x6008, 0xa705, 0x600a, 0x2091, 0x8000, 0x1078, 0x201d, 0x2091,
+	0x8001, 0x78b8, 0xa065, 0x0040, 0x2343, 0x609c, 0x78ba, 0x609f,
+	0x0000, 0x0078, 0x2330, 0x78b6, 0x78ba, 0x007c, 0x7970, 0x7874,
+	0x2818, 0xd384, 0x0040, 0x2350, 0x8000, 0xa112, 0x0048, 0x2355,
+	0x8000, 0xa112, 0x00c8, 0x2365, 0xc384, 0x7a7c, 0x721a, 0x7a78,
+	0x721e, 0xdac4, 0x0040, 0x2360, 0x7a84, 0x7222, 0x7a80, 0x7226,
+	0xa006, 0xd384, 0x0040, 0x2365, 0x8000, 0x7876, 0x70d2, 0x781c,
+	0xa005, 0x0040, 0x2373, 0x8001, 0x781e, 0x00c0, 0x2373, 0x0068,
+	0x2373, 0x2091, 0x4080, 0x007c, 0x2039, 0x238c, 0x0078, 0x237a,
+	0x2039, 0x2392, 0x2704, 0xa005, 0x0040, 0x238b, 0xac00, 0x2068,
+	0x6908, 0x6810, 0x6912, 0x680a, 0x690c, 0x6814, 0x6916, 0x680e,
+	0x8738, 0x0078, 0x237a, 0x007c, 0x0003, 0x0009, 0x000f, 0x0015,
+	0x001b, 0x0000, 0x0015, 0x001b, 0x0000, 0x2041, 0x0000, 0x780c,
+	0x0079, 0x239a, 0x256c, 0x253f, 0x239e, 0x2417, 0x2039, 0x9674,
+	0x2734, 0x7d10, 0x0078, 0x23be, 0x6084, 0xa086, 0x0103, 0x00c0,
+	0x2400, 0x6114, 0x6018, 0xa105, 0x0040, 0x23b3, 0x86ff, 0x00c0,
+	0x23cf, 0x0078, 0x2400, 0x8603, 0xa080, 0x9655, 0x620c, 0x2202,
+	0x8000, 0x6210, 0x2202, 0x1078, 0x203f, 0x8630, 0xa68e, 0x000f,
+	0x0040, 0x248b, 0x786c, 0xa065, 0x00c0, 0x23a4, 0x7808, 0xa602,
+	0x00c8, 0x23cf, 0xd5ac, 0x00c0, 0x23cf, 0x263a, 0x007c, 0xa682,
+	0x0003, 0x00c8, 0x248b, 0x2091, 0x8000, 0x2069, 0x0000, 0x6818,
+	0xd084, 0x00c0, 0x23fb, 0x2011, 0x9655, 0x2204, 0x70c6, 0x8210,
+	0x2204, 0x70ca, 0xd684, 0x00c0, 0x23eb, 0x8210, 0x2204, 0x70da,
+	0x8210, 0x2204, 0x70de, 0xa685, 0x8020, 0x70c2, 0x681b, 0x0001,
+	0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091, 0x8001,
+	0x203b, 0x0000, 0x007c, 0x7810, 0xc0ad, 0x7812, 0x0078, 0x248b,
+	0x263a, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065, 0x00c0,
+	0x23a4, 0x2091, 0x8000, 0x7810, 0xa084, 0xffcf, 0x86ff, 0x0040,
+	0x2412, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0078, 0x2599, 0x2039,
+	0x9674, 0x2734, 0x7d10, 0x0078, 0x2433, 0x6084, 0xa086, 0x0103,
+	0x00c0, 0x2474, 0x6114, 0x6018, 0xa105, 0x0040, 0x242c, 0x86ff,
+	0x00c0, 0x2444, 0x0078, 0x2474, 0xa680, 0x9655, 0x620c, 0x2202,
+	0x1078, 0x203f, 0x8630, 0xa68e, 0x001e, 0x0040, 0x248b, 0x786c,
+	0xa065, 0x00c0, 0x241d, 0x7808, 0xa602, 0x00c8, 0x2444, 0xd5ac,
+	0x00c0, 0x2444, 0x263a, 0x007c, 0xa682, 0x0006, 0x00c8, 0x248b,
+	0x2091, 0x8000, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x246f,
+	0x2011, 0x9655, 0x2009, 0x964e, 0x26a8, 0x211c, 0x2204, 0x201a,
+	0x8108, 0x8210, 0x00f0, 0x2455, 0xa685, 0x8030, 0x70c2, 0x681b,
+	0x0001, 0x2091, 0x4080, 0x7810, 0xa084, 0xffcf, 0x7812, 0x2091,
+	0x8001, 0xa006, 0x2009, 0x9675, 0x200a, 0x203a, 0x007c, 0x7810,
+	0xc0ad, 0x7812, 0x0078, 0x248b, 0x263a, 0x1078, 0x2576, 0x00c0,
+	0x2599, 0x786c, 0xa065, 0x00c0, 0x241d, 0x2091, 0x8000, 0x7810,
+	0xa084, 0xffcf, 0x86ff, 0x0040, 0x2486, 0xc0ad, 0x7812, 0x2091,
+	0x8001, 0x0078, 0x2599, 0x2091, 0x8000, 0x7007, 0x0004, 0x7994,
+	0x70d4, 0xa102, 0x0048, 0x249c, 0x0040, 0x24a6, 0x7b90, 0xa302,
+	0x00c0, 0x24a6, 0x0078, 0x249f, 0x8002, 0x00c0, 0x24a6, 0x263a,
+	0x7810, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x007c, 0xa184, 0xff00,
+	0x0040, 0x24b3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
+	0xa100, 0x0078, 0x24b6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0xa210,
+	0x721a, 0x7a98, 0xa006, 0xa211, 0x721e, 0xd4c4, 0x0040, 0x24c6,
+	0x7aa4, 0xa211, 0x7222, 0x7aa0, 0xa211, 0x7226, 0x20a1, 0x0030,
+	0x7003, 0x0000, 0x2009, 0x9654, 0x260a, 0x8109, 0x2198, 0x2104,
+	0xd084, 0x0040, 0x24d4, 0x8633, 0xa6b0, 0x0002, 0x26a8, 0x53a6,
+	0x8603, 0x7012, 0x7007, 0x0001, 0x7990, 0x7894, 0x8000, 0xa10a,
+	0x00c8, 0x24e3, 0xa006, 0x2028, 0x7974, 0xa184, 0xff00, 0x0040,
+	0x24f2, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007, 0xa100,
+	0x0078, 0x24f5, 0x8107, 0x8004, 0x8004, 0x797c, 0xa108, 0x7a78,
+	0xa006, 0xa211, 0xd4c4, 0x0040, 0x2501, 0x7b84, 0xa319, 0x7c80,
+	0xa421, 0x7008, 0xd0fc, 0x0040, 0x2501, 0xa084, 0x01e0, 0x0040,
+	0x2526, 0x7d10, 0x2031, 0x9654, 0x2634, 0x78a8, 0x8000, 0x78aa,
+	0xd08c, 0x00c0, 0x251b, 0x7007, 0x0006, 0x7004, 0xd094, 0x00c0,
+	0x2515, 0x0078, 0x248d, 0x2069, 0x4e47, 0x206b, 0x0003, 0x78ac,
+	0xa085, 0x0300, 0x78ae, 0xa006, 0x0078, 0x252f, 0x2030, 0x75d6,
+	0x2091, 0x4080, 0x7d96, 0x7d10, 0xa5ac, 0xffcf, 0x7d12, 0x2091,
+	0x8001, 0x78aa, 0x7007, 0x0006, 0x263a, 0x7003, 0x0001, 0x711a,
+	0x721e, 0xd5c4, 0x0040, 0x253e, 0x7322, 0x7426, 0x007c, 0x6084,
+	0xa086, 0x0103, 0x00c0, 0x2562, 0x6114, 0x6018, 0xa105, 0x00c0,
+	0x2562, 0x2069, 0x0000, 0x6818, 0xd084, 0x00c0, 0x2562, 0x600c,
+	0x70c6, 0x6010, 0x70ca, 0x70c3, 0x8020, 0x681b, 0x0001, 0x2091,
+	0x4080, 0x1078, 0x203f, 0x0068, 0x2561, 0x786c, 0xa065, 0x00c0,
+	0x253f, 0x007c, 0x1078, 0x2576, 0x00c0, 0x2599, 0x786c, 0xa065,
+	0x00c0, 0x253f, 0x0078, 0x2599, 0x1078, 0x2576, 0x00c0, 0x2599,
+	0x786c, 0xa065, 0x00c0, 0x256c, 0x0078, 0x2599, 0x6084, 0xa086,
+	0x0103, 0x00c0, 0x258a, 0x6018, 0xc0fc, 0x601a, 0xa086, 0x0004,
+	0x00c0, 0x258a, 0x7804, 0xd0a4, 0x0040, 0x258a, 0x1078, 0x203f,
+	0xa006, 0x007c, 0x1078, 0x259f, 0x00c0, 0x2591, 0xa085, 0x0001,
+	0x007c, 0x1078, 0x25ae, 0x00c0, 0x2597, 0x2041, 0x0001, 0x7d10,
+	0x007c, 0x88ff, 0x0040, 0x259e, 0x2091, 0x4080, 0x007c, 0x7b90,
+	0x7994, 0x70d4, 0xa102, 0x00c0, 0x25a8, 0xa385, 0x0000, 0x007c,
+	0x0048, 0x25ac, 0xa302, 0x007c, 0x8002, 0x007c, 0x7810, 0xd0ec,
+	0x0040, 0x25c6, 0x0e7e, 0x2091, 0x8000, 0x2071, 0x0020, 0x7004,
+	0xa005, 0x00c0, 0x25c3, 0x7008, 0x0e7f, 0xa086, 0x0008, 0x0040,
+	0x25c6, 0x0078, 0x2617, 0x0e7f, 0x0078, 0x2617, 0xa184, 0xff00,
+	0x0040, 0x25d3, 0x810f, 0x810c, 0x810c, 0x8004, 0x8004, 0x8007,
+	0xa100, 0x0078, 0x25d6, 0x8107, 0x8004, 0x8004, 0x7a9c, 0x7b98,
+	0x7ca4, 0x7da0, 0xa210, 0xa006, 0xa319, 0xa421, 0xa529, 0x2009,
+	0x0018, 0x6028, 0xa005, 0x0040, 0x25e7, 0x2009, 0x0040, 0x1078,
+	0x1d74, 0x0040, 0x2609, 0x78a8, 0x8000, 0x78aa, 0xd08c, 0x00c0,
+	0x2617, 0x6014, 0xd0fc, 0x00c0, 0x25f9, 0x2069, 0x4e40, 0x0078,
+	0x25fb, 0x2069, 0x4e80, 0x2091, 0x8000, 0x681f, 0x0003, 0x78ab,
+	0x0000, 0x78ac, 0xa085, 0x0300, 0x78ae, 0x2091, 0x8001, 0x0078,
+	0x2617, 0x78ab, 0x0000, 0x1078, 0x203f, 0x7990, 0x7894, 0x8000,
+	0xa10a, 0x00c8, 0x2614, 0xa006, 0x7896, 0x70d6, 0xa006, 0x2071,
+	0x0010, 0x2091, 0x8001, 0x007c, 0xd7fc, 0x00c0, 0x2623, 0x2009,
+	0x4e59, 0x0078, 0x2625, 0x2009, 0x4e99, 0x2091, 0x8000, 0x200a,
+	0x0f7e, 0xd7fc, 0x00c0, 0x263c, 0x2009, 0x4e40, 0x2001, 0x4e04,
+	0x2004, 0xd0ec, 0x0040, 0x2638, 0x2079, 0x0100, 0x0078, 0x2640,
+	0x2079, 0x0200, 0x0078, 0x2640, 0x2009, 0x4e80, 0x2079, 0x0100,
+	0x2104, 0xa086, 0x0000, 0x00c0, 0x2659, 0xd7fc, 0x00c0, 0x264c,
+	0x2009, 0x4e45, 0x0078, 0x264e, 0x2009, 0x4e85, 0x2104, 0xa005,
+	0x00c0, 0x2659, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x2659, 0x781b,
+	0x0045, 0x0f7f, 0x007c, 0x2009, 0x0002, 0x2069, 0x4e00, 0x6810,
+	0xd0ec, 0x00c0, 0x26c8, 0x2071, 0x4e80, 0x2079, 0x0100, 0x2021,
+	0x50bf, 0x784b, 0x000f, 0x2019, 0x4457, 0xd184, 0x0040, 0x267c,
+	0x6810, 0xd0ec, 0x0040, 0x2678, 0x20a1, 0x012b, 0x0078, 0x267e,
+	0x20a1, 0x022b, 0x0078, 0x267e, 0x20a1, 0x012b, 0x2304, 0xa005,
+	0x0040, 0x268b, 0x789a, 0x8318, 0x23ac, 0x8318, 0x2398, 0x53a6,
+	0x3318, 0x0078, 0x267e, 0x789b, 0x0020, 0x20a9, 0x0010, 0x6814,
+	0xd0e4, 0x0040, 0x269b, 0x78af, 0x0000, 0x78af, 0x9020, 0x00f0,
+	0x2693, 0x0078, 0x26a1, 0x78af, 0x0000, 0x78af, 0x8020, 0x00f0,
+	0x269b, 0x7003, 0x0000, 0x017e, 0xd18c, 0x2009, 0x0000, 0x0040,
+	0x26aa, 0xc1bd, 0x1078, 0x289b, 0x017f, 0x7020, 0xa084, 0x000f,
+	0x007e, 0x6814, 0xd0e4, 0x007f, 0x00c0, 0x26ba, 0xa085, 0x6340,
+	0x0078, 0x26bc, 0xa085, 0x62c0, 0x7806, 0x780f, 0x9200, 0x7843,
+	0x00d8, 0x7853, 0x0080, 0x780b, 0x0008, 0x7456, 0x7053, 0x0000,
+	0x8109, 0x0040, 0x26db, 0x2071, 0x4e40, 0x6810, 0xd0ec, 0x0040,
+	0x26d5, 0x2079, 0x0100, 0x0078, 0x26d7, 0x2079, 0x0200, 0x2021,
+	0x4ebf, 0x0078, 0x2669, 0x007c, 0x017e, 0xd1bc, 0x00c0, 0x26f0,
+	0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x26ec,
+	0x2011, 0x0101, 0x0078, 0x26f2, 0x2011, 0x0201, 0x0078, 0x26f2,
+	0x2011, 0x0101, 0xa18c, 0x000f, 0x2204, 0xa084, 0xfff0, 0xa105,
+	0x2012, 0x017f, 0x1078, 0x289b, 0x007c, 0xd3fc, 0x00c0, 0x2710,
+	0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x270c,
+	0x2011, 0x0101, 0x0078, 0x2712, 0x2011, 0x0201, 0x0078, 0x2712,
+	0x2011, 0x0101, 0x20a9, 0x0009, 0x810b, 0x00f0, 0x2714, 0xa18c,
+	0x0e00, 0x2204, 0xa084, 0xf1ff, 0xa105, 0x2012, 0x007c, 0x2019,
+	0x0002, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040, 0x272c, 0x8319,
+	0x2009, 0x0101, 0x0078, 0x272e, 0x2009, 0x0101, 0x20a9, 0x0005,
+	0x8213, 0x00f0, 0x2730, 0xa294, 0x00e0, 0x2104, 0xa084, 0xff1f,
+	0xa205, 0x200a, 0x8319, 0x0040, 0x2741, 0x2009, 0x0201, 0x0078,
+	0x272e, 0x007c, 0xd3fc, 0x00c0, 0x2755, 0x007e, 0x2001, 0x4e04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x2751, 0x2011, 0x0101, 0x0078,
+	0x2757, 0x2011, 0x0201, 0x0078, 0x2757, 0x2011, 0x0101, 0x20a9,
+	0x000c, 0x810b, 0x00f0, 0x2759, 0xa18c, 0xf000, 0x2204, 0xa084,
+	0x0fff, 0xa105, 0x2012, 0x007c, 0xd3fc, 0x00c0, 0x2777, 0x007e,
+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2773, 0x2011,
+	0x0102, 0x0078, 0x2779, 0x2011, 0x0202, 0x0078, 0x2779, 0x2011,
+	0x0102, 0x2204, 0xa084, 0xffcf, 0xa105, 0x2012, 0x007c, 0x0c7e,
+	0xd1bc, 0x00c0, 0x2793, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
+	0x007f, 0x0040, 0x278f, 0x2061, 0x0100, 0x0078, 0x2795, 0x2061,
+	0x0200, 0x0078, 0x2795, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
+	0xa080, 0x0020, 0x609a, 0x62ac, 0x63ac, 0x0c7f, 0x007c, 0x0c7e,
+	0xd1bc, 0x00c0, 0x27b3, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
+	0x007f, 0x0040, 0x27af, 0x2061, 0x0100, 0x0078, 0x27b5, 0x2061,
+	0x0200, 0x0078, 0x27b5, 0x2061, 0x0100, 0xc1bc, 0x8103, 0x8003,
+	0xa080, 0x0022, 0x609a, 0x60a4, 0xa084, 0xffdf, 0x60ae, 0x0c7f,
+	0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27d5, 0x007e, 0x2001, 0x4e04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x27d1, 0x2061, 0x0100, 0x0078,
+	0x27d7, 0x2061, 0x0200, 0x0078, 0x27d7, 0x2061, 0x0100, 0xc1bc,
+	0x8103, 0x8003, 0xa080, 0x0022, 0x609a, 0x60a4, 0xa085, 0x0020,
+	0x60ae, 0x0c7f, 0x007c, 0x0c7e, 0xd1bc, 0x00c0, 0x27f7, 0x007e,
+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x27f3, 0x2061,
+	0x0100, 0x0078, 0x27f9, 0x2061, 0x0200, 0x0078, 0x27f9, 0x2061,
+	0x0100, 0xc1bc, 0x8103, 0x8003, 0xa080, 0x0020, 0x609a, 0x60a4,
+	0xa28c, 0x0020, 0x0040, 0x2807, 0xc2ac, 0xa39d, 0x4000, 0xc3fc,
+	0xd3b4, 0x00c0, 0x280c, 0xc3fd, 0x62ae, 0x2010, 0x60a4, 0x63ae,
+	0x2018, 0x0c7f, 0x007c, 0x2091, 0x8000, 0x0c7e, 0x0e7e, 0x6818,
+	0xa005, 0x0040, 0x2879, 0xd1fc, 0x0040, 0x2822, 0x2061, 0x95d0,
+	0x0078, 0x2824, 0x2061, 0x94c0, 0x1078, 0x2881, 0x0040, 0x285b,
+	0x20a9, 0x0101, 0xd1fc, 0x0040, 0x2831, 0x2061, 0x94d0, 0x0078,
+	0x2833, 0x2061, 0x93c0, 0x0c7e, 0x1078, 0x2881, 0x0040, 0x283e,
+	0x0c7f, 0x8c60, 0x00f0, 0x2833, 0x0078, 0x2879, 0x007f, 0xd1fc,
+	0x0040, 0x2848, 0xa082, 0x94d0, 0x2071, 0x4e80, 0x0078, 0x284c,
+	0xa082, 0x93c0, 0x2071, 0x4e40, 0x707a, 0x7176, 0x2138, 0x2001,
+	0x0004, 0x7066, 0x7083, 0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x1078,
+	0x261c, 0x0078, 0x2875, 0xd1fc, 0x00c0, 0x2862, 0x2071, 0x4e40,
+	0x0078, 0x2864, 0x2071, 0x4e80, 0x6020, 0xc0dd, 0x6022, 0x7176,
+	0x2138, 0x2c00, 0x707e, 0x2001, 0x0006, 0x7066, 0x7083, 0x000f,
+	0x71d4, 0xc1dc, 0x71d6, 0x1078, 0x261c, 0x2001, 0x0000, 0x0078,
+	0x287b, 0x2001, 0x0001, 0x2091, 0x8001, 0xa005, 0x0e7f, 0x0c7f,
+	0x007c, 0x2c04, 0xa005, 0x0040, 0x2898, 0x2060, 0x6010, 0xa306,
+	0x00c0, 0x2895, 0x600c, 0xa206, 0x00c0, 0x2895, 0x6014, 0xa106,
+	0x00c0, 0x2895, 0xa006, 0x0078, 0x289a, 0x6000, 0x0078, 0x2882,
+	0xa085, 0x0001, 0x007c, 0x0f7e, 0x0e7e, 0x017e, 0xd1bc, 0x00c0,
+	0x28b3, 0x2079, 0x4e40, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
+	0x007f, 0x0040, 0x28af, 0x2071, 0x0100, 0x0078, 0x28b7, 0x2071,
+	0x0200, 0x0078, 0x28b7, 0x2079, 0x4e80, 0x2071, 0x0100, 0x7920,
+	0xa18c, 0x000f, 0x70ec, 0xd0c4, 0x00c0, 0x28c1, 0x017f, 0x0078,
+	0x28dc, 0x810b, 0x810b, 0x810b, 0x810b, 0x007f, 0xd0bc, 0x00c0,
+	0x28d9, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040,
+	0x28d5, 0xa18d, 0x0f00, 0x0078, 0x28db, 0xa18d, 0x0f00, 0x0078,
+	0x28db, 0xa18d, 0x0800, 0x2104, 0x0e7f, 0x0f7f, 0x007c, 0x0e7e,
+	0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0, 0x295c, 0x68e4, 0xd0ac,
+	0x0040, 0x295c, 0xa084, 0x0006, 0x00c0, 0x295c, 0x6014, 0xd0fc,
+	0x00c0, 0x28f6, 0x2071, 0x52c0, 0x0078, 0x28f8, 0x2071, 0x5340,
+	0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xae70, 0x7004,
+	0xa084, 0x000a, 0x00c0, 0x295c, 0x7108, 0xa194, 0xff00, 0x0040,
+	0x295c, 0xa18c, 0x00ff, 0x2001, 0x000a, 0xa106, 0x0040, 0x292b,
+	0x2001, 0x000c, 0xa106, 0x0040, 0x292f, 0x2001, 0x0012, 0xa106,
+	0x0040, 0x2933, 0x2001, 0x0014, 0xa106, 0x0040, 0x2937, 0x2001,
+	0x0019, 0xa106, 0x0040, 0x293b, 0x2001, 0x0032, 0xa106, 0x0040,
+	0x293f, 0x0078, 0x2943, 0x2009, 0x000c, 0x0078, 0x2945, 0x2009,
+	0x0012, 0x0078, 0x2945, 0x2009, 0x0014, 0x0078, 0x2945, 0x2009,
+	0x0019, 0x0078, 0x2945, 0x2009, 0x0020, 0x0078, 0x2945, 0x2009,
+	0x003f, 0x0078, 0x2945, 0x2011, 0x0000, 0x2100, 0xa205, 0x700a,
+	0x2071, 0x4e00, 0x7004, 0xd0bc, 0x0040, 0x295c, 0x6014, 0xd0fc,
+	0x00c0, 0x2957, 0x70ea, 0x2071, 0x4e40, 0x0078, 0x295a, 0x70ee,
+	0x2071, 0x4e80, 0x701f, 0x000d, 0x0e7f, 0x007c, 0x2001, 0x4e05,
+	0x2004, 0xd0e4, 0x00c0, 0x296a, 0x7804, 0xa084, 0xff1f, 0xa085,
+	0x6340, 0x7806, 0x007c, 0x0068, 0x296b, 0x2091, 0x8000, 0x2071,
+	0x0000, 0x007e, 0x7018, 0xd084, 0x00c0, 0x2972, 0x007f, 0x2071,
+	0x0010, 0x70ca, 0x007f, 0x70c6, 0x70c3, 0x8002, 0x70db, 0x080f,
+	0x70df, 0x0000, 0x2071, 0x0000, 0x701b, 0x0001, 0x2091, 0x4080,
+	0x0078, 0x2988, 0x7f3c, 0x7e58, 0x7c30, 0x7d38, 0x78a0, 0x708e,
+	0x7592, 0x7496, 0x769a, 0x779e, 0xa594, 0x003f, 0xd4f4, 0x0040,
+	0x299f, 0xa784, 0x007d, 0x00c0, 0x43cd, 0x1078, 0x296b, 0xa49c,
+	0x000f, 0xa382, 0x0004, 0x0050, 0x29aa, 0xa3a6, 0x0007, 0x00c0,
+	0x296b, 0x2418, 0x8507, 0xa084, 0x000f, 0x0079, 0x29af, 0x3028,
+	0x3119, 0x3144, 0x33b6, 0x379f, 0x3819, 0x38ce, 0x395f, 0x3a4d,
+	0x3b3c, 0x29c2, 0x29bf, 0x2df9, 0x2f1c, 0x3770, 0x29bf, 0x1078,
+	0x296b, 0x007c, 0xa006, 0x0078, 0x29cc, 0x7808, 0xc08d, 0x780a,
+	0xa006, 0x7002, 0x704e, 0x7046, 0x70d2, 0x7060, 0xa005, 0x00c0,
+	0x2b32, 0x7064, 0xa084, 0x0007, 0x0079, 0x29d6, 0x29de, 0x2a51,
+	0x2a5a, 0x2a65, 0x2a70, 0x2b18, 0x2a7b, 0x2a51, 0x7830, 0xd0bc,
+	0x00c0, 0x29c1, 0x71d4, 0xd1bc, 0x00c0, 0x29c1, 0xd1b4, 0x00c0,
+	0x2a2e, 0x70a4, 0xa086, 0x0001, 0x0040, 0x29c1, 0x70b4, 0xa06d,
+	0x6800, 0xa065, 0xa055, 0x789b, 0x0010, 0x6b0c, 0x7baa, 0x6808,
+	0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d, 0xa886, 0x0001, 0x0040,
+	0x2a04, 0x69bc, 0x7daa, 0x79aa, 0x68c0, 0xa04d, 0x6e1c, 0x2001,
+	0x0010, 0x0078, 0x2c8c, 0x7060, 0xa005, 0x00c0, 0x29c1, 0x0c7e,
+	0x0d7e, 0x70b4, 0xa06d, 0x6800, 0xa065, 0xa055, 0x789b, 0x0010,
+	0x6b0c, 0x7baa, 0x6808, 0xa045, 0x6d10, 0x6804, 0xa06d, 0xa05d,
+	0xa886, 0x0001, 0x0040, 0x2a27, 0x69bc, 0x7daa, 0x79aa, 0x68c0,
+	0xa04d, 0x6e1c, 0x2001, 0x0020, 0x0078, 0x2c8c, 0x1078, 0x4360,
+	0x00c0, 0x29c1, 0x781b, 0x005b, 0x70bc, 0xa06d, 0x68b4, 0x785a,
 	0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d,
-	0x780a, 0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac,
-	0xa206, 0x00c0, 0x2ce4, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc,
-	0x7042, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046,
-	0x007c, 0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007,
-	0x7882, 0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b,
-	0x005b, 0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300,
-	0xa605, 0x0040, 0x2d1c, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300,
-	0x00c0, 0x2d16, 0x2009, 0x0000, 0x0078, 0x2d18, 0x2009, 0x0001,
-	0xa284, 0x000f, 0x1079, 0x2d20, 0xad80, 0x0009, 0x7046, 0x007c,
-	0x2d28, 0x45f7, 0x45f7, 0x45e4, 0x45f7, 0x2d28, 0x2d28, 0x2d28,
-	0x1078, 0x28ec, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0f7e, 0x2079,
-	0x4a00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2d4e, 0x7064, 0xa086,
-	0x0001, 0x00c0, 0x2d3e, 0x7066, 0x0078, 0x2e27, 0x7064, 0xa086,
-	0x0005, 0x00c0, 0x2d4c, 0x707c, 0x2068, 0x681b, 0x0004, 0x6817,
-	0x0000, 0x6820, 0xc09d, 0x6822, 0x7067, 0x0000, 0x70a7, 0x0000,
-	0x70a8, 0x70b2, 0x70b6, 0x70d4, 0xd0b4, 0x0040, 0x2d64, 0xc0b4,
+	0x780a, 0x68bc, 0x7042, 0xc1b4, 0x71d6, 0x70b8, 0xa065, 0x68c0,
+	0x705a, 0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046,
+	0x007c, 0x1078, 0x4360, 0x00c0, 0x2a59, 0x781b, 0x0047, 0x7003,
+	0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a64, 0x2011, 0x000c,
+	0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0,
+	0x2a6f, 0x2011, 0x0006, 0x1078, 0x2a8b, 0x7003, 0x0004, 0x007c,
+	0x1078, 0x4360, 0x00c0, 0x2a7a, 0x2011, 0x000d, 0x1078, 0x2a8b,
+	0x7003, 0x0004, 0x007c, 0x1078, 0x4360, 0x00c0, 0x2a8a, 0x2011,
+	0x0006, 0x1078, 0x2a8b, 0x707c, 0x707f, 0x0000, 0x2068, 0x704e,
+	0x7003, 0x0001, 0x007c, 0x7174, 0xc1fc, 0x8107, 0x7882, 0x789b,
+	0x0010, 0xa286, 0x000c, 0x00c0, 0x2a9a, 0x7aaa, 0x2001, 0x0001,
+	0x0078, 0x2aaf, 0xa18c, 0x001f, 0xa18d, 0x00c0, 0x79aa, 0xa286,
+	0x000d, 0x0040, 0x2aa8, 0x7aaa, 0x2001, 0x0002, 0x0078, 0x2aaf,
+	0x78ab, 0x0020, 0x7178, 0x79aa, 0x7aaa, 0x2001, 0x0004, 0x789b,
+	0x0060, 0x78aa, 0x785b, 0x0004, 0x781b, 0x0116, 0x1078, 0x4383,
+	0x7083, 0x000f, 0x70d4, 0xd0b4, 0x0040, 0x2acb, 0xc0b4, 0x70d6,
+	0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
+	0x8001, 0x601a, 0x0c7f, 0x007c, 0x7014, 0xa005, 0x00c0, 0x2ada,
+	0x70d4, 0xd0b4, 0x0040, 0x2adb, 0x70b8, 0xac06, 0x00c0, 0x2adb,
+	0x1078, 0x2aba, 0x007c, 0x017e, 0x71a4, 0xa186, 0x0001, 0x0040,
+	0x2b0d, 0x0d7e, 0x027e, 0x2100, 0x2011, 0x0001, 0xa212, 0x70b4,
+	0x2068, 0x6800, 0xac06, 0x0040, 0x2af4, 0x8211, 0x0040, 0x2b0b,
+	0x1078, 0x2b0f, 0x0078, 0x2ae9, 0x0c7e, 0x2100, 0x2011, 0x0001,
+	0xa212, 0x70b4, 0x2068, 0x6800, 0x2060, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x8211, 0x0040, 0x2b08, 0x1078, 0x2b0f, 0x0078, 0x2afb,
+	0x70a7, 0x0001, 0x0c7f, 0x027f, 0x0d7f, 0x017f, 0x007c, 0xade8,
+	0x0005, 0x70ac, 0xad06, 0x00c0, 0x2b17, 0x70a8, 0x2068, 0x007c,
+	0x1078, 0x4360, 0x00c0, 0x29c1, 0x707c, 0x2068, 0x7774, 0x1078,
+	0x41fe, 0x2c50, 0x1078, 0x4442, 0x789b, 0x0010, 0x6814, 0xa084,
+	0x001f, 0xc0bd, 0x78aa, 0x6e1c, 0x2041, 0x0001, 0x2001, 0x0004,
+	0x0078, 0x2c92, 0x1078, 0x4360, 0x00c0, 0x29c1, 0x789b, 0x0010,
+	0x7060, 0x2068, 0x6f14, 0x70d4, 0xd0b4, 0x0040, 0x2b4c, 0xc0b4,
 	0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x6018, 0x8001, 0x601a, 0x0c7f, 0x157e, 0x2011, 0x0004, 0x7164,
-	0xa186, 0x0001, 0x0040, 0x2d7d, 0xa186, 0x0007, 0x00c0, 0x2d74,
-	0x701f, 0x0005, 0x0078, 0x2d7d, 0x701f, 0x0001, 0x7067, 0x0000,
-	0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x2d7f, 0x7067, 0x0000, 0x2001,
-	0x4a0a, 0x2004, 0xa084, 0x00ff, 0xa086, 0x0018, 0x0040, 0x2d8f,
-	0x7018, 0x7016, 0xa005, 0x00c0, 0x2d8f, 0x70a7, 0x0001, 0x1078,
-	0x4326, 0x20a9, 0x0010, 0x2039, 0x0000, 0x1078, 0x3edb, 0xa7b8,
-	0x0100, 0x00f0, 0x2d95, 0x7000, 0x0079, 0x2d9e, 0x2dcd, 0x2db3,
-	0x2db3, 0x2da8, 0x2dcd, 0x2dcd, 0x2dcd, 0x2da6, 0x1078, 0x28ec,
-	0x7060, 0xa005, 0x0040, 0x2dcd, 0xad06, 0x00c0, 0x2db3, 0x6800,
-	0x7062, 0x0078, 0x2dc5, 0x6820, 0xd084, 0x00c0, 0x2dc1, 0x6f14,
-	0x1078, 0x3fe1, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bb5, 0x0078,
-	0x2dc5, 0x705c, 0x2060, 0x6800, 0x6002, 0x6a1a, 0x6817, 0x0000,
-	0x6820, 0xc09d, 0x6822, 0x1078, 0x202a, 0xb284, 0x0400, 0x0040,
-	0x2dd5, 0x2021, 0x91d0, 0x0078, 0x2dd7, 0x2021, 0x90c0, 0x1078,
-	0x2e2c, 0xb284, 0x0400, 0x0040, 0x2de1, 0x2021, 0x4a98, 0x0078,
-	0x2de3, 0x2021, 0x4a58, 0x1078, 0x2e2c, 0x20a9, 0x0101, 0xb284,
-	0x0400, 0x0040, 0x2def, 0x2021, 0x90d0, 0x0078, 0x2df1, 0x2021,
-	0x8fc0, 0x1078, 0x2e2c, 0x8420, 0x00f0, 0x2df1, 0xb284, 0x0300,
-	0x0040, 0x2dfe, 0x2061, 0x4fc0, 0x0078, 0x2e00, 0x2061, 0x6fc0,
-	0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040, 0x2e1d,
-	0x6018, 0x017e, 0x007e, 0x2011, 0x4a02, 0x220c, 0xa102, 0x2012,
-	0x007f, 0x017f, 0xa102, 0x0050, 0x2e1d, 0x6012, 0x00c0, 0x2e1d,
-	0x2011, 0x4a04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000, 0xace0,
-	0x0010, 0x00f0, 0x2e04, 0x8421, 0x00c0, 0x2e02, 0x157f, 0x7003,
-	0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005, 0x0040,
-	0x2e3f, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000, 0x6820,
-	0xc09d, 0x6822, 0x1078, 0x202a, 0x007f, 0x0078, 0x2e2e, 0x047f,
-	0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2e49, 0x1078,
-	0x28ec, 0x2300, 0x0079, 0x2e4c, 0x2e4f, 0x2eda, 0x2ef7, 0xa282,
-	0x0002, 0x0040, 0x2e55, 0x1078, 0x28ec, 0x7064, 0x7067, 0x0000,
-	0x7083, 0x0000, 0x0079, 0x2e5c, 0x2e64, 0x2e64, 0x2e66, 0x2ea6,
-	0x3bf1, 0x2e64, 0x2ea6, 0x2e64, 0x1078, 0x28ec, 0x7774, 0x1078,
-	0x3edb, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x3fe1, 0x6018, 0xa005,
-	0x0040, 0x2e9d, 0xd7fc, 0x00c0, 0x2e79, 0x2021, 0x90c0, 0x0078,
-	0x2e7b, 0x2021, 0x91d0, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078,
-	0x2f12, 0x0040, 0x2e9d, 0x157e, 0x20a9, 0x0101, 0xd7fc, 0x00c0,
-	0x2e8d, 0x2021, 0x8fc0, 0x0078, 0x2e8f, 0x2021, 0x90d0, 0x047e,
-	0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2f12, 0x047f, 0x0040,
-	0x2e9c, 0x8420, 0x00f0, 0x2e8f, 0x157f, 0x8738, 0xa784, 0x001f,
-	0x00c0, 0x2e6c, 0x0078, 0x2946, 0x0078, 0x2946, 0x7774, 0x1078,
-	0x3fe1, 0x6018, 0xa005, 0x0040, 0x2ed8, 0xd7fc, 0x00c0, 0x2eb4,
-	0x2021, 0x90c0, 0x0078, 0x2eb6, 0x2021, 0x91d0, 0x2009, 0x0005,
-	0x2011, 0x0020, 0x1078, 0x2f12, 0x0040, 0x2ed8, 0x157e, 0x20a9,
-	0x0101, 0xd7fc, 0x00c0, 0x2ec8, 0x2021, 0x8fc0, 0x0078, 0x2eca,
-	0x2021, 0x90d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020, 0x1078,
-	0x2f12, 0x047f, 0x0040, 0x2ed7, 0x8420, 0x00f0, 0x2eca, 0x157f,
-	0x0078, 0x2946, 0x2200, 0x0079, 0x2edd, 0x2ee0, 0x2ee2, 0x2ee2,
-	0x1078, 0x28ec, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002, 0x0040,
-	0x2eeb, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2ef0, 0x691a,
-	0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x40c9, 0x2200,
-	0x0079, 0x2efa, 0x2eff, 0x2ee2, 0x2efd, 0x1078, 0x28ec, 0x1078,
-	0x4326, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b7a, 0x1078, 0x3bd2,
-	0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040, 0x3b7a,
-	0x0078, 0x2946, 0x2404, 0xa005, 0x0040, 0x2f41, 0x2068, 0x2d04,
-	0x007e, 0x6814, 0xa706, 0x0040, 0x2f21, 0x2d20, 0x007f, 0x0078,
-	0x2f13, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x6820, 0xa205,
-	0x6822, 0x1078, 0x202a, 0x2021, 0x4a02, 0x241c, 0x8319, 0x2322,
-	0x6010, 0x8001, 0x6012, 0x00c0, 0x2f3a, 0x2021, 0x4a04, 0x2404,
-	0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078, 0x3bd2,
-	0x007c, 0xa085, 0x0001, 0x0078, 0x2f40, 0x2300, 0x0079, 0x2f48,
-	0x2f4d, 0x2f4b, 0x2fce, 0x1078, 0x28ec, 0x78e4, 0xa005, 0x00d0,
-	0x2f84, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f,
-	0x0040, 0x2f5e, 0xa18c, 0x0300, 0x0078, 0x2f60, 0xa18c, 0x0400,
-	0x0040, 0x2f66, 0x0018, 0x2942, 0x0078, 0x2f68, 0x0028, 0x2942,
-	0x2008, 0xa084, 0x0030, 0x00c0, 0x2f70, 0x781b, 0x005b, 0x007c,
-	0x78ec, 0xa084, 0x0003, 0x0040, 0x2f6d, 0x2100, 0xa084, 0x0007,
-	0x0079, 0x2f7a, 0x2fae, 0x2fb8, 0x2fa3, 0x2f82, 0x4111, 0x4111,
-	0x2f82, 0x2fc3, 0x1078, 0x28ec, 0x7000, 0xa086, 0x0004, 0x00c0,
-	0x2f9e, 0x7064, 0xa086, 0x0002, 0x00c0, 0x2f94, 0x2011, 0x0002,
-	0x2019, 0x0000, 0x0078, 0x2e43, 0x7064, 0xa086, 0x0006, 0x0040,
-	0x2f8e, 0x7064, 0xa086, 0x0004, 0x0040, 0x2f8e, 0x79e4, 0x2001,
-	0x0003, 0x0078, 0x3304, 0x6818, 0xd0fc, 0x0040, 0x2fa9, 0x681b,
-	0x001d, 0x1078, 0x3eae, 0x781b, 0x0061, 0x007c, 0x6818, 0xd0fc,
-	0x0040, 0x2fb4, 0x681b, 0x001d, 0x1078, 0x3eae, 0x0078, 0x40ed,
-	0x6818, 0xd0fc, 0x0040, 0x2fbe, 0x681b, 0x001d, 0x1078, 0x3eae,
-	0x781b, 0x00ef, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x2fc9, 0x681b,
-	0x001d, 0x1078, 0x3eae, 0x781b, 0x00bf, 0x007c, 0xa584, 0x000f,
-	0x00c0, 0x2feb, 0x7000, 0x0079, 0x2fd5, 0x2946, 0x2fdd, 0x2fdf,
-	0x3b7a, 0x3b7a, 0x3b7a, 0x2fdd, 0x2fdd, 0x1078, 0x28ec, 0x1078,
-	0x3bd2, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3b6b, 0x0040,
-	0x3b7a, 0x0078, 0x2946, 0x78e4, 0xa005, 0x00d0, 0x2f84, 0x3208,
-	0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x2ffc,
-	0xa18c, 0x0300, 0x0078, 0x2ffe, 0xa18c, 0x0400, 0x0040, 0x3004,
-	0x0018, 0x2f84, 0x0078, 0x3006, 0x0028, 0x2f84, 0x2008, 0xa084,
-	0x0030, 0x00c0, 0x300e, 0x781b, 0x005b, 0x007c, 0x78ec, 0xa084,
-	0x0003, 0x0040, 0x300b, 0x2100, 0xa184, 0x0007, 0x0079, 0x3018,
-	0x3027, 0x302b, 0x3022, 0x3020, 0x4111, 0x4111, 0x3020, 0x410b,
-	0x1078, 0x28ec, 0x1078, 0x3eb6, 0x781b, 0x0061, 0x007c, 0x1078,
-	0x3eb6, 0x0078, 0x40ed, 0x1078, 0x3eb6, 0x781b, 0x00ef, 0x007c,
-	0x1078, 0x3eb6, 0x781b, 0x00bf, 0x007c, 0x2300, 0x0079, 0x3038,
-	0x303d, 0x303b, 0x303f, 0x1078, 0x28ec, 0x0078, 0x37bd, 0x681b,
-	0x0016, 0x78a3, 0x0000, 0x79e4, 0xa184, 0x0030, 0x0040, 0x37bd,
-	0x78ec, 0xa084, 0x0003, 0x0040, 0x37bd, 0xa184, 0x0100, 0x0040,
-	0x3043, 0xa184, 0x0007, 0x0079, 0x3055, 0x305d, 0x302b, 0x2fa3,
-	0x40c9, 0x4111, 0x4111, 0x40c9, 0x410b, 0x1078, 0x40d5, 0x007c,
-	0xa282, 0x0005, 0x0050, 0x3066, 0x1078, 0x28ec, 0x2300, 0x0079,
-	0x3069, 0x306c, 0x328b, 0x3296, 0x2200, 0x0079, 0x306f, 0x3089,
-	0x3076, 0x3089, 0x3074, 0x326e, 0x1078, 0x28ec, 0x789b, 0x0018,
-	0x78a8, 0xa084, 0x00ff, 0xa082, 0x0020, 0x0048, 0x3e9d, 0xa08a,
-	0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3085, 0x3e9d, 0x3e9d, 0x3e9d,
-	0x3e47, 0x789b, 0x0018, 0x79a8, 0xa184, 0x0080, 0x0040, 0x309a,
-	0x0078, 0x3e9d, 0x7000, 0xa005, 0x00c0, 0x3090, 0x2011, 0x0004,
-	0x0078, 0x3998, 0xa184, 0x00ff, 0xa08a, 0x0010, 0x00c8, 0x3e9d,
-	0x0079, 0x30a2, 0x30b4, 0x30b2, 0x30c9, 0x30cd, 0x318f, 0x3e9d,
-	0x3e9d, 0x3191, 0x3e9d, 0x3e9d, 0x326a, 0x326a, 0x3e9d, 0x3e9d,
-	0x3e9d, 0x326c, 0x1078, 0x28ec, 0xd6e4, 0x0040, 0x30bf, 0x2001,
-	0x0300, 0x8000, 0x8000, 0x783a, 0x781b, 0x00ba, 0x007c, 0x6818,
-	0xd0fc, 0x0040, 0x30c7, 0x681b, 0x001d, 0x0078, 0x30b7, 0x0078,
-	0x40c9, 0x681b, 0x001d, 0x0078, 0x3ea7, 0x6920, 0x6922, 0xa684,
-	0x1800, 0x00c0, 0x3121, 0x6820, 0xd084, 0x00c0, 0x3127, 0x6818,
-	0xa086, 0x0008, 0x00c0, 0x30de, 0x681b, 0x0000, 0xd6d4, 0x0040,
-	0x318c, 0xd6bc, 0x0040, 0x311e, 0x7087, 0x0000, 0x6818, 0xa084,
-	0x003f, 0xa08a, 0x000d, 0x0050, 0x311e, 0xa08a, 0x000c, 0x7186,
-	0x2001, 0x000c, 0x800c, 0x718a, 0x789b, 0x0061, 0x78aa, 0x157e,
-	0x137e, 0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x3110,
-	0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x310c,
-	0x20a1, 0x012b, 0x0078, 0x3112, 0x20a1, 0x022b, 0x0078, 0x3112,
-	0x20a1, 0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80,
-	0x000b, 0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x781b, 0x0064,
-	0x007c, 0xd6e4, 0x0040, 0x3127, 0x781b, 0x0076, 0x007c, 0xa684,
-	0x0060, 0x0040, 0x3189, 0xd6dc, 0x0040, 0x3189, 0xd6fc, 0x00c0,
-	0x3133, 0x0078, 0x314a, 0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8,
-	0x78d0, 0x801b, 0x00c8, 0x313d, 0x8000, 0xa084, 0x003f, 0xa108,
-	0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
-	0xa303, 0x68ae, 0xd6f4, 0x0040, 0x3150, 0xc6f4, 0x7e5a, 0x6eb6,
-	0x7000, 0xa086, 0x0003, 0x00c0, 0x315e, 0x007e, 0x1078, 0x4326,
-	0x1078, 0x45f7, 0x007f, 0x781b, 0x0073, 0x007c, 0xa006, 0x1078,
-	0x46e5, 0x6ab0, 0x69ac, 0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040,
-	0x316d, 0x2200, 0xa422, 0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda,
-	0x6ba6, 0x7bd6, 0x7bde, 0x2300, 0xa405, 0x00c0, 0x317d, 0xc6f5,
-	0x7e5a, 0x6eb6, 0x781b, 0x0073, 0x007c, 0x781b, 0x0073, 0x2200,
-	0xa115, 0x00c0, 0x3186, 0x1078, 0x45f7, 0x007c, 0x1078, 0x462d,
-	0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0064, 0x007c, 0x1078,
-	0x28ec, 0x0078, 0x31dd, 0x6920, 0xd1c4, 0x0040, 0x31a6, 0xc1c4,
-	0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004,
-	0xa084, 0xfff5, 0x6006, 0x0c7f, 0x0078, 0x31d1, 0xd1cc, 0x0040,
-	0x31d1, 0xc1cc, 0x6922, 0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec,
-	0x6002, 0x6004, 0xc0a4, 0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c,
-	0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040,
-	0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a,
-	0xd6d4, 0x00c0, 0x31ce, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075,
-	0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x31d8, 0x781b, 0x0064, 0x007c,
-	0x781b, 0x0076, 0x007c, 0x0078, 0x3ea2, 0x2019, 0x0000, 0x7990,
-	0xa18c, 0x0007, 0x00c0, 0x31eb, 0x6820, 0xa084, 0x0100, 0x0040,
-	0x31db, 0x2009, 0x0008, 0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff,
-	0xa286, 0x0001, 0x00c0, 0x3207, 0x2300, 0x7ca8, 0xa400, 0x2018,
-	0xa102, 0x0040, 0x31ff, 0x0048, 0x31ff, 0x0078, 0x3201, 0x0078,
-	0x3193, 0x24a8, 0x7aa8, 0x00f0, 0x3201, 0x0078, 0x31ed, 0xa284,
-	0x00f0, 0xa086, 0x0020, 0x00c0, 0x325b, 0x8318, 0x8318, 0x2300,
-	0xa102, 0x0040, 0x3217, 0x0048, 0x3217, 0x0078, 0x3258, 0xa286,
-	0x0023, 0x0040, 0x31db, 0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58,
-	0xa684, 0xfff1, 0xc0a5, 0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a,
-	0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4,
-	0x0040, 0x3238, 0x1078, 0x3fdd, 0x1078, 0x3df6, 0x0078, 0x3246,
-	0x0c7e, 0x7058, 0x2060, 0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c,
-	0x0040, 0x31d1, 0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040,
-	0x31d1, 0x789b, 0x0060, 0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4,
-	0x00c0, 0x3255, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c,
-	0x7aa8, 0x0078, 0x31ed, 0x8318, 0x2300, 0xa102, 0x0040, 0x3264,
-	0x0048, 0x3264, 0x0078, 0x31ed, 0xa284, 0x0080, 0x00c0, 0x3ea7,
-	0x0078, 0x3ea2, 0x0078, 0x3ea7, 0x0078, 0x3e9d, 0x7058, 0xa04d,
-	0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040,
-	0x327b, 0x1078, 0x28ec, 0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084,
-	0x00ff, 0xa08a, 0x0004, 0x00c8, 0x3e9d, 0x0079, 0x3287, 0x3e9d,
-	0x3c2c, 0x3e9d, 0x3d9e, 0xa282, 0x0000, 0x00c0, 0x3291, 0x1078,
-	0x28ec, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0xa282, 0x0003,
-	0x00c0, 0x329c, 0x1078, 0x28ec, 0xd4fc, 0x00c0, 0x32bc, 0x7064,
-	0xa005, 0x0040, 0x32a5, 0x1078, 0x28ec, 0x6f14, 0x7776, 0xa7bc,
-	0x8f00, 0x1078, 0x3fe1, 0x6008, 0xa085, 0x0021, 0x600a, 0x8738,
-	0xa784, 0x001f, 0x00c0, 0x32a9, 0x1078, 0x3eb2, 0x7067, 0x0002,
-	0x701f, 0x0009, 0x0078, 0x32be, 0x1078, 0x3ebe, 0x781b, 0x0075,
-	0x007c, 0xa282, 0x0004, 0x0050, 0x32c7, 0x1078, 0x28ec, 0x2300,
-	0x0079, 0x32ca, 0x32cd, 0x346b, 0x34ae, 0xa286, 0x0003, 0x0040,
-	0x3304, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x71d4, 0xd1b4, 0x0078,
-	0x32fc, 0x0040, 0x32fc, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x32fc,
-	0xa282, 0x0002, 0x00c8, 0x32fc, 0x0d7e, 0x783b, 0x8300, 0x781b,
-	0x004c, 0x70bc, 0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
-	0x6898, 0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f,
-	0x2001, 0x0000, 0x0078, 0x3308, 0x783b, 0x1300, 0x781b, 0x004a,
-	0x2001, 0x0000, 0x0078, 0x3308, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0,
-	0x704a, 0x68a0, 0xd0ec, 0x0040, 0x3310, 0x6008, 0xc08d, 0x600a,
-	0xa284, 0x000f, 0x0079, 0x3314, 0x344b, 0x3321, 0x331e, 0x35ae,
-	0x35f2, 0x2946, 0x331c, 0x331c, 0x1078, 0x28ec, 0x6008, 0xc0d4,
-	0x600a, 0xd6e4, 0x00c0, 0x3328, 0x1078, 0x4326, 0x0040, 0x3404,
-	0x7868, 0xa08c, 0x00ff, 0x0040, 0x3369, 0xa186, 0x0008, 0x00c0,
-	0x333e, 0x1078, 0x3bd2, 0x6008, 0xc0a4, 0x600a, 0x1078, 0x3b6b,
-	0x0040, 0x3369, 0x1078, 0x4326, 0x0078, 0x3353, 0xa186, 0x0028,
-	0x00c0, 0x3369, 0x1078, 0x4326, 0x6008, 0xc0a4, 0x600a, 0x6018,
-	0xa005, 0x0040, 0x3353, 0x8001, 0x601a, 0x0040, 0x3353, 0x8001,
-	0x0040, 0x3353, 0x601e, 0x6820, 0xd084, 0x0040, 0x2946, 0xc084,
-	0x6822, 0x705c, 0x0c7e, 0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004,
-	0x6802, 0xa005, 0x2d00, 0x00c0, 0x3366, 0x6002, 0x6006, 0x0078,
-	0x2946, 0x017e, 0x81ff, 0x00c0, 0x33b0, 0x7000, 0xa086, 0x0030,
-	0x0040, 0x33b0, 0x71d4, 0xd1b4, 0x00c0, 0x3397, 0x7060, 0xa005,
-	0x00c0, 0x33b0, 0x70a4, 0xa086, 0x0001, 0x0040, 0x33b0, 0x7003,
+	0x6018, 0x8001, 0x601a, 0x0c7f, 0x1078, 0x41fe, 0x2c50, 0x1078,
+	0x4442, 0x6824, 0xa005, 0x0040, 0x2b5d, 0xa082, 0x0006, 0x0048,
+	0x2b5b, 0x0078, 0x2b5d, 0x6827, 0x0005, 0x6814, 0xa084, 0x001f,
+	0xc0bd, 0x78aa, 0x2031, 0x0020, 0x2041, 0x0001, 0x2001, 0x0003,
+	0x0078, 0x2c92, 0xc28d, 0x72d6, 0x72c0, 0xa200, 0xa015, 0x7154,
+	0x8108, 0xa12a, 0x0048, 0x2b75, 0x71c0, 0x2164, 0x6504, 0x85ff,
+	0x00c0, 0x2b8c, 0x7156, 0x8421, 0x00c0, 0x2b70, 0x70d4, 0xd08c,
+	0x0040, 0x2b88, 0x70d0, 0xa005, 0x00c0, 0x2b88, 0x70d3, 0x000a,
+	0x007c, 0x2200, 0x0078, 0x2b7a, 0x70d4, 0xc08c, 0x70d6, 0x70d3,
+	0x0000, 0x6034, 0xa005, 0x00c0, 0x2b89, 0x6708, 0xa784, 0x073f,
+	0x0040, 0x2bbb, 0xd7d4, 0x00c0, 0x2b89, 0xa784, 0x0021, 0x00c0,
+	0x2b89, 0xa784, 0x0002, 0x0040, 0x2bac, 0xa784, 0x0004, 0x0040,
+	0x2b89, 0xa7bc, 0xfffb, 0x670a, 0xa784, 0x0218, 0x00c0, 0x2b89,
+	0xa784, 0x0100, 0x0040, 0x2bbb, 0x6018, 0xa005, 0x00c0, 0x2b89,
+	0xa7bc, 0xfeff, 0x670a, 0x2568, 0x6823, 0x0000, 0x6e1c, 0xa684,
+	0x000e, 0x6318, 0x0040, 0x2bcc, 0x601c, 0xa302, 0x0048, 0x2bcf,
+	0x0040, 0x2bcf, 0x0078, 0x2b89, 0x83ff, 0x00c0, 0x2b89, 0x2d58,
+	0x2c50, 0x7156, 0xd7bc, 0x00c0, 0x2bd8, 0x7028, 0x6022, 0x603a,
+	0xc7bc, 0x670a, 0x68c0, 0xa065, 0xa04d, 0x6100, 0x2a60, 0x2041,
+	0x0001, 0x6b14, 0xa39c, 0x001f, 0xa39d, 0x00c0, 0xd1fc, 0x0040,
+	0x2bec, 0xd684, 0x0040, 0x2bee, 0xa39c, 0xffbf, 0xd6a4, 0x0040,
+	0x2bf3, 0xa39d, 0x0020, 0xa684, 0x000e, 0x00c0, 0x2c3e, 0xc7a5,
+	0x670a, 0x2c00, 0x68c6, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12,
+	0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8,
+	0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa,
+	0x0078, 0x2c8a, 0x8739, 0x77a6, 0x2750, 0x77b0, 0xa7b0, 0x0005,
+	0x70ac, 0xa606, 0x00c0, 0x2c1d, 0x76a8, 0x76b2, 0x2c3a, 0x8738,
+	0x2d3a, 0x8738, 0x283a, 0x8738, 0x233a, 0x8738, 0x253a, 0x7830,
+	0xd0bc, 0x0040, 0x2c35, 0x2091, 0x8000, 0x2091, 0x303d, 0x70d4,
+	0xa084, 0x303d, 0x2091, 0x8000, 0x2090, 0xaad5, 0x0000, 0x0040,
+	0x2c3d, 0x8421, 0x2200, 0x00c0, 0x2b6f, 0x007c, 0xd1dc, 0x0040,
+	0x3e00, 0x2029, 0x0020, 0xd69c, 0x00c0, 0x2c4b, 0x8528, 0xd68c,
+	0x00c0, 0x2c4b, 0x8528, 0x8840, 0x6f14, 0x610c, 0x8108, 0xa18c,
+	0x00ff, 0x70cc, 0xa160, 0x2c64, 0x8cff, 0x0040, 0x2c6a, 0x6014,
+	0xa706, 0x00c0, 0x2c53, 0x60b8, 0x8001, 0x60ba, 0x00c0, 0x2c4e,
+	0x2a60, 0x6008, 0xa085, 0x0100, 0x600a, 0x2200, 0x8421, 0x00c0,
+	0x2b6f, 0x007c, 0x2a60, 0x610e, 0x69be, 0x2c00, 0x68c6, 0x8840,
+	0x6008, 0xc0d5, 0x600a, 0x77a4, 0xa786, 0x0001, 0x00c0, 0x2c12,
+	0x70d4, 0xd0b4, 0x00c0, 0x2c12, 0x7000, 0xa082, 0x0002, 0x00c8,
+	0x2c12, 0x7830, 0xd0bc, 0x00c0, 0x2c12, 0x789b, 0x0010, 0x7baa,
+	0x7daa, 0x79aa, 0x2001, 0x0002, 0x007e, 0x6018, 0x8000, 0x601a,
+	0x0078, 0x2c93, 0x007e, 0x2960, 0x6104, 0x2a60, 0xa184, 0x0018,
+	0x0040, 0x2caf, 0xa184, 0x0010, 0x0040, 0x2ca2, 0x1078, 0x4011,
+	0x00c0, 0x2cd4, 0xa184, 0x0008, 0x0040, 0x2caf, 0x69a0, 0xa184,
+	0x0600, 0x00c0, 0x2caf, 0x1078, 0x3ef5, 0x0078, 0x2cd4, 0x69a0,
+	0xa184, 0x1e00, 0x0040, 0x2cdf, 0xa184, 0x0800, 0x0040, 0x2cc8,
+	0x0c7e, 0x2960, 0x6000, 0xa085, 0x2000, 0x6002, 0x6104, 0xa18d,
+	0x0010, 0x6106, 0x0c7f, 0x1078, 0x4011, 0x00c0, 0x2cd4, 0x69a0,
+	0xa184, 0x0200, 0x0040, 0x2cd0, 0x1078, 0x3f54, 0x0078, 0x2cd4,
+	0xa184, 0x0400, 0x00c0, 0x2cab, 0x69a0, 0xa184, 0x1000, 0x0040,
+	0x2cdf, 0x6914, 0xa18c, 0xff00, 0x810f, 0x1078, 0x279f, 0x027f,
+	0xa68c, 0x00e0, 0xa684, 0x0060, 0x0040, 0x2cec, 0xa086, 0x0060,
+	0x00c0, 0x2cec, 0xa18d, 0x4000, 0xa18d, 0x0104, 0x69b6, 0x789b,
+	0x0060, 0x2800, 0x78aa, 0x6818, 0xc0fd, 0x681a, 0xd6bc, 0x0040,
+	0x2d07, 0xc0fc, 0x7087, 0x0000, 0xa08a, 0x000d, 0x0050, 0x2d05,
+	0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a, 0x78aa,
+	0x3518, 0x3340, 0x3428, 0x8000, 0x80ac, 0xaf80, 0x002b, 0x20a0,
+	0x789b, 0x0000, 0xad80, 0x000b, 0x2098, 0x53a6, 0x23a8, 0x2898,
+	0x25a0, 0xa286, 0x0020, 0x00c0, 0x2d3f, 0x70d4, 0xc0b5, 0x70d6,
+	0x2c00, 0x70ba, 0x2d00, 0x70be, 0x6814, 0xc0fc, 0x8007, 0x7882,
+	0xa286, 0x0002, 0x0040, 0x2d75, 0x70a4, 0x8000, 0x70a6, 0x74b4,
+	0xa498, 0x0005, 0x70ac, 0xa306, 0x00c0, 0x2d37, 0x73a8, 0x73b6,
+	0xa286, 0x0010, 0x0040, 0x29c1, 0x0d7f, 0x0c7f, 0x007c, 0x7000,
+	0xa005, 0x00c0, 0x2d1d, 0xa286, 0x0002, 0x00c0, 0x2d8f, 0x1078,
+	0x4360, 0x00c0, 0x2d1d, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x2091,
+	0x8000, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de,
+	0x6898, 0x78d2, 0x78da, 0x2091, 0x8001, 0x7808, 0xc08d, 0x780a,
+	0x127e, 0x0d7e, 0x0c7e, 0x70d4, 0xa084, 0x2700, 0x2090, 0x0c7f,
+	0x0d7f, 0x127f, 0x2900, 0x705a, 0x68bc, 0x7042, 0x7003, 0x0002,
+	0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x7830, 0xd0bc, 0x0040,
+	0x2d81, 0x2091, 0x303d, 0x70d4, 0xa084, 0x303d, 0x2091, 0x8000,
+	0x2090, 0x70a4, 0xa005, 0x00c0, 0x2d86, 0x007c, 0x8421, 0x0040,
+	0x2d85, 0x7250, 0x70c0, 0xa200, 0xa015, 0x0078, 0x2b6f, 0xa286,
+	0x0010, 0x00c0, 0x2dc0, 0x1078, 0x4360, 0x00c0, 0x2d1d, 0x6814,
+	0xc0fc, 0x8007, 0x7882, 0x781b, 0x005b, 0x68b4, 0x785a, 0x6894,
+	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0x7808, 0xc08d, 0x780a,
+	0x70a4, 0x8000, 0x70a6, 0x74b4, 0xa490, 0x0005, 0x70ac, 0xa206,
+	0x00c0, 0x2db3, 0x72a8, 0x72b6, 0x2900, 0x705a, 0x68bc, 0x7042,
+	0x7003, 0x0002, 0x2d00, 0x704e, 0xad80, 0x0009, 0x7046, 0x007c,
+	0x6bb4, 0xa39d, 0x2000, 0x7b5a, 0x6814, 0xc0fc, 0x8007, 0x7882,
+	0x6b94, 0x7bd6, 0x7bde, 0x6e98, 0x7ed2, 0x7eda, 0x781b, 0x005b,
+	0x2900, 0x705a, 0x7202, 0x7808, 0xc08d, 0x780a, 0x2300, 0xa605,
+	0x0040, 0x2deb, 0x70d4, 0xa084, 0x2700, 0xa086, 0x2300, 0x00c0,
+	0x2de5, 0x2009, 0x0000, 0x0078, 0x2de7, 0x2009, 0x0001, 0xa284,
+	0x000f, 0x1079, 0x2def, 0xad80, 0x0009, 0x7046, 0x007c, 0x2df7,
+	0x48bd, 0x48bd, 0x48aa, 0x48bd, 0x2df7, 0x2df7, 0x2df7, 0x1078,
+	0x296b, 0x7808, 0xa084, 0xfffd, 0x780a, 0x1078, 0x295e, 0x0f7e,
+	0x2079, 0x4e00, 0x78ac, 0x0f7f, 0xd084, 0x0040, 0x2e21, 0x7064,
+	0xa086, 0x0001, 0x00c0, 0x2e0f, 0x7066, 0x0078, 0x2ef8, 0x7064,
+	0xa086, 0x0005, 0x00c0, 0x2e1f, 0x707c, 0x2068, 0x681b, 0x0004,
+	0x6817, 0x0000, 0x6820, 0xa084, 0x00ff, 0xc09d, 0x6822, 0x7067,
+	0x0000, 0x70a7, 0x0000, 0x70a8, 0x70b2, 0x70b6, 0x1078, 0x2aba,
+	0x157e, 0x2011, 0x0004, 0x7164, 0xa186, 0x0001, 0x0040, 0x2e41,
+	0xa186, 0x0007, 0x00c0, 0x2e38, 0x701f, 0x0005, 0x0078, 0x2e41,
+	0x701f, 0x0001, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078,
+	0x2e43, 0x7067, 0x0000, 0x2001, 0x4e0a, 0x2004, 0xa084, 0x00ff,
+	0xa086, 0x0018, 0x0040, 0x2e53, 0x7018, 0x7016, 0xa005, 0x00c0,
+	0x2e53, 0x70a7, 0x0001, 0x067e, 0x1078, 0x4586, 0x20a9, 0x0010,
+	0x2039, 0x0000, 0x1078, 0x40f8, 0xa7b8, 0x0100, 0x00f0, 0x2e5a,
+	0x067f, 0x7000, 0x0079, 0x2e64, 0x2e9e, 0x2e79, 0x2e79, 0x2e6e,
+	0x2e9e, 0x2e9e, 0x2e9e, 0x2e6c, 0x1078, 0x296b, 0x7060, 0xa005,
+	0x0040, 0x2e9e, 0xad06, 0x00c0, 0x2e79, 0x6800, 0x7062, 0x0078,
+	0x2e8b, 0x6820, 0xd084, 0x00c0, 0x2e87, 0x6f14, 0x1078, 0x41fe,
+	0x6008, 0xc0d4, 0x600a, 0x1078, 0x3dd0, 0x0078, 0x2e8b, 0x705c,
+	0x2060, 0x6800, 0x6002, 0xa684, 0x5f00, 0x681e, 0x6818, 0xd0fc,
+	0x0040, 0x2e93, 0x6a1a, 0x6817, 0x0000, 0x682b, 0x0000, 0x6820,
+	0xa084, 0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0xb284, 0x0400,
+	0x0040, 0x2ea6, 0x2021, 0x95d0, 0x0078, 0x2ea8, 0x2021, 0x94c0,
+	0x1078, 0x2efd, 0xb284, 0x0400, 0x0040, 0x2eb2, 0x2021, 0x4e98,
+	0x0078, 0x2eb4, 0x2021, 0x4e58, 0x1078, 0x2efd, 0x20a9, 0x0101,
+	0xb284, 0x0400, 0x0040, 0x2ec0, 0x2021, 0x94d0, 0x0078, 0x2ec2,
+	0x2021, 0x93c0, 0x1078, 0x2efd, 0x8420, 0x00f0, 0x2ec2, 0xb284,
+	0x0300, 0x0040, 0x2ecf, 0x2061, 0x53c0, 0x0078, 0x2ed1, 0x2061,
+	0x73c0, 0x2021, 0x0002, 0x20a9, 0x0100, 0x6110, 0x81ff, 0x0040,
+	0x2eee, 0x6018, 0x017e, 0x007e, 0x2011, 0x4e02, 0x220c, 0xa102,
+	0x2012, 0x007f, 0x017f, 0xa102, 0x0050, 0x2eee, 0x6012, 0x00c0,
+	0x2eee, 0x2011, 0x4e04, 0x2204, 0xc0a5, 0x2012, 0x601b, 0x0000,
+	0xace0, 0x0010, 0x00f0, 0x2ed5, 0x8421, 0x00c0, 0x2ed3, 0x157f,
+	0x7003, 0x0000, 0x704f, 0x0000, 0x007c, 0x047e, 0x2404, 0xa005,
+	0x0040, 0x2f18, 0x2068, 0x6800, 0x007e, 0x6a1a, 0x6817, 0x0000,
+	0x682b, 0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084,
+	0x00ff, 0xc09d, 0x6822, 0x1078, 0x202c, 0x007f, 0x0078, 0x2eff,
+	0x047f, 0x2023, 0x0000, 0x007c, 0xa282, 0x0003, 0x0050, 0x2f22,
+	0x1078, 0x296b, 0x2300, 0x0079, 0x2f25, 0x2f28, 0x2fb3, 0x2fd0,
+	0xa282, 0x0002, 0x0040, 0x2f2e, 0x1078, 0x296b, 0x7064, 0x7067,
+	0x0000, 0x7083, 0x0000, 0x0079, 0x2f35, 0x2f3d, 0x2f3d, 0x2f3f,
+	0x2f7f, 0x3e0c, 0x2f3d, 0x2f7f, 0x2f3d, 0x1078, 0x296b, 0x7774,
+	0x1078, 0x40f8, 0x7774, 0xa7bc, 0x8f00, 0x1078, 0x41fe, 0x6018,
+	0xa005, 0x0040, 0x2f76, 0xd7fc, 0x00c0, 0x2f52, 0x2021, 0x94c0,
+	0x0078, 0x2f54, 0x2021, 0x95d0, 0x2009, 0x0005, 0x2011, 0x0010,
+	0x1078, 0x2feb, 0x0040, 0x2f76, 0x157e, 0x20a9, 0x0101, 0xd7fc,
+	0x00c0, 0x2f66, 0x2021, 0x93c0, 0x0078, 0x2f68, 0x2021, 0x94d0,
+	0x047e, 0x2009, 0x0005, 0x2011, 0x0010, 0x1078, 0x2feb, 0x047f,
+	0x0040, 0x2f75, 0x8420, 0x00f0, 0x2f68, 0x157f, 0x8738, 0xa784,
+	0x001f, 0x00c0, 0x2f45, 0x0078, 0x29c5, 0x0078, 0x29c5, 0x7774,
+	0x1078, 0x41fe, 0x6018, 0xa005, 0x0040, 0x2fb1, 0xd7fc, 0x00c0,
+	0x2f8d, 0x2021, 0x94c0, 0x0078, 0x2f8f, 0x2021, 0x95d0, 0x2009,
+	0x0005, 0x2011, 0x0020, 0x1078, 0x2feb, 0x0040, 0x2fb1, 0x157e,
+	0x20a9, 0x0101, 0xd7fc, 0x00c0, 0x2fa1, 0x2021, 0x93c0, 0x0078,
+	0x2fa3, 0x2021, 0x94d0, 0x047e, 0x2009, 0x0005, 0x2011, 0x0020,
+	0x1078, 0x2feb, 0x047f, 0x0040, 0x2fb0, 0x8420, 0x00f0, 0x2fa3,
+	0x157f, 0x0078, 0x29c5, 0x2200, 0x0079, 0x2fb6, 0x2fb9, 0x2fbb,
+	0x2fbb, 0x1078, 0x296b, 0x2009, 0x0012, 0x7064, 0xa086, 0x0002,
+	0x0040, 0x2fc4, 0x2009, 0x000e, 0x6818, 0xd0fc, 0x0040, 0x2fc9,
+	0x691a, 0x7067, 0x0000, 0x70d4, 0xc0dd, 0x70d6, 0x0078, 0x430d,
+	0x2200, 0x0079, 0x2fd3, 0x2fd8, 0x2fbb, 0x2fd6, 0x1078, 0x296b,
+	0x1078, 0x4586, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3d7e, 0x1078,
+	0x3ded, 0x6008, 0xa084, 0xfbef, 0x600a, 0x1078, 0x3d6f, 0x0040,
+	0x3d7e, 0x0078, 0x29c5, 0x2404, 0xa005, 0x0040, 0x3024, 0x2068,
+	0x2d04, 0x007e, 0x6814, 0xa706, 0x0040, 0x2ffa, 0x2d20, 0x007f,
+	0x0078, 0x2fec, 0x007f, 0x2022, 0x691a, 0x6817, 0x0000, 0x682b,
+	0x0000, 0x68b4, 0xa084, 0x5f00, 0x681e, 0x6820, 0xa084, 0x00ff,
+	0xa205, 0x6822, 0x1078, 0x202c, 0x2021, 0x4e02, 0x241c, 0x8319,
+	0x2322, 0x6010, 0x8001, 0x6012, 0x00c0, 0x301b, 0x2021, 0x4e04,
+	0x2404, 0xc0a5, 0x2022, 0x6008, 0xa084, 0xf9ef, 0x600a, 0x1078,
+	0x2adb, 0x1078, 0x3ded, 0x007c, 0xa085, 0x0001, 0x0078, 0x3023,
+	0x2300, 0x0079, 0x302b, 0x3030, 0x302e, 0x30b0, 0x1078, 0x296b,
+	0x78e4, 0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x3041, 0xa18c, 0x0300, 0x0078,
+	0x3043, 0xa18c, 0x0400, 0x0040, 0x3049, 0x0018, 0x29c1, 0x0078,
+	0x304b, 0x0028, 0x29c1, 0x2008, 0xa084, 0x0030, 0x00c0, 0x3052,
+	0x0078, 0x3770, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3050, 0x2100,
+	0xa084, 0x0007, 0x0079, 0x305c, 0x3090, 0x309a, 0x3085, 0x3064,
+	0x4355, 0x4355, 0x3064, 0x30a5, 0x1078, 0x296b, 0x7000, 0xa086,
+	0x0004, 0x00c0, 0x3080, 0x7064, 0xa086, 0x0002, 0x00c0, 0x3076,
+	0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2f1c, 0x7064, 0xa086,
+	0x0006, 0x0040, 0x3070, 0x7064, 0xa086, 0x0004, 0x0040, 0x3070,
+	0x79e4, 0x2001, 0x0003, 0x0078, 0x33fa, 0x6818, 0xd0fc, 0x0040,
+	0x308b, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x0064, 0x007c,
+	0x6818, 0xd0fc, 0x0040, 0x3096, 0x681b, 0x001d, 0x1078, 0x40c8,
+	0x0078, 0x4331, 0x6818, 0xd0fc, 0x0040, 0x30a0, 0x681b, 0x001d,
+	0x1078, 0x40c8, 0x781b, 0x00f8, 0x007c, 0x6818, 0xd0fc, 0x0040,
+	0x30ab, 0x681b, 0x001d, 0x1078, 0x40c8, 0x781b, 0x00c8, 0x007c,
+	0xa584, 0x000f, 0x00c0, 0x30cf, 0x1078, 0x295e, 0x7000, 0x0079,
+	0x30b9, 0x29c5, 0x30c1, 0x30c3, 0x3d7e, 0x3d7e, 0x3d7e, 0x30c1,
+	0x30c1, 0x1078, 0x296b, 0x1078, 0x3ded, 0x6008, 0xa084, 0xfbef,
+	0x600a, 0x1078, 0x3d6f, 0x0040, 0x3d7e, 0x0078, 0x29c5, 0x78e4,
+	0xa005, 0x00d0, 0x3066, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004,
+	0xd0ec, 0x007f, 0x0040, 0x30e0, 0xa18c, 0x0300, 0x0078, 0x30e2,
+	0xa18c, 0x0400, 0x0040, 0x30e8, 0x0018, 0x3066, 0x0078, 0x30ea,
+	0x0028, 0x3066, 0x2008, 0xa084, 0x0030, 0x00c0, 0x30f2, 0x781b,
+	0x005b, 0x007c, 0x78ec, 0xa084, 0x0003, 0x0040, 0x30ef, 0x2100,
+	0xa184, 0x0007, 0x0079, 0x30fc, 0x310b, 0x310f, 0x3106, 0x3104,
+	0x4355, 0x4355, 0x3104, 0x434f, 0x1078, 0x296b, 0x1078, 0x40d0,
+	0x781b, 0x0064, 0x007c, 0x1078, 0x40d0, 0x0078, 0x4331, 0x1078,
+	0x40d0, 0x781b, 0x00f8, 0x007c, 0x1078, 0x40d0, 0x781b, 0x00c8,
+	0x007c, 0x2300, 0x0079, 0x311c, 0x3121, 0x311f, 0x3123, 0x1078,
+	0x296b, 0x0078, 0x395f, 0x681b, 0x0016, 0x78a3, 0x0000, 0x79e4,
+	0xa184, 0x0030, 0x0040, 0x395f, 0x78ec, 0xa084, 0x0003, 0x0040,
+	0x395f, 0xa184, 0x0100, 0x0040, 0x3127, 0xa184, 0x0007, 0x0079,
+	0x3139, 0x3141, 0x310f, 0x3085, 0x430d, 0x4355, 0x4355, 0x430d,
+	0x434f, 0x1078, 0x4319, 0x007c, 0xa282, 0x0005, 0x0050, 0x314a,
+	0x1078, 0x296b, 0x2300, 0x0079, 0x314d, 0x3150, 0x3380, 0x338b,
+	0x2200, 0x0079, 0x3153, 0x316d, 0x315a, 0x316d, 0x3158, 0x3363,
+	0x1078, 0x296b, 0x789b, 0x0018, 0x78a8, 0xa084, 0x00ff, 0xa082,
+	0x0020, 0x0048, 0x40b7, 0xa08a, 0x0004, 0x00c8, 0x40b7, 0x0079,
+	0x3169, 0x40b7, 0x40b7, 0x40b7, 0x4061, 0x789b, 0x0018, 0x79a8,
+	0xa184, 0x0080, 0x0040, 0x317e, 0x0078, 0x40b7, 0x7000, 0xa005,
+	0x00c0, 0x3174, 0x2011, 0x0004, 0x0078, 0x3b4a, 0xa184, 0x00ff,
+	0xa08a, 0x0010, 0x00c8, 0x40b7, 0x0079, 0x3186, 0x3198, 0x3196,
+	0x31ad, 0x31b1, 0x3284, 0x40b7, 0x40b7, 0x3286, 0x40b7, 0x40b7,
+	0x335f, 0x335f, 0x40b7, 0x40b7, 0x40b7, 0x3361, 0x1078, 0x296b,
+	0xd6e4, 0x0040, 0x31a3, 0x2001, 0x0300, 0x8000, 0x8000, 0x783a,
+	0x781b, 0x00c3, 0x007c, 0x6818, 0xd0fc, 0x0040, 0x31ab, 0x681b,
+	0x001d, 0x0078, 0x319b, 0x0078, 0x430d, 0x681b, 0x001d, 0x0078,
+	0x40c1, 0x6920, 0x6922, 0xa684, 0x1800, 0x00c0, 0x3216, 0x6820,
+	0xd084, 0x00c0, 0x321c, 0x6818, 0xa086, 0x0008, 0x00c0, 0x31c2,
+	0x681b, 0x0000, 0xd6d4, 0x0040, 0x3281, 0xd6bc, 0x0040, 0x3202,
+	0x7087, 0x0000, 0x6818, 0xa084, 0x003f, 0xa08a, 0x000d, 0x0050,
+	0x3202, 0xa08a, 0x000c, 0x7186, 0x2001, 0x000c, 0x800c, 0x718a,
+	0x789b, 0x0061, 0x78aa, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208,
+	0xa18c, 0x0300, 0x0040, 0x31f4, 0x007e, 0x2001, 0x4e04, 0x2004,
+	0xd0ec, 0x007f, 0x0040, 0x31f0, 0x20a1, 0x012b, 0x0078, 0x31f6,
+	0x20a1, 0x022b, 0x0078, 0x31f6, 0x20a1, 0x012b, 0x017f, 0x789b,
+	0x0000, 0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f,
+	0x137f, 0x157f, 0x6038, 0xa005, 0x00c0, 0x3211, 0x681c, 0xa084,
+	0x000e, 0x0040, 0x40c1, 0x1078, 0x40d7, 0x782b, 0x3008, 0x0078,
+	0x3213, 0x8001, 0x603a, 0x781b, 0x0067, 0x007c, 0xd6e4, 0x0040,
+	0x321c, 0x781b, 0x0079, 0x007c, 0xa684, 0x0060, 0x0040, 0x327e,
+	0xd6dc, 0x0040, 0x327e, 0xd6fc, 0x00c0, 0x3228, 0x0078, 0x323f,
+	0xc6fc, 0x7e5a, 0x6eb6, 0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8,
+	0x3232, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98,
+	0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0xd6f4,
+	0x0040, 0x3245, 0xc6f4, 0x7e5a, 0x6eb6, 0x7000, 0xa086, 0x0003,
+	0x00c0, 0x3253, 0x007e, 0x1078, 0x4586, 0x1078, 0x48bd, 0x007f,
+	0x781b, 0x0076, 0x007c, 0xa006, 0x1078, 0x49c3, 0x6ab0, 0x69ac,
+	0x6c98, 0x6b94, 0x2200, 0xa105, 0x0040, 0x3262, 0x2200, 0xa422,
+	0x2100, 0xa31b, 0x6caa, 0x7cd2, 0x7cda, 0x6ba6, 0x7bd6, 0x7bde,
+	0x2300, 0xa405, 0x00c0, 0x3272, 0xc6f5, 0x7e5a, 0x6eb6, 0x781b,
+	0x0076, 0x007c, 0x781b, 0x0076, 0x2200, 0xa115, 0x00c0, 0x327b,
+	0x1078, 0x48bd, 0x007c, 0x1078, 0x48f5, 0x007c, 0x781b, 0x0079,
+	0x007c, 0x781b, 0x0067, 0x007c, 0x1078, 0x296b, 0x0078, 0x32d2,
+	0x6920, 0xd1c4, 0x0040, 0x329b, 0xc1c4, 0x6922, 0x0c7e, 0x7058,
+	0x2060, 0x6000, 0xc0e4, 0x6002, 0x6004, 0xa084, 0xfff5, 0x6006,
+	0x0c7f, 0x0078, 0x32c6, 0xd1cc, 0x0040, 0x32c6, 0xc1cc, 0x6922,
+	0x0c7e, 0x7058, 0x2060, 0x6000, 0xc0ec, 0x6002, 0x6004, 0xc0a4,
+	0x6006, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078,
+	0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060,
+	0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x32c3,
+	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7e58, 0xd6d4,
+	0x00c0, 0x32cd, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079, 0x007c,
+	0x0078, 0x40bc, 0x2019, 0x0000, 0x7990, 0xa18c, 0x0007, 0x00c0,
+	0x32e0, 0x6820, 0xa084, 0x0100, 0x0040, 0x32d0, 0x2009, 0x0008,
+	0x789b, 0x0010, 0x78a8, 0xa094, 0x00ff, 0xa286, 0x0001, 0x00c0,
+	0x32fc, 0x2300, 0x7ca8, 0xa400, 0x2018, 0xa102, 0x0040, 0x32f4,
+	0x0048, 0x32f4, 0x0078, 0x32f6, 0x0078, 0x3288, 0x24a8, 0x7aa8,
+	0x00f0, 0x32f6, 0x0078, 0x32e2, 0xa284, 0x00f0, 0xa086, 0x0020,
+	0x00c0, 0x3350, 0x8318, 0x8318, 0x2300, 0xa102, 0x0040, 0x330c,
+	0x0048, 0x330c, 0x0078, 0x334d, 0xa286, 0x0023, 0x0040, 0x32d0,
+	0x681c, 0xa084, 0xfff1, 0x681e, 0x7e58, 0xa684, 0xfff1, 0xc0a5,
+	0x2030, 0x7e5a, 0x6008, 0xc0a5, 0x600a, 0x0c7e, 0x7058, 0x2060,
+	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd1a4, 0x0040, 0x332d, 0x1078,
+	0x41fa, 0x1078, 0x4011, 0x0078, 0x333b, 0x0c7e, 0x7058, 0x2060,
+	0x6004, 0x2008, 0x2c48, 0x0c7f, 0xd19c, 0x0040, 0x32c6, 0x1078,
+	0x41fa, 0x1078, 0x3ef5, 0x88ff, 0x0040, 0x32c6, 0x789b, 0x0060,
+	0x2800, 0x78aa, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x334a, 0x781b,
+	0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x7aa8, 0x0078, 0x32e2,
+	0x8318, 0x2300, 0xa102, 0x0040, 0x3359, 0x0048, 0x3359, 0x0078,
+	0x32e2, 0xa284, 0x0080, 0x00c0, 0x40c1, 0x0078, 0x40bc, 0x0078,
+	0x40c1, 0x0078, 0x40b7, 0x7058, 0xa04d, 0x789b, 0x0018, 0x78a8,
+	0xa084, 0x00ff, 0xa08e, 0x0001, 0x0040, 0x3370, 0x1078, 0x296b,
+	0x7aa8, 0xa294, 0x00ff, 0x78a8, 0xa084, 0x00ff, 0xa08a, 0x0004,
+	0x00c8, 0x40b7, 0x0079, 0x337c, 0x40b7, 0x3e46, 0x40b7, 0x3fb9,
+	0xa282, 0x0000, 0x00c0, 0x3386, 0x1078, 0x296b, 0x1078, 0x40c8,
+	0x781b, 0x0078, 0x007c, 0xa282, 0x0003, 0x00c0, 0x3391, 0x1078,
+	0x296b, 0xd4fc, 0x00c0, 0x33b1, 0x7064, 0xa005, 0x0040, 0x339a,
+	0x1078, 0x296b, 0x6f14, 0x7776, 0xa7bc, 0x8f00, 0x1078, 0x41fe,
+	0x6008, 0xa085, 0x0021, 0x600a, 0x8738, 0xa784, 0x001f, 0x00c0,
+	0x339e, 0x1078, 0x40cc, 0x7067, 0x0002, 0x701f, 0x0009, 0x0078,
+	0x33b3, 0x1078, 0x40db, 0x781b, 0x0078, 0x007c, 0xa282, 0x0004,
+	0x0050, 0x33bc, 0x1078, 0x296b, 0x2300, 0x0079, 0x33bf, 0x33c2,
+	0x3582, 0x35c5, 0xa286, 0x0003, 0x0040, 0x33fa, 0x7200, 0x7cd8,
+	0x7ddc, 0x7fd0, 0x71d4, 0xd1bc, 0x00c0, 0x33f2, 0xd1b4, 0x0040,
+	0x33f2, 0x7868, 0xa084, 0x00ff, 0x00c0, 0x33f2, 0xa282, 0x0002,
+	0x00c8, 0x33f2, 0x0d7e, 0x783b, 0x8300, 0x781b, 0x004c, 0x70bc,
+	0xa06d, 0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2,
+	0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x2001, 0x0000,
+	0x0078, 0x33fe, 0x783b, 0x1300, 0x781b, 0x004a, 0x2001, 0x0000,
+	0x0078, 0x33fe, 0x7200, 0x7cd8, 0x7ddc, 0x7fd0, 0x704a, 0x68a0,
+	0xd0ec, 0x0040, 0x3406, 0x6008, 0xc08d, 0x600a, 0xa284, 0x000f,
+	0x0079, 0x340a, 0x3562, 0x3417, 0x3414, 0x36c8, 0x3754, 0x29c5,
+	0x3412, 0x3412, 0x1078, 0x296b, 0x6008, 0xc0d4, 0x600a, 0xd6e4,
+	0x0040, 0x341f, 0x7048, 0xa086, 0x0014, 0x00c0, 0x343f, 0x1078,
+	0x4586, 0x2009, 0x0000, 0x6818, 0xd0fc, 0x0040, 0x3428, 0x7048,
+	0xa086, 0x0014, 0x0040, 0x3439, 0x6818, 0xa086, 0x0008, 0x00c0,
+	0x351a, 0x7858, 0xd09c, 0x0040, 0x351a, 0x6820, 0xd0ac, 0x0040,
+	0x351a, 0x681b, 0x0014, 0x2009, 0x0002, 0x0078, 0x347e, 0x7868,
+	0xa08c, 0x00ff, 0x0040, 0x347e, 0xa186, 0x0008, 0x00c0, 0x3455,
+	0x6008, 0xc0a4, 0x600a, 0x1078, 0x3d6f, 0x0040, 0x347e, 0x1078,
+	0x3ded, 0x1078, 0x4586, 0x0078, 0x3466, 0xa186, 0x0028, 0x00c0,
+	0x347e, 0x6018, 0xa005, 0x0040, 0x3448, 0x8001, 0x0040, 0x3448,
+	0x8001, 0x0040, 0x3448, 0x601e, 0x0078, 0x3448, 0x6820, 0xd084,
+	0x0040, 0x29c5, 0xc084, 0x6822, 0x1078, 0x2acc, 0x705c, 0x0c7e,
+	0x2060, 0x6800, 0x6002, 0x0c7f, 0x6004, 0x6802, 0xa005, 0x2d00,
+	0x00c0, 0x347b, 0x6002, 0x6006, 0x0078, 0x29c5, 0x017e, 0x81ff,
+	0x00c0, 0x34c8, 0x7000, 0xa086, 0x0030, 0x0040, 0x34c8, 0x71d4,
+	0xd1bc, 0x00c0, 0x34c8, 0xd1b4, 0x00c0, 0x34af, 0x7060, 0xa005,
+	0x00c0, 0x34c8, 0x70a4, 0xa086, 0x0001, 0x0040, 0x34c8, 0x7003,
 	0x0000, 0x047e, 0x057e, 0x077e, 0x067e, 0x0c7e, 0x0d7e, 0x1078,
-	0x296c, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4,
-	0xd1b4, 0x00c0, 0x33b0, 0x7003, 0x0040, 0x0078, 0x33b0, 0x1078,
-	0x411c, 0x00c0, 0x33b0, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d,
+	0x29ee, 0x0d7f, 0x0c7f, 0x067f, 0x077f, 0x057f, 0x047f, 0x71d4,
+	0xd1b4, 0x00c0, 0x34c8, 0x7003, 0x0040, 0x0078, 0x34c8, 0x1078,
+	0x4360, 0x00c0, 0x34c8, 0x781b, 0x005b, 0x0d7e, 0x70bc, 0xa06d,
 	0x68b4, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da,
 	0xc1b4, 0x71d6, 0x7003, 0x0030, 0x7808, 0xc08d, 0x780a, 0x0d7f,
-	0x1078, 0x34e8, 0x017f, 0x81ff, 0x0040, 0x3403, 0xa684, 0xdf00,
-	0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x3404,
-	0x70d4, 0xd0b4, 0x0040, 0x33d1, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8,
-	0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
-	0x0c7f, 0x6820, 0xd0dc, 0x00c0, 0x3404, 0x8717, 0xa294, 0x000f,
-	0x8213, 0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x33e3, 0xa290,
-	0x4ec0, 0x0078, 0x33e5, 0xa290, 0x4f40, 0xa290, 0x0000, 0x221c,
-	0xd3c4, 0x00c0, 0x33ed, 0x0078, 0x33f3, 0x8210, 0x2204, 0xa085,
-	0x0018, 0x2012, 0x8211, 0xd3d4, 0x0040, 0x33fe, 0x68a0, 0xd0c4,
-	0x00c0, 0x33fe, 0x1078, 0x3562, 0x0078, 0x2946, 0x6008, 0xc08d,
-	0x600a, 0x0078, 0x3404, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040,
-	0x340b, 0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff,
-	0x0040, 0x3420, 0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421,
-	0x6412, 0x00c0, 0x3420, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022,
-	0x6018, 0xa005, 0x0040, 0x3428, 0x8001, 0x601a, 0x00c0, 0x342b,
-	0x6008, 0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x3437, 0x6800,
-	0xa005, 0x00c0, 0x3434, 0x6002, 0x6006, 0x0078, 0x343b, 0x705c,
-	0x2060, 0x6800, 0x6002, 0x2061, 0x4a00, 0x6887, 0x0103, 0x2d08,
-	0x206b, 0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x344a, 0x2d02,
-	0x0078, 0x344b, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x345b,
-	0xa286, 0x0040, 0x00c0, 0x2946, 0x7003, 0x0002, 0x704c, 0x2068,
-	0x68c4, 0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc,
-	0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80,
-	0x0009, 0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3471, 0x1078,
-	0x28ec, 0x2200, 0x0079, 0x3474, 0x3478, 0x3489, 0x3496, 0x3489,
-	0xa586, 0x1300, 0x0040, 0x3489, 0xa586, 0x8300, 0x00c0, 0x346f,
-	0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x7000, 0xa086, 0x0005, 0x0040, 0x3493, 0x1078, 0x3eae,
-	0x781b, 0x0075, 0x007c, 0x781b, 0x0076, 0x007c, 0x7890, 0x8007,
-	0x8001, 0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c,
-	0x00ff, 0xa186, 0x0003, 0x0040, 0x34ab, 0xa186, 0x0000, 0x0040,
-	0x34ab, 0x0078, 0x3e9d, 0x781b, 0x0076, 0x007c, 0x6820, 0xc095,
-	0x6822, 0x82ff, 0x00c0, 0x34b8, 0x1078, 0x3eae, 0x0078, 0x34bf,
-	0x8211, 0x0040, 0x34bd, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b,
-	0x0075, 0x007c, 0x1078, 0x4131, 0x7830, 0xa084, 0x00c0, 0x00c0,
-	0x34e5, 0x017e, 0x3208, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x34d7, 0xa18c, 0x0300, 0x0078, 0x34d9, 0xa18c,
-	0x0400, 0x017f, 0x0040, 0x34e0, 0x0018, 0x34e5, 0x0078, 0x34e2,
-	0x0028, 0x34e5, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c,
-	0xa684, 0x0060, 0x00c0, 0x34f2, 0x682f, 0x0000, 0x6833, 0x0000,
-	0x0078, 0x3561, 0xd6dc, 0x00c0, 0x350a, 0x68b4, 0xd0dc, 0x00c0,
-	0x350a, 0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0,
-	0x3507, 0x2200, 0xa105, 0x0040, 0x4326, 0x704b, 0x0015, 0x0078,
-	0x4326, 0x007c, 0xd6ac, 0x0040, 0x3530, 0xd6f4, 0x0040, 0x3516,
-	0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4326, 0x68b4, 0xa084,
-	0x4000, 0xa635, 0xd6f4, 0x00c0, 0x3510, 0x7048, 0xa005, 0x00c0,
-	0x3523, 0x704b, 0x0015, 0xd6dc, 0x00c0, 0x352c, 0x68b4, 0xd0dc,
-	0x0040, 0x352c, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4326,
-	0xd6f4, 0x0040, 0x3539, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
-	0x4326, 0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x3533,
-	0x7048, 0xa005, 0x00c0, 0x3546, 0x704b, 0x0015, 0x2408, 0x2510,
-	0x2700, 0x80fb, 0x00c8, 0x354d, 0x8000, 0xa084, 0x003f, 0xa108,
-	0xa291, 0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x355a,
-	0x0078, 0x4326, 0x7000, 0xa086, 0x0006, 0x0040, 0x3561, 0x0078,
-	0x4326, 0x007c, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3568, 0xc08d,
-	0x600a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893, 0x0000, 0x6a30,
-	0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833, 0x0000, 0x6837,
-	0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000, 0x0079, 0x3580,
-	0x2946, 0x3592, 0x358a, 0x3588, 0x3588, 0x3588, 0x3588, 0x3588,
-	0x1078, 0x28ec, 0x6820, 0xd084, 0x00c0, 0x3592, 0x1078, 0x3bb5,
-	0x0078, 0x3598, 0x705c, 0x2c50, 0x2060, 0x6800, 0x6002, 0x2a60,
-	0x3208, 0xa18c, 0x0300, 0x0040, 0x35a1, 0x2021, 0x4a58, 0x0078,
-	0x35a3, 0x2021, 0x4a98, 0x2404, 0xa005, 0x0040, 0x35aa, 0x2020,
-	0x0078, 0x35a3, 0x2d22, 0x206b, 0x0000, 0x007c, 0x1078, 0x3bbc,
-	0x1078, 0x3bd2, 0x6008, 0xc0cc, 0x600a, 0x682b, 0x0000, 0x789b,
-	0x000e, 0x6f14, 0x6817, 0x0002, 0x3208, 0xa18c, 0x0300, 0x0040,
-	0x35c5, 0x2009, 0x0000, 0x0078, 0x35c7, 0x2009, 0x0001, 0x1078,
-	0x471a, 0xd6dc, 0x0040, 0x35cf, 0x691c, 0xc1ed, 0x691e, 0x6818,
-	0xd0fc, 0x0040, 0x35de, 0x7868, 0xa08c, 0x00ff, 0x0040, 0x35dc,
-	0x681b, 0x001e, 0x0078, 0x35de, 0x681b, 0x0000, 0xb284, 0x0300,
-	0x00c0, 0x35e6, 0x2021, 0x4a98, 0x0078, 0x35e8, 0x2021, 0x4a58,
-	0x6800, 0x2022, 0x6a3c, 0x6940, 0x6a32, 0x692e, 0x1078, 0x202a,
-	0x0078, 0x2946, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078, 0x34e8, 0x682b,
-	0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4135, 0xa08c, 0x00ff,
-	0x6916, 0x6818, 0xd0fc, 0x0040, 0x3607, 0x7048, 0x681a, 0xa68c,
-	0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x2946, 0x7000, 0xa005,
-	0x00c0, 0x3614, 0x0078, 0x2946, 0xa006, 0x1078, 0x4326, 0x6817,
-	0x0000, 0x681b, 0x0014, 0xa68c, 0xdf00, 0x691e, 0x682b, 0x0000,
-	0x6820, 0xa084, 0x00ff, 0x6822, 0x7000, 0x0079, 0x3627, 0x2946,
-	0x3634, 0x3631, 0x3636, 0x3636, 0x3636, 0x362f, 0x362f, 0x1078,
-	0x28ec, 0x6008, 0xc0d4, 0x600a, 0x1078, 0x3bd2, 0x6008, 0xc0a4,
-	0x600a, 0x0078, 0x3b85, 0x2300, 0x0079, 0x363e, 0x3641, 0x3643,
-	0x369f, 0x1078, 0x28ec, 0xd6fc, 0x00c0, 0x3686, 0x7000, 0xa00d,
-	0x0079, 0x364a, 0x2946, 0x3654, 0x3654, 0x3678, 0x3654, 0x3683,
-	0x3652, 0x3652, 0x1078, 0x28ec, 0xa684, 0x0060, 0xa086, 0x0060,
-	0x00c0, 0x3675, 0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x681c, 0xc0ac,
-	0x681e, 0xa186, 0x0002, 0x0040, 0x3667, 0x1078, 0x4326, 0x1078,
-	0x45f7, 0x781b, 0x0076, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4,
-	0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x365c,
-	0x6818, 0xd0fc, 0x0040, 0x3683, 0x681b, 0x0015, 0xd6f4, 0x0040,
-	0x3683, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0xc6fc, 0x7e5a,
-	0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x368f, 0x8000, 0xa084,
-	0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
-	0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0076, 0x007c, 0x1078,
-	0x28ec, 0x2300, 0x0079, 0x36a4, 0x36a9, 0x36c5, 0x3719, 0x1078,
-	0x28ec, 0x7000, 0x0079, 0x36ac, 0x36b4, 0x36b6, 0x36b6, 0x36b4,
-	0x36b4, 0x36b4, 0x36b4, 0x36b4, 0x1078, 0x28ec, 0x1078, 0x45f7,
-	0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x2942, 0x70a4,
-	0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6fc, 0x00c0, 0x3709,
-	0x7000, 0xa00d, 0x0079, 0x36cc, 0x2946, 0x36dc, 0x36d6, 0x3700,
-	0x36dc, 0x3706, 0x36d4, 0x36d4, 0x1078, 0x28ec, 0x6894, 0x78d6,
-	0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0xa086, 0x0060,
-	0x00c0, 0x36fd, 0xa6b4, 0xbfbf, 0xc6ed, 0x7e5a, 0xa186, 0x0002,
-	0x0040, 0x36ec, 0x1078, 0x4326, 0x1078, 0x45f7, 0x781b, 0x0076,
-	0x681c, 0xc0b4, 0x681e, 0x71d4, 0xd1b4, 0x00c0, 0x2942, 0x70a4,
-	0xa086, 0x0001, 0x00c0, 0x2989, 0x007c, 0xd6ec, 0x0040, 0x36e4,
-	0x6818, 0xd0fc, 0x0040, 0x3706, 0x681b, 0x0007, 0x781b, 0x00f0,
-	0x007c, 0xc6fc, 0x7e5a, 0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302,
-	0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x79d2, 0x781b, 0x0076,
-	0x007c, 0xd6dc, 0x0040, 0x3722, 0x782b, 0x3009, 0x781b, 0x0076,
-	0x0078, 0x2942, 0x7884, 0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008,
-	0x00c0, 0x3735, 0xa484, 0x0200, 0x0040, 0x372f, 0xc6f5, 0xc6dd,
-	0x7e5a, 0x781b, 0x0076, 0x0078, 0x2942, 0x6820, 0xc095, 0x6822,
-	0x1078, 0x4062, 0xc6dd, 0x1078, 0x3eae, 0x781b, 0x0075, 0x0078,
-	0x2942, 0x2300, 0x0079, 0x3744, 0x3747, 0x3749, 0x374b, 0x1078,
-	0x28ec, 0x0078, 0x3ea7, 0xd6d4, 0x00c0, 0x3771, 0x79e4, 0xd1ac,
-	0x0040, 0x3759, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3759, 0x782b,
-	0x3009, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a,
-	0x79e4, 0xd1ac, 0x0040, 0x3769, 0x78ec, 0xa084, 0x0003, 0x00c0,
-	0x376d, 0x2001, 0x0014, 0x0078, 0x3304, 0xa184, 0x0007, 0x0079,
-	0x37a7, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060, 0x79a8, 0x81ff,
-	0x0040, 0x37a5, 0x789b, 0x0010, 0x7ba8, 0xa384, 0x0001, 0x00c0,
-	0x3798, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0, 0x378b, 0x2009,
-	0xfff7, 0x0078, 0x3791, 0xa386, 0x0003, 0x00c0, 0x3798, 0x2009,
-	0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104, 0x6006, 0x0c7f,
-	0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x782b,
-	0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x2fae,
-	0x2fb8, 0x37b1, 0x37b7, 0x37af, 0x37af, 0x40c9, 0x40c9, 0x1078,
-	0x28ec, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x40cf, 0x6920,
-	0xa18c, 0xfcff, 0x6922, 0x0078, 0x40c9, 0x79e4, 0xa184, 0x0030,
-	0x0040, 0x37c7, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x37f1, 0x7000,
-	0xa086, 0x0004, 0x00c0, 0x37e1, 0x7064, 0xa086, 0x0002, 0x00c0,
-	0x37d7, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078, 0x2e43, 0x7064,
-	0xa086, 0x0006, 0x0040, 0x37d1, 0x7064, 0xa086, 0x0004, 0x0040,
-	0x37d1, 0x7000, 0xa086, 0x0000, 0x0040, 0x2942, 0x6820, 0xd0ac,
-	0x00c0, 0x37ed, 0x6818, 0xc0fd, 0x681a, 0x2001, 0x0014, 0x0078,
-	0x3304, 0xa184, 0x0007, 0x0079, 0x37f5, 0x40c9, 0x40c9, 0x37fd,
-	0x40c9, 0x4111, 0x4111, 0x40c9, 0x40c9, 0xd6bc, 0x0040, 0x383f,
-	0x7184, 0x81ff, 0x0040, 0x383f, 0xa182, 0x000d, 0x00d0, 0x380c,
-	0x7087, 0x0000, 0x0078, 0x3811, 0xa182, 0x000c, 0x7086, 0x2009,
-	0x000c, 0x789b, 0x0061, 0x79aa, 0x157e, 0x137e, 0x147e, 0x7088,
-	0x8114, 0xa210, 0x728a, 0xa080, 0x000b, 0xad00, 0x2098, 0xb284,
-	0x0300, 0x0040, 0x3833, 0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec,
-	0x007f, 0x0040, 0x382f, 0x20a1, 0x012b, 0x0078, 0x3835, 0x20a1,
-	0x022b, 0x0078, 0x3835, 0x20a1, 0x012b, 0x789b, 0x0000, 0x8108,
-	0x81ac, 0x53a6, 0x147f, 0x137f, 0x157f, 0x0078, 0x40cf, 0xd6d4,
-	0x00c0, 0x3893, 0x6820, 0xd084, 0x0040, 0x40cf, 0xa68c, 0x0060,
-	0xa684, 0x0060, 0x0040, 0x3851, 0xa086, 0x0060, 0x00c0, 0x3851,
-	0xc1f5, 0xc194, 0x795a, 0x69b6, 0x789b, 0x0060, 0x78ab, 0x0000,
-	0x789b, 0x0061, 0x6818, 0xc0fd, 0x681a, 0x78aa, 0x8008, 0x810c,
-	0x0040, 0x3beb, 0xa18c, 0x00f8, 0x00c0, 0x3beb, 0x157e, 0x137e,
-	0x147e, 0x017e, 0x3208, 0xa18c, 0x0300, 0x0040, 0x387f, 0x007e,
-	0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x387b, 0x20a1,
-	0x012b, 0x0078, 0x3881, 0x20a1, 0x022b, 0x0078, 0x3881, 0x20a1,
-	0x012b, 0x017f, 0x789b, 0x0000, 0x8000, 0x80ac, 0xad80, 0x000b,
-	0x2098, 0x53a6, 0x147f, 0x137f, 0x157f, 0x6814, 0xc0fc, 0x8007,
-	0x7882, 0x0078, 0x40cf, 0x6818, 0xd0fc, 0x0040, 0x3899, 0x681b,
-	0x0008, 0x6820, 0xc0ad, 0x6822, 0x1078, 0x3eb6, 0x781b, 0x00e1,
-	0x007c, 0x2300, 0x0079, 0x38a4, 0x38a9, 0x397b, 0x38a7, 0x1078,
-	0x28ec, 0x7cd8, 0x7ddc, 0x7fd0, 0x82ff, 0x00c0, 0x38d1, 0x7200,
-	0xa286, 0x0003, 0x0040, 0x32d2, 0x71d4, 0xd1b4, 0x0078, 0x38d4,
-	0x0040, 0x38d4, 0x0d7e, 0x783b, 0x8800, 0x781b, 0x004c, 0x70bc,
-	0xa06d, 0x68b4, 0xc0a5, 0x785a, 0x6894, 0x78d6, 0x78de, 0x6898,
-	0x78d2, 0x78da, 0xc1b4, 0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078,
-	0x38d8, 0x7200, 0x0078, 0x38d8, 0x783b, 0x1800, 0x781b, 0x004a,
-	0xa284, 0x000f, 0x0079, 0x38dc, 0x3966, 0x391a, 0x38e6, 0x3300,
-	0x38e4, 0x3966, 0x38e4, 0x38e4, 0x1078, 0x28ec, 0x681c, 0xd0ec,
-	0x0040, 0x38ed, 0x6008, 0xc08d, 0x600a, 0x6920, 0xc185, 0x6922,
-	0x6800, 0x6006, 0xa005, 0x00c0, 0x38f6, 0x6002, 0x6008, 0xc0d4,
-	0x600a, 0x681c, 0xa084, 0x000e, 0x00c0, 0x390a, 0xb284, 0x0300,
-	0x0040, 0x3906, 0x2009, 0x90c0, 0x0078, 0x390f, 0x2009, 0x91d0,
-	0x0078, 0x390f, 0x7030, 0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104,
-	0x6802, 0x2d0a, 0x715e, 0xd6dc, 0x00c0, 0x391a, 0xc6fc, 0x6eb6,
-	0x0078, 0x3966, 0x6eb6, 0xa684, 0x0060, 0x0040, 0x3966, 0xd6dc,
-	0x00c0, 0x392d, 0xa684, 0x7fff, 0x68b6, 0x6894, 0x68a6, 0x6898,
-	0x68aa, 0x1078, 0x4326, 0x0078, 0x3966, 0xd6ac, 0x0040, 0x3939,
-	0xa006, 0x1078, 0x4326, 0x2408, 0x2510, 0x69aa, 0x6aa6, 0x0078,
-	0x3949, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8, 0x3940, 0x8000,
-	0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa, 0x6aa6, 0x1078,
-	0x4326, 0xd6fc, 0x0040, 0x3966, 0xa684, 0x7fff, 0x68b6, 0x2510,
-	0x2408, 0xd6ac, 0x00c0, 0x395e, 0x2700, 0x801b, 0x00c8, 0x3959,
-	0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100,
-	0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae, 0x7000, 0xa086,
-	0x0030, 0x00c0, 0x2946, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc,
-	0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80,
-	0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0, 0x3988, 0x7003,
+	0x1078, 0x35ff, 0x017f, 0x81ff, 0x0040, 0x351a, 0xa684, 0xdf00,
+	0x681e, 0x682b, 0x0000, 0x6f14, 0xa186, 0x0002, 0x00c0, 0x351b,
+	0x6818, 0xa086, 0x0014, 0x00c0, 0x34e4, 0x2008, 0xd6e4, 0x0040,
+	0x34e4, 0x7868, 0xa08c, 0x00ff, 0x1078, 0x2aba, 0x1078, 0x2adb,
+	0x6820, 0xd0dc, 0x00c0, 0x351b, 0x8717, 0xa294, 0x000f, 0x8213,
+	0x8213, 0x8213, 0xb284, 0x0300, 0x0040, 0x34fa, 0xa290, 0x52c0,
+	0x0078, 0x34fc, 0xa290, 0x5340, 0xa290, 0x0000, 0x221c, 0xd3c4,
+	0x00c0, 0x3504, 0x0078, 0x350a, 0x8210, 0x2204, 0xa085, 0x0018,
+	0x2012, 0x8211, 0xd3d4, 0x0040, 0x3515, 0x68a0, 0xd0c4, 0x00c0,
+	0x3515, 0x1078, 0x3679, 0x0078, 0x29c5, 0x6008, 0xc08d, 0x600a,
+	0x0078, 0x351b, 0x692a, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3522,
+	0x7048, 0x681a, 0xa68c, 0xdf00, 0x691e, 0x6410, 0x84ff, 0x0040,
+	0x3537, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412,
+	0x00c0, 0x3537, 0x2021, 0x4e04, 0x2404, 0xc0a5, 0x2022, 0x6018,
+	0xa005, 0x0040, 0x353f, 0x8001, 0x601a, 0x00c0, 0x3542, 0x6008,
+	0xc0a4, 0x600a, 0x6820, 0xd084, 0x00c0, 0x354e, 0x6800, 0xa005,
+	0x00c0, 0x354b, 0x6002, 0x6006, 0x0078, 0x3552, 0x705c, 0x2060,
+	0x6800, 0x6002, 0x2061, 0x4e00, 0x6887, 0x0103, 0x2d08, 0x206b,
+	0x0000, 0x6068, 0xa005, 0x616a, 0x0040, 0x3561, 0x2d02, 0x0078,
+	0x3562, 0x616e, 0x7200, 0xa286, 0x0030, 0x0040, 0x3572, 0xa286,
+	0x0040, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x704c, 0x2068, 0x68c4,
+	0x2060, 0x007c, 0x7003, 0x0002, 0x70bc, 0xa06d, 0x68bc, 0x7042,
+	0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00, 0x704e, 0xad80, 0x0009,
+	0x7046, 0x007c, 0xa282, 0x0004, 0x0048, 0x3588, 0x1078, 0x296b,
+	0x2200, 0x0079, 0x358b, 0x358f, 0x35a0, 0x35ad, 0x35a0, 0xa586,
+	0x1300, 0x0040, 0x35a0, 0xa586, 0x8300, 0x00c0, 0x3586, 0x7003,
 	0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x0078, 0x3ea7, 0x7047, 0x0000, 0xa282, 0x0006, 0x0050, 0x3992,
-	0x1078, 0x28ec, 0x2300, 0x0079, 0x3995, 0x3998, 0x39cf, 0x3a01,
-	0x2200, 0x0079, 0x399b, 0x39a1, 0x3ea7, 0x39a3, 0x39a1, 0x3a38,
-	0x3a9b, 0x1078, 0x28ec, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040,
-	0x39ad, 0x2001, 0x91e0, 0x0078, 0x39af, 0x2001, 0x9212, 0x2068,
-	0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0,
-	0x39b4, 0x157f, 0xb284, 0x0300, 0x0040, 0x39c2, 0x6817, 0x0000,
-	0x0078, 0x39c4, 0x6817, 0x8000, 0xad80, 0x0009, 0x7046, 0x68b7,
-	0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x0078, 0x3e9d, 0x7000,
-	0xa086, 0x0002, 0x00c0, 0x39e0, 0x1078, 0x3bd2, 0x0078, 0x39da,
-	0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a, 0x0078, 0x39e5,
-	0x7000, 0xa086, 0x0003, 0x0040, 0x39d8, 0x7003, 0x0005, 0xb284,
-	0x0300, 0x0040, 0x39ef, 0x2001, 0x91e0, 0x0078, 0x39f1, 0x2001,
-	0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046, 0x2200, 0x0079,
-	0x39f9, 0x3ea7, 0x39ff, 0x39ff, 0x3a38, 0x39ff, 0x3ea7, 0x1078,
-	0x28ec, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3a12, 0x1078, 0x3bd2,
-	0x0078, 0x3a0c, 0x1078, 0x4326, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x0078, 0x3a17, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a0a, 0x7003,
-	0x0005, 0xb284, 0x0300, 0x0040, 0x3a21, 0x2001, 0x91e0, 0x0078,
-	0x3a23, 0x2001, 0x9212, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046,
-	0x2200, 0x0079, 0x3a2b, 0x3a33, 0x3a31, 0x3a31, 0x3a33, 0x3a31,
-	0x3a33, 0x1078, 0x28ec, 0x1078, 0x3ebe, 0x781b, 0x0075, 0x007c,
-	0x7000, 0xa086, 0x0002, 0x00c0, 0x3a4a, 0x70d4, 0xc0b5, 0x70d6,
-	0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3a4f, 0x1078, 0x4326,
-	0x0078, 0x3a4f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3a46, 0x7003,
-	0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484,
-	0x001f, 0xa215, 0x2069, 0x90c0, 0xb284, 0x0300, 0x00c0, 0x3a63,
-	0xc2fd, 0x2069, 0x91d0, 0x2d04, 0x2d08, 0x715e, 0xa06d, 0x0040,
-	0x3a70, 0x6814, 0xa206, 0x0040, 0x3a90, 0x6800, 0x0078, 0x3a64,
-	0x7003, 0x0005, 0xd2fc, 0x00c0, 0x3a79, 0x2001, 0x91e0, 0x0078,
-	0x3a7b, 0x2001, 0x9212, 0x2068, 0x704e, 0x157e, 0x20a9, 0x0032,
-	0x2003, 0x0000, 0x8000, 0x00f0, 0x3a80, 0x157f, 0xad80, 0x0009,
-	0x7046, 0x6a16, 0x68b7, 0x0700, 0x6823, 0x0800, 0x6827, 0x0003,
-	0x6eb4, 0x7e5a, 0x6820, 0xa084, 0x0c00, 0x0040, 0x3b10, 0x1078,
-	0x3eb6, 0x0078, 0x3b10, 0x7200, 0xa286, 0x0002, 0x00c0, 0x3aad,
-	0x70d4, 0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078,
-	0x3ab1, 0x1078, 0x4326, 0x0078, 0x3ab1, 0xa286, 0x0003, 0x0040,
-	0x3aa9, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
-	0x7ca8, 0xa484, 0x001f, 0xa215, 0xb284, 0x0300, 0x00c0, 0x3ac1,
-	0xc2fd, 0x79a8, 0x79a8, 0xa18c, 0x00ff, 0x70cc, 0xa168, 0x2d04,
-	0x2d08, 0x715e, 0xa06d, 0x0040, 0x3ad4, 0x6814, 0xa206, 0x0040,
-	0x3afd, 0x6800, 0x0078, 0x3ac8, 0x7003, 0x0005, 0xb284, 0x0300,
-	0x0040, 0x3ade, 0x2001, 0x91e0, 0x0078, 0x3ae0, 0x2001, 0x9212,
-	0x2068, 0x704e, 0x157e, 0x20a9, 0x0032, 0x2003, 0x0000, 0x8000,
-	0x00f0, 0x3ae5, 0x157f, 0xb284, 0x0300, 0x0040, 0x3af2, 0xc2fc,
-	0x0078, 0x3af3, 0xc2fd, 0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7,
-	0x0700, 0x6823, 0x0800, 0x6827, 0x0003, 0x6eb4, 0x6820, 0xa084,
-	0x0c00, 0x0040, 0x3b10, 0xd0dc, 0x0040, 0x3b0a, 0x1078, 0x3eba,
-	0x0078, 0x3b10, 0x1078, 0x3eb6, 0x707f, 0x0000, 0x0078, 0x3b10,
-	0xa6ac, 0x0060, 0x0040, 0x3b4e, 0x6b98, 0x6c94, 0x69ac, 0x68b0,
-	0xa105, 0x00c0, 0x3b33, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0xa6b4,
-	0xb7ff, 0xa586, 0x0060, 0x0040, 0x3b4e, 0xc6ed, 0x7e5a, 0x2009,
-	0x0076, 0xd69c, 0x0040, 0x3b2e, 0x2009, 0x0075, 0x791a, 0x1078,
-	0x45f7, 0x0078, 0x3b57, 0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400,
-	0xa305, 0x0040, 0x3b4e, 0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0,
-	0xc6f4, 0x7e5a, 0x2011, 0x0076, 0xd69c, 0x0040, 0x3b49, 0x2011,
-	0x0075, 0x7a1a, 0x1078, 0x462d, 0x0078, 0x3b57, 0x7e5a, 0x2009,
-	0x0076, 0xd69c, 0x0040, 0x3b56, 0x2009, 0x0075, 0x791a, 0x68c0,
-	0x705a, 0x2d00, 0x704e, 0x68c4, 0x2060, 0x71d4, 0xd1b4, 0x00c0,
-	0x2942, 0x2300, 0xa405, 0x0040, 0x2942, 0x70a4, 0xa086, 0x0001,
-	0x00c0, 0x2989, 0x007c, 0x6020, 0xa005, 0x0040, 0x3b79, 0x8001,
-	0x6022, 0x6008, 0xa085, 0x0008, 0x600a, 0x700f, 0x0100, 0x702c,
-	0x6026, 0x007c, 0xa006, 0x1078, 0x4326, 0x6817, 0x0000, 0x681b,
+	0x7000, 0xa086, 0x0005, 0x0040, 0x35aa, 0x1078, 0x40c8, 0x781b,
+	0x0078, 0x007c, 0x781b, 0x0079, 0x007c, 0x7890, 0x8007, 0x8001,
+	0xa084, 0x0007, 0xa080, 0x0018, 0x789a, 0x79a8, 0xa18c, 0x00ff,
+	0xa186, 0x0003, 0x0040, 0x35c2, 0xa186, 0x0000, 0x0040, 0x35c2,
+	0x0078, 0x40b7, 0x781b, 0x0079, 0x007c, 0x6820, 0xc095, 0x6822,
+	0x82ff, 0x00c0, 0x35cf, 0x1078, 0x40c8, 0x0078, 0x35d6, 0x8211,
+	0x0040, 0x35d4, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078,
+	0x007c, 0x1078, 0x4383, 0x7830, 0xa084, 0x00c0, 0x00c0, 0x35fc,
+	0x017e, 0x3208, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f,
+	0x0040, 0x35ee, 0xa18c, 0x0300, 0x0078, 0x35f0, 0xa18c, 0x0400,
+	0x017f, 0x0040, 0x35f7, 0x0018, 0x35fc, 0x0078, 0x35f9, 0x0028,
+	0x35fc, 0x791a, 0xa006, 0x007c, 0xa085, 0x0001, 0x007c, 0xa684,
+	0x0060, 0x00c0, 0x3609, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078,
+	0x3678, 0xd6dc, 0x00c0, 0x3621, 0x68b4, 0xd0dc, 0x00c0, 0x3621,
+	0x6998, 0x6a94, 0x692e, 0x6a32, 0x7048, 0xa005, 0x00c0, 0x361e,
+	0x2200, 0xa105, 0x0040, 0x4586, 0x704b, 0x0015, 0x0078, 0x4586,
+	0x007c, 0xd6ac, 0x0040, 0x3647, 0xd6f4, 0x0040, 0x362d, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x0078, 0x4586, 0x68b4, 0xa084, 0x4000,
+	0xa635, 0xd6f4, 0x00c0, 0x3627, 0x7048, 0xa005, 0x00c0, 0x363a,
+	0x704b, 0x0015, 0xd6dc, 0x00c0, 0x3643, 0x68b4, 0xd0dc, 0x0040,
+	0x3643, 0x6ca8, 0x6da4, 0x6c2e, 0x6d32, 0x0078, 0x4586, 0xd6f4,
+	0x0040, 0x3650, 0x682f, 0x0000, 0x6833, 0x0000, 0x0078, 0x4586,
+	0x68b4, 0xa084, 0x4800, 0xa635, 0xd6f4, 0x00c0, 0x364a, 0x7048,
+	0xa005, 0x00c0, 0x365d, 0x704b, 0x0015, 0x2408, 0x2510, 0x2700,
+	0x80fb, 0x00c8, 0x3664, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291,
+	0x0000, 0x692e, 0x6a32, 0x2100, 0xa205, 0x00c0, 0x3671, 0x0078,
+	0x4586, 0x7000, 0xa086, 0x0006, 0x0040, 0x3678, 0x0078, 0x4586,
+	0x007c, 0x6946, 0x6008, 0xc0cd, 0xd3cc, 0x0040, 0x3680, 0xc08d,
+	0x600a, 0x6818, 0x683a, 0x681b, 0x0006, 0x688f, 0x0000, 0x6893,
+	0x0000, 0x6a30, 0x692c, 0x6a3e, 0x6942, 0x682f, 0x0003, 0x6833,
+	0x0000, 0x6837, 0x0020, 0x6897, 0x0000, 0x689b, 0x0020, 0x7000,
+	0x0079, 0x369a, 0x29c5, 0x36ac, 0x36a4, 0x36a2, 0x36a2, 0x36a2,
+	0x36a2, 0x36a2, 0x1078, 0x296b, 0x6820, 0xd084, 0x00c0, 0x36ac,
+	0x1078, 0x3dd0, 0x0078, 0x36b2, 0x705c, 0x2c50, 0x2060, 0x6800,
+	0x6002, 0x2a60, 0x3208, 0xa18c, 0x0300, 0x0040, 0x36bb, 0x2021,
+	0x4e58, 0x0078, 0x36bd, 0x2021, 0x4e98, 0x2404, 0xa005, 0x0040,
+	0x36c4, 0x2020, 0x0078, 0x36bd, 0x2d22, 0x206b, 0x0000, 0x007c,
+	0x1078, 0x3dd7, 0x1078, 0x3ded, 0x6008, 0xc0cc, 0x600a, 0x682b,
+	0x0000, 0x789b, 0x000e, 0x6f14, 0x6938, 0x691a, 0x6944, 0x6916,
+	0x3208, 0xa18c, 0x0300, 0x0040, 0x36e1, 0x2009, 0x0000, 0x0078,
+	0x36e3, 0x2009, 0x0001, 0x1078, 0x49f8, 0xd6dc, 0x0040, 0x36eb,
+	0x691c, 0xc1ed, 0x691e, 0x6818, 0xd0fc, 0x0040, 0x36fa, 0x7868,
+	0xa08c, 0x00ff, 0x0040, 0x36f8, 0x681b, 0x001e, 0x0078, 0x36fa,
+	0x681b, 0x0000, 0xb284, 0x0300, 0x00c0, 0x3702, 0x2021, 0x4e98,
+	0x0078, 0x3704, 0x2021, 0x4e58, 0x6800, 0x2022, 0x6a3c, 0x6940,
+	0x6a32, 0x692e, 0x68c0, 0x2060, 0x6000, 0xd0a4, 0x0040, 0x3744,
+	0x2041, 0x0021, 0x2049, 0x0005, 0x2051, 0x0020, 0x0d7e, 0x0f7e,
+	0x157e, 0x147e, 0x2079, 0x4e00, 0x1078, 0x1dff, 0x147f, 0x157f,
+	0x0f7f, 0x70cc, 0x2010, 0x2009, 0x0101, 0x027e, 0x2204, 0xa06d,
+	0x0040, 0x3734, 0x6814, 0xa706, 0x0040, 0x3731, 0x6800, 0x0078,
+	0x3727, 0x6820, 0xc0d5, 0x6822, 0x027f, 0x8210, 0x8109, 0x00c0,
+	0x3725, 0x0d7f, 0x7067, 0x0003, 0x707f, 0x0000, 0x7776, 0x7083,
+	0x000f, 0x71d4, 0xc1dc, 0x71d6, 0x6818, 0xa086, 0x0002, 0x00c0,
+	0x3750, 0x6817, 0x0000, 0x682b, 0x0000, 0x681c, 0xc0ec, 0x681e,
+	0x1078, 0x202c, 0x0078, 0x29c5, 0x7cd8, 0x7ddc, 0x7fd0, 0x1078,
+	0x35ff, 0x682b, 0x0000, 0x789b, 0x000e, 0x6f14, 0x1078, 0x4387,
+	0xa08c, 0x00ff, 0x6916, 0x6818, 0xd0fc, 0x0040, 0x3769, 0x7048,
+	0x681a, 0xa68c, 0xdf00, 0x691e, 0x7067, 0x0000, 0x0078, 0x29c5,
+	0x7000, 0xa005, 0x00c0, 0x3776, 0x0078, 0x29c5, 0xa006, 0x1078,
+	0x4586, 0x6920, 0xd1ac, 0x00c0, 0x377f, 0x681b, 0x0014, 0xa68c,
+	0xdf00, 0x691e, 0x682b, 0x0000, 0x6820, 0xa084, 0x00ff, 0x6822,
+	0x7000, 0x0079, 0x378b, 0x29c5, 0x3795, 0x3795, 0x3798, 0x3798,
+	0x3798, 0x3793, 0x3793, 0x1078, 0x296b, 0x6818, 0x0078, 0x33fa,
+	0x6008, 0xc0a4, 0x600a, 0x6817, 0x0000, 0x0078, 0x3d95, 0x2300,
+	0x0079, 0x37a2, 0x37a5, 0x37a7, 0x3817, 0x1078, 0x296b, 0xd6fc,
+	0x00c0, 0x37fe, 0x7000, 0xa00d, 0x0079, 0x37ae, 0x29c5, 0x37b8,
+	0x37b8, 0x37e8, 0x37b8, 0x37fb, 0x37b6, 0x37b6, 0x1078, 0x296b,
+	0xa684, 0x0060, 0x0040, 0x37e8, 0xa086, 0x0060, 0x00c0, 0x37e5,
+	0xc6ac, 0xc6f4, 0xc6ed, 0x7e5a, 0x6eb6, 0x681c, 0xc0ac, 0x681e,
+	0xa186, 0x0002, 0x0040, 0x37d7, 0x1078, 0x4586, 0x69ac, 0x68b0,
+	0xa115, 0x0040, 0x37d7, 0x1078, 0x48f5, 0x0078, 0x37d9, 0x1078,
+	0x48bd, 0x781b, 0x0079, 0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4,
+	0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x37c2,
+	0x6818, 0xd0fc, 0x0040, 0x37fb, 0xd6f4, 0x00c0, 0x37f5, 0x681b,
+	0x0015, 0x781b, 0x0079, 0x0078, 0x29c1, 0x681b, 0x0007, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x1078, 0x4319, 0x007c, 0xc6fc, 0x7e5a,
+	0x7adc, 0x79d8, 0x78d0, 0x801b, 0x00c8, 0x3807, 0x8000, 0xa084,
+	0x003f, 0xa108, 0xa291, 0x0000, 0x6b98, 0x2100, 0xa302, 0x68b2,
+	0x6b94, 0x2200, 0xa303, 0x68ae, 0x781b, 0x0079, 0x007c, 0x1078,
+	0x296b, 0x2300, 0x0079, 0x381c, 0x3821, 0x3846, 0x38a6, 0x1078,
+	0x296b, 0x7000, 0x0079, 0x3824, 0x382c, 0x382e, 0x3837, 0x382c,
+	0x382c, 0x382c, 0x382c, 0x382c, 0x1078, 0x296b, 0x69ac, 0x68b0,
+	0xa115, 0x0040, 0x3837, 0x1078, 0x48f5, 0x0078, 0x3839, 0x1078,
+	0x48bd, 0x681c, 0xc0b4, 0x681e, 0x70d4, 0xd0b4, 0x00c0, 0x29c1,
+	0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0xd6fc, 0x00c0,
+	0x3896, 0x7000, 0xa00d, 0x0079, 0x384d, 0x29c5, 0x385d, 0x3857,
+	0x388d, 0x385d, 0x3893, 0x3855, 0x3855, 0x1078, 0x296b, 0x6894,
+	0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xa684, 0x0060, 0x0040,
+	0x388d, 0xa086, 0x0060, 0x00c0, 0x388a, 0xa6b4, 0xbfbf, 0xc6ed,
+	0x7e5a, 0x6eb6, 0xa186, 0x0002, 0x0040, 0x3879, 0x1078, 0x4586,
+	0x69ac, 0x68b0, 0xa115, 0x0040, 0x3879, 0x1078, 0x48f5, 0x0078,
+	0x387b, 0x1078, 0x48bd, 0x781b, 0x0079, 0x681c, 0xc0b4, 0x681e,
+	0x71d4, 0xd1b4, 0x00c0, 0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0,
+	0x2a0b, 0x007c, 0xd6ec, 0x0040, 0x3867, 0x6818, 0xd0fc, 0x0040,
+	0x3893, 0x681b, 0x0007, 0x781b, 0x00f9, 0x007c, 0xc6fc, 0x7e5a,
+	0x7adc, 0x79d8, 0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200,
+	0xa303, 0x68ae, 0x79d2, 0x781b, 0x0079, 0x007c, 0xd6dc, 0x0040,
+	0x38af, 0x782b, 0x3009, 0x781b, 0x0079, 0x0078, 0x29c1, 0x7884,
+	0xc0ac, 0x7886, 0x78e4, 0xa084, 0x0008, 0x00c0, 0x38c2, 0xa484,
+	0x0200, 0x0040, 0x38bc, 0xc6f5, 0xc6dd, 0x7e5a, 0x781b, 0x0079,
+	0x0078, 0x29c1, 0x6820, 0xc095, 0x6822, 0x1078, 0x4292, 0xc6dd,
+	0x1078, 0x40c8, 0x781b, 0x0078, 0x0078, 0x29c1, 0x2300, 0x0079,
+	0x38d1, 0x38d4, 0x38d6, 0x38d8, 0x1078, 0x296b, 0x0078, 0x40c1,
+	0xd6d4, 0x00c0, 0x3913, 0x79e4, 0xd1ac, 0x0040, 0x38e6, 0x78ec,
+	0xa084, 0x0003, 0x0040, 0x38e6, 0x782b, 0x3009, 0x789b, 0x0060,
+	0x78ab, 0x0000, 0xa684, 0xfffb, 0x785a, 0x79e4, 0xd1ac, 0x0040,
+	0x38f6, 0x78ec, 0xa084, 0x0003, 0x00c0, 0x390f, 0x2001, 0x4e04,
+	0x2004, 0xd0e4, 0x00c0, 0x390b, 0x6820, 0xd0c4, 0x0040, 0x390b,
+	0x0c7e, 0x7058, 0x2060, 0x6004, 0xc09d, 0x6006, 0x6008, 0xa084,
+	0x00ff, 0x600a, 0x0c7f, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184,
+	0x0007, 0x0079, 0x3949, 0x7a90, 0xa294, 0x0007, 0x789b, 0x0060,
+	0x79a8, 0x81ff, 0x0040, 0x3947, 0x789b, 0x0010, 0x7ba8, 0xa384,
+	0x0001, 0x00c0, 0x393a, 0x7ba8, 0x7ba8, 0xa386, 0x0001, 0x00c0,
+	0x392d, 0x2009, 0xfff7, 0x0078, 0x3933, 0xa386, 0x0003, 0x00c0,
+	0x393a, 0x2009, 0xffef, 0x0c7e, 0x7058, 0x2060, 0x6004, 0xa104,
+	0x6006, 0x0c7f, 0x789b, 0x0060, 0x78ab, 0x0000, 0xa684, 0xfffb,
+	0x785a, 0x782b, 0x3009, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
+	0x430d, 0x3090, 0x309a, 0x3953, 0x3959, 0x3951, 0x3951, 0x430d,
+	0x430d, 0x1078, 0x296b, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078,
+	0x4313, 0x6920, 0xa18c, 0xfcff, 0x6922, 0x0078, 0x430d, 0x79e4,
+	0xa184, 0x0030, 0x0040, 0x3969, 0x78ec, 0xa084, 0x0003, 0x00c0,
+	0x399d, 0x7000, 0xa086, 0x0004, 0x00c0, 0x3983, 0x7064, 0xa086,
+	0x0002, 0x00c0, 0x3979, 0x2011, 0x0002, 0x2019, 0x0000, 0x0078,
+	0x2f1c, 0x7064, 0xa086, 0x0006, 0x0040, 0x3973, 0x7064, 0xa086,
+	0x0004, 0x0040, 0x3973, 0x7000, 0xa086, 0x0000, 0x0040, 0x29c1,
+	0x6920, 0xa184, 0x0420, 0x0040, 0x3992, 0xc1d4, 0x6922, 0x6818,
+	0x0078, 0x33fa, 0x6818, 0xa08e, 0x0002, 0x0040, 0x399b, 0xc0fd,
+	0x681a, 0x2001, 0x0014, 0x0078, 0x33fa, 0xa184, 0x0007, 0x0079,
+	0x39a1, 0x430d, 0x430d, 0x39a9, 0x430d, 0x4355, 0x4355, 0x430d,
+	0x430d, 0xd6bc, 0x0040, 0x39eb, 0x7184, 0x81ff, 0x0040, 0x39eb,
+	0xa182, 0x000d, 0x00d0, 0x39b8, 0x7087, 0x0000, 0x0078, 0x39bd,
+	0xa182, 0x000c, 0x7086, 0x2009, 0x000c, 0x789b, 0x0061, 0x79aa,
+	0x157e, 0x137e, 0x147e, 0x7088, 0x8114, 0xa210, 0x728a, 0xa080,
+	0x000b, 0xad00, 0x2098, 0xb284, 0x0300, 0x0040, 0x39df, 0x007e,
+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x39db, 0x20a1,
+	0x012b, 0x0078, 0x39e1, 0x20a1, 0x022b, 0x0078, 0x39e1, 0x20a1,
+	0x012b, 0x789b, 0x0000, 0x8108, 0x81ac, 0x53a6, 0x147f, 0x137f,
+	0x157f, 0x0078, 0x4313, 0xd6d4, 0x00c0, 0x3a3f, 0x6820, 0xd084,
+	0x0040, 0x4313, 0xa68c, 0x0060, 0xa684, 0x0060, 0x0040, 0x39fd,
+	0xa086, 0x0060, 0x00c0, 0x39fd, 0xc1f5, 0xc194, 0x795a, 0x69b6,
+	0x789b, 0x0060, 0x78ab, 0x0000, 0x789b, 0x0061, 0x6818, 0xc0fd,
+	0x681a, 0x78aa, 0x8008, 0x810c, 0x0040, 0x3e06, 0xa18c, 0x00f8,
+	0x00c0, 0x3e06, 0x157e, 0x137e, 0x147e, 0x017e, 0x3208, 0xa18c,
+	0x0300, 0x0040, 0x3a2b, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec,
+	0x007f, 0x0040, 0x3a27, 0x20a1, 0x012b, 0x0078, 0x3a2d, 0x20a1,
+	0x022b, 0x0078, 0x3a2d, 0x20a1, 0x012b, 0x017f, 0x789b, 0x0000,
+	0x8000, 0x80ac, 0xad80, 0x000b, 0x2098, 0x53a6, 0x147f, 0x137f,
+	0x157f, 0x6814, 0xc0fc, 0x8007, 0x7882, 0x0078, 0x4313, 0x6818,
+	0xd0fc, 0x0040, 0x3a45, 0x681b, 0x0008, 0x6820, 0xc0ad, 0x6822,
+	0x1078, 0x40d0, 0x781b, 0x00ea, 0x007c, 0x2300, 0x0079, 0x3a50,
+	0x3a55, 0x3b2d, 0x3a53, 0x1078, 0x296b, 0x7cd8, 0x7ddc, 0x7fd0,
+	0x82ff, 0x00c0, 0x3a7e, 0x7200, 0xa286, 0x0003, 0x0040, 0x33c7,
+	0x71d4, 0xd1bc, 0x00c0, 0x3a81, 0xd1b4, 0x0040, 0x3a81, 0x0d7e,
+	0x783b, 0x8800, 0x781b, 0x004c, 0x70bc, 0xa06d, 0x68b4, 0xc0a5,
+	0x785a, 0x6894, 0x78d6, 0x78de, 0x6898, 0x78d2, 0x78da, 0xc1b4,
+	0x71d6, 0x7003, 0x0030, 0x0d7f, 0x0078, 0x3a85, 0x7200, 0x0078,
+	0x3a85, 0x783b, 0x1800, 0x781b, 0x004a, 0xa284, 0x000f, 0x0079,
+	0x3a89, 0x3b18, 0x3ac7, 0x3a93, 0x33f6, 0x3a91, 0x3b18, 0x3a91,
+	0x3a91, 0x1078, 0x296b, 0x681c, 0xd0ec, 0x0040, 0x3a9a, 0x6008,
+	0xc08d, 0x600a, 0x6920, 0xc185, 0x6922, 0x6800, 0x6006, 0xa005,
+	0x00c0, 0x3aa3, 0x6002, 0x6008, 0xc0d4, 0x600a, 0x681c, 0xa084,
+	0x000e, 0x00c0, 0x3ab7, 0xb284, 0x0300, 0x0040, 0x3ab3, 0x2009,
+	0x94c0, 0x0078, 0x3abc, 0x2009, 0x95d0, 0x0078, 0x3abc, 0x7030,
+	0x68ba, 0x7140, 0x70cc, 0xa108, 0x2104, 0x6802, 0x2d0a, 0x715e,
+	0xd6dc, 0x00c0, 0x3ac7, 0xc6fc, 0x6eb6, 0x0078, 0x3b18, 0x6eb6,
+	0xa684, 0x0060, 0x00c0, 0x3ad1, 0xa684, 0x7fff, 0x68b6, 0x0078,
+	0x3b18, 0xd6dc, 0x00c0, 0x3adf, 0xa684, 0x7fff, 0x68b6, 0x6894,
+	0x68a6, 0x6898, 0x68aa, 0x1078, 0x4586, 0x0078, 0x3b18, 0xd6ac,
+	0x0040, 0x3aeb, 0xa006, 0x1078, 0x4586, 0x2408, 0x2510, 0x69aa,
+	0x6aa6, 0x0078, 0x3afb, 0x2408, 0x2510, 0x2700, 0x801b, 0x00c8,
+	0x3af2, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000, 0x69aa,
+	0x6aa6, 0x1078, 0x4586, 0xd6fc, 0x0040, 0x3b18, 0xa684, 0x7fff,
+	0x68b6, 0x2510, 0x2408, 0xd6ac, 0x00c0, 0x3b10, 0x2700, 0x801b,
+	0x00c8, 0x3b0b, 0x8000, 0xa084, 0x003f, 0xa108, 0xa291, 0x0000,
+	0x6b98, 0x2100, 0xa302, 0x68b2, 0x6b94, 0x2200, 0xa303, 0x68ae,
+	0x7000, 0xa086, 0x0030, 0x00c0, 0x29c5, 0x7003, 0x0002, 0x70bc,
+	0xa06d, 0x68bc, 0x7042, 0x70b8, 0xa065, 0x68c0, 0x705a, 0x2d00,
+	0x704e, 0xad80, 0x0009, 0x7046, 0x007c, 0xa586, 0x8800, 0x00c0,
+	0x3b3a, 0x7003, 0x0000, 0x6018, 0x8001, 0x601a, 0x6008, 0xa084,
+	0xfbef, 0x600a, 0x0078, 0x40c1, 0x7047, 0x0000, 0xa282, 0x0006,
+	0x0050, 0x3b44, 0x1078, 0x296b, 0x2300, 0x0079, 0x3b47, 0x3b4a,
+	0x3b5c, 0x3b68, 0x2200, 0x0079, 0x3b4d, 0x3b53, 0x40c1, 0x3b55,
+	0x3b53, 0x3ba2, 0x3bf7, 0x1078, 0x296b, 0x7a80, 0xa294, 0x0f00,
+	0x1078, 0x3c81, 0x0078, 0x40b7, 0x1078, 0x3b79, 0x0079, 0x3b60,
+	0x40c1, 0x3b66, 0x3b66, 0x3ba2, 0x3b66, 0x40c1, 0x1078, 0x296b,
+	0x1078, 0x3b79, 0x0079, 0x3b6c, 0x3b74, 0x3b72, 0x3b72, 0x3b74,
+	0x3b72, 0x3b74, 0x1078, 0x296b, 0x1078, 0x40db, 0x781b, 0x0078,
+	0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3b8a, 0x1078, 0x3ded,
+	0x0078, 0x3b84, 0x1078, 0x4586, 0x6008, 0xa084, 0xfbef, 0x600a,
+	0x0078, 0x3b8f, 0x7000, 0xa086, 0x0003, 0x0040, 0x3b82, 0x7003,
+	0x0005, 0xb284, 0x0300, 0x0040, 0x3b99, 0x2001, 0x95e0, 0x0078,
+	0x3b9b, 0x2001, 0x9612, 0x2068, 0x704e, 0xad80, 0x0009, 0x7046,
+	0x2200, 0x007c, 0x7000, 0xa086, 0x0002, 0x00c0, 0x3bb4, 0x70d4,
+	0xc0b5, 0x70d6, 0x2c00, 0x70ba, 0x2d00, 0x70be, 0x0078, 0x3bb9,
+	0x1078, 0x4586, 0x0078, 0x3bb9, 0x7000, 0xa086, 0x0003, 0x0040,
+	0x3bb0, 0x7003, 0x0001, 0x7a80, 0xa294, 0x0f00, 0x789b, 0x0018,
+	0x7ca8, 0xa484, 0x001f, 0xa215, 0x2069, 0x94c0, 0xb284, 0x0300,
+	0x00c0, 0x3bcd, 0xc2fd, 0x2069, 0x95d0, 0x2d04, 0x2d08, 0x715e,
+	0xa06d, 0x0040, 0x3bda, 0x6814, 0xa206, 0x0040, 0x3bdc, 0x6800,
+	0x0078, 0x3bce, 0x1078, 0x3c81, 0x6eb4, 0x7e5a, 0x6920, 0xa184,
+	0x0c00, 0x0040, 0x3cab, 0x7064, 0xa086, 0x0006, 0x00c0, 0x3bee,
+	0x7074, 0xa206, 0x00c0, 0x3bee, 0x7066, 0x707e, 0x681b, 0x0005,
+	0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x0078, 0x3cab, 0x7200,
+	0xa286, 0x0002, 0x00c0, 0x3c09, 0x70d4, 0xc0b5, 0x70d6, 0x2c00,
+	0x70ba, 0x2d00, 0x70be, 0x0078, 0x3c0d, 0x1078, 0x4586, 0x0078,
+	0x3c0d, 0xa286, 0x0003, 0x0040, 0x3c05, 0x7003, 0x0001, 0x7a80,
+	0xa294, 0x0f00, 0x789b, 0x0018, 0x7ca8, 0xa484, 0x001f, 0xa215,
+	0xb284, 0x0300, 0x00c0, 0x3c1d, 0xc2fd, 0x79a8, 0x79a8, 0xa18c,
+	0x00ff, 0x2118, 0x70cc, 0xa168, 0x2d04, 0x2d08, 0x715e, 0xa06d,
+	0x0040, 0x3c31, 0x6814, 0xa206, 0x0040, 0x3c5a, 0x6800, 0x0078,
+	0x3c25, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c3b, 0x2001,
+	0x95e0, 0x0078, 0x3c3d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e,
+	0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c42, 0x157f,
+	0xb284, 0x0300, 0x0040, 0x3c4f, 0xc2fc, 0x0078, 0x3c50, 0xc2fd,
+	0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
+	0x6827, 0x0003, 0x6eb4, 0x6920, 0xa184, 0x0c00, 0x0040, 0x3cab,
+	0xd0dc, 0x0040, 0x3c76, 0x7064, 0xa086, 0x0004, 0x00c0, 0x3c72,
+	0x7074, 0xa206, 0x00c0, 0x3c72, 0x7078, 0xa306, 0x00c0, 0x3c72,
+	0x7066, 0x707e, 0x1078, 0x40d7, 0x0078, 0x3cab, 0x681b, 0x0005,
+	0xc1ad, 0xc1d4, 0x6922, 0x1078, 0x40d0, 0x707f, 0x0000, 0x0078,
+	0x3cab, 0x7003, 0x0005, 0xb284, 0x0300, 0x0040, 0x3c8b, 0x2001,
+	0x95e0, 0x0078, 0x3c8d, 0x2001, 0x9612, 0x2068, 0x704e, 0x157e,
+	0x20a9, 0x0032, 0x2003, 0x0000, 0x8000, 0x00f0, 0x3c92, 0x157f,
+	0xb284, 0x0300, 0x0040, 0x3c9f, 0xc2fc, 0x0078, 0x3ca0, 0xc2fd,
+	0x6a16, 0xad80, 0x0009, 0x7046, 0x68b7, 0x0700, 0x6823, 0x0800,
+	0x6827, 0x0003, 0x007c, 0xc6ec, 0xa6ac, 0x0060, 0x0040, 0x3cfd,
+	0x6b98, 0x6c94, 0x69ac, 0x68b0, 0xa105, 0x00c0, 0x3cd8, 0x7bd2,
+	0x7bda, 0x7cd6, 0x7cde, 0xa586, 0x0060, 0x0040, 0x3d02, 0xd6f4,
+	0x00c0, 0x3cc3, 0xc6ed, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079,
+	0xd69c, 0x0040, 0x3cd0, 0x2009, 0x0078, 0x2019, 0x0000, 0x2320,
+	0x791a, 0xd6ec, 0x0040, 0x3d0d, 0x1078, 0x48bd, 0x0078, 0x3d0d,
+	0x68b0, 0xa31a, 0x2100, 0xa423, 0x2400, 0xa305, 0x0040, 0x3d04,
+	0x7bd2, 0x7bda, 0x7cd6, 0x7cde, 0x68b0, 0xd6f4, 0x00c0, 0x3ce9,
+	0xc6ed, 0xc6f4, 0x7e5a, 0x2011, 0x0079, 0xd69c, 0x0040, 0x3cf5,
+	0x2011, 0x0078, 0x2019, 0x0000, 0x2320, 0x7a1a, 0xd6ec, 0x0040,
+	0x3d0d, 0x1078, 0x48f5, 0x0078, 0x3d0d, 0x2019, 0x0000, 0x2320,
+	0x0078, 0x3d04, 0xa6b4, 0xb7ff, 0x7e5a, 0x2009, 0x0079, 0xd69c,
+	0x0040, 0x3d0c, 0x2009, 0x0078, 0x791a, 0x68c0, 0x705a, 0x2d00,
+	0x704e, 0x68c4, 0x2060, 0x71d4, 0x2001, 0x4e01, 0x2004, 0xd0c4,
+	0x00c0, 0x3d62, 0x70d8, 0xa02d, 0x0040, 0x3d3b, 0xd1bc, 0x0040,
+	0x3d55, 0x7a80, 0xa294, 0x0f00, 0x70dc, 0xa206, 0x0040, 0x3d2c,
+	0x78e0, 0xa504, 0x00c0, 0x3d62, 0x70da, 0xc1bc, 0x71d6, 0x0078,
+	0x3d62, 0x2031, 0x0001, 0x852c, 0x0048, 0x3d3a, 0x8633, 0x8210,
+	0x0078, 0x3d33, 0x007c, 0x7de0, 0xa594, 0xff00, 0x0040, 0x3d48,
+	0x2011, 0x0008, 0x852f, 0x1078, 0x3d31, 0x8637, 0x0078, 0x3d4a,
+	0x1078, 0x3d31, 0x8217, 0x7880, 0xa084, 0x0f00, 0xa206, 0x0040,
+	0x3d62, 0x72de, 0x76da, 0x0078, 0x3d62, 0x7a80, 0xa294, 0x0f00,
+	0x70dc, 0xa236, 0x0040, 0x3d52, 0x78e0, 0xa534, 0x0040, 0x3d52,
+	0xc1bd, 0x71d6, 0xd1b4, 0x00c0, 0x29c1, 0x2300, 0xa405, 0x0040,
+	0x29c1, 0x70a4, 0xa086, 0x0001, 0x00c0, 0x2a0b, 0x007c, 0x6020,
+	0xa005, 0x0040, 0x3d7d, 0x8001, 0x6022, 0x6008, 0xa085, 0x0008,
+	0x600a, 0x700f, 0x0100, 0x702c, 0x6026, 0x007c, 0xa006, 0x1078,
+	0x4586, 0x7000, 0xa086, 0x0002, 0x0040, 0x3d8b, 0x7064, 0xa086,
+	0x0005, 0x00c0, 0x3d95, 0x682b, 0x0000, 0x6817, 0x0000, 0x681b,
 	0x0001, 0x6823, 0x0040, 0x681f, 0x0100, 0x7000, 0xa084, 0x000f,
-	0x0079, 0x3b8a, 0x2946, 0x3b94, 0x3b94, 0x3bb1, 0x3b9c, 0x2946,
-	0x3b92, 0x3b92, 0x1078, 0x28ec, 0x1078, 0x3bbc, 0x1078, 0x3bb5,
-	0x1078, 0x202a, 0x0078, 0x2946, 0x7064, 0x7067, 0x0000, 0x7083,
-	0x0000, 0x0079, 0x3ba3, 0x3bad, 0x3bad, 0x3bab, 0x3bab, 0x3bab,
-	0x3bad, 0x3bab, 0x3bad, 0x0079, 0x2e5c, 0x7067, 0x0000, 0x0078,
-	0x2946, 0x681b, 0x0000, 0x0078, 0x35ae, 0x6800, 0xa005, 0x00c0,
-	0x3bba, 0x6002, 0x6006, 0x007c, 0x6410, 0x84ff, 0x0040, 0x3bce,
-	0x2009, 0x4a02, 0x2104, 0x8001, 0x200a, 0x8421, 0x6412, 0x00c0,
-	0x3bce, 0x2021, 0x4a04, 0x2404, 0xc0a5, 0x2022, 0x6008, 0xc0a4,
-	0x600a, 0x007c, 0x6018, 0xa005, 0x0040, 0x3bd8, 0x8001, 0x601a,
-	0x007c, 0x1078, 0x4131, 0x681b, 0x0018, 0x0078, 0x3c1a, 0x1078,
-	0x4131, 0x681b, 0x0019, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b,
-	0x001a, 0x0078, 0x3c1a, 0x1078, 0x4131, 0x681b, 0x0003, 0x0078,
-	0x3c1a, 0x7774, 0x1078, 0x3fe1, 0x7178, 0xa18c, 0x00ff, 0x3210,
-	0xa294, 0x0300, 0x0040, 0x3c00, 0xa1e8, 0x8fc0, 0x0078, 0x3c02,
-	0xa1e8, 0x90d0, 0x2d04, 0x2d08, 0x2068, 0xa005, 0x00c0, 0x3c0a,
-	0x0078, 0x2946, 0x6814, 0xc0fc, 0x7274, 0xc2fc, 0xa206, 0x0040,
-	0x3c14, 0x6800, 0x0078, 0x3c03, 0x6800, 0x200a, 0x681b, 0x0005,
-	0x707f, 0x0000, 0x1078, 0x3bbc, 0x6820, 0xd084, 0x00c0, 0x3c22,
-	0x1078, 0x3bb5, 0x1078, 0x3bd2, 0x681f, 0x0000, 0x6823, 0x0020,
-	0x1078, 0x202a, 0x0078, 0x2946, 0xa282, 0x0003, 0x00c0, 0x3e9d,
-	0x7da8, 0xa5ac, 0x00ff, 0x7ea8, 0xa6b4, 0x00ff, 0x6920, 0xc1bd,
-	0x6922, 0xd1c4, 0x0040, 0x3c86, 0xc1c4, 0x6922, 0xa6b4, 0x00ff,
-	0x0040, 0x3c73, 0xa682, 0x000c, 0x0048, 0x3c4a, 0x0040, 0x3c4a,
-	0x2031, 0x000c, 0x2500, 0xa086, 0x000a, 0x0040, 0x3c51, 0x852b,
-	0x852b, 0x1078, 0x3f73, 0x0040, 0x3c59, 0x1078, 0x3d55, 0x0078,
-	0x3c7c, 0x1078, 0x3f2e, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5,
-	0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x6920, 0xc1c5, 0x6922, 0x7e58,
-	0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3c70, 0x781b, 0x0061, 0x007c,
-	0x781b, 0x0075, 0x007c, 0x0c7e, 0x2960, 0x6004, 0xa084, 0xfff5,
-	0x6006, 0x1078, 0x3d8a, 0x0c7f, 0x7e58, 0xd6d4, 0x00c0, 0x3c83,
-	0x781b, 0x0064, 0x007c, 0x781b, 0x0076, 0x007c, 0x0c7e, 0x7058,
-	0x2060, 0x6100, 0xd1e4, 0x0040, 0x3ccf, 0x6208, 0x8217, 0xa294,
-	0x00ff, 0xa282, 0x000c, 0x0048, 0x3c99, 0x0040, 0x3c99, 0x2011,
-	0x000c, 0x2600, 0xa202, 0x00c8, 0x3c9e, 0x2230, 0x6208, 0xa294,
-	0x00ff, 0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3cb3, 0x78ec,
-	0xd0e4, 0x0040, 0x3cb3, 0xa282, 0x000a, 0x00c8, 0x3cb9, 0x2011,
-	0x000a, 0x0078, 0x3cb9, 0xa282, 0x000c, 0x00c8, 0x3cb9, 0x2011,
-	0x000c, 0x2200, 0xa502, 0x00c8, 0x3cbe, 0x2228, 0x1078, 0x3f32,
-	0x2500, 0xa086, 0x000a, 0x0040, 0x3cc7, 0x852b, 0x852b, 0x1078,
-	0x3f73, 0x0040, 0x3ccf, 0x1078, 0x3d55, 0x0078, 0x3cd3, 0x1078,
-	0x3f2e, 0x1078, 0x3d8a, 0x7858, 0xc095, 0x785a, 0x0c7f, 0x781b,
-	0x0075, 0x007c, 0x0c7e, 0x2960, 0x6000, 0xd0e4, 0x00c0, 0x3cf1,
-	0x6010, 0xa084, 0x000f, 0x00c0, 0x3ceb, 0x6104, 0xa18c, 0xfff5,
-	0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078,
-	0x3d1c, 0x68a0, 0xd0cc, 0x00c0, 0x3ceb, 0x6208, 0xa294, 0x00ff,
-	0x2001, 0x4a05, 0x2004, 0xd0e4, 0x00c0, 0x3d0a, 0x78ec, 0xd0e4,
-	0x0040, 0x3d0a, 0xa282, 0x000a, 0x00c0, 0x3d0a, 0x2011, 0x000a,
-	0x0078, 0x3d10, 0xa282, 0x000c, 0x00c8, 0x3d10, 0x2011, 0x000c,
-	0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c, 0x0048, 0x3d1c,
-	0x0040, 0x3d1c, 0x2019, 0x000c, 0x78ab, 0x0001, 0x78ab, 0x0003,
-	0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005, 0x6820, 0xc0c5,
-	0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3d38, 0xc0b4, 0x70d6, 0x70b8,
-	0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
-	0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c, 0xfff5, 0x6106,
-	0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3d46, 0x78ab, 0x0001,
+	0x0079, 0x3d9a, 0x29c5, 0x3daa, 0x3da4, 0x3dcc, 0x3db4, 0x29c5,
+	0x3da2, 0x3da2, 0x1078, 0x296b, 0x1078, 0x3dd7, 0x1078, 0x3dd0,
+	0x0078, 0x3db0, 0x1078, 0x3dd7, 0x705c, 0x2060, 0x6800, 0x6002,
+	0x1078, 0x202c, 0x0078, 0x29c5, 0x7064, 0x7067, 0x0000, 0x7083,
+	0x0000, 0x0079, 0x3dbb, 0x3dc8, 0x3dc8, 0x3dc3, 0x3dc3, 0x3dc3,
+	0x3dc8, 0x3dc3, 0x3dc8, 0x77d4, 0xc7dd, 0x77d6, 0x0079, 0x2f35,
+	0x7067, 0x0000, 0x0078, 0x29c5, 0x681b, 0x0000, 0x0078, 0x36c8,
+	0x6800, 0xa005, 0x00c0, 0x3dd5, 0x6002, 0x6006, 0x007c, 0x6410,
+	0x84ff, 0x0040, 0x3de9, 0x2009, 0x4e02, 0x2104, 0x8001, 0x200a,
+	0x8421, 0x6412, 0x00c0, 0x3de9, 0x2021, 0x4e04, 0x2404, 0xc0a5,
+	0x2022, 0x6008, 0xc0a4, 0x600a, 0x007c, 0x6018, 0xa005, 0x0040,
+	0x3df3, 0x8001, 0x601a, 0x007c, 0x1078, 0x4383, 0x681b, 0x0018,
+	0x0078, 0x3e34, 0x1078, 0x4383, 0x681b, 0x0019, 0x0078, 0x3e34,
+	0x1078, 0x4383, 0x681b, 0x001a, 0x0078, 0x3e34, 0x1078, 0x4383,
+	0x681b, 0x0003, 0x0078, 0x3e34, 0x7774, 0x1078, 0x41fe, 0x7178,
+	0xa18c, 0x00ff, 0x3210, 0xa294, 0x0300, 0x0040, 0x3e1b, 0xa1e8,
+	0x93c0, 0x0078, 0x3e1d, 0xa1e8, 0x94d0, 0x2d04, 0x2d08, 0x2068,
+	0xa005, 0x00c0, 0x3e26, 0x707e, 0x0078, 0x29c5, 0x6814, 0x7274,
+	0xa206, 0x0040, 0x3e2e, 0x6800, 0x0078, 0x3e1e, 0x6800, 0x200a,
+	0x681b, 0x0005, 0x707f, 0x0000, 0x1078, 0x3dd7, 0x6820, 0xd084,
+	0x00c0, 0x3e3c, 0x1078, 0x3dd0, 0x1078, 0x3ded, 0x681f, 0x0000,
+	0x6823, 0x0020, 0x1078, 0x202c, 0x0078, 0x29c5, 0xa282, 0x0003,
+	0x00c0, 0x40b7, 0x7da8, 0xa5ac, 0x00ff, 0x7e5a, 0x7ea8, 0xa6b4,
+	0x00ff, 0x6920, 0xc1bd, 0x6922, 0xd1c4, 0x0040, 0x3ea1, 0xc1c4,
+	0x6922, 0xa6b4, 0x00ff, 0x0040, 0x3e8e, 0xa682, 0x000c, 0x0048,
+	0x3e65, 0x0040, 0x3e65, 0x2031, 0x000c, 0x2500, 0xa086, 0x000a,
+	0x0040, 0x3e6c, 0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3e74,
+	0x1078, 0x3f6f, 0x0078, 0x3e97, 0x1078, 0x414b, 0x0c7e, 0x2960,
+	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x6920,
+	0xc1c5, 0x6922, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0, 0x3e8b,
+	0x781b, 0x0064, 0x007c, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960,
+	0x6004, 0xa084, 0xfff5, 0x6006, 0x1078, 0x3fa5, 0x0c7f, 0x7e58,
+	0xd6d4, 0x00c0, 0x3e9e, 0x781b, 0x0067, 0x007c, 0x781b, 0x0079,
+	0x007c, 0x0c7e, 0x7058, 0x2060, 0x6100, 0xd1e4, 0x0040, 0x3eea,
+	0x6208, 0x8217, 0xa294, 0x00ff, 0xa282, 0x000c, 0x0048, 0x3eb4,
+	0x0040, 0x3eb4, 0x2011, 0x000c, 0x2600, 0xa202, 0x00c8, 0x3eb9,
+	0x2230, 0x6208, 0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4,
+	0x00c0, 0x3ece, 0x78ec, 0xd0e4, 0x0040, 0x3ece, 0xa282, 0x000a,
+	0x00c8, 0x3ed4, 0x2011, 0x000a, 0x0078, 0x3ed4, 0xa282, 0x000c,
+	0x00c8, 0x3ed4, 0x2011, 0x000c, 0x2200, 0xa502, 0x00c8, 0x3ed9,
+	0x2228, 0x1078, 0x414f, 0x2500, 0xa086, 0x000a, 0x0040, 0x3ee2,
+	0x852b, 0x852b, 0x1078, 0x4190, 0x0040, 0x3eea, 0x1078, 0x3f6f,
+	0x0078, 0x3eee, 0x1078, 0x414b, 0x1078, 0x3fa5, 0x7858, 0xc095,
+	0x785a, 0x0c7f, 0x781b, 0x0078, 0x007c, 0x0c7e, 0x2960, 0x6000,
+	0xd0e4, 0x00c0, 0x3f0b, 0xa084, 0x0040, 0x00c0, 0x3f05, 0x6104,
+	0xa18c, 0xfff5, 0x6106, 0x0c7f, 0x007c, 0x2011, 0x0032, 0x2019,
+	0x0000, 0x0078, 0x3f36, 0x68a0, 0xd0cc, 0x00c0, 0x3f05, 0x6208,
+	0xa294, 0x00ff, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x3f24,
+	0x78ec, 0xd0e4, 0x0040, 0x3f24, 0xa282, 0x000b, 0x00c8, 0x3f24,
+	0x2011, 0x000a, 0x0078, 0x3f2a, 0xa282, 0x000c, 0x00c8, 0x3f2a,
+	0x2011, 0x000c, 0x6308, 0x831f, 0xa39c, 0x00ff, 0xa382, 0x000c,
+	0x0048, 0x3f36, 0x0040, 0x3f36, 0x2019, 0x000c, 0x78ab, 0x0001,
 	0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa, 0xa8c0, 0x0005,
-	0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e, 0x7158, 0x2160,
-	0x2018, 0xa08c, 0x0020, 0x0040, 0x3d5e, 0xc0ac, 0x2008, 0xa084,
-	0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae, 0x6612, 0x78a4,
-	0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xa39c, 0x0020, 0x0040,
-	0x3d73, 0xa085, 0x4000, 0xc0fc, 0xd0b4, 0x00c0, 0x3d78, 0xc0fd,
-	0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f, 0x8637, 0x8204, 0x8004,
-	0xa084, 0x00ff, 0xa605, 0x600e, 0x6004, 0xa084, 0xfff5, 0x6006,
-	0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x6018, 0x789a, 0x78a4,
-	0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884, 0xa084, 0xfff0, 0x7886,
-	0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f, 0x007c, 0xa282, 0x0002,
-	0x00c0, 0x3e9d, 0x7aa8, 0x6920, 0xc1bd, 0x6922, 0xd1cc, 0x0040,
-	0x3dd9, 0xc1cc, 0x6922, 0xa294, 0x00ff, 0xa282, 0x0002, 0x00c8,
-	0x3e9d, 0x1078, 0x3e2a, 0x1078, 0x3d8a, 0xa980, 0x0001, 0x200c,
-	0x1078, 0x3fdd, 0x1078, 0x3cda, 0x88ff, 0x0040, 0x3dcf, 0x789b,
-	0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695, 0x7e5a, 0xd6d4, 0x00c0,
-	0x3dcc, 0x781b, 0x0061, 0x007c, 0x781b, 0x0075, 0x007c, 0x7e58,
-	0xd6d4, 0x00c0, 0x3dd6, 0x781b, 0x0064, 0x007c, 0x781b, 0x0076,
-	0x007c, 0xa282, 0x0002, 0x00c8, 0x3de1, 0xa284, 0x0001, 0x0040,
-	0x3dea, 0x7158, 0xa188, 0x0000, 0x210c, 0xd1ec, 0x00c0, 0x3dea,
-	0x2011, 0x0000, 0x1078, 0x3f0f, 0x1078, 0x3e2a, 0x1078, 0x3d8a,
-	0x7858, 0xc095, 0x785a, 0x781b, 0x0075, 0x007c, 0x0c7e, 0x027e,
-	0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec, 0x00c0, 0x3e0b, 0x6014,
-	0xa084, 0x0040, 0x00c0, 0x3e09, 0xc1a4, 0x6106, 0xa006, 0x0078,
-	0x3e27, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab,
-	0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3e23,
-	0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a,
-	0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200, 0x6822, 0x027f,
-	0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff, 0x0040, 0x3e32,
-	0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a, 0x78a4, 0xa084,
-	0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x3e3f, 0xc0fd, 0x78a6,
-	0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f, 0x007c, 0x007e,
-	0x7000, 0xa086, 0x0003, 0x0040, 0x3e50, 0x007f, 0x0078, 0x3e53,
-	0x007f, 0x0078, 0x3e9a, 0xd6ac, 0x0040, 0x3e9a, 0x7888, 0xa084,
-	0x0040, 0x0040, 0x3e9a, 0x7bb8, 0xa384, 0x003f, 0x831b, 0x00c8,
-	0x3e62, 0x8000, 0xa005, 0x0040, 0x3e77, 0x831b, 0x00c8, 0x3e6b,
-	0x8001, 0x0040, 0x3e97, 0xd6f4, 0x0040, 0x3e77, 0x78b8, 0x801b,
-	0x00c8, 0x3e73, 0x8000, 0xa084, 0x003f, 0x00c0, 0x3e97, 0xc6f4,
-	0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108, 0x00c8, 0x3e82,
-	0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade, 0x1078, 0x46e5,
-	0x781b, 0x0073, 0xb284, 0x0300, 0x0040, 0x3e92, 0x2001, 0x0000,
-	0x0078, 0x3e94, 0x2001, 0x0001, 0x1078, 0x4585, 0x007c, 0x781b,
-	0x0073, 0x007c, 0x781b, 0x0076, 0x007c, 0x1078, 0x3ec2, 0x781b,
-	0x0075, 0x007c, 0x1078, 0x3eae, 0x781b, 0x0075, 0x007c, 0x6827,
-	0x0002, 0x1078, 0x3eb6, 0x781b, 0x0075, 0x007c, 0x2001, 0x0005,
-	0x0078, 0x3ec4, 0x2001, 0x000c, 0x0078, 0x3ec4, 0x2001, 0x0006,
-	0x0078, 0x3ec4, 0x2001, 0x000d, 0x0078, 0x3ec4, 0x2001, 0x0009,
-	0x0078, 0x3ec4, 0x2001, 0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d,
-	0x7e5a, 0x70d4, 0xd0b4, 0x0040, 0x3eda, 0xc0b4, 0x70d6, 0x0c7e,
+	0x6820, 0xc0c5, 0x6822, 0x70d4, 0xd0b4, 0x0040, 0x3f52, 0xc0b4,
+	0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018,
+	0x8001, 0x601a, 0x0c7f, 0x007c, 0x0c7e, 0x2960, 0x6104, 0xa18c,
+	0xfff5, 0x6106, 0x2011, 0x0032, 0x2019, 0x0000, 0x0078, 0x3f60,
+	0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7aaa, 0x7baa,
+	0xa8c0, 0x0005, 0x6820, 0xc0c5, 0x6822, 0x0c7f, 0x007c, 0x0c7e,
+	0x7158, 0x2160, 0x2018, 0xa08c, 0x0020, 0x0040, 0x3f78, 0xc0ac,
+	0x2008, 0xa084, 0xfff0, 0xa635, 0x7e86, 0x6018, 0x789a, 0x7eae,
+	0x6612, 0x78a4, 0xa084, 0xfff0, 0xa18c, 0x000f, 0xa105, 0xc0f4,
+	0xa39c, 0x0020, 0x0040, 0x3f8e, 0xa085, 0x4000, 0xc0fc, 0xd0b4,
+	0x00c0, 0x3f93, 0xc0fd, 0x78a6, 0x6016, 0x788a, 0xa6b4, 0x000f,
+	0x8637, 0x8204, 0x8004, 0xa084, 0x00ff, 0xa605, 0x600e, 0x6004,
+	0xa084, 0xfff5, 0x6006, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060,
+	0x6018, 0x789a, 0x78a4, 0xa084, 0xfff0, 0x78a6, 0x6012, 0x7884,
+	0xa084, 0xfff0, 0x7886, 0x600c, 0xa084, 0x00ff, 0x600e, 0x0c7f,
+	0x007c, 0xa282, 0x0002, 0x00c0, 0x40b7, 0x7aa8, 0x6920, 0xc1bd,
+	0x6922, 0xd1cc, 0x0040, 0x3ff4, 0xc1cc, 0x6922, 0xa294, 0x00ff,
+	0xa282, 0x0002, 0x00c8, 0x40b7, 0x1078, 0x4044, 0x1078, 0x3fa5,
+	0xa980, 0x0001, 0x200c, 0x1078, 0x41fa, 0x1078, 0x3ef5, 0x88ff,
+	0x0040, 0x3fea, 0x789b, 0x0060, 0x2800, 0x78aa, 0x7e58, 0xc695,
+	0x7e5a, 0xd6d4, 0x00c0, 0x3fe7, 0x781b, 0x0064, 0x007c, 0x781b,
+	0x0078, 0x007c, 0x7e58, 0xd6d4, 0x00c0, 0x3ff1, 0x781b, 0x0067,
+	0x007c, 0x781b, 0x0079, 0x007c, 0xa282, 0x0002, 0x00c8, 0x3ffc,
+	0xa284, 0x0001, 0x0040, 0x4005, 0x7158, 0xa188, 0x0000, 0x210c,
+	0xd1ec, 0x00c0, 0x4005, 0x2011, 0x0000, 0x1078, 0x412c, 0x1078,
+	0x4044, 0x1078, 0x3fa5, 0x7858, 0xc095, 0x785a, 0x781b, 0x0078,
+	0x007c, 0x0c7e, 0x027e, 0x2960, 0x6000, 0x2011, 0x0001, 0xd0ec,
+	0x00c0, 0x4025, 0xa084, 0x0080, 0x00c0, 0x4023, 0xc1a4, 0x6106,
+	0xa006, 0x0078, 0x4041, 0x2011, 0x0000, 0x78ab, 0x0001, 0x78ab,
+	0x0002, 0x78ab, 0x0003, 0x7aaa, 0xa8c0, 0x0004, 0x70d4, 0xd0b4,
+	0x0040, 0x403d, 0xc0b4, 0x70d6, 0x70b8, 0xa065, 0x6008, 0xa084,
+	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x6820, 0xa085, 0x0200,
+	0x6822, 0x027f, 0x0c7f, 0x007c, 0x0c7e, 0x7058, 0x2060, 0x82ff,
+	0x0040, 0x404c, 0x2011, 0x0040, 0x6018, 0xa080, 0x0002, 0x789a,
+	0x78a4, 0xa084, 0xffbf, 0xa205, 0xc0fc, 0xd0b4, 0x00c0, 0x4059,
+	0xc0fd, 0x78a6, 0x6016, 0x788a, 0x6004, 0xc0a4, 0x6006, 0x0c7f,
+	0x007c, 0x007e, 0x7000, 0xa086, 0x0003, 0x0040, 0x406a, 0x007f,
+	0x0078, 0x406d, 0x007f, 0x0078, 0x40b4, 0xd6ac, 0x0040, 0x40b4,
+	0x7888, 0xa084, 0x0040, 0x0040, 0x40b4, 0x7bb8, 0xa384, 0x003f,
+	0x831b, 0x00c8, 0x407c, 0x8000, 0xa005, 0x0040, 0x4091, 0x831b,
+	0x00c8, 0x4085, 0x8001, 0x0040, 0x40b1, 0xd6f4, 0x0040, 0x4091,
+	0x78b8, 0x801b, 0x00c8, 0x408d, 0x8000, 0xa084, 0x003f, 0x00c0,
+	0x40b1, 0xc6f4, 0x7e5a, 0x79d8, 0x7adc, 0x2001, 0x0001, 0xa108,
+	0x00c8, 0x409c, 0xa291, 0x0000, 0x79d2, 0x79da, 0x7ad6, 0x7ade,
+	0x1078, 0x49c3, 0x781b, 0x0076, 0xb284, 0x0300, 0x0040, 0x40ac,
+	0x2001, 0x0000, 0x0078, 0x40ae, 0x2001, 0x0001, 0x1078, 0x484b,
+	0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0079, 0x007c, 0x1078,
+	0x40df, 0x781b, 0x0078, 0x007c, 0x1078, 0x40c8, 0x781b, 0x0078,
+	0x007c, 0x6827, 0x0002, 0x1078, 0x40d0, 0x781b, 0x0078, 0x007c,
+	0x2001, 0x0005, 0x0078, 0x40e1, 0x2001, 0x000c, 0x0078, 0x40e1,
+	0x6820, 0xc0d5, 0x6822, 0x2001, 0x0006, 0x0078, 0x40e1, 0x2001,
+	0x000d, 0x0078, 0x40e1, 0x2001, 0x0009, 0x0078, 0x40e1, 0x2001,
+	0x0007, 0x789b, 0x007e, 0x78aa, 0xc69d, 0x7e5a, 0x70d4, 0xd0b4,
+	0x0040, 0x40f7, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008,
+	0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c,
+	0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b, 0x873b, 0x8703, 0x017e,
+	0xb28c, 0x0300, 0x0040, 0x4108, 0xa0e0, 0x52c0, 0x0078, 0x410a,
+	0xa0e0, 0x5340, 0x017f, 0xa7b8, 0x0020, 0x7f9a, 0x79a4, 0xa184,
+	0x000f, 0x0040, 0x411a, 0xa184, 0xfff0, 0x78a6, 0x6012, 0x6004,
+	0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a, 0x79a4, 0xa184, 0x0040,
+	0x0040, 0x412a, 0xa184, 0xffbf, 0xc0fd, 0x78a6, 0x6016, 0x6004,
+	0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b, 0x0010, 0x78ab, 0x0001,
+	0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa, 0x789b, 0x0060, 0x78ab,
+	0x0004, 0x70d4, 0xd0b4, 0x0040, 0x414a, 0xc0b4, 0x70d6, 0x0c7e,
 	0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001,
-	0x601a, 0x0c7f, 0x007c, 0x077e, 0x873f, 0xa7bc, 0x000f, 0x873b,
-	0x873b, 0x8703, 0x017e, 0xb28c, 0x0300, 0x0040, 0x3eeb, 0xa0e0,
-	0x4ec0, 0x0078, 0x3eed, 0xa0e0, 0x4f40, 0x017f, 0xa7b8, 0x0020,
-	0x7f9a, 0x79a4, 0xa184, 0x000f, 0x0040, 0x3efd, 0xa184, 0xfff0,
-	0x78a6, 0x6012, 0x6004, 0xc09d, 0x6006, 0x8738, 0x8738, 0x7f9a,
-	0x79a4, 0xa184, 0x0040, 0x0040, 0x3f0d, 0xa184, 0xffbf, 0xc0fd,
-	0x78a6, 0x6016, 0x6004, 0xc0a5, 0x6006, 0x077f, 0x007c, 0x789b,
-	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0002, 0x78ab, 0x0003, 0x7aaa,
-	0x789b, 0x0060, 0x78ab, 0x0004, 0x70d4, 0xd0b4, 0x0040, 0x3f2d,
-	0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084, 0xfbef,
-	0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000,
-	0x2029, 0x0032, 0x789b, 0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003,
-	0x78ab, 0x0001, 0x7daa, 0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005,
-	0x70d4, 0xd0b4, 0x0040, 0x3f51, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8,
-	0xa065, 0x6008, 0xa084, 0xfbef, 0x600a, 0x6018, 0x8001, 0x601a,
-	0x0c7f, 0x007c, 0x157e, 0x8007, 0xa084, 0x00ff, 0x8003, 0x8003,
-	0xa080, 0x0020, 0x789a, 0x79a4, 0xa18c, 0xfff0, 0x2021, 0x3fc6,
-	0x2019, 0x0011, 0x20a9, 0x000e, 0x2011, 0x0032, 0x2404, 0xa084,
-	0xfff0, 0xa106, 0x0040, 0x3f71, 0x8420, 0x2300, 0xa210, 0x00f0,
-	0x3f66, 0x157f, 0x007c, 0x157e, 0x2001, 0x4a05, 0x2004, 0xd0e4,
-	0x00c0, 0x3fa4, 0x2021, 0x3fd4, 0x20a9, 0x0009, 0x2011, 0x0028,
-	0xa582, 0x0019, 0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x95a9,
-	0x2011, 0x0032, 0xa582, 0x0032, 0x0040, 0x3fba, 0x0048, 0x3fba,
-	0x8420, 0x95a9, 0x2019, 0x000a, 0x2011, 0x0064, 0x2200, 0xa502,
-	0x0040, 0x3fba, 0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0,
-	0x3f96, 0x157f, 0x0078, 0x3fb8, 0x2021, 0x3fc6, 0x2019, 0x0011,
-	0x20a9, 0x000e, 0x2011, 0x0032, 0x2200, 0xa502, 0x0040, 0x3fba,
-	0x0048, 0x3fba, 0x8420, 0x2300, 0xa210, 0x00f0, 0x3fac, 0x157f,
-	0xa006, 0x007c, 0x157f, 0xa582, 0x0064, 0x00c8, 0x3fc3, 0x7808,
-	0xa085, 0x0070, 0x780a, 0x2404, 0xa005, 0x007c, 0x1209, 0x3002,
-	0x3202, 0x4203, 0x4403, 0x5404, 0x5604, 0x6605, 0x6805, 0x7806,
-	0x7a06, 0x0c07, 0x0c07, 0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05,
-	0x6a06, 0x6c06, 0x7c07, 0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046,
-	0x007c, 0xa784, 0x0f00, 0x800b, 0xa784, 0x001f, 0x8003, 0x8003,
-	0x8003, 0x8003, 0xa105, 0xd7fc, 0x0040, 0x3ff2, 0xa0e0, 0x6fc0,
-	0x0078, 0x3ff4, 0xa0e0, 0x4fc0, 0x007c, 0x0e7e, 0x0f7e, 0xd084,
-	0x0040, 0x4002, 0x2079, 0x0100, 0x2009, 0x4a80, 0x2071, 0x4a80,
-	0x0078, 0x4014, 0x2009, 0x4a40, 0x007e, 0x2001, 0x4a04, 0x2004,
-	0xd0ec, 0x007f, 0x0040, 0x4010, 0x2079, 0x0100, 0x0078, 0x4014,
-	0x2079, 0x0200, 0x2071, 0x4a40, 0x2091, 0x8000, 0x2104, 0xa084,
-	0x000f, 0x0079, 0x401b, 0x405d, 0x4025, 0x4025, 0x4025, 0x4025,
-	0x4025, 0x4023, 0x4023, 0x1078, 0x28ec, 0x784b, 0x0004, 0x7848,
-	0xa084, 0x0004, 0x00c0, 0x4027, 0x784b, 0x0008, 0x7848, 0xa084,
-	0x0008, 0x00c0, 0x402e, 0x68b4, 0xc0f5, 0x68b6, 0x7858, 0xc0f5,
-	0x785a, 0x7830, 0xd0bc, 0x00c0, 0x405d, 0x007e, 0x2001, 0x4a04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4049, 0xb284, 0x0300, 0x0078,
-	0x404b, 0xb284, 0x0400, 0x0040, 0x4051, 0x0018, 0x405d, 0x0078,
-	0x4053, 0x0028, 0x405d, 0x681c, 0xd0ac, 0x00c0, 0x405b, 0x1078,
-	0x40d5, 0x0078, 0x405d, 0x781b, 0x00f0, 0x2091, 0x8001, 0x0f7f,
-	0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4a01, 0x2004, 0xd0ac, 0x00c0,
-	0x40c7, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
-	0xb28c, 0x0300, 0x0040, 0x4078, 0xa0e0, 0x4ec0, 0x0078, 0x407a,
-	0xa0e0, 0x4f40, 0x6004, 0xa084, 0x000a, 0x00c0, 0x40c7, 0x6108,
-	0xa194, 0xff00, 0x0040, 0x40c7, 0xa18c, 0x00ff, 0x2001, 0x000a,
-	0xa106, 0x0040, 0x40a6, 0x2001, 0x000c, 0xa106, 0x0040, 0x40aa,
-	0x2001, 0x0012, 0xa106, 0x0040, 0x40ae, 0x2001, 0x0014, 0xa106,
-	0x0040, 0x40b2, 0x2001, 0x0019, 0xa106, 0x0040, 0x40b6, 0x2001,
-	0x0032, 0xa106, 0x0040, 0x40ba, 0x0078, 0x40be, 0x2009, 0x000c,
-	0x0078, 0x40c0, 0x2009, 0x0012, 0x0078, 0x40c0, 0x2009, 0x0014,
-	0x0078, 0x40c0, 0x2009, 0x0019, 0x0078, 0x40c0, 0x2009, 0x0020,
-	0x0078, 0x40c0, 0x2009, 0x003f, 0x0078, 0x40c0, 0x2011, 0x0000,
-	0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x0c7f,
-	0x007c, 0x781b, 0x0076, 0x007c, 0x781b, 0x0075, 0x007c, 0x781b,
-	0x0064, 0x007c, 0x781b, 0x0061, 0x007c, 0x2009, 0x4a19, 0x210c,
-	0xa186, 0x0000, 0x0040, 0x40e7, 0xa186, 0x0001, 0x0040, 0x40ea,
-	0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x781b,
-	0x00e7, 0x007c, 0x701f, 0x000a, 0x007c, 0x2009, 0x4a19, 0x210c,
-	0xa186, 0x0000, 0x0040, 0x4102, 0xa186, 0x0001, 0x0040, 0x40ff,
-	0x701f, 0x000b, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c, 0x701f,
-	0x000a, 0x007c, 0x781b, 0x00e6, 0x007c, 0x781b, 0x00f0, 0x007c,
-	0x781b, 0x00ef, 0x007c, 0x781b, 0x00c0, 0x007c, 0x781b, 0x00bf,
-	0x007c, 0x6818, 0xd0fc, 0x0040, 0x4117, 0x681b, 0x001d, 0x7067,
-	0x0001, 0x781b, 0x0047, 0x007c, 0x7830, 0xa084, 0x00c0, 0x00c0,
-	0x4130, 0x7808, 0xc08c, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
-	0x78ec, 0xa084, 0x0021, 0x0040, 0x4130, 0x7808, 0xc08d, 0x780a,
-	0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830, 0xa084, 0x0040,
-	0x00c0, 0x4135, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4144,
-	0xb284, 0x0300, 0x0078, 0x4146, 0xb284, 0x0400, 0x0040, 0x414c,
-	0x0098, 0x4150, 0x0078, 0x414e, 0x00a8, 0x4150, 0x78ac, 0x007c,
-	0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005, 0x0005, 0x0005,
-	0x78ec, 0xa084, 0x0021, 0x0040, 0x4173, 0x007e, 0x2001, 0x4a04,
-	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4169, 0xb284, 0x0300, 0x0078,
-	0x416b, 0xb284, 0x0400, 0x0040, 0x4171, 0x0098, 0x416d, 0x0078,
-	0x4173, 0x00a8, 0x4171, 0x78ac, 0x007e, 0x7808, 0xa085, 0x0002,
-	0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0, 0x360e, 0xa784,
-	0x0070, 0x0040, 0x418b, 0x0c7e, 0x2d60, 0x2f68, 0x1078, 0x2881,
-	0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040, 0x4198, 0x784b,
-	0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946, 0x0078, 0x40c9,
-	0xa784, 0x0004, 0x0040, 0x41c7, 0x78b8, 0xa084, 0x4001, 0x0040,
-	0x41c7, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2946,
-	0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0, 0x41c7, 0x78c0,
-	0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f0, 0x007c, 0x784b,
-	0x0008, 0x6818, 0xd0fc, 0x0040, 0x41c4, 0x681b, 0x0015, 0xd6f4,
-	0x0040, 0x41c4, 0x681b, 0x0007, 0x1078, 0x40d5, 0x007c, 0x681b,
-	0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f, 0x0000, 0x6833,
-	0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x2f84,
-	0x007e, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x41e4,
-	0xb284, 0x0300, 0x0078, 0x41e6, 0xb284, 0x0400, 0x0040, 0x41ec,
-	0x0018, 0x2942, 0x0078, 0x41ee, 0x0028, 0x2942, 0x0078, 0x3ea2,
-	0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003, 0xd3fc,
-	0x0040, 0x41fe, 0xa080, 0x4f40, 0x0078, 0x4200, 0xa080, 0x4ec0,
-	0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020, 0x0020, 0x0000,
+	0x601a, 0x0c7f, 0x007c, 0x2031, 0x0000, 0x2029, 0x0032, 0x789b,
+	0x0010, 0x78ab, 0x0001, 0x78ab, 0x0003, 0x78ab, 0x0001, 0x7daa,
+	0x7eaa, 0x789b, 0x0060, 0x78ab, 0x0005, 0x70d4, 0xd0b4, 0x0040,
+	0x416e, 0xc0b4, 0x70d6, 0x0c7e, 0x70b8, 0xa065, 0x6008, 0xa084,
+	0xfbef, 0x600a, 0x6018, 0x8001, 0x601a, 0x0c7f, 0x007c, 0x157e,
+	0x8007, 0xa084, 0x00ff, 0x8003, 0x8003, 0xa080, 0x0020, 0x789a,
+	0x79a4, 0xa18c, 0xfff0, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9,
+	0x000e, 0x2011, 0x0032, 0x2404, 0xa084, 0xfff0, 0xa106, 0x0040,
+	0x418e, 0x8420, 0x2300, 0xa210, 0x00f0, 0x4183, 0x157f, 0x007c,
+	0x157e, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x41c1, 0x2021,
+	0x41f1, 0x20a9, 0x0009, 0x2011, 0x0028, 0xa582, 0x0019, 0x0040,
+	0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2011, 0x0032, 0xa582,
+	0x0032, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420, 0x95a9, 0x2019,
+	0x000a, 0x2011, 0x0064, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048,
+	0x41d7, 0x8420, 0x2300, 0xa210, 0x00f0, 0x41b3, 0x157f, 0x0078,
+	0x41d5, 0x2021, 0x41e3, 0x2019, 0x0011, 0x20a9, 0x000e, 0x2011,
+	0x0032, 0x2200, 0xa502, 0x0040, 0x41d7, 0x0048, 0x41d7, 0x8420,
+	0x2300, 0xa210, 0x00f0, 0x41c9, 0x157f, 0xa006, 0x007c, 0x157f,
+	0xa582, 0x0064, 0x00c8, 0x41e0, 0x7808, 0xa085, 0x0070, 0x780a,
+	0x2404, 0xa005, 0x007c, 0x1209, 0x3002, 0x3202, 0x4203, 0x4403,
+	0x5404, 0x5604, 0x6605, 0x6805, 0x7806, 0x7a06, 0x0c07, 0x0c07,
+	0x0e07, 0x10e1, 0x330a, 0x5805, 0x5a05, 0x6a06, 0x6c06, 0x7c07,
+	0x7e07, 0x0e00, 0x789b, 0x0010, 0xa046, 0x007c, 0xa784, 0x0f00,
+	0x800b, 0xa784, 0x001f, 0x8003, 0x8003, 0x8003, 0x8003, 0xa105,
+	0xd7fc, 0x0040, 0x420f, 0xa0e0, 0x73c0, 0x0078, 0x4211, 0xa0e0,
+	0x53c0, 0x007c, 0x0e7e, 0x0f7e, 0xd084, 0x0040, 0x421f, 0x2079,
+	0x0100, 0x2009, 0x4e80, 0x2071, 0x4e80, 0x0078, 0x422f, 0x2009,
+	0x4e40, 0x2071, 0x4e40, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x0040,
+	0x422d, 0x2079, 0x0100, 0x0078, 0x422f, 0x2079, 0x0200, 0x2091,
+	0x8000, 0x2104, 0xa084, 0x000f, 0x0079, 0x4236, 0x4240, 0x4240,
+	0x4240, 0x4240, 0x4240, 0x4240, 0x423e, 0x423e, 0x1078, 0x296b,
+	0x69b4, 0xc1f5, 0xa18c, 0xff9f, 0x69b6, 0xa005, 0x0040, 0x428f,
+	0x7858, 0xa084, 0xff9f, 0xa085, 0x6000, 0x785a, 0x7828, 0xa086,
+	0x1814, 0x00c0, 0x428f, 0x784b, 0x0004, 0x7848, 0xa084, 0x0004,
+	0x00c0, 0x4255, 0x784b, 0x0008, 0x7848, 0xa084, 0x0008, 0x00c0,
+	0x425c, 0x7830, 0xd0bc, 0x00c0, 0x428f, 0x007e, 0x2001, 0x4e04,
+	0x2004, 0xd0ec, 0x007f, 0x0040, 0x4271, 0xb284, 0x0300, 0x0078,
+	0x4273, 0xb284, 0x0400, 0x0040, 0x4279, 0x0018, 0x428f, 0x0078,
+	0x427b, 0x0028, 0x428f, 0x79e4, 0xa184, 0x0030, 0x0040, 0x428f,
+	0x78ec, 0xa084, 0x0003, 0x0040, 0x428f, 0x681c, 0xd0ac, 0x00c0,
+	0x428d, 0x1078, 0x4319, 0x0078, 0x428f, 0x781b, 0x00f9, 0x0f7f,
+	0x0e7f, 0x007c, 0x0c7e, 0x2001, 0x4e01, 0x2004, 0xd0ac, 0x00c0,
+	0x430b, 0x6814, 0x8007, 0xa084, 0x000f, 0x8003, 0x8003, 0x8003,
+	0xb28c, 0x0300, 0x0040, 0x42a8, 0xa0e0, 0x52c0, 0x0078, 0x42aa,
+	0xa0e0, 0x5340, 0x6004, 0xa084, 0x000a, 0x00c0, 0x430b, 0x6108,
+	0xa194, 0xff00, 0x0040, 0x430b, 0xa18c, 0x00ff, 0x2001, 0x000a,
+	0xa106, 0x0040, 0x42d6, 0x2001, 0x000c, 0xa106, 0x0040, 0x42da,
+	0x2001, 0x0012, 0xa106, 0x0040, 0x42de, 0x2001, 0x0014, 0xa106,
+	0x0040, 0x42e2, 0x2001, 0x0019, 0xa106, 0x0040, 0x42e6, 0x2001,
+	0x0032, 0xa106, 0x0040, 0x42ea, 0x0078, 0x42ee, 0x2009, 0x000c,
+	0x0078, 0x42f0, 0x2009, 0x0012, 0x0078, 0x42f0, 0x2009, 0x0014,
+	0x0078, 0x42f0, 0x2009, 0x0019, 0x0078, 0x42f0, 0x2009, 0x0020,
+	0x0078, 0x42f0, 0x2009, 0x003f, 0x0078, 0x42f0, 0x2011, 0x0000,
+	0x2100, 0xa205, 0x600a, 0x6004, 0xa085, 0x0002, 0x6006, 0x2061,
+	0x4e00, 0x6004, 0xd0bc, 0x0040, 0x430b, 0x6814, 0xd0fc, 0x00c0,
+	0x4306, 0x60ea, 0x2061, 0x4e40, 0x0078, 0x4309, 0x60ee, 0x2061,
+	0x4e80, 0x601f, 0x800f, 0x0c7f, 0x007c, 0x781b, 0x0079, 0x007c,
+	0x781b, 0x0078, 0x007c, 0x781b, 0x0067, 0x007c, 0x781b, 0x0064,
+	0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x432b,
+	0xa186, 0x0001, 0x0040, 0x432e, 0x701f, 0x000b, 0x7067, 0x0001,
+	0x781b, 0x0047, 0x007c, 0x781b, 0x00f0, 0x007c, 0x701f, 0x000a,
+	0x007c, 0x2009, 0x4e19, 0x210c, 0xa186, 0x0000, 0x0040, 0x4346,
+	0xa186, 0x0001, 0x0040, 0x4343, 0x701f, 0x000b, 0x7067, 0x0001,
+	0x781b, 0x0047, 0x007c, 0x701f, 0x000a, 0x007c, 0x781b, 0x00ef,
+	0x007c, 0x781b, 0x00f9, 0x007c, 0x781b, 0x00f8, 0x007c, 0x781b,
+	0x00c9, 0x007c, 0x781b, 0x00c8, 0x007c, 0x6818, 0xd0fc, 0x0040,
+	0x435b, 0x681b, 0x001d, 0x7067, 0x0001, 0x781b, 0x0047, 0x007c,
+	0x7830, 0xa084, 0x00c0, 0x00c0, 0x4382, 0x7808, 0xc08c, 0x780a,
+	0x0005, 0x0005, 0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x00c0,
+	0x437f, 0x2001, 0x4e05, 0x2004, 0xd0e4, 0x00c0, 0x437d, 0x7804,
+	0xa084, 0xff1f, 0xa085, 0x00e0, 0x7806, 0xa006, 0x007c, 0x7808,
+	0xc08d, 0x780a, 0x007c, 0x7808, 0xc08d, 0x780a, 0x007c, 0x7830,
+	0xa084, 0x0040, 0x00c0, 0x4387, 0x2001, 0x4e04, 0x2004, 0xd0ec,
+	0x0040, 0x4396, 0xb284, 0x0300, 0x0078, 0x4398, 0xb284, 0x0400,
+	0x0040, 0x439e, 0x0098, 0x43a2, 0x0078, 0x43a0, 0x00a8, 0x43a2,
+	0x78ac, 0x007c, 0x7808, 0xa084, 0xfffd, 0x780a, 0x0005, 0x0005,
+	0x0005, 0x0005, 0x78ec, 0xa084, 0x0021, 0x0040, 0x43c5, 0x007e,
+	0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f, 0x0040, 0x43bb, 0xb284,
+	0x0300, 0x0078, 0x43bd, 0xb284, 0x0400, 0x0040, 0x43c3, 0x0098,
+	0x43bf, 0x0078, 0x43c5, 0x00a8, 0x43c3, 0x78ac, 0x007e, 0x7808,
+	0xa085, 0x0002, 0x780a, 0x007f, 0x007c, 0xa784, 0x0001, 0x00c0,
+	0x3770, 0xa784, 0x0070, 0x0040, 0x43dd, 0x0c7e, 0x2d60, 0x2f68,
+	0x1078, 0x28df, 0x2d78, 0x2c68, 0x0c7f, 0xa784, 0x0008, 0x0040,
+	0x43ea, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003, 0x0040, 0x3770,
+	0x0078, 0x430d, 0xa784, 0x0004, 0x0040, 0x4419, 0x78b8, 0xa084,
+	0x4001, 0x0040, 0x4419, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x3770, 0x78e4, 0xa084, 0x0007, 0xa086, 0x0001, 0x00c0,
+	0x4419, 0x78c0, 0xa685, 0x4800, 0x2030, 0x7e5a, 0x781b, 0x00f9,
+	0x007c, 0x784b, 0x0008, 0x6818, 0xd0fc, 0x0040, 0x4416, 0x681b,
+	0x0015, 0xd6f4, 0x0040, 0x4416, 0x681b, 0x0007, 0x1078, 0x4319,
+	0x007c, 0x681b, 0x0003, 0x7858, 0xa084, 0x3f00, 0x681e, 0x682f,
+	0x0000, 0x6833, 0x0000, 0x784b, 0x0008, 0x78ec, 0xa084, 0x0003,
+	0x0040, 0x3066, 0x007e, 0x2001, 0x4e04, 0x2004, 0xd0ec, 0x007f,
+	0x0040, 0x4436, 0xb284, 0x0300, 0x0078, 0x4438, 0xb284, 0x0400,
+	0x0040, 0x443e, 0x0018, 0x29c1, 0x0078, 0x4440, 0x0028, 0x29c1,
+	0x0078, 0x40bc, 0x6b14, 0x8307, 0xa084, 0x000f, 0x8003, 0x8003,
+	0x8003, 0xd3fc, 0x0040, 0x4450, 0xa080, 0x5340, 0x0078, 0x4452,
+	0xa080, 0x52c0, 0x2060, 0x2048, 0x705a, 0x2a60, 0x007c, 0x0020,
+	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
 	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000,
-	0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0000, 0x0020, 0x0062,
-	0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014, 0x9906, 0x98f4,
-	0x0014, 0x0014, 0x0080, 0x00f1, 0x0100, 0x0402, 0x2008, 0xf880,
-	0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014, 0x2500, 0x0013,
-	0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
-	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0xa200,
-	0x3806, 0x8839, 0x20c4, 0x0864, 0xa850, 0x3008, 0x28c1, 0x9d0d,
-	0xa201, 0x300c, 0x2847, 0x8161, 0x846a, 0x8000, 0x84a4, 0x1856,
-	0x883a, 0xa808, 0x28e2, 0x9cc2, 0xa8f3, 0x0864, 0xa83e, 0x300c,
-	0xa801, 0x3008, 0x28e1, 0x9cc2, 0x2021, 0xa81b, 0xa205, 0x870c,
-	0xd8de, 0x64a0, 0x6de0, 0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205,
-	0x883d, 0x9d25, 0x882b, 0x1814, 0x883b, 0x9d2b, 0x883b, 0x7027,
-	0x85f2, 0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa812, 0x883e,
-	0xa810, 0x280c, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x9d25,
-	0x1814, 0x9d2b, 0x883b, 0x7023, 0x8576, 0x8677, 0xa802, 0x7861,
-	0x883e, 0x206b, 0x28c1, 0x9d0d, 0x2044, 0x2103, 0x20a2, 0x2081,
-	0xa8c9, 0xa207, 0x2901, 0xa80a, 0x0014, 0xa203, 0x8000, 0x85a4,
-	0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601, 0xa208, 0x856e, 0x866f,
-	0x7161, 0x0014, 0x0704, 0x3008, 0x9cc2, 0x0014, 0xa202, 0x8000,
-	0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844, 0x856e, 0x883f, 0x08e6,
-	0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014, 0xf881, 0x0016, 0x85b2,
-	0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014, 0x8532, 0xf221, 0x0014,
-	0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014, 0x3008, 0x8000, 0x284a,
-	0x1011, 0xa8fc, 0x3008, 0x9d25, 0x8000, 0xa000, 0x2802, 0x1011,
-	0xa8fd, 0x9d2b, 0xa887, 0x3008, 0x9d25, 0x283b, 0x1011, 0xa8fd,
-	0xa209, 0x0017, 0x300c, 0x8000, 0x85a4, 0x1de2, 0xdac1, 0x0014,
+	0x0020, 0x0062, 0x0009, 0x0014, 0x0014, 0x9848, 0x0014, 0x0014,
+	0x9914, 0x98fd, 0x0014, 0x0014, 0x0080, 0x00ff, 0x0100, 0x0402,
+	0x2008, 0xf880, 0x0018, 0xa20a, 0x0014, 0x300b, 0xa20c, 0x0014,
+	0x2500, 0x0013, 0x2500, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
+	0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010, 0x0010,
+	0x0010, 0xa200, 0x3806, 0x7102, 0x805f, 0x9481, 0x8839, 0x20c4,
+	0x0864, 0xa856, 0x3008, 0x28c1, 0x9d1b, 0xa201, 0x300c, 0x2847,
+	0x8161, 0x846a, 0x8000, 0x84a4, 0x1856, 0x883a, 0xa808, 0x28e2,
+	0x9ccb, 0xa8f3, 0x0864, 0xa844, 0x300c, 0xa801, 0x3008, 0x28e1,
+	0x9ccb, 0x2021, 0xa81d, 0xa205, 0x870c, 0xd8de, 0x64a0, 0x6de0,
+	0x6fc0, 0x63a4, 0x6c80, 0x0212, 0xa205, 0x883d, 0x7942, 0x8020,
+	0xa4a1, 0x882b, 0x1814, 0x883b, 0x80df, 0x94a1, 0x7027, 0x85f2,
+	0xa737, 0xa532, 0xf003, 0x8576, 0x8677, 0xa816, 0x883e, 0xa814,
+	0x2001, 0xa812, 0xa204, 0x64c0, 0x6de0, 0x67a0, 0x6fc0, 0x7942,
+	0x8020, 0xa4a1, 0x1814, 0x80df, 0x94a1, 0x883b, 0x7023, 0x8576,
+	0x8677, 0xa802, 0x7861, 0x883e, 0x206b, 0x28c1, 0x9d1b, 0x2044,
+	0x2103, 0x20a2, 0x2081, 0xa8c3, 0xa207, 0x0904, 0xa20e, 0xa809,
+	0xa203, 0x8000, 0x85a4, 0x1872, 0x879a, 0x883c, 0x1fe2, 0xf601,
+	0xa208, 0x856e, 0x866f, 0x7161, 0x0014, 0x0704, 0x3008, 0x9ccb,
+	0x0014, 0xa202, 0x8000, 0x85a4, 0x3009, 0x84a8, 0x19e2, 0xf844,
+	0x856e, 0x883f, 0x08e6, 0xa8f5, 0xf861, 0xa8ea, 0xf801, 0x0014,
+	0xf881, 0x0016, 0x85b2, 0x80f0, 0x9532, 0xfaa2, 0x1de2, 0x0014,
+	0x8532, 0xf221, 0x0014, 0x1de2, 0x84a8, 0xd6e0, 0x1fe6, 0x0014,
+	0x3008, 0x8000, 0x284a, 0x1011, 0xa8fc, 0x3008, 0x9d33, 0x8000,
+	0xa000, 0x2802, 0x1011, 0xa8fd, 0x9d39, 0xa8bd, 0x3008, 0x9d33,
+	0x283b, 0x1011, 0xa8fd, 0xa209, 0x7102, 0x805f, 0x9481, 0x0017,
+	0x300c, 0xa209, 0x8000, 0x85a4, 0x1de2, 0xa209, 0xdac1, 0x0014,
 	0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0,
-	0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d17,
+	0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d25,
 	0x0704, 0xa206, 0x6865, 0x817e, 0x842a, 0x1dc1, 0x8823, 0x0016,
 	0x6042, 0x8008, 0xa8fa, 0x8000, 0x84a4, 0x8160, 0x842a, 0xf021,
 	0x3008, 0x84a8, 0x11d6, 0x7042, 0x20dd, 0x0011, 0x20d4, 0x8822,
 	0x0016, 0x7944, 0x8421, 0xa020, 0xa532, 0x84a1, 0x0016, 0x7944,
 	0x8421, 0xa0df, 0x9532, 0x84a1, 0x0016, 0x0000, 0x127e, 0x70d4,
 	0xa084, 0x4600, 0x8004, 0x2090, 0x7204, 0x7008, 0xc09c, 0xa205,
-	0x00c0, 0x4342, 0x720c, 0x82ff, 0x0040, 0x433d, 0x8aff, 0x00c0,
-	0x4342, 0x7200, 0xd284, 0x00c0, 0x4342, 0x7003, 0x0008, 0x127f,
+	0x00c0, 0x45a2, 0x720c, 0x82ff, 0x0040, 0x459d, 0x8aff, 0x00c0,
+	0x45a2, 0x7200, 0xd284, 0x00c0, 0x45a2, 0x7003, 0x0008, 0x127f,
 	0x2000, 0x007c, 0x7000, 0xa084, 0x0003, 0x7002, 0xc69c, 0xd084,
-	0x0040, 0x4374, 0x2001, 0x4a05, 0x2004, 0xd0ec, 0x00c0, 0x43a5,
-	0xd0e4, 0x00c0, 0x435a, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003,
-	0x0040, 0x43a5, 0x0e7e, 0x2071, 0x0010, 0x2009, 0x0007, 0x7008,
-	0xa084, 0x3000, 0x00c0, 0x435d, 0x8109, 0x00c0, 0x435f, 0x0e7f,
-	0x2009, 0x0007, 0x7008, 0xa084, 0x3000, 0x00c0, 0x435a, 0x8109,
-	0x00c0, 0x436a, 0x0078, 0x43a5, 0x7108, 0xd1fc, 0x0040, 0x437f,
-	0x1078, 0x44ba, 0x8aff, 0x0040, 0x432c, 0x0078, 0x4374, 0x700c,
-	0xa08c, 0x03ff, 0x0040, 0x43aa, 0x7004, 0xd084, 0x0040, 0x439c,
-	0x7014, 0xa005, 0x00c0, 0x4398, 0x7010, 0x7310, 0xa306, 0x00c0,
-	0x438c, 0x2300, 0xa005, 0x0040, 0x439c, 0xa102, 0x00c8, 0x4374,
-	0x7007, 0x0010, 0x0078, 0x43a5, 0x8aff, 0x0040, 0x43aa, 0x1078,
-	0x46a3, 0x00c0, 0x439f, 0x0040, 0x4374, 0x1078, 0x4443, 0x127f,
-	0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8, 0x43b9,
-	0x1078, 0x44ba, 0x0078, 0x43aa, 0x7003, 0x0008, 0x127f, 0x2000,
-	0x007c, 0xa205, 0x00c0, 0x43a5, 0x7003, 0x0008, 0x127f, 0x2000,
-	0x007c, 0x6428, 0x84ff, 0x0040, 0x43ed, 0x2c70, 0x7004, 0xa0bc,
-	0x000f, 0xa7b8, 0x43fd, 0x273c, 0x87fb, 0x00c0, 0x43db, 0x0048,
-	0x43d3, 0x1078, 0x28ec, 0x609c, 0xa075, 0x0040, 0x43ed, 0x0078,
-	0x43c6, 0x2039, 0x43f2, 0x2704, 0xae68, 0x6808, 0xa630, 0x680c,
-	0xa529, 0x8421, 0x0040, 0x43ed, 0x8738, 0x2704, 0xa005, 0x00c0,
-	0x43dc, 0x709c, 0xa075, 0x00c0, 0x43c6, 0x007c, 0x0000, 0x0005,
-	0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000, 0x0003,
-	0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x43f2, 0x43ef,
-	0x0000, 0x0000, 0x8000, 0x0000, 0x43f2, 0x0000, 0x43fa, 0x43f7,
-	0x0000, 0x0000, 0x0000, 0x0000, 0x43fa, 0x0000, 0x43f5, 0x43f5,
-	0x0000, 0x0000, 0x8000, 0x0000, 0x43f5, 0x0000, 0x43fb, 0x43fb,
-	0x0000, 0x0000, 0x0000, 0x0000, 0x43fb, 0x2079, 0x4a00, 0x2071,
-	0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001, 0x7810,
-	0xd0ec, 0x0040, 0x4431, 0x2009, 0x0001, 0x2071, 0x0020, 0x0078,
-	0x4435, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a, 0x7007,
-	0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x4442, 0x2071, 0x0020,
-	0x0078, 0x4435, 0x007c, 0x7004, 0x8004, 0x00c8, 0x44a6, 0x7007,
-	0x0012, 0x2019, 0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x444b,
-	0xa184, 0x01e0, 0x0040, 0x4456, 0x1078, 0x28ec, 0x7810, 0xd0ec,
-	0x0040, 0x4470, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0,
-	0x4474, 0xa184, 0x4000, 0x0040, 0x4478, 0xa382, 0x0003, 0x00c8,
-	0x4478, 0xa184, 0x0004, 0x0040, 0x444b, 0x8318, 0x0078, 0x444b,
-	0x7814, 0xd0ec, 0x00c0, 0x4478, 0xa184, 0x4000, 0x00c0, 0x444b,
-	0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4486, 0xa386, 0x0008,
-	0x0040, 0x4491, 0xa386, 0x200c, 0x00c0, 0x444b, 0x7200, 0x8204,
-	0x0048, 0x4491, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4491, 0x1078,
-	0x28ec, 0x7007, 0x0012, 0x7000, 0xd084, 0x00c0, 0x44a6, 0x7008,
-	0xa084, 0x01e0, 0x00c0, 0x44a6, 0x7310, 0x7014, 0xa305, 0x0040,
-	0x44a6, 0x710c, 0xa184, 0x03ff, 0x00c0, 0x4443, 0x7007, 0x0012,
-	0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x44aa, 0x7007, 0x0012,
-	0x7108, 0x8103, 0x0048, 0x44ae, 0x7003, 0x0008, 0x007c, 0x7108,
-	0x0078, 0x44ba, 0xa184, 0x01e0, 0x00c0, 0x44ee, 0x7108, 0xa184,
-	0x01e0, 0x00c0, 0x44ee, 0xa184, 0x0007, 0x0079, 0x44c7, 0x44d1,
-	0x44e1, 0x44cf, 0x44e1, 0x44cf, 0x4533, 0x44cf, 0x4531, 0x1078,
-	0x28ec, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0,
-	0x44dc, 0x2049, 0x0000, 0x007c, 0x1078, 0x46a3, 0x00c0, 0x44dc,
-	0x007c, 0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x0040,
-	0x44ed, 0x1078, 0x46a3, 0x00c0, 0x44e9, 0x007c, 0x7007, 0x0012,
-	0x7108, 0x00e0, 0x44f1, 0x2091, 0x6000, 0x00e0, 0x44f5, 0x2091,
-	0x6000, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0,
-	0x44fd, 0x7007, 0x0012, 0x7108, 0xd1fc, 0x00c0, 0x4501, 0x7003,
-	0x0000, 0x7000, 0xa005, 0x00c0, 0x4515, 0x7004, 0xa005, 0x00c0,
-	0x4515, 0x700c, 0xa005, 0x0040, 0x4517, 0x0078, 0x44f9, 0x2049,
-	0x0000, 0xb284, 0x0100, 0x0040, 0x4521, 0x2001, 0x0000, 0x0078,
-	0x4523, 0x2001, 0x0001, 0x1078, 0x3ff5, 0x6818, 0xa084, 0x8000,
-	0x0040, 0x452c, 0x681b, 0x0002, 0x007c, 0x1078, 0x28ec, 0x1078,
-	0x28ec, 0x1078, 0x4570, 0x7210, 0x7114, 0x700c, 0xa09c, 0x03ff,
-	0x2800, 0xa300, 0xa211, 0xa189, 0x0000, 0x1078, 0x4570, 0x2704,
-	0x2c58, 0xac60, 0x6308, 0x2200, 0xa322, 0x630c, 0x2100, 0xa31b,
-	0x2400, 0xa305, 0x0040, 0x4556, 0x00c8, 0x4556, 0x8412, 0x8210,
-	0x830a, 0xa189, 0x0000, 0x2b60, 0x0078, 0x453d, 0x2b60, 0x8a07,
-	0x007e, 0x6004, 0xa084, 0x0008, 0x0040, 0x4562, 0xa7ba, 0x43f7,
-	0x0078, 0x4564, 0xa7ba, 0x43ef, 0x007f, 0xa73d, 0x2c00, 0x6886,
-	0x6f8a, 0x6c92, 0x6b8e, 0x7007, 0x0012, 0x1078, 0x4443, 0x007c,
-	0x8a50, 0x8739, 0x2704, 0xa004, 0x00c0, 0x4584, 0x6000, 0xa064,
-	0x00c0, 0x457b, 0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x440d,
-	0x203c, 0x87fb, 0x1040, 0x28ec, 0x007c, 0x127e, 0x0d7e, 0x70d4,
-	0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888,
-	0x6b8c, 0x6c90, 0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e,
-	0x6804, 0xa084, 0x0008, 0x007f, 0x0040, 0x45a2, 0xa0b8, 0x43f7,
-	0x0078, 0x45a4, 0xa0b8, 0x43ef, 0xb284, 0x0100, 0x0040, 0x45ab,
-	0x7e20, 0x0078, 0x45ac, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4,
-	0x0040, 0x45b3, 0xc685, 0x2400, 0xa305, 0x0040, 0x45dd, 0x2c58,
-	0x2704, 0x6104, 0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301,
-	0x701e, 0xa184, 0x0008, 0x0040, 0x45cd, 0x6010, 0xa081, 0x0000,
-	0x7022, 0x6014, 0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202,
-	0x7012, 0x620c, 0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001,
-	0x2b60, 0x1078, 0x46c6, 0x0078, 0x45df, 0x1078, 0x46a3, 0x00c0,
-	0x45dd, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084,
-	0x4600, 0x8004, 0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094,
-	0x00c0, 0x45ee, 0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e,
-	0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x7e20,
-	0xb284, 0x0100, 0x00c0, 0x4605, 0x7e24, 0xa6b5, 0x000c, 0x681c,
-	0xd0ac, 0x00c0, 0x4610, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
-	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd,
-	0x273c, 0x87fb, 0x00c0, 0x4626, 0x0048, 0x4620, 0x1078, 0x28ec,
-	0x689c, 0xa065, 0x0040, 0x462a, 0x0078, 0x4613, 0x1078, 0x46a3,
-	0x00c0, 0x4626, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
-	0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x7e20, 0xb284,
-	0x0100, 0x00c0, 0x463c, 0x7e24, 0x0d7f, 0x037f, 0x047f, 0xa6b5,
-	0x000c, 0x681c, 0xd0b4, 0x0040, 0x464a, 0xc685, 0x7003, 0x0000,
-	0x7007, 0x0004, 0x2049, 0x462d, 0x6828, 0xa055, 0x0040, 0x46a0,
-	0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f, 0xa7b8, 0x43fd, 0x273c,
-	0x87fb, 0x00c0, 0x4666, 0x0048, 0x465f, 0x1078, 0x28ec, 0x709c,
-	0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x2704, 0xae68,
-	0x6808, 0xa422, 0x680c, 0xa31b, 0x0048, 0x467f, 0x8a51, 0x00c0,
-	0x4673, 0x1078, 0x28ec, 0x8738, 0x2704, 0xa005, 0x00c0, 0x4667,
-	0x709c, 0xa075, 0x2060, 0x0040, 0x46a0, 0x0078, 0x4652, 0x8422,
-	0x8420, 0x831a, 0xa399, 0x0000, 0x6908, 0x2400, 0xa122, 0x690c,
-	0x2300, 0xa11b, 0x00c8, 0x468e, 0x1078, 0x28ec, 0xb284, 0x0100,
-	0x0040, 0x469c, 0x2001, 0x4a04, 0x2004, 0xd0ec, 0x00c0, 0x469c,
-	0x2071, 0x0050, 0x0078, 0x469e, 0x2071, 0x0020, 0x0078, 0x45b3,
-	0x127f, 0x2000, 0x007c, 0x7008, 0xa084, 0x0003, 0xa086, 0x0003,
-	0x00c0, 0x46ab, 0x007c, 0x2704, 0xac78, 0x7800, 0x701a, 0x7804,
-	0x701e, 0x7808, 0x7012, 0x780c, 0x7016, 0x6004, 0xa084, 0x0008,
-	0x0040, 0x46be, 0x7810, 0x7022, 0x7814, 0x7026, 0x7602, 0x7004,
-	0xa084, 0x0010, 0xc085, 0x7006, 0x2079, 0x4a00, 0x8a51, 0x0040,
-	0x46e1, 0x8738, 0x2704, 0xa005, 0x00c0, 0x46dc, 0x609c, 0xa005,
-	0x0040, 0x46e2, 0x2060, 0x6004, 0xa084, 0x000f, 0xa080, 0x43fd,
-	0x203c, 0x87fb, 0x1040, 0x28ec, 0x7008, 0xa084, 0x0003, 0xa086,
-	0x0003, 0x007c, 0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e,
-	0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108,
-	0xa184, 0x0003, 0x00c0, 0x46fa, 0x6828, 0xa005, 0x0040, 0x470a,
-	0x0078, 0x4342, 0x7108, 0xd1fc, 0x0040, 0x4702, 0x1078, 0x44ba,
-	0x0078, 0x46ef, 0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x4704,
-	0x1078, 0x44ba, 0x7008, 0xa086, 0x0008, 0x00c0, 0x46ef, 0x7000,
-	0xa005, 0x00c0, 0x46ef, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f,
-	0x2000, 0x007c, 0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e,
-	0x70d4, 0xa084, 0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x471a,
-	0xad80, 0x0011, 0x20a0, 0xb284, 0x0100, 0x0040, 0x473d, 0x2001,
-	0x4a04, 0x2004, 0xd0ec, 0x0040, 0x4739, 0x2099, 0x0031, 0x0078,
-	0x473f, 0x2099, 0x0032, 0x0078, 0x473f, 0x2099, 0x0031, 0x700c,
-	0xa084, 0x03ff, 0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003,
-	0x0001, 0x0040, 0x474e, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084,
-	0x03ff, 0x0040, 0x475a, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004,
-	0x00c0, 0x4755, 0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f,
-	0x137f, 0x147f, 0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091,
-	0x6000, 0x78ac, 0xa005, 0x00c0, 0x477c, 0x7974, 0x70d0, 0xa106,
-	0x00c0, 0x477c, 0x781c, 0xa005, 0x0040, 0x477c, 0x781f, 0x0000,
-	0x0068, 0x477c, 0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0,
-	0x4804, 0x7834, 0x7832, 0x7810, 0xd0ec, 0x00c0, 0x47fd, 0x2061,
-	0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4796,
-	0x8001, 0x68d2, 0x00c0, 0x4796, 0x1078, 0x4998, 0x6800, 0xa084,
-	0x000f, 0x0040, 0x47ab, 0xa086, 0x0001, 0x0040, 0x47ab, 0x6844,
-	0xa00d, 0x0040, 0x47ab, 0x2104, 0xa005, 0x0040, 0x47ab, 0x8001,
-	0x200a, 0x0040, 0x4909, 0x6814, 0xa005, 0x0040, 0x47d0, 0x8001,
-	0x6816, 0x00c0, 0x47d0, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0,
-	0x47c5, 0x7810, 0xd0ec, 0x0040, 0x47c1, 0x2079, 0x0100, 0x0078,
-	0x47c7, 0x2079, 0x0200, 0x0078, 0x47c7, 0x2079, 0x0100, 0x1078,
-	0x4131, 0x0f7f, 0x6864, 0xa005, 0x0040, 0x47d0, 0x1078, 0x25de,
-	0x6880, 0xa005, 0x0040, 0x47dd, 0x8001, 0x6882, 0x00c0, 0x47dd,
-	0x6867, 0x0000, 0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040,
-	0x47fa, 0xc0fc, 0x68d6, 0x20a9, 0x0200, 0x603c, 0xa005, 0x0040,
-	0x47f6, 0x8001, 0x603e, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x47f6,
-	0x6010, 0xa005, 0x0040, 0x47f6, 0x1078, 0x25de, 0xace0, 0x0010,
-	0x00f0, 0x47e5, 0xd7fc, 0x0040, 0x4804, 0x2061, 0x4fc0, 0x2069,
-	0x4a40, 0xc7fc, 0x0078, 0x478c, 0x1078, 0x4840, 0x7838, 0x8001,
-	0x783a, 0x00c0, 0x4826, 0x783c, 0x783a, 0x2061, 0x4fc0, 0x2069,
-	0x4a40, 0xc7fc, 0x680c, 0xa005, 0x0040, 0x4818, 0x1078, 0x487f,
-	0xd7fc, 0x00c0, 0x4826, 0x7810, 0xd0ec, 0x00c0, 0x4826, 0x2061,
-	0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x4812, 0x7814, 0xd0e4,
-	0x00c0, 0x482a, 0x7810, 0xd0cc, 0x0040, 0x483d, 0xd0ac, 0x00c0,
-	0x4836, 0xd0a4, 0x0040, 0x483d, 0xc0ad, 0x7812, 0x2091, 0x8001,
-	0x0068, 0x483c, 0x1078, 0x2368, 0x007c, 0x2091, 0x8001, 0x007c,
-	0x7840, 0x8001, 0x7842, 0x00c0, 0x487e, 0x7844, 0x7842, 0x2091,
-	0x8000, 0x2061, 0x4fc0, 0x2069, 0x4a40, 0xc7fc, 0x6810, 0xa005,
-	0x00c0, 0x4854, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040,
-	0x485d, 0xa080, 0x90d0, 0x0078, 0x485f, 0xa080, 0x8fc0, 0x2040,
-	0x2004, 0xa065, 0x0040, 0x4870, 0x6024, 0xa005, 0x0040, 0x486c,
-	0x8001, 0x6026, 0x0040, 0x48ad, 0x6000, 0x2c40, 0x0078, 0x4861,
-	0xd7fc, 0x00c0, 0x487e, 0x7810, 0xd0ec, 0x00c0, 0x487e, 0x2061,
-	0x6fc0, 0x2069, 0x4a80, 0xc7fd, 0x0078, 0x484e, 0x007c, 0x2009,
-	0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4899, 0x6024,
-	0xa005, 0x0040, 0x488f, 0x8001, 0x6026, 0x0078, 0x4897, 0x6008,
-	0xc09c, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4899, 0xa18d,
-	0x0100, 0xace0, 0x0010, 0x00f0, 0x4883, 0xa184, 0x0001, 0x0040,
-	0x48a8, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x25de, 0x0078, 0x48a9,
-	0x690e, 0x007c, 0x00c0, 0x48a9, 0x786c, 0x6800, 0xa005, 0x0040,
-	0x48b5, 0x684c, 0xac06, 0x0040, 0x4909, 0x6864, 0xa005, 0x0040,
-	0x48bd, 0x6027, 0x0001, 0x0078, 0x4906, 0x2c00, 0x687e, 0x601b,
-	0x0006, 0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
-	0xa085, 0x0060, 0x6022, 0x6000, 0x2042, 0x6714, 0x6f76, 0x1078,
-	0x1e02, 0x6818, 0xa005, 0x0040, 0x48d7, 0x8001, 0x681a, 0x6808,
-	0xc0a4, 0x680a, 0x6810, 0x7908, 0x8109, 0x790a, 0x8001, 0x00d0,
-	0x48e3, 0x1078, 0x28ec, 0x6812, 0x00c0, 0x48e9, 0x7910, 0xc1a5,
-	0x7912, 0x602f, 0x0000, 0x6033, 0x0000, 0x2c68, 0x1078, 0x202a,
-	0xd7fc, 0x00c0, 0x48f7, 0x2069, 0x4a40, 0x0078, 0x48f9, 0x2069,
-	0x4a80, 0x6910, 0xa184, 0x0100, 0x2001, 0x0006, 0x00c0, 0x4903,
-	0x697a, 0x2001, 0x0004, 0x2708, 0x1078, 0x25d1, 0x2091, 0x8001,
-	0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0, 0x491b, 0x7810,
-	0xd0ec, 0x0040, 0x4917, 0x2069, 0x0100, 0x0078, 0x491d, 0x2069,
-	0x0200, 0x0078, 0x491d, 0x2069, 0x0100, 0x1078, 0x2881, 0x601b,
-	0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff,
-	0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033, 0x0000, 0x6830,
-	0xd0b4, 0x0040, 0x494b, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848,
-	0xd094, 0x0040, 0x493d, 0x00f0, 0x4937, 0x684b, 0x0009, 0x20a9,
-	0x0014, 0x6848, 0xd084, 0x0040, 0x4947, 0x00f0, 0x4941, 0x20a9,
-	0x00fa, 0x00f0, 0x4949, 0x6808, 0xa084, 0xfffd, 0x680a, 0x681b,
-	0x0047, 0x0d7f, 0x6867, 0x0007, 0x2091, 0x8001, 0x007c, 0x2079,
-	0x4a00, 0x1078, 0x498b, 0x1078, 0x4971, 0x1078, 0x497e, 0x2009,
-	0x0002, 0x2069, 0x4a80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817,
-	0x0000, 0x8109, 0x0040, 0x4970, 0x2069, 0x4a40, 0x0078, 0x4963,
-	0x007c, 0x7810, 0xd0ec, 0x0040, 0x4979, 0x2019, 0x00cc, 0x0078,
-	0x497b, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4,
-	0x00c0, 0x4986, 0x2019, 0x0040, 0x0078, 0x4988, 0x2019, 0x0026,
-	0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4993, 0x2019,
-	0x3f94, 0x0078, 0x4995, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c,
-	0x6950, 0xa185, 0x0000, 0x0040, 0x49ad, 0x0c7e, 0x6ac0, 0x2264,
-	0x602b, 0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210,
-	0x8109, 0x00c0, 0x499f, 0x6952, 0x0c7f, 0x007c, 0x70ec, 0xd0dc,
-	0x00c0, 0x49b7, 0xd0d4, 0x0040, 0x49d6, 0x0078, 0x49d9, 0x7810,
-	0xd0ec, 0x0040, 0x49c2, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x49dd,
-	0x0078, 0x49d9, 0xae8e, 0x0100, 0x0040, 0x49ce, 0x7814, 0xc0f5,
-	0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0x7814, 0xc0fd,
-	0x7816, 0xd0d4, 0x00c0, 0x49dd, 0x0078, 0x49d9, 0xd0e4, 0x0040,
-	0x49df, 0x7804, 0xd08c, 0x0040, 0x49df, 0x681f, 0x000c, 0x70a0,
-	0x70a2, 0x007c, 0x699a
+	0x0040, 0x45e5, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45aa,
+	0xa184, 0x0003, 0x0040, 0x4616, 0xa184, 0x01e0, 0x00c0, 0x4616,
+	0xd1f4, 0x00c0, 0x45aa, 0xa184, 0x3000, 0xa086, 0x1000, 0x0040,
+	0x45aa, 0x2011, 0x0180, 0x710c, 0x8211, 0x0040, 0x45cf, 0x7008,
+	0xd0f4, 0x00c0, 0x45aa, 0x700c, 0xa106, 0x0040, 0x45c4, 0x7007,
+	0x0012, 0x7108, 0x0005, 0x7008, 0xa106, 0x00c0, 0x45d1, 0xa184,
+	0x0003, 0x0040, 0x4616, 0xd194, 0x0040, 0x45d1, 0xd1f4, 0x0040,
+	0x4616, 0x7007, 0x0002, 0x0078, 0x45aa, 0x7108, 0xd1fc, 0x0040,
+	0x45f0, 0x1078, 0x4769, 0x8aff, 0x0040, 0x458c, 0x0078, 0x45e5,
+	0x700c, 0xa08c, 0x03ff, 0x0040, 0x461b, 0x7004, 0xd084, 0x0040,
+	0x460d, 0x7014, 0xa005, 0x00c0, 0x4609, 0x7010, 0x7310, 0xa306,
+	0x00c0, 0x45fd, 0x2300, 0xa005, 0x0040, 0x460d, 0xa102, 0x00c8,
+	0x45e5, 0x7007, 0x0010, 0x0078, 0x4616, 0x8aff, 0x0040, 0x461b,
+	0x1078, 0x4970, 0x00c0, 0x4610, 0x0040, 0x45e5, 0x1078, 0x46b4,
+	0x127f, 0x2000, 0x007c, 0x7204, 0x7108, 0xc19c, 0x8103, 0x00c8,
+	0x462a, 0x7007, 0x0002, 0x0078, 0x461b, 0x7003, 0x0008, 0x127f,
+	0x2000, 0x007c, 0xa205, 0x00c0, 0x4616, 0x7003, 0x0008, 0x127f,
+	0x2000, 0x007c, 0x6428, 0x84ff, 0x0040, 0x465e, 0x2c70, 0x7004,
+	0xa0bc, 0x000f, 0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x464c,
+	0x0048, 0x4644, 0x1078, 0x296b, 0x609c, 0xa075, 0x0040, 0x465e,
+	0x0078, 0x4637, 0x2039, 0x4663, 0x2704, 0xae68, 0x6808, 0xa630,
+	0x680c, 0xa529, 0x8421, 0x0040, 0x465e, 0x8738, 0x2704, 0xa005,
+	0x00c0, 0x464d, 0x709c, 0xa075, 0x00c0, 0x4637, 0x007c, 0x0000,
+	0x0005, 0x0009, 0x000d, 0x0011, 0x0015, 0x0019, 0x001d, 0x0000,
+	0x0003, 0x0009, 0x000f, 0x0015, 0x001b, 0x0000, 0x0000, 0x4663,
+	0x4660, 0x0000, 0x0000, 0x8000, 0x0000, 0x4663, 0x0000, 0x466b,
+	0x4668, 0x0000, 0x0000, 0x0000, 0x0000, 0x466b, 0x0000, 0x4666,
+	0x4666, 0x0000, 0x0000, 0x8000, 0x0000, 0x4666, 0x0000, 0x466c,
+	0x466c, 0x0000, 0x0000, 0x0000, 0x0000, 0x466c, 0x2079, 0x4e00,
+	0x2071, 0x0010, 0x7007, 0x000a, 0x7007, 0x0002, 0x7003, 0x0001,
+	0x7810, 0xd0ec, 0x0040, 0x46a2, 0x2009, 0x0001, 0x2071, 0x0020,
+	0x0078, 0x46a6, 0x2009, 0x0002, 0x2071, 0x0050, 0x7007, 0x000a,
+	0x7007, 0x0002, 0x7003, 0x0000, 0x8109, 0x0040, 0x46b3, 0x2071,
+	0x0020, 0x0078, 0x46a6, 0x007c, 0x7004, 0x8004, 0x00c8, 0x473d,
+	0x7108, 0x7008, 0xa106, 0x00c0, 0x46b8, 0xa184, 0x01e0, 0x0040,
+	0x46c5, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x2019,
+	0x0000, 0x7108, 0x7008, 0xa106, 0x00c0, 0x46c9, 0xa184, 0x01e0,
+	0x0040, 0x46d6, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7810, 0xd0ec,
+	0x0040, 0x46f0, 0x2001, 0x04fd, 0x2004, 0xa086, 0x0003, 0x00c0,
+	0x46f4, 0xa184, 0x4000, 0x0040, 0x46f8, 0xa382, 0x0003, 0x00c8,
+	0x46f8, 0xa184, 0x0004, 0x0040, 0x46c9, 0x8318, 0x0078, 0x46c9,
+	0x7814, 0xd0ec, 0x00c0, 0x46f8, 0xa184, 0x4000, 0x00c0, 0x46c9,
+	0xa19c, 0x300c, 0xa386, 0x2004, 0x0040, 0x4715, 0xa386, 0x0008,
+	0x0040, 0x4720, 0x7004, 0xd084, 0x00c0, 0x4711, 0x7108, 0x7008,
+	0xa106, 0x00c0, 0x4706, 0xa184, 0x0003, 0x0040, 0x4711, 0x0078,
+	0x47ac, 0xa386, 0x200c, 0x00c0, 0x46c9, 0x7200, 0x8204, 0x0048,
+	0x4720, 0x730c, 0xa384, 0x03ff, 0x0040, 0x4720, 0x1078, 0x296b,
+	0x7108, 0x7008, 0xa106, 0x00c0, 0x4720, 0xa184, 0x01e0, 0x0040,
+	0x472d, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007, 0x0012, 0x7000,
+	0xd084, 0x00c0, 0x473d, 0x7310, 0x7014, 0xa305, 0x0040, 0x473d,
+	0x710c, 0xa184, 0x03ff, 0x00c0, 0x46b4, 0x7108, 0x7008, 0xa106,
+	0x00c0, 0x473d, 0xa184, 0x01e0, 0x0040, 0x474a, 0x1078, 0x47ac,
+	0x0078, 0x4765, 0x7007, 0x0012, 0x7007, 0x0008, 0x7004, 0xd09c,
+	0x00c0, 0x474e, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4752, 0xa184,
+	0x01e0, 0x0040, 0x475f, 0x1078, 0x47ac, 0x0078, 0x4765, 0x7007,
+	0x0012, 0x7108, 0x8103, 0x0048, 0x4752, 0x7003, 0x0008, 0x007c,
+	0x7108, 0xa184, 0x01e0, 0x00c0, 0x47ac, 0x7108, 0xa184, 0x01e0,
+	0x00c0, 0x47ac, 0xa184, 0x0007, 0x0079, 0x4776, 0x4780, 0x4790,
+	0x477e, 0x4790, 0x477e, 0x47ee, 0x477e, 0x47ec, 0x1078, 0x296b,
+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x8aff, 0x00c0, 0x478b,
+	0x2049, 0x0000, 0x007c, 0x1078, 0x4970, 0x00c0, 0x478b, 0x007c,
+	0x7004, 0xa084, 0x0010, 0xc08d, 0x7006, 0x7004, 0xd084, 0x00c0,
+	0x47a4, 0x7108, 0x7008, 0xa106, 0x00c0, 0x4799, 0xa184, 0x0003,
+	0x0040, 0x47a4, 0x0078, 0x47ac, 0x8aff, 0x0040, 0x47ab, 0x1078,
+	0x4970, 0x00c0, 0x47a7, 0x007c, 0x7007, 0x0012, 0x7108, 0x00e0,
+	0x47af, 0x2091, 0x6000, 0x00e0, 0x47b3, 0x2091, 0x6000, 0x7007,
+	0x0012, 0x7007, 0x0008, 0x7004, 0xd09c, 0x00c0, 0x47bb, 0x7007,
+	0x0012, 0x7108, 0xd1fc, 0x00c0, 0x47bf, 0x7003, 0x0000, 0x7000,
+	0xa005, 0x00c0, 0x47d3, 0x7004, 0xa005, 0x00c0, 0x47d3, 0x700c,
+	0xa005, 0x0040, 0x47d5, 0x0078, 0x47b7, 0x2049, 0x0000, 0xb284,
+	0x0100, 0x0040, 0x47df, 0x2001, 0x0000, 0x0078, 0x47e1, 0x2001,
+	0x0001, 0x1078, 0x4212, 0x681b, 0x0002, 0x2051, 0x0000, 0x007c,
+	0x1078, 0x296b, 0x1078, 0x296b, 0x1078, 0x4836, 0x7210, 0x7114,
+	0x700c, 0xa09c, 0x03ff, 0x2800, 0xa300, 0xa211, 0xa189, 0x0000,
+	0x1078, 0x4836, 0x2704, 0x2c58, 0xac60, 0x6308, 0x2200, 0xa322,
+	0x630c, 0x2100, 0xa31b, 0x2400, 0xa305, 0x0040, 0x4811, 0x00c8,
+	0x4811, 0x8412, 0x8210, 0x830a, 0xa189, 0x0000, 0x2b60, 0x0078,
+	0x47f8, 0x2b60, 0x8a07, 0x007e, 0x6004, 0xa084, 0x0008, 0x0040,
+	0x481d, 0xa7ba, 0x4668, 0x0078, 0x481f, 0xa7ba, 0x4660, 0x007f,
+	0xa73d, 0x2c00, 0x6886, 0x6f8a, 0x6c92, 0x6b8e, 0x7108, 0x7008,
+	0xa106, 0x00c0, 0x4826, 0xa184, 0x01e0, 0x0040, 0x4831, 0x1078,
+	0x47ac, 0x7007, 0x0012, 0x1078, 0x46b4, 0x007c, 0x8a50, 0x8739,
+	0x2704, 0xa004, 0x00c0, 0x484a, 0x6000, 0xa064, 0x00c0, 0x4841,
+	0x2d60, 0x6004, 0xa084, 0x000f, 0xa080, 0x467e, 0x203c, 0x87fb,
+	0x1040, 0x296b, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600,
+	0x8004, 0x2090, 0x0d7f, 0x6884, 0x2060, 0x6888, 0x6b8c, 0x6c90,
+	0x8057, 0xaad4, 0x00ff, 0xa084, 0x00ff, 0x007e, 0x6804, 0xa084,
+	0x0008, 0x007f, 0x0040, 0x4868, 0xa0b8, 0x4668, 0x0078, 0x486a,
+	0xa0b8, 0x4660, 0xb284, 0x0100, 0x0040, 0x4871, 0x7e20, 0x0078,
+	0x4872, 0x7e24, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4879,
+	0xc685, 0x2400, 0xa305, 0x0040, 0x48a3, 0x2c58, 0x2704, 0x6104,
+	0xac60, 0x6000, 0xa400, 0x701a, 0x6004, 0xa301, 0x701e, 0xa184,
+	0x0008, 0x0040, 0x4893, 0x6010, 0xa081, 0x0000, 0x7022, 0x6014,
+	0xa081, 0x0000, 0x7026, 0x6208, 0x2400, 0xa202, 0x7012, 0x620c,
+	0x2300, 0xa203, 0x7016, 0x7602, 0x7007, 0x0001, 0x2b60, 0x1078,
+	0x499b, 0x0078, 0x48a5, 0x1078, 0x4970, 0x00c0, 0x48a3, 0x127f,
+	0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004,
+	0x2090, 0x0d7f, 0x7007, 0x0004, 0x7004, 0xd094, 0x00c0, 0x48b4,
+	0x7003, 0x0008, 0x127f, 0x2000, 0x007c, 0x127e, 0x0d7e, 0x70d4,
+	0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f, 0x0d7f, 0x7e20,
+	0xb284, 0x0100, 0x00c0, 0x48cd, 0x7e24, 0xa6b5, 0x000c, 0x681c,
+	0xd0ac, 0x00c0, 0x48d8, 0xc685, 0x7003, 0x0000, 0x7007, 0x0004,
+	0x6828, 0x2050, 0x2d60, 0x6004, 0xa0bc, 0x000f, 0xa7b8, 0x466e,
+	0x273c, 0x87fb, 0x00c0, 0x48ee, 0x0048, 0x48e8, 0x1078, 0x296b,
+	0x689c, 0xa065, 0x0040, 0x48f2, 0x0078, 0x48db, 0x1078, 0x4970,
+	0x00c0, 0x48ee, 0x127f, 0x2000, 0x007c, 0x127e, 0x007e, 0x017e,
+	0x0d7e, 0x70d4, 0xa084, 0x4600, 0x8004, 0x007e, 0x2090, 0x007f,
+	0x7e20, 0xb284, 0x0100, 0x00c0, 0x4906, 0x7e24, 0x0d7f, 0x037f,
+	0x047f, 0xa6b5, 0x000c, 0x681c, 0xd0b4, 0x0040, 0x4914, 0xc685,
+	0x7003, 0x0000, 0x7007, 0x0004, 0x2049, 0x48f5, 0x6828, 0xa055,
+	0x0d7e, 0x0040, 0x496c, 0x2d70, 0x2e60, 0x7004, 0xa0bc, 0x000f,
+	0xa7b8, 0x466e, 0x273c, 0x87fb, 0x00c0, 0x4931, 0x0048, 0x492a,
+	0x1078, 0x296b, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c, 0x0078,
+	0x491d, 0x2704, 0xae68, 0x6808, 0xa422, 0x680c, 0xa31b, 0x0048,
+	0x494a, 0x8a51, 0x00c0, 0x493e, 0x1078, 0x296b, 0x8738, 0x2704,
+	0xa005, 0x00c0, 0x4932, 0x709c, 0xa075, 0x2060, 0x0040, 0x496c,
+	0x0078, 0x491d, 0x8422, 0x8420, 0x831a, 0xa399, 0x0000, 0x6908,
+	0x2400, 0xa122, 0x690c, 0x2300, 0xa11b, 0x00c8, 0x4959, 0x1078,
+	0x296b, 0xb284, 0x0100, 0x0040, 0x4967, 0x2001, 0x4e04, 0x2004,
+	0xd0ec, 0x00c0, 0x4967, 0x2071, 0x0050, 0x0078, 0x4969, 0x2071,
+	0x0020, 0x0d7f, 0x0078, 0x4879, 0x0d7f, 0x127f, 0x2000, 0x007c,
+	0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x4979, 0xa006,
+	0x007c, 0xa084, 0x0003, 0xa086, 0x0003, 0x00c0, 0x4980, 0x007c,
+	0x2704, 0xac78, 0x7800, 0x701a, 0x7804, 0x701e, 0x7808, 0x7012,
+	0x780c, 0x7016, 0x6004, 0xa084, 0x0008, 0x0040, 0x4993, 0x7810,
+	0x7022, 0x7814, 0x7026, 0x7602, 0x7004, 0xa084, 0x0010, 0xc085,
+	0x7006, 0x2079, 0x4e00, 0x8a51, 0x0040, 0x49bf, 0x8738, 0x2704,
+	0xa005, 0x00c0, 0x49b1, 0x609c, 0xa005, 0x0040, 0x49c0, 0x2060,
+	0x6004, 0xa084, 0x000f, 0xa080, 0x466e, 0x203c, 0x87fb, 0x1040,
+	0x296b, 0x7008, 0x007e, 0xa084, 0x01e0, 0x007f, 0x0040, 0x49bb,
+	0xa006, 0x0078, 0x49c0, 0xa084, 0x0003, 0xa086, 0x0003, 0x007c,
+	0x2051, 0x0000, 0x007c, 0x127e, 0x007e, 0x0d7e, 0x70d4, 0xa084,
+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x087f, 0x7108, 0xa184, 0x0003,
+	0x00c0, 0x49d8, 0x6828, 0xa005, 0x0040, 0x49e8, 0x0078, 0x45a2,
+	0x7108, 0xd1fc, 0x0040, 0x49e0, 0x1078, 0x4769, 0x0078, 0x49cd,
+	0x7007, 0x0010, 0x7108, 0xd1fc, 0x0040, 0x49e2, 0x1078, 0x4769,
+	0x7008, 0xa086, 0x0008, 0x00c0, 0x49cd, 0x7000, 0xa005, 0x00c0,
+	0x49cd, 0x7003, 0x0000, 0x2049, 0x0000, 0x127f, 0x2000, 0x007c,
+	0x127e, 0x147e, 0x137e, 0x157e, 0x0c7e, 0x0d7e, 0x70d4, 0xa084,
+	0x4600, 0x8004, 0x2090, 0x0d7f, 0x2049, 0x49f8, 0xad80, 0x0011,
+	0x20a0, 0xb284, 0x0100, 0x0040, 0x4a1b, 0x2001, 0x4e04, 0x2004,
+	0xd0ec, 0x0040, 0x4a17, 0x2099, 0x0031, 0x0078, 0x4a1d, 0x2099,
+	0x0032, 0x0078, 0x4a1d, 0x2099, 0x0031, 0x700c, 0xa084, 0x03ff,
+	0x682a, 0x7007, 0x0008, 0x7007, 0x0002, 0x7003, 0x0001, 0x0040,
+	0x4a2c, 0x8000, 0x80ac, 0x53a5, 0x700c, 0xa084, 0x03ff, 0x0040,
+	0x4a38, 0x7007, 0x0004, 0x7004, 0xa084, 0x0004, 0x00c0, 0x4a33,
+	0x0c7f, 0x2049, 0x0000, 0x7003, 0x0000, 0x157f, 0x137f, 0x147f,
+	0x127f, 0x2000, 0x007c, 0x2091, 0x8000, 0x2091, 0x6000, 0x78ac,
+	0xa005, 0x00c0, 0x4a5a, 0x7974, 0x70d0, 0xa106, 0x00c0, 0x4a5a,
+	0x781c, 0xa005, 0x0040, 0x4a5a, 0x781f, 0x0000, 0x0068, 0x4a5a,
+	0x2091, 0x4080, 0x7830, 0x8001, 0x7832, 0x00c0, 0x4ae2, 0x7834,
+	0x7832, 0x7810, 0xd0ec, 0x00c0, 0x4adb, 0x2061, 0x73c0, 0x2069,
+	0x4e80, 0xc7fd, 0x68d0, 0xa005, 0x0040, 0x4a74, 0x8001, 0x68d2,
+	0x00c0, 0x4a74, 0x1078, 0x4cb0, 0x6800, 0xa084, 0x000f, 0x0040,
+	0x4a89, 0xa086, 0x0001, 0x0040, 0x4a89, 0x6844, 0xa00d, 0x0040,
+	0x4a89, 0x2104, 0xa005, 0x0040, 0x4a89, 0x8001, 0x200a, 0x0040,
+	0x4c23, 0x6814, 0xa005, 0x0040, 0x4aae, 0x8001, 0x6816, 0x00c0,
+	0x4aae, 0x68a7, 0x0001, 0x0f7e, 0xd7fc, 0x00c0, 0x4aa3, 0x7810,
+	0xd0ec, 0x0040, 0x4a9f, 0x2079, 0x0100, 0x0078, 0x4aa5, 0x2079,
+	0x0200, 0x0078, 0x4aa5, 0x2079, 0x0100, 0x1078, 0x4383, 0x0f7f,
+	0x6864, 0xa005, 0x0040, 0x4aae, 0x1078, 0x2628, 0x6880, 0xa005,
+	0x0040, 0x4abb, 0x8001, 0x6882, 0x00c0, 0x4abb, 0x6867, 0x0000,
+	0x68d4, 0xc0dd, 0x68d6, 0x68d4, 0xd0fc, 0x0040, 0x4ad8, 0xc0fc,
+	0x68d6, 0x20a9, 0x0200, 0x6034, 0xa005, 0x0040, 0x4ad4, 0x8001,
+	0x6036, 0x68d4, 0xc0fd, 0x68d6, 0x00c0, 0x4ad4, 0x6010, 0xa005,
+	0x0040, 0x4ad4, 0x1078, 0x2628, 0xace0, 0x0010, 0x00f0, 0x4ac3,
+	0xd7fc, 0x0040, 0x4ae2, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc,
+	0x0078, 0x4a6a, 0x1078, 0x4b1e, 0x7838, 0x8001, 0x783a, 0x00c0,
+	0x4b04, 0x783c, 0x783a, 0x2061, 0x53c0, 0x2069, 0x4e40, 0xc7fc,
+	0x680c, 0xa005, 0x0040, 0x4af6, 0x1078, 0x4b88, 0xd7fc, 0x00c0,
+	0x4b04, 0x7810, 0xd0ec, 0x00c0, 0x4b04, 0x2061, 0x73c0, 0x2069,
+	0x4e80, 0xc7fd, 0x0078, 0x4af0, 0x7814, 0xd0e4, 0x00c0, 0x4b08,
+	0x7810, 0xd0cc, 0x0040, 0x4b1b, 0xd0ac, 0x00c0, 0x4b14, 0xd0a4,
+	0x0040, 0x4b1b, 0xc0ad, 0x7812, 0x2091, 0x8001, 0x0068, 0x4b1a,
+	0x1078, 0x2395, 0x007c, 0x2091, 0x8001, 0x007c, 0x7840, 0x8001,
+	0x7842, 0x00c0, 0x4b87, 0x7844, 0x7842, 0x2069, 0x4e40, 0xc7fc,
+	0x7810, 0x2079, 0x0200, 0xd0ec, 0x0040, 0x4b30, 0x2079, 0x0100,
+	0x68d8, 0xa005, 0x0040, 0x4b3c, 0x7de0, 0xa504, 0x00c0, 0x4b3c,
+	0x68da, 0x68d4, 0xc0bc, 0x68d6, 0x2079, 0x4e00, 0x6810, 0xa005,
+	0x00c0, 0x4b44, 0x2001, 0x0101, 0x8001, 0x6812, 0xd7fc, 0x0040,
+	0x4b4d, 0xa080, 0x94d0, 0x0078, 0x4b4f, 0xa080, 0x93c0, 0x2040,
+	0x2004, 0xa065, 0x0040, 0x4b79, 0x6024, 0xa005, 0x0040, 0x4b75,
+	0x8001, 0x6026, 0x00c0, 0x4b75, 0x6800, 0xa005, 0x0040, 0x4b68,
+	0x684c, 0xac06, 0x00c0, 0x4b68, 0x1078, 0x4c23, 0x0078, 0x4b79,
+	0x6864, 0xa005, 0x0040, 0x4b70, 0x6027, 0x0001, 0x0078, 0x4b75,
+	0x1078, 0x4bd6, 0x2804, 0x0078, 0x4b51, 0x6000, 0x2c40, 0x0078,
+	0x4b51, 0xd7fc, 0x00c0, 0x4b87, 0x7810, 0xd0ec, 0x00c0, 0x4b87,
+	0x2069, 0x4e80, 0xc7fd, 0x2079, 0x0100, 0x0078, 0x4b30, 0x007c,
+	0x2009, 0x0000, 0x20a9, 0x0200, 0x6008, 0xd09c, 0x0040, 0x4bc2,
+	0x6024, 0xa005, 0x0040, 0x4b98, 0x8001, 0x6026, 0x0078, 0x4bc0,
+	0x6008, 0xc09c, 0xd084, 0x00c0, 0x4ba0, 0xd0ac, 0x0040, 0x4bba,
+	0x600a, 0x6004, 0xa005, 0x0040, 0x4bc2, 0x0d7e, 0x0c7e, 0x017e,
+	0x2068, 0x6010, 0x8001, 0x6012, 0x1078, 0x3dd0, 0x2d00, 0x2c68,
+	0x2060, 0x1078, 0x1e5b, 0x1078, 0x201d, 0x017f, 0x0c7f, 0x0d7f,
+	0x0078, 0x4bc2, 0xc0bd, 0x600a, 0xa18d, 0x0001, 0x0078, 0x4bc2,
+	0xa18d, 0x0100, 0xace0, 0x0010, 0x00f0, 0x4b8c, 0xa184, 0x0001,
+	0x0040, 0x4bd1, 0xa18c, 0xfffe, 0x690e, 0x1078, 0x2628, 0x0078,
+	0x4bd2, 0x690e, 0x007c, 0x00c0, 0x4bd2, 0x786c, 0x2c00, 0x687e,
+	0x6714, 0x6f76, 0x6017, 0x0000, 0x602b, 0x0000, 0x601b, 0x0006,
+	0x60b4, 0xa084, 0x3f00, 0x601e, 0x6020, 0xa084, 0x00ff, 0xa085,
+	0x0060, 0x6022, 0x6000, 0x2042, 0x1078, 0x1de4, 0x6818, 0xa005,
+	0x0040, 0x4bf4, 0x8001, 0x681a, 0x6808, 0xc0a4, 0x680a, 0x6810,
+	0x7908, 0x8109, 0x790a, 0x8001, 0x00d0, 0x4c00, 0x1078, 0x296b,
+	0x6812, 0x00c0, 0x4c06, 0x7910, 0xc1a5, 0x7912, 0x602f, 0x0000,
+	0x6033, 0x0000, 0x2c68, 0x1078, 0x202c, 0xd7fc, 0x00c0, 0x4c14,
+	0x2069, 0x4e40, 0x0078, 0x4c16, 0x2069, 0x4e80, 0x6910, 0xa184,
+	0x0100, 0x2001, 0x0006, 0x00c0, 0x4c20, 0x697a, 0x2001, 0x0004,
+	0x1078, 0x261c, 0x007c, 0x0d7e, 0x694c, 0x2160, 0xd7fc, 0x00c0,
+	0x4c35, 0x7810, 0xd0ec, 0x0040, 0x4c31, 0x2069, 0x0100, 0x0078,
+	0x4c37, 0x2069, 0x0200, 0x0078, 0x4c37, 0x2069, 0x0100, 0x1078,
+	0x28df, 0x601b, 0x0006, 0x6858, 0xa084, 0x3f00, 0x601e, 0x6020,
+	0xa084, 0x00ff, 0xa085, 0x0048, 0x6022, 0x602f, 0x0000, 0x6033,
+	0x0000, 0x6808, 0xa084, 0xfffd, 0x680a, 0x6830, 0xd0b4, 0x0040,
+	0x4c69, 0x684b, 0x0004, 0x20a9, 0x0014, 0x6848, 0xd094, 0x0040,
+	0x4c5b, 0x00f0, 0x4c55, 0x684b, 0x0009, 0x20a9, 0x0014, 0x6848,
+	0xd084, 0x0040, 0x4c65, 0x00f0, 0x4c5f, 0x20a9, 0x00fa, 0x00f0,
+	0x4c67, 0x681b, 0x0047, 0x0d7f, 0x6867, 0x0007, 0x007c, 0x2079,
+	0x4e00, 0x1078, 0x4ca3, 0x1078, 0x4c89, 0x1078, 0x4c96, 0x2009,
+	0x0002, 0x2069, 0x4e80, 0x680f, 0x0000, 0x6813, 0x0000, 0x6817,
+	0x0000, 0x8109, 0x0040, 0x4c88, 0x2069, 0x4e40, 0x0078, 0x4c7b,
+	0x007c, 0x7810, 0xd0ec, 0x0040, 0x4c91, 0x2019, 0x00cc, 0x0078,
+	0x4c93, 0x2019, 0x007b, 0x7b3a, 0x7b3e, 0x007c, 0x7814, 0xd0e4,
+	0x00c0, 0x4c9e, 0x2019, 0x0040, 0x0078, 0x4ca0, 0x2019, 0x0026,
+	0x7b42, 0x7b46, 0x007c, 0x7814, 0xd0e4, 0x00c0, 0x4cab, 0x2019,
+	0x3f94, 0x0078, 0x4cad, 0x2019, 0x2624, 0x7b32, 0x7b36, 0x007c,
+	0x6a50, 0xa285, 0x0000, 0x0040, 0x4cdc, 0x6954, 0x6bc0, 0xa300,
+	0x0c7e, 0x2164, 0x6304, 0x83ff, 0x00c0, 0x4cc8, 0x8211, 0x0040,
+	0x4ccc, 0x8108, 0xa11a, 0x0048, 0x4cb9, 0x69c0, 0x0078, 0x4cb9,
+	0x68d3, 0x000a, 0x0c7f, 0x007c, 0x6950, 0x6ac0, 0x2264, 0x602b,
+	0x0000, 0x602f, 0x0000, 0x6008, 0xc0b5, 0x600a, 0x8210, 0x8109,
+	0x00c0, 0x4cce, 0x6952, 0x0c7f, 0x007c, 0x00e0, 0x4cdd, 0x2091,
+	0x6000, 0x00e0, 0x4ce1, 0x2091, 0x6000, 0x70ec, 0xd0dc, 0x00c0,
+	0x4cee, 0xd0d4, 0x0040, 0x4d17, 0x0078, 0x4d1a, 0x2008, 0x7810,
+	0xd0ec, 0x0040, 0x4d01, 0xd1c4, 0x00c0, 0x4d39, 0x7814, 0xc0c5,
+	0x7816, 0x7810, 0xc0f5, 0x7812, 0xd0ec, 0x0040, 0x4d35, 0x0078,
+	0x4d31, 0xae8e, 0x0100, 0x0040, 0x4d0e, 0x7814, 0xc0f5, 0xc0c5,
+	0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0x7814, 0xc0fd,
+	0xc0c5, 0x7816, 0xd0d4, 0x00c0, 0x4d35, 0x0078, 0x4d31, 0xd0e4,
+	0x0040, 0x4d37, 0x00e0, 0x4d1a, 0x2091, 0x6000, 0x2009, 0x000c,
+	0x00e0, 0x4d20, 0x2091, 0x6000, 0x8109, 0x00c0, 0x4d20, 0x70e4,
+	0xa084, 0x01ff, 0xa086, 0x01ff, 0x00c0, 0x4d31, 0x70ec, 0x0078,
+	0x4cee, 0x7804, 0xd08c, 0x0040, 0x4d37, 0x681f, 0x000c, 0x70a0,
+	0x70a2, 0x007c, 0x205b
 };
-unsigned short   fw1280ei_length01 = 0x39e3;
-
+#ifdef UNIQUE_FW_NAME
+unsigned short   fw1280ei_length01 = 0x3d3b;
+#else
+unsigned short   risc_code_length01 = 0x3d3b;
+#endif
diff -urN linux-2.4.23-pre6/drivers/scsi/qla1280.c linux-2.4.23-pre7/drivers/scsi/qla1280.c
--- linux-2.4.23-pre6/drivers/scsi/qla1280.c	2001-09-30 12:26:07.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/qla1280.c	2003-10-09 17:48:22.000000000 -0700
@@ -1,165 +1,273 @@
-/********************************************************************************
- *                  QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP1x80/1x160 device driver for Linux 2.3.x (redhat 6.X).
- *
- * COPYRIGHT (C) 1999-2000 QLOGIC CORPORATION    
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the Qlogic's Linux Software License. See below.
- *
- * This program is WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistribution's or source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification, immediately at the beginning of the file.
- * 2. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- ********************************************************************************/
- 
-/*****************************************************************************************
-			QLOGIC CORPORATION SOFTWARE
-           "GNU" GENERAL PUBLIC LICENSE
-    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION
-                 AND MODIFICATION
-
-This GNU General Public License ("License") applies solely to QLogic Linux 
-Software ("Software") and may be distributed under the terms of this License.  
- 
-1. You may copy and distribute verbatim copies of the Software's source code as 
-you receive it, in any medium, provided that you conspicuously and appropriately 
-publish on each copy an appropriate copyright notice and disclaimer of warranty;
-keep intact all the notices that refer to this License and to the absence of any
-warranty; and give any other recipients of the Software a copy of this License along
-with the Software. 
-
-You may charge a fee for the physical act of transferring a copy, and you may at your
-option offer warranty protection in exchange for a fee.
- 
-2. You may modify your copy or copies of the Software or any portion of it, thus forming
-a work based on the Software, and copy and distribute such modifications or work under
-the terms of Section 1 above, provided that you also meet all of these conditions:
- 
-* a) You must cause the modified files to carry prominent notices stating that you
-changed the files and the date of any change. 
-
-* b) You must cause any work that you distribute or publish that in whole or in part
-contains or is derived from the Software or any part thereof, to be licensed as a
-whole at no charge to all third parties under the terms of this License. 
-
-* c) If the modified Software normally reads commands interactively when run, you
-must cause it, when started running for such interactive use in the most ordinary way,
-to print or display an announcement including an appropriate copyright notice and a 
-notice that there is no warranty (or else, saying that you provide a warranty) and that
-users may redistribute the Software under these conditions, and telling the user how to
-view a copy of this License. (Exception:if the Software itself is interactive but does 
-not normally print such an announcement, your work based on the Software is not required
-to print an announcement.) 
-
-These requirements apply to the modified work as a whole. If identifiable sections of
-that work are not derived from the Software, and can be reasonably considered independent
-and separate works in themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you distribute the same
-sections as part of a whole which is a work based on the Software, the distribution of the
-whole must be on the terms of this License, whose permissions for other licensees extend
-to the entire whole, and thus to each and every part regardless of who wrote it. 
-
-3. You may copy and distribute the Software (or a work based on it, under Section 2) in 
-object code or executable form under the terms of Sections 1 and 2 above provided that
-you also do one of the following: 
-
-* a) Accompany it with the complete corresponding machine-readable source code, which must
-be distributed under the terms of Sections 1 and 2 above on a medium customarily used for
-software interchange; or, 
-
-* b) Accompany it with a written offer, valid for at least three years, to give any third
-party, for a charge no more than your cost of physically performing source distribution,
-a complete machine-readable copy of the corresponding source code, to be distributed under
-the terms of Sections 1 and 2 above on a medium customarily used for software interchange;
-or,
-
-* c) Accompany it with the information you received as to the offer to distribute 
-corresponding source code. (This alternative is allowed only for noncommercial distribution
-and only if you received the Software in object code or executable form with such an offer,
-in accord with Subsection b above.) 
-
-The source code for a work means the preferred form of the work for making modifications
-to it. For an executable work, complete source code means all the source code for all 
-modules it contains, plus any associated interface definition files, plus the scripts used
-to control compilation and installation of the executable.     
-
-If distribution of executable or object code is made by offering access to copy from a 
-designated place, then offering equivalent access to copy the source code from the same
-place counts as distribution of the source code, even though third parties are not 
-compelled to copy the source along with the object code. 
-
-4. You may not copy, modify, sublicense, or distribute the Software except as expressly 
-provided under this License. Any attempt otherwise to copy, modify, sublicense or 
-distribute the Software is void, and will automatically terminate your rights under this
-License. However, parties who have received copies, or rights, from you under this License
-will not have their licenses terminated so long as such parties remain in full compliance. 
-
-5. This license grants you world wide, royalty free non-exclusive rights to modify or 
-distribute the Software or its derivative works. These actions are prohibited by law 
-if you do not accept this License. Therefore, by modifying or distributing the Software
-(or any work based on the Software), you indicate your acceptance of this License to do
-so, and all its terms and conditions for copying, distributing or modifying the Software
-or works based on it.
- 
-6. Each time you redistribute the Software (or any work based on the Software), the 
-recipient automatically receives a license from the original licensor to copy, distribute
-or modify the Software subject to these terms and conditions. You may not impose any 
-further restrictions on the recipients' exercise of the rights granted herein. You are
-not responsible for enforcing compliance by third parties to this License.
- 
-7. If, as a consequence of a court judgment or allegation of patent infringement or for
-any other reason (not limited to patent issues), conditions are imposed on you 
-(whether by court order, agreement or otherwise) that contradict the conditions of this
-License, they do not excuse you from the conditions of this License. If you cannot 
-distribute so as to satisfy simultaneously your obligations under this License 
-and any other pertinent obligations, then as a consequence you may not distribute the
-Software at all.    
-
-If any portion of this section is held invalid or unenforceable under any particular 
-circumstance, the balance of the section is intended to apply and the section as a whole
-is intended to apply in other circumstances. 
-NO WARRANTY
-
-11. THE SOFTWARE IS PROVIDED WITHOUT A WARRANTY OF ANY KIND. THERE IS NO 
-WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 
-OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, 
-EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 
-ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. 
-SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 
-NECESSARY SERVICING, REPAIR OR CORRECTION.
- 
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 
-REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR 
-DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL 
-DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING 
-BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 
-LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO 
-OPERATE WITH ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS 
-BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
-END OF TERMS AND CONDITIONS 
-
-*******************************************************************************************/ 
-
-/****************************************************************************
+/******************************************************************************
+*                  QLOGIC LINUX SOFTWARE
+*
+* QLogic  QLA1280 (Ultra2)  and  QLA12160 (Ultra3) SCSI driver
+* Copyright (C) 2000 Qlogic Corporation (www.qlogic.com)
+* Copyright (C) 2001-2003 Jes Sorensen, Wild Open Source 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, 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.
+*
+******************************************************************************/
+#define QLA1280_VERSION      "3.23.37"
+/*****************************************************************************
     Revision History:
-    Rev. 3.00       Jan 17, 1999    DG  Qlogic
+    Rev  3.23.37 October 1, 2003, Jes Sorensen
+	- Make MMIO depend on CONFIG_X86_VISWS instead of yet another
+	  random CONFIG option
+	- Clean up locking in probe path
+    Rev  3.23.36 October 1, 2003, Christoph Hellwig
+	- queuecommand only ever receives new commands - clear flags
+	- Reintegrate lost fixes from Linux 2.5
+    Rev  3.23.35 August 14, 2003, Jes Sorensen
+	- Build against 2.6
+    Rev  3.23.34 July 23, 2003, Jes Sorensen
+	- Remove pointless TRUE/FALSE macros
+	- Clean up vchan handling
+    Rev  3.23.33 July 3, 2003, Jes Sorensen
+	- Don't define register access macros before define determining MMIO.
+	  This just happend to work out on ia64 but not elsewhere.
+	- Don't try and read from the card while it is in reset as
+	  it won't respond and causes an MCA
+    Rev  3.23.32 June 23, 2003, Jes Sorensen
+	- Basic support for boot time arguments
+    Rev  3.23.31 June 8, 2003, Jes Sorensen
+	- Reduce boot time messages
+    Rev  3.23.30 June 6, 2003, Jes Sorensen
+	- Do not enable sync/wide/ppr before it has been determined
+	  that the target device actually supports it
+	- Enable DMA arbitration for multi channel controllers
+    Rev  3.23.29 June 3, 2003, Jes Sorensen
+	- Port to 2.5.69
+    Rev  3.23.28 June 3, 2003, Jes Sorensen
+	- Eliminate duplicate marker commands on bus resets
+	- Handle outstanding commands appropriately on bus/device resets
+    Rev  3.23.27 May 28, 2003, Jes Sorensen
+	- Remove bogus input queue code, let the Linux SCSI layer do the work
+	- Clean up NVRAM handling, only read it once from the card
+	- Add a number of missing default nvram parameters
+    Rev  3.23.26 Beta May 28, 2003, Jes Sorensen
+	- Use completion queue for mailbox commands instead of busy wait
+    Rev  3.23.25 Beta May 27, 2003, James Bottomley
+	- Migrate to use new error handling code
+    Rev  3.23.24 Beta May 21, 2003, James Bottomley
+	- Big endian support
+	- Cleanup data direction code
+    Rev  3.23.23 Beta May 12, 2003, Jes Sorensen
+	- Switch to using MMIO instead of PIO
+    Rev  3.23.22 Beta April 15, 2003, Jes Sorensen
+	- Fix PCI parity problem with 12160 during reset.
+    Rev  3.23.21 Beta April 14, 2003, Jes Sorensen
+	- Use pci_map_page()/pci_unmap_page() instead of map_single version.
+    Rev  3.23.20 Beta April 9, 2003, Jes Sorensen
+	- Remove < 2.4.x support
+	- Introduce HOST_LOCK to make the spin lock changes portable.
+	- Remove a bunch of idiotic and unnecessary typedef's
+	- Kill all leftovers of target-mode support which never worked anyway
+    Rev  3.23.19 Beta April 11, 2002, Linus Torvalds
+	- Do qla1280_pci_config() before calling request_irq() and
+	  request_region()
+	- Use pci_dma_hi32() to handle upper word of DMA addresses instead
+	  of large shifts
+	- Hand correct arguments to free_irq() in case of failure
+    Rev  3.23.18 Beta April 11, 2002, Jes Sorensen
+	- Run source through Lindent and clean up the output
+    Rev  3.23.17 Beta April 11, 2002, Jes Sorensen
+	- Update SCSI firmware to qla1280 v8.15.00 and qla12160 v10.04.32
+    Rev  3.23.16 Beta March 19, 2002, Jes Sorensen
+	- Rely on mailbox commands generating interrupts - do not
+	  run qla1280_isr() from ql1280_mailbox_command()
+	- Remove device_reg_t
+	- Integrate ql12160_set_target_parameters() with 1280 version
+	- Make qla1280_setup() non static
+	- Do not call qla1280_check_for_dead_scsi_bus() on every I/O request
+	  sent to the card - this command pauses the firmare!!!
+    Rev  3.23.15 Beta March 19, 2002, Jes Sorensen
+	- Clean up qla1280.h - remove obsolete QL_DEBUG_LEVEL_x definitions
+	- Remove a pile of pointless and confusing (srb_t **) and
+	  (scsi_lu_t *) typecasts
+	- Explicit mark that we do not use the new error handling (for now)
+	- Remove scsi_qla_host_t and use 'struct' instead
+	- Remove in_abort, watchdog_enabled, dpc, dpc_sched, bios_enabled,
+	  pci_64bit_slot flags which weren't used for anything anyway
+	- Grab host->host_lock while calling qla1280_isr() from abort()
+	- Use spin_lock()/spin_unlock() in qla1280_intr_handler() - we
+	  do not need to save/restore flags in the interrupt handler
+	- Enable interrupts early (before any mailbox access) in preparation
+	  for cleaning up the mailbox handling
+    Rev  3.23.14 Beta March 14, 2002, Jes Sorensen
+	- Further cleanups. Remove all trace of QL_DEBUG_LEVEL_x and replace
+	  it with proper use of dprintk().
+	- Make qla1280_print_scsi_cmd() and qla1280_dump_buffer() both take
+	  a debug level argument to determine if data is to be printed
+	- Add KERN_* info to printk()
+    Rev  3.23.13 Beta March 14, 2002, Jes Sorensen
+	- Significant cosmetic cleanups
+	- Change debug code to use dprintk() and remove #if mess
+    Rev  3.23.12 Beta March 13, 2002, Jes Sorensen
+	- More cosmetic cleanups, fix places treating return as function
+	- use cpu_relax() in qla1280_debounce_register()
+    Rev  3.23.11 Beta March 13, 2002, Jes Sorensen
+	- Make it compile under 2.5.5
+    Rev  3.23.10 Beta October 1, 2001, Jes Sorensen
+	- Do no typecast short * to long * in QL1280BoardTbl, this
+	  broke miserably on big endian boxes
+    Rev  3.23.9 Beta September 30, 2001, Jes Sorensen
+	- Remove pre 2.2 hack for checking for reentrance in interrupt handler
+	- Make data types used to receive from SCSI_{BUS,TCN,LUN}_32
+	  unsigned int to match the types from struct scsi_cmnd
+    Rev  3.23.8 Beta September 29, 2001, Jes Sorensen
+	- Remove bogus timer_t typedef from qla1280.h
+	- Remove obsolete pre 2.2 PCI setup code, use proper #define's
+	  for PCI_ values, call pci_set_master()
+	- Fix memleak of qla1280_buffer on module unload
+	- Only compile module parsing code #ifdef MODULE - should be
+	  changed to use individual MODULE_PARM's later
+	- Remove dummy_buffer that was never modified nor printed
+	- ENTER()/LEAVE() are noops unless QL_DEBUG_LEVEL_3, hence remove
+	  #ifdef QL_DEBUG_LEVEL_3/#endif around ENTER()/LEAVE() calls
+	- Remove \r from print statements, this is Linux, not DOS
+	- Remove obsolete QLA1280_{SCSILU,INTR,RING}_{LOCK,UNLOCK}
+	  dummy macros
+	- Remove C++ compile hack in header file as Linux driver are not
+	  supposed to be compiled as C++
+	- Kill MS_64BITS macro as it makes the code more readable
+	- Remove unnecessary flags.in_interrupts bit
+    Rev  3.23.7 Beta August 20, 2001, Jes Sorensen
+	- Dont' check for set flags on q->q_flag one by one in qla1280_next()
+        - Check whether the interrupt was generated by the QLA1280 before
+          doing any processing
+	- qla1280_status_entry(): Only zero out part of sense_buffer that
+	  is not being copied into
+	- Remove more superflouous typecasts
+	- qla1280_32bit_start_scsi() replace home-brew memcpy() with memcpy()
+    Rev  3.23.6 Beta August 20, 2001, Tony Luck, Intel
+        - Don't walk the entire list in qla1280_putq_t() just to directly
+	  grab the pointer to the last element afterwards
+    Rev  3.23.5 Beta August 9, 2001, Jes Sorensen
+	- Don't use SA_INTERRUPT, it's use is deprecated for this kinda driver
+    Rev  3.23.4 Beta August 8, 2001, Jes Sorensen
+	- Set dev->max_sectors to 1024
+    Rev  3.23.3 Beta August 6, 2001, Jes Sorensen
+	- Provide compat macros for pci_enable_device(), pci_find_subsys()
+	  and scsi_set_pci_device()
+	- Call scsi_set_pci_device() for all devices
+	- Reduce size of kernel version dependent device probe code
+	- Move duplicate probe/init code to separate function
+	- Handle error if qla1280_mem_alloc() fails
+	- Kill OFFSET() macro and use Linux's PCI definitions instead
+        - Kill private structure defining PCI config space (struct config_reg)
+	- Only allocate I/O port region if not in MMIO mode
+	- Remove duplicate (unused) sanity check of sife of srb_t
+    Rev  3.23.2 Beta August 6, 2001, Jes Sorensen
+	- Change home-brew memset() implementations to use memset()
+        - Remove all references to COMTRACE() - accessing a PC's COM2 serial
+          port directly is not legal under Linux.
+    Rev  3.23.1 Beta April 24, 2001, Jes Sorensen
+        - Remove pre 2.2 kernel support
+        - clean up 64 bit DMA setting to use 2.4 API (provide backwards compat)
+        - Fix MMIO access to use readl/writel instead of directly
+          dereferencing pointers
+        - Nuke MSDOS debugging code
+        - Change true/false data types to int from uint8_t
+        - Use int for counters instead of uint8_t etc.
+        - Clean up size & byte order conversion macro usage
+    Rev  3.23 Beta January 11, 2001 BN Qlogic
+        - Added check of device_id when handling non
+          QLA12160s during detect().
+    Rev  3.22 Beta January 5, 2001 BN Qlogic
+        - Changed queue_task() to schedule_task()
+          for kernels 2.4.0 and higher.
+          Note: 2.4.0-testxx kernels released prior to
+                the actual 2.4.0 kernel release on January 2001
+                will get compile/link errors with schedule_task().
+                Please update your kernel to released 2.4.0 level,
+                or comment lines in this file flagged with  3.22
+                to resolve compile/link error of schedule_task().
+        - Added -DCONFIG_SMP in addition to -D__SMP__
+          in Makefile for 2.4.0 builds of driver as module.
+    Rev  3.21 Beta January 4, 2001 BN Qlogic
+        - Changed criteria of 64/32 Bit mode of HBA
+          operation according to BITS_PER_LONG rather
+          than HBA's NVRAM setting of >4Gig memory bit;
+          so that the HBA auto-configures without the need
+          to setup each system individually.
+    Rev  3.20 Beta December 5, 2000 BN Qlogic
+        - Added priority handling to IA-64  onboard SCSI
+          ISP12160 chip for kernels greater than 2.3.18.
+        - Added irqrestore for qla1280_intr_handler.
+        - Enabled /proc/scsi/qla1280 interface.
+        - Clear /proc/scsi/qla1280 counters in detect().
+    Rev  3.19 Beta October 13, 2000 BN Qlogic
+        - Declare driver_template for new kernel
+          (2.4.0 and greater) scsi initialization scheme.
+        - Update /proc/scsi entry for 2.3.18 kernels and
+          above as qla1280
+    Rev  3.18 Beta October 10, 2000 BN Qlogic
+        - Changed scan order of adapters to map
+          the QLA12160 followed by the QLA1280.
+    Rev  3.17 Beta September 18, 2000 BN Qlogic
+        - Removed warnings for 32 bit 2.4.x compiles
+        - Corrected declared size for request and response
+          DMA addresses that are kept in each ha
+    Rev. 3.16 Beta  August 25, 2000   BN  Qlogic
+        - Corrected 64 bit addressing issue on IA-64
+          where the upper 32 bits were not properly
+          passed to the RISC engine.
+    Rev. 3.15 Beta  August 22, 2000   BN  Qlogic
+        - Modified qla1280_setup_chip to properly load
+          ISP firmware for greater that 4 Gig memory on IA-64
+    Rev. 3.14 Beta  August 16, 2000   BN  Qlogic
+        - Added setting of dma_mask to full 64 bit
+          if flags.enable_64bit_addressing is set in NVRAM
+    Rev. 3.13 Beta  August 16, 2000   BN  Qlogic
+        - Use new PCI DMA mapping APIs for 2.4.x kernel
+    Rev. 3.12       July 18, 2000    Redhat & BN Qlogic
+        - Added check of pci_enable_device to detect() for 2.3.x
+        - Use pci_resource_start() instead of
+          pdev->resource[0].start in detect() for 2.3.x
+        - Updated driver version
+    Rev. 3.11       July 14, 2000    BN  Qlogic
+	- Updated SCSI Firmware to following versions:
+	  qla1x80:   8.13.08
+	  qla1x160:  10.04.08
+	- Updated driver version to 3.11
+    Rev. 3.10    June 23, 2000   BN Qlogic
+        - Added filtering of AMI SubSys Vendor ID devices
+    Rev. 3.9
+        - DEBUG_QLA1280 undefined and  new version  BN Qlogic
+    Rev. 3.08b      May 9, 2000    MD Dell
+        - Added logic to check against AMI subsystem vendor ID
+	Rev. 3.08       May 4, 2000    DG  Qlogic
+        - Added logic to check for PCI subsystem ID.
+	Rev. 3.07       Apr 24, 2000    DG & BN  Qlogic
+	   - Updated SCSI Firmware to following versions:
+	     qla12160:   10.01.19
+		 qla1280:     8.09.00
+	Rev. 3.06       Apr 12, 2000    DG & BN  Qlogic
+	   - Internal revision; not released
+    Rev. 3.05       Mar 28, 2000    DG & BN  Qlogic
+       - Edit correction for virt_to_bus and PROC.
+    Rev. 3.04       Mar 28, 2000    DG & BN  Qlogic
+       - Merge changes from ia64 port.
+    Rev. 3.03       Mar 28, 2000    BN  Qlogic
+       - Increase version to reflect new code drop with compile fix
+         of issue with inclusion of linux/spinlock for 2.3 kernels
+    Rev. 3.02       Mar 15, 2000    BN  Qlogic
+       - Merge qla1280_proc_info from 2.10 code base
+    Rev. 3.01       Feb 10, 2000    BN  Qlogic
+       - Corrected code to compile on a 2.2.x kernel.
+    Rev. 3.00       Jan 17, 2000    DG  Qlogic
 	   - Added 64-bit support.
     Rev. 2.07       Nov 9, 1999     DG  Qlogic
-	   - Added new routine to set target parameters for ISP12160. 
+	   - Added new routine to set target parameters for ISP12160.
     Rev. 2.06       Sept 10, 1999     DG  Qlogic
        - Added support for ISP12160 Ultra 3 chip.
     Rev. 2.03       August 3, 1999    Fred Lewis, Intel DuPont
@@ -173,27 +281,19 @@
         - Added l modifiers to sprintf and printk format specifiers for longs.
         - Removed unused local variables.
     Rev. 1.20       June 8, 1999      DG,  Qlogic
-         Changes to support RedHat release 6.0 (kernel 2.2.5).  
-       - Added SCSI exclusive access lock (io_request_lock) when accessing 
+         Changes to support RedHat release 6.0 (kernel 2.2.5).
+       - Added SCSI exclusive access lock (io_request_lock) when accessing
          the adapter.
        - Added changes for the new LINUX interface template. Some new error
          handling routines have been added to the template, but for now we
          will use the old ones.
-    -   Initial Beta Release.  
+    -   Initial Beta Release.
 *****************************************************************************/
 
 
-#ifdef MODULE
+#include <linux/config.h>
 #include <linux/module.h>
-#endif
 
-#define QLA1280_VERSION      " 3.00-Beta"
-
-#include <stdarg.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/segment.h>
-#include <asm/byteorder.h>
 #include <linux/version.h>
 #include <linux/types.h>
 #include <linux/string.h>
@@ -205,226 +305,253 @@
 #include <linux/sched.h>
 #include <linux/pci.h>
 #include <linux/proc_fs.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/pci_ids.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/byteorder.h>
+#include <asm/processor.h>
+#include <asm/types.h>
+#include <asm/system.h>
+
+#if LINUX_VERSION_CODE >= 0x020545
+#include <scsi/scsi_host.h>
+#include "scsi.h"
+#else
 #include <linux/blk.h>
-#include <linux/tqueue.h>
-/* MRS #include <linux/tasks.h> */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-# include <linux/bios32.h>
-#endif
-#include "sd.h"
 #include "scsi.h"
 #include "hosts.h"
-#define UNIQUE_FW_NAME
-#include "qla1280.h"
-#include "ql12160_fw.h"                     /* ISP RISC code */
-#include "ql1280_fw.h"
+#include "sd.h"
+#endif
 
-#include <linux/stat.h>
-#include <linux/slab.h>        /* for kmalloc() */
+#if LINUX_VERSION_CODE < 0x020407
+#error "Kernels older than 2.4.7 are no longer supported"
+#endif
 
 
-#ifndef KERNEL_VERSION
-#  define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-#endif
+/*
+ * Compile time Options:
+ *            0 - Disable and 1 - Enable
+ */
+#define  QL1280_LUN_SUPPORT	0
+#define  WATCHDOGTIMER		0
 
+#define  DEBUG_QLA1280_INTR	0
+#define  DEBUG_PRINT_NVRAM	0
+#define  DEBUG_QLA1280		0
 
 /*
- * Compile time Options: 
- *            0 - Disable and 1 - Enable 
+ * The SGI VISWS is broken and doesn't support MMIO ;-(
  */
-#define  QLA1280_64BIT_SUPPORT         1   /* 64-bit Support */
-#define  QL1280_TARGET_MODE_SUPPORT    0   /* Target mode support */
-#define  WATCHDOGTIMER                 0
-#define  MEMORY_MAPPED_IO              0
-#define  DEBUG_QLA1280_INTR            0
-#define  USE_NVRAM_DEFAULTS	       0
-#define  DEBUG_PRINT_NVRAM             0
-#define  LOADING_RISC_ACTIVITY         0
-#define  AUTO_ESCALATE_RESET           0   /* Automatically escalate resets */
-#define  AUTO_ESCALATE_ABORT           0   /* Automatically escalate aborts */
-#define  STOP_ON_ERROR                 0   /* Stop on aborts and resets  */
-#define  STOP_ON_RESET                 0 
-#define  STOP_ON_ABORT                 0 
-#undef   DYNAMIC_MEM_ALLOC
+#ifdef CONFIG_X86_VISWS
+#define	MEMORY_MAPPED_IO	0
+#else
+#define	MEMORY_MAPPED_IO	1
+#endif
+
+#define UNIQUE_FW_NAME
+#include "qla1280.h"
+#include "ql12160_fw.h"		/* ISP RISC codes */
+#include "ql1280_fw.h"
 
-#define  DEBUG_QLA1280                 0    /* Debugging  */
-/* #define CHECKSRBSIZE */
 
 /*
- * These macros to assist programming
+ * Missing PCI ID's
  */
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP1080
+#define PCI_DEVICE_ID_QLOGIC_ISP1080	0x1080
+#endif
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP1240
+#define PCI_DEVICE_ID_QLOGIC_ISP1240	0x1240
+#endif
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP1280
+#define PCI_DEVICE_ID_QLOGIC_ISP1280	0x1280
+#endif
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP10160
+#define PCI_DEVICE_ID_QLOGIC_ISP10160	0x1016
+#endif
+#ifndef PCI_DEVICE_ID_QLOGIC_ISP12160
+#define PCI_DEVICE_ID_QLOGIC_ISP12160	0x1216
+#endif
 
-#define	BZERO(ptr, amt)		memset(ptr, 0, amt)
-#define	BCOPY(src, dst, amt)	memcpy(dst, src, amt)
-#define	KMALLOC(siz)	kmalloc((siz), GFP_ATOMIC)
-#define	KMFREE(ip,siz)	kfree((ip))
-#define	SYS_DELAY(x)		udelay(x);barrier()
-#define QLA1280_DELAY(sec)  mdelay(sec * 1000)
-#define VIRT_TO_BUS(a) virt_to_bus((a))
-#if  QLA1280_64BIT_SUPPORT
-#if  BITS_PER_LONG <= 32
-#define  VIRT_TO_BUS_LOW(a) (uint32_t)virt_to_bus((a))
-#define  VIRT_TO_BUS_HIGH(a) (uint32_t)(0x0)
-#else
-#define  VIRT_TO_BUS_LOW(a) (uint32_t)(0xffffffff & virt_to_bus((a)))
-#define  VIRT_TO_BUS_HIGH(a) (uint32_t)(0xffffffff & (virt_to_bus((a))>>32))
+#ifndef PCI_VENDOR_ID_AMI
+#define PCI_VENDOR_ID_AMI               0x101e
 #endif
-#endif  /* QLA1280_64BIT_SUPPORT */
 
-#define STATIC     
+#ifndef BITS_PER_LONG
+#error "BITS_PER_LONG not defined!"
+#endif
+#if (BITS_PER_LONG == 64) || defined CONFIG_HIGHMEM
+#define QLA_64BIT_PTR	1
+#endif
 
-#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */
-void qla1280_device_queue_depth(scsi_qla_host_t *, Scsi_Device *);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+#include <asm/sn/pci/pciio.h>
+/* Ugly hack needed for the virtual channel fix on SN2 */
+extern int snia_pcibr_rrb_alloc(struct pci_dev *pci_dev,
+				int *count_vchan0, int *count_vchan1);
+#endif
 
-#define  CACHE_FLUSH(a) (RD_REG_WORD(a))
-#define  INVALID_HANDLE    (MAX_OUTSTANDING_COMMANDS+1)
+#ifdef QLA_64BIT_PTR
+#define pci_dma_hi32(a)			((a >> 16) >> 16)
+#else
+#define pci_dma_hi32(a)			0
+#endif
+#define pci_dma_lo32(a)			(a & 0xffffffff)
 
-#define  MSW(x)          (uint16_t)((uint32_t)(x) >> 16)
-#define  LSW(x)          (uint16_t)(x)
-#define  MSB(x)          (uint8_t)((uint16_t)(x) >> 8)
-#define  LSB(x)          (uint8_t)(x)
+#define NVRAM_DELAY()			udelay(500)	/* 2 microseconds */
 
-#if  BITS_PER_LONG <= 32
-#define  LS_64BITS(x) (uint32_t)(x)
-#define  MS_64BITS(x) (uint32_t)(0x0)
+#if LINUX_VERSION_CODE < 0x020417
+/* Compat already available in 2.4.23 */
+#define irqreturn_t			void
+#define IRQ_RETVAL(foo)
+#endif
+#if LINUX_VERSION_CODE < 0x020500
+#define HOST_LOCK			&io_request_lock
+#define MSG_ORDERED_TAG			1
+static inline void
+scsi_adjust_queue_depth(Scsi_Device *device, int tag, int depth)
+{
+	if (tag) {
+		device->tagged_queue = tag;
+		device->current_tag = 0;
+	}
+	device->queue_depth = depth;
+}
+#else
+#define HOST_LOCK			ha->host->host_lock
+#endif
+#if LINUX_VERSION_CODE < 0x020600
+#define DEV_SIMPLE_TAGS(device)		device->tagged_queue
 #else
-#define  LS_64BITS(x) (uint32_t)(0xffffffff & (x))
-#define  MS_64BITS(x) (uint32_t)(0xffffffff & ((x)>>32) )
+#define DEV_SIMPLE_TAGS(device)		device->simple_tags
+#endif
+#if defined(__ia64__) && !defined(ia64_platform_is)
+#define ia64_platform_is(foo)		(!strcmp(x, platform_name))
 #endif
 
 /*
  *  QLogic Driver Support Function Prototypes.
  */
-STATIC void   qla1280_done(scsi_qla_host_t *, srb_t **, srb_t **);
-STATIC void   qla1280_next(scsi_qla_host_t *, scsi_lu_t *, uint8_t);
-STATIC void   qla1280_putq_t(scsi_lu_t *, srb_t *);
-STATIC void   qla1280_done_q_put(srb_t *, srb_t **, srb_t **);
-STATIC void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
-#ifdef  QLA1280_UNUSED 
-static void qla1280_dump_regs(struct Scsi_Host *host);
-#endif
-#if  STOP_ON_ERROR 
-static void qla1280_panic(char *, struct Scsi_Host *host);
-#endif
-void qla1280_print_scsi_cmd(Scsi_Cmnd *cmd);
-STATIC void qla1280_abort_queue_single(scsi_qla_host_t *,uint32_t,uint32_t,uint32_t,uint32_t);
-
-STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd       *cp);
-STATIC void qla1280_removeq(scsi_lu_t *q, srb_t *sp);
-STATIC void qla1280_mem_free(scsi_qla_host_t *ha);
-static void qla1280_do_dpc(void *p);
-#ifdef  QLA1280_UNUSED 
-static void qla1280_set_flags(char * s);
-#endif
-static char	*qla1280_get_token(char *, char *);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-STATIC inline void mdelay(int);
+static void qla1280_done(struct scsi_qla_host *, struct srb **, struct srb **);
+static void qla1280_done_q_put(struct srb *, struct srb **, struct srb **);
+static int qla1280_slave_configure(Scsi_Device *);
+#if LINUX_VERSION_CODE < 0x020545
+static void qla1280_select_queue_depth(struct Scsi_Host *, Scsi_Device *);
+static void qla1280_get_target_options(struct scsi_cmnd *, struct scsi_qla_host *);
 #endif
-static inline void qla1280_enable_intrs(scsi_qla_host_t *);
-static inline void qla1280_disable_intrs(scsi_qla_host_t *);
+
+static int qla1280_return_status(struct response * sts, Scsi_Cmnd * cp);
+static void qla1280_mem_free(struct scsi_qla_host *ha);
+static int qla1280_get_token(char *);
+static int qla1280_setup(char *s) __init;
+static inline void qla1280_enable_intrs(struct scsi_qla_host *);
+static inline void qla1280_disable_intrs(struct scsi_qla_host *);
 
 /*
  *  QLogic ISP1280 Hardware Support Function Prototypes.
  */
-STATIC uint8_t   qla1280_initialize_adapter(struct scsi_qla_host   *ha);
-STATIC uint8_t   qla1280_enable_tgt(scsi_qla_host_t *, uint8_t);
-STATIC uint8_t   qla1280_isp_firmware(scsi_qla_host_t *);
-STATIC uint8_t   qla1280_pci_config(scsi_qla_host_t *);
-STATIC uint8_t   qla1280_chip_diag(scsi_qla_host_t *);
-STATIC uint8_t   qla1280_setup_chip(scsi_qla_host_t *);
-STATIC uint8_t   qla1280_init_rings(scsi_qla_host_t *);
-STATIC uint8_t   qla1280_nvram_config(scsi_qla_host_t *);
-STATIC uint8_t   qla1280_mailbox_command(scsi_qla_host_t *, uint8_t, uint16_t *);
-STATIC uint8_t   qla1280_bus_reset(scsi_qla_host_t *, uint8_t);
-STATIC uint8_t   qla1280_device_reset(scsi_qla_host_t *, uint8_t, uint32_t);
-STATIC uint8_t   qla1280_abort_device(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t);
-STATIC uint8_t   qla1280_abort_command(scsi_qla_host_t *, srb_t *),
-#if  QLA1280_64BIT_SUPPORT
-                 qla1280_64bit_start_scsi(scsi_qla_host_t *, srb_t *),
-#endif
-                 qla1280_32bit_start_scsi(scsi_qla_host_t *, srb_t *),
-                 qla1280_abort_isp(scsi_qla_host_t *);
-STATIC void      qla1280_nv_write(scsi_qla_host_t *, uint16_t),
-                 qla1280_nv_delay(scsi_qla_host_t *),
-                 qla1280_poll(scsi_qla_host_t *),
-                 qla1280_reset_adapter(scsi_qla_host_t *),
-                 qla1280_marker(scsi_qla_host_t *, uint8_t, uint32_t, uint32_t, uint8_t),
-                 qla1280_isp_cmd(scsi_qla_host_t *),
-                 qla1280_isr(scsi_qla_host_t *, srb_t **, srb_t **),
-                 qla1280_rst_aen(scsi_qla_host_t *),
-                 qla1280_status_entry(scsi_qla_host_t *, sts_entry_t *, srb_t **,
-                                      srb_t **),
-                 qla1280_error_entry(scsi_qla_host_t *, response_t *, srb_t **,
-                                     srb_t **),
-                 qla1280_restart_queues(scsi_qla_host_t *),
-                 qla1280_abort_queues(scsi_qla_host_t *);
-STATIC uint16_t  qla1280_get_nvram_word(scsi_qla_host_t *, uint32_t),
-                 qla1280_nvram_request(scsi_qla_host_t *, uint32_t),
-                 qla1280_debounce_register(volatile uint16_t *);
-STATIC request_t *qla1280_req_pkt(scsi_qla_host_t *);
-int  qla1280_check_for_dead_scsi_bus(scsi_qla_host_t *ha, srb_t *sp);
-STATIC uint8_t qla1280_mem_alloc(scsi_qla_host_t *ha);
-STATIC uint8_t  qla1280_register_with_Linux(scsi_qla_host_t *ha, uint8_t maxchannels);
-
-STATIC uint8_t qla12160_set_target_parameters(scsi_qla_host_t *, uint32_t, uint32_t, uint32_t, nvram160_t *);
-STATIC void qla12160_get_target_parameters(scsi_qla_host_t *, uint32_t, uint32_t, uint32_t);
-
-#if QL1280_TARGET_MODE_SUPPORT
-STATIC void      qla1280_enable_lun(scsi_qla_host_t *, uint8_t, uint32_t),
-                 qla1280_notify_ack(scsi_qla_host_t *, notify_entry_t *),
-                 qla1280_immed_notify(scsi_qla_host_t *, notify_entry_t *),
-                 qla1280_accept_io(scsi_qla_host_t *, ctio_ret_entry_t *),
-#if  QLA1280_64BIT_SUPPORT
-                 qla1280_64bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t,
-                                     paddr32_t *),
-#endif
-                 qla1280_32bit_continue_io(scsi_qla_host_t *, atio_entry_t *, uint32_t,
-                                     paddr32_t *),
-                 qla1280_atio_entry(scsi_qla_host_t *, atio_entry_t *),
-                 qla1280_notify_entry(scsi_qla_host_t *, notify_entry_t *);
-#endif  /* QLA1280_TARGET_MODE_SUPPORT */
-
-#ifdef QL_DEBUG_ROUTINES
-/*
- *  Driver Debug Function Prototypes.
- */
-STATIC uint8_t  qla1280_getbyte(uint8_t *);
-STATIC uint16_t qla1280_getword(uint16_t *);
-STATIC uint32_t qla1280_getdword(uint32_t *);
-STATIC void     qla1280_putbyte(uint8_t *, uint8_t),
-                qla1280_putword(uint16_t *, uint16_t),
-                qla1280_putdword(uint32_t *, uint32_t),
-                qla1280_print(caddr_t),
-                qla1280_output_number(uint32_t, uint8_t),
-                qla1280_putc(uint8_t),
-                qla1280_dump_buffer(caddr_t, uint32_t);
-
-char          debug_buff[80];
-#if DEBUG_QLA1280 
-STATIC uint8_t ql_debug_print = 1;
-#else
-STATIC uint8_t ql_debug_print = 0;
+static int qla1280_initialize_adapter(struct scsi_qla_host *ha);
+static int qla1280_isp_firmware(struct scsi_qla_host *);
+static int qla1280_pci_config(struct scsi_qla_host *);
+static int qla1280_chip_diag(struct scsi_qla_host *);
+static int qla1280_setup_chip(struct scsi_qla_host *);
+static int qla1280_init_rings(struct scsi_qla_host *);
+static int qla1280_nvram_config(struct scsi_qla_host *);
+static int qla1280_mailbox_command(struct scsi_qla_host *,
+				   uint8_t, uint16_t *);
+static int qla1280_bus_reset(struct scsi_qla_host *, int);
+static int qla1280_device_reset(struct scsi_qla_host *, int, int);
+static int qla1280_abort_device(struct scsi_qla_host *, int, int, int);
+static int qla1280_abort_command(struct scsi_qla_host *, struct srb *, int);
+static int qla1280_abort_isp(struct scsi_qla_host *);
+static int qla1280_64bit_start_scsi(struct scsi_qla_host *, struct srb *);
+static int qla1280_32bit_start_scsi(struct scsi_qla_host *, struct srb *);
+static void qla1280_nv_write(struct scsi_qla_host *, uint16_t);
+static void qla1280_poll(struct scsi_qla_host *);
+static void qla1280_reset_adapter(struct scsi_qla_host *);
+static void qla1280_marker(struct scsi_qla_host *, int, int, int, u8);
+static void qla1280_isp_cmd(struct scsi_qla_host *);
+irqreturn_t qla1280_intr_handler(int, void *, struct pt_regs *);
+static void qla1280_isr(struct scsi_qla_host *, struct srb **, struct srb **);
+static void qla1280_rst_aen(struct scsi_qla_host *);
+static void qla1280_status_entry(struct scsi_qla_host *, struct response *,
+				 struct srb **, struct srb **);
+static void qla1280_error_entry(struct scsi_qla_host *, struct response *,
+				struct srb **, struct srb **);
+static uint16_t qla1280_get_nvram_word(struct scsi_qla_host *, uint32_t);
+static uint16_t qla1280_nvram_request(struct scsi_qla_host *, uint32_t);
+static uint16_t qla1280_debounce_register(volatile uint16_t *);
+static request_t *qla1280_req_pkt(struct scsi_qla_host *);
+static int qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *,
+					   unsigned int);
+static int qla1280_mem_alloc(struct scsi_qla_host *ha);
+
+static void qla12160_get_target_parameters(struct scsi_qla_host *,
+					   Scsi_Device *);
+static int qla12160_set_target_parameters(struct scsi_qla_host *, int, int);
+
+
+static struct qla_driver_setup driver_setup __initdata;
+
+/*
+ * convert scsi data direction to request_t control flags
+ */
+static inline uint16_t
+qla1280_data_direction(struct scsi_cmnd *cmnd)
+{
+	uint16_t flags = 0;
+
+	switch(cmnd->sc_data_direction) {
+
+	case SCSI_DATA_NONE:
+		flags = 0;
+		break;
+
+	case SCSI_DATA_READ:
+		flags = BIT_5;
+		break;
+
+	case SCSI_DATA_WRITE:
+		flags = BIT_6;
+		break;
+
+	case SCSI_DATA_UNKNOWN:
+	default:
+		flags = BIT_5 | BIT_6;
+		break;
+	}
+	return flags;
+}
+		
+#if QL1280_LUN_SUPPORT
+static void qla1280_enable_lun(struct scsi_qla_host *, int, int);
 #endif
+
+#if DEBUG_QLA1280
+static void __qla1280_print_scsi_cmd(Scsi_Cmnd * cmd);
+static void __qla1280_dump_buffer(char *, int);
 #endif
 
+
 /*
  * insmod needs to find the variable and make it point to something
  */
 #ifdef MODULE
-static char *options = NULL;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,18)
+static char *qla1280;
 
 /* insmod qla1280 options=verbose" */
-MODULE_PARM(options, "s");  
+MODULE_PARM(qla1280, "s");
+#else
+__setup("qla1280=", qla1280_setup);
 #endif
-/*
- * Just in case someone uses commas to separate items on the insmod
- * command line, we define a dummy buffer here to avoid having insmod
- * write wild stuff into our code segment
- */
-static char dummy_buffer[60] = "Please don't add commas in your insmod command!!\n";
 
-#endif
+MODULE_LICENSE("GPL");
+
 
 /* We use the Scsi_Pointer structure that's included with each command
  * SCSI_Cmnd as a scratchpad for our SRB.
@@ -440,122 +567,88 @@
  *  - SCp.phase --> not used
  */
 
-#define	CMD_SP(Cmnd)		(&(Cmnd)->SCp)
-#define	CMD_XFRLEN(Cmnd)	(Cmnd)->request_bufflen
-#define	CMD_CDBLEN(Cmnd)	(Cmnd)->cmd_len
-#define	CMD_CDBP(Cmnd)		(Cmnd)->cmnd
-#define	CMD_SNSP(Cmnd)		(Cmnd)->sense_buffer
-#define	CMD_SNSLEN(Cmnd)	(sizeof (Cmnd)->sense_buffer)
-#define	CMD_RESULT(Cmnd)	((Cmnd)->result)
-#define	CMD_HANDLE(Cmnd)	((Cmnd)->host_scribble)
+#define	CMD_SP(Cmnd)		&Cmnd->SCp
+#define	CMD_CDBLEN(Cmnd)	Cmnd->cmd_len
+#define	CMD_CDBP(Cmnd)		Cmnd->cmnd
+#define	CMD_SNSP(Cmnd)		Cmnd->sense_buffer
+#define	CMD_SNSLEN(Cmnd)	sizeof(Cmnd->sense_buffer)
+#define	CMD_RESULT(Cmnd)	Cmnd->result
+#define	CMD_HANDLE(Cmnd)	Cmnd->host_scribble
+#if LINUX_VERSION_CODE < 0x020545
+#define	CMD_HOST(Cmnd)		Cmnd->host
+#define CMD_REQUEST(Cmnd)	Cmnd->request.cmd
+#define SCSI_BUS_32(Cmnd)	Cmnd->channel
+#define SCSI_TCN_32(Cmnd)	Cmnd->target
+#define SCSI_LUN_32(Cmnd)	Cmnd->lun
+#else
+#define	CMD_HOST(Cmnd)		Cmnd->device->host
+#define CMD_REQUEST(Cmnd)	Cmnd->request->cmd
+#define SCSI_BUS_32(Cmnd)	Cmnd->device->channel
+#define SCSI_TCN_32(Cmnd)	Cmnd->device->id
+#define SCSI_LUN_32(Cmnd)	Cmnd->device->lun
+#endif
 
 /*****************************************/
 /*   ISP Boards supported by this driver */
 /*****************************************/
-#define QLA1280_VENDOR_ID   0x1077
-#define QLA1080_DEVICE_ID   0x1080
-#define QLA1240_DEVICE_ID   0x1240
-#define QLA1280_DEVICE_ID   0x1280
-#define QLA12160_DEVICE_ID  0x1216
-#define QLA10160_DEVICE_ID  0x1016
-#define NUM_OF_ISP_DEVICES        6
-
-typedef struct _qlaboards 
-{
-   unsigned char   bdName[9];       /* Board ID String */
-   unsigned long   device_id;       /* Device PCI ID   */
-   int   numPorts;                  /* Number of SCSI ports */
-   unsigned short   *fwcode;        /* pointer to FW array         */
-   unsigned long    *fwlen;         /* number of words in array    */
-   unsigned short   *fwstart;       /* start address for F/W       */
-   unsigned char   *fwver;          /* Ptr to F/W version array    */
-} qla_boards_t;
-
-struct _qlaboards   QLBoardTbl[NUM_OF_ISP_DEVICES] = 
-{
-   /* Name ,  Board PCI Device ID,         Number of ports */
-  {"QLA1080 ", QLA1080_DEVICE_ID,           1,        
-               &fw1280ei_code01[0],  (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] },       
-  {"QLA1240 ", QLA1240_DEVICE_ID,           2,       
-               &fw1280ei_code01[0],  (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] },       
-  {"QLA1280 ", QLA1280_DEVICE_ID,           2,      
-               &fw1280ei_code01[0],  (unsigned long *)&fw1280ei_length01,&fw1280ei_addr01, &fw1280ei_version_str[0] },       
-  {"QLA12160 ", QLA12160_DEVICE_ID,          2,      
-               &fw12160i_code01[0],  (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] },       
-  {"QLA10160 ", QLA10160_DEVICE_ID,          1,      
-               &fw12160i_code01[0],  (unsigned long *)&fw12160i_length01,&fw12160i_addr01, &fw12160i_version_str[0] },       
-  {"        ",                 0,           0}
-};
 
-static unsigned long qla1280_verbose = 1L;
-static scsi_qla_host_t *qla1280_hostlist = NULL;
-#ifdef QLA1280_PROFILE
-static int qla1280_buffer_size = 0;
-static char *qla1280_buffer = NULL;
-#endif
-
-#ifdef QL_DEBUG_LEVEL_3 
-#define ENTER(x)	sprintf(debug_buff,"qla1280 : Entering %s()\n\r", x); \
-                        qla1280_print(debug_buff);
-#define LEAVE(x)	sprintf(debug_buff,"qla1280 : Leaving %s()\n\r", x); \
-                        qla1280_print(debug_buff);
-#define ENTER_INTR(x)	sprintf(debug_buff,"qla1280 : Entering %s()\n\r", x); \
-                        qla1280_print(debug_buff);
-#define LEAVE_INTR(x)	sprintf(debug_buff,"qla1280 : Leaving %s()\n\r", x); \
-                        qla1280_print(debug_buff);
-#define DEBUG3(x)	x
-#else
-#define ENTER(x)
-#define LEAVE(x)
-#define ENTER_INTR(x)
-#define LEAVE_INTR(x)
-#define DEBUG3(x)
-#endif
+#define NUM_OF_ISP_DEVICES	6
 
-#if  DEBUG_QLA1280  
-#define COMTRACE(x)
-/* #define COMTRACE(x)     qla1280_putc(x); */
-#define DEBUG(x)	x
-#else
-#define DEBUG(x)
-#define COMTRACE(x)
-#endif
+struct qla_boards {
+	unsigned char name[9];	/* Board ID String */
+	unsigned long device_id;	/* Device PCI ID   */
+	int numPorts;		/* Number of SCSI ports */
+	unsigned short *fwcode;	/* pointer to FW array         */
+	unsigned short *fwlen;	/* number of words in array    */
+	unsigned short *fwstart;	/* start address for F/W       */
+	unsigned char *fwver;	/* Ptr to F/W version array    */
+};
 
-#ifdef QL_DEBUG_LEVEL_2 
-#define DEBUG2(x)	x
-#else
-#define DEBUG2(x)
-#endif
-#define DEBUG5(x)
+struct qla_boards ql1280_board_tbl[NUM_OF_ISP_DEVICES] = {
+	/* Name ,  Board PCI Device ID,         Number of ports */
+	{"QLA12160", PCI_DEVICE_ID_QLOGIC_ISP12160, 2,
+	 &fw12160i_code01[0], &fw12160i_length01,
+	 &fw12160i_addr01, &fw12160i_version_str[0]},
+	{"QLA1080", PCI_DEVICE_ID_QLOGIC_ISP1080, 1,
+	 &fw1280ei_code01[0], &fw1280ei_length01,
+	 &fw1280ei_addr01, &fw1280ei_version_str[0]},
+	{"QLA1240", PCI_DEVICE_ID_QLOGIC_ISP1240, 2,
+	 &fw1280ei_code01[0], &fw1280ei_length01,
+	 &fw1280ei_addr01, &fw1280ei_version_str[0]},
+	{"QLA1280", PCI_DEVICE_ID_QLOGIC_ISP1280, 2,
+	 &fw1280ei_code01[0], &fw1280ei_length01,
+	 &fw1280ei_addr01, &fw1280ei_version_str[0]},
+	{"QLA10160", PCI_DEVICE_ID_QLOGIC_ISP10160, 1,
+	 &fw12160i_code01[0], &fw12160i_length01,
+	 &fw12160i_addr01, &fw12160i_version_str[0]},
+	{"        ", 0, 0}
+};
 
-#if (BITS_PER_LONG==64)
-#   define OFFSET(w)   (((uint64_t) &w) & 0xFF)   /* 256 byte offsets */
+static int qla1280_verbose = 1;
+static struct scsi_qla_host *qla1280_hostlist;
+static int qla1280_buffer_size;
+static char *qla1280_buffer;
+
+#if DEBUG_QLA1280
+static int ql_debug_level = 1;
+#define dprintk(level, format, a...)	\
+	do { if (ql_debug_level >= level) printk(KERN_ERR format, ##a); } while(0)
+#define qla1280_dump_buffer(level, buf, size)	\
+	if (ql_debug_level >= level) __qla1280_dump_buffer(buf, size)
+#define qla1280_print_scsi_cmd(level, cmd)	\
+	if (ql_debug_level >= level) __qla1280_print_scsi_cmd(cmd)
 #else
-#   define OFFSET(w)   (((uint32_t) &w) & 0xFF)   /* 256 byte offsets */
+#define ql_debug_level			0
+#define dprintk(level, format, a...)	do{}while(0)
+#define qla1280_dump_buffer(a, b, c)	do{}while(0)
+#define qla1280_print_scsi_cmd(a, b)	do{}while(0)
 #endif
 
-#define SCSI_BUS_32(scp)   ((scp)->channel)
-#define SCSI_TCN_32(scp)    ((scp)->target)
-#define SCSI_LUN_32(scp)    ((scp)->lun)
-
-/****************************************************************************/
-/*  LINUX -  Loadable Module Functions.                                     */
-/****************************************************************************/
-
+#define ENTER(x)		dprintk(3, "qla1280 : Entering %s()\n", x);
+#define LEAVE(x)		dprintk(3, "qla1280 : Leaving %s()\n", x);
+#define ENTER_INTR(x)		dprintk(4, "qla1280 : Entering %s()\n", x);
+#define LEAVE_INTR(x)		dprintk(4, "qla1280 : Leaving %s()\n", x);
 
-/*************************************************************************
- *   qla1280_set_info
- *
- * Description:
- *   Set parameters for the driver from the /proc filesystem.
- *
- * Returns:
- *************************************************************************/
-int
-qla1280_set_info(char *buffer, int length, struct Scsi_Host *HBAptr)
-{
-  return (-ENOSYS);  /* Currently this is a no-op */
-}
 
 /*************************************************************************
  * qla1280_proc_info
@@ -567,464 +660,549 @@
  *
  * Returns:
  *************************************************************************/
-#ifdef QLA1280_PROFILE
-#define	PROC_BUF	(&qla1280_buffer[size])
-#define LUN_ID       (targ_lun>>(MAX_T_BITS+MAX_L_BITS)),((targ_lun>>MAX_L_BITS)&0xf), targ_lun&0x7 
-#endif
-int
-qla1280_proc_info ( char *buffer, char **start, off_t offset, int length, 
-                    int hostno, int inout)
-{
-#ifdef QLA1280_PROFILE
-  struct Scsi_Host *host;
-  scsi_qla_host_t *ha;
-  int    size = 0;
-  int  targ_lun;
-  scsi_lu_t  *up;
-  int   no_devices;
-
-  printk("Entering proc_info 0x%p,0x%lx,0x%x,0x%x\n",buffer,offset,length,hostno);
-  host = NULL;
-  /* find the host they want to look at */
-  for(ha=qla1280_hostlist; (ha != NULL) && ha->host->host_no != hostno; ha=ha->next)
-    ;
-
-  if (!ha)
-  {
-    size += sprintf(buffer, "Can't find adapter for host number %d\n", hostno);
-    if (size > length)
-    {
-      return (size);
-    }
-    else
-    {
-      return (length);
-    }
-  }
-
-  host = ha->host;
-  if (inout == TRUE) /* Has data been written to the file? */ 
-  {
-    return (qla1280_set_info(buffer, length, host));
-  }
-
-  /* compute number of active devices */
-  no_devices = 0;
-  for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++)
-  {
-          if( (up = ha->dev[targ_lun]) == NULL )
-              continue;
-          no_devices++;
-  }
-  /* size = 112 * no_devices; */
-  size = 4096;
-  /* round up to the next page */
-  
-  /* 
-   * if our old buffer is the right size use it otherwise 
-   * allocate a new one.
-   */
-  if (qla1280_buffer_size != size)
-  {
-    /* deallocate this buffer and get a new one */
-    if (qla1280_buffer != NULL) 
-    {
-      kfree(qla1280_buffer);
-      qla1280_buffer_size = 0;
-    }
-    qla1280_buffer = kmalloc(size, GFP_KERNEL);
-  }
-  if (qla1280_buffer == NULL)
-  {
-    size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n",
-        __LINE__);
-    return size;
-  }
-  qla1280_buffer_size = size;
-
-  size = 0;
-  size += sprintf(PROC_BUF, "Qlogic 1280/1080 SCSI driver version: ");   /* 43 bytes */
-  size += sprintf(PROC_BUF, "%5s, ", QLA1280_VERSION);                         /* 5        */
-  size += sprintf(PROC_BUF, "Qlogic Firmware version: ");                     /* 25       */
-  size += sprintf(PROC_BUF, "%2d.%2d.%2d",_firmware_version[0],           /* 8        */
-                                          ql12_firmware_version[1],
-                                          ql12_firmware_version[2]);
-  size += sprintf(PROC_BUF, "\n");                                             /* 1       */
-                           
-  size += sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n", QLBoardTbl[ha->devnum].bdName);
-  size += sprintf(PROC_BUF, "Request Queue = 0x%lx, Response Queue = 0x%lx\n",
-                        ha->request_dma,
-                        ha->response_dma);
-  size += sprintf(PROC_BUF, "Request Queue count= 0x%x, Response Queue count= 0x%x\n",
-                        REQUEST_ENTRY_CNT,
-                        RESPONSE_ENTRY_CNT);
-  size += sprintf(PROC_BUF,"Number of pending commands = 0x%lx\n", ha->actthreads);
-  size += sprintf(PROC_BUF,"Number of queued commands = 0x%lx\n", ha->qthreads);
-  size += sprintf(PROC_BUF,"Number of free request entries = %d\n",ha->req_q_cnt);
-  size += sprintf(PROC_BUF, "\n");                                             /* 1       */
-                        
-  size += sprintf(PROC_BUF, "Attached devices:\n");
-  /* scan for all equipment stats */ 
-  for (targ_lun = 0; targ_lun < MAX_EQ; targ_lun++)
-  {
-      if( (up = ha->dev[targ_lun]) == NULL )
-           continue;
-      if( up->io_cnt == 0 )
-      {
-          size += sprintf(PROC_BUF,"(%2d:%2d:%2d) No stats\n",LUN_ID);
-           continue;
-      }
-      /* total reads since boot */
-      /* total writes since boot */
-      /* total requests since boot  */
-      size += sprintf(PROC_BUF, "Total requests %ld,",up->io_cnt);
-      /* current number of pending requests */
-      size += sprintf(PROC_BUF, "(%2d:%2d:%2d) pending requests %d,",LUN_ID,up->q_outcnt);
-      /* avg response time */
-      size += sprintf(PROC_BUF, "Avg response time %ld%%,",(up->resp_time/up->io_cnt)*100);
-      
-      /* avg active time */
-      size += sprintf(PROC_BUF, "Avg active time %ld%%\n",(up->act_time/up->io_cnt)*100);
-  }
-
-  if (size >= qla1280_buffer_size)
-  {
-    printk(KERN_WARNING "qla1280: Overflow buffer in qla1280_proc.c\n");
-  }
-
-  if (offset > size - 1)
-  {
-    kfree(qla1280_buffer);
-    qla1280_buffer = NULL;
-    qla1280_buffer_size = length = 0;
-    *start = NULL;
-  }
-  else
-  {
-    *start = &qla1280_buffer[offset];   /* Start of wanted data */
-    if (size - offset < length)
-    {
-      length = size - offset;
-    }
-  }
+#define	PROC_BUF	&qla1280_buffer[len]
+
+#if LINUX_VERSION_CODE < 0x020600
+static int qla1280_proc_info(char *buffer, char **start, off_t offset,
+			     int length, int hostno, int inout)
+#else
+static int qla1280_proc_info(struct Scsi_Host *host, char *buffer,
+			     char **start, off_t offset, int length, int inout)
+#endif
+{
+	struct scsi_qla_host *ha;
+	int size = 0;
+	int len = 0;
+	struct qla_boards *bdp;
+#ifdef BOGUS_QUEUE
+	struct scsi_lu *up;
+	uint32_t b, t, l;
+#endif
+#if LINUX_VERSION_CODE >= 0x020600
+	ha = (struct scsi_qla_host *)host->hostdata;
+#else
+	struct Scsi_Host *host;
+	/* Find the host that was specified */
+	for (ha = qla1280_hostlist; (ha != NULL)
+		     && ha->host->host_no != hostno; ha = ha->next) ;
+
+	/* if host wasn't found then exit */
+	if (!ha) {
+		size =  sprintf(buffer, "Can't find adapter for host "
+				"number %d\n", hostno);
+		if (size > length) {
+			return size;
+		} else {
+			return 0;
+		}
+	}
+
+	host = ha->host;
+#endif
+
+	if (inout)
+		return -ENOSYS;
+
+	/*
+	 * if our old buffer is the right size use it otherwise
+	 * allocate a new one.
+	 */
+	if (qla1280_buffer_size != PAGE_SIZE) {
+		/* deallocate this buffer and get a new one */
+		if (qla1280_buffer != NULL) {
+			free_page((unsigned long)qla1280_buffer);
+			qla1280_buffer_size = 0;
+		}
+		qla1280_buffer = (char *)get_zeroed_page(GFP_KERNEL);
+	}
+	if (qla1280_buffer == NULL) {
+		size = sprintf(buffer, "qla1280 - kmalloc error at line %d\n",
+			       __LINE__);
+		return size;
+	}
+	/* save the size of our buffer */
+	qla1280_buffer_size = PAGE_SIZE;
+
+	/* 3.20 clear the buffer we use for proc display */
+	memset(qla1280_buffer, 0, PAGE_SIZE);
+
+	/* start building the print buffer */
+	bdp = &ql1280_board_tbl[ha->devnum];
+	size = sprintf(PROC_BUF,
+		       "QLogic PCI to SCSI Adapter for ISP 1280/12160:\n"
+		       "        Firmware version: %2d.%02d.%02d, Driver version %s\n",
+		       bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
+		       QLA1280_VERSION);
+
+	len += size;
+
+	size = sprintf(PROC_BUF, "SCSI Host Adapter Information: %s\n",
+		       bdp->name);
+	len += size;
+	size = sprintf(PROC_BUF, "Request Queue count= 0x%x, Response "
+		       "Queue count= 0x%x\n",
+		       REQUEST_ENTRY_CNT, RESPONSE_ENTRY_CNT);
+	len += size;
+	size = sprintf(PROC_BUF, "Number of pending commands = 0x%lx\n",
+		       ha->actthreads);
+	len += size;
+	size = sprintf(PROC_BUF, "Number of free request entries = %d\n",
+		       ha->req_q_cnt);
+	len += size;
+	size = sprintf(PROC_BUF, "\n");	/* 1       */
+	len += size;
+
+	size = sprintf(PROC_BUF, "SCSI device Information:\n");
+	len += size;
+#ifdef BOGUS_QUEUE
+	/* scan for all equipment stats */
+	for (b = 0; b < MAX_BUSES; b++)
+		for (t = 0; t < MAX_TARGETS; t++) {
+			for (l = 0; l < MAX_LUNS; l++) {
+				up = LU_Q(ha, b, t, l);
+				if (up == NULL)
+					continue;
+				/* unused device/lun */
+				if (up->io_cnt == 0 || up->io_cnt < 2)
+					continue;
+				/* total reads since boot */
+				/* total writes since boot */
+				/* total requests since boot  */
+				size = sprintf (PROC_BUF,
+						"(%2d:%2d:%2d): Total reqs %ld,",
+						b, t, l, up->io_cnt);
+				len += size;
+				/* current number of pending requests */
+				size =	sprintf(PROC_BUF, " Pend reqs %d,",
+						up->q_outcnt);
+				len += size;
+#if 0
+				/* avg response time */
+				size = sprintf(PROC_BUF, " Avg resp time %ld%%,",
+					       (up->resp_time / up->io_cnt) *
+					       100);
+				len += size;
+
+				/* avg active time */
+				size = sprintf(PROC_BUF,
+					       " Avg active time %ld%%\n",
+					       (up->act_time / up->io_cnt) * 100);
+#else
+				size = sprintf(PROC_BUF, "\n");
 #endif
+				len += size;
+			}
+			if (len >= qla1280_buffer_size)
+				break;
+		}
+#endif
+
+	if (len >= qla1280_buffer_size) {
+		printk(KERN_WARNING
+		       "qla1280: Overflow buffer in qla1280_proc.c\n");
+	}
+
+	if (offset > len - 1) {
+		free_page((unsigned long) qla1280_buffer);
+		qla1280_buffer = NULL;
+		qla1280_buffer_size = length = 0;
+		*start = NULL;
+	} else {
+		*start = &qla1280_buffer[offset];	/* Start of wanted data */
+		if (len - offset < length) {
+			length = len - offset;
+		}
+	}
+	return length;
+}
+
+
+static int qla1280_read_nvram(struct scsi_qla_host *ha)
+{
+	uint16_t *wptr;
+	uint8_t chksum;
+	int cnt;
+	struct nvram *nv;
+
+	ENTER("qla1280_read_nvram");
+
+	if (driver_setup.no_nvram)
+		return 1;
+
+	printk(KERN_INFO "scsi(%ld): Reading NVRAM\n", ha->host_no);
+
+	wptr = (uint16_t *)&ha->nvram;
+	nv = &ha->nvram;
+	chksum = 0;
+	for (cnt = 0; cnt < 3; cnt++) {
+		*wptr = qla1280_get_nvram_word(ha, cnt);
+		chksum += *wptr & 0xff;
+		chksum += (*wptr >> 8) & 0xff;
+		wptr++;
+	}
 
-  return (length);
+	if (nv->id0 != 'I' || nv->id1 != 'S' ||
+	    nv->id2 != 'P' || nv->id3 != ' ' || nv->version < 1) {
+		dprintk(2, "Invalid nvram ID or version!\n");
+		chksum = 1;
+	} else {
+		for (; cnt < sizeof(struct nvram); cnt++) {
+			*wptr = qla1280_get_nvram_word(ha, cnt);
+			chksum += *wptr & 0xff;
+			chksum += (*wptr >> 8) & 0xff;
+			wptr++;
+		}
+	}
+
+	dprintk(3, "qla1280_read_nvram: NVRAM Magic ID= %c %c %c %02x"
+	       " version %i\n", nv->id0, nv->id1, nv->id2, nv->id3,
+	       nv->version);
+
+
+	if (chksum) {
+		if (!driver_setup.no_nvram)
+			printk(KERN_WARNING "scsi(%ld): Unable to identify or "
+			       "validate NVRAM checksum, using default "
+			       "settings\n", ha->host_no);
+		ha->nvram_valid = 0;
+	} else
+		ha->nvram_valid = 1;
+
+	dprintk(1, "qla1280_read_nvram: Completed Reading NVRAM\n");
+	LEAVE("qla1280_read_nvram");
+
+	return chksum;
 }
 
 
 /**************************************************************************
- * qla1280_detect
- *    This routine will probe for Qlogic 1280 SCSI host adapters.
- *    It returns the number of host adapters of a particular
- *    type that were found.	 It also initialize all data necessary for 
- *    the driver.  It is passed-in the host number, so that it
- *    knows where its first entry is in the scsi_hosts[] array.
+ * qla1280_do_device_init
+ *    This routine will register the device with the SCSI subsystem,
+ *    initialize the host adapter structure and call the device init
+ *    routines.
  *
  * Input:
- *     template - pointer to SCSI template
+ *     pdev      - pointer to struct pci_dev for adapter
+ *     template  - pointer to SCSI template
+ *     devnum    - the device number
+ *     bdp       - pointer to struct _qlaboards
+ *     num_hosts - the host number
  *
  * Returns:
- *  num - number of host adapters found.  
+ *  host - pointer to SCSI host structure
  **************************************************************************/
-int
-qla1280_detect(Scsi_Host_Template *template)
-{
-    int num_hosts = 0;
-    struct Scsi_Host *host;
-    scsi_qla_host_t *ha, *cur_ha;
-    struct _qlaboards  *bdp;
-    int i, j;
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,95)
-    unsigned int piobase;
-    unsigned char pci_bus, pci_devfn, pci_irq;
-    config_reg_t   *cfgp = 0;
-#endif
-    device_reg_t   *reg;
-    char   *cp;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-    struct pci_dev *pdev = NULL;
+struct Scsi_Host *
+qla1280_do_device_init(struct pci_dev *pdev, Scsi_Host_Template * template,
+		       int devnum, struct qla_boards *bdp, int num_hosts)
+{
+	struct Scsi_Host *host;
+	struct scsi_qla_host *ha;
+
+	printk(KERN_INFO "qla1280: %s found on PCI bus %i, dev %i\n",
+	       bdp->name, pdev->bus->number, PCI_SLOT(pdev->devfn));
+
+	host = scsi_register(template, sizeof(struct scsi_qla_host));
+	if (!host) {
+		printk(KERN_WARNING
+		       "qla1280: Failed to register host, aborting.\n");
+		goto error;
+	}
+
+#if LINUX_VERSION_CODE < 0x020545
+	scsi_set_pci_device(host, pdev);
 #else
-    int index;
+	scsi_set_device(host, &pdev->dev);
 #endif
+	ha = (struct scsi_qla_host *)host->hostdata;
+	/* Clear our data area */
+	memset(ha, 0, sizeof(struct scsi_qla_host));
+	/* Sanitize the information from PCI BIOS.  */
+	host->irq = pdev->irq;
+	ha->pci_bus = pdev->bus->number;
+	ha->pci_device_fn = pdev->devfn;
+	ha->pdev = pdev;
+	ha->device_id = bdp->device_id;
+	ha->devnum = devnum;	/* specifies microcode load address */
+
+	if (qla1280_mem_alloc(ha)) {
+		printk(KERN_INFO "qla1x160: Failed to get memory\n");
+		goto error_scsi_unregister;
+	}
 
-    ENTER("qla1280_detect");
+	ha->ports = bdp->numPorts;
+	/* following needed for all cases of OS versions */
+	ha->host = host;
+	ha->host_no = host->host_no;
 
-#ifdef CHECKSRBSIZE
-    if (sizeof(srb_t) > sizeof(Scsi_Pointer) )
-    {
-      printk("Redefine SRB - its too big");
-      return 0;
-    }
+	host->can_queue = 0xfffff;	/* unlimited  */
+	host->cmd_per_lun = 1;
+	host->base = (unsigned long)ha->mmpbase;
+	host->max_channel = bdp->numPorts - 1;
+	host->max_lun = MAX_LUNS - 1;
+	host->max_id = MAX_TARGETS;
+	host->max_sectors = 1024;
+#if LINUX_VERSION_CODE < 0x020545
+	host->select_queue_depths = qla1280_select_queue_depth;
 #endif
 
-#ifdef MODULE
-	DEBUG(sprintf(debug_buff,"DEBUG: qla1280_detect starts at address = %p\n",qla1280_detect);)
-	DEBUG(qla1280_print(debug_buff);)
-    /*
-    * If we are called as a module, the qla1280 pointer may not be null
-    * and it would point to our bootup string, just like on the lilo
-    * command line.  IF not NULL, then process this config string with
-    * qla1280_setup
-    *
-    * Boot time Options
-    * To add options at boot time add a line to your lilo.conf file like:
-    * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
-    * which will result in the first four devices on the first two
-    * controllers being set to a tagged queue depth of 32.
-    */
-    if(options)
-        qla1280_setup(options, NULL);
-    if(dummy_buffer[0] != 'P')
-        printk(KERN_WARNING "qla1280: Please read the file /usr/src/linux/drivers"
-                "/scsi/README.qla1280\n"
-                "qla1280: to see the proper way to specify options to the qla1280 "
-                "module\n"
-                "qla1280: Specifically, don't use any commas when passing arguments to\n"
-                "qla1280: insmod or else it might trash certain memory areas.\n");
-#endif
-
-    if ((int) !pcibios_present())
-    {
-		printk("scsi: PCI not present\n");
-		return 0;
-    } /* end of IF */
-    bdp = &QLBoardTbl[0];
-    qla1280_hostlist = NULL;
-#if 0
-    template->proc_dir = &proc_scsi_qla1280;
-#else
-    template->proc_name = "qla1280";
+	ha->instance = num_hosts;
+	host->unique_id = ha->instance;
+
+	if (qla1280_pci_config(ha)) {
+		printk(KERN_INFO "qla1x160: Unable to configure PCI\n");
+		goto error_mem_alloced;
+	}
+
+	/* Disable ISP interrupts. */
+	qla1280_disable_intrs(ha);
+
+	/* Register the IRQ with Linux (sharable) */
+	if (request_irq(host->irq, qla1280_intr_handler, SA_SHIRQ,
+			"qla1280", ha)) {
+		printk("qla1280 : Failed to reserve interrupt %d already "
+		       "in use\n", host->irq);
+		goto error_iounmap;
+	}
+#if !MEMORY_MAPPED_IO
+	/* Register the I/O space with Linux */
+	if (!request_region(host->io_port, 0xff, "qla1280")) {
+		printk("qla1280: Failed to reserve i/o region 0x%04lx-0x%04lx"
+		       " already in use\n",
+		       host->io_port, host->io_port + 0xff);
+		goto error_free_irq;
+	}
 #endif
-    
-	/* Try and find each different type of adapter we support */
-	for( i=0; bdp->device_id != 0 && i < NUM_OF_ISP_DEVICES; i++, bdp++ ) {
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-		while ((pdev = pci_find_device(QLA1280_VENDOR_ID,
-			bdp->device_id, pdev ) ))  {
-		if (pci_enable_device(pdev)) continue;
-#else
-		while (!(pcibios_find_device(QLA1280_VENDOR_ID,
-			bdp->device_id,
-			index++, &pci_bus, &pci_devfn)) )  {
-#endif
-                /* found a adapter */
-		host = scsi_register(template, sizeof(scsi_qla_host_t));
-                if (!host) { 
-			printk(KERN_WARNING "qla1280: Failed to register host, aborting.\n");
-                        return 0;
-                }
-		scsi_set_pci_device(host, pdev);
-		ha = (scsi_qla_host_t *) host->hostdata;
-		/* Clear our data area */
-		for( j =0, cp = (char *)ha;  j < sizeof(scsi_qla_host_t); j++)
-			*cp = 0;
-		/* Sanitize the information from PCI BIOS.  */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-		host->irq = pdev->irq;
-		host->io_port = pci_resource_start(pdev, 0);
-		ha->pci_bus = pdev->bus->number;
-		ha->pci_device_fn = pdev->devfn;
-		ha->pdev = pdev;
-#else
-		pcibios_read_config_byte(pci_bus, pci_devfn, OFFSET(cfgp->interrupt_line), &pci_irq);
-		pcibios_read_config_dword(pci_bus, pci_devfn, OFFSET(cfgp->base_port), &piobase);
-		host->irq = pci_irq;
-		host->io_port = (unsigned int) piobase;
-		host->io_port &= PCI_BASE_ADDRESS_IO_MASK;
-		ha->pci_bus = pci_bus;
-		ha->pci_device_fn = pci_devfn;
-#endif
-		ha->device_id = bdp->device_id;
-    
-                ha->devnum = i;
-		if( qla1280_mem_alloc(ha) ) {
-			printk(KERN_INFO "qla1280: Failed to allocate memory for adapter\n");
-		}
-                
-                ha->ports = bdp->numPorts; 
-                ha->iobase = (device_reg_t *) host->io_port;
-                ha->host = host;
-                ha->host_no = host->host_no;
-
-                /* load the F/W, read paramaters, and init the H/W */
-                if (qla1280_initialize_adapter(ha))
-                {
-
-                    printk(KERN_INFO "qla1280: Failed to initialized adapter\n");
-                    qla1280_mem_free(ha);
-                    scsi_unregister(host);
-                    continue;
-                }
-                
-                host->max_channel = bdp->numPorts-1; 
-                ha->instance = num_hosts;
-		/* Register our resources with Linux */
-		if( qla1280_register_with_Linux(ha, bdp->numPorts-1) ) {
-			printk(KERN_INFO "qla1280: Failed to register our resources\n");
-			qla1280_mem_free(ha);
-			scsi_unregister(host);
-			continue;
-		}
 
+	/* load the F/W, read paramaters, and init the H/W */
+	if (qla1280_initialize_adapter(ha)) {
+		printk(KERN_INFO "qla1x160: Failed to initialize adapter\n");
+		goto error_release_region;
+	}
 
-                reg = ha->iobase;
-                /* Disable ISP interrupts. */
-		qla1280_disable_intrs(ha);
+	/* set our host ID  (need to do something about our two IDs) */
+	host->this_id = ha->bus_settings[0].id;
 
-                /* Insure mailbox registers are free. */
-                WRT_REG_WORD(&reg->semaphore, 0);
-                WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
-                WRT_REG_WORD(&reg->host_cmd, HC_CLR_HOST_INT);
-
-                /* Enable chip interrupts. */
-		qla1280_enable_intrs(ha);
-               
-                /* Insert new entry into the list of adapters */
-                ha->next = NULL;
-                if( qla1280_hostlist == NULL )
-                {
-                    cur_ha = qla1280_hostlist = ha;
-                }
-                else
-                {
-                    cur_ha = qla1280_hostlist;
-                    while( cur_ha->next != NULL )
-                        cur_ha = cur_ha->next;
-                    cur_ha->next = ha;
-                }
-                num_hosts++;
-            }  /* end of WHILE */
-        } /* end of FOR */
+	return host;
 
-    LEAVE("qla1280_detect");
-    return num_hosts; 
+ error_release_region:
+#if !MEMORY_MAPPED_IO
+	release_region(host->io_port, 0xff);
+ error_free_irq:
+#endif
+	free_irq(host->irq, ha);
+ error_iounmap:
+#if MEMORY_MAPPED_IO
+	if (ha->mmpbase)
+		iounmap((void *)(((unsigned long) ha->mmpbase) & PAGE_MASK));
+#endif
+ error_mem_alloced:
+	qla1280_mem_free(ha);
+ error_scsi_unregister:
+	scsi_unregister(host);
+ error:
+	return NULL;
 }
 
 /**************************************************************************
-*   qla1280_register_with_Linux
-*
-* Description:
-*   Free the passed in Scsi_Host memory structures prior to unloading the
-*   module.
-*
-* Input:
-*     ha - pointer to host adapter structure
-*     maxchannels - MAX number of channels.
-*
-* Returns:
-*  0 - Sucessfully reserved resources.
-*  1 - Failed to reserved a resource.
-**************************************************************************/
-STATIC uint8_t  qla1280_register_with_Linux(scsi_qla_host_t *ha, uint8_t maxchannels)
+ * qla1280_detect
+ *    This routine will probe for Qlogic 1280 SCSI host adapters.
+ *    It returns the number of host adapters of a particular
+ *    type that were found.	 It also initialize all data necessary for
+ *    the driver.  It is passed-in the host number, so that it
+ *    knows where its first entry is in the scsi_hosts[] array.
+ *
+ * Input:
+ *     template - pointer to SCSI template
+ *
+ * Returns:
+ *  num - number of host adapters found.
+ **************************************************************************/
+static int
+qla1280_detect(Scsi_Host_Template * template)
 {
+	struct pci_dev *pdev = NULL;
+	struct Scsi_Host *host;
+	struct scsi_qla_host *ha, *cur_ha;
+	struct qla_boards *bdp;
+	uint16_t subsys_vendor, subsys_device;
+	int num_hosts = 0;
+	int devnum = 0;
+
+	ENTER("qla1280_detect");
+
+	if (sizeof(struct srb) > sizeof(Scsi_Pointer)) {
+		printk(KERN_WARNING
+		       "qla1280_detect: [WARNING] struct srb too big\n");
+		return 0;
+	}
+#ifdef MODULE
+	/*
+	 * If we are called as a module, the qla1280 pointer may not be null
+	 * and it would point to our bootup string, just like on the lilo
+	 * command line.  IF not NULL, then process this config string with
+	 * qla1280_setup
+	 *
+	 * Boot time Options
+	 * To add options at boot time add a line to your lilo.conf file like:
+	 * append="qla1280=verbose,max_tags:{{255,255,255,255},{255,255,255,255}}"
+	 * which will result in the first four devices on the first two
+	 * controllers being set to a tagged queue depth of 32.
+	 */
+	if (qla1280)
+		qla1280_setup(qla1280);
+#endif
+
+	bdp = &ql1280_board_tbl[0];
+	qla1280_hostlist = NULL;
+	template->proc_name = "qla1280";
+
+	/* First Initialize QLA12160 on PCI Bus 1 Dev 2 */
+	while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC, bdp->device_id,
+				       PCI_ANY_ID, PCI_ANY_ID, pdev))) {
 
-	struct Scsi_Host *host = ha->host;
+		/* find QLA12160 device on PCI bus=1 slot=2 */
+		if ((pdev->bus->number != 1) || (PCI_SLOT(pdev->devfn) != 2))
+			continue;
 
-	host->can_queue = 0xfffff;  /* unlimited  */
-	host->cmd_per_lun = 1;
-       host->select_queue_depths = qla1280_select_queue_depth;
-	host->n_io_port = 0xFF;
-	host->base = (unsigned long) ha->mmpbase;
-	host->max_channel = maxchannels; 
-       host->max_lun = MAX_LUNS-1; 
-	host->unique_id = ha->instance;
-       host->max_id = MAX_TARGETS; 
-       host->unique_id = ha->instance;
+		/* Bypass all AMI SUBSYS VENDOR IDs */
+		if (pdev->subsystem_vendor == PCI_VENDOR_ID_AMI) {
+			printk(KERN_INFO
+			       "qla1x160: Skip AMI SubSys Vendor ID Chip\n");
+			continue;
+		}
 
-	/* set our host ID  (need to do something about our two IDs) */
-       host->this_id = ha->bus_settings[0].id;
-       /* Register the IRQ with Linux (sharable) */
-       if ( request_irq(host->irq, qla1280_intr_handler, SA_INTERRUPT| SA_SHIRQ, "qla1280", ha))
-       {
-          printk("qla1280 : Failed to reserved interrupt %d already in use\n", host->irq);
-          qla1280_mem_free(ha);
-          scsi_unregister(host);
-	     return 1;
-       }
-
-       /* Register the I/O space with Linux */
-       if (check_region(host->io_port, 0xff))
-       {
-           printk("qla1280 : Failed to reserved i/o region 0x%04lx-0x%04lx already in use\n",
-              host->io_port, host->io_port + 0xff);
-           free_irq(host->irq, NULL);
-           qla1280_mem_free(ha);
-           scsi_unregister(host);
-	     return 1;
-       }
+		if (pci_enable_device(pdev))
+			goto find_devices;
+
+		host = qla1280_do_device_init(pdev, template, devnum,
+					      bdp, num_hosts);
+		if (!host)
+			continue;
+		ha = (struct scsi_qla_host *)host->hostdata;
 
-       request_region(host->io_port, 0xff, "qla1280");
+		/* this preferred device will always be the first one found */
+		cur_ha = qla1280_hostlist = ha;
+		num_hosts++;
+	}
 
-	return 0;
-}
+ find_devices:
 
+	pdev = NULL;
+	/* Try and find each different type of adapter we support */
+	for (devnum = 0; bdp->device_id != 0 && devnum < NUM_OF_ISP_DEVICES;
+	     devnum++, bdp++) {
+		/* PCI_SUBSYSTEM_IDS supported */
+		while ((pdev = pci_find_subsys(PCI_VENDOR_ID_QLOGIC,
+					       bdp->device_id, PCI_ANY_ID,
+					       PCI_ANY_ID, pdev))) {
+			if (pci_enable_device(pdev))
+				continue;
+			/* found an adapter */
+			subsys_vendor = pdev->subsystem_vendor;
+			subsys_device = pdev->subsystem_device;
+
+			/*
+			 * skip QLA12160 already initialized on
+			 * PCI Bus 1 Dev 2 since we already initialized
+			 * and presented it
+			 */
+			if ((bdp->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160)&&
+			    (pdev->bus->number == 1) &&
+			    (PCI_SLOT(pdev->devfn) == 2))
+				continue;
+
+			/* Bypass all AMI SUBSYS VENDOR IDs */
+			if (subsys_vendor == PCI_VENDOR_ID_AMI) {
+				printk(KERN_INFO
+				       "qla1x160: Skip AMI SubSys Vendor ID Chip\n");
+				continue;
+			}
+			dprintk(1, "qla1x160: Supported Device Found VID=%x "
+			       "DID=%x SSVID=%x SSDID=%x\n", pdev->vendor,
+			       pdev->device, subsys_vendor, subsys_device);
+
+			host = qla1280_do_device_init(pdev, template,
+						      devnum, bdp, num_hosts);
+			if (!host)
+				continue;
+			ha = (struct scsi_qla_host *)host->hostdata;
+
+			if (qla1280_hostlist == NULL) {
+				cur_ha = qla1280_hostlist = ha;
+			} else {
+				cur_ha = qla1280_hostlist;
+				while (cur_ha->next != NULL)
+					cur_ha = cur_ha->next;
+				cur_ha->next = ha;
+			}
+			num_hosts++;
+		}		/* end of WHILE */
+	}			/* end of FOR */
+
+	LEAVE("qla1280_detect");
+	return num_hosts;
+}
 
 /**************************************************************************
  *   qla1280_release
  *   Free the passed in Scsi_Host memory structures prior to unloading the
  *   module.
  **************************************************************************/
-int
+static int
 qla1280_release(struct Scsi_Host *host)
 {
-    scsi_qla_host_t *ha = (scsi_qla_host_t *) host->hostdata;
-
-    ENTER("qla1280_release");
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
 
-    if( !ha->flags.online )
-        return(0);
+	ENTER("qla1280_release");
 
-    /* turn-off interrupts on the card */
-    WRT_REG_WORD(&ha->iobase->ictrl, 0);
+	if (!ha->flags.online)
+		return 0;
 
-    /* Detach interrupts */
-    if(host->irq)
-        free_irq(host->irq, ha);
+	/* turn-off interrupts on the card */
+	WRT_REG_WORD(&ha->iobase->ictrl, 0);
 
-    /* release io space registers  */
-    if( host->io_port )
-        release_region(host->io_port, 0xff);
+	/* Detach interrupts */
+	if (host->irq)
+		free_irq(host->irq, ha);
 
 #if MEMORY_MAPPED_IO
-    if(ha->mmpbase)
-    {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-        vfree((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK));
+	if (ha->mmpbase)
+		iounmap(ha->mmpbase);
 #else
-        iounmap((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK));
-#endif
-    }
-#endif /* MEMORY_MAPPED_IO */
-    qla1280_mem_free(ha);
+	/* release io space registers  */
+	if (host->io_port)
+		release_region(host->io_port, 0xff);
+#endif				/* MEMORY_MAPPED_IO */
 
-    ENTER("qla1280_release");
-    return(0);
+	qla1280_mem_free(ha);
+
+	ENTER("qla1280_release");
+	return 0;
 }
 
 /**************************************************************************
  *   qla1280_info
  *     Return a string describing the driver.
  **************************************************************************/
-const char *
+static const char *
 qla1280_info(struct Scsi_Host *host)
 {
-    static char qla1280_buffer[125];
-    char *bp;
-    scsi_qla_host_t *ha;
-    qla_boards_t   *bdp; 
-
-    bp = &qla1280_buffer[0];
-    ha = (scsi_qla_host_t *)host->hostdata;
-    bdp = &QLBoardTbl[ha->devnum];
-    memset(bp, 0, sizeof(qla1280_buffer));
-    sprintf(bp,
-            "QLogic %sPCI to SCSI Host Adapter: bus %d device %d irq %d\n"
-            "       Firmware version: %2d.%02d.%02d, Driver version %s",
-            (char *)&bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, host->irq,
-            bdp->fwver[0],bdp->fwver[1],bdp->fwver[2],
-            QLA1280_VERSION);
-    return(bp);
+	static char qla1280_scsi_name_buffer[125];
+	char *bp;
+	struct scsi_qla_host *ha;
+	struct qla_boards *bdp;
+
+	bp = &qla1280_scsi_name_buffer[0];
+	ha = (struct scsi_qla_host *)host->hostdata;
+	bdp = &ql1280_board_tbl[ha->devnum];
+	memset(bp, 0, sizeof(qla1280_scsi_name_buffer));
+	sprintf (bp,
+		 "QLogic %s PCI to SCSI Host Adapter: bus %d device %d irq %d\n"
+		 "       Firmware version: %2d.%02d.%02d, Driver version %s",
+		 &bdp->name[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3,
+		 host->irq, bdp->fwver[0], bdp->fwver[1], bdp->fwver[2],
+		 QLA1280_VERSION);
+	return bp;
 }
 
 /**************************************************************************
@@ -1038,246 +1216,86 @@
  * handling).   Unfortunely, it sometimes calls the scheduler in interrupt
  * context which is a big NO! NO!.
  **************************************************************************/
-int
-qla1280_queuecommand(Scsi_Cmnd *cmd, void (*fn)(Scsi_Cmnd *))
+static int
+qla1280_queuecommand(Scsi_Cmnd * cmd, void (*fn) (Scsi_Cmnd *))
 {
-    scsi_qla_host_t *ha;
-    srb_t  *sp;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-    struct Scsi_Host *host;
-    uint32_t        b, t, l;
-    scsi_lu_t       *q;
-    u_long          handle;
-
-    ENTER("qla1280_queuecommand");
-    COMTRACE('C') 
-
-    host = cmd->host;
-    ha = (scsi_qla_host_t *) host->hostdata;
-
-    /* send command to adapter */
-    sp = (srb_t *) CMD_SP(cmd);
-    sp->cmd =  cmd;
-    cmd->scsi_done = fn;
-    if (cmd->flags == 0)  /* new command */
-    {
-        sp->flags = 0;
-    }
-
-    DEBUG5(qla1280_print_scsi_cmd(cmd));
-
-    /* Generate LU queue on bus, target, LUN */
-    b = SCSI_BUS_32(cmd);
-    t = SCSI_TCN_32(cmd);
-    l = SCSI_LUN_32(cmd);
-    if((q = LU_Q(ha, b, t, l)) == NULL )
-    {
-        DRIVER_LOCK
-        if( (q = (scsi_lu_t *)KMALLOC(sizeof(struct scsi_lu))) )
-        {
-           LU_Q(ha, b, t, l) = q;
-           BZERO(q,sizeof(struct scsi_lu));
-           DEBUG(sprintf(debug_buff,"Allocate new device queue 0x%x\n",q));
-           DEBUG(qla1280_print(debug_buff));
-           DRIVER_UNLOCK
-        }
-        else
-        {
-            CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16);
-            qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
-
-            schedule_task(&ha->run_qla_bh);
-            ha->flags.dpc_sched = TRUE;
-            DRIVER_UNLOCK
-            return(0);
-        }
-    }
-    /* Set an invalid handle until we issue the command to ISP */
-    /* then we will set the real handle value.                 */
-    handle = INVALID_HANDLE;  
-    CMD_HANDLE(cmd) = (unsigned char *)handle;
-
-    /* Bookkeeping information */
-    sp->r_start = jiffies;       /* time the request was received */
-    sp->u_start = 0;              
-
-    /* add the command to our queue */
-    ha->qthreads++;
-    qla1280_putq_t(q,sp);
-    
-    DEBUG(sprintf(debug_buff,"qla1280_queuecmd: queue pid=%d, hndl=0x%x\n\r",cmd->pid,handle));
-    DEBUG(qla1280_print(debug_buff));
-
-    /* send command to adapter */
-    DRIVER_LOCK
-        if (q->q_outcnt == 0)
-            qla1280_restart_queues(ha);
-    DRIVER_UNLOCK
-    
-    
-    LEAVE("qla1280_queuecommand");
-    return (0);
+	struct scsi_qla_host *ha;
+	struct srb *sp;
+	struct Scsi_Host *host;
+	int bus, target, lun;
+	int status;
+
+	/*ENTER("qla1280_queuecommand");
+	 */
+	dprintk(2, "qla1280_queuecommand(): jiffies %li\n", jiffies);
+
+	host = CMD_HOST(cmd);
+	ha = (struct scsi_qla_host *)host->hostdata;
+
+	/* send command to adapter */
+	sp = (struct srb *)CMD_SP(cmd);
+	sp->cmd = cmd;
+	cmd->scsi_done = fn;
+	sp->flags = 0;
+
+	qla1280_print_scsi_cmd(5, cmd);
+
+	/* Generate LU queue on bus, target, LUN */
+	bus = SCSI_BUS_32(cmd);
+	target = SCSI_TCN_32(cmd);
+	lun = SCSI_LUN_32(cmd);
+	if (ha->flags.enable_64bit_addressing)
+		status = qla1280_64bit_start_scsi(ha, sp);
+	else
+		status = qla1280_32bit_start_scsi(ha, sp);
+
+	/*LEAVE("qla1280_queuecommand"); */
+	return status;
 }
 
-/**************************************************************************
- *   qla1200_abort
- *     Abort the speciifed SCSI command(s).
- **************************************************************************/
-int
-qla1280_abort(Scsi_Cmnd *cmd)
+enum action {
+	ABORT_COMMAND,
+	ABORT_DEVICE,
+	DEVICE_RESET,
+	BUS_RESET,
+	ADAPTER_RESET,
+	FAIL
+};
+
+/* timer action for error action processor */
+static void qla1280_error_wait_timeout(unsigned long __data)
+{
+	struct scsi_cmnd *cmd = (struct scsi_cmnd *)__data;
+	struct srb *sp = (struct srb *)CMD_SP(cmd);
+
+	complete(sp->wait);
+}
+
+static void qla1280_mailbox_timeout(unsigned long __data)
 {
-    scsi_qla_host_t *ha;
-    srb_t  *sp;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-    struct Scsi_Host *host;
-    uint32_t        b, t, l;
-    scsi_lu_t       *q;
-    int return_status = SCSI_ABORT_SUCCESS;
-    int found = 0;
-    int i;
-    u_long     handle;
-    u_short    data;
-
-    ENTER("qla1280_abort");
-    COMTRACE('A')
-    ha = (scsi_qla_host_t *) cmd->host->hostdata;
-    host = cmd->host;
-    DRIVER_LOCK
-
-    /* Get the SCSI request ptr */
-    sp = (srb_t *) CMD_SP(cmd);
-    handle = (u_long) CMD_HANDLE(cmd);
-    if (qla1280_verbose)
-        printk("scsi(%d): ABORT Command=0x%lx, handle=0x%lx\n",(int)ha->host_no,(long)cmd,handle);
-
-    /* Check for pending interrupts. */
-    if( handle == 0L )
-    {
-    COMTRACE('a')
-        /* we never got this command */
-        printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
-        DRIVER_UNLOCK
-                return(SCSI_ABORT_NOT_RUNNING);  /* no action - we don't have command */
-    }
-    data = qla1280_debounce_register(&ha->iobase->istatus);
-    if( !(ha->flags.in_isr) && (data & RISC_INT) )
-    {
-        /* put any pending command in done queue */
-        qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-    }
-
-    handle = (u_long) CMD_HANDLE(cmd);
-
-    /* Generate LU queue on bus, target, LUN */
-    b = SCSI_BUS_32(cmd);
-    t = SCSI_TCN_32(cmd);
-    l = SCSI_LUN_32(cmd);
-    if((q = LU_Q(ha, b, t, l)) == NULL )
-    {
-    COMTRACE('a')
-        /* No lun queue -- command must not be active */
-        DRIVER_UNLOCK
-        printk(KERN_WARNING "qla1280 (%d:%d:%d): No LUN queue for the specified device\n",(int)b,(int)t,(int)l);
-        return(SCSI_ABORT_NOT_RUNNING);  /* no action - we don't have command */
-    }
-
-#if AUTO_ESCALATE_ABORT
-    if ( (sp->flags & SRB_ABORTED) )
-    {
-        DRIVER_UNLOCK
-        DEBUG(qla1280_print("qla1280_abort: Abort escalayted - returning SCSI_ABORT_SNOOZE.\n\r"));
-        return(SCSI_ABORT_SNOOZE);
-    }
-#endif
-
-    if ( (sp->flags & SRB_ABORT_PENDING) )
-    {
-    COMTRACE('a')
-        DRIVER_UNLOCK
-        if( qla1280_verbose  )
-            printk("scsi(): Command has a pending abort message - ABORT_PENDING.\n");
-        DEBUG(qla1280_print("qla1280: Command has a pending abort message - ABORT_PENDING.\n\r"));
-        return(SCSI_ABORT_PENDING);
-    }
-
-#if  STOP_ON_ABORT 
-    printk("Scsi layer issued a ABORT command= 0x%x\n",(int)cmd);
-    DEBUG2(qla1280_print_scsi_cmd(cmd));
-#endif
-
-    ha->flags.in_abort = TRUE;
-    /*
-    * Normally, would would need to search our queue for the specified command
-    * but; since our sp contains the cmd ptr, we can just remove it from our
-    * LUN queue.
-    */
-    if( !(sp->flags&SRB_SENT) )
-    { 
-        found++;
-        if( qla1280_verbose  )
-            printk("scsi(): Command returned from queue aborted.\n");
-        DEBUG(qla1280_print("qla1280: Command returned from queue aborted.\n\r"));
-        /* Remove srb from SCSI LU queue. */
-        qla1280_removeq(q, sp);
-        sp->flags |=  SRB_ABORTED;
-        CMD_RESULT(cmd) = DID_ABORT << 16; 
-        qla1280_done_q_put(sp, &ha->done_q_first, &ha->done_q_last);
-        return_status = SCSI_ABORT_SUCCESS;
-    }
-    else
-    {  /* find the command in our active list */
-        for (i = 1; i < MAX_OUTSTANDING_COMMANDS; i++)
-        {
-            if( sp == ha->outstanding_cmds[i] )
-            {
-                found++;
-                DEBUG(qla1280_print("qla1280: RISC aborting command.\n\r"));
-                qla1280_abort_command(ha,sp);
-                return_status = SCSI_ABORT_PENDING;
-                break;
-            }
-        }
-    }
-
-#if  STOP_ON_ABORT 
-    qla1280_panic("qla1280_abort",ha->host);
-#endif
-    if ( found == 0 )
-        return_status = SCSI_ABORT_NOT_RUNNING;  /* no action - we don't have command */
-
-    DEBUG(sprintf(debug_buff, "qla1280_abort: Aborted status returned = 0x%x.\n\r",return_status));
-    DEBUG(qla1280_print(debug_buff));
-
-    if( ha->done_q_first )
-       qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-    if ( found )
-    {
-        qla1280_restart_queues(ha);
-    }
-    ha->flags.in_abort = FALSE;
-    DRIVER_UNLOCK
-
-    LEAVE("qla1280_abort");
-    COMTRACE('a')
-    return(return_status);
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)__data;
+	struct device_reg *reg;
+	reg = ha->iobase;
+
+	ha->mailbox_out[0] = RD_REG_WORD(&reg->mailbox0);
+	printk(KERN_ERR "scsi(%ld): mailbox timed out, mailbox0 %04x, "
+	       "ictrl %04x, istatus %04x\n", ha->host_no, ha->mailbox_out[0],
+	       RD_REG_WORD(&reg->ictrl), RD_REG_WORD(&reg->istatus));
+	complete(ha->mailbox_wait);
 }
 
 /**************************************************************************
- * qla1200_reset
- *    The reset function will reset the SCSI bus and abort any executing
- *    commands. 
+ * qla1200_error_action
+ *    The function will attempt to perform a specified error action and
+ *    wait for the results (or time out).
  *
  * Input:
  *      cmd = Linux SCSI command packet of the command that cause the
  *            bus reset.
- *      flags = SCSI bus reset option flags (see scsi.h)
+ *      action = error action to take (see action_t)
  *
  * Returns:
- *      DID_RESET in cmd.host_byte of aborted command(s) 
+ *      SUCCESS or FAILED
  *
  * Note:
  *      Resetting the bus always succeeds - is has to, otherwise the
@@ -1285,360 +1303,369 @@
  *      DEVICE RESET message - on the offending target before pulling
  *      the SCSI bus reset line.
  **************************************************************************/
-int
-qla1280_reset(Scsi_Cmnd *cmd, unsigned int flags)
+static int
+qla1280_error_action(Scsi_Cmnd * cmd, enum action action)
 {
-    scsi_qla_host_t *ha;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-    uint32_t        b, t, l;
-    srb_t  *sp;
-    typedef enum
-    {
-        ABORT_DEVICE = 1, 
-                DEVICE_RESET = 2, 
-                BUS_RESET    = 3, 
-                ADAPTER_RESET= 4,
-                RESET_DELAYED= 5,
-                FAIL         = 6
-    } action_t;
-    action_t     action = ADAPTER_RESET;
-    u_short    data;
-    scsi_lu_t       *q;
-    int result;
-
-
-    ENTER("qla1280_reset");
-    COMTRACE('R')
-    if (qla1280_verbose)
-        printk("scsi(): Resetting Cmnd=0x%lx, Handle=0x%lx, flags=0x%x\n",(long)cmd,(long)CMD_HANDLE(cmd),flags);
-    if ( cmd == NULL )
-    {
-        printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL Scsi_Cmnd "
-                "pointer, failing.\n");
-        return(SCSI_RESET_SNOOZE);
-    }
-    ha = (scsi_qla_host_t *) cmd->host->hostdata;
-    sp = (srb_t *) CMD_SP(cmd);
-
-#if  STOP_ON_RESET 
-    qla1280_panic("qla1280_reset",ha->host);
-#endif 
-
-    DRIVER_LOCK
-    /* Check for pending interrupts. */
-    data = qla1280_debounce_register(&ha->iobase->istatus);
-    if( !(ha->flags.in_isr) && (data & RISC_INT) )
-    {
-        qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-    }
-    DRIVER_UNLOCK
-
-    /*
-    * Determine the suggested action that the mid-level driver wants
-    * us to perform.
-    */
-    if( CMD_HANDLE(cmd) == (unsigned char *) 0  )
-    {
-        /* 
-        * if mid-level driver called reset with a orphan SCSI_Cmnd 
-        * (i.e. a command that's not pending ), so perform the 
-        * function specified.
-        */
-        if( (flags & SCSI_RESET_SUGGEST_HOST_RESET) )
-            action = ADAPTER_RESET;
-        else 
-            action = BUS_RESET;
-    }
-    else
-    { /* 
-        * Mid-level driver has called reset with this SCSI_Cmnd and 
-        * its pending.
-        */
-        if( flags & SCSI_RESET_SUGGEST_HOST_RESET )
-            action = ADAPTER_RESET;
-        else if( flags & SCSI_RESET_SUGGEST_BUS_RESET )
-            action = BUS_RESET;
-        else 
-            action = DEVICE_RESET;
-    }
-
-    b = SCSI_BUS_32(cmd);
-    t = SCSI_TCN_32(cmd);
-    l = SCSI_LUN_32(cmd);
-    q = LU_Q(ha, b, t, l);
-
-#if AUTO_ESCALATE_RESET
-    if ( (action & DEVICE_RESET) && (q->q_flag & QLA1280_QRESET) )
-    {
-        printk(KERN_INFO "qla1280(%d): Bus device reset already sent to " "device, escalating.\n", (int)ha->host_no);
-        action = BUS_RESET;
-    }
-    if ( (action & DEVICE_RESET) && (sp->flags & SRB_ABORT_PENDING) )
-    {
-        printk(KERN_INFO "qla1280(%d):Have already attempted to reach " "device with abort device\n", (int)ha->host_no);
-        printk(KERN_INFO "qla1280(%d):message, will escalate to BUS " "RESET.\n",(int) ha->host_no);
-        action = BUS_RESET;
-    }
-#endif
-
-    /*
-    *  By this point, we want to already know what we are going to do,
-    *  so we only need to perform the course of action.
-    */
-    DRIVER_LOCK
-    result = SCSI_RESET_ERROR;
-    switch (action)
-    {
-        case FAIL:
-            break;
-
-        case RESET_DELAYED:
-            result = SCSI_RESET_PENDING;
-            break;
-
-        case ABORT_DEVICE:
-            ha->flags.in_reset = TRUE;
-            if (qla1280_verbose)
-                printk(KERN_INFO "scsi(%d:%d:%d:%d): Queueing abort device command.\n", (int)ha->host_no,(int)b,(int)t,(int)l); 
-            qla1280_abort_queue_single(ha,b,t,l,DID_ABORT);
-            if( qla1280_abort_device(ha, b, t, l) == 0)
-                result = SCSI_RESET_PENDING;
-            break;
-
-        case DEVICE_RESET:
-            if (qla1280_verbose)
-                printk(KERN_INFO "scsi(%d:%d:%d:%d): Queueing device reset command.\n",(int) ha->host_no,(int)b,(int)t,(int)l); 
-            ha->flags.in_reset = TRUE;
-            for (l = 0; l < MAX_LUNS; l++)
-                qla1280_abort_queue_single(ha,b,t,l,DID_ABORT);
-            if( qla1280_device_reset(ha, b, t) == 0 ) 
-                result = SCSI_RESET_PENDING;
-            q->q_flag |= QLA1280_QRESET;
-            break;
-
-        case BUS_RESET:
-                if (qla1280_verbose)
-                    printk(KERN_INFO "qla1280(%d:%d:%d:%d): Issuing BUS DEVICE RESET.\n",(int) ha->host_no,(int)b,(int)t,(int)l); 
-            ha->flags.in_reset = TRUE;
-            for (t = 0; t < MAX_TARGETS; t++)
-                for (l = 0; l < MAX_LUNS; l++)
-                    qla1280_abort_queue_single(ha,b,t,l,DID_RESET);
-                qla1280_bus_reset(ha, b);
-                /*
-                * The bus reset routine returns all the outstanding commands back
-                * with "DID_RESET" in the status field after a short delay
-                * by the firmware. If the mid-level time out the SCSI reset before
-                * our delay we may need to ignore it.
-                */
-                /* result = SCSI_RESET_PENDING | SCSI_RESET_BUS_RESET; */
-                result = SCSI_RESET_SUCCESS | SCSI_RESET_BUS_RESET;
-                mdelay(4 * 1000); barrier();
-                if( flags & SCSI_RESET_SYNCHRONOUS )
-                {
-                  CMD_RESULT(cmd) = (int) (DID_BUS_BUSY << 16);
-                  (*(cmd)->scsi_done)(cmd); 
-                }
-                /* ha->reset_start = jiffies; */
-                break;
-
-            case ADAPTER_RESET:
-            default:
-                if (qla1280_verbose)
-                {
-                    printk(KERN_INFO "scsi(%d:%d:%d:%d): Issued an ADAPTER RESET.\n",(int) ha->host_no,(int)b,(int)t,(int)l); 
-                    printk(KERN_INFO "scsi(%d:%d:%d:%d): I/O processing will continue automatically.\n",(int) ha->host_no,(int)b,(int)t,(int)l); 
-                }
-                ha->flags.reset_active = TRUE;
-                /* 
-                * We restarted all of the commands automatically, so the mid-level code can expect 
-                * completions momentitarily.
-                */
-                if( qla1280_abort_isp(ha) == 0 )
-                    result = SCSI_RESET_SUCCESS | SCSI_RESET_HOST_RESET;
-
-                        ha->flags.reset_active = FALSE;
-    }
-
-    if( ha->done_q_first ) 
-        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-    qla1280_restart_queues(ha);
-    ha->flags.in_reset = FALSE;
-    
-DRIVER_UNLOCK
-    DEBUG(printk("RESET returning %d\n", result)); 
-
-    COMTRACE('r')
-    LEAVE("qla1280_reset");
-    return( result );
+	struct scsi_qla_host *ha;
+	int bus, target, lun;
+	struct srb *sp;
+	uint16_t data;
+	unsigned char *handle;
+	int result, i;
+	DECLARE_COMPLETION(wait);
+	struct timer_list timer;
+
+	ha = (struct scsi_qla_host *)(CMD_HOST(cmd)->hostdata);
+
+	dprintk(4, "error_action %i, istatus 0x%04x\n", action,
+		RD_REG_WORD(&ha->iobase->istatus));
+
+	dprintk(4, "host_cmd 0x%04x, ictrl 0x%04x, jiffies %li\n",
+		RD_REG_WORD(&ha->iobase->host_cmd),
+		RD_REG_WORD(&ha->iobase->ictrl), jiffies);
+
+	ENTER("qla1280_error_action");
+	if (qla1280_verbose)
+		printk(KERN_INFO "scsi(%li): Resetting Cmnd=0x%p, "
+		       "Handle=0x%p, action=0x%x\n",
+		       ha->host_no, cmd, CMD_HANDLE(cmd), action);
+
+	if (cmd == NULL) {
+		printk(KERN_WARNING "(scsi?:?:?:?) Reset called with NULL "
+		       "si_Cmnd pointer, failing.\n");
+		LEAVE("qla1280_error_action");
+		return FAILED;
+	}
+
+	ha = (struct scsi_qla_host *)cmd->device->host->hostdata;
+	sp = (struct srb *)CMD_SP(cmd);
+	handle = CMD_HANDLE(cmd);
+
+	/* Check for pending interrupts. */
+	data = qla1280_debounce_register(&ha->iobase->istatus);
+	/*
+	 * The io_request_lock is held when the reset handler is called, hence
+	 * the interrupt handler cannot be running in parallel as it also
+	 * grabs the lock. /Jes
+	 */
+	if (data & RISC_INT)
+		qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
+
+	/*
+	 * Determine the suggested action that the mid-level driver wants
+	 * us to perform.
+	 */
+	if (handle == (unsigned char *)INVALID_HANDLE || handle == NULL) {
+		if(action == ABORT_COMMAND) {
+			/* we never got this command */
+			printk(KERN_INFO "qla1280: Aborting a NULL handle\n");
+			return SUCCESS;	/* no action - we don't have command */
+		}
+	} else {
+		sp->wait = &wait;
+	}
+
+	bus = SCSI_BUS_32(cmd);
+	target = SCSI_TCN_32(cmd);
+	lun = SCSI_LUN_32(cmd);
+
+	/* Overloading result.  Here it means the success or fail of the
+	 * *issue* of the action.  When we return from the routine, it must
+	 * mean the actual success or fail of the action */
+	result = FAILED;
+	switch (action) {
+	case FAIL:
+		break;
+
+	case ABORT_COMMAND:
+		if ((sp->flags & SRB_ABORT_PENDING)) {
+			printk(KERN_WARNING
+			       "scsi(): Command has a pending abort "
+			       "message - ABORT_PENDING.\n");
+			/* This should technically be impossible since we
+			 * now wait for abort completion */
+			break;
+		}
+
+		for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) {
+			if (sp == ha->outstanding_cmds[i]) {
+				dprintk(1, "qla1280: RISC aborting command\n");
+				if (qla1280_abort_command(ha, sp, i) == 0)
+					result = SUCCESS;
+				else {
+					/*
+					 * Since we don't know what might
+					 * have happend to the command, it
+					 * is unsafe to remove it from the
+					 * device's queue at this point.
+					 * Wait and let the escalation
+					 * process take care of it.
+					 */
+					printk(KERN_WARNING
+					       "scsi(%li:%i:%i:%i): Unable"
+					       " to abort command!\n",
+					       ha->host_no, bus, target, lun);
+				}
+			}
+		}
+		break;
+
+	case ABORT_DEVICE:
+		ha->flags.in_reset = 1;
+		if (qla1280_verbose)
+			printk(KERN_INFO
+			       "scsi(%ld:%d:%d:%d): Queueing abort device "
+			       "command.\n", ha->host_no, bus, target, lun);
+		if (qla1280_abort_device(ha, bus, target, lun) == 0)
+			result = SUCCESS;
+		break;
+
+	case DEVICE_RESET:
+		if (qla1280_verbose)
+			printk(KERN_INFO
+			       "scsi(%ld:%d:%d:%d): Queueing device reset "
+			       "command.\n", ha->host_no, bus, target, lun);
+		ha->flags.in_reset = 1;
+		if (qla1280_device_reset(ha, bus, target) == 0)
+			result = SUCCESS;
+		break;
+
+	case BUS_RESET:
+		if (qla1280_verbose)
+			printk(KERN_INFO "qla1280(%ld:%d): Issuing BUS "
+			       "DEVICE RESET\n", ha->host_no, bus);
+		ha->flags.in_reset = 1;
+		if (qla1280_bus_reset(ha, bus == 0))
+			result = SUCCESS;
+
+		break;
+
+	case ADAPTER_RESET:
+	default:
+		if (qla1280_verbose) {
+			printk(KERN_INFO
+			       "scsi(%ld): Issued ADAPTER RESET\n",
+			       ha->host_no);
+			printk(KERN_INFO "scsi(%ld): I/O processing will "
+			       "continue automatically\n", ha->host_no);
+		}
+		ha->flags.reset_active = 1;
+		/*
+		 * We restarted all of the commands automatically, so the
+		 * mid-level code can expect completions momentitarily.
+		 */
+		if (qla1280_abort_isp(ha) == 0)
+			result = SUCCESS;
+
+		ha->flags.reset_active = 0;
+	}
+
+	if (ha->done_q_first)
+		qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
+	ha->flags.in_reset = 0;
+
+	/* If we didn't manage to issue the action, or we have no
+	 * command to wait for, exit here */
+	if (result == FAILED || handle == NULL ||
+	    handle == (unsigned char *)INVALID_HANDLE)
+		goto leave;
+
+	/* set up a timer just in case we're really jammed */
+	init_timer(&timer);
+	timer.expires = jiffies + 4*HZ;
+	timer.data = (unsigned long)cmd;
+	timer.function = qla1280_error_wait_timeout;
+	add_timer(&timer);
+
+	/* wait for the action to complete (or the timer to expire) */
+	spin_unlock_irq(HOST_LOCK);
+	wait_for_completion(&wait);
+	del_timer_sync(&timer);
+	spin_lock_irq(HOST_LOCK);
+	sp->wait = NULL;
+
+	/* the only action we might get a fail for is abort */
+	if (action == ABORT_COMMAND) {
+		if(sp->flags & SRB_ABORTED)
+			result = SUCCESS;
+		else
+			result = FAILED;
+	}
+
+ leave:
+	dprintk(1, "RESET returning %d\n", result);
+
+	LEAVE("qla1280_error_action");
+	return result;
 }
 
 /**************************************************************************
- * qla1200_biosparam
- *   Return the disk geometry for the given SCSI device.
+ *   qla1280_abort
+ *     Abort the specified SCSI command(s).
  **************************************************************************/
-int
-qla1280_biosparam(Disk *disk, kdev_t dev, int geom[])
+static int
+qla1280_eh_abort(struct scsi_cmnd * cmd)
 {
-    int heads, sectors, cylinders;
-
-            heads = 64;
-    sectors = 32;
-    cylinders = disk->capacity / (heads * sectors);
-    if (cylinders > 1024)
-    {
-        heads = 255;
-        sectors = 63;
-        cylinders = disk->capacity / (heads * sectors);
-        /* if (cylinders > 1023)
-        cylinders = 1023; */
-    }
-
-    geom[0] = heads;
-    geom[1] = sectors;
-    geom[2] = cylinders;
-
-    return (0);
+	return qla1280_error_action(cmd, ABORT_COMMAND);
 }
+
 /**************************************************************************
- * qla1280_intr_handler
- *   Handles the H/W interrupt
+ *   qla1280_device_reset
+ *     Reset the specified SCSI device
  **************************************************************************/
-void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+static int
+qla1280_eh_device_reset(struct scsi_cmnd *cmd)
 {
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-    scsi_qla_host_t *ha;
-    u_short    data;
-    device_reg_t *reg;
-
-    ENTER_INTR("qla1280_intr_handler");
-    COMTRACE('I')
-    ha = (scsi_qla_host_t *) dev_id;
-    if(!ha)
-    {
-        printk(KERN_INFO "scsi(): Interrupt with NULL host ptr\n");
-        COMTRACE('X')
-        return;
-    }
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,95)
-    spin_lock_irqsave(&io_request_lock, cpu_flags);
-    if(test_and_set_bit(QLA1280_IN_ISR_BIT, &ha->flags))
-    {
-        COMTRACE('X')
-        spin_unlock_irqrestore(&io_request_lock, cpu_flags);
-        return;
-    }
-    ha->isr_count++;
-    reg = ha->iobase;
-     /* disable our interrupt. */
-    WRT_REG_WORD(&reg->ictrl, 0); 
-    data = qla1280_debounce_register(&reg->istatus);
-    /* Check for pending interrupts. */
-    if ( !(data & RISC_INT) )
-    {
-        /* spurious interrupts can happen legally */
-        DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no));
-        COMTRACE('X')
-    }
-    else
-      qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-    if (ha->done_q_first)
-        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-
-    clear_bit(QLA1280_IN_ISR_BIT, &ha->flags);
-    spin_unlock_irqrestore(&io_request_lock, cpu_flags);
-#else  /* LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95) */
-
-    if( test_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags) )
-    {
-          COMTRACE('X')
-          printk(KERN_INFO "scsi(%d): Already in interrupt - returning \n", (int)ha->host_no);
-          return;
-    }
-    set_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags);
-    ha->isr_count++;
-    reg = ha->iobase;
-     /* disable our interrupt. */
-    WRT_REG_WORD(&reg->ictrl, 0); 
-
-    data = qla1280_debounce_register(&reg->istatus);
-    /* Check for pending interrupts. */
-    if ( !(data & RISC_INT) )
-    {
-        /* spurious interrupts can happen legally */
-        DEBUG(printk("scsi(%d): Spurious interrupt - ignoring\n",(int)ha->host_no));
-        COMTRACE('X')
-    }
-    else
-     qla1280_isr(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-
-    /* if no work to do then call the SCSI mid-level right away */
-    if( ha->done_q_first )
-        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-
-    /* Schedule the DPC routine */
-    if (ha->flags.isp_abort_needed || ha->flags.reset_marker ||
-            ha->done_q_first        )
-        {
-            ha->run_qla_bh.data = (void *) ha;
-            ha->run_qla_bh.routine = qla1280_do_dpc; 
-
-             COMTRACE('P') 
-            schedule_task(&ha->run_qla_bh);
-            ha->flags.dpc_sched = TRUE;
-        }
-        clear_bit(QLA1280_IN_ISR_BIT, (int *)&ha->flags);
-#endif
-     /* enable our interrupt. */
-        WRT_REG_WORD(&reg->ictrl, ISP_EN_INT + ISP_EN_RISC);
+	return qla1280_error_action(cmd, DEVICE_RESET);
+}
 
-        COMTRACE('i')  
-        LEAVE_INTR("qla1280_intr_handler");
+/**************************************************************************
+ *   qla1280_bus_reset
+ *     Reset the specified bus.
+ **************************************************************************/
+static int
+qla1280_eh_bus_reset(struct scsi_cmnd *cmd)
+{
+	return qla1280_error_action(cmd, BUS_RESET);
 }
 
 /**************************************************************************
- *   qla1280_do_dpc
- *
- * Description:
- * This routine is a task that is schedule by the interrupt handler 
- * to perform the background processing for interrupts.  We put it 
- * on a task queue that is consumed whenever the scheduler runs; that's
- * so you can do anything (i.e. put the process to sleep etc).  In fact, the 
- * mid-level tries to sleep when it reaches the driver threshold 
- * "host->can_queue". This can cause a panic if we were in our interrupt
- * code .
+ *   qla1280_adapter_reset
+ *     Reset the specified adapter (both channels)
  **************************************************************************/
-static void qla1280_do_dpc(void *p)
+static int
+qla1280_eh_adapter_reset(struct scsi_cmnd *cmd)
 {
-    scsi_qla_host_t *ha = (scsi_qla_host_t *) p;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
+	return qla1280_error_action(cmd, ADAPTER_RESET);
+}
 
-    COMTRACE('p')  
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-    spin_lock_irqsave(&io_request_lock, cpu_flags);
+/**************************************************************************
+ * qla1280_biosparam
+ *   Return the disk geometry for the given SCSI device.
+ **************************************************************************/
+static int
+#if LINUX_VERSION_CODE < 0x020545
+qla1280_biosparam(Disk * disk, kdev_t dev, int geom[])
+#else
+qla1280_biosparam(struct scsi_device *sdev, struct block_device *bdev,
+		  sector_t capacity, int geom[])
 #endif
-    if (ha->flags.isp_abort_needed)
-        qla1280_abort_isp(ha);
+{
+	int heads, sectors, cylinders;
+#if LINUX_VERSION_CODE < 0x020545
+	unsigned long capacity = disk->capacity;
+#endif
+
+	heads = 64;
+	sectors = 32;
+	cylinders = (unsigned long)capacity / (heads * sectors);
+	if (cylinders > 1024) {
+		heads = 255;
+		sectors = 63;
+		cylinders = (unsigned long)capacity / (heads * sectors);
+		/* if (cylinders > 1023)
+		   cylinders = 1023; */
+	}
 
-    if (ha->flags.reset_marker)
-        qla1280_rst_aen(ha);
+	geom[0] = heads;
+	geom[1] = sectors;
+	geom[2] = cylinders;
 
-    if (ha->done_q_first)
-        qla1280_done(ha, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-    ha->flags.dpc_sched = FALSE;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-    spin_unlock_irqrestore(&io_request_lock, cpu_flags);
-#endif
+	return 0;
 }
 
 /**************************************************************************
- *   qla1280_device_queue_depth
- *
+ * qla1280_intr_handler
+ *   Handles the H/W interrupt
+ **************************************************************************/
+irqreturn_t
+qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct scsi_qla_host *ha;
+	struct device_reg *reg;
+	u16 data;
+	int handled = 0;
+
+	ENTER_INTR ("qla1280_intr_handler");
+	ha = (struct scsi_qla_host *)dev_id;
+
+	spin_lock(HOST_LOCK);
+
+	ha->isr_count++;
+	reg = ha->iobase;
+
+	WRT_REG_WORD(&reg->ictrl, 0);	/* disable our interrupt. */
+
+	data = qla1280_debounce_register(&reg->istatus);
+	/* Check for pending interrupts. */
+	if (data & RISC_INT) {
+		qla1280_isr(ha, &ha->done_q_first, &ha->done_q_last);
+		handled = 1;
+	}
+	if (ha->done_q_first)
+		qla1280_done(ha, &ha->done_q_first, &ha->done_q_last);
+
+	spin_unlock(HOST_LOCK);
+
+	/* enable our interrupt. */
+	WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
+
+	LEAVE_INTR("qla1280_intr_handler");
+	return IRQ_RETVAL(handled);
+}
+
+
+static int
+qla12160_set_target_parameters(struct scsi_qla_host *ha, int bus, int target)
+{
+	uint8_t mr;
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	struct nvram *nv;
+	int is1x160, status;
+
+	nv = &ha->nvram;
+
+	if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+	    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
+		is1x160 = 1;
+	else
+		is1x160 = 0;
+
+	mr = BIT_3 | BIT_2 | BIT_1 | BIT_0;
+
+	/* Set Target Parameters. */
+	mb[0] = MBC_SET_TARGET_PARAMETERS;
+	mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
+	mb[1] <<= 8;
+
+	mb[2] = (nv->bus[bus].target[target].parameter.c << 8);
+
+	if (is1x160)
+		mb[3] =	nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
+	else
+		mb[3] =	nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
+	mb[3] |= nv->bus[bus].target[target].sync_period;
+
+	if (is1x160) {
+		mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
+		mb[6] =	nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
+		mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
+		mr |= BIT_6;
+	}
+
+	status = qla1280_mailbox_command(ha, mr, &mb[0]);
+
+	if (status)
+		printk(KERN_WARNING "scsi(%ld:%i:%i): "
+		       "qla1280_set_target_parameters() failed\n",
+		       ha->host_no, bus, target);
+	return status;
+}
+
+
+/**************************************************************************
+ *   qla1280_slave_configure
+ *
  * Description:
  *   Determines the queue depth for a given device.  There are two ways
  *   a queue depth can be obtained for a tagged queueing device.  One
@@ -1647,29 +1674,64 @@
  *   as the default queue depth.  Otherwise, we use either 4 or 8 as the
  *   default queue depth (dependent on the number of hardware SCBs).
  **************************************************************************/
-STATIC void qla1280_device_queue_depth(scsi_qla_host_t *p, Scsi_Device *device)
+static int
+qla1280_slave_configure(Scsi_Device *device)
 {
-    int default_depth = 3;
-    int bus = device->channel;
-    int target = device->id;
-
-    device->queue_depth = default_depth;
-
-    if (device->tagged_supported &&
-        (p->bus_settings[bus].qtag_enables & (BIT_0 << target)) )
-    {
-        device->tagged_queue = 1;
-        device->current_tag = 0;
-        device->queue_depth = p->bus_settings[bus].hiwat; 
-        /* device->queue_depth = 20; */
-        printk(KERN_INFO "scsi(%d:%d:%d:%d): Enabled tagged queuing, queue depth %d.\n",
-                (int)p->host_no, device->channel, device->id,
-                device->lun, device->queue_depth);
-    }
-    qla12160_get_target_parameters(p, bus, target, device->lun);
+	struct scsi_qla_host *ha;
+	int default_depth = 3;
+	int bus = device->channel;
+	int target = device->id;
+	int status = 0;
+	struct nvram *nv;
+	unsigned long flags;
+
+	ha = (struct scsi_qla_host *)device->host->hostdata;
+	nv = &ha->nvram;
+
+	if (qla1280_check_for_dead_scsi_bus(ha, bus))
+		return 1;
+
+	if (device->tagged_supported &&
+	    (ha->bus_settings[bus].qtag_enables & (BIT_0 << target))) {
+		scsi_adjust_queue_depth(device, MSG_ORDERED_TAG,
+					ha->bus_settings[bus].hiwat);
+	} else {
+		scsi_adjust_queue_depth(device, 0, default_depth);
+	}
+
+#if LINUX_VERSION_CODE > 0x020500
+	nv->bus[bus].target[target].parameter.f.enable_sync = device->sdtr;
+	nv->bus[bus].target[target].parameter.f.enable_wide = device->wdtr;
+	nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = device->ppr;
+#endif
+
+	if (driver_setup.no_sync ||
+	    (driver_setup.sync_mask &&
+	     (~driver_setup.sync_mask & (1 << target))))
+		nv->bus[bus].target[target].parameter.f.enable_sync = 0;
+	if (driver_setup.no_wide ||
+	    (driver_setup.wide_mask &&
+	     (~driver_setup.wide_mask & (1 << target))))
+		nv->bus[bus].target[target].parameter.f.enable_wide = 0;
+	if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+	    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160) {
+		if (driver_setup.no_ppr ||
+		    (driver_setup.ppr_mask &&
+		     (~driver_setup.ppr_mask & (1 << target))))
+			nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
+	}
+
+	spin_lock_irqsave(HOST_LOCK, flags);
+	if (nv->bus[bus].target[target].parameter.f.enable_sync) {
+		status = qla12160_set_target_parameters(ha, bus, target);
+	}
 
+	qla12160_get_target_parameters(ha, device);
+	spin_unlock_irqrestore(HOST_LOCK, flags);
+	return status;
 }
 
+#if LINUX_VERSION_CODE < 0x020545
 /**************************************************************************
  *   qla1280_select_queue_depth
  *
@@ -1677,43 +1739,30 @@
  *   host adapter.  We use a queue depth of 2 for devices that do not
  *   support tagged queueing.
  **************************************************************************/
-STATIC void
+static void
 qla1280_select_queue_depth(struct Scsi_Host *host, Scsi_Device *scsi_devs)
 {
-    Scsi_Device *device;
-    scsi_qla_host_t  *p = (scsi_qla_host_t *) host->hostdata;
+	Scsi_Device *device;
+	struct scsi_qla_host *ha = (struct scsi_qla_host *)host->hostdata;
 
-    ENTER("qla1280_select_queue_depth");
-    for (device = scsi_devs; device != NULL; device = device->next)
-    {
-        if (device->host == host)
-            qla1280_device_queue_depth(p, device);
-    }
-    LEAVE("qla1280_select_queue_depth");
-}
-
-/*--------------------------**
-** Driver Support Routines  **
-**--------------------------*/
+	ENTER("qla1280_select_queue_depth");
+	for (device = scsi_devs; device != NULL; device = device->next) {
+		if (device->host == host)
+			qla1280_slave_configure(device);
+	}
 
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-/*
- * mdelay
- *      Delay in milliseconds 
- *
- * Input:
- *      milliseconds  = delay 
- */
-STATIC inline void mdelay(int milliseconds)
-{
-    int i;
+	if (scsi_devs)
+		qla1280_check_for_dead_scsi_bus(ha, scsi_devs->channel);
 
-    for(i=0; i<milliseconds; i++)
-        udelay(1000);
+	LEAVE("qla1280_select_queue_depth");
 }
 #endif
 
 /*
+ * Driver Support Routines
+ */
+
+/*
  * qla1280_done
  *      Process completed commands.
  *
@@ -1722,176 +1771,170 @@
  *      done_q_first = done queue first pointer.
  *      done_q_last  = done queue last pointer.
  */
-STATIC void
-qla1280_done(scsi_qla_host_t *ha, srb_t **done_q_first, srb_t **done_q_last)
-{
-    srb_t           *sp;
-    scsi_lu_t       *q;
-    uint32_t        b, t, l;
-    Scsi_Cmnd  *cmd;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-
-    ENTER("qla1280_done");
-    COMTRACE('D') 
-
-    DRIVER_LOCK 
-    while (*done_q_first !=  NULL)
-    {
-        /* remove command from done list */
-                sp = *done_q_first;
-        if (!(*done_q_first = sp->s_next))
-            *done_q_last = NULL;
-        else
-            (*done_q_first)->s_prev = NULL;
-                cmd = sp->cmd;
-        b = SCSI_BUS_32(cmd);
-        t = SCSI_TCN_32(cmd);
-        l = SCSI_LUN_32(cmd);
-        q = LU_Q(ha, b, t, l);
-
-        /* Decrement outstanding commands on device. */
-        if (q->q_outcnt)
-            q->q_outcnt--;
-        if (q->q_outcnt < ha->bus_settings[b].hiwat)
-        {
-            q->q_flag &= ~QLA1280_QBUSY;
-        }
-        
-        q->resp_time += jiffies - sp->r_start;                /* Lun bookkeeping information */
-        q->act_time += jiffies - sp->u_start;
-        q->io_cnt++;
-        if( sp->dir & BIT_5 )
-         q->r_cnt++;
-        else
-         q->w_cnt++;
-
-        switch ( (CMD_RESULT(cmd)>>16))
-        {
-            case DID_RESET:
-                q->q_flag &= ~QLA1280_QRESET;
-                /* Issue marker command. */
-                qla1280_marker(ha, b, t, 0, MK_SYNC_ID); 
-                break;
-            case DID_ABORT:
-                sp->flags &= ~SRB_ABORT_PENDING;
-                sp->flags |= SRB_ABORTED;
-                if (sp->flags & SRB_TIMEOUT)
-                    CMD_RESULT(sp->cmd)= DID_TIME_OUT << 16;
-                break;
-            default:
-                break;
-        }
-
-        /* Call the mid-level driver interrupt handler */
-        CMD_HANDLE(sp->cmd) = (unsigned char *) 0;
-        ha->actthreads--;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-        sti(); 
-        (*(cmd)->scsi_done)(cmd);
-        cli(); 
-#else
-        (*(cmd)->scsi_done)(cmd);
+static void
+qla1280_done(struct scsi_qla_host *ha, struct srb ** done_q_first,
+	     struct srb ** done_q_last)
+{
+	struct srb *sp;
+	int bus, target, lun;
+	Scsi_Cmnd *cmd;
+
+	ENTER("qla1280_done");
+
+	while (*done_q_first != NULL) {
+		/* remove command from done list */
+		sp = *done_q_first;
+		if (!(*done_q_first = sp->s_next))
+			*done_q_last = NULL;
+		else
+			(*done_q_first)->s_prev = NULL;
+
+		cmd = sp->cmd;
+		bus = SCSI_BUS_32(cmd);
+		target = SCSI_TCN_32(cmd);
+		lun = SCSI_LUN_32(cmd);
+
+		switch ((CMD_RESULT(cmd) >> 16)) {
+		case DID_RESET:
+			/* Issue marker command. */
+			qla1280_marker(ha, bus, target, 0, MK_SYNC_ID);
+			break;
+		case DID_ABORT:
+			sp->flags &= ~SRB_ABORT_PENDING;
+			sp->flags |= SRB_ABORTED;
+			if (sp->flags & SRB_TIMEOUT)
+				CMD_RESULT(sp->cmd) = DID_TIME_OUT << 16;
+			break;
+		default:
+			break;
+		}
+
+		/* Release memory used for this I/O */
+		if (cmd->use_sg) {
+			dprintk(3, "S/G unmap_sg cmd=%p\n", cmd);
+
+			pci_unmap_sg(ha->pdev, cmd->request_buffer,
+				     cmd->use_sg,
+				     scsi_to_pci_dma_dir(cmd->sc_data_direction));
+		} else if (cmd->request_bufflen) {
+			/*dprintk(1, "No S/G unmap_single cmd=%x saved_dma_handle=%lx\n",
+			  cmd, sp->saved_dma_handle); */
+
+			pci_unmap_page(ha->pdev, sp->saved_dma_handle,
+				       cmd->request_bufflen,
+				       scsi_to_pci_dma_dir(cmd->sc_data_direction));
+		}
+
+		/* Call the mid-level driver interrupt handler */
+		CMD_HANDLE(sp->cmd) = (unsigned char *)INVALID_HANDLE;
+		ha->actthreads--;
+
+#if LINUX_VERSION_CODE < 0x020500
+		if (cmd->cmnd[0] == INQUIRY)
+			qla1280_get_target_options(cmd, ha);
 #endif
-        qla1280_next(ha, q, b);
-    }
-    DRIVER_UNLOCK 
+		(*(cmd)->scsi_done)(cmd);
 
+		if(sp->wait != NULL)
+			complete(sp->wait);
 
-    COMTRACE('d') 
-    LEAVE("qla1280_done");
+	}
+	LEAVE("qla1280_done");
 }
 
 /*
  * Translates a ISP error to a Linux SCSI error
  */
-STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd       *cp)
+static int
+qla1280_return_status(struct response * sts, Scsi_Cmnd * cp)
 {
-    int host_status = DID_ERROR;
+	int host_status = DID_ERROR;
 #if DEBUG_QLA1280_INTR
-    STATIC char *reason[] =
-    {
-        "DID_OK",
-                "DID_NO_CONNECT",
-                "DID_BUS_BUSY",
-                "DID_TIME_OUT",
-                "DID_BAD_TARGET",
-                "DID_ABORT",
-                "DID_PARITY",
-                "DID_ERROR",
-                "DID_RESET",
-                "DID_BAD_INTR"
-    };
-#endif /* DEBUG_QLA1280_INTR */
+	static char *reason[] = {
+		"DID_OK",
+		"DID_NO_CONNECT",
+		"DID_BUS_BUSY",
+		"DID_TIME_OUT",
+		"DID_BAD_TARGET",
+		"DID_ABORT",
+		"DID_PARITY",
+		"DID_ERROR",
+		"DID_RESET",
+		"DID_BAD_INTR"
+	};
+#endif				/* DEBUG_QLA1280_INTR */
 
-    ENTER("qla1280_return_status");
+	ENTER("qla1280_return_status");
 
 #if DEBUG_QLA1280_INTR
-    /*
-    DEBUG(printk("qla1280_return_status: compl status = 0x%04x\n", sts->comp_status));
-    */
-#endif
-    switch(sts->comp_status)
-    {
-        case CS_COMPLETE:
-            host_status = DID_OK;
-            break;
-        case CS_INCOMPLETE:
-            if (!(sts->state_flags & SF_GOT_BUS))
-                host_status = DID_NO_CONNECT;
-            else if (!(sts->state_flags & SF_GOT_TARGET))
-                host_status = DID_BAD_TARGET;
-            else if (!(sts->state_flags & SF_SENT_CDB))
-                host_status = DID_ERROR;
-            else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
-                host_status = DID_ERROR;
-            else if (!(sts->state_flags & SF_GOT_STATUS))
-                host_status = DID_ERROR;
-            else if (!(sts->state_flags & SF_GOT_SENSE))
-                host_status = DID_ERROR;
-            break;
-        case CS_RESET:
-            host_status = DID_RESET;
-            break;
-        case CS_ABORTED:
-            host_status = DID_ABORT;
-            break;
-        case CS_TIMEOUT:
-            host_status = DID_TIME_OUT;
-            break;
-        case CS_DATA_OVERRUN:
-#ifdef QL_DEBUG_LEVEL_2 
-            printk("Data overrun 0x%x\n",(int)sts->residual_length);
-            qla1280_print(
-                        "\n\rqla1280_isr: response packet data\n\r");
-                        qla1280_dump_buffer((caddr_t)sts,
-                        RESPONSE_ENTRY_SIZE); 
-#endif
-            host_status = DID_ERROR;
-            break;
-        case CS_DATA_UNDERRUN:
-            if ( (CMD_XFRLEN(cp) - sts->residual_length) < cp->underflow)    
-            { 
-              printk("scsi: Underflow detected - retrying command.\n");
-              host_status = DID_ERROR;
-            }
-            else
-                host_status = DID_OK;
-            break;
-        default:
-            host_status = DID_ERROR;
-            break;
-    }
+	/*
+	  dprintk(1, "qla1280_return_status: compl status = 0x%04x\n",
+	  sts->comp_status);
+	*/
+#endif
+	switch (sts->comp_status) {
+	case CS_COMPLETE:
+		host_status = DID_OK;
+		break;
+
+	case CS_INCOMPLETE:
+		if (!(sts->state_flags & SF_GOT_BUS))
+			host_status = DID_NO_CONNECT;
+		else if (!(sts->state_flags & SF_GOT_TARGET))
+			host_status = DID_BAD_TARGET;
+		else if (!(sts->state_flags & SF_SENT_CDB))
+			host_status = DID_ERROR;
+		else if (!(sts->state_flags & SF_TRANSFERRED_DATA))
+			host_status = DID_ERROR;
+		else if (!(sts->state_flags & SF_GOT_STATUS))
+			host_status = DID_ERROR;
+		else if (!(sts->state_flags & SF_GOT_SENSE))
+			host_status = DID_ERROR;
+		break;
+
+	case CS_RESET:
+		host_status = DID_RESET;
+		break;
+
+	case CS_ABORTED:
+		host_status = DID_ABORT;
+		break;
+
+	case CS_TIMEOUT:
+		host_status = DID_TIME_OUT;
+		break;
+
+	case CS_DATA_OVERRUN:
+		dprintk(2, "Data overrun 0x%x\n", sts->residual_length);
+		dprintk(2, "qla1280_isr: response packet data\n");
+		qla1280_dump_buffer(2, (char *)sts, RESPONSE_ENTRY_SIZE);
+		host_status = DID_ERROR;
+		break;
+
+	case CS_DATA_UNDERRUN:
+		if ((cp->request_bufflen - sts->residual_length) <
+		    cp->underflow) {
+			printk(KERN_WARNING
+			       "scsi: Underflow detected - retrying "
+			       "command.\n");
+			host_status = DID_ERROR;
+		} else
+			host_status = DID_OK;
+		break;
+
+	default:
+		host_status = DID_ERROR;
+		break;
+	}
 
 #if DEBUG_QLA1280_INTR
-    sprintf(debug_buff, "qla1280 ISP status: host status (%s) scsi status %x\n\r", reason[host_status], sts->scsi_status);
-    qla1280_print(debug_buff);
+	dprintk(1, "qla1280 ISP status: host status (%s) scsi status %x\n",
+		reason[host_status], sts->scsi_status);
 #endif
 
-    LEAVE("qla1280_return_status");
+	LEAVE("qla1280_return_status");
 
-    return (sts->scsi_status & 0xff) | (host_status << 16);
+	return (sts->scsi_status & 0xff) | (host_status << 16);
 }
 
 /*
@@ -1903,252 +1946,24 @@
  *      done_q_first = done queue first pointer.
  *      done_q_last  = done queue last pointer.
  */
-STATIC void
-qla1280_done_q_put(srb_t *sp, srb_t **done_q_first, srb_t **done_q_last)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_put_done_q");
-#endif
-    /* Place block on done queue */
-    DRIVER_LOCK
-            sp->s_next = NULL;
-    sp->s_prev = *done_q_last;
-    if (!*done_q_first)
-        *done_q_first = sp;
-    else
-        (*done_q_last)->s_next = sp;
-    *done_q_last = sp;
-
-    DRIVER_UNLOCK
-#ifdef QL_DEBUG_LEVEL_3
-            LEAVE("qla1280_put_done_q");
-#endif
-}
-
-/*
- * qla1280_next
- *      Retrieve and process next job in the queue.
- *
- * Input:
- *      ha = adapter block pointer.
- *      q  = SCSI LU pointer.
- *      b  = SCSI bus number.
- *      SCSI_LU_Q lock must be already obtained and no other locks.
- *
- * Output:
- *      Releases SCSI_LU_Q upon exit.
- */
-STATIC void
-qla1280_next(scsi_qla_host_t *ha, scsi_lu_t *q, uint8_t b)
-{
-    srb_t   *sp;
-    uint32_t cnt;
-    uint8_t status;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-
-    ENTER("qla1280_next");
-
-    DRIVER_LOCK
-    while ( ((sp = q->q_first) != NULL) &&     /* we have a queue pending */
-        !(q->q_flag &  QLA1280_QBUSY) &&      /* device not busy */
-        !ha->flags.abort_isp_active &&      /* not resetting the adapter */
-        !(q->q_flag & QLA1280_QSUSP) )      /* device not suspended */
-    {
-        /* Remove srb from SCSI LU queue. */
-        qla1280_removeq(q, sp);
-
-        DEBUG(sprintf(debug_buff,"starting request 0x%p<-(0x%p)\n\r",q,sp));
-        DEBUG(qla1280_print(debug_buff));
-        {
-            /* Set busy flag if reached high water mark. */
-            q->q_outcnt++;
-            if (q->q_outcnt >= ha->bus_settings[b].hiwat)
-                q->q_flag |= QLA1280_QBUSY;
-
-#if  QLA1280_64BIT_SUPPORT
-            if (ha->flags.enable_64bit_addressing)
-                status = qla1280_64bit_start_scsi(ha, sp);
-            else
-#endif
-                status = qla1280_32bit_start_scsi(ha, sp);
-
-            if (status)  /* if couldn't start the request */
-            {
-                if (q->q_outcnt == 1)
-                {
-                    /* Release SCSI LU queue specific lock */
-                    QLA1280_SCSILU_UNLOCK(q);
-
-                    /* Wait for 30 sec for command to be accepted. */
-                    for (cnt = 6000000; cnt; cnt--)
-                    {
-#if  QLA1280_64BIT_SUPPORT
-                        if (ha->flags.enable_64bit_addressing)
-                            status = qla1280_64bit_start_scsi(ha, sp);
-                        else
-#endif
-                            status = qla1280_32bit_start_scsi(ha, sp);
-
-                        if (!status)
-                        {
-                            break;
-                        }
-
-                        /* Go check for pending interrupts. */
-                        qla1280_poll(ha);
-
-                        SYS_DELAY(5);  /* 10 */
-                    }
-                    if (!cnt)
-                    {
-                        /* Set timeout status */
-                        CMD_RESULT(sp->cmd) = DID_TIME_OUT << 16;
-
-#if WATCHDOGTIMER
-                        /* Remove command from watchdog queue. */
-                        if (sp->flags & SRB_WATCHDOG)
-                            qla1280_timeout_remove(ha, sp);
-#endif
-                        COMTRACE('M') 
-                        CMD_HANDLE(sp->cmd) = (unsigned char *) 0;
-
-                        /* Call the mid-level driver interrupt handler */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-                        sti(); 
-                        (*(sp->cmd)->scsi_done)(sp->cmd);
-                        cli(); 
-#else
-                        (*(sp->cmd)->scsi_done)(sp->cmd);
-#endif
-
-                        /* Acquire LU queue specific lock */
-                        QLA1280_SCSILU_LOCK(q);
-
-                        if (q->q_outcnt)
-                            q->q_outcnt--;
-                    }
-                    else
-                        /* Acquire LU queue specific lock */
-                        QLA1280_SCSILU_LOCK(q);
-                }
-                else
-                {   /* Place request back on top of device queue. */
-                    qla1280_putq_t(q, sp);
-
-                    if (q->q_outcnt)
-                        q->q_outcnt--;
-                    if (q->q_outcnt < ha->bus_settings[b].hiwat)
-                        q->q_flag &= ~QLA1280_QBUSY;
-                    break;
-                }
-            }
-        }
-    }
-   DRIVER_UNLOCK
-
-    /* Release SCSI LU queue specific lock */
-    QLA1280_SCSILU_UNLOCK(q);
-
-    LEAVE("qla1280_next");
-}
+static void
+qla1280_done_q_put(struct srb * sp, struct srb ** done_q_first,
+		   struct srb ** done_q_last)
+{
+	ENTER("qla1280_put_done_q");
+
+	/* Place block on done queue */
+	sp->s_next = NULL;
+	sp->s_prev = *done_q_last;
+	if (!*done_q_first)
+		*done_q_first = sp;
+	else
+		(*done_q_last)->s_next = sp;
+	*done_q_last = sp;
 
-/*
- * qla1280_putq_t
- *      Add the standard SCB job to the top of standard SCB commands.
- *
- * Input:
- *      q  = SCSI LU pointer.
- *      sp = srb pointer.
- *      SCSI_LU_Q lock must be already obtained.
- */
-STATIC void
-qla1280_putq_t(scsi_lu_t *q, srb_t *sp)
-{
-    srb_t *srb_p;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_putq_t");
-#endif
-    DRIVER_LOCK
-    DEBUG(sprintf(debug_buff,"Adding to device 0x%p<-(0x%p)\n\r",q,sp));
-    DEBUG(qla1280_print(debug_buff));
-    sp->s_next = NULL;
-    if (!q->q_first)                  /* If queue empty */
-    {
-        sp->s_prev = NULL;
-        q->q_first = sp;
-        q->q_last = sp;
-    }
-    else
-    {      
-        srb_p = q->q_first;
-        while (srb_p )
-            srb_p = srb_p->s_next;
-
-        if (srb_p)
-        {
-            sp->s_prev = srb_p->s_prev;
-            if (srb_p->s_prev)
-                srb_p->s_prev->s_next = sp;
-            else
-                q->q_first = sp;
-            srb_p->s_prev = sp;
-            sp->s_next = srb_p;
-        }
-        else
-        {
-            sp->s_prev = q->q_last;
-            q->q_last->s_next = sp;
-            q->q_last = sp;
-        }
-    }
-
-    DRIVER_UNLOCK
-#ifdef QL_DEBUG_LEVEL_3
-            LEAVE("qla1280_putq_t");
-#endif
+	LEAVE("qla1280_put_done_q");
 }
 
-/*
- * qla1280_removeq
- *      Function used to remove a command block from the
- *      LU queue.
- *
- * Input:
- *      q  = SCSI LU pointer.
- *      sp = srb pointer.
- *      SCSI_LU_Q lock must be already obtained.
- */
-STATIC void
-qla1280_removeq(scsi_lu_t *q, srb_t *sp)
-{
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-    DEBUG(sprintf(debug_buff,"Removing from device_q (0x%p)->(0x%p)\n\r",q,sp));
-    DEBUG(qla1280_print(debug_buff));
-    DRIVER_LOCK
-            if (sp->s_prev)
-    {
-        if ((sp->s_prev->s_next = sp->s_next) != NULL)
-            sp->s_next->s_prev = sp->s_prev;
-        else
-            q->q_last = sp->s_prev;
-    }
-    else if (!(q->q_first = sp->s_next))
-        q->q_last = NULL;
-    else
-        q->q_first->s_prev = NULL;
-    DRIVER_UNLOCK
-}
 
 /*
 * qla1280_mem_alloc
@@ -2158,44 +1973,44 @@
 *      0  = success.
 *      1  = failure.
 */
-STATIC uint8_t
-qla1280_mem_alloc(scsi_qla_host_t *ha)
+static int
+qla1280_mem_alloc(struct scsi_qla_host *ha)
 {
+	int status = 1;
+	dma_addr_t dma_handle;
 
-	uint8_t   status = 1;
-
-#ifdef QL_DEBUG_LEVEL_3
 	ENTER("qla1280_mem_alloc");
-#endif
 
-#ifdef DYNAMIC_MEM_ALLOC
-	ha->request_ring = qla1280_alloc_phys(REQUEST_ENTRY_SIZE * REQUEST_ENTRY_CNT,
-	&ha->request_dma);
-	if(ha->request_ring) {
-		ha->response_ring = qla1280_alloc_phys(RESPONSE_ENTRY_SIZE * RESPONSE_ENTRY_CNT,
-		&ha->response_dma);
-		if(ha->response_ring) {
-			status = 0;
-		}
-	}
-#else
-	ha->request_ring = &ha->req[0];
-	ha->request_dma = VIRT_TO_BUS(&ha->req[0]);
-	ha->response_ring = &ha->res[0];
-	ha->response_dma = VIRT_TO_BUS(&ha->res[0]);
+	/* get consistent memory allocated for request and response rings */
+	ha->request_ring = pci_alloc_consistent(ha->pdev,
+						((REQUEST_ENTRY_CNT + 1) *
+						 (sizeof(request_t))),
+						&dma_handle);
+	if (!ha->request_ring)
+		goto error;
+	ha->request_dma = dma_handle;
+	ha->response_ring = pci_alloc_consistent(ha->pdev,
+						 ((RESPONSE_ENTRY_CNT + 1) *
+						  (sizeof(struct response))),
+						 &dma_handle);
+	if (!ha->response_ring)
+		goto error;
+	ha->response_dma = dma_handle;
 	status = 0;
-#endif
+	goto finish;
 
-	if(status) {
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-		qla1280_print("qla1280_mem_alloc: **** FAILED ****\n");
-#endif
-	}
-#ifdef QL_DEBUG_LEVEL_3
-	else
-		LEAVE("qla1280_mem_alloc");
-#endif
-	return(status);
+ error:
+	if (status)
+		dprintk(2, "qla1280_mem_alloc: **** FAILED ****\n");
+
+	if (ha->request_ring)
+		pci_free_consistent(ha->pdev,
+                                    ((REQUEST_ENTRY_CNT + 1) *
+				     (sizeof(request_t))),
+                                    ha->request_ring, ha->request_dma);
+ finish:
+	LEAVE("qla1280_mem_alloc");
+	return status;
 }
 
 /*
@@ -2205,66 +2020,68 @@
  * Input:
  *      ha = adapter block pointer.
  */
-STATIC void
-qla1280_mem_free(scsi_qla_host_t *ha)
+static void
+qla1280_mem_free(struct scsi_qla_host *ha)
 {
-    scsi_lu_t *q;
-    uint32_t  b, t, l;
-
-    ENTER("qlc1280_mem_free");
-    if (ha)
-    {
-        /* Free device queues. */
-        for (b = 0; b < MAX_BUSES; b++)
-        {
-            q = LU_Q(ha, b, ha->bus_settings[b].id, 0);
-            for (t = 0; t < MAX_TARGETS; t++)
-                for (l = 0; l < MAX_LUNS; l++)
-                    if (LU_Q(ha, b, t, l) != NULL && LU_Q(ha, b, t, l) != q)
-                        KMFREE(LU_Q(ha, b, t, l),sizeof(struct scsi_lu));
-                    KMFREE(q, sizeof(struct scsi_lu));
-        }
-        for( b =0; b < MAX_EQ; b++ )
-            ha->dev[b] =  (scsi_lu_t  *)NULL;
-    }
+	ENTER("qlc1280_mem_free");
+	/* free consistent memory allocated for request and response rings */
+	if (ha->request_ring)
+		pci_free_consistent(ha->pdev,
+				    ((REQUEST_ENTRY_CNT + 1) *
+				     (sizeof(request_t))),
+				    ha->request_ring, ha->request_dma);
+
+	if (ha->response_ring)
+		pci_free_consistent(ha->pdev,
+				    ((RESPONSE_ENTRY_CNT + 1) *
+				     (sizeof(struct response))),
+				    ha->response_ring, ha->response_dma);
+
+	if (qla1280_buffer) {
+		free_page((unsigned long) qla1280_buffer);
+		qla1280_buffer = NULL;
+	}
 
-    LEAVE("qlc1280_mem_free");
+	LEAVE("qlc1280_mem_free");
 }
 
-
-
-
 /****************************************************************************/
 /*                QLogic ISP1280 Hardware Support Functions.                */
 /****************************************************************************/
 
  /*
- * qla2100_enable_intrs
- * qla2100_disable_intrs
- *
- * Input:
- *      ha = adapter block pointer.
- *
- * Returns:
- *      None      
- */
-    static inline void qla1280_enable_intrs(scsi_qla_host_t *ha) {
-        device_reg_t *reg;
-
-        reg = ha->iobase;
-        ha->flags.interrupts_on = 1;
-        /* enable risc and host interrupts */
-        WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT+ ISP_EN_RISC));
-    }
-
-    static inline void qla1280_disable_intrs(scsi_qla_host_t *ha) {
-        device_reg_t *reg;
-
-        reg = ha->iobase;
-        ha->flags.interrupts_on = 0;
-        /* disable risc and host interrupts */
-        WRT_REG_WORD(&reg->ictrl, 0);
-    }
+    * qla2100_enable_intrs
+    * qla2100_disable_intrs
+    *
+    * Input:
+    *      ha = adapter block pointer.
+    *
+    * Returns:
+    *      None
+  */
+static inline void
+qla1280_enable_intrs(struct scsi_qla_host *ha)
+{
+	struct device_reg *reg;
+
+	reg = ha->iobase;
+	/* enable risc and host interrupts */
+	WRT_REG_WORD(&reg->ictrl, (ISP_EN_INT | ISP_EN_RISC));
+	RD_REG_WORD(&reg->ictrl);	/* PCI Posted Write flush */
+	ha->flags.ints_enabled = 1;
+}
+
+static inline void
+qla1280_disable_intrs(struct scsi_qla_host *ha)
+{
+	struct device_reg *reg;
+
+	reg = ha->iobase;
+	/* disable risc and host interrupts */
+	WRT_REG_WORD(&reg->ictrl, 0);
+	RD_REG_WORD(&reg->ictrl);	/* PCI Posted Write flush */
+	ha->flags.ints_enabled = 0;
+}
 
 /*
  * qla1280_initialize_adapter
@@ -2276,159 +2093,130 @@
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_initialize_adapter(scsi_qla_host_t *ha)
+static int
+qla1280_initialize_adapter(struct scsi_qla_host *ha)
 {
-    device_reg_t *reg;
-    uint8_t      status;
-    /* uint8_t      cnt; */
-    uint8_t      b;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_initialize_adapter");
-#endif
-
-    /* Clear adapter flags. */
-    ha->flags.online = FALSE;
-    ha->flags.isp_abort_needed = FALSE;
-    ha->flags.disable_host_adapter = FALSE;
-    ha->flags.reset_active = FALSE;
-    ha->flags.abort_isp_active = FALSE;
-    ha->flags.watchdog_enabled = FALSE;
-
-    DEBUG(printk("Configure PCI space for adapter...\n"));
-    if (!(status = qla1280_pci_config(ha)))
-    {
-        reg = ha->iobase;
-
-        /* Disable ISP interrupts. */
-        WRT_REG_WORD(&reg->ictrl, 0);
-
-        /* Insure mailbox registers are free. */
-        WRT_REG_WORD(&reg->semaphore, 0);
-        WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
-        WRT_REG_WORD(&reg->host_cmd, HC_CLR_HOST_INT);
-
-        /* If firmware needs to be loaded */
-        if (qla1280_verbose)
-         printk("scsi(%d): Determining if RISC is loaded...\n",(int)ha->host_no);
-        if (qla1280_isp_firmware(ha))
-        {
-            if (qla1280_verbose)
-              printk("scsi(%d): Verifying chip...\n",(int)ha->host_no);
-            if (!(status = qla1280_chip_diag(ha)))
-            {
-                if (qla1280_verbose)
-                  printk("scsi(%d): Setup chip...\n",(int)ha->host_no);
-                status = qla1280_setup_chip(ha); 
-            }
-        }
-
-        if (!status)
-        {
-            /* Setup adapter based on NVRAM parameters. */
-            if (qla1280_verbose)
-              printk("scsi(%d): Configure NVRAM parameters...\n",(int)ha->host_no);
-            qla1280_nvram_config(ha);
-
-            if (!ha->flags.disable_host_adapter &&
-                !qla1280_init_rings(ha))
-            {
-                /* Issue SCSI reset. */
-                for (b = 0; b < ha->ports; b++)
-                    if (!ha->bus_settings[b].disable_scsi_reset)
-                    {
-                      /* dg 03/13 if we can't reset twice then bus is dead */
-                        if( qla1280_bus_reset(ha, b) )
-                           if( qla1280_bus_reset(ha, b) )
-                           {
-                               ha->bus_settings[b].scsi_bus_dead = TRUE;
-                            }
-                    }
-
-                    do
-                    {
-                        /* Issue marker command. */
-                        ha->flags.reset_marker = FALSE;
-                        for (b = 0; b < ha->ports; b++)
-                        {
-                            ha->bus_settings[b].reset_marker = FALSE;
-                            qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL);
-                        }
-                    }while (ha->flags.reset_marker);
-
-                    ha->flags.online = TRUE;
-
-                    /* Enable host adapter target mode. */
-                    for (b = 0; b < ha->ports; b++)
-                    {
-                        if (!(status = qla1280_enable_tgt(ha, b)))
-                        {
-                            /* for (cnt = 0; cnt < MAX_LUNS; cnt++)
-                            {
-                                qla1280_enable_lun(ha, b, cnt);
-                                 qla1280_poll(ha);
-                            }*/
-                        }
-                        else
-                            break;
-                    }
-            }
-            else
-                status = 1;
-        }
-    }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_initialize_adapter: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_initialize_adapter");
+	struct device_reg *reg;
+	int status;
+	int bus;
+#if LINUX_VERSION_CODE > 0x020500
+	unsigned long flags;
+#endif
+
+	ENTER("qla1280_initialize_adapter");
+
+	/* Clear adapter flags. */
+	ha->flags.online = 0;
+	ha->flags.disable_host_adapter = 0;
+	ha->flags.reset_active = 0;
+	ha->flags.abort_isp_active = 0;
+
+	ha->flags.ints_enabled = 0;
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+	if (ia64_platform_is("sn2")) {
+		int count1, count2;
+		int c;
+
+		count1 = 3;
+		count2 = 3;
+		printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
+		       "dual channel lockup workaround\n", ha->host_no);
+		if ((c = snia_pcibr_rrb_alloc(ha->pdev, &count1, &count2)) < 0)
+			printk(KERN_ERR "scsi(%li): Unable to allocate SN2 "
+			       "virtual DMA channels\n", ha->host_no);
+		ha->flags.use_pci_vchannel = 1;
+
+		driver_setup.no_nvram = 1;
+	}
 #endif
-    return(status);
-}
 
-/*
- * qla1280_enable_tgt
- *      Enable target mode.
- *
- * Input:
- *      ha = adapter block pointer.
- *      b  = SCSI bus number.
- *
- * Returns:
- *      0 = success.
- */
-STATIC uint8_t
-qla1280_enable_tgt(scsi_qla_host_t *ha, uint8_t b)
-{
-    uint8_t     status = 0;
-    /*  uint16_t    mb[MAILBOX_REGISTER_COUNT]; */
+	dprintk(1, "Configure PCI space for adapter...\n");
+
+	reg = ha->iobase;
+
+	/* Insure mailbox registers are free. */
+	WRT_REG_WORD(&reg->semaphore, 0);
+	WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
+	WRT_REG_WORD(&reg->host_cmd, HC_CLR_HOST_INT);
+	RD_REG_WORD(&reg->host_cmd);
+
+	if (qla1280_read_nvram(ha)) {
+		dprintk(2, "qla1280_initialize_adapter: failed to read "
+			"NVRAM\n");
+	}
+
+#if LINUX_VERSION_CODE >= 0x020500
+	/*
+	 * It's necessary to grab the spin here as qla1280_mailbox_command
+	 * needs to be able to drop the lock unconditionally to wait
+	 * for completion.
+	 * In 2.4 ->detect is called with the io_request_lock held.
+	 */
+	spin_lock_irqsave(HOST_LOCK, flags);
+#endif
+	/* If firmware needs to be loaded */
+	if (qla1280_isp_firmware(ha)) {
+		if (!(status = qla1280_chip_diag (ha))) {
+			status = qla1280_setup_chip(ha);
+		}
+	} else {
+		printk(KERN_ERR "scsi(%li): isp_firmware() failed!\n",
+		       ha->host_no);
+		status = 1;
+	}
+
+	if (status) {
+		printk(KERN_ERR "scsi(%li): initialize: pci probe failed!\n",
+		       ha->host_no);
+		goto out;
+	}
+
+	/* Setup adapter based on NVRAM parameters. */
+	dprintk(1, "scsi(%ld): Configure NVRAM parameters\n", ha->host_no);
+	qla1280_nvram_config(ha);
+
+	if (!ha->flags.disable_host_adapter && !qla1280_init_rings(ha)) {
+		/* Issue SCSI reset. */
+		/* dg 03/13 if we can't reset twice then bus is dead */
+		for (bus = 0; bus < ha->ports; bus++) {
+			if (!ha->bus_settings[bus].disable_scsi_reset){
+				if (qla1280_bus_reset(ha, bus)) {
+					if (qla1280_bus_reset(ha, bus)) {
+						ha->bus_settings[bus].scsi_bus_dead = 1;
+					}
+				}
+			}
+		}
 
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_enable_tgt: entered\n\r");
+		/*
+		 * qla1280_bus_reset() will take care of issueing markers,
+		 * no need to do that here as well!
+		 */
+#if 0
+		/* Issue marker command. */
+		ha->flags.reset_marker = 0;
+		for (bus = 0; bus < ha->ports; bus++) {
+			ha->bus_settings[bus].reset_marker = 0;
+			qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL);
+		}
 #endif
 
-    /* Enable target mode. */
-    /*
-    mb[0] = MBC_ENABLE_TARGET_MODE;
-    mb[1] = BIT_15;
-    mb[2] = (uint16_t)(b << 15);
-    status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]);
-    */
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_enable_tgt: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_enable_tgt: exiting normally\n\r");
+		ha->flags.online = 1;
+	} else
+		status = 1;
+
+ out:
+#if LINUX_VERSION_CODE >= 0x020500
+	spin_unlock_irqrestore(HOST_LOCK, flags);
 #endif
-    return(status);
+	if (status)
+		dprintk(2, "qla1280_initialize_adapter: **** FAILED ****\n");
+
+	LEAVE("qla1280_initialize_adapter");
+	return status;
 }
 
+
 /*
  * ISP Firmware Test
  *      Checks if present version of RISC firmware is older than
@@ -2440,83 +2228,55 @@
  * Returns:
  *      0 = firmware does not need to be loaded.
  */
-STATIC uint8_t
-qla1280_isp_firmware(scsi_qla_host_t *ha)
+static int
+qla1280_isp_firmware(struct scsi_qla_host *ha)
 {
-    nvram_t     *nv    = (nvram_t *)ha->response_ring; 
-    uint16_t    *wptr;
-    uint8_t     chksum;
-    uint8_t     cnt;
-    uint8_t     status = 0;    /* dg 2/27 always loads RISC */
-    uint16_t    mb[MAILBOX_REGISTER_COUNT];
-
-    ENTER("qla1280_isp_firmware");
-
-    /* Verify valid NVRAM checksum. */
-    wptr = (uint16_t *)ha->response_ring;
-    DEBUG(printk("qla1280_isp_firmware: Reading NVRAM\n"));
-    chksum = 0;
-    for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++)
-    {
-        *wptr = qla1280_get_nvram_word(ha, cnt);
-        chksum += (uint8_t)*wptr;
-        chksum += (uint8_t)(*wptr >> 8);
-        wptr++;
-    }
-    DEBUG(printk("qla1280_isp_firmware: Completed Reading NVRAM\n"));
-
-#if defined(QL_DEBUG_LEVEL_3)
-    sprintf(debug_buff,"qla1280_isp_firmware: NVRAM Magic ID= %c %c %c\n\r",(char *) nv->id[0],nv->id[1],nv->id[2]);
-    qla1280_print(debug_buff);
-#endif
-
-    /* Bad NVRAM data, load RISC code. */
-    if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
-        nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1)
-    {
-        printk(KERN_INFO "qla1280_isp_firmware: Bad checksum or magic number or version in NVRAM.\n");
-        ha->flags.disable_risc_code_load = FALSE;
-    }
-    else
-        ha->flags.disable_risc_code_load = nv->cntr_flags_1.disable_loading_risc_code;
-
-    if (ha->flags.disable_risc_code_load)
-    {
-#if defined(QL_DEBUG_LEVEL_3)
-        qla1280_print("qla1280_isp_firmware: Telling RISC to verify checksum of loaded BIOS code.\n\r");
-#endif
-        /* Verify checksum of loaded RISC code. */
-        mb[0] = MBC_VERIFY_CHECKSUM;
-        /* mb[1] = ql12_risc_code_addr01; */
-        mb[1] = *QLBoardTbl[ha->devnum].fwstart;  
-
-        if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0])))
-        {
-            /* Start firmware execution. */
-#if defined(QL_DEBUG_LEVEL_3)
-            qla1280_print("qla1280_isp_firmware: Startng F/W execution.\n\r");
-#endif
-            mb[0] = MBC_EXECUTE_FIRMWARE;
-            /* mb[1] = ql12_risc_code_addr01; */
-            mb[1] = *QLBoardTbl[ha->devnum].fwstart;  
-            qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
-        }
-        else
-            printk(KERN_INFO "qla1280: RISC checksum failed.\n");
-    }
-    else
-    {
-        DEBUG(printk("qla1280: NVRAM configured to load RISC load.\n"));
-        status = 1;
-     }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print(
-                "qla1280_isp_firmware: **** Load RISC code ****\n\r");
-#endif
-    LEAVE("qla1280_isp_firmware");
-    return(status);
+	struct nvram *nv = (struct nvram *) ha->response_ring;
+	int status = 0;		/* dg 2/27 always loads RISC */
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+
+	ENTER("qla1280_isp_firmware");
+
+	dprintk(1, "scsi(%li): Determining if RISC is loaded\n", ha->host_no);
+
+	/* Bad NVRAM data, load RISC code. */
+	if (!ha->nvram_valid) {
+		ha->flags.disable_risc_code_load = 0;
+	} else
+		ha->flags.disable_risc_code_load =
+			nv->cntr_flags_1.disable_loading_risc_code;
+
+	if (ha->flags.disable_risc_code_load) {
+		dprintk(3, "qla1280_isp_firmware: Telling RISC to verify "
+			"checksum of loaded BIOS code.\n");
+
+		/* Verify checksum of loaded RISC code. */
+		mb[0] = MBC_VERIFY_CHECKSUM;
+		/* mb[1] = ql12_risc_code_addr01; */
+		mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+
+		if (!(status =
+		      qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
+			/* Start firmware execution. */
+			dprintk(3, "qla1280_isp_firmware: Startng F/W "
+				"execution.\n");
+
+			mb[0] = MBC_EXECUTE_FIRMWARE;
+			/* mb[1] = ql12_risc_code_addr01; */
+			mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+			qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+		} else
+			printk(KERN_INFO "qla1280: RISC checksum failed.\n");
+	} else {
+		dprintk(1, "qla1280: NVRAM configured to load RISC load.\n");
+		status = 1;
+	}
+
+	if (status)
+		dprintk(2, "qla1280_isp_firmware: **** Load RISC code ****\n");
+
+	LEAVE("qla1280_isp_firmware");
+	return status;
 }
 
 /*
@@ -2529,75 +2289,60 @@
  * Returns:
  *      0 = success.
  */
-STATIC uint8_t
-qla1280_pci_config(scsi_qla_host_t *ha)
+static int
+qla1280_pci_config(struct scsi_qla_host *ha)
 {
-    uint8_t      status = 1;
-    uint32_t     command;
 #if MEMORY_MAPPED_IO
-    uint32_t  page_offset, base;
-    uint32_t   mmapbase;
+	unsigned long base;
+	int size;
 #endif
-    config_reg_t *creg = 0;
-    uint16_t     buf_wd;
+	uint16_t buf_wd;
+	int status = 1;
 
-    ENTER("qla1280_pci_config");
+	ENTER("qla1280_pci_config");
 
-    /* Get command register. */
-    if (pci_read_config_word(ha->pdev,OFFSET(creg->command), &buf_wd) == PCIBIOS_SUCCESSFUL)
-    {
-        command = buf_wd;
-        /*
-        * Set Bus Master Enable, Memory Address Space Enable and
-        * reset any error bits.
-        */
-        buf_wd &= ~0x7;
+	pci_set_master(ha->pdev);
+	/*
+	 * Set Bus Master Enable, Memory Address Space Enable and
+	 * reset any error bits, in the command register.
+	 */
+	pci_read_config_word (ha->pdev, PCI_COMMAND, &buf_wd);
 #if MEMORY_MAPPED_IO
-        DEBUG(printk("qla1280: MEMORY MAPPED IO is enabled.\n"));
-        buf_wd |= BIT_2 + BIT_1 + BIT_0;
-#else
-        buf_wd |= BIT_2 + BIT_0;
+	buf_wd |= PCI_COMMAND_MEMORY;
 #endif
-        if( pci_write_config_word(ha->pdev,OFFSET(creg->command), buf_wd) )
-        {
-            printk(KERN_WARNING "qla1280: Could not write config word.\n");
-        }
-        /* Get expansion ROM address. */
-        if (pci_read_config_word(ha->pdev,OFFSET(creg->expansion_rom), &buf_wd) == PCIBIOS_SUCCESSFUL)
-        {
-            /* Reset expansion ROM address decode enable. */
-            buf_wd &= ~BIT_0;
-            if (pci_write_config_word(ha->pdev,OFFSET(creg->expansion_rom), buf_wd) == PCIBIOS_SUCCESSFUL)
-            {
+	buf_wd |= PCI_COMMAND_IO;
+	pci_write_config_word (ha->pdev, PCI_COMMAND, buf_wd);
+	/*
+	 * Reset expansion ROM address decode enable.
+	 */
+	pci_read_config_word(ha->pdev, PCI_ROM_ADDRESS, &buf_wd);
+	buf_wd &= ~PCI_ROM_ADDRESS_ENABLE;
+	pci_write_config_word (ha->pdev, PCI_ROM_ADDRESS, buf_wd);
+
+	ha->host->io_port = pci_resource_start(ha->pdev, 0);
+	ha->host->io_port &= PCI_BASE_ADDRESS_IO_MASK;
+	ha->iobase = (struct device_reg *) ha->host->io_port;
+
 #if MEMORY_MAPPED_IO
-                /* Get memory mapped I/O address. */
-                pci_read_config_dword(ha->pdev,OFFSET(cfgp->mem_base_addr), &mmapbase);
-                mmapbase &= PCI_BASE_ADDRESS_MEM_MASK;
-
-                /* Find proper memory chunk for memory map I/O reg. */
-                base = mmapbase & PAGE_MASK;
-                page_offset = mmapbase - base;
-                /* Get virtual address for I/O registers. */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-                ha->mmpbase = ioremap_nocache(base, page_offset + 256);
-#else
-                ha->mmpbase = vremap(base,page_offset + 256);
-#endif
-                if( ha->mmpbase )
-                {
-                    ha->mmpbase += page_offset;
-                    /* ha->iobase = ha->mmpbase; */
-                    status = 0;
-                }
-#else /* MEMORY_MAPPED_IO */
-                status = 0;
-#endif /* MEMORY_MAPPED_IO */
-            }
-        }
-    }
+	/*
+	 * Find proper memory chunk for memory map I/O reg.
+	 */
+	base = pci_resource_start(ha->pdev, 1);
+	size = pci_resource_len(ha->pdev, 1);
+	/*
+	 * Get virtual address for I/O registers.
+	 */
+	ha->mmpbase = ioremap(base, size);
+	if (ha->mmpbase) {
+		ha->iobase = (struct device_reg *)ha->mmpbase;
+		status = 0;
+	}
+#else				/* MEMORY_MAPPED_IO */
+	status = 0;
+#endif				/* MEMORY_MAPPED_IO */
 
-    LEAVE("qla1280_pci_config");
-    return(status);
+	LEAVE("qla1280_pci_config");
+	return status;
 }
 
 /*
@@ -2610,109 +2355,129 @@
  * Returns:
  *      0 = success.
  */
-STATIC uint8_t
-qla1280_chip_diag(scsi_qla_host_t *ha)
+static int
+qla1280_chip_diag(struct scsi_qla_host *ha)
 {
-    device_reg_t *reg   = ha->iobase;
-    uint8_t      status = 0;
-    uint16_t     data;
-    uint32_t     cnt;
-    uint16_t     mb[MAILBOX_REGISTER_COUNT];
-
-#ifdef QL_DEBUG_LEVEL_3
-    sprintf(debug_buff, "qla1280_chip_diag: testing device at 0x%p \n\r",&reg->id_l);
-    qla1280_print(debug_buff);
-#endif
-
-    /* Soft reset chip and wait for it to finish. */
-    WRT_REG_WORD(&reg->ictrl, ISP_RESET); 
-    data = qla1280_debounce_register(&reg->ictrl);
-    for (cnt = 6000000; cnt && data & ISP_RESET; cnt--)
-    {
-        SYS_DELAY(5);
-        data = RD_REG_WORD(&reg->ictrl);
-    }
-    if (cnt)
-    {
-        /* Reset register not cleared by chip reset. */
-#if defined(QL_DEBUG_LEVEL_3)
-        qla1280_print("qla1280_chip_diag: reset register cleared by chip reset\n\r");
-#endif
-        WRT_REG_WORD(&reg->cfg_1, 0);
-
-        /* Reset RISC and disable BIOS which
-        allows RISC to execute out of RAM. */
-        WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC);
-        WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
-        WRT_REG_WORD(&reg->host_cmd, HC_DISABLE_BIOS);
-        data = qla1280_debounce_register(&reg->mailbox0);
-        for (cnt = 6000000; cnt && data == MBS_BUSY; cnt--)
-        {
-            SYS_DELAY(5);
-            data = RD_REG_WORD(&reg->mailbox0);
-        }
-
-        if (cnt)
-        {
-            /* Check product ID of chip */
-#if defined(QL_DEBUG_LEVEL_3)
-            qla1280_print("qla1280_chip_diag: Checking product ID of chip\n\r");
-#endif
-            if (RD_REG_WORD(&reg->mailbox1) != PROD_ID_1 ||
-                (RD_REG_WORD(&reg->mailbox2) != PROD_ID_2 &&
-                RD_REG_WORD(&reg->mailbox2) != PROD_ID_2a) ||
-                RD_REG_WORD(&reg->mailbox3) != PROD_ID_3 ||
-                RD_REG_WORD(&reg->mailbox4) != PROD_ID_4)
-            {
-                printk(KERN_INFO "qla1280: Wrong product ID = 0x%x,0x%x,0x%x,0x%x\n",
-                        RD_REG_WORD(&reg->mailbox1),
-                        RD_REG_WORD(&reg->mailbox2),
-                        RD_REG_WORD(&reg->mailbox3),
-                        RD_REG_WORD(&reg->mailbox4) );
-                status = 1;
-            }
-            else
-            {
-                DEBUG(printk("qla1280_chip_diag: Checking mailboxes of chip\n"));
-                /* Wrap Incoming Mailboxes Test. */
-                mb[0] = MBC_MAILBOX_REGISTER_TEST;
-                mb[1] = 0xAAAA;
-                mb[2] = 0x5555;
-                mb[3] = 0xAA55;
-                mb[4] = 0x55AA;
-                mb[5] = 0xA5A5;
-                mb[6] = 0x5A5A;
-                mb[7] = 0x2525;
-                if (!(status = qla1280_mailbox_command(ha,
-                    (BIT_7|BIT_6|BIT_5|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0),
-                    &mb[0])))
-                {
-                    if (mb[1] != 0xAAAA || mb[2] != 0x5555 ||
-                        mb[3] != 0xAA55 || mb[4] != 0x55AA)
-                        status = 1;
-                    if (mb[5] != 0xA5A5 || mb[6] != 0x5A5A ||
-                        mb[7] != 0x2525)
-                        status = 1;
-                    if( status == 1 )
-                        printk(KERN_INFO "qla1280: Failed mailbox check\n");
-                }
-            }
-        }
-        else
-            status = 1;
-    }
-    else
-        status = 1;
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_chip_diag: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_chip_diag: exiting normally\n\r");
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	struct device_reg *reg = ha->iobase;
+	int status = 0;
+	int cnt;
+	uint16_t data;
+
+	dprintk(3, "qla1280_chip_diag: testing device at 0x%p \n", &reg->id_l);
+
+	dprintk(1, "scsi(%ld): Verifying chip\n", ha->host_no);
+
+	/* Soft reset chip and wait for it to finish. */
+	WRT_REG_WORD(&reg->ictrl, ISP_RESET);
+	/*
+	 * We can't do a traditional PCI write flush here by reading
+	 * back the register. The card will not respond once the reset
+	 * is in action and we end up with a machine check exception
+	 * instead. Nothing to do but wait and hope for the best.
+	 * A portable pci_write_flush(pdev) call would be very useful here.
+	 */
+	udelay(20);
+	data = qla1280_debounce_register(&reg->ictrl);
+	/*
+	 * Yet another QLogic gem ;-(
+	 */
+	for (cnt = 1000000; cnt && data & ISP_RESET; cnt--) {
+		udelay(5);
+		data = RD_REG_WORD(&reg->ictrl);
+	}
+
+	if (cnt) {
+		/* Reset register cleared by chip reset. */
+		dprintk(3, "qla1280_chip_diag: reset register cleared by "
+			"chip reset\n");
+
+		WRT_REG_WORD(&reg->cfg_1, 0);
+
+		/* Reset RISC and disable BIOS which
+		   allows RISC to execute out of RAM. */
+#if 0
+		WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC);
+		RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+		WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
+		RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+		WRT_REG_WORD(&reg->host_cmd, HC_DISABLE_BIOS);
+#else
+		WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC |
+			     HC_RELEASE_RISC | HC_DISABLE_BIOS);
 #endif
-    return(status);
+		RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+		data = qla1280_debounce_register(&reg->mailbox0);
+		/*
+		 * I *LOVE* this code!
+		 */
+		for (cnt = 1000000; cnt && data == MBS_BUSY; cnt--) {
+			udelay(5);
+			data = RD_REG_WORD(&reg->mailbox0);
+		}
+
+		if (cnt) {
+			/* Check product ID of chip */
+			dprintk(3, "qla1280_chip_diag: Checking product "
+				"ID of chip\n");
+
+			if (RD_REG_WORD(&reg->mailbox1) != PROD_ID_1 ||
+			    (RD_REG_WORD(&reg->mailbox2) != PROD_ID_2 &&
+			     RD_REG_WORD(&reg->mailbox2) != PROD_ID_2a) ||
+			    RD_REG_WORD(&reg->mailbox3) != PROD_ID_3 ||
+			    RD_REG_WORD(&reg->mailbox4) != PROD_ID_4) {
+				printk(KERN_INFO "qla1280: Wrong product ID = "
+				       "0x%x,0x%x,0x%x,0x%x\n",
+				       RD_REG_WORD(&reg->mailbox1),
+				       RD_REG_WORD(&reg->mailbox2),
+				       RD_REG_WORD(&reg->mailbox3),
+				       RD_REG_WORD(&reg->mailbox4));
+				status = 1;
+			} else {
+				/*
+				 * Enable ints early!!!
+				 */
+				qla1280_enable_intrs(ha);
+
+				dprintk(1, "qla1280_chip_diag: Checking "
+					"mailboxes of chip\n");
+				/* Wrap Incoming Mailboxes Test. */
+				mb[0] = MBC_MAILBOX_REGISTER_TEST;
+				mb[1] = 0xAAAA;
+				mb[2] = 0x5555;
+				mb[3] = 0xAA55;
+				mb[4] = 0x55AA;
+				mb[5] = 0xA5A5;
+				mb[6] = 0x5A5A;
+				mb[7] = 0x2525;
+				if (!(status = qla1280_mailbox_command(ha,
+								       0xff,
+								       &mb
+								       [0]))) {
+					if (mb[1] != 0xAAAA ||
+					    mb[2] != 0x5555 ||
+					    mb[3] != 0xAA55 ||
+					    mb[4] != 0x55AA ||
+					    mb[5] != 0xA5A5 ||
+					    mb[6] != 0x5A5A ||
+					    mb[7] != 0x2525) {
+						status = 1;
+						printk(KERN_INFO "qla1280: "
+						       "Failed mbox check\n");
+					}
+				}
+			}
+		} else
+			status = 1;
+	} else
+		status = 1;
+
+	if (status)
+		dprintk(2, "qla1280_chip_diag: **** FAILED ****\n");
+	else
+		dprintk(3, "qla1280_chip_diag: exiting normally\n");
+
+	return status;
 }
 
 /*
@@ -2725,173 +2490,142 @@
  * Returns:
  *      0 = success.
  */
-STATIC uint8_t
-qla1280_setup_chip(scsi_qla_host_t *ha)
-{
-    uint8_t      status = 0;
-    uint16_t     risc_address;
-    uint16_t     *risc_code_address;
-    long         risc_code_size;
-    uint16_t     mb[MAILBOX_REGISTER_COUNT];
-#ifdef QLA1280_UNUSED
-    uint8_t	*sp;
-    int i;
-#endif
-    uint16_t     cnt;
-    int          num;
-    uint8_t    *tbuf;
-    u_long     p_tbuf;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_setup_chip");
-#endif
-
-	if( (tbuf = (uint8_t *)KMALLOC(8000) ) == NULL )
-        {
-            printk("setup_chip: couldn't alloacte memory\n");
-            return(1);
-        }
-        p_tbuf =  VIRT_TO_BUS(tbuf);
-    /* Load RISC code. */
-    /* 
-    risc_address      = ql12_risc_code_addr01;
-    risc_code_address = &ql12_risc_code01[0];
-    risc_code_size    = ql12_risc_code_length01;
-    */
-    risc_address = *QLBoardTbl[ha->devnum].fwstart;  
-    risc_code_address = QLBoardTbl[ha->devnum].fwcode;  
-    risc_code_size    = (long)(*QLBoardTbl[ha->devnum].fwlen & 0xffff);  
-
-    DEBUG(printk("qla1280: DMAing RISC code (%d) words.\n",(int)risc_code_size));
-    DEBUG(sprintf(debug_buff,"qla1280_setup_chip:  Loading RISC code size =(%ld).\n\r",risc_code_size);)
-    DEBUG(qla1280_print(debug_buff));
-    num =0;
-    while (risc_code_size > 0 && !status)
-    {
-        cnt = 2000 >> 1;
-
-        if ( cnt > risc_code_size ) 
-            cnt = risc_code_size;
-
-        DEBUG(sprintf(debug_buff,"qla1280_setup_chip:  loading risc @ =(0x%p),%d,%d(0x%x).\n\r",risc_code_address,cnt,num,risc_address);)
-        DEBUG(qla1280_print(debug_buff));
-        DEBUG(printk("qla1280_setup_chip:  loading risc @ =code=(0x%p),cnt=%d,seg=%d,addr=0x%x\n\r",risc_code_address,cnt,num,risc_address));
-        BCOPY((caddr_t) risc_code_address,(caddr_t) ha->request_ring, (cnt <<1));
-        mb[0] = MBC_LOAD_RAM; 
-        /* mb[0] = MBC_LOAD_RAM_A64; */
-        mb[1] = risc_address;
-        mb[4] = cnt;
-        mb[3] = (uint16_t)  ha->request_dma & 0xffff;
-        mb[2] = (uint16_t) (ha->request_dma >> 16) & 0xffff;
-        mb[7] = (uint16_t) (MS_64BITS(ha->request_dma) & 0xffff);
-        mb[6] = (uint16_t) (MS_64BITS(ha->request_dma) >> 16) & 0xffff;
-        DEBUG(printk("qla1280_setup_chip: op=%d  0x%lx = 0x%4x,0x%4x,0x%4x,0x%4x\n",mb[0],ha->request_dma,mb[6],mb[7],mb[2],mb[3]));
-        if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0,
-            &mb[0]))  )
-        {
-            printk("Failed to load partial segment of f/w\n");
-            break;
-        }
-        /* dump it back */
+#define DUMP_IT_BACK 0		/* for debug of RISC loading */
+static int
+qla1280_setup_chip(struct scsi_qla_host *ha)
+{
+	int status = 0;
+	uint16_t risc_address;
+	uint16_t *risc_code_address;
+	int risc_code_size;
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	uint16_t cnt;
+	int num, i;
+#if DUMP_IT_BACK
+	uint8_t *sp;
+	uint8_t *tbuf;
+	dma_addr_t p_tbuf;
+#endif
+
+	ENTER("qla1280_setup_chip");
+
+	dprintk(1, "scsi(%ld): Setup chip\n", ha->host_no);
+
+#if DUMP_IT_BACK
+	/* get consistent memory allocated for setup_chip */
+	tbuf = pci_alloc_consistent(ha->pdev, 8000, &p_tbuf);
+#endif
+
+	/* Load RISC code. */
+	risc_address = *ql1280_board_tbl[ha->devnum].fwstart;
+	risc_code_address = ql1280_board_tbl[ha->devnum].fwcode;
+	risc_code_size = (int) *ql1280_board_tbl[ha->devnum].fwlen;
+
+	dprintk(1, "qla1280_setup_chip: DMA RISC code (%i) words\n",
+		risc_code_size);
+
+	num = 0;
+	while (risc_code_size > 0 && !status) {
+		int warn __attribute__((unused)) = 0;
+
+		cnt = 2000 >> 1;
+
+		if (cnt > risc_code_size)
+			cnt = risc_code_size;
+
+		dprintk(2, "qla1280_setup_chip:  loading risc @ =(0x%p),"
+			"%d,%d(0x%x)\n",
+			risc_code_address, cnt, num, risc_address);
+		for(i = 0; i < cnt; i++)
+			((uint16_t *)ha->request_ring)[i] =
+				cpu_to_le16(risc_code_address[i]);
+
+		flush_cache_all();
+
+		mb[0] = MBC_LOAD_RAM;
+		mb[1] = risc_address;
+		mb[4] = cnt;
+		mb[3] = ha->request_dma & 0xffff;
+		mb[2] = (ha->request_dma >> 16) & 0xffff;
+		mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
+		mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
+		dprintk(2, "qla1280_setup_chip: op=%d  0x%p = 0x%4x,0x%4x,"
+			"0x%4x,0x%4x\n", mb[0], (void *)(long)ha->request_dma,
+			mb[6], mb[7], mb[2], mb[3]);
+		if ((status = qla1280_mailbox_command(ha, BIT_4 | BIT_3 |
+						      BIT_2 | BIT_1 | BIT_0,
+						      &mb[0]))) {
+			printk(KERN_ERR "scsi(%li): Failed to load partial "
+			       "segment of f\n", ha->host_no);
+			break;
+		}
 
-#if 0
-        mb[0] = MBC_DUMP_RAM_A64;
-        mb[1] = risc_address;
-        mb[4] = cnt;
-        mb[3] = (uint16_t)  p_tbuf & 0xffff;
-        mb[2] = (uint16_t) (p_tbuf >> 16) & 0xffff;
-        mb[7] = (uint16_t) (p_tbuf >> 32) & 0xffff;
-        mb[6] = (uint16_t) (p_tbuf >> 48) & 0xffff;
-
-        if( (status = qla1280_mailbox_command(ha, BIT_4|BIT_3|BIT_2|BIT_1|BIT_0,
-            &mb[0]))  )
-        {
-            printk("Failed to dump partial segment of f/w\n");
-            break;
-        }
-        sp =  (uint8_t *)ha->request_ring;
-        for (i = 0; i < (cnt<< 1) ; i++)
-        {
-            if( tbuf[i] != sp[i] )
-            {
-               printk("qla1280 : firmware compare error @ byte (0x%x)\n",i);
-                break;
-            }
-        }
-
-#endif
-        risc_address += cnt;
-        risc_code_size = risc_code_size - cnt;
-        risc_code_address = risc_code_address + cnt;
-        num++;
-    }
-#ifdef QLA1280_UNUSED
-    DEBUG(ql_debug_print = 0;)
-    {
-        for (i = 0; i < ql12_risc_code_length01; i++)
-        {
-            mb[0] = 0x4;
-            mb[1] = ql12_risc_code_addr01 + i;
-            mb[2] = ql12_risc_code01[i];
-
-            status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0,
-                    &mb[0]);
-            if (status)
-            {
-                printk("qla1280 : firmware load failure\n");
-                break;
-            }
-
-            mb[0] = 0x5;
-            mb[1] = ql12_risc_code_addr01 + i;
-            mb[2] = 0;
-
-            status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0,
-                    &mb[0]);
-            if (status)
-            {
-                printk("qla1280 : firmware dump failure\n");
-                break;
-            }
-            if( mb[2] != ql12_risc_code01[i] )
-                printk("qla1280 : firmware compare error @ (0x%x)\n",ql12_risc_code_addr01+i);
-        }
-    }
-    DEBUG(ql_debug_print = 1;)
-#endif
-
-    /* Verify checksum of loaded RISC code. */
-    if (!status)
-    {
-        DEBUG(printk("qla1280_setup_chip: Verifying checksum of loaded RISC code.\n");)
-        mb[0] = MBC_VERIFY_CHECKSUM;
-        /* mb[1] = ql12_risc_code_addr01; */
-        mb[1] = *QLBoardTbl[ha->devnum].fwstart;  
-        
-        if (!(status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0])))
-        {
-            /* Start firmware execution. */
-            DEBUG(qla1280_print("qla1280_setup_chip: start firmware running.\n\r");)
-            mb[0] = MBC_EXECUTE_FIRMWARE;
-            /* mb[1] = ql12_risc_code_addr01; */
-            mb[1] = *QLBoardTbl[ha->devnum].fwstart;  
-            qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
-        }
-        else
-            printk("qla1280_setup_chip: Failed checksum.\n");
-    }
-
-	KMFREE(tbuf,8000);
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_setup_chip: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_setup_chip");
+#if DUMP_IT_BACK
+		mb[0] = MBC_DUMP_RAM;
+		mb[1] = risc_address;
+		mb[4] = cnt;
+		mb[3] = p_tbuf & 0xffff;
+		mb[2] = (p_tbuf >> 16) & 0xffff;
+		mb[7] = pci_dma_hi32(p_tbuf) & 0xffff;
+		mb[6] = pci_dma_hi32(p_tbuf) >> 16;
+
+		if ((status = qla1280_mailbox_command(ha,
+						      BIT_4 | BIT_3 | BIT_2 |
+						      BIT_1 | BIT_0,
+						      &mb[0]))) {
+			printk(KERN_ERR
+			       "Failed to dump partial segment of f/w\n");
+			break;
+		}
+		sp = (uint8_t *)ha->request_ring;
+		for (i = 0; i < (cnt << 1); i++) {
+			if (tbuf[i] != sp[i] && warn++ < 10) {
+				printk(KERN_ERR "qla1280_setup_chip: FW "
+				       "compare error @ byte(0x%x) loop#=%x\n",
+				       i, num);
+				printk(KERN_ERR "setup_chip: FWbyte=%x  "
+				       "FWfromChip=%x\n", sp[i], tbuf[i]);
+				/*break; */
+			}
+		}
+#endif
+		risc_address += cnt;
+		risc_code_size = risc_code_size - cnt;
+		risc_code_address = risc_code_address + cnt;
+		num++;
+	}
+
+	/* Verify checksum of loaded RISC code. */
+	if (!status) {
+		dprintk(1, "qla1280_setup_chip: Verifying checksum of "
+			"loaded RISC code.\n");
+		mb[0] = MBC_VERIFY_CHECKSUM;
+		/* mb[1] = ql12_risc_code_addr01; */
+		mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+
+		if (!(status =
+		      qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]))) {
+			/* Start firmware execution. */
+			dprintk(1,
+				"qla1280_setup_chip: start firmware running.\n");
+			mb[0] = MBC_EXECUTE_FIRMWARE;
+			mb[1] = *ql1280_board_tbl[ha->devnum].fwstart;
+			qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+		} else
+			printk(KERN_ERR "scsi(%li): qla1280_setup_chip: "
+			       "Failed checksum\n", ha->host_no);
+	}
+
+#if DUMP_IT_BACK
+	/* free consistent memory allocated for setup_chip */
+	pci_free_consistent(ha->pdev, 8000, tbuf, p_tbuf);
 #endif
-    return(status);
+
+	if (status)
+		dprintk(2, "qla1280_setup_chip: **** FAILED ****\n");
+
+	LEAVE("qla1280_setup_chip");
+	return status;
 }
 
 /*
@@ -2907,61 +2641,54 @@
  * Returns:
  *      0 = success.
  */
-STATIC uint8_t
-qla1280_init_rings(scsi_qla_host_t *ha)
+static int
+qla1280_init_rings(struct scsi_qla_host *ha)
 {
-    uint8_t     status = 0;
-    uint16_t    cnt;
-    uint16_t    mb[MAILBOX_REGISTER_COUNT];
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_init_rings");
-#endif
-    /* Clear outstanding commands array. */
-    for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
-        ha->outstanding_cmds[cnt] = 0;
-
-    /* Initialize request queue. */
-    ha->request_ring_ptr = ha->request_ring;
-    ha->req_ring_index   = 0;
-    ha->req_q_cnt        = REQUEST_ENTRY_CNT;
-    /* mb[0] = MBC_INIT_REQUEST_QUEUE; */
-    mb[0] = MBC_INIT_REQUEST_QUEUE_A64;
-    mb[1] = REQUEST_ENTRY_CNT;
-    mb[3] = (uint16_t)LS_64BITS(ha->request_dma);
-    mb[2] = (uint16_t)( LS_64BITS(ha->request_dma) >> 16);
-    mb[4] = 0;
-    mb[7] = (uint16_t)MS_64BITS(ha->request_dma);
-    mb[6] = (uint16_t)( MS_64BITS(ha->request_dma) >> 16);
-    if (!(status = qla1280_mailbox_command(ha,
-        BIT_7|BIT_6|BIT_4|BIT_3|BIT_2|BIT_1|BIT_0,
-        &mb[0])))
-    {
-        /* Initialize response queue. */
-        ha->response_ring_ptr = ha->response_ring;
-        ha->rsp_ring_index    = 0;
-        /* mb[0] = MBC_INIT_RESPONSE_QUEUE; */
-        mb[0] = MBC_INIT_RESPONSE_QUEUE_A64;
-        mb[1] = RESPONSE_ENTRY_CNT;
-        mb[3] = (uint16_t)LS_64BITS(ha->response_dma);
-        mb[2] = (uint16_t)(LS_64BITS(ha->response_dma) >> 16);
-        mb[5] = 0;
-        mb[7] = (uint16_t)MS_64BITS(ha->response_dma);
-        mb[6] = (uint16_t)(MS_64BITS(ha->response_dma) >> 16);
-        status = qla1280_mailbox_command(ha,
-                BIT_7|BIT_6|BIT_5|BIT_3|BIT_2|BIT_1|BIT_0,
-                &mb[0]);
-    }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_init_rings: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_init_rings");
-#endif
-    return(status);
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	int status = 0;
+
+	ENTER("qla1280_init_rings");
+
+	/* Clear outstanding commands array. */
+	memset(ha->outstanding_cmds, 0,
+	       sizeof(struct srb *) * MAX_OUTSTANDING_COMMANDS);
+
+	/* Initialize request queue. */
+	ha->request_ring_ptr = ha->request_ring;
+	ha->req_ring_index = 0;
+	ha->req_q_cnt = REQUEST_ENTRY_CNT;
+	/* mb[0] = MBC_INIT_REQUEST_QUEUE; */
+	mb[0] = MBC_INIT_REQUEST_QUEUE_A64;
+	mb[1] = REQUEST_ENTRY_CNT;
+	mb[3] = ha->request_dma & 0xffff;
+	mb[2] = (ha->request_dma >> 16) & 0xffff;
+	mb[4] = 0;
+	mb[7] = pci_dma_hi32(ha->request_dma) & 0xffff;
+	mb[6] = pci_dma_hi32(ha->request_dma) >> 16;
+	if (!(status = qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_4 |
+					       BIT_3 | BIT_2 | BIT_1 | BIT_0,
+					       &mb[0]))) {
+		/* Initialize response queue. */
+		ha->response_ring_ptr = ha->response_ring;
+		ha->rsp_ring_index = 0;
+		/* mb[0] = MBC_INIT_RESPONSE_QUEUE; */
+		mb[0] = MBC_INIT_RESPONSE_QUEUE_A64;
+		mb[1] = RESPONSE_ENTRY_CNT;
+		mb[3] = ha->response_dma & 0xffff;
+		mb[2] = (ha->response_dma >> 16) & 0xffff;
+		mb[5] = 0;
+		mb[7] = pci_dma_hi32(ha->response_dma) & 0xffff;
+		mb[6] = pci_dma_hi32(ha->response_dma) >> 16;
+		status = qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_5 |
+						 BIT_3 | BIT_2 | BIT_1 | BIT_0,
+						 &mb[0]);
+	}
+
+	if (status)
+		dprintk(2, "qla1280_init_rings: **** FAILED ****\n");
+
+	LEAVE("qla1280_init_rings");
+	return status;
 }
 
 /*
@@ -2977,322 +2704,366 @@
  * Returns:
  *      0 = success.
  */
-STATIC uint8_t
-qla1280_nvram_config(scsi_qla_host_t *ha)
+static int
+qla1280_nvram_config(struct scsi_qla_host *ha)
 {
-    device_reg_t *reg   = ha->iobase;
-    nvram_t      *nv    = (nvram_t *)ha->response_ring; 
-    uint8_t      status = 0;
-    uint32_t     b, t, l;
-    uint16_t     *wptr;
-    uint16_t     mb[MAILBOX_REGISTER_COUNT];
-    uint8_t      cnt;
-    uint8_t      chksum;
-    uint32_t     nvsize;
-
-#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4)
-    uint8_t      saved_print_status = ql_debug_print;
-#endif
-    ENTER("qla1280_nvram_config");
-#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4)
-    ql_debug_print = FALSE;
-#endif
-
-    /* Verify valid NVRAM checksum. */
-#if  USE_NVRAM_DEFAULTS
-    chksum = 1;
-#else
-    wptr = (uint16_t *)ha->response_ring;
-    chksum = 0;
-    if( ha->device_id == QLA12160_DEVICE_ID ||  
-        ha->device_id == QLA10160_DEVICE_ID )  
-    nvsize = sizeof(nvram160_t)/2;
-    else
-    nvsize = sizeof(nvram_t)/2;
-    for( cnt = 0; cnt < nvsize; cnt++ ) 
-    {
-        *wptr = qla1280_get_nvram_word(ha, cnt); 
-        chksum += (uint8_t)*wptr;
-        chksum += (uint8_t)(*wptr >> 8);
-        wptr++;
-    }
-#endif
-
+	struct device_reg *reg = ha->iobase;
+	struct nvram *nv;
+	int is1x160, status = 0;
+	int bus, target, lun;
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	uint16_t mask;
+
+	ENTER("qla1280_nvram_config");
+
+	if (ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP12160 ||
+	    ha->device_id == PCI_DEVICE_ID_QLOGIC_ISP10160)
+		is1x160 = 1;
+	else
+		is1x160 = 0;
 
-    /* Bad NVRAM data, set defaults parameters. */
-    if (chksum || nv->id[0] != 'I' || nv->id[1] != 'S' ||
-        nv->id[2] != 'P' || nv->id[3] != ' ' || nv->version < 1)
-    {
-#if  USE_NVRAM_DEFAULTS
-        DEBUG(printk("Using defaults for NVRAM\n"));
+	nv = &ha->nvram;
+	if (!ha->nvram_valid) {
+		dprintk(1, "Using defaults for NVRAM: \n");
+		memset(nv, 0, sizeof(struct nvram));
+
+		/* nv->cntr_flags_1.disable_loading_risc_code = 1; */
+		nv->firmware_feature.f.enable_fast_posting = 1;
+		nv->firmware_feature.f.disable_synchronous_backoff = 1;
+
+		nv->termination.f.scsi_bus_0_control = 3;
+		nv->termination.f.scsi_bus_1_control = 3;
+		nv->termination.f.auto_term_support = 1;
+
+		/*
+		 * Set default FIFO magic - What appropriate values
+		 * would be here is unknown. This is what I have found
+		 * testing with 12160s.
+		 * Now, I would love the magic decoder ring for this one,
+		 * the header file provided by QLogic seems to be bogus
+		 * or incomplete at best.
+		 */
+		nv->isp_config.c = 0x44;
+
+		if (is1x160)
+			nv->isp_parameter = 0x01;
+
+		for (bus = 0; bus < MAX_BUSES; bus++) {
+			nv->bus[bus].config_1.initiator_id = 7;
+			nv->bus[bus].bus_reset_delay = 5;
+			/* 8 = 5.0 clocks */
+			nv->bus[bus].config_2.async_data_setup_time = 8;
+			nv->bus[bus].config_2.req_ack_active_negation = 1;
+			nv->bus[bus].config_2.data_line_active_negation = 1;
+			nv->bus[bus].selection_timeout = 250;
+			nv->bus[bus].max_queue_depth = 256;
+
+			for (target = 0; target < MAX_TARGETS; target++) {
+				nv->bus[bus].target[target].parameter.f.
+					renegotiate_on_error = 1;
+				nv->bus[bus].target[target].parameter.f.
+					auto_request_sense = 1;
+				nv->bus[bus].target[target].parameter.f.
+					tag_queuing = 1;
+				nv->bus[bus].target[target].parameter.f.
+					enable_sync = 1;
+#if 1	/* Some SCSI Processors do not seem to like this */
+				nv->bus[bus].target[target].parameter.f.
+					enable_wide = 1;
+#endif
+				nv->bus[bus].target[target].parameter.f.
+					parity_checking = 1;
+				nv->bus[bus].target[target].parameter.f.
+					disconnect_allowed = 1;
+				nv->bus[bus].target[target].execution_throttle=
+					nv->bus[bus].max_queue_depth - 1;
+				if (is1x160) {
+					nv->bus[bus].target[target].flags.
+						flags1x160.device_enable = 1;
+					nv->bus[bus].target[target].flags.
+						flags1x160.sync_offset = 0x0e;
+					nv->bus[bus].target[target].
+						sync_period = 9;
+					nv->bus[bus].target[target].
+						ppr_1x160.flags.enable_ppr = 1;
+					nv->bus[bus].target[target].ppr_1x160.
+						flags.ppr_options = 2;
+					nv->bus[bus].target[target].ppr_1x160.
+						flags.ppr_bus_width = 1;
+				} else {
+					nv->bus[bus].target[target].flags.
+						flags1x80.device_enable = 1;
+					nv->bus[bus].target[target].flags.
+						flags1x80.sync_offset = 0x8;
+					nv->bus[bus].target[target].
+						sync_period = 10;
+				}
+			}
+		}
+	} else {
+		/* Always force AUTO sense for LINUX SCSI */
+		for (bus = 0; bus < MAX_BUSES; bus++)
+			for (target = 0; target < MAX_TARGETS; target++) {
+				nv->bus[bus].target[target].parameter.f.
+					auto_request_sense = 1;
+			}
+	}
+	dprintk(1, "qla1280 : initiator scsi id bus[0]=%d\n",
+		nv->bus[0].config_1.initiator_id);
+	dprintk(1, "qla1280 : initiator scsi id bus[1]=%d\n",
+		nv->bus[1].config_1.initiator_id);
+
+	dprintk(1, "qla1280 : bus reset delay[0]=%d\n",
+		nv->bus[0].bus_reset_delay);
+	dprintk(1, "qla1280 : bus reset delay[1]=%d\n",
+		nv->bus[1].bus_reset_delay);
+
+	dprintk(1, "qla1280 : retry count[0]=%d\n", nv->bus[0].retry_count);
+	dprintk(1, "qla1280 : retry delay[0]=%d\n", nv->bus[0].retry_delay);
+	dprintk(1, "qla1280 : retry count[1]=%d\n", nv->bus[1].retry_count);
+	dprintk(1, "qla1280 : retry delay[1]=%d\n", nv->bus[1].retry_delay);
+
+	dprintk(1, "qla1280 : async data setup time[0]=%d\n",
+		nv->bus[0].config_2.async_data_setup_time);
+	dprintk(1, "qla1280 : async data setup time[1]=%d\n",
+		nv->bus[1].config_2.async_data_setup_time);
+
+	dprintk(1, "qla1280 : req/ack active negation[0]=%d\n",
+		nv->bus[0].config_2.req_ack_active_negation);
+	dprintk(1, "qla1280 : req/ack active negation[1]=%d\n",
+		nv->bus[1].config_2.req_ack_active_negation);
+
+	dprintk(1, "qla1280 : data line active negation[0]=%d\n",
+		nv->bus[0].config_2.data_line_active_negation);
+	dprintk(1, "qla1280 : data line active negation[1]=%d\n",
+		nv->bus[1].config_2.data_line_active_negation);
+
+	dprintk(1, "qla1280 : disable loading risc code=%d\n",
+		nv->cntr_flags_1.disable_loading_risc_code);
+
+	dprintk(1, "qla1280 : enable 64bit addressing=%d\n",
+		nv->cntr_flags_1.enable_64bit_addressing);
+
+	dprintk(1, "qla1280 : selection timeout limit[0]=%d\n",
+		nv->bus[0].selection_timeout);
+	dprintk(1, "qla1280 : selection timeout limit[1]=%d\n",
+		nv->bus[1].selection_timeout);
+
+	dprintk(1, "qla1280 : max queue depth[0]=%d\n",
+		nv->bus[0].max_queue_depth);
+	dprintk(1, "qla1280 : max queue depth[1]=%d\n",
+		nv->bus[1].max_queue_depth);
+
+	/* Disable RISC load of firmware. */
+	ha->flags.disable_risc_code_load =
+		nv->cntr_flags_1.disable_loading_risc_code;
+
+#ifdef QLA_64BIT_PTR
+	/* Enable 64bit addressing for OS/System combination supporting it   */
+	/* actual NVRAM bit is: nv->cntr_flags_1.enable_64bit_addressing     */
+	/* but we will ignore it and use BITS_PER_LONG macro to setup for    */
+	/* 64 or 32 bit access of host memory in all x86/ia-64/Alpha systems */
+	ha->flags.enable_64bit_addressing = 1;
 #else
-        DEBUG(printk("Using defaults for NVRAM: \n"));
-        DEBUG(printk("checksum=0x%x, Id=%c, version=0x%x\n",chksum,nv->id[0],nv->version));
-#if defined(QL_DEBUG_LEVEL_3)
-        /* ql_debug_print = 1;
-        qla1280_dump_buffer((caddr_t)ha->response_ring, REQUEST_ENTRY_SIZE);
-        ql_debug_print = 0; */
-#endif
-                wptr = (uint16_t *)ha->response_ring;
-        for (cnt = 0; cnt < sizeof(nvram_t)/2; cnt++)
-            *wptr++ = 0;
+	ha->flags.enable_64bit_addressing = 0;
 #endif
 
+	if (ha->flags.enable_64bit_addressing) {
+		dprintk(2, "scsi(%li): 64 Bit PCI Addressing Enabled\n",
+			ha->host_no);
 
-        /* nv->cntr_flags_1.disable_loading_risc_code = 1; */
-        nv->firmware_feature.w = BIT_0;
-        nv->termination.f.scsi_bus_0_control = 3;
-        nv->termination.f.scsi_bus_1_control = 3;
-        nv->termination.f.auto_term_support = 1;
-
-        for (b = 0; b < MAX_BUSES; b++)
-        {
-            nv->bus[b].config_1.initiator_id = 7;
-            nv->bus[b].bus_reset_delay = 5;
-            nv->bus[b].config_2.async_data_setup_time = 9;
-            nv->bus[b].config_2.req_ack_active_negation = 1;
-            nv->bus[b].config_2.data_line_active_negation = 1;
-            nv->bus[b].selection_timeout = 250;
-            nv->bus[b].max_queue_depth = 256;
-
-            for (t = 0; t < MAX_TARGETS; t++)
-            {
-                nv->bus[b].target[t].parameter.f.auto_request_sense = 1;
-                nv->bus[b].target[t].parameter.f.disconnect_allowed = 1;
-                nv->bus[b].target[t].parameter.f.tag_queuing = 1;
-                nv->bus[b].target[t].flags.device_enable = 1;
-            }
-        }
+		pci_set_dma_mask(ha->pdev, (dma_addr_t) ~ 0ULL);
+	}
 
-#if  USE_NVRAM_DEFAULTS
-        status = 0;
-#else
-        status = 1;
+	/* Set ISP hardware DMA burst */
+	mb[0] = nv->isp_config.c;
+	/* Enable DMA arbitration on dual channel controllers */
+	if (ha->ports > 1)
+		mb[0] |= BIT_13;
+	WRT_REG_WORD(&reg->cfg_1, mb[0]);
+
+#if 1	/* Is this safe? */
+	/* Set SCSI termination. */
+	WRT_REG_WORD(&reg->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
+	mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
+	WRT_REG_WORD(&reg->gpio_data, mb[0]);
+#endif
+
+	/* ISP parameter word. */
+	mb[0] = MBC_SET_SYSTEM_PARAMETER;
+	mb[1] = nv->isp_parameter;
+	status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+
+#if 0
+	/* clock rate - for qla1240 and older, only */
+	mb[0] = MBC_SET_CLOCK_RATE;
+	mb[1] = 0x50;
+ 	status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+#endif
+	/* Firmware feature word. */
+	mb[0] = MBC_SET_FIRMWARE_FEATURES;
+	mask = BIT_5 | BIT_1 | BIT_0;
+	mb[1] = le16_to_cpu(nv->firmware_feature.w) & (mask);
+#if defined(CONFIG_IA64_GENERIC) || defined (CONFIG_IA64_SGI_SN2)
+	if (ia64_platform_is("sn2")) {
+		printk(KERN_INFO "scsi(%li): Enabling SN2 PCI DMA "
+		       "workaround\n", ha->host_no);
+		mb[1] |= BIT_9;
+	}
 #endif
-    }
-    else
-    {
-        /* Always force AUTO sense for LINUX SCSI */
-        for (b = 0; b < MAX_BUSES; b++)
-            for (t = 0; t < MAX_TARGETS; t++)
-            {
-                nv->bus[b].target[t].parameter.f.auto_request_sense = 1;
-            }
-    }
-#if  DEBUG_PRINT_NVRAM
-    ql_debug_print = 1;
-    sprintf(debug_buff,"qla1280 : initiator scsi id bus[0]=%d\n\r",
-            nv->bus[0].config_1.initiator_id);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : initiator scsi id bus[1]=%d\n\r",
-            nv->bus[1].config_1.initiator_id);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : bus reset delay[0]=%d\n\r",
-            nv->bus[0].bus_reset_delay);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : bus reset delay[1]=%d\n\r",
-            nv->bus[1].bus_reset_delay);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : retry count[0]=%d\n\r",
-            nv->bus[0].retry_count);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : retry delay[0]=%d\n\r",
-            nv->bus[0].retry_delay);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : retry count[1]=%d\n\r",
-            nv->bus[1].retry_count);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : retry delay[1]=%d\n\r",
-            nv->bus[1].retry_delay);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : async data setup time[0]=%d\n\r",
-            nv->bus[0].config_2.async_data_setup_time);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : async data setup time[1]=%d\n\r",
-            nv->bus[1].config_2.async_data_setup_time);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : req/ack active negation[0]=%d\n\r",
-            nv->bus[0].config_2.req_ack_active_negation);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : req/ack active negation[1]=%d\n\r",
-            nv->bus[1].config_2.req_ack_active_negation);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : data line active negation[0]=%d\n\r",
-            nv->bus[0].config_2.data_line_active_negation);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : data line active negation[1]=%d\n\r",
-            nv->bus[1].config_2.data_line_active_negation);
-    qla1280_print(debug_buff);
-
-
-    sprintf(debug_buff,"qla1280 : disable loading risc code=%d\n\r",
-            nv->cntr_flags_1.disable_loading_risc_code);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : enable 64bit addressing=%d\n\r",
-            nv->cntr_flags_1.enable_64bit_addressing);
-    qla1280_print(debug_buff);
-
-    sprintf(debug_buff,"qla1280 : selection timeout limit[0]=%d\n\r",
-            nv->bus[0].selection_timeout);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : selection timeout limit[1]=%d\n\r",
-            nv->bus[1].selection_timeout);
-
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : max queue depth[0]=%d\n\r",
-            nv->bus[0].max_queue_depth);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"qla1280 : max queue depth[1]=%d\n\r",
-            nv->bus[1].max_queue_depth);
-    qla1280_print(debug_buff);
-#endif
-
-    DEBUG(ql_debug_print = 0;)
-
-    /* Disable RISC load of firmware. */
-    ha->flags.disable_risc_code_load =
-            nv->cntr_flags_1.disable_loading_risc_code;
-    /* Enable 64bit addressing. */
-    ha->flags.enable_64bit_addressing =
-            nv->cntr_flags_1.enable_64bit_addressing;
-
-    /* Set ISP hardware DMA burst */
-    mb[0] = nv->isp_config.c;
-    WRT_REG_WORD(&reg->cfg_1, mb[0]);
-
-    /* Set SCSI termination. */
-    WRT_REG_WORD(&reg->gpio_enable, (BIT_3 + BIT_2 + BIT_1 + BIT_0));
-    mb[0] = nv->termination.c & (BIT_3 + BIT_2 + BIT_1 + BIT_0);
-    WRT_REG_WORD(&reg->gpio_data, mb[0]);
-
-    /* ISP parameter word. */
-    mb[0] = MBC_SET_SYSTEM_PARAMETER;
-    mb[1] = nv->isp_parameter;
-    status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
-
-    /* Firmware feature word. */
-    mb[0] = MBC_SET_FIRMWARE_FEATURES;
-    mb[1] = nv->firmware_feature.w & (BIT_1|BIT_0);
-    status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
-
-    /* Retry count and delay. */
-    mb[0] = MBC_SET_RETRY_COUNT;
-    mb[1] = nv->bus[0].retry_count;
-    mb[2] = nv->bus[0].retry_delay;
-    mb[6] = nv->bus[1].retry_count;
-    mb[7] = nv->bus[1].retry_delay;
-    status |= qla1280_mailbox_command(ha, BIT_7|BIT_6|BIT_2|BIT_1|BIT_0, &mb[0]);
-
-    /* ASYNC data setup time. */
-    mb[0] = MBC_SET_ASYNC_DATA_SETUP;
-    mb[1] = nv->bus[0].config_2.async_data_setup_time;
-    mb[2] = nv->bus[1].config_2.async_data_setup_time;
-    status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]);
-
-    /* Active negation states. */
-    mb[0] = MBC_SET_ACTIVE_NEGATION;
-    mb[1] = 0;
-    if (nv->bus[0].config_2.req_ack_active_negation)
-        mb[1] |= BIT_5;
-    if (nv->bus[0].config_2.data_line_active_negation)
-        mb[1] |= BIT_4;
-    mb[2] = 0;
-    if (nv->bus[1].config_2.req_ack_active_negation)
-        mb[2] |= BIT_5;
-    if (nv->bus[1].config_2.data_line_active_negation)
-        mb[2] |= BIT_4;
-    status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]);
-
-    /* Selection timeout. */
-    mb[0] = MBC_SET_SELECTION_TIMEOUT;
-    mb[1] = nv->bus[0].selection_timeout;
-    mb[2] = nv->bus[1].selection_timeout;
-    status |= qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]);
-
-    for (b = 0; b < ha->ports; b++)
-    {
-        /* SCSI Reset Disable. */
-        ha->bus_settings[b].disable_scsi_reset = nv->bus[b].config_1.scsi_reset_disable;
-
-        /* Initiator ID. */
-        ha->bus_settings[b].id = nv->bus[b].config_1.initiator_id;
-        mb[0] = MBC_SET_INITIATOR_ID;
-        mb[1] = b ? ha->bus_settings[b].id | BIT_7 : ha->bus_settings[b].id;
-        status |= qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
-
-        /* Reset Delay. */
-        ha->bus_settings[b].bus_reset_delay = nv->bus[b].bus_reset_delay;
-
-        /* Command queue depth per device. */
-        ha->bus_settings[b].hiwat = nv->bus[b].max_queue_depth - 1;
-
-        /* Set target parameters. */
-        for (t = 0; t < MAX_TARGETS; t++)
-        {
-            if( ha->device_id == QLA12160_DEVICE_ID ||  
-                ha->device_id == QLA10160_DEVICE_ID )  
-            {
-                status = qla12160_set_target_parameters(ha,b,t,0,(nvram160_t *)nv);
-            }
+	status |= qla1280_mailbox_command(ha, mask, &mb[0]);
+
+	/* Retry count and delay. */
+	mb[0] = MBC_SET_RETRY_COUNT;
+	mb[1] = nv->bus[0].retry_count;
+	mb[2] = nv->bus[0].retry_delay;
+	mb[6] = nv->bus[1].retry_count;
+	mb[7] = nv->bus[1].retry_delay;
+	status |= qla1280_mailbox_command(ha, BIT_7 | BIT_6 | BIT_2 |
+					  BIT_1 | BIT_0, &mb[0]);
+
+	/* ASYNC data setup time. */
+	mb[0] = MBC_SET_ASYNC_DATA_SETUP;
+	mb[1] = nv->bus[0].config_2.async_data_setup_time;
+	mb[2] = nv->bus[1].config_2.async_data_setup_time;
+	status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
+	/* Active negation states. */
+	mb[0] = MBC_SET_ACTIVE_NEGATION;
+	mb[1] = 0;
+	if (nv->bus[0].config_2.req_ack_active_negation)
+		mb[1] |= BIT_5;
+	if (nv->bus[0].config_2.data_line_active_negation)
+		mb[1] |= BIT_4;
+	mb[2] = 0;
+	if (nv->bus[1].config_2.req_ack_active_negation)
+		mb[2] |= BIT_5;
+	if (nv->bus[1].config_2.data_line_active_negation)
+		mb[2] |= BIT_4;
+	status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
+	mb[0] = MBC_SET_DATA_OVERRUN_RECOVERY;
+	mb[1] = 2;	/* Reset SCSI bus and return all outstanding IO */
+	status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+
+	/* thingy */
+	mb[0] = MBC_SET_PCI_CONTROL;
+	mb[1] = 2;	/* Data DMA Channel Burst Enable */
+	mb[2] = 2;	/* Command DMA Channel Burst Enable */
+	status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
+	/* Selection timeout. */
+	mb[0] = MBC_SET_SELECTION_TIMEOUT;
+	mb[1] = nv->bus[0].selection_timeout;
+	mb[2] = nv->bus[1].selection_timeout;
+	status |= qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
+	for (bus = 0; bus < ha->ports; bus++) {
+		/* SCSI Reset Disable. */
+		ha->bus_settings[bus].disable_scsi_reset =
+			nv->bus[bus].config_1.scsi_reset_disable;
+
+		/* Initiator ID. */
+		ha->bus_settings[bus].id = nv->bus[bus].config_1.initiator_id;
+		mb[0] = MBC_SET_INITIATOR_ID;
+		mb[1] = bus ? ha->bus_settings[bus].id | BIT_7 :
+			ha->bus_settings[bus].id;
+		status |= qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
+
+		/* Reset Delay. */
+		ha->bus_settings[bus].bus_reset_delay =
+			nv->bus[bus].bus_reset_delay;
+
+		/* Command queue depth per device. */
+		ha->bus_settings[bus].hiwat = nv->bus[bus].max_queue_depth - 1;
+
+		/* Set target parameters. */
+		for (target = 0; target < MAX_TARGETS; target++) {
+			uint8_t mr = BIT_2 | BIT_1 | BIT_0;
+
+			/* Set Target Parameters. */
+			mb[0] = MBC_SET_TARGET_PARAMETERS;
+			mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
+			mb[1] <<= 8;
+			/*
+			 * Do not enable wide, sync, and ppr for the initial
+			 * INQUIRY run. We enable this later if we determine
+			 * the target actually supports it.
+			 */
+			nv->bus[bus].target[target].parameter.f.
+				auto_request_sense = 1;
+			nv->bus[bus].target[target].parameter.f.
+				stop_queue_on_check = 0;
+
+			if (is1x160)
+				nv->bus[bus].target[target].ppr_1x160.
+					flags.enable_ppr = 0;
+			/*
+			 * No sync, wide, etc. while probing
+			 */
+			mb[2] = (nv->bus[bus].target[target].parameter.c << 8)&
+				~(TP_SYNC /*| TP_WIDE | TP_PPR*/);
+
+			if (is1x160)
+				mb[3] =	nv->bus[bus].target[target].flags.flags1x160.sync_offset << 8;
 			else
-            {
-                /* Set Target Parameters. */
-                mb[0] = MBC_SET_TARGET_PARAMETERS;
-                mb[1] = (uint16_t)(b ? t | BIT_7 :t);
-                mb[1] <<= 8;
-                mb[2] = nv->bus[b].target[t].parameter.c << 8;
-                mb[2] |= TP_AUTO_REQUEST_SENSE;
-                mb[2] &= ~TP_STOP_QUEUE;
-                mb[3] = nv->bus[b].target[t].flags.sync_offset << 8;
-                mb[3] |= nv->bus[b].target[t].sync_period;
-                status |= qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0,
-                    &mb[0]);
-            }
-
-            /* Save Tag queuing enable flag. */
-            mb[0] = BIT_0 << t;
-            if (nv->bus[b].target[t].parameter.f.tag_queuing)
-                ha->bus_settings[b].qtag_enables |= mb[0];
-
-            /* Save Device enable flag. */
-            if (nv->bus[b].target[t].flags.device_enable)
-                ha->bus_settings[b].device_enables |= mb[0];
-
-            /* Save LUN disable flag. */
-            if (nv->bus[b].target[t].flags.lun_disable)
-                ha->bus_settings[b].lun_disables |= mb[0];
-
-            /* Set Device Queue Parameters. */
-            for (l = 0; l < MAX_LUNS; l++)
-            {
-                mb[0] = MBC_SET_DEVICE_QUEUE;
-                mb[1] = (uint16_t)(b ? t | BIT_7 :t);
-                mb[1] = mb[1] << 8 | l;
-                mb[2] = nv->bus[b].max_queue_depth;
-                mb[3] = nv->bus[b].target[t].execution_throttle;
-                status |= qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0,
-                        &mb[0]);
-            }
-        }
-    }
-    DEBUG(ql_debug_print = 0;)
-
-#if defined(QL_DEBUG_ROUTINES) && !defined(QL_DEBUG_LEVEL_4)
-    ql_debug_print = saved_print_status;
-#endif
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    DEBUG(if (status))
-        DEBUG(qla1280_print("qla1280_nvram_config: **** FAILED ****\n\r");)
-#endif
-    LEAVE("qla1280_nvram_config");
-    return(status);
+				mb[3] =	nv->bus[bus].target[target].flags.flags1x80.sync_offset << 8;
+			mb[3] |= nv->bus[bus].target[target].sync_period;
+			mr |= BIT_3;
+
+			/*
+			 * We don't want to enable ppr etc. before we have 
+			 * determined that the target actually supports it
+			 */
+#if 0
+			if (is1x160) {
+				mb[2] |= nv->bus[bus].target[target].ppr_1x160.flags.enable_ppr << 5;
+
+				mb[6] =	nv->bus[bus].target[target].ppr_1x160.flags.ppr_options << 8;
+				mb[6] |= nv->bus[bus].target[target].ppr_1x160.flags.ppr_bus_width;
+				mr |= BIT_6;
+			}
+#endif
+
+			status = qla1280_mailbox_command(ha, mr, &mb[0]);
+
+			/* Save Tag queuing enable flag. */
+			mb[0] = BIT_0 << target;
+			if (nv->bus[bus].target[target].parameter.f.tag_queuing)
+				ha->bus_settings[bus].qtag_enables |= mb[0];
+
+			/* Save Device enable flag. */
+			if (is1x160) {
+				if (nv->bus[bus].target[target].flags.flags1x160.device_enable)
+					ha->bus_settings[bus].device_enables |= mb[0];
+				ha->bus_settings[bus].lun_disables |= 0;
+			} else {
+				if (nv->bus[bus].target[target].flags.flags1x80.device_enable)
+					ha->bus_settings[bus].device_enables |= mb[0];
+				/* Save LUN disable flag. */
+				if (nv->bus[bus].target[target].flags.flags1x80.lun_disable)
+				ha->bus_settings[bus].lun_disables |= mb[0];
+			}
+
+
+			/* Set Device Queue Parameters. */
+			for (lun = 0; lun < MAX_LUNS; lun++) {
+				mb[0] = MBC_SET_DEVICE_QUEUE;
+				mb[1] = (uint16_t)(bus ? target | BIT_7 : target);
+				mb[1] = mb[1] << 8 | lun;
+				mb[2] = nv->bus[bus].max_queue_depth;
+				mb[3] = nv->bus[bus].target[target].execution_throttle;
+				status |= qla1280_mailbox_command(ha, 0x0f,
+								  &mb[0]);
+			}
+		}
+	}
+
+	if (status)
+		dprintk(2, "qla1280_nvram_config: **** FAILED ****\n");
+
+	LEAVE("qla1280_nvram_config");
+	return status;
 }
 
 /*
@@ -3307,36 +3078,21 @@
  * Returns:
  *      data word.
  */
-STATIC uint16_t
-qla1280_get_nvram_word(scsi_qla_host_t *ha, uint32_t address)
+static uint16_t
+qla1280_get_nvram_word(struct scsi_qla_host *ha, uint32_t address)
 {
-    uint32_t nv_cmd;
-    uint16_t data;
+	uint32_t nv_cmd;
+	uint16_t data;
 
-#ifdef QL_DEBUG_ROUTINES
-    uint8_t  saved_print_status = ql_debug_print;
-#endif
-#ifdef QL_DEBUG_LEVEL_4
-    ENTER("qla1280_get_nvram_word");
-#endif
+	nv_cmd = address << 16;
+	nv_cmd |= NV_READ_OP;
 
-    nv_cmd = address << 16;
-    nv_cmd |= NV_READ_OP;
+	data = le16_to_cpu(qla1280_nvram_request(ha, nv_cmd));
 
-#ifdef QL_DEBUG_ROUTINES
-    ql_debug_print = FALSE;
-#endif
-    data = qla1280_nvram_request(ha, nv_cmd);
-#ifdef QL_DEBUG_ROUTINES
-    ql_debug_print = saved_print_status;
-#endif
+	dprintk(8, "qla1280_get_nvram_word: exiting normally NVRAM data = "
+		"0x%x", data);
 
-#ifdef QL_DEBUG_LEVEL_4
-    qla1280_print("qla1280_get_nvram_word: exiting normally NVRAM data = ");
-    qla1280_output_number((uint32_t)data, 16);
-    qla1280_print("\n\r");
-#endif
-    return(data);
+	return data;
 }
 
 /*
@@ -3353,76 +3109,63 @@
  * Returns:
  *      data word.
  */
-STATIC uint16_t
-qla1280_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
+static uint16_t
+qla1280_nvram_request(struct scsi_qla_host *ha, uint32_t nv_cmd)
+{
+	struct device_reg *reg = ha->iobase;
+	int cnt;
+	uint16_t data = 0;
+	uint16_t reg_data;
+
+	/* Send command to NVRAM. */
+
+	nv_cmd <<= 5;
+	for (cnt = 0; cnt < 11; cnt++) {
+		if (nv_cmd & BIT_31)
+			qla1280_nv_write(ha, NV_DATA_OUT);
+		else
+			qla1280_nv_write(ha, 0);
+		nv_cmd <<= 1;
+	}
+
+	/* Read data from NVRAM. */
+
+	for (cnt = 0; cnt < 16; cnt++) {
+		WRT_REG_WORD(&reg->nvram, (NV_SELECT | NV_CLOCK));
+		RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+		NVRAM_DELAY();
+		data <<= 1;
+		reg_data = RD_REG_WORD(&reg->nvram);
+		if (reg_data & NV_DATA_IN)
+			data |= BIT_0;
+		WRT_REG_WORD(&reg->nvram, NV_SELECT);
+		RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+		NVRAM_DELAY();
+	}
+
+	/* Deselect chip. */
+
+	WRT_REG_WORD(&reg->nvram, NV_DESELECT);
+	RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+	NVRAM_DELAY();
+
+	return data;
+}
+
+static void
+qla1280_nv_write(struct scsi_qla_host *ha, uint16_t data)
 {
-    uint8_t      cnt;
-    device_reg_t *reg = ha->iobase;
-    uint16_t     data = 0;
-    uint16_t     reg_data;
-
-    /* Send command to NVRAM. */
-
-    nv_cmd <<= 5;
-    for (cnt = 0; cnt < 11; cnt++)
-    {
-        if (nv_cmd & BIT_31)
-            qla1280_nv_write(ha, NV_DATA_OUT);
-        else
-            qla1280_nv_write(ha, 0);
-        nv_cmd <<= 1;
-    }
-
-    /* Read data from NVRAM. */
-
-    for (cnt = 0; cnt < 16; cnt++)
-    {
-        WRT_REG_WORD(&reg->nvram, NV_SELECT+NV_CLOCK);
-        /* qla1280_nv_delay(ha); */
-        NVRAM_DELAY();
-        data <<= 1;
-        reg_data = RD_REG_WORD(&reg->nvram);
-        if (reg_data & NV_DATA_IN)
-            data |= BIT_0;
-        WRT_REG_WORD(&reg->nvram, NV_SELECT);
-        /* qla1280_nv_delay(ha); */
-        NVRAM_DELAY();
-    }
-
-    /* Deselect chip. */
-
-    WRT_REG_WORD(&reg->nvram, NV_DESELECT);
-    /* qla1280_nv_delay(ha); */
-    NVRAM_DELAY();
-
-    return(data);
-}
-
-STATIC void
-qla1280_nv_write(scsi_qla_host_t *ha, uint16_t data)
-{
-    device_reg_t *reg = ha->iobase;
-
-    WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
-    NVRAM_DELAY();
-    /* qla1280_nv_delay(ha); */
-    WRT_REG_WORD(&reg->nvram, data | NV_SELECT | NV_CLOCK);
-    /* qla1280_nv_delay(ha); */
-    NVRAM_DELAY();
-    WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
-    /* qla1280_nv_delay(ha); */
-    NVRAM_DELAY();
-}
-
-STATIC void
-qla1280_nv_delay(scsi_qla_host_t *ha)
-{
-    device_reg_t *reg = ha->iobase;
-    int          cnt  = NV_DELAY_COUNT;
-    uint16_t     data = 0;
+	struct device_reg *reg = ha->iobase;
 
-    while (cnt--)
-        data |= RD_REG_WORD(&reg->nvram);
+	WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
+	RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+	NVRAM_DELAY();
+	WRT_REG_WORD(&reg->nvram, data | NV_SELECT | NV_CLOCK);
+	RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+	NVRAM_DELAY();
+	WRT_REG_WORD(&reg->nvram, data | NV_SELECT);
+	RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
+	NVRAM_DELAY();
 }
 
 /*
@@ -3440,112 +3183,108 @@
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_mailbox_command(scsi_qla_host_t *ha, uint8_t mr, uint16_t *mb)
+static int
+qla1280_mailbox_command(struct scsi_qla_host *ha, uint8_t mr, uint16_t *mb)
 {
-    device_reg_t *reg   = ha->iobase;
-    uint8_t      status = 0;
-    uint32_t     cnt;
-    uint16_t     *optr, *iptr;
-    uint16_t     data;
-    srb_t        *done_q_first = 0;
-    srb_t        *done_q_last = 0;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_mailbox_command");
-#endif
-
-    /* Acquire interrupt specific lock */
-    QLA1280_INTR_LOCK(ha);
-    DRIVER_LOCK
-            ha->flags.mbox_busy = TRUE;
-
-    /* Load mailbox registers. */
-    optr = (uint16_t *)&reg->mailbox0;
-    iptr = mb;
-    for (cnt = 0; cnt < MAILBOX_REGISTER_COUNT; cnt++)
-    {
-        if (mr & BIT_0)
-        {
-            WRT_REG_WORD(optr, (*iptr));
-        }
-
-        mr >>= 1;
-        optr++;
-        iptr++;
-    }
-    /* Issue set host interrupt command. */
-    ha->flags.mbox_int = FALSE;
-    WRT_REG_WORD(&reg->host_cmd, HC_SET_HOST_INT);
-    data = qla1280_debounce_register(&reg->istatus);
-
-    /* Wait for 30 seconds for command to finish. */
-    for (cnt = 30000000; cnt > 0 && !ha->flags.mbox_int; cnt--)
-    {
-        /* Check for pending interrupts. */
-        if (data & RISC_INT)
-        {
-            qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last);
-        }
-        SYS_DELAY(1);
-        data = RD_REG_WORD(&reg->istatus);
-    }
-
-    /* Check for mailbox command timeout. */
-    if ( !cnt )
-    {
-#ifdef QL_DEBUG_LEVEL_2
-        qla1280_print(
-                "qla1280_mailbox_command: **** Command Timeout, mailbox0 = ");
-        qla1280_output_number((uint32_t)mb[0], 16);
-        qla1280_print(" ****\n\r");
-#endif
-        ha->flags.isp_abort_needed = TRUE; 
-        status = 1;
-    }
-    else if (ha->mailbox_out[0] != MBS_CMD_CMP)
-        status = 1;
-
-    /* Load return mailbox registers. */
-    optr = mb;
-    iptr = (uint16_t *)&ha->mailbox_out[0];
-    mr = MAILBOX_REGISTER_COUNT;
-    while (mr--)
-        *optr++ = *iptr++;
-
-    /* Go check for any response interrupts pending. */
-    ha->flags.mbox_busy = FALSE;
-    qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last);
-
-    /* Release interrupt specific lock */
-    QLA1280_INTR_UNLOCK(ha);
-    DRIVER_UNLOCK
-
-            if (ha->flags.isp_abort_needed)
-        qla1280_abort_isp(ha);
-
-    if (ha->flags.reset_marker)
-        qla1280_rst_aen(ha);
-
-    if (done_q_first)
-        qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last);
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-    {
-        qla1280_print("qla1280_mailbox_command: **** FAILED, mailbox0 = ");
-        qla1280_output_number((uint32_t)mb[0], 16);
-        qla1280_print(" ****\n\r");
-    }
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_mailbox_command");
+	struct device_reg *reg = ha->iobase;
+#if 0
+	struct srb *done_q_first = 0;
+	struct srb *done_q_last = 0;
+#endif
+	int status = 0;
+	int cnt;
+	uint16_t *optr, *iptr;
+	uint16_t data;
+	DECLARE_COMPLETION(wait);
+	struct timer_list timer;
+
+	ENTER("qla1280_mailbox_command");
+
+	ha->flags.mbox_busy = 1;
+
+	if (ha->mailbox_wait) {
+		printk(KERN_ERR "Warning mailbox wait already in use!\n");
+	}
+	ha->mailbox_wait = &wait;
+
+	/*
+	 * We really should start out by verifying that the mailbox is
+	 * available before starting sending the command data
+	 */
+	/* Load mailbox registers. */
+	optr = (uint16_t *) &reg->mailbox0;
+	iptr = mb;
+	for (cnt = 0; cnt < MAILBOX_REGISTER_COUNT; cnt++) {
+		if (mr & BIT_0) {
+			WRT_REG_WORD(optr, (*iptr));
+		}
+
+		mr >>= 1;
+		optr++;
+		iptr++;
+	}
+
+	/* Issue set host interrupt command. */
+	ha->flags.mbox_busy = 0;
+
+	/* set up a timer just in case we're really jammed */
+	init_timer(&timer);
+	timer.expires = jiffies + 20*HZ;
+	timer.data = (unsigned long)ha;
+	timer.function = qla1280_mailbox_timeout;
+	add_timer(&timer);
+
+	spin_unlock_irq(HOST_LOCK);
+	WRT_REG_WORD(&reg->host_cmd, HC_SET_HOST_INT);
+	data = qla1280_debounce_register(&reg->istatus);
+
+	wait_for_completion(&wait);
+	del_timer_sync(&timer);
+
+	spin_lock_irq(HOST_LOCK);
+
+	ha->mailbox_wait = NULL;
+
+	/* Check for mailbox command timeout. */
+	if (ha->mailbox_out[0] != MBS_CMD_CMP) {
+		printk(KERN_WARNING "qla1280_mailbox_command: Command failed, "
+		       "mailbox0 = 0x%04x, mailbox_out0 = 0x%04x, istatus = "
+		       "0x%04x\n", 
+		       mb[0], ha->mailbox_out[0], RD_REG_WORD(&reg->istatus));
+		printk(KERN_WARNING "m0 %04x, m1 %04x, m2 %04x, m3 %04x\n",
+		       RD_REG_WORD(&reg->mailbox0), RD_REG_WORD(&reg->mailbox1),
+		       RD_REG_WORD(&reg->mailbox2), RD_REG_WORD(&reg->mailbox3));
+		printk(KERN_WARNING "m4 %04x, m5 %04x, m6 %04x, m7 %04x\n",
+		       RD_REG_WORD(&reg->mailbox4), RD_REG_WORD(&reg->mailbox5),
+		       RD_REG_WORD(&reg->mailbox6), RD_REG_WORD(&reg->mailbox7));
+		status = 1;
+	}
+
+	/* Load return mailbox registers. */
+	optr = mb;
+	iptr = (uint16_t *) &ha->mailbox_out[0];
+	mr = MAILBOX_REGISTER_COUNT;
+	memcpy(optr, iptr, MAILBOX_REGISTER_COUNT * sizeof(uint16_t));
+
+#if 0
+	/* Go check for any response interrupts pending. */
+	qla1280_isr(ha, &done_q_first, &done_q_last);
+#endif
+
+	if (ha->flags.reset_marker)
+		qla1280_rst_aen(ha);
+
+#if 0
+	if (done_q_first)
+		qla1280_done (ha, &done_q_first, &done_q_last);
 #endif
-    return(status);
+
+	if (status)
+		dprintk(2, "qla1280_mailbox_command: **** FAILED, mailbox0 = "
+			"0x%x ****\n", mb[0]);
+
+	LEAVE("qla1280_mailbox_command");
+	return status;
 }
 
 /*
@@ -3555,43 +3294,30 @@
  * Input:
  *      ha = adapter block pointer.
  */
-STATIC void
-qla1280_poll(scsi_qla_host_t *ha)
+static void
+qla1280_poll(struct scsi_qla_host *ha)
 {
-    device_reg_t    *reg   = ha->iobase;
-    uint16_t        data;
-    srb_t           *done_q_first = 0;
-    srb_t           *done_q_last = 0;
-
-#ifdef QL_DEBUG_LEVEL_3
-    /* ENTER("qla1280_poll"); */
-#endif
-
-    /* Acquire interrupt specific lock */
-    QLA1280_INTR_LOCK(ha);
-
-    /* Check for pending interrupts. */
-    data = RD_REG_WORD(&reg->istatus);
-    if (data & RISC_INT)
-        qla1280_isr(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last);
-
-    /* Release interrupt specific lock */
-    QLA1280_INTR_UNLOCK(ha);
-
-    if (!ha->flags.mbox_busy)
-    {
-        if (ha->flags.isp_abort_needed)
-            qla1280_abort_isp(ha);
-        if (ha->flags.reset_marker)
-            qla1280_rst_aen(ha);
-    }
+	struct device_reg *reg = ha->iobase;
+	uint16_t data;
+	struct srb *done_q_first = 0;
+	struct srb *done_q_last = 0;
+
+	/* ENTER("qla1280_poll"); */
+
+	/* Check for pending interrupts. */
+	data = RD_REG_WORD(&reg->istatus);
+	if (data & RISC_INT)
+		qla1280_isr(ha, &done_q_first, &done_q_last);
+
+	if (!ha->flags.mbox_busy) {
+		if (ha->flags.reset_marker)
+			qla1280_rst_aen(ha);
+	}
 
-    if (done_q_first)
-        qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last);
+	if (done_q_first)
+		qla1280_done(ha, &done_q_first, &done_q_last);
 
-#ifdef QL_DEBUG_LEVEL_3
-    /* LEAVE("qla1280_poll"); */
-#endif
+	/* LEAVE("qla1280_poll"); */
 }
 
 /*
@@ -3599,54 +3325,58 @@
  *      Issue SCSI bus reset.
  *
  * Input:
- *      ha = adapter block pointer.
- *      b  = SCSI bus number.
+ *      ha  = adapter block pointer.
+ *      bus = SCSI bus number.
  *
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_bus_reset(scsi_qla_host_t *ha, uint8_t b)
+static int
+qla1280_bus_reset(struct scsi_qla_host *ha, int bus)
 {
-    uint8_t     status;
-    uint16_t    mb[MAILBOX_REGISTER_COUNT];
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	uint16_t reset_delay;
+	int status;
+
+	dprintk(3, "qla1280_bus_reset: entered\n");
+
+	if (qla1280_verbose)
+		printk(KERN_INFO "scsi(%li:%i): Resetting SCSI BUS\n",
+		       ha->host_no, bus);
+
+	reset_delay = ha->bus_settings[bus].bus_reset_delay;
+	mb[0] = MBC_BUS_RESET;
+	mb[1] = reset_delay;
+	mb[2] = (uint16_t) bus;
+	status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
+
+	if (status) {
+		if (ha->bus_settings[bus].failed_reset_count > 2)
+			ha->bus_settings[bus].scsi_bus_dead = 1;
+		ha->bus_settings[bus].failed_reset_count++;
+	} else {
+		spin_unlock_irq(HOST_LOCK);
+		schedule_timeout(reset_delay * HZ);
+		spin_lock_irq(HOST_LOCK);
+
+		ha->bus_settings[bus].scsi_bus_dead = 0;
+		ha->bus_settings[bus].failed_reset_count = 0;
+		ha->bus_settings[bus].reset_marker = 0;
+		/* Issue marker command. */
+		qla1280_marker(ha, bus, 0, 0, MK_SYNC_ALL);
+	}
 
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_bus_reset: entered\n\r");
-#endif
-   if( qla1280_verbose )
-   {
-    printk("scsi(%d): Resetting SCSI BUS (%d)\n",(int)ha->host_no,b);
-   }
-
-    mb[0] = MBC_BUS_RESET;
-    mb[1] = ha->bus_settings[b].bus_reset_delay;
-    mb[2] = (uint16_t)b;
-    status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]);
-
-    if (status)
-    {
-        if (ha->bus_settings[b].failed_reset_count > 2)                  /* dg - 03/13/99 */
-            ha->bus_settings[b].scsi_bus_dead = TRUE;
-        ha->bus_settings[b].failed_reset_count++;
-    }
+	/*
+	 * We should probably call qla1280_set_target_parameters()
+	 * here as well for all devices on the bus.
+	 */
+
+	if (status)
+		dprintk(2, "qla1280_bus_reset: **** FAILED ****\n");
 	else
-    {
-       QLA1280_DELAY(4);
-       ha->bus_settings[b].scsi_bus_dead = FALSE;                         /* dg - 03/13/99 */
-       ha->bus_settings[b].failed_reset_count = 0;
-       /* Issue marker command. */
-       qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL);
-    }
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_bus_reset: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_bus_reset: exiting normally\n\r");
-#endif
-    return(status);
+		dprintk(3, "qla1280_bus_reset: exiting normally\n");
+
+	return status;
 }
 
 /*
@@ -3654,40 +3384,34 @@
  *      Issue bus device reset message to the target.
  *
  * Input:
- *      ha = adapter block pointer.
- *      b  = SCSI BUS number.
- *      t  = SCSI ID.
+ *      ha      = adapter block pointer.
+ *      bus     = SCSI BUS number.
+ *      target  = SCSI ID.
  *
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_device_reset(scsi_qla_host_t *ha, uint8_t b, uint32_t t)
+static int
+qla1280_device_reset(struct scsi_qla_host *ha, int bus, int target)
 {
-    uint8_t     status;
-    uint16_t    mb[MAILBOX_REGISTER_COUNT];
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	int status;
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_device_reset");
-#endif
+	ENTER("qla1280_device_reset");
 
-    mb[0] = MBC_ABORT_TARGET;
-    mb[1] = (b ? (t | BIT_7) : t) << 8;
-    mb[2] = 1;
-    status = qla1280_mailbox_command(ha, BIT_2|BIT_1|BIT_0, &mb[0]);
+	mb[0] = MBC_ABORT_TARGET;
+	mb[1] = (bus ? (target | BIT_7) : target) << 8;
+	mb[2] = 1;
+	status = qla1280_mailbox_command(ha, BIT_2 | BIT_1 | BIT_0, &mb[0]);
 
-    /* Issue marker command. */
-    qla1280_marker(ha, b, t, 0, MK_SYNC_ID);
+	/* Issue marker command. */
+	qla1280_marker(ha, bus, target, 0, MK_SYNC_ID);
 
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_device_reset: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_device_reset");
-#endif
-    return(status);
+	if (status)
+		dprintk(2, "qla1280_device_reset: **** FAILED ****\n");
+
+	LEAVE("qla1280_device_reset");
+	return status;
 }
 
 /*
@@ -3695,40 +3419,34 @@
  *      Issue an abort message to the device
  *
  * Input:
- *      ha = adapter block pointer.
- *      b  = SCSI BUS.
- *      t  = SCSI ID.
- *      l  = SCSI LUN.
+ *      ha     = adapter block pointer.
+ *      bus    = SCSI BUS.
+ *      target = SCSI ID.
+ *      lun    = SCSI LUN.
  *
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_abort_device(scsi_qla_host_t *ha, uint8_t b, uint32_t t, uint32_t l)
+static int
+qla1280_abort_device(struct scsi_qla_host *ha, int bus, int target, int lun)
 {
-    uint8_t     status;
-    uint16_t    mb[MAILBOX_REGISTER_COUNT];
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	int status;
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_abort_device");
-#endif
+	ENTER("qla1280_abort_device");
 
-    mb[0] = MBC_ABORT_DEVICE;
-    mb[1] = (b ? t | BIT_7 : t) << 8 | l;
-    status = qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
+	mb[0] = MBC_ABORT_DEVICE;
+	mb[1] = (bus ? target | BIT_7 : target) << 8 | lun;
+	status = qla1280_mailbox_command(ha, BIT_1 | BIT_0, &mb[0]);
 
-    /* Issue marker command. */
-    qla1280_marker(ha, b, t, l, MK_SYNC_ID_LUN);
+	/* Issue marker command. */
+	qla1280_marker(ha, bus, target, lun, MK_SYNC_ID_LUN);
 
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_abort_device: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_abort_device");
-#endif
-    return(status);
+	if (status)
+		dprintk(2, "qla1280_abort_device: **** FAILED ****\n");
+
+	LEAVE("qla1280_abort_device");
+	return status;
 }
 
 /*
@@ -3742,41 +3460,35 @@
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_abort_command(scsi_qla_host_t *ha, srb_t *sp)
+static int
+qla1280_abort_command(struct scsi_qla_host *ha, struct srb * sp, int handle)
 {
-    uint8_t         status;
-    uint16_t        mb[MAILBOX_REGISTER_COUNT];
-    uint32_t        b, t, l;
-    uint32_t        handle;
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	unsigned int bus, target, lun;
+	int status;
+
+	ENTER("qla1280_abort_command");
+
+	bus = SCSI_BUS_32(sp->cmd);
+	target = SCSI_TCN_32(sp->cmd);
+	lun = SCSI_LUN_32(sp->cmd);
+
+	sp->flags |= SRB_ABORT_PENDING;
+
+	mb[0] = MBC_ABORT_COMMAND;
+	mb[1] = (bus ? target | BIT_7 : target) << 8 | lun;
+	mb[2] = handle >> 16;
+	mb[3] = handle & 0xffff;
+	status = qla1280_mailbox_command(ha, 0x0f, &mb[0]);
+
+	if (status) {
+		dprintk(2, "qla1280_abort_command: **** FAILED ****\n");
+		sp->flags &= ~SRB_ABORT_PENDING;
+	}
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_abort_command");
-#endif
 
-    /* Locate handle number. */
-    for (handle = 0; handle < MAX_OUTSTANDING_COMMANDS; handle++)
-        if (ha->outstanding_cmds[handle] == sp)
-            break;
-
-                b  = SCSI_BUS_32(sp->cmd);
-        t  = SCSI_TCN_32(sp->cmd);
-        l  = SCSI_LUN_32(sp->cmd);
-
-        mb[0] = MBC_ABORT_COMMAND;
-        mb[1] = (b ? t | BIT_7 : t) << 8 | l;
-        mb[2] = handle >> 16;
-        mb[3] = (uint16_t)handle;
-        status = qla1280_mailbox_command(ha, BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]);
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-        if (status)
-            qla1280_print("qla1280_abort_command: **** FAILED ****\n\r");
-#endif
-        sp->flags |= SRB_ABORT_PENDING;
-
-        LEAVE("qla1280_abort_command");
-        return(status);
+	LEAVE("qla1280_abort_command");
+	return status;
 }
 
 /*
@@ -3786,25 +3498,21 @@
  * Input:
  *      ha = adapter block pointer.
  */
-STATIC void
-qla1280_reset_adapter(scsi_qla_host_t *ha)
+static void
+qla1280_reset_adapter(struct scsi_qla_host *ha)
 {
-    device_reg_t *reg = ha->iobase;
+	struct device_reg *reg = ha->iobase;
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_reset_adapter");
-#endif
+	ENTER("qla1280_reset_adapter");
 
-    /* Disable ISP chip */
-    ha->flags.online = FALSE;
-    WRT_REG_WORD(&reg->ictrl, ISP_RESET);
-    WRT_REG_WORD(&reg->host_cmd, HC_RESET_RISC);
-    WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
-    WRT_REG_WORD(&reg->host_cmd, HC_DISABLE_BIOS);
+	/* Disable ISP chip */
+	ha->flags.online = 0;
+	WRT_REG_WORD(&reg->ictrl, ISP_RESET);
+	WRT_REG_WORD(&reg->host_cmd,
+		     HC_RESET_RISC | HC_RELEASE_RISC | HC_DISABLE_BIOS);
+	RD_REG_WORD(&reg->id_l);	/* Flush PCI write */
 
-#ifdef QL_DEBUG_LEVEL_3
-    LEAVE("qla1280_reset_adapter");
-#endif
+	LEAVE("qla1280_reset_adapter");
 }
 
 /*
@@ -3813,38 +3521,34 @@
  *
  * Input:
  *      ha   = adapter block pointer.
- *      b    = SCSI BUS number
- *      t    = SCSI ID
- *      l    = SCSI LUN
+ *      bus  = SCSI BUS number
+ *      id   = SCSI ID
+ *      lun  = SCSI LUN
  *      type = marker modifier
  */
-STATIC void
-qla1280_marker(scsi_qla_host_t *ha, uint8_t b, uint32_t t, uint32_t l, uint8_t type)
+static void
+qla1280_marker(struct scsi_qla_host *ha, int bus, int id, int lun, u8 type)
 {
-    mrk_entry_t     *pkt;
+	struct mrk_entry *pkt;
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_marker");
-#endif
+	ENTER("qla1280_marker");
 
-    /* Get request packet. */
-    if ( (pkt = (mrk_entry_t *)qla1280_req_pkt(ha)) )
-    {
-        pkt->entry_type = MARKER_TYPE;
-        pkt->lun = (uint8_t)l;
-        pkt->target = (uint8_t)(b ? (t | BIT_7) : t);
-        pkt->modifier = type;
+	/* Get request packet. */
+	if ((pkt = (struct mrk_entry *) qla1280_req_pkt(ha))) {
+		pkt->entry_type = MARKER_TYPE;
+		pkt->lun = (uint8_t) lun;
+		pkt->target = (uint8_t) (bus ? (id | BIT_7) : id);
+		pkt->modifier = type;
+		pkt->entry_status = 0;
 
-        /* Issue command to ISP */
-        qla1280_isp_cmd(ha);
-    }
+		/* Issue command to ISP */
+		qla1280_isp_cmd(ha);
+	}
 
-#ifdef QL_DEBUG_LEVEL_3
-    LEAVE("qla1280_marker");
-#endif
+	LEAVE("qla1280_marker");
 }
 
-#if  QLA1280_64BIT_SUPPORT
+
 /*
  * qla1280_64bit_start_scsi
  *      The start SCSI is responsible for building request packets on
@@ -3857,296 +3561,271 @@
  * Returns:
  *      0 = success, was able to issue command.
  */
-STATIC uint8_t
-qla1280_64bit_start_scsi(scsi_qla_host_t *ha, srb_t *sp)
+static int
+qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 {
-    device_reg_t    *reg   = ha->iobase;
-    uint8_t         status = 0;
-    Scsi_Cmnd       *cmd = sp->cmd;
-    uint32_t        cnt;
-    cmd_a64_entry_t     *pkt;
-    uint16_t        req_cnt;
-    uint16_t        seg_cnt;
-    struct scatterlist    *sg = (struct scatterlist *) NULL;
-    uint32_t        *dword_ptr;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_64bit_start_scsi:");
-#endif
-
-    if( qla1280_check_for_dead_scsi_bus(ha, sp) )
-    {
-        return(0);
-    }
-
-    /* Calculate number of entries and segments required. */
-    seg_cnt = 0;
-    req_cnt = 1;
-    if (cmd->use_sg)
-    {
-        seg_cnt =  cmd->use_sg;
-        sg = (struct scatterlist *) cmd->request_buffer;
-            
-        if (seg_cnt > 2)
-        {
-           req_cnt += (uint16_t)(seg_cnt - 2) / 5;
-           if ((uint16_t)(seg_cnt - 2) % 5)
-               req_cnt++;
-        }
-    }
-    else if (cmd->request_bufflen)  /* If data transfer. */
-    {
-        DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen));
-        seg_cnt = 1;
-    }
-
-    /* Acquire ring specific lock */
-    QLA1280_RING_LOCK(ha);
-
-    if ((uint16_t)(req_cnt + 2) >= ha->req_q_cnt)
-    {
-        /* Calculate number of free request entries. */
-        cnt = RD_REG_WORD(&reg->mailbox4);
-        if (ha->req_ring_index < cnt)
-            ha->req_q_cnt = cnt - ha->req_ring_index;
-        else
-            ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
-    }
-
-    /* If room for request in request ring. */
-    if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt)
-    {
-        /* Check for room in outstanding command list. */
-        for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS &&
-            ha->outstanding_cmds[cnt] != 0; cnt++)
-            ;
-
-        if (cnt < MAX_OUTSTANDING_COMMANDS)
-        {
-            ha->outstanding_cmds[cnt] = sp;
-            ha->req_q_cnt -= req_cnt;
-            CMD_HANDLE(sp->cmd) = (unsigned char *) (u_long) cnt;
-
-            /*
-            * Build command packet.
-            */
-            pkt = (cmd_a64_entry_t *)ha->request_ring_ptr;
-
-            pkt->entry_type = COMMAND_A64_TYPE;
-            pkt->entry_count = (uint8_t)req_cnt;
-            pkt->sys_define = (uint8_t)ha->req_ring_index;
-            pkt->handle = (uint32_t)cnt;
-
-            /* Zero out remaining portion of packet. */
-            dword_ptr = (uint32_t *)pkt + 2;
-            for (cnt = 2; cnt < REQUEST_ENTRY_SIZE/4; cnt++)
-                *dword_ptr++ = 0;
-
-            /* Set ISP command timeout. */
-            pkt->timeout = (uint16_t)30;
-
-            /* Set device target ID and LUN */
-            pkt->lun = SCSI_LUN_32(cmd);
-            pkt->target = SCSI_BUS_32(cmd) ?
-                    (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
-
-            /* Enable simple tag queuing if device supports it. */
-            if (cmd->device->tagged_queue )
-                pkt->control_flags |= BIT_3;
-
-            /* Load SCSI command packet. */
-            pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd);
-            BCOPY(&(CMD_CDBP(cmd)), pkt->scsi_cdb, pkt->cdb_len);
-            DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]));
-
-            /*
-            * Load data segments.
-            */
-            if (seg_cnt)                /* If data transfer. */
-            {
-                /* Set transfer direction. */
-                if ( (cmd->data_cmnd[0] == WRITE_6) )
-                    pkt->control_flags |= BIT_6;
-                else
-                    pkt->control_flags |= (BIT_5|BIT_6);
-                    
-                sp->dir = pkt->control_flags & (BIT_5|BIT_6);
-
-                /* Set total data segment count. */
-                pkt->dseg_count = seg_cnt;
-
-                /* Setup packet address segment pointer. */
-                dword_ptr = (uint32_t *)&pkt->dseg_0_address;
-
-                if (cmd->use_sg)              /* If scatter gather */
-                {
-                    /* Load command entry data segments. */
-                    for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--)
-                    {
-                        DEBUG(sprintf(debug_buff,"SG Segment ap=0x%p, len=0x%x\n\r",sg->address,sg->length));
-                        DEBUG(qla1280_print(debug_buff));
-                        *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(sg->address));
-                        *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address));
-                        *dword_ptr++ = sg->length;
-                        sg++;
-                    }
-#ifdef QL_DEBUG_LEVEL_5
-                    qla1280_print(
-                            "qla1280_64bit_start_scsi: Scatter/gather command packet data - ");
-                    qla1280_print("b ");
-                    qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10);
-                    qla1280_print(" t ");
-                    qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10);
-                    qla1280_print(" d ");
-                    qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10);
-                    qla1280_print("\n\r");
-                    qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE);
-#endif
-                    /*
-                    * Build continuation packets.
-                    */
-                    while (seg_cnt > 0)
-                    {
-                        /* Adjust ring index. */
-                        ha->req_ring_index++;
-                        if (ha->req_ring_index == REQUEST_ENTRY_CNT)
-                        {
-                            ha->req_ring_index = 0;
-                            ha->request_ring_ptr = ha->request_ring;
-                        }
-                        else
-                            ha->request_ring_ptr++;
-
-                        pkt = (cmd_a64_entry_t *)ha->request_ring_ptr;
-
-                        /* Zero out packet. */
-                        dword_ptr = (uint32_t *)pkt;
-                        for (cnt = 0;cnt < REQUEST_ENTRY_SIZE/4; cnt++)
-                            *dword_ptr++ = 0;
-
-                        /* Load packet defaults. */
-                        ((cont_a64_entry_t *)pkt)->entry_type =
-                                CONTINUE_A64_TYPE;
-                        ((cont_a64_entry_t *)pkt)->entry_count = 1;
-                        ((cont_a64_entry_t *)pkt)->sys_define = (uint8_t)
-                                ha->req_ring_index;
-
-                        /* Setup packet address segment pointer. */
-                        dword_ptr = (uint32_t *)
-                                &((cont_a64_entry_t *)pkt)->dseg_0_address;
-
-                        /* Load continuation entry data segments. */
-                        for (cnt = 0; cnt < 5 && seg_cnt; cnt++, seg_cnt--)
-                        {
-                            *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(sg->address));
-                            *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(sg->address));
-                            *dword_ptr++ = sg->length;
-                            sg++;
-                        }
-#ifdef QL_DEBUG_LEVEL_5
-                        qla1280_print(
-                                "qla1280_64bit_start_scsi: continuation packet data - c");
-                        qla1280_print(" b ");
-                        qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10);
-
-                        qla1280_print(" t ");
-                        qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10);
-                        qla1280_print(" d ");
-                        qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10);
-                        qla1280_print("\n\r");
-                        qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE);
-#endif
-                    }
-                }
-                else                    /* No scatter gather data transfer */
-                {
-                    *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_LOW(cmd->request_buffer));
-                    *dword_ptr++ = cpu_to_le32(VIRT_TO_BUS_HIGH(cmd->request_buffer));
-                    *dword_ptr = (uint32_t) cmd->request_bufflen;
-#ifdef QL_DEBUG_LEVEL_5
-                    qla1280_print(
-                            "qla1280_64bit_start_scsi: No scatter/gather command packet data - c");
-                    qla1280_print(" b ");
-                    qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10);
-                    qla1280_print(" t ");
-                    qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10);
-                    qla1280_print(" d ");
-                    qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10);
-                    qla1280_print("\n\r");
-                    qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE);
-#endif
-                }
-            }
-#ifdef QL_DEBUG_LEVEL_5
-            else                            /* No data transfer */
-            {
-                *dword_ptr++ = (uint32_t) 0;
-                *dword_ptr++ = (uint32_t) 0;
-                *dword_ptr = (uint32_t)  0;
-                qla1280_print(
-                        "qla1280_64bit_start_scsi: No data, command packet data - c");
-                qla1280_print(" b ");
-                qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10);
-                qla1280_print(" t ");
-                qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10);
-                qla1280_print(" d ");
-                qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10);
-                qla1280_print("\n\r");
-                qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE);
-            }
-#endif
-            /* Adjust ring index. */
-            ha->req_ring_index++;
-            if (ha->req_ring_index == REQUEST_ENTRY_CNT)
-            {
-                ha->req_ring_index = 0;
-                ha->request_ring_ptr = ha->request_ring;
-            }
-            else
-                ha->request_ring_ptr++;
-
-            /* Set chip new ring index. */
-            WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-        }
-        else
-        {
-            status = 1;
-#ifdef QL_DEBUG_LEVEL_2
-            qla1280_print(
-                    "qla1280_64bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r");
-            qla1280_print(" req_q_cnt=");
-            qla1280_output_number((uint32_t)ha->req_q_cnt, 16);
-#endif
-        }
-    }
-    else
-    {
-        status = 1;
-#ifdef QL_DEBUG_LEVEL_2
-        qla1280_print("qla1280_64bit_start_scsi: in-ptr=");
-        qla1280_output_number((uint32_t)ha->req_ring_index, 16);
-        qla1280_print(" req_q_cnt=");
-        qla1280_output_number((uint32_t)ha->req_q_cnt, 16);
-        qla1280_print(" req_cnt=");
-        qla1280_output_number((uint32_t)req_cnt, 16);
-        qla1280_print("\n\r");
-#endif
-    }
-
-    /* Release ring specific lock */
-    QLA1280_RING_UNLOCK(ha);
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (status)
-        qla1280_print("qla1280_64bit_start_scsi: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_64bit_start_scsi: exiting normally\n\r");
-#endif
-    return(status);
+	struct device_reg *reg = ha->iobase;
+	Scsi_Cmnd *cmd = sp->cmd;
+	cmd_a64_entry_t *pkt;
+	struct scatterlist *sg = NULL;
+	u32 *dword_ptr;
+	dma_addr_t dma_handle;
+	int status = 0;
+	int cnt;
+	int req_cnt;
+	u16 seg_cnt;
+
+	ENTER("qla1280_64bit_start_scsi:");
+
+	/* Calculate number of entries and segments required. */
+	req_cnt = 1;
+	if (cmd->use_sg) {
+		sg = (struct scatterlist *) cmd->request_buffer;
+		seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+				     scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
+		if (seg_cnt > 2) {
+			req_cnt += (seg_cnt - 2) / 5;
+			if ((seg_cnt - 2) % 5)
+				req_cnt++;
+		}
+	} else if (cmd->request_bufflen) {	/* If data transfer. */
+		seg_cnt = 1;
+	} else {
+		seg_cnt = 0;
+	}
+
+	if ((req_cnt + 2) >= ha->req_q_cnt) {
+		/* Calculate number of free request entries. */
+		cnt = RD_REG_WORD(&reg->mailbox4);
+		if (ha->req_ring_index < cnt)
+			ha->req_q_cnt = cnt - ha->req_ring_index;
+		else
+			ha->req_q_cnt =
+				REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
+	}
+
+	/* If room for request in request ring. */
+	if ((req_cnt + 2) >= ha->req_q_cnt) {
+		status = 1;
+		dprintk(2, "qla1280_64bit_start_scsi: in-ptr=0x%x  req_q_cnt="
+			"0x%xreq_cnt=0x%x", ha->req_ring_index, ha->req_q_cnt,
+			req_cnt);
+		goto out;
+	}
+
+	/* Check for room in outstanding command list. */
+	for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS &&
+		     ha->outstanding_cmds[cnt] != 0; cnt++);
+
+	if (cnt >= MAX_OUTSTANDING_COMMANDS) {
+		status = 1;
+		dprintk(2, "qla1280_64bit_start_scsi: NO ROOM IN "
+			"OUTSTANDING ARRAY, req_q_cnt=0x%x", ha->req_q_cnt);
+		goto out;
+	}
+
+	ha->outstanding_cmds[cnt] = sp;
+	ha->req_q_cnt -= req_cnt;
+	CMD_HANDLE(sp->cmd) = (unsigned char *)(unsigned long)(cnt + 1);
+
+	dprintk(2, "64bit_start: cmd=%p sp=%p CDB=%xm, handle %lx\n", cmd, sp,
+		cmd->cmnd[0], (long)CMD_HANDLE(sp->cmd));
+	dprintk(2, "             bus %i, target %i, lun %i\n",
+		SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
+	qla1280_dump_buffer(2, cmd->cmnd, MAX_COMMAND_SIZE);
+
+	/*
+	 * Build command packet.
+	 */
+	pkt = (cmd_a64_entry_t *) ha->request_ring_ptr;
+
+	pkt->entry_type = COMMAND_A64_TYPE;
+	pkt->entry_count = (uint8_t) req_cnt;
+	pkt->sys_define = (uint8_t) ha->req_ring_index;
+	pkt->entry_status = 0;
+	pkt->handle = cpu_to_le32(cnt);
+
+	/* Zero out remaining portion of packet. */
+	memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
+
+	/* Set ISP command timeout. */
+	pkt->timeout = cpu_to_le16(30);
+
+	/* Set device target ID and LUN */
+	pkt->lun = SCSI_LUN_32(cmd);
+	pkt->target = SCSI_BUS_32(cmd) ?
+		(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
+
+	/* Enable simple tag queuing if device supports it. */
+	if (DEV_SIMPLE_TAGS(cmd->device))
+		pkt->control_flags |= cpu_to_le16(BIT_3);
+
+	/* Load SCSI command packet. */
+	pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
+	memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+	/* dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
+
+	/* Set transfer direction. */
+	sp->dir = qla1280_data_direction(cmd);
+	pkt->control_flags |= cpu_to_le16(sp->dir);
+
+	/* Set total data segment count. */
+	pkt->dseg_count = cpu_to_le16(seg_cnt);
+
+	/*
+	 * Load data segments.
+	 */
+	if (seg_cnt) {	/* If data transfer. */
+		/* Setup packet address segment pointer. */
+		dword_ptr = (u32 *)&pkt->dseg_0_address;
+
+		if (cmd->use_sg) {	/* If scatter gather */
+			/* Load command entry data segments. */
+			for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) {
+				dma_handle = sg_dma_address(sg);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+				if (ha->flags.use_pci_vchannel)
+					sn_pci_set_vchan(ha->pdev, &dma_handle,
+							 SCSI_BUS_32(cmd));
+#endif
+				*dword_ptr++ =
+					cpu_to_le32(pci_dma_lo32(dma_handle));
+				*dword_ptr++ =
+					cpu_to_le32(pci_dma_hi32(dma_handle));
+				*dword_ptr++ = cpu_to_le32(sg_dma_len(sg));
+				sg++;
+				dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
+					cpu_to_le32(pci_dma_hi32(dma_handle)),
+					cpu_to_le32(pci_dma_lo32(dma_handle)),
+					cpu_to_le32(sg_dma_len(sg)));
+			}
+			dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
+				"command packet data - b %i, t %i, l %i \n",
+				SCSI_BUS_32(cmd), SCSI_TCN_32(cmd),
+				SCSI_LUN_32(cmd));
+			qla1280_dump_buffer(5, (char *)pkt,
+					    REQUEST_ENTRY_SIZE);
+
+			/*
+			 * Build continuation packets.
+			 */
+			dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
+				"remains\n", seg_cnt);
+
+			while (seg_cnt > 0) {
+				/* Adjust ring index. */
+				ha->req_ring_index++;
+				if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+					ha->req_ring_index = 0;
+					ha->request_ring_ptr =
+						ha->request_ring;
+				} else
+						ha->request_ring_ptr++;
+
+				pkt = (cmd_a64_entry_t *)ha->request_ring_ptr;
+
+				/* Zero out packet. */
+				memset(pkt, 0, REQUEST_ENTRY_SIZE);
+
+				/* Load packet defaults. */
+				((struct cont_a64_entry *) pkt)->entry_type =
+					CONTINUE_A64_TYPE;
+				((struct cont_a64_entry *) pkt)->entry_count = 1;
+				((struct cont_a64_entry *) pkt)->sys_define =
+					(uint8_t)ha->req_ring_index;
+				/* Setup packet address segment pointer. */
+				dword_ptr =
+					(u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
+
+				/* Load continuation entry data segments. */
+				for (cnt = 0; cnt < 5 && seg_cnt;
+				     cnt++, seg_cnt--) {
+					dma_handle = sg_dma_address(sg);
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+				if (ha->flags.use_pci_vchannel)
+					sn_pci_set_vchan(ha->pdev, &dma_handle,
+							 SCSI_BUS_32(cmd));
+#endif
+					*dword_ptr++ =
+						cpu_to_le32(pci_dma_lo32(dma_handle));
+					*dword_ptr++ =
+						cpu_to_le32(pci_dma_hi32(dma_handle));
+					*dword_ptr++ =
+						cpu_to_le32(sg_dma_len(sg));
+					dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
+						cpu_to_le32(pci_dma_hi32(dma_handle)),
+						cpu_to_le32(pci_dma_lo32(dma_handle)),
+						cpu_to_le32(sg_dma_len(sg)));
+					sg++;
+				}
+				dprintk(5, "qla1280_64bit_start_scsi: "
+					"continuation packet data - b %i, t "
+					"%i, l %i \n", SCSI_BUS_32(cmd),
+					SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
+				qla1280_dump_buffer(5, (char *)pkt,
+						    REQUEST_ENTRY_SIZE);
+			}
+		} else {	/* No scatter gather data transfer */
+			struct page *page = virt_to_page(cmd->request_buffer);
+			unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK;
+
+			dma_handle = pci_map_page(ha->pdev, page, off,
+						  cmd->request_bufflen,
+						  scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
+			/* save dma_handle for pci_unmap_page */
+			sp->saved_dma_handle = dma_handle;
+#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
+			if (ha->flags.use_pci_vchannel)
+				sn_pci_set_vchan(ha->pdev, &dma_handle,
+						 SCSI_BUS_32(cmd));
+#endif
+			*dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle));
+			*dword_ptr++ = cpu_to_le32(pci_dma_hi32(dma_handle));
+			*dword_ptr = (uint32_t)cmd->request_bufflen;
+
+			dprintk(5, "qla1280_64bit_start_scsi: No scatter/"
+				"gather command packet data - b %i, t %i, "
+				"l %i \n", SCSI_BUS_32(cmd), SCSI_TCN_32(cmd),
+				SCSI_LUN_32(cmd));
+			qla1280_dump_buffer(5, (char *)pkt,
+					    REQUEST_ENTRY_SIZE);
+		}
+	} else {	/* No data transfer */
+		dword_ptr = (uint32_t *)(pkt + 1);
+		*dword_ptr++ = 0;
+		*dword_ptr++ = 0;
+		*dword_ptr = 0;
+		dprintk(5, "qla1280_64bit_start_scsi: No data, command "
+			"packet data - b %i, t %i, l %i \n",
+			SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
+		qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE);
+	}
+	/* Adjust ring index. */
+	ha->req_ring_index++;
+	if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+		ha->req_ring_index = 0;
+		ha->request_ring_ptr = ha->request_ring;
+	} else
+		ha->request_ring_ptr++;
+
+	/* Set chip new ring index. */
+	dprintk(2,
+		"qla1280_64bit_start_scsi: Wakeup RISC for pending command\n");
+	sp->flags |= SRB_SENT;
+	ha->actthreads++;
+	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
+
+ out:
+	if (status)
+		dprintk(2, "qla1280_64bit_start_scsi: **** FAILED ****\n");
+	else
+		dprintk(3, "qla1280_64bit_start_scsi: exiting normally\n");
+
+	return status;
 }
-#endif  /* QLA1280_64BIT_SUPPORT */
+
 
 /*
  * qla1280_32bit_start_scsi
@@ -4155,9 +3834,9 @@
  *
  *      The Qlogic firmware interface allows every queue slot to have a SCSI
  *      command and up to 4 scatter/gather (SG) entries.  If we need more
- *      than 4 SG entries, then continuation entries are used that can 
+ *      than 4 SG entries, then continuation entries are used that can
  *      hold another 7 entries each.  The start routine determines if there
- *      is eought empty slots then build the combination of requests to 
+ *      is eought empty slots then build the combination of requests to
  *      fulfill the OS request.
  *
  * Input:
@@ -4167,302 +3846,253 @@
  * Returns:
  *      0 = success, was able to issue command.
  */
-STATIC uint8_t
-qla1280_32bit_start_scsi(scsi_qla_host_t *ha, srb_t *sp)
+static int
+qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
 {
-    device_reg_t    *reg   = ha->iobase;
-    uint8_t         status = 0;
-    Scsi_Cmnd       *cmd = sp->cmd;
-    uint32_t        cnt;
-    cmd_entry_t     *pkt;
-    uint16_t        req_cnt;
-    uint16_t        seg_cnt;
-    struct scatterlist    *sg = (struct scatterlist *) NULL;
-    uint8_t        *data_ptr;
-    uint32_t        *dword_ptr;
-
-    ENTER("qla1280_32bit_start_scsi");
-
-
-    if( qla1280_check_for_dead_scsi_bus(ha, sp) )
-    {
-        return(0);
-    }
-
-    /* Calculate number of entries and segments required. */
-    req_cnt = 1;
-    if (cmd->use_sg)
-    {
-        /*
-        * We must build an SG list in adapter format, as the kernel's SG list
-        * cannot be used directly because of data field size (__alpha__)
-        * differences and the kernel SG list uses virtual addresses where
-        * we need physical addresses.
-        */
-        seg_cnt =  cmd->use_sg;
-        sg = (struct scatterlist *) cmd->request_buffer;
-        /* 
-        * if greater than four sg entries then we need to allocate
-        * continuation entries
-        */
-        if (seg_cnt > 4)
-        {
-            req_cnt += (uint16_t)(seg_cnt - 4) / 7;
-            if ((uint16_t)(seg_cnt - 4) % 7)
-                req_cnt++;
-        }
-        DEBUG(sprintf(debug_buff,"S/G for data transfer -num segs(%d), req blk cnt(%d)\n\r",seg_cnt,req_cnt));
-        DEBUG(qla1280_print(debug_buff));
-    }
-    else if (cmd->request_bufflen)  /* If data transfer. */
-    {
-        DEBUG(printk("Single data transfer (0x%x)\n",cmd->request_bufflen));
-        seg_cnt = 1;
-    }
-    else
-    {
-        DEBUG(printk("No data transfer \n"));
-        seg_cnt = 0;
-    }
-
-    /* Acquire ring specific lock */
-    QLA1280_RING_LOCK(ha);
-
-    if ((uint16_t)(req_cnt + 2) >= ha->req_q_cnt)
-    {
-        /* Calculate number of free request entries. */
-        cnt = RD_REG_WORD(&reg->mailbox4);
-        if (ha->req_ring_index < cnt)
-            ha->req_q_cnt = cnt - ha->req_ring_index;
-        else
-            ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
-    }
-
-    DEBUG(sprintf(debug_buff,"Number of free entries = (%d)\n\r",ha->req_q_cnt));
-    DEBUG(qla1280_print(debug_buff));
-    /* If room for request in request ring. */
-    if ((uint16_t)(req_cnt + 2) < ha->req_q_cnt)
-    {
-        /* Check for empty slot in outstanding command list. */
-        for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS &&
-            (ha->outstanding_cmds[cnt] != 0); cnt++)
-            ;
-
-        if (cnt < MAX_OUTSTANDING_COMMANDS)
-        {
-            CMD_HANDLE(sp->cmd) = (unsigned char *)(unsigned long)cnt;
-            ha->outstanding_cmds[cnt] = sp;
-            ha->req_q_cnt -= req_cnt;
-
-            /*
-            * Build command packet.
-            */
-            pkt = (cmd_entry_t *)ha->request_ring_ptr;
-
-            pkt->entry_type = COMMAND_TYPE;
-            pkt->entry_count = (uint8_t)req_cnt;
-            pkt->sys_define = (uint8_t)ha->req_ring_index;
-            pkt->handle = (uint32_t)cnt;
-
-            /* Zero out remaining portion of packet. */
-            dword_ptr = (uint32_t *)pkt + 2;
-            for (cnt = 2; cnt < REQUEST_ENTRY_SIZE/4; cnt++)
-                *dword_ptr++ = 0;
-
-            /* Set ISP command timeout. */
-            pkt->timeout = (uint16_t)30;
-
-            /* Set device target ID and LUN */
-            pkt->lun = SCSI_LUN_32(cmd);
-            pkt->target = SCSI_BUS_32(cmd) ?
-                    (SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
-
-            /* Enable simple tag queuing if device supports it. */
-            if (cmd->device->tagged_queue )
-                pkt->control_flags |= BIT_3;
-
-            /* Load SCSI command packet. */
-            pkt->cdb_len = (uint16_t)CMD_CDBLEN(cmd);
-            data_ptr = (uint8_t *) &(CMD_CDBP(cmd));
-            for (cnt = 0; cnt < pkt->cdb_len; cnt++)
-                pkt->scsi_cdb[cnt] = *data_ptr++;
-            DEBUG(printk("Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]));
-            /*
-            * Load data segments.
-            */
-            if (seg_cnt)
-            {
-                DEBUG(printk("loading data segments..\n"));
-                /* Set transfer direction (READ and WRITE) */
-                /* Linux doesn't tell us                   */
-
-                /*
-                * 3/10 dg - Normally, we should need this check with our F/W
-                * but because of a small issue with it we do.
-                *
-                * For block devices, cmd->request.cmd has the operation 
-                * For character devices, this isn't always set properly, so
-                * we need to check data_cmnd[0].  This catches the conditions
-                * for st.c, but not sg. Generic commands are pass down to us.
-                */
-                if ( (cmd->data_cmnd[0] == WRITE_6) )
-                    pkt->control_flags |= BIT_6;
-                else
-                    pkt->control_flags |= (BIT_5|BIT_6);
-                    
-                sp->dir = pkt->control_flags & (BIT_5|BIT_6);
-
-                /* Set total data segment count. */
-                pkt->dseg_count = seg_cnt;
-
-                /* Setup packet address segment pointer. */
-                dword_ptr = (uint32_t *)&pkt->dseg_0_address;
-
-                if (cmd->use_sg)     /* If scatter gather */
-                {
-                    DEBUG(qla1280_print("Building S/G data segments..\n\r"));
-                    DEBUG(qla1280_dump_buffer((caddr_t)sg, 4*16 ));
-                    /* Load command entry data segments. */
-                    for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--)
-                    {
-                        *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(sg->address));
-                        *dword_ptr++ = sg->length;
-                        DEBUG(sprintf(debug_buff,"SG Segment ap=0x%p, len=0x%x\n\r",sg->address,sg->length));
-                        DEBUG(qla1280_print(debug_buff));
-                        sg++;
-                    }
-                    /*
-                    * Build continuation packets.
-                    */
-                    while (seg_cnt > 0)
-                    {
-                        /* Adjust ring index. */
-                        ha->req_ring_index++;
-                        if (ha->req_ring_index == REQUEST_ENTRY_CNT)
-                        {
-                            ha->req_ring_index = 0;
-                            ha->request_ring_ptr = ha->request_ring;
-                        }
-                        else
-                            ha->request_ring_ptr++;
-
-                        pkt = (cmd_entry_t *)ha->request_ring_ptr;
-
-                        /* Zero out packet. */
-                        dword_ptr = (uint32_t *)pkt;
-                        for (cnt = 0;cnt < REQUEST_ENTRY_SIZE/4; cnt++)
-                            *dword_ptr++ = 0;
-
-                        /* Load packet defaults. */
-                        ((cont_entry_t *)pkt)->entry_type =
-                                CONTINUE_TYPE;
-                        ((cont_entry_t *)pkt)->entry_count = 1;
-
-                        ((cont_entry_t *)pkt)->sys_define = (uint8_t)
-                                ha->req_ring_index;
-
-                        /* Setup packet address segment pointer. */
-                        dword_ptr = (uint32_t *)
-                                &((cont_entry_t *)pkt)->dseg_0_address;
-
-                        /* Load continuation entry data segments. */
-                        for (cnt = 0; cnt < 7 && seg_cnt; cnt++, seg_cnt--)
-                        {
-                            *dword_ptr++ = (u_int) cpu_to_le32(VIRT_TO_BUS(sg->address));
-                            *dword_ptr++ = sg->length;
-                            sg++;
-                        }
-#ifdef QL_DEBUG_LEVEL_5
-                        qla1280_print(
-                                "qla1280_32bit_start_scsi: continuation packet data - scsi(");
-                        qla1280_output_number((uint32_t)SCSI_BUS_32(cmd), 10);
-                        qla1280_print(":");
-                        qla1280_output_number((uint32_t)SCSI_TCN_32(cmd), 10);
-                        qla1280_print(":");
-                        qla1280_output_number((uint32_t)SCSI_LUN_32(cmd), 10);
-                        qla1280_print(")\n\r");
-                        qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE);
-#endif
-                    }
-                }
-                else                    /* No scatter gather data transfer */
-                {
-                    *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS(cmd->request_buffer));
-                    *dword_ptr = (uint32_t) cmd->request_bufflen;
-                    DEBUG(printk("Single Segment ap=0x%p, len=0x%x\n",cmd->request_buffer,cmd->request_bufflen));
-                }
-            }
-            else                            /* No data transfer */
-            {
-                *dword_ptr++ = (uint32_t) 0;
-                *dword_ptr = (uint32_t)  0;
-#ifdef QL_DEBUG_LEVEL_5
-                qla1280_print(
-                        "qla1280_32bit_start_scsi: No data, command packet data - ");
-                qla1280_print("\n\r");
-                qla1280_dump_buffer((caddr_t)pkt, REQUEST_ENTRY_SIZE);
-#endif
-            }
-#ifdef QL_DEBUG_LEVEL_5
-            qla1280_print("qla1280_32bit_start_scsi: First IOCB block:\n\r");
-            qla1280_dump_buffer((caddr_t)ha->request_ring_ptr, REQUEST_ENTRY_SIZE);
-#endif
-            /* Adjust ring index. */
-            ha->req_ring_index++;
-            if (ha->req_ring_index == REQUEST_ENTRY_CNT)
-            {
-                ha->req_ring_index = 0;
-                ha->request_ring_ptr = ha->request_ring;
-            }
-            else
-                ha->request_ring_ptr++;
-
-            /* Set chip new ring index. */
-            DEBUG(qla1280_print("qla1280_32bit_start_scsi: Wakeup RISC for pending command\n\r"));
-            ha->qthreads--;
-            sp->u_start = jiffies;
-            sp->flags |= SRB_SENT;
-            ha->actthreads++;
-            /* qla1280_output_number((uint32_t)ha->actthreads++, 16); */
-            WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
-        }
-        else
-        {
-            status = 1;
-#ifdef QL_DEBUG_LEVEL_2
-            qla1280_print(
-                    "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING ARRAY\n\r");
-            qla1280_print(" req_q_cnt=");
-            qla1280_output_number((uint32_t)ha->req_q_cnt, 16);
-            qla1280_print("\n\r");
-#endif
-        }
-    }
-    else
-    {
-        status = 1;
-#ifdef QL_DEBUG_LEVEL_2
-        /*  qla1280_print("qla1280_32bit_start_scsi: in-ptr=");
-        qla1280_output_number((uint32_t)ha->req_ring_index, 16);
-        qla1280_print(" req_q_cnt=");
-        qla1280_output_number((uint32_t)ha->req_q_cnt, 16);
-        qla1280_print(" req_cnt=");
-        qla1280_output_number((uint32_t)req_cnt, 16);
-        qla1280_print("\n\r"); */
-#endif
-    }
-
-    /* Release ring specific lock */
-    QLA1280_RING_UNLOCK(ha);
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    /* if (status)
-    qla1280_print("qla1280_32bit_start_scsi: **** FAILED ****\n\r"); */
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-            LEAVE("qla1280_32bit_start_scsi");
-#endif
-    return(status);
+	struct device_reg *reg = ha->iobase;
+	Scsi_Cmnd *cmd = sp->cmd;
+	struct cmd_entry *pkt;
+	struct scatterlist *sg = NULL;
+	uint32_t *dword_ptr;
+	int status = 0;
+	int cnt;
+	int req_cnt;
+	uint16_t seg_cnt;
+	dma_addr_t dma_handle;
+
+	ENTER("qla1280_32bit_start_scsi");
+
+	dprintk(1, "32bit_start: cmd=%p sp=%p CDB=%x\n", cmd, sp,
+		cmd->cmnd[0]);
+
+	/* Calculate number of entries and segments required. */
+	req_cnt = 1;
+	if (cmd->use_sg) {
+		/*
+		 * We must build an SG list in adapter format, as the kernel's
+		 * SG list cannot be used directly because of data field size
+		 * (__alpha__) differences and the kernel SG list uses virtual
+		 * addresses where we need physical addresses.
+		 */
+		sg = (struct scatterlist *) cmd->request_buffer;
+		seg_cnt = pci_map_sg(ha->pdev, sg, cmd->use_sg,
+				     scsi_to_pci_dma_dir(cmd->sc_data_direction));
+
+		/*
+		 * if greater than four sg entries then we need to allocate
+		 * continuation entries
+		 */
+		if (seg_cnt > 4) {
+			req_cnt += (seg_cnt - 4) / 7;
+			if ((seg_cnt - 4) % 7)
+				req_cnt++;
+		}
+		dprintk(3, "S/G Transfer cmd=%p seg_cnt=0x%x, req_cnt=%x\n",
+			cmd, seg_cnt, req_cnt);
+	} else if (cmd->request_bufflen) {	/* If data transfer. */
+		dprintk(3, "No S/G transfer t=%x cmd=%p len=%x CDB=%x\n",
+			SCSI_TCN_32(cmd), cmd, cmd->request_bufflen,
+			cmd->cmnd[0]);
+		seg_cnt = 1;
+	} else {
+		/* dprintk(1, "No data transfer \n"); */
+		seg_cnt = 0;
+	}
+
+	if ((req_cnt + 2) >= ha->req_q_cnt) {
+		/* Calculate number of free request entries. */
+		cnt = RD_REG_WORD(&reg->mailbox4);
+		if (ha->req_ring_index < cnt)
+			ha->req_q_cnt = cnt - ha->req_ring_index;
+		else
+			ha->req_q_cnt =
+				REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
+	}
+
+	dprintk(3, "Number of free entries=(%d) seg_cnt=0x%x\n",
+		ha->req_q_cnt, seg_cnt);
+	/* If room for request in request ring. */
+	if ((req_cnt + 2) >= ha->req_q_cnt) {
+		status = 1;
+		dprintk(2, "qla1280_32bit_start_scsi: in-ptr=0x%x, "
+			"req_q_cnt=0x%x, req_cnt=0x%x", ha->req_ring_index,
+			ha->req_q_cnt, req_cnt);
+		goto out;
+	}
+
+	/* Check for empty slot in outstanding command list. */
+	for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS &&
+		     (ha->outstanding_cmds[cnt] != 0); cnt++) ;
+
+	if (cnt >= MAX_OUTSTANDING_COMMANDS) {
+		status = 1;
+		dprintk(2, "qla1280_32bit_start_scsi: NO ROOM IN OUTSTANDING "
+			"ARRAY, req_q_cnt=0x%x\n", ha->req_q_cnt);
+		goto out;
+	}
+
+	CMD_HANDLE(sp->cmd) = (unsigned char *) (unsigned long)(cnt + 1);
+	ha->outstanding_cmds[cnt] = sp;
+	ha->req_q_cnt -= req_cnt;
+
+	/*
+	 * Build command packet.
+	 */
+	pkt = (struct cmd_entry *) ha->request_ring_ptr;
+
+	pkt->entry_type = COMMAND_TYPE;
+	pkt->entry_count = (uint8_t) req_cnt;
+	pkt->sys_define = (uint8_t) ha->req_ring_index;
+	pkt->entry_status = 0;
+	pkt->handle = cpu_to_le32(cnt);
+
+	/* Zero out remaining portion of packet. */
+	memset(((char *)pkt + 8), 0, (REQUEST_ENTRY_SIZE - 8));
+
+	/* Set ISP command timeout. */
+	pkt->timeout = cpu_to_le16(30);
+
+	/* Set device target ID and LUN */
+	pkt->lun = SCSI_LUN_32(cmd);
+	pkt->target = SCSI_BUS_32(cmd) ?
+		(SCSI_TCN_32(cmd) | BIT_7) : SCSI_TCN_32(cmd);
+
+	/* Enable simple tag queuing if device supports it. */
+	if (DEV_SIMPLE_TAGS(cmd->device))
+		pkt->control_flags |= cpu_to_le16(BIT_3);
+
+	/* Load SCSI command packet. */
+	pkt->cdb_len = cpu_to_le16(CMD_CDBLEN(cmd));
+	memcpy(pkt->scsi_cdb, &(CMD_CDBP(cmd)), CMD_CDBLEN(cmd));
+
+	/*dprintk(1, "Build packet for command[0]=0x%x\n",pkt->scsi_cdb[0]); */
+	/* Set transfer direction. */
+	sp->dir = qla1280_data_direction(cmd);
+	pkt->control_flags |= cpu_to_le16(sp->dir);
+
+	/* Set total data segment count. */
+	pkt->dseg_count = cpu_to_le16(seg_cnt);
+
+	/*
+	 * Load data segments.
+	 */
+	if (seg_cnt) {
+		/* Setup packet address segment pointer. */
+		dword_ptr = &pkt->dseg_0_address;
+
+		if (cmd->use_sg) {	/* If scatter gather */
+			dprintk(3, "Building S/G data segments..\n");
+			qla1280_dump_buffer(1, (char *)sg, 4 * 16);
+
+			/* Load command entry data segments. */
+			for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) {
+				*dword_ptr++ =
+					cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
+				*dword_ptr++ =
+					cpu_to_le32(sg_dma_len(sg));
+				dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
+					(pci_dma_lo32(sg_dma_address(sg))),
+					(sg_dma_len(sg)));
+				sg++;
+			}
+			/*
+			 * Build continuation packets.
+			 */
+			dprintk(3, "S/G Building Continuation"
+				"...seg_cnt=0x%x remains\n", seg_cnt);
+			while (seg_cnt > 0) {
+				/* Adjust ring index. */
+				ha->req_ring_index++;
+				if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+					ha->req_ring_index = 0;
+					ha->request_ring_ptr =
+						ha->request_ring;
+				} else
+					ha->request_ring_ptr++;
+
+				pkt = (struct cmd_entry *)ha->request_ring_ptr;
+
+				/* Zero out packet. */
+				memset(pkt, 0, REQUEST_ENTRY_SIZE);
+
+				/* Load packet defaults. */
+				((struct cont_entry *) pkt)->
+					entry_type = CONTINUE_TYPE;
+				((struct cont_entry *) pkt)->entry_count = 1;
+
+				((struct cont_entry *) pkt)->sys_define =
+					(uint8_t) ha->req_ring_index;
+
+				/* Setup packet address segment pointer. */
+				dword_ptr =
+					&((struct cont_entry *) pkt)->dseg_0_address;
+
+				/* Load continuation entry data segments. */
+				for (cnt = 0; cnt < 7 && seg_cnt;
+				     cnt++, seg_cnt--) {
+					*dword_ptr++ =
+						cpu_to_le32(pci_dma_lo32(sg_dma_address(sg)));
+					*dword_ptr++ =
+						cpu_to_le32(sg_dma_len(sg));
+					dprintk(1,
+						"S/G Segment Cont. phys_addr=0x%x, "
+						"len=0x%x\n",
+						cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))),
+						cpu_to_le32(sg_dma_len(sg)));
+					sg++;
+				}
+				dprintk(5, "qla1280_32bit_start_scsi: "
+					"continuation packet data - "
+					"scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd),
+					SCSI_TCN_32(cmd), SCSI_LUN_32(cmd));
+				qla1280_dump_buffer(5, (char *)pkt,
+						    REQUEST_ENTRY_SIZE);
+			}
+		} else {	/* No S/G data transfer */
+			struct page *page = virt_to_page(cmd->request_buffer);
+			unsigned long off = (unsigned long)cmd->request_buffer & ~PAGE_MASK;
+			dma_handle = pci_map_page(ha->pdev, page, off,
+						  cmd->request_bufflen,
+						  scsi_to_pci_dma_dir(cmd->sc_data_direction));
+			sp->saved_dma_handle = dma_handle;
+
+			*dword_ptr++ = cpu_to_le32(pci_dma_lo32(dma_handle));
+			*dword_ptr = cpu_to_le32(cmd->request_bufflen);
+		}
+	} else {	/* No data transfer at all */
+		dword_ptr = (uint32_t *)(pkt + 1);
+		*dword_ptr++ = 0;
+		*dword_ptr = 0;
+		dprintk(5, "qla1280_32bit_start_scsi: No data, command "
+			"packet data - \n");
+		qla1280_dump_buffer(5, (char *)pkt, REQUEST_ENTRY_SIZE);
+	}
+	dprintk(5, "qla1280_32bit_start_scsi: First IOCB block:\n");
+	qla1280_dump_buffer(5, (char *)ha->request_ring_ptr,
+			    REQUEST_ENTRY_SIZE);
+
+	/* Adjust ring index. */
+	ha->req_ring_index++;
+	if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+		ha->req_ring_index = 0;
+		ha->request_ring_ptr = ha->request_ring;
+	} else
+		ha->request_ring_ptr++;
+
+	/* Set chip new ring index. */
+	dprintk(2, "qla1280_32bit_start_scsi: Wakeup RISC "
+		"for pending command\n");
+	sp->flags |= SRB_SENT;
+	ha->actthreads++;
+	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
+
+out:
+	if (status)
+		dprintk(2, "qla1280_32bit_start_scsi: **** FAILED ****\n");
+
+	LEAVE("qla1280_32bit_start_scsi");
+
+	return status;
 }
 
 /*
@@ -4476,405 +4106,140 @@
  * Returns:
  *      0 = failed to get slot.
  */
-STATIC request_t *
-qla1280_req_pkt(scsi_qla_host_t *ha)
+static request_t *
+qla1280_req_pkt(struct scsi_qla_host *ha)
 {
-    device_reg_t    *reg = ha->iobase;
-    request_t       *pkt = 0;
-    uint16_t        cnt;
-    uint32_t        *dword_ptr;
-    uint32_t        timer;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_req_pkt");
-#endif
-
-    /* Wait for 30 seconds for slot. */
-    for (timer = 15000000; timer; timer--)
-    {
-        /* Acquire ring specific lock */
-        QLA1280_RING_LOCK(ha);
-
-        if (ha->req_q_cnt > 0)
-        {
-            /* Calculate number of free request entries. */
-            cnt = RD_REG_WORD(&reg->mailbox4);
-            if (ha->req_ring_index < cnt)
-                ha->req_q_cnt = cnt - ha->req_ring_index;
-            else
-                ha->req_q_cnt = REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
-        }
-
-        /* Found empty request ring slot? */
-        if (ha->req_q_cnt > 0)
-        {
-            ha->req_q_cnt--;
-            pkt = ha->request_ring_ptr;
-
-            /* Zero out packet. */
-            dword_ptr = (uint32_t *)pkt;
-            for (cnt = 0; cnt < REQUEST_ENTRY_SIZE/4; cnt++)
-                *dword_ptr++ = 0;
-
-            /* Set system defined field. */
-            pkt->sys_define = (uint8_t)ha->req_ring_index;
-
-            /* Set entry count. */
-            pkt->entry_count = 1;
-
-            break;
-        }
-
-        /* Release ring specific lock */
-        QLA1280_RING_UNLOCK(ha);
-
-        SYS_DELAY(2);   /* 10 */ 
-
-        /* Check for pending interrupts. */
-        qla1280_poll(ha);
-    }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_req_pkt: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_req_pkt: exiting normally\n\r");
-#endif
-    return(pkt);
-}
-
-/*
- * qla1280_isp_cmd
- *      Function is responsible for modifying ISP input pointer.
- *      Releases ring lock.
- *
- * Input:
- *      ha  = adapter block pointer.
- */
-STATIC void
-qla1280_isp_cmd(scsi_qla_host_t *ha)
-{
-    device_reg_t    *reg = ha->iobase;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_isp_cmd");
-#endif
-
-#ifdef QL_DEBUG_LEVEL_5
-    qla1280_print("qla1280_isp_cmd: IOCB data:\n\r");
-    qla1280_dump_buffer((caddr_t)ha->request_ring_ptr, REQUEST_ENTRY_SIZE); 
-#endif
-
-    /* Adjust ring index. */
-    ha->req_ring_index++;
-    if (ha->req_ring_index == REQUEST_ENTRY_CNT)
-    {
-        ha->req_ring_index = 0;
-        ha->request_ring_ptr = ha->request_ring;
-    }
-    else
-        ha->request_ring_ptr++;
-
-    /* Set chip new ring index. */
-    WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
+	struct device_reg *reg = ha->iobase;
+	request_t *pkt = 0;
+	int cnt;
+	uint32_t timer;
+
+	ENTER("qla1280_req_pkt");
+
+	/*
+	 * This can be called from interrupt context, damn it!!!
+	 */
+	/* Wait for 30 seconds for slot. */
+	for (timer = 15000000; timer; timer--) {
+		if (ha->req_q_cnt > 0) {
+			/* Calculate number of free request entries. */
+			cnt = RD_REG_WORD(&reg->mailbox4);
+			if (ha->req_ring_index < cnt)
+				ha->req_q_cnt = cnt - ha->req_ring_index;
+			else
+				ha->req_q_cnt =
+					REQUEST_ENTRY_CNT - (ha->req_ring_index - cnt);
+		}
 
-    /* Release ring specific lock */
-    QLA1280_RING_UNLOCK(ha);
+		/* Found empty request ring slot? */
+		if (ha->req_q_cnt > 0) {
+			ha->req_q_cnt--;
+			pkt = ha->request_ring_ptr;
+
+			/* Zero out packet. */
+			memset(pkt, 0, REQUEST_ENTRY_SIZE);
+
+			/*
+			 * How can this be right when we have a ring
+			 * size of 512???
+			 */
+			/* Set system defined field. */
+			pkt->sys_define = (uint8_t) ha->req_ring_index;
 
-#ifdef QL_DEBUG_LEVEL_3
-    LEAVE("qla1280_isp_cmd");
-#endif
-}
+			/* Set entry count. */
+			pkt->entry_count = 1;
 
-/*
- * qla1280_enable_lun
- *      Issue enable LUN entry IOCB.
- *
- * Input:
- *      ha = adapter block pointer.
- *      b  = SCSI BUS number.
- *      l  = LUN number.
- */
-STATIC void
-qla1280_enable_lun(scsi_qla_host_t *ha, uint8_t b, uint32_t l)
-{
-    elun_entry_t    *pkt;
+			break;
+		}
 
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_enable_lun: entered\n\r");
-#endif
+		udelay(2);	/* 10 */
 
-    /* Get request packet. */
-    /*
-    if (pkt = (elun_entry_t *)qla1280_req_pkt(ha))
-    {
-    pkt->entry_type = ENABLE_LUN_TYPE;
-    pkt->lun = (uint16_t)(b ? l | BIT_15 : l);
-    pkt->command_count = 32;
-    pkt->immed_notify_count = 1;
-    pkt->group_6_length = MAX_CMDSZ;
-    pkt->group_7_length = MAX_CMDSZ;
-    pkt->timeout = 0x30;
+		/* Check for pending interrupts. */
+		qla1280_poll(ha);
+	}
 
-    qla1280_isp_cmd(ha);
-    }
-    */
-    pkt = (elun_entry_t *)1;
+	if (!pkt)
+		dprintk(2, "qla1280_req_pkt: **** FAILED ****\n");
+	else
+		dprintk(3, "qla1280_req_pkt: exiting normally\n");
 
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_enable_lun: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_enable_lun: exiting normally\n\r");
-#endif
+	return pkt;
 }
 
-#if QL1280_TARGET_MODE_SUPPORT
-/****************************************************************************/
-/*                      Target Mode Support Functions.                      */
-/****************************************************************************/
-
 /*
- * qla1280_notify_ack
- *      Issue notify acknowledge IOCB.
- *      If sequence ID is zero, acknowledgement of
- *      SCSI bus reset or bus device reset is assumed.
+ * qla1280_isp_cmd
+ *      Function is responsible for modifying ISP input pointer.
+ *      Releases ring lock.
  *
  * Input:
- *      ha      = adapter block pointer.
- *      inotify = immediate notify entry pointer.
+ *      ha  = adapter block pointer.
  */
-STATIC void
-qla1280_notify_ack(scsi_qla_host_t *ha, notify_entry_t *inotify)
+static void
+qla1280_isp_cmd(struct scsi_qla_host *ha)
 {
-    nack_entry_t    *pkt;
-
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_notify_ack: entered\n\r");
-#endif
-
-    /* Get request packet. */
-    if (pkt = (nack_entry_t *)qla1280_req_pkt(ha))
-    {
-        pkt->entry_type = NOTIFY_ACK_TYPE;
-        pkt->lun = inotify->lun;
-        pkt->initiator_id = inotify->initiator_id;
-        pkt->target_id = inotify->target_id;
-        if (inotify->seq_id == 0)
-            pkt->event = BIT_7;
-        else
-            pkt->seq_id = inotify->seq_id;
-
-        /* Issue command to ISP */
-        qla1280_isp_cmd(ha);
-    }
+	struct device_reg *reg = ha->iobase;
 
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_notify_ack: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_notify_ack: exiting normally\n\r");
-#endif
-}
-
-/*
- * qla1280_immed_notify
- *      Issue immediate notify IOCB for LUN 0.
- *
- * Input:
- *      ha      = adapter block pointer.
- *      inotify = immediate notify entry pointer.
- */
-STATIC void
-qla1280_immed_notify(scsi_qla_host_t *ha, notify_entry_t *inotify)
-{
-    notify_entry_t    *pkt;
+	ENTER("qla1280_isp_cmd");
 
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_immed_notify: entered\n\r");
-#endif
+	dprintk(5, "qla1280_isp_cmd: IOCB data:\n");
+	qla1280_dump_buffer(5, (char *)ha->request_ring_ptr,
+			    REQUEST_ENTRY_SIZE);
 
-    /* Get request packet. */
-    if (pkt = (notify_entry_t *)qla1280_req_pkt(ha))
-    {
-        pkt->entry_type = IMMED_NOTIFY_TYPE;
-        pkt->lun = inotify->lun;
-        pkt->initiator_id = inotify->initiator_id;
-        pkt->target_id = inotify->target_id;
-        pkt->status = 1;
+	/* Adjust ring index. */
+	ha->req_ring_index++;
+	if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
+		ha->req_ring_index = 0;
+		ha->request_ring_ptr = ha->request_ring;
+	} else
+		ha->request_ring_ptr++;
 
-        /* Issue command to ISP */
-        qla1280_isp_cmd(ha);
-    }
+	/* Set chip new ring index. */
+	WRT_REG_WORD(&reg->mailbox4, ha->req_ring_index);
 
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_immed_notify: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_immed_notify: exiting normally\n\r");
-#endif
+	LEAVE("qla1280_isp_cmd");
 }
 
+#if QL1280_LUN_SUPPORT
 /*
- * qla1280_accept_io
- *      Issue accept target I/O IOCB for LUN 0.
+ * qla1280_enable_lun
+ *      Issue enable LUN entry IOCB.
  *
  * Input:
- *      ha = adapter block pointer.
- *      ctio = ctio returned entry pointer.
+ *      ha  = adapter block pointer.
+ *      bus = SCSI BUS number.
+ *      lun  = LUN number.
  */
-STATIC void
-qla1280_accept_io(scsi_qla_host_t *ha, ctio_ret_entry_t *ctio)
+static void
+qla1280_enable_lun(struct scsi_qla_host *ha, int bus, int lun)
 {
-    atio_entry_t    *pkt;
-
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_accept_io: entered\n\r");
-#endif
+	struct elun_entry *pkt;
 
-    /* Get request packet. */
-    if (pkt = (atio_entry_t *)qla1280_req_pkt(ha))
-    {
-        pkt->entry_type = ACCEPT_TGT_IO_TYPE;
-        pkt->lun = ctio->lun;
-        pkt->initiator_id = ctio->initiator_id;
-        pkt->target_id = ctio->target_id;
-        pkt->tag_value = ctio->tag_value;
-        pkt->status = 1;
+	ENTER("qla1280_enable_lun");
+
+	/* Get request packet. */
+	/*
+	  if (pkt = (struct elun_entry *)qla1280_req_pkt(ha))
+	  {
+	  pkt->entry_type = ENABLE_LUN_TYPE;
+	  pkt->lun = cpu_to_le16(bus ? lun | BIT_15 : lun);
+	  pkt->command_count = 32;
+	  pkt->immed_notify_count = 1;
+	  pkt->group_6_length = MAX_CMDSZ;
+	  pkt->group_7_length = MAX_CMDSZ;
+	  pkt->timeout = cpu_to_le16(0x30);
+
+	  qla1280_isp_cmd(ha);
+	  }
+	*/
+	pkt = (struct elun_entry *) 1;
 
-        /* Issue command to ISP */
-        qla1280_isp_cmd(ha);
-    }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_accept_io: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_accept_io: exiting normally\n\r");
-#endif
+	if (!pkt)
+		dprintk(2, "qla1280_enable_lun: **** FAILED ****\n");
+	else
+		dprintk(3, "qla1280_enable_lun: exiting normally\n");
 }
-
-/*
- * qla1280_64bit_continue_io
- *      Issue continue target I/O IOCB.
- *
- * Input:
- *      ha   = adapter block pointer.
- *      atio = atio pointer.
- *      len  = total bytecount.
- *      addr = physical address pointer.
- */
-STATIC void
-qla1280_64bit_continue_io(scsi_qla_host_t *ha, atio_entry_t *atio, uint32_t len,
-                    paddr32_t *addr)
-{
-    ctio_a64_entry_t *pkt;
-    uint32_t         *dword_ptr;
-
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_64bit_continue_io: entered\n\r");
-#endif
-
-    /* Get request packet. */
-    if (pkt = (ctio_a64_entry_t *)qla1280_req_pkt(ha))
-    {
-        pkt->entry_type = CTIO_A64_TYPE;
-        pkt->lun = atio->lun;
-        pkt->initiator_id = atio->initiator_id;
-        pkt->target_id = atio->target_id;
-        pkt->option_flags = atio->option_flags;
-        pkt->tag_value = atio->tag_value;
-        pkt->scsi_status = atio->scsi_status;
-
-        if (len)
-        {
-            pkt->dseg_count = 1;
-            pkt->transfer_length = len;
-            pkt->dseg_0_length = len;
-            dword_ptr = (uint32_t *)addr;
-            pkt->dseg_0_address[0] = *dword_ptr++;
-            pkt->dseg_0_address[1] = *dword_ptr;
-        }
-
-        /* Issue command to ISP */
-        qla1280_isp_cmd(ha);
-    }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_64bit_continue_io: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_64bit_continue_io: exiting normally\n\r");
 #endif
-}
 
-/*
- * qla1280_32bit_continue_io
- *      Issue continue target I/O IOCB.
- *
- * Input:
- *      ha   = adapter block pointer.
- *      atio = atio pointer.
- *      len  = total bytecount.
- *      addr = physical address pointer.
- */
-STATIC void
-qla1280_32bit_continue_io(scsi_qla_host_t *ha, atio_entry_t *atio, uint32_t len,
-                    paddr32_t *addr)
-{
-    ctio_entry_t *pkt;
-    uint32_t     *dword_ptr;
-
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_32bit_continue_io: entered\n\r");
-#endif
-
-    /* Get request packet. */
-    if (pkt = (ctio_entry_t *)qla1280_req_pkt(ha))
-    {
-        pkt->entry_type = CONTINUE_TGT_IO_TYPE;
-        pkt->lun = atio->lun;
-        pkt->initiator_id = atio->initiator_id;
-        pkt->target_id = atio->target_id;
-        pkt->option_flags = atio->option_flags;
-        pkt->tag_value = atio->tag_value;
-        pkt->scsi_status = atio->scsi_status;
-
-        if (len)
-        {
-            pkt->dseg_count = 1;
-            pkt->transfer_length = len;
-            pkt->dseg_0_length = len;
-            dword_ptr = (uint32_t *)addr;
-            pkt->dseg_0_address = *dword_ptr;
-        }
-
-        /* Issue command to ISP */
-        qla1280_isp_cmd(ha);
-    }
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-    if (!pkt)
-        qla1280_print("qla1280_32bit_continue_io: **** FAILED ****\n\r");
-#endif
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        qla1280_print("qla1280_32bit_continue_io: exiting normally\n\r");
-#endif
-}
-#endif /* QL1280_TARGET_MODE_SUPPORT */
 
 /****************************************************************************/
 /*                        Interrupt Service Routine.                        */
@@ -4888,832 +4253,313 @@
  *      ha           = adapter block pointer.
  *      done_q_first = done queue first pointer.
  *      done_q_last  = done queue last pointer.
- *      INTR_LOCK must be already obtained.
  ****************************************************************************/
-STATIC void
-qla1280_isr(scsi_qla_host_t *ha, srb_t **done_q_first, srb_t **done_q_last)
-{
-    device_reg_t    *reg = ha->iobase;
-    response_t      *pkt;
-    srb_t           *sp;
-    uint16_t        mailbox[MAILBOX_REGISTER_COUNT];
-    uint16_t        *wptr;
-    uint32_t        index;
-
-    ENTER("qla1280_isr");
-
-
-    /* Save mailbox register 5 */
-    mailbox[5] = RD_REG_WORD(&reg->mailbox5);
-
-    /* Check for mailbox interrupt. */
-
-    mailbox[0] = RD_REG_WORD(&reg->semaphore);
-    if (mailbox[0] & BIT_0)
-    {
-        /* Get mailbox data. */
-
-        wptr = &mailbox[0];
-        *wptr++ = RD_REG_WORD(&reg->mailbox0);
-        *wptr++ = RD_REG_WORD(&reg->mailbox1);
-        *wptr = RD_REG_WORD(&reg->mailbox2);
-        if (mailbox[0] != MBA_SCSI_COMPLETION)
-        {
-            wptr++;
-            *wptr++ = RD_REG_WORD(&reg->mailbox3);
-            *wptr++ = RD_REG_WORD(&reg->mailbox4);
-            wptr++;
-            *wptr++ = RD_REG_WORD(&reg->mailbox6);
-            *wptr   = RD_REG_WORD(&reg->mailbox7);
-        }
-
-        /* Release mailbox registers. */
-
-        WRT_REG_WORD(&reg->semaphore, 0);
-        WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
-
-#ifdef QL_DEBUG_LEVEL_5
-        qla1280_print("qla1280_isr: mailbox interrupt mailbox[0] = ");
-        qla1280_output_number((uint32_t)mailbox[0], 16);
-        qla1280_print("\n\r");
-#endif
-
-        /* Handle asynchronous event */
-
-        switch (mailbox[0])
-        {
-            case MBA_SCSI_COMPLETION:   /* Response completion */
-#ifdef QL_DEBUG_LEVEL_5
-                qla1280_print("qla1280_isr: mailbox response completion\n\r");
-#endif
-                if (ha->flags.online)
-                {
-                    /* Get outstanding command index. */
-                    index = (uint32_t)(mailbox[2] << 16 | mailbox[1]);
-
-                    /* Validate handle. */
-                    if (index < MAX_OUTSTANDING_COMMANDS)
-                        sp = ha->outstanding_cmds[index];
-                    else
-                        sp = 0;
-
-                    if (sp)
-                    {
-                        /* Free outstanding command slot. */
-                        ha->outstanding_cmds[index] = 0;
-
-                        /* Save ISP completion status */
-                        CMD_RESULT(sp->cmd) = 0;
-
-                        /* Place block on done queue */
-                        sp->s_next = NULL;
-                        sp->s_prev = *done_q_last;
-                        if (!*done_q_first)
-                            *done_q_first = sp;
-                        else
-                            (*done_q_last)->s_next = sp;
-                        *done_q_last = sp;
-                    }
-                    else
-                    {
-#ifdef QL_DEBUG_LEVEL_2
-                            qla1280_print("qla1280_isr: ISP invalid handle\n\r");
-#endif
-                            printk(KERN_WARNING "qla1280: ISP invalid handle");
-                            ha->flags.isp_abort_needed = TRUE;
-                    }
-                }
-                break;
-            case MBA_BUS_RESET:         /* SCSI Bus Reset */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print("qla1280_isr: asynchronous BUS_RESET\n\r");
-#endif
-                ha->flags.reset_marker = TRUE;
-                index = mailbox[6] & BIT_0;
-                ha->bus_settings[index].reset_marker = TRUE;
-                break;
-            case MBA_SYSTEM_ERR:        /* System Error */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print("qla1280_isr: ISP System Error - mbx1=");
-                qla1280_output_number((uint32_t)mailbox[1], 16);
-                qla1280_print(", mbx2=");
-                qla1280_output_number((uint32_t)mailbox[2], 16);
-                qla1280_print(", mbx3=");
-                qla1280_output_number((uint32_t)mailbox[3], 16);
-                qla1280_print("\n\r");
-#endif
-                printk(KERN_WARNING
-                        "qla1280: ISP System Error - mbx1=%xh, mbx2=%xh, mbx3=%xh\n",
-                        mailbox[1], mailbox[2], mailbox[3]);
-                ha->flags.isp_abort_needed = TRUE;
-                break;
-            case MBA_REQ_TRANSFER_ERR:  /* Request Transfer Error */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print("qla1280_isr: ISP Request Transfer Error\n\r");
-#endif
-                printk(KERN_WARNING "qla1280: ISP Request Transfer Error\n");
-                ha->flags.isp_abort_needed = TRUE;
-                break;
-            case MBA_RSP_TRANSFER_ERR:  /* Response Transfer Error */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print("qla1280_isr: ISP Response Transfer Error\n\r");
-#endif
-                printk(KERN_WARNING "qla1280: ISP Response Transfer Error\n");
-                ha->flags.isp_abort_needed = TRUE;
-                break;
-            case MBA_WAKEUP_THRES:      /* Request Queue Wake-up */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print("qla1280_isr: asynchronous WAKEUP_THRES\n\r");
-#endif
-                break;
-            case MBA_TIMEOUT_RESET:     /* Execution Timeout Reset */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print("qla1280_isr: asynchronous TIMEOUT_RESET\n\r");
-#endif
-                break;
-            case MBA_DEVICE_RESET:         /* Bus Device Reset */
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print(
-                        "qla1280_isr: asynchronous BUS_DEVICE_RESET\n\r");
-#endif
-                ha->flags.reset_marker = TRUE;
-                index = mailbox[6] & BIT_0;
-                ha->bus_settings[index].reset_marker = TRUE;
-                break;
-            case MBA_BUS_MODE_CHANGE:
-#ifdef QL_DEBUG_LEVEL_2
-                qla1280_print(
-                        "qla1280_isr: asynchronous BUS_MODE_CHANGE\n\r");
-#endif
-                break;
-            default:
-                if (mailbox[0] < MBA_ASYNC_EVENT)
-                {
-                        wptr = &mailbox[0];
-                        ha->mailbox_out[0] = *wptr++;
-                        ha->mailbox_out[1] = *wptr++;
-                        ha->mailbox_out[2] = *wptr++;
-                        ha->mailbox_out[3] = *wptr++;
-                        ha->mailbox_out[4] = *wptr++;
-                        ha->mailbox_out[5] = *wptr++;
-                        ha->mailbox_out[6] = *wptr++;
-                        ha->mailbox_out[7] = *wptr;
-                        ha->flags.mbox_int = TRUE;
-                }
-                break;
-        }
-    }
-    else
-        WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
-
-    /*
-    * Response ring
-    */
-    if (ha->flags.online && !ha->flags.mbox_busy)
-    {
-        if (mailbox[5] < RESPONSE_ENTRY_CNT)
-        {
-            while (ha->rsp_ring_index != mailbox[5])
-            {
-                pkt = ha->response_ring_ptr;
-
-#ifdef QL_DEBUG_LEVEL_5
-                qla1280_print("qla1280_isr: ha->rsp_ring_index = ");
-                qla1280_output_number((uint32_t)ha->rsp_ring_index, 16);
-                qla1280_print(" mailbox[5] = ");
-                qla1280_output_number((uint32_t)mailbox[5], 16);
-                qla1280_print("\n\rqla1280_isr: response packet data\n\r");
-                qla1280_dump_buffer((caddr_t)pkt, RESPONSE_ENTRY_SIZE);
-#endif
-
-#if defined(QL_DEBUG_LEVEL_2) && !defined(QL_DEBUG_LEVEL_5)
-                if (pkt->entry_type == STATUS_TYPE)
-                {
-                    if ((uint8_t)(pkt->scsi_status) || pkt->comp_status ||
-                        pkt->entry_status)
-                    {
-                        DEBUG(qla1280_print("qla1280_isr: ha->rsp_ring_index = ");)
-                        DEBUG(qla1280_output_number((uint32_t)ha->rsp_ring_index,
-                                16);)
-                        DEBUG(qla1280_print(" mailbox[5] = ");)
-                        DEBUG(qla1280_output_number((uint32_t)mailbox[5], 16);)
-                        DEBUG(qla1280_print( "\n\r comp_status = ");)
-                        DEBUG(qla1280_output_number((uint32_t)pkt->comp_status,16);)
-                        DEBUG(qla1280_print( ", ");)
-                        DEBUG(qla1280_print( " scsi_status = ");)
-                        DEBUG(qla1280_output_number((uint32_t)pkt->scsi_status,16);)
-                        DEBUG(qla1280_print( "\n\r");)
-                        /* qla1280_print(
-                        "\n\rqla1280_isr: response packet data\n\r");
-                        qla1280_dump_buffer((caddr_t)pkt,
-                        RESPONSE_ENTRY_SIZE); */
-                    }
-                }
-                else
-                {
-                    qla1280_print("qla1280_isr: ha->rsp_ring_index = ");
-                    qla1280_output_number((uint32_t)ha->rsp_ring_index, 16);
-                    qla1280_print(" mailbox[5] = ");
-                    qla1280_output_number((uint32_t)mailbox[5], 16);
-                    qla1280_print(
-                            "\n\rqla1280_isr: response packet data\n\r");
-                    qla1280_dump_buffer((caddr_t)pkt, RESPONSE_ENTRY_SIZE);
-                }
-#endif
-                if (pkt->entry_type == STATUS_TYPE || pkt->entry_status)
-                {
-                    if (pkt->entry_type == STATUS_TYPE)
-                        qla1280_status_entry(ha, (sts_entry_t *)pkt,
-                                done_q_first, done_q_last);
-                    else
-                        qla1280_error_entry(ha, pkt,
-                                done_q_first, done_q_last);
-
-                    /* Adjust ring index. */
-                    ha->rsp_ring_index++;
-                    if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT)
-                    {
-                        ha->rsp_ring_index = 0;
-                        ha->response_ring_ptr = ha->response_ring;
-                    }
-                    else
-                        ha->response_ring_ptr++;
-                    WRT_REG_WORD(&reg->mailbox5, ha->rsp_ring_index);
-                }
-#if QLA1280_TARGET_MODE_SUPPORT
-                else
-                {
-                    pkt = &response_entry;
-
-                    /* Copy packet. */
-                    dptr1 = (uint32_t *)ha->response_ring_ptr;
-                    dptr2 = (uint32_t *)pkt;
-                    for (index = 0; index < RESPONSE_ENTRY_SIZE/4; index++)
-                        *dptr2++ = *dptr1++;
-
-                    /* Adjust ring index. */
-                    ha->rsp_ring_index++;
-                    if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT)
-                    {
-                        ha->rsp_ring_index = 0;
-                        ha->response_ring_ptr = ha->response_ring;
-                    }
-                    else
-                        ha->response_ring_ptr++;
-                    WRT_REG_WORD(&reg->mailbox5, ha->rsp_ring_index);
-
-                    /* Release interrupt specific lock */
-                    QLA1280_INTR_UNLOCK(ha);
-
-                    switch (pkt->entry_type)
-                    {
-                        case ACCEPT_TGT_IO_TYPE:
-                            qla1280_atio_entry(ha, (atio_entry_t *)pkt);
-                            break;
-                        case IMMED_NOTIFY_TYPE:
-                            qla1280_notify_entry(ha, (notify_entry_t *)pkt);
-                            break;
-                        case CTIO_RET_TYPE:
-                            qla1280_accept_io(ha, (ctio_ret_entry_t *)pkt);
-                            break;
-                        default:
-                            break;
-                    }
-
-                    /* Acquire interrupt specific lock */
-                    QLA1280_INTR_LOCK(ha);
-                }
-#endif
-            }
-        }
-        else
-        {
-            ha->flags.isp_abort_needed = TRUE;
-#ifdef QL_DEBUG_LEVEL_2
-            qla1280_print("qla1280_isr: Response pointer Error\n");
-#endif
-        }
-    }
+static void
+qla1280_isr(struct scsi_qla_host *ha, struct srb ** done_q_first,
+	    struct srb ** done_q_last)
+{
+	struct device_reg *reg = ha->iobase;
+	struct response *pkt;
+	struct srb *sp = 0;
+	uint16_t mailbox[MAILBOX_REGISTER_COUNT];
+	uint16_t *wptr;
+	uint32_t index;
+	u16 istatus;
+
+	ENTER("qla1280_isr");
+
+	istatus = RD_REG_WORD(&reg->istatus);
+	if (!(istatus & (RISC_INT | PCI_INT)))
+		return;
+
+	/* Save mailbox register 5 */
+	mailbox[5] = RD_REG_WORD(&reg->mailbox5);
+
+	/* Check for mailbox interrupt. */
+
+	mailbox[0] = RD_REG_WORD(&reg->semaphore);
+
+	if (mailbox[0] & BIT_0) {
+		/* Get mailbox data. */
+		/* dprintk(1, "qla1280_isr: In Get mailbox data \n"); */
+
+		wptr = &mailbox[0];
+		*wptr++ = RD_REG_WORD(&reg->mailbox0);
+		*wptr++ = RD_REG_WORD(&reg->mailbox1);
+		*wptr = RD_REG_WORD(&reg->mailbox2);
+		if (mailbox[0] != MBA_SCSI_COMPLETION) {
+			wptr++;
+			*wptr++ = RD_REG_WORD(&reg->mailbox3);
+			*wptr++ = RD_REG_WORD(&reg->mailbox4);
+			wptr++;
+			*wptr++ = RD_REG_WORD(&reg->mailbox6);
+			*wptr = RD_REG_WORD(&reg->mailbox7);
+		}
 
-    LEAVE("qla1280_isr");
-}
+		/* Release mailbox registers. */
 
-/*
- *  qla1280_rst_aen
- *      Processes asynchronous reset.
- *
- * Input:
- *      ha  = adapter block pointer.
- */
-STATIC void
-qla1280_rst_aen(scsi_qla_host_t *ha)
-{
-#if QL1280_TARGET_MODE_SUPPORT
-    notify_entry_t  nentry;
-#endif
-    uint8_t         b;
+		WRT_REG_WORD(&reg->semaphore, 0);
+		WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
+
+		dprintk(5, "qla1280_isr: mailbox interrupt mailbox[0] = 0x%x",
+			mailbox[0]);
+
+		/* Handle asynchronous event */
+		switch (mailbox[0]) {
+		case MBA_SCSI_COMPLETION:	/* Response completion */
+			dprintk(5, "qla1280_isr: mailbox SCSI response "
+				"completion\n");
+
+			if (ha->flags.online) {
+				/* Get outstanding command index. */
+				index = mailbox[2] << 16 | mailbox[1];
+
+				/* Validate handle. */
+				if (index < MAX_OUTSTANDING_COMMANDS)
+					sp = ha->outstanding_cmds[index];
+				else
+					sp = 0;
+
+				if (sp) {
+					/* Free outstanding command slot. */
+					ha->outstanding_cmds[index] = 0;
+
+					/* Save ISP completion status */
+					CMD_RESULT(sp->cmd) = 0;
+
+					/* Place block on done queue */
+					sp->s_next = NULL;
+					sp->s_prev = *done_q_last;
+					if (!*done_q_first)
+						*done_q_first = sp;
+					else
+						(*done_q_last)->s_next = sp;
+					*done_q_last = sp;
+				} else {
+					/*
+					 * If we get here we have a real problem!
+					 */
+					printk(KERN_WARNING
+					       "qla1280: ISP invalid handle");
+				}
+			}
+			break;
+
+		case MBA_BUS_RESET:	/* SCSI Bus Reset */
+			ha->flags.reset_marker = 1;
+			index = mailbox[6] & BIT_0;
+			ha->bus_settings[index].reset_marker = 1;
+
+			printk(KERN_DEBUG "qla1280_isr(): index %i "
+			       "asynchronous BUS_RESET\n", index);
+			break;
+
+		case MBA_SYSTEM_ERR:	/* System Error */
+			printk(KERN_WARNING
+			       "qla1280: ISP System Error - mbx1=%xh, mbx2="
+			       "%xh, mbx3=%xh\n", mailbox[1], mailbox[2],
+			       mailbox[3]);
+			break;
+
+		case MBA_REQ_TRANSFER_ERR:	/* Request Transfer Error */
+			printk(KERN_WARNING
+			       "qla1280: ISP Request Transfer Error\n");
+			break;
+
+		case MBA_RSP_TRANSFER_ERR:	/* Response Transfer Error */
+			printk(KERN_WARNING
+			       "qla1280: ISP Response Transfer Error\n");
+			break;
+
+		case MBA_WAKEUP_THRES:	/* Request Queue Wake-up */
+			dprintk(2, "qla1280_isr: asynchronous WAKEUP_THRES\n");
+			break;
+
+		case MBA_TIMEOUT_RESET:	/* Execution Timeout Reset */
+			dprintk(2,
+				"qla1280_isr: asynchronous TIMEOUT_RESET\n");
+			break;
+
+		case MBA_DEVICE_RESET:	/* Bus Device Reset */
+			printk(KERN_INFO "qla1280_isr(): asynchronous "
+			       "BUS_DEVICE_RESET\n");
+
+			ha->flags.reset_marker = 1;
+			index = mailbox[6] & BIT_0;
+			ha->bus_settings[index].reset_marker = 1;
+			break;
+
+		case MBA_BUS_MODE_CHANGE:
+			dprintk(2,
+				"qla1280_isr: asynchronous BUS_MODE_CHANGE\n");
+			break;
+
+		default:
+			/* dprintk(1, "qla1280_isr: default case of switch MB \n"); */
+			if (mailbox[0] < MBA_ASYNC_EVENT) {
+				wptr = &mailbox[0];
+				memcpy((uint16_t *) ha->mailbox_out, wptr,
+				       MAILBOX_REGISTER_COUNT *
+				       sizeof(uint16_t));
+
+				if(ha->mailbox_wait != NULL)
+					complete(ha->mailbox_wait);
+			}
+			break;
+		}
+	} else {
+		WRT_REG_WORD(&reg->host_cmd, HC_CLR_RISC_INT);
+	}
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_rst_aen");
+	/*
+	 * Response ring - waiting for the mbox_busy flag here seems
+	 * unnecessary as the mailbox data has been copied to ha->mailbox_out
+	 * by the time we actually get here!
+	 */
+	if (!(ha->flags.online
+#if 0
+	    && !ha->flags.mbox_busy
 #endif
+		)) {
+		dprintk(2, "qla1280_isr: Response pointer Error\n");
+		goto out;
+	}
 
-    if (ha->flags.online && !ha->flags.reset_active &&
-        !ha->flags.abort_isp_active)
-    {
-        ha->flags.reset_active = TRUE;
-        while (ha->flags.reset_marker)
-        {
-            /* Issue marker command. */
-            ha->flags.reset_marker = FALSE;
-            for (b = 0; b < ha->ports && !ha->flags.reset_marker; b++)
-            {
-                if (ha->bus_settings[b].reset_marker)
-                {
-                    ha->bus_settings[b].reset_marker = FALSE;
-                    qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL);
+	if (mailbox[5] >= RESPONSE_ENTRY_CNT)
+		goto out;
 
-                    if (!ha->flags.reset_marker)
-                    {
-#if QL1280_TARGET_MODE_SUPPORT
-                        /* Issue notify acknowledgement command. */
-                        bzero((caddr_t)&nentry, sizeof(notify_entry_t));
+	while (ha->rsp_ring_index != mailbox[5]) {
+		pkt = ha->response_ring_ptr;
 
-                        nentry.initiator_id = nentry.target_id = b ?
-                                ha->bus_settings[b].id | BIT_7 :
-                        ha->bus_settings[b].id;
-                        qla1280_notify_entry(ha, &nentry);
-#endif
+		dprintk(5, "qla1280_isr: ha->rsp_ring_index = 0x%x, mailbox[5]"
+			" = 0x%x\n", ha->rsp_ring_index, mailbox[5]);
+		dprintk(5,"qla1280_isr: response packet data\n");
+		qla1280_dump_buffer(5, (char *)pkt, RESPONSE_ENTRY_SIZE);
+
+		if (pkt->entry_type == STATUS_TYPE) {
+			if ((le16_to_cpu(pkt->scsi_status) & 0xff)
+			    || pkt->comp_status || pkt->entry_status) {
+				dprintk(2, "qla1280_isr: ha->rsp_ring_index = "
+					"0x%x mailbox[5] = 0x%x, comp_status "
+					"= 0x%x, scsi_status = 0x%x\n",
+					ha->rsp_ring_index, mailbox[5],
+					le16_to_cpu(pkt->comp_status),
+					le16_to_cpu(pkt->scsi_status));
+			}
+		} else {
+			dprintk(2, "qla1280_isr: ha->rsp_ring_index = "
+				"0x%x, mailbox[5] = 0x%x\n",
+				ha->rsp_ring_index, mailbox[5]);
+			dprintk(2, "qla1280_isr: response packet data\n");
+			qla1280_dump_buffer(2, (char *)pkt,
+					    RESPONSE_ENTRY_SIZE);
+		}
 
-                        /* Asynchronous event notification */
-                    }
-                }
-            }
-        }
-    }
+		if (pkt->entry_type == STATUS_TYPE || pkt->entry_status) {
+			dprintk(2, "status: Cmd %p, handle %i\n",
+				ha->outstanding_cmds[pkt->handle]->cmd,
+				pkt->handle);
+			if (pkt->entry_type == STATUS_TYPE)
+				qla1280_status_entry(ha, pkt, done_q_first,
+						     done_q_last);
+			else
+				qla1280_error_entry(ha, pkt, done_q_first,
+						    done_q_last);
 
-#ifdef QL_DEBUG_LEVEL_3
-    LEAVE("qla1280_rst_aen");
-#endif
+			/* Adjust ring index. */
+			ha->rsp_ring_index++;
+			if (ha->rsp_ring_index == RESPONSE_ENTRY_CNT) {
+				ha->rsp_ring_index = 0;
+				ha->response_ring_ptr =	ha->response_ring;
+			} else
+				ha->response_ring_ptr++;
+			WRT_REG_WORD(&reg->mailbox5, ha->rsp_ring_index);
+		}
+	}
+	
+ out:
+	LEAVE("qla1280_isr");
 }
 
-#if QL1280_TARGET_MODE_SUPPORT
 /*
- *  qla1280_atio_entry
- *      Processes received ISP accept target I/O entry.
+ *  qla1280_rst_aen
+ *      Processes asynchronous reset.
  *
  * Input:
  *      ha  = adapter block pointer.
- *      pkt = entry pointer.
  */
-STATIC void
-qla1280_atio_entry(scsi_qla_host_t *ha, atio_entry_t *pkt)
+static void
+qla1280_rst_aen(struct scsi_qla_host *ha)
 {
-    uint64_t    *a64;
-    uint64_t    *end_a64;
-    paddr32_t   phy_addr[2];
-    paddr32_t   end_addr[2];
-    uint32_t    len;
-    uint32_t    offset;
-    uint8_t     t;
-    uint8_t     *sense_ptr;
-
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_atio_entry: entered\n\r");
-#endif
-
-    t = pkt->initiator_id;
-    sense_ptr = ha->tsense + t * TARGET_SENSE_SIZE;
-    a64 = (uint64_t *)&phy_addr[0];
-    end_a64 = (uint64_t *)&end_addr[0];
-
-    switch (pkt->status & ~BIT_7)
-    {
-        case 7:                         /* Path invalid */
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-            qla1280_print("qla1280_atio_entry: Path invalid\n\r");
-#endif
-            break;
-        case 0x14:                  /* Target Bus Phase Sequence Failure */
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-            qla1280_print(
-                    "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r");
-#endif
-            if (pkt->status & BIT_7)
-            {
-                BCOPY((caddr_t)&pkt->sense_data, sense_ptr,TARGET_SENSE_SIZE);
-            }
-            else
-            {
-                    bzero(sense_ptr, TARGET_SENSE_SIZE);
-                    *sense_ptr = 0x70;
-                    *(sense_ptr+2) = SD_HARDERR;
-                    *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                    *(sense_ptr+12) = SC_SELFAIL;
-            }
-            pkt->scsi_status = S_CKCON;
-            pkt->option_flags |= (uint32_t)OF_SSTS | (uint32_t)OF_NO_DATA;
-            if (ha->flags.enable_64bit_addressing)
-                qla1280_64bit_continue_io(ha, pkt, 0, 0);
-            else
-                qla1280_32bit_continue_io(ha, pkt, 0, 0);
-            break;
-        case 0x16:                  /* Requested Capability Not Available */
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-            qla1280_print(
-                    "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r");
-#endif
-            break;
-        case 0x17:                  /* Bus Device Reset Message Received */
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-            qla1280_print(
-                    "qla1280_atio_entry: Target Bus Phase Sequence Failure\n\r");
-#endif
-            break;
-        case 0x3D:                  /* CDB Received */
-
-            /* Check for invalid LUN */
-            if (pkt->lun && pkt->cdb[0] != SS_INQUIR &&
-                pkt->cdb[0] != SS_REQSEN)
-                pkt->cdb[0] = SS_TEST;
-
-            switch (pkt->cdb[0])
-            {
-                case SS_TEST:
-#ifdef QL_DEBUG_LEVEL_3
-                    qla1280_print("qla1280_atio_entry: SS_TEST\n\r");
-#endif
-                    bzero(sense_ptr, TARGET_SENSE_SIZE);
-                    len = 0;
-                    if (pkt->lun == 0)
-                        pkt->scsi_status = S_GOOD;
-                    else
-                    {
-                        *sense_ptr = 0x70;
-                        *(sense_ptr+2) = SD_ILLREQ;
-                        *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                        *(sense_ptr+12) = SC_INVLUN;
-                        pkt->scsi_status = S_CKCON;
-                    }
-
-                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                            (uint32_t)OF_NO_DATA;
-                    break;
-                case SS_REQSEN:
-#ifdef QL_DEBUG_LEVEL_3
-                    qla1280_print("qla1280_atio_entry: SS_REQSEN\n\r");
-#endif
-                    phy_addr[0] = ha->tsense_dma;
-                    phy_addr[1] = 0;
-                    *a64 += t * TARGET_SENSE_SIZE;
-                    if (pkt->cdb[4] > TARGET_SENSE_SIZE)
-                        len = TARGET_SENSE_SIZE;
-                    else
-                        len = pkt->cdb[4];
-                    pkt->scsi_status = S_GOOD;
-                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                            (uint32_t)OF_DATA_IN;
-                    break;
-                case SS_INQUIR:
-#ifdef QL_DEBUG_LEVEL_3
-                    qla1280_print("qla1280_atio_entry: SS_INQUIR\n\r");
-#endif
-                    bzero(sense_ptr, TARGET_SENSE_SIZE);
-                    phy_addr[0] = ha->tbuf_dma;
-                    phy_addr[1] = 0;
-                    *a64 += TARGET_INQ_OFFSET;
-
-                    if (pkt->lun == 0)
-                    {
-                            ha->tbuf->inq.id_type = ID_PROCESOR;
-                            ha->tbuf->inq.id_pqual = ID_QOK;
-                    }
-                    else
-                    {
-                            ha->tbuf->inq.id_type = ID_NODEV;
-                            ha->tbuf->inq.id_pqual = ID_QNOLU;
-                    }
-
-                    if (pkt->cdb[4] > sizeof(struct ident))
-                        len = sizeof(struct ident);
-                    else
-                        len = pkt->cdb[4];
-                    pkt->scsi_status = S_GOOD;
-                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                            (uint32_t)OF_DATA_IN;
-                    break;
-                case SM_WRDB:
-                    bzero(sense_ptr, TARGET_SENSE_SIZE);
-                    offset = pkt->cdb[5];
-                    offset |= pkt->cdb[4] << 8;
-                    offset |= pkt->cdb[3] << 16;
-                    len = pkt->cdb[8];
-                    len |= pkt->cdb[7] << 8;
-                    len |= pkt->cdb[6] << 16;
-                    end_addr[0] = phy_addr[0] = ha->tbuf_dma;
-                    end_addr[1] = phy_addr[1] = 0;
-                    *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE;
-                    switch (pkt->cdb[1] & 7)
-                    {
-                        case RW_BUF_HDATA:
-#ifdef QL_DEBUG_LEVEL_3
-                            qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_HDATA\n\r");
-#endif
-                            if (len > TARGET_DATA_SIZE + 4)
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                qla1280_print("qla1280_atio_entry: SM_WRDB, length > buffer size\n\r");
-#endif
-                                *sense_ptr = 0x70;
-                                *(sense_ptr+2) = SD_ILLREQ;
-                                *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                                *(sense_ptr+12) = SC_ILLCDB;
-                                pkt->scsi_status = S_CKCON;
-                                pkt->option_flags |= (uint32_t)OF_SSTS |
-                                        (uint32_t)OF_NO_DATA;
-                                len = 0;
-                            }
-                            else if (len)
-                            {
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_DATA_OUT;
-#ifdef QL_DEBUG_LEVEL_3
-                                    qla1280_print("qla1280_atio_entry: Issuing SDI_TARMOD_WRCOMP\n\r");
-#endif
-                                    sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr,
-                                            pkt->target_id, pkt->lun, 0, offset);
-                            }
-                            else
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                    qla1280_print("qla1280_atio_entry: SM_WRDB, zero length\n\r");
-#endif
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_NO_DATA;
-                            }
-
-                            break;
-                        case RW_BUF_DATA:
-#ifdef QL_DEBUG_LEVEL_3
-                            qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_DATA\n\r");
-#endif
-                            *a64 += offset + TARGET_DATA_OFFSET;
-                            if (pkt->cdb[2] != 0 || *a64 >= *end_a64 ||
-                                *a64 + len > *end_a64)
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                    qla1280_print("qla1280_atio_entry: SM_WRDB, RW_BUF_DATA BAD\n\r");
-                                    qla1280_print("buf_id=");
-                                    qla1280_output_number((uint32_t)pkt->cdb[2], 16);
-                                    qla1280_print(", offset=");
-                                    qla1280_output_number((uint32_t)offset, 16);
-                                    qla1280_print(", length=");
-                                    qla1280_output_number((uint32_t)len, 16);
-                                    qla1280_print("\n\r");
-#endif
-                                    *sense_ptr = 0x70;
-                                    *(sense_ptr+2) = SD_ILLREQ;
-                                    *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                                    *(sense_ptr+12) = SC_ILLCDB;
-                                    len = 0;
-                                    pkt->scsi_status = S_CKCON;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_NO_DATA;
-                            }
-                            else if (len)
-                            {
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_DATA_OUT;
-#ifdef QL_DEBUG_LEVEL_3
-                                    qla1280_print("qla1280_atio_entry: Issuing SDI_TARMOD_WRCOMP\n\r");
-#endif
-                                    sdi_xaen(SDI_TARMOD_WRCOMP, ha->cntlr,
-                                            pkt->target_id, pkt->lun, 0, offset);
-                            }
-                            else
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                    qla1280_print("qla1280_atio_entry: SM_WRDB, zero length\n\r");
-#endif
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_NO_DATA;
-                            }
-                            break;
-                        default:
-#ifdef QL_DEBUG_LEVEL_2
-                            qla1280_print("qla1280_atio_entry: SM_WRDB unknown mode\n\r");
-#endif
-                            *sense_ptr = 0x70;
-                            *(sense_ptr+2) = SD_ILLREQ;
-                            *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                            *(sense_ptr+12) = SC_ILLCDB;
-                            len = 0;
-                            pkt->scsi_status = S_CKCON;
-                            pkt->option_flags |= (uint32_t)OF_SSTS |
-                                    (uint32_t)OF_NO_DATA;
-                            break;
-                    }
-                    break;
-                case SM_RDDB:
-                    bzero(sense_ptr, TARGET_SENSE_SIZE);
-                    offset = pkt->cdb[5];
-                    offset |= pkt->cdb[4] << 8;
-                    offset |= pkt->cdb[3] << 16;
-                    len = pkt->cdb[8];
-                    len |= pkt->cdb[7] << 8;
-                    len |= pkt->cdb[6] << 16;
-                    end_addr[0] = phy_addr[0] = ha->tbuf_dma;
-                    end_addr[1] = phy_addr[1] = 0;
-                    *end_a64 += TARGET_DATA_OFFSET + TARGET_DATA_SIZE;
-                    switch (pkt->cdb[1] & 7)
-                    {
-                        case RW_BUF_HDATA:
-#ifdef QL_DEBUG_LEVEL_3
-                            qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_HDATA\n\r");
-#endif
-                            if (len)
-                            {
-                                ha->tbuf->hdr[0] = 0;
-                                ha->tbuf->hdr[1] =
-                                        (uint8_t)(TARGET_DATA_SIZE >> 16);
-                                ha->tbuf->hdr[2] =
-                                        (uint8_t)(TARGET_DATA_SIZE >> 8);
-                                ha->tbuf->hdr[3] = (uint8_t)TARGET_DATA_SIZE;
-                                if (len > TARGET_DATA_SIZE + 4)
-                                    len = TARGET_DATA_SIZE + 4;
-                                pkt->scsi_status = S_GOOD;
-                                pkt->option_flags |= (uint32_t)OF_SSTS |
-                                        (uint32_t)OF_DATA_IN;
-                            }
-                            else
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                    qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r");
-#endif
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_NO_DATA;
-                            }
-                            break;
-                        case RW_BUF_DATA:
-#ifdef QL_DEBUG_LEVEL_3
-                            qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DATA\n\r");
-#endif
-                            *a64 += offset + TARGET_DATA_OFFSET;
-                            if (pkt->cdb[2] != 0 || *a64 >= *end_a64)
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                    qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DATA BAD\n\r");
-                                    qla1280_print("buf_id=");
-                                    qla1280_output_number((uint32_t)pkt->cdb[2], 16);
-                                    qla1280_print(", offset=");
-                                    qla1280_output_number((uint32_t)offset, 16);
-                                    qla1280_print("\n\r");
-#endif
-                                    *sense_ptr = 0x70;
-                                    *(sense_ptr+2) = SD_ILLREQ;
-                                    *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                                    *(sense_ptr+12) = SC_ILLCDB;
-                                    len = 0;
-                                    pkt->scsi_status = S_CKCON;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_NO_DATA;
-                            }
-                            else
-                            {
-                                    if (*a64 + len > *end_a64)
-                                        len = *end_a64 - *a64;
-                                    if (len)
-                                    {
-                                        pkt->scsi_status = S_GOOD;
-                                        pkt->option_flags |= (uint32_t)OF_SSTS |
-                                                (uint32_t)OF_DATA_IN;
-                                    }
-                                    else
-                                    {
-#ifdef QL_DEBUG_LEVEL_2
-                                            qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r");
-#endif
-                                            pkt->scsi_status = S_GOOD;
-                                            pkt->option_flags |= (uint32_t)OF_SSTS |
-                                                    (uint32_t)OF_NO_DATA;
-                                    }
-                            }
-                            break;
-                        case RW_BUF_DESC:
-#ifdef QL_DEBUG_LEVEL_3
-                            qla1280_print("qla1280_atio_entry: SM_RDDB, RW_BUF_DESC\n\r");
-#endif
-                            if (len)
-                            {
-                                    if (len > 4)
-                                        len = 4;
-
-                                    ha->tbuf->hdr[0] = 0;
-                                    if (pkt->cdb[2] != 0)
-                                    {
-                                        ha->tbuf->hdr[1] = 0;
-                                        ha->tbuf->hdr[2] = 0;
-                                        ha->tbuf->hdr[3] = 0;
-                                    }
-                                    else
-                                    {
-                                            ha->tbuf->hdr[1] =
-                                                    (uint8_t)(TARGET_DATA_SIZE >> 16);
-                                            ha->tbuf->hdr[2] =
-                                                    (uint8_t)(TARGET_DATA_SIZE >> 8);
-                                            ha->tbuf->hdr[3] =
-                                                    (uint8_t)TARGET_DATA_SIZE;
-                                    }
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_DATA_IN;
-                            }
-                            else
-                            {
-#ifdef QL_DEBUG_LEVEL_2
-                                    qla1280_print("qla1280_atio_entry: SM_RDDB, zero length\n\r");
-#endif
-                                    pkt->scsi_status = S_GOOD;
-                                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                                            (uint32_t)OF_NO_DATA;
-                            }
-                            break;
-                        default:
-#ifdef QL_DEBUG_LEVEL_2
-                            qla1280_print("qla1280_atio_entry: SM_RDDB unknown mode\n\r");
-#endif
-                            *sense_ptr = 0x70;
-                            *(sense_ptr+2) = SD_ILLREQ;
-                            *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                            *(sense_ptr+12) = SC_ILLCDB;
-                            len = 0;
-                            pkt->scsi_status = S_CKCON;
-                            pkt->option_flags |= (uint32_t)OF_SSTS |
-                                    (uint32_t)OF_NO_DATA;
-                            break;
-                    }
-                    break;
-                default:
-#ifdef QL_DEBUG_LEVEL_2
-                    qla1280_print("qla1280_atio_entry: Unknown SCSI command\n\r");
-                    qla1280_dump_buffer((caddr_t)&pkt->cdb[0], pkt->cdb_len);
-#endif
-                    bzero(sense_ptr, TARGET_SENSE_SIZE);
-                    *sense_ptr = 0x70;
-                    *(sense_ptr+2) = SD_ILLREQ;
-                    *(sense_ptr+7) = TARGET_SENSE_SIZE-8;
-                    *(sense_ptr+12) = SC_INVOPCODE;
-                    len = 0;
-                    pkt->scsi_status = S_CKCON;
-                    pkt->option_flags |= (uint32_t)OF_SSTS |
-                            (uint32_t)OF_NO_DATA;
-                    break;
-            }
-            if (ha->flags.enable_64bit_addressing)
-                qla1280_64bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr);
-            else
-                qla1280_32bit_continue_io(ha, pkt, len, (paddr32_t *)&phy_addr);
-            break;
-        default:
-            break;
-    }
+	uint8_t bus;
 
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_atio_entry: exiting normally\n\r");
-#endif
+	ENTER("qla1280_rst_aen");
+
+	if (ha->flags.online && !ha->flags.reset_active &&
+	    !ha->flags.abort_isp_active) {
+		ha->flags.reset_active = 1;
+		while (ha->flags.reset_marker) {
+			/* Issue marker command. */
+			ha->flags.reset_marker = 0;
+			for (bus = 0; bus < ha->ports &&
+				     !ha->flags.reset_marker; bus++) {
+				if (ha->bus_settings[bus].reset_marker) {
+					ha->bus_settings[bus].reset_marker = 0;
+					qla1280_marker(ha, bus, 0, 0,
+						       MK_SYNC_ALL);
+				}
+			}
+		}
+	}
+
+	LEAVE("qla1280_rst_aen");
 }
 
+
+#if LINUX_VERSION_CODE < 0x020500
 /*
- *  qla1280_notify_entry
- *      Processes received ISP immediate notify entry.
  *
- * Input:
- *      ha  = adapter block pointer.
- *      pkt = entry pointer.
  */
-STATIC void
-qla1280_notify_entry(scsi_qla_host_t *ha, notify_entry_t *pkt)
+static void
+qla1280_get_target_options(struct scsi_cmnd *cmd, struct scsi_qla_host *ha)
 {
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_notify_entry: entered\n\r");
-#endif
+	unsigned char *result;
+	struct nvram *n;
+	int bus, target, lun;
 
-    /* Acknowledge immediate notify */
-    qla1280_notify_ack(ha, pkt);
+	bus = SCSI_BUS_32(cmd);
+	target = SCSI_TCN_32(cmd);
+	lun = SCSI_LUN_32(cmd);
 
-    /* Issue notify entry to increment resource count */
-    qla1280_immed_notify(ha, pkt);
+	/*
+	 * Make sure to not touch anything if someone is using the
+	 * sg interface.
+	 */
+	if (cmd->use_sg || (CMD_RESULT(cmd) >> 16) != DID_OK || lun)
+		return;
 
-#ifdef QL_DEBUG_LEVEL_3
-    qla1280_print("qla1280_notify_entry: exiting normally\n\r");
-#endif
+	result = cmd->request_buffer;
+	n = &ha->nvram;
+
+	n->bus[bus].target[target].parameter.f.enable_wide = 0;
+	n->bus[bus].target[target].parameter.f.enable_sync = 0;
+	n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 0;
+
+        if (result[7] & 0x60)
+		n->bus[bus].target[target].parameter.f.enable_wide = 1;
+        if (result[7] & 0x10)
+		n->bus[bus].target[target].parameter.f.enable_sync = 1;
+	if ((result[2] >= 3) && (result[4] + 5 > 56) &&
+	    (result[56] & 0x4))
+		n->bus[bus].target[target].ppr_1x160.flags.enable_ppr = 1;
+
+	dprintk(2, "get_target_options(): wide %i, sync %i, ppr %i\n",
+		n->bus[bus].target[target].parameter.f.enable_wide,
+		n->bus[bus].target[target].parameter.f.enable_sync,
+		n->bus[bus].target[target].ppr_1x160.flags.enable_ppr);
 }
+#endif
 
-#endif  /* QLA1280_TARGET_MODE_SUPPORT */
 /*
  *  qla1280_status_entry
  *      Processes received ISP status entry.
@@ -5724,104 +4570,92 @@
  *      done_q_first = done queue first pointer.
  *      done_q_last  = done queue last pointer.
  */
-STATIC void
-qla1280_status_entry(scsi_qla_host_t *ha, sts_entry_t *pkt, srb_t **done_q_first,
-                     srb_t **done_q_last)
-{
-    uint32_t        b, t, l;
-    uint8_t         sense_sz = 0;
-    srb_t           *sp;
-    scsi_lu_t       *q;
-    Scsi_Cmnd       *cp;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_status_entry");
-#endif
-
-    /* Validate handle. */
-    if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
-        sp = ha->outstanding_cmds[pkt->handle];
-    else
-        sp = 0;
-
-    if (sp)
-    {
-        /* Free outstanding command slot. */
-        ha->outstanding_cmds[pkt->handle] = 0;
-
-        cp = sp->cmd;
-        /* Generate LU queue on cntrl, target, LUN */
-        b = SCSI_BUS_32(cp);
-        t = SCSI_TCN_32(cp);
-        l = SCSI_LUN_32(cp);
-        q = LU_Q(ha, b, t, l);
-        if( pkt->comp_status || pkt->scsi_status )
-        {
-            DEBUG(qla1280_print( "scsi: comp_status = ");)
-            DEBUG(qla1280_output_number((uint32_t)pkt->comp_status,16);)
-            DEBUG(qla1280_print( ", ");)
-            DEBUG(qla1280_print( " scsi_status = ");)
-            DEBUG(qla1280_output_number((uint32_t)pkt->scsi_status,16);)
-            DEBUG(qla1280_print( "\n\r");)
-            DEBUG(qla1280_print(", handle = ");)
-            DEBUG(qla1280_output_number((uint32_t)pkt->handle, 16);)
-            DEBUG(qla1280_print("\n\r");)
-        }
-
-        /* Target busy */
-        if ( pkt->scsi_status & SS_BUSY_CONDITION &&
-            pkt->scsi_status != SS_RESERVE_CONFLICT   )
-        {
-            CMD_RESULT(cp) = (int) (DID_BUS_BUSY << 16) |
-                    (pkt->scsi_status & 0xff);
-        }
-        else
-        {
-
-            /* Save ISP completion status */
-            CMD_RESULT(cp) = qla1280_return_status( pkt, cp );
-
-            if (pkt->scsi_status & SS_CHECK_CONDITION)
-            {
-                BZERO(cp->sense_buffer, CMD_SNSLEN(cp));
-                if (pkt->comp_status != CS_ARS_FAILED)
-                {
-                    if ( pkt->req_sense_length < CMD_SNSLEN(cp)  )
-                        sense_sz = pkt->req_sense_length;
-                    else
-                        sense_sz = CMD_SNSLEN(cp) - 1;
-
-                    BCOPY((caddr_t)&pkt->req_sense_data, cp->sense_buffer, sense_sz);
-
-                }
-#ifdef QL_DEBUG_LEVEL_2
-                DEBUG(qla1280_print(
-                        "qla1280_status_entry: Check condition Sense data, b");)
-                DEBUG(qla1280_output_number((uint32_t)b, 10);)
-                DEBUG(qla1280_print("t");)
-                DEBUG(qla1280_output_number((uint32_t)t, 10);)
-                DEBUG(qla1280_print("d");)
-                DEBUG(qla1280_output_number((uint32_t)l, 10);)
-                DEBUG(qla1280_print("\n\r");)
-                DEBUG(if (sense_sz))
-                    DEBUG(qla1280_dump_buffer(cp->sense_buffer, sense_sz);)
-#endif
-            }
-        }
-        /* Place command on done queue. */
-        qla1280_done_q_put(sp, done_q_first, done_q_last);
-    }
-    else
-    {
-#ifdef QL_DEBUG_LEVEL_2
-        qla1280_print("qla1280_status_entry: ISP Invalid handle\n\r");
-#endif
-        printk(KERN_WARNING "qla1280: Status Entry invalid handle\n");
-        ha->flags.isp_abort_needed = TRUE;
-    }
-#ifdef QL_DEBUG_LEVEL_3
-    LEAVE("qla1280_status_entry");
-#endif
+static void
+qla1280_status_entry(struct scsi_qla_host *ha, struct response *pkt,
+		     struct srb **done_q_first, struct srb **done_q_last)
+{
+	unsigned int bus, target, lun;
+	int sense_sz;
+	struct srb *sp;
+	Scsi_Cmnd *cmd;
+	uint32_t handle = le32_to_cpu(pkt->handle);
+	uint16_t scsi_status = le16_to_cpu(pkt->scsi_status);
+	uint16_t comp_status = le16_to_cpu(pkt->comp_status);
+
+	ENTER("qla1280_status_entry");
+
+	/* Validate handle. */
+	if (handle < MAX_OUTSTANDING_COMMANDS)
+		sp = ha->outstanding_cmds[handle];
+	else
+		sp = NULL;
+
+	if (!sp) {
+		printk(KERN_WARNING "qla1280: Status Entry invalid handle\n");
+		goto out;
+	}
+
+	/* Free outstanding command slot. */
+	ha->outstanding_cmds[handle] = 0;
+
+	cmd = sp->cmd;
+
+	/* Generate LU queue on cntrl, target, LUN */
+	bus = SCSI_BUS_32(cmd);
+	target = SCSI_TCN_32(cmd);
+	lun = SCSI_LUN_32(cmd);
+
+	if (comp_status || scsi_status) {
+		dprintk(3, "scsi: comp_status = 0x%x, scsi_status = "
+			"0x%x, handle = 0x%x\n", comp_status,
+			scsi_status, handle);
+	}
+
+	/* Target busy */
+	if (scsi_status & SS_BUSY_CONDITION &&
+	    scsi_status != SS_RESERVE_CONFLICT) {
+		CMD_RESULT(cmd) =
+			DID_BUS_BUSY << 16 | (scsi_status & 0xff);
+	} else {
+
+		/* Save ISP completion status */
+		CMD_RESULT(cmd) = qla1280_return_status(pkt, cmd);
+
+		if (scsi_status & SS_CHECK_CONDITION) {
+			if (comp_status != CS_ARS_FAILED) {
+				uint16_t req_sense_length =
+					le16_to_cpu(pkt->req_sense_length);
+				if (req_sense_length < CMD_SNSLEN(cmd))
+					sense_sz = req_sense_length;
+				else
+					/*
+					 * Scsi_Cmnd->sense_buffer is
+					 * 64 bytes, why only copy 63?
+					 * This looks wrong! /Jes
+					 */
+					sense_sz = CMD_SNSLEN(cmd) - 1;
+
+				memcpy(cmd->sense_buffer,
+				       &pkt->req_sense_data, sense_sz);
+			} else
+				sense_sz = 0;
+			memset(cmd->sense_buffer + sense_sz, 0,
+			       sizeof(cmd->sense_buffer) - sense_sz);
+
+			dprintk(2, "qla1280_status_entry: Check "
+				"condition Sense data, b %i, t %i, "
+				"l %i\n", bus, target, lun);
+			if (sense_sz)
+				qla1280_dump_buffer(2,
+						    (char *)cmd->sense_buffer,
+						    sense_sz);
+		}
+	}
+	/* Place command on done queue. */
+	qla1280_done_q_put(sp, done_q_first, done_q_last);
+
+ out:
+	LEAVE("qla1280_status_entry");
 }
 
 /*
@@ -5834,71 +4668,55 @@
  *      done_q_first = done queue first pointer.
  *      done_q_last  = done queue last pointer.
  */
-STATIC void
-qla1280_error_entry(scsi_qla_host_t *ha, response_t *pkt, srb_t **done_q_first,
-                    srb_t **done_q_last)
-{
-    srb_t   *sp;
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_error_entry");
-#endif
-
-#ifdef QL_DEBUG_LEVEL_2
-    if (pkt->entry_status & BIT_3)
-        qla1280_print("qla1280_error_entry: BAD PAYLOAD flag error\n\r");
-    else if (pkt->entry_status & BIT_2)
-        qla1280_print("qla1280_error_entry: BAD HEADER flag error\n\r");
-    else if (pkt->entry_status & BIT_1)
-        qla1280_print("qla1280_error_entry: FULL flag error\n\r");
-    else
-        qla1280_print("qla1280_error_entry: UNKNOWN flag error\n\r");
-#endif
-
-    /* Validate handle. */
-    if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
-        sp = ha->outstanding_cmds[pkt->handle];
-    else
-        sp = 0;
-
-    if (sp)
-    {
-        /* Free outstanding command slot. */
-        ha->outstanding_cmds[pkt->handle] = 0;
-
-        /* Bad payload or header */
-        if (pkt->entry_status & (BIT_3 + BIT_2))
-        {
-            /* Bad payload or header, set error status. */
-            /* CMD_RESULT(sp->cmd) = CS_BAD_PAYLOAD; */
-            CMD_RESULT(sp->cmd) = (int) DID_ERROR << 16;
-        }
-        else if (pkt->entry_status & BIT_1 ) /* FULL flag */
-        {
-            CMD_RESULT(sp->cmd) = (int) DID_BUS_BUSY << 16;
-        }
-        else
-        {
-            /* Set error status. */
-            CMD_RESULT(sp->cmd) =(int)  DID_ERROR << 16;
-        }
-        /* Place command on done queue. */
-        qla1280_done_q_put(sp, done_q_first, done_q_last);
-    }
-#if  QLA1280_64BIT_SUPPORT
-    else if (pkt->entry_type == COMMAND_A64_TYPE)
-    {
-#ifdef QL_DEBUG_LEVEL_2
-        qla1280_print("qla1280_error_entry: ISP Invalid handle\n\r");
-#endif
-        printk(KERN_WARNING "!qla1280: Error Entry invalid handle");
-        ha->flags.isp_abort_needed = TRUE;
-    }
-#endif
+static void
+qla1280_error_entry(struct scsi_qla_host *ha, struct response * pkt,
+		    struct srb ** done_q_first, struct srb ** done_q_last)
+{
+	struct srb *sp;
+	uint32_t handle = le32_to_cpu(pkt->handle);
+
+	ENTER("qla1280_error_entry");
+
+	if (pkt->entry_status & BIT_3)
+		dprintk(2, "qla1280_error_entry: BAD PAYLOAD flag error\n");
+	else if (pkt->entry_status & BIT_2)
+		dprintk(2, "qla1280_error_entry: BAD HEADER flag error\n");
+	else if (pkt->entry_status & BIT_1)
+		dprintk(2, "qla1280_error_entry: FULL flag error\n");
+	else
+		dprintk(2, "qla1280_error_entry: UNKNOWN flag error\n");
 
-#ifdef QL_DEBUG_LEVEL_3
-    LEAVE("qla1280_error_entry");
+	/* Validate handle. */
+	if (handle < MAX_OUTSTANDING_COMMANDS)
+		sp = ha->outstanding_cmds[handle];
+	else
+		sp = 0;
+
+	if (sp) {
+		/* Free outstanding command slot. */
+		ha->outstanding_cmds[handle] = 0;
+
+		/* Bad payload or header */
+		if (pkt->entry_status & (BIT_3 + BIT_2)) {
+			/* Bad payload or header, set error status. */
+			/* CMD_RESULT(sp->cmd) = CS_BAD_PAYLOAD; */
+			CMD_RESULT(sp->cmd) = DID_ERROR << 16;
+		} else if (pkt->entry_status & BIT_1) {	/* FULL flag */
+			CMD_RESULT(sp->cmd) = DID_BUS_BUSY << 16;
+		} else {
+			/* Set error status. */
+			CMD_RESULT(sp->cmd) = DID_ERROR << 16;
+		}
+		/* Place command on done queue. */
+		qla1280_done_q_put(sp, done_q_first, done_q_last);
+	}
+#ifdef QLA_64BIT_PTR
+	else if (pkt->entry_type == COMMAND_A64_TYPE) {
+		printk(KERN_WARNING "!qla1280: Error Entry invalid handle");
+	}
 #endif
+
+	LEAVE("qla1280_error_entry");
 }
 
 /*
@@ -5911,236 +4729,91 @@
  * Returns:
  *      0 = success
  */
-STATIC uint8_t
-qla1280_abort_isp(scsi_qla_host_t *ha)
-{
-    device_reg_t    *reg = ha->iobase;
-    uint8_t         status = 0;
-    uint16_t        cnt;
-    srb_t           *sp;
-    scsi_lu_t       *q;
-    uint32_t        b, t, l;
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-    unsigned long cpu_flags = 0;
-#endif
-
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_abort_isp");
-#endif
-
-    DRIVER_LOCK
-            ha->flags.isp_abort_needed = FALSE;
-    if (!ha->flags.abort_isp_active && ha->flags.online)
-    {
-        ha->flags.abort_isp_active = TRUE;
-
-        /* Disable ISP interrupts. */
-        WRT_REG_WORD(&reg->ictrl, 0);
-
-        /* Dequeue all commands in outstanding command list. */
-        for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++)
-        {
-            sp = ha->outstanding_cmds[cnt];
-            if (sp)
-            {
-                ha->outstanding_cmds[cnt] = 0;
-
-                /* Generate LU queue on controller, target, LUN */
-                b = SCSI_BUS_32(sp->cmd);
-                t = SCSI_TCN_32(sp->cmd);
-                l = SCSI_LUN_32(sp->cmd);
-
-                q = (scsi_lu_t       *)LU_Q(ha, b, t, l);
-
-                /* Reset outstanding command count. */
-                q->q_outcnt = 0;
-                q->q_flag &= ~QLA1280_QBUSY;
-                q->q_flag =  0;
-
-                /* Adjust watchdog timer for command. */
-                /* if (sp->flags & SRB_WATCHDOG)
-                sp->timeout += 2; */
-
-                /* Place request back on top of device queue. */
-                /* sp->flags &= ~(SRB_SENT | SRB_TIMEOUT); */ 
-                sp->flags = 0;
-                qla1280_putq_t(q, sp);
-            }
-        }
-
-        /* If firmware needs to be loaded */
-        if (qla1280_isp_firmware(ha))
-        {
-            if (!(status = qla1280_chip_diag(ha)))
-                status = qla1280_setup_chip(ha); 
-        }
-
-        if (!status)
-        {
-            /* Setup adapter based on NVRAM parameters. */
-            qla1280_nvram_config(ha); 
-
-            if (!(status = qla1280_init_rings(ha)))
-            {
-                /* Issue SCSI reset. */
-                for (b = 0; b < ha->ports; b++)
-                {
-                    qla1280_bus_reset(ha, b);
-                }
-                do
-                {
-                    /* Issue marker command. */
-                    ha->flags.reset_marker = FALSE;
-                    for (b = 0; b < ha->ports; b++)
-                    {
-                        ha->bus_settings[b].reset_marker = FALSE;
-                        qla1280_marker(ha, b, 0, 0, MK_SYNC_ALL);
-                    }
-                }while (ha->flags.reset_marker);
-
-                /* Enable host adapter target mode. */
-                for (b = 0; b < ha->ports; b++)
-                {
-                    if (!(status = qla1280_enable_tgt(ha, b)))
-                    {
-                        for (cnt = 0; cnt < MAX_LUNS; cnt++)
-                        {
-                            /* qla1280_enable_lun(ha, b, cnt); */
-                            qla1280_poll(ha);
-                        }
-                    }
-                    else
-                        break;
-                }
-
-                if (!status)
-                { 
-                    /* Enable ISP interrupts. */
-                    WRT_REG_WORD(&reg->ictrl, ISP_EN_INT + ISP_EN_RISC);
-                    ha->flags.abort_isp_active = FALSE;
-                    /* Restart queues that may have been stopped. */
-                    qla1280_restart_queues(ha);
-                }
-            }
-        }
-    }
-
-    if (status)
-    {
-        printk(KERN_WARNING
-                "qla1280: ISP error recovery failed, board disabled");
-        qla1280_reset_adapter(ha);
-        qla1280_abort_queues(ha);
-
-#if defined(QL_DEBUG_LEVEL_2) || defined(QL_DEBUG_LEVEL_3)
-        qla1280_print("qla1280_abort_isp: **** FAILED ****\n\r");
-#endif
-    }
-#ifdef QL_DEBUG_LEVEL_3
-    else
-        LEAVE("qla1280_abort_isp");
-#endif
-    DRIVER_UNLOCK
-
-            return(status);
-}
-
-/*
- *  qla1280_restart_queues
- *      Restart all device queues.
- *
- * Input:
- *      ha = adapter block pointer.
- */
-STATIC void
-qla1280_restart_queues(scsi_qla_host_t *ha)
+static int
+qla1280_abort_isp(struct scsi_qla_host *ha)
 {
-    scsi_lu_t *q;
-    uint32_t  b, t, l;
+	struct srb *sp;
+	int status = 0;
+	int cnt;
+	int bus;
 
-#ifdef QL_DEBUG_LEVEL_3
-    ENTER("qla1280_restart_queues");
-#endif
-
-    for (b = 0; b < ha->ports; b++)
-        for (t = 0; t < MAX_TARGETS; t++)
-            for (l = 0; l < MAX_LUNS; l++)
-            {
-                q = (scsi_lu_t *) LU_Q(ha, b, t, l);
-                if (q != NULL)
-                {
-                    /* Acquire LU queue specific lock */
-                    QLA1280_SCSILU_LOCK(q);
+	ENTER("qla1280_abort_isp");
 
-                    if (q->q_first)
-                        qla1280_next(ha, q, b);
-                    else
-                        /* Release LU queue specific lock */
-                        QLA1280_SCSILU_UNLOCK(q);
-                }
-            }
-#ifdef QL_DEBUG_LEVEL_3
-            qla1280_print("qla1280_restart_queues: exiting normally\n");
-#endif
-}
+	if (!ha->flags.abort_isp_active && ha->flags.online) {
+		struct device_reg *reg = ha->iobase;
+		ha->flags.abort_isp_active = 1;
 
-/*
- *  qla1280_abort_queue_single
- *      Abort all commands on a device queues.
- *
- * Input:
- *      ha = adapter block pointer.
- */
-STATIC void qla1280_abort_queue_single(scsi_qla_host_t *ha,uint32_t b,uint32_t t,uint32_t l,uint32_t stat)
-{
-    scsi_lu_t *q;
-    srb_t     *sp, *sp_next; 
+		/* Disable ISP interrupts. */
+		qla1280_disable_intrs(ha);
+		WRT_REG_WORD(&reg->host_cmd, HC_PAUSE_RISC);
+		RD_REG_WORD(&reg->id_l);
 
-    ENTER("qla1280_abort_queue_single");
-    q = (scsi_lu_t * )LU_Q(ha, b, t, l);
-    if (q != NULL)
-    {
-        /* Acquire LU queue specific lock */
-        QLA1280_SCSILU_LOCK(q);
+		printk(KERN_INFO "scsi(%li): dequeuing outstanding commands\n",
+		       ha->host_no);
+		/* Dequeue all commands in outstanding command list. */
+		for (cnt = 0; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
+			Scsi_Cmnd *cmd;
+			sp = ha->outstanding_cmds[cnt];
+			if (sp) {
+
+				cmd = sp->cmd;
+				CMD_RESULT(cmd) = DID_RESET << 16;
 
-        sp = q->q_first;
-        q->q_first = q->q_last = NULL;
+				sp->cmd = NULL;
+				ha->outstanding_cmds[cnt] = NULL;
 
-        QLA1280_SCSILU_UNLOCK(q);
+				(*cmd->scsi_done)(cmd);
 
-        while (sp)
-        {
-            sp_next = sp->s_next;
-            CMD_RESULT(sp->cmd) = stat;
-            qla1280_done_q_put(sp, (srb_t **)&ha->done_q_first, (srb_t **)&ha->done_q_last);
-            sp = sp_next;
-        }
-    }
-    LEAVE("qla1280_abort_queue_single");
-}
+				sp->flags = 0;
+			}
+		}
 
-/*
- *  qla1280_abort_queues
- *      Abort all commands on device queues.
- *
- * Input:
- *      ha = adapter block pointer.
- */
-STATIC void
-qla1280_abort_queues(scsi_qla_host_t *ha)
-{
-    uint32_t  b, t, l;
+		/* If firmware needs to be loaded */
+		if (qla1280_isp_firmware (ha)) {
+			if (!(status = qla1280_chip_diag(ha)))
+				status = qla1280_setup_chip(ha);
+		}
 
-    ENTER("qla1280_abort_queues");
+		if (!status) {
+			/* Setup adapter based on NVRAM parameters. */
+			qla1280_nvram_config (ha);
+
+			if (!(status = qla1280_init_rings(ha))) {
+				/* Issue SCSI reset. */
+				for (bus = 0; bus < ha->ports; bus++) {
+					qla1280_bus_reset(ha, bus);
+				}
+				/*
+				 * qla1280_bus_reset() will do the marker
+				 * dance - no reason to repeat here!
+				 */
+#if  0
+				/* Issue marker command. */
+				ha->flags.reset_marker = 0;
+				for (bus = 0; bus < ha->ports; bus++) {
+					ha->bus_settings[bus].
+						reset_marker = 0;
+					qla1280_marker(ha, bus, 0, 0,
+						       MK_SYNC_ALL);
+				}
+#endif
+				ha->flags.abort_isp_active = 0;
+			}
+		}
+	}
 
-    for (b = 0; b < ha->ports; b++)
-        for (t = 0; t < MAX_TARGETS; t++)
-            for (l = 0; l < MAX_LUNS; l++)
-                qla1280_abort_queue_single(ha,b,t,l,DID_RESET);
+	if (status) {
+		printk(KERN_WARNING
+		       "qla1280: ISP error recovery failed, board disabled");
+		qla1280_reset_adapter(ha);
+		dprintk(2, "qla1280_abort_isp: **** FAILED ****\n");
+	}
 
-            LEAVE("qla1280_abort_queues");
+	LEAVE("qla1280_abort_isp");
+	return status;
 }
 
+
 /*
  * qla1280_debounce_register
  *      Debounce register.
@@ -6151,28 +4824,27 @@
  * Returns:
  *      register value.
  */
-STATIC uint16_t
-qla1280_debounce_register(volatile uint16_t *addr)
+static u16
+qla1280_debounce_register(volatile u16 * addr)
 {
-    volatile uint16_t ret;
-    volatile uint16_t ret2;
+	volatile u16 ret;
+	volatile u16 ret2;
 
-    do
-    {
-        ret = RD_REG_WORD(addr);
-        ret2 = RD_REG_WORD(addr);
-    }while (ret != ret2);
+	ret = RD_REG_WORD(addr);
+	ret2 = RD_REG_WORD(addr);
 
-    return(ret);
-}
+	if (ret == ret2)
+		return ret;
 
+	do {
+		cpu_relax();
+		ret = RD_REG_WORD(addr);
+		ret2 = RD_REG_WORD(addr);
+	} while (ret != ret2);
 
-/*
- * Declarations for load module
- */
-static Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE;
+	return ret;
+}
 
-#include "scsi_module.c"
 
 /************************************************************************
  * qla1280_check_for_dead_scsi_bus                                      *
@@ -6181,638 +4853,309 @@
  ************************************************************************/
 #define SET_SXP_BANK            0x0100
 #define SCSI_PHASE_INVALID      0x87FF
-int  qla1280_check_for_dead_scsi_bus(scsi_qla_host_t *ha, srb_t *sp)
-{
-    uint16_t  config_reg, scsi_control;
-    device_reg_t    *reg = ha->iobase;
-    uint32_t  b;
-    Scsi_Cmnd       *cp;
-
-    /*
-     * If SCSI Bus is Dead because of bad termination,
-     * we will return a status of Selection timeout.
-     */
- 
-     cp = sp->cmd;
-     b = SCSI_BUS_32(cp);
-    if (ha->bus_settings[b].scsi_bus_dead)
-    {
-        WRT_REG_WORD(&reg->host_cmd, HC_PAUSE_RISC);
-        config_reg = RD_REG_WORD(&reg->cfg_1);
-        WRT_REG_WORD(&reg->cfg_1,SET_SXP_BANK);
-        scsi_control = RD_REG_WORD(&reg->scsiControlPins);
-        WRT_REG_WORD(&reg->cfg_1,config_reg);
-        WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
-
-        if (scsi_control == SCSI_PHASE_INVALID)
-        {
-            CMD_RESULT(cp) = DID_NO_CONNECT << 16;
-            CMD_HANDLE(cp) = (unsigned char *) 0;
-            /* ha->actthreads--; */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-            sti(); 
-            (*(cp)->scsi_done)(cp);
-            cli(); 
-#else
-            (*(cp)->scsi_done)(cp);
-#endif
-            return(TRUE);   /* bus is dead */
-        }
-        else
-        {
-            ha->bus_settings[b].scsi_bus_dead = FALSE;
-            ha->bus_settings[b].failed_reset_count= 0; 
-        }
-    }
-    return(FALSE);   /* bus is not dead */
-}
-
-STATIC uint8_t
-qla12160_set_target_parameters(scsi_qla_host_t *ha, uint32_t b, uint32_t t, uint32_t l, nvram160_t *nv)
+static int
+qla1280_check_for_dead_scsi_bus(struct scsi_qla_host *ha, unsigned int bus)
 {
-    uint16_t        mb[MAILBOX_REGISTER_COUNT];
+	uint16_t config_reg, scsi_control;
+	struct device_reg *reg = ha->iobase;
 
-    /* Set Target Parameters. */
-    mb[0] = MBC_SET_TARGET_PARAMETERS;
-    mb[1] = (uint16_t)(b ? t | BIT_7 :t);
-    mb[1] <<= 8;
-    mb[2] = nv->bus[b].target[t].parameter.c << 8;
-    mb[2] |= TP_AUTO_REQUEST_SENSE;
-    mb[2] &= ~TP_STOP_QUEUE;
-    mb[2] |=  (nv->bus[b].target[t].flags.enable_ppr << 5);
-    mb[3] = nv->bus[b].target[t].flags.sync_offset << 8;
-    mb[3] |= nv->bus[b].target[t].sync_period;
+	if (ha->bus_settings[bus].scsi_bus_dead) {
+		WRT_REG_WORD(&reg->host_cmd, HC_PAUSE_RISC);
+		config_reg = RD_REG_WORD(&reg->cfg_1);
+		WRT_REG_WORD(&reg->cfg_1, SET_SXP_BANK);
+		scsi_control = RD_REG_WORD(&reg->scsiControlPins);
+		WRT_REG_WORD(&reg->cfg_1, config_reg);
+		WRT_REG_WORD(&reg->host_cmd, HC_RELEASE_RISC);
 
-    mb[6] = nv->bus[b].target[t].flags.ppr_options << 8;
-    mb[6] |= nv->bus[b].target[t].flags.ppr_bus_width;
-    return( qla1280_mailbox_command(ha, BIT_6|BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]) ) ;
+		if (scsi_control == SCSI_PHASE_INVALID) {
+			ha->bus_settings[bus].scsi_bus_dead = 1;
+#if 0
+			CMD_RESULT(cp) = DID_NO_CONNECT << 16;
+			CMD_HANDLE(cp) = INVALID_HANDLE;
+			/* ha->actthreads--; */
+
+			(*(cp)->scsi_done)(cp);
+#endif
+			return 1;	/* bus is dead */
+		} else {
+			ha->bus_settings[bus].scsi_bus_dead = 0;
+			ha->bus_settings[bus].failed_reset_count = 0;
+		}
+	}
+	return 0;		/* bus is not dead */
 }
 
-STATIC void
-qla12160_get_target_parameters(scsi_qla_host_t *ha, uint32_t b, uint32_t t, uint32_t l)
+static void
+qla12160_get_target_parameters(struct scsi_qla_host *ha, Scsi_Device *device)
 {
-    uint16_t        mb[MAILBOX_REGISTER_COUNT];
+	uint16_t mb[MAILBOX_REGISTER_COUNT];
+	int bus, target, lun;
 
-    mb[0] = MBC_GET_TARGET_PARAMETERS;
-    mb[1] = (uint16_t)(b ? t | BIT_7 :t);
-    mb[1] <<= 8;
-    qla1280_mailbox_command(ha, BIT_6|BIT_3|BIT_2|BIT_1|BIT_0, &mb[0]);
-    if( mb[3] != 0 )
-    printk(KERN_INFO "scsi(%d:%d:%d:%d): Synchronous tranfer at period %d, offset %d. \n",
-        (int)ha->host_no, b, t, l, (mb[3] &0xff), (mb[3] >> 8));
+	bus = device->channel;
+	target = device->id;
+	lun = device->lun;
 
-    if ( (mb[2] & BIT_5) &&  ((mb[6] >> 8) & 0xff) >= 2 )
-            printk(KERN_INFO "scsi(%d:%d:%d:%d): Dual Transition enabled.\n",
-                          (int)ha->host_no, b, t, l);
-}
 
+	mb[0] = MBC_GET_TARGET_PARAMETERS;
+	mb[1] = (uint16_t) (bus ? target | BIT_7 : target);
+	mb[1] <<= 8;
+	qla1280_mailbox_command(ha, BIT_6 | BIT_3 | BIT_2 | BIT_1 | BIT_0,
+				&mb[0]);
 
-#ifdef QL_DEBUG_ROUTINES
-/****************************************************************************/
-/*                         Driver Debug Functions.                          */
-/****************************************************************************/
+	printk(KERN_INFO "scsi(%li:%d:%d:%d):", ha->host_no, bus, target, lun);
 
-/*
- *  Get byte from I/O port
- */
-STATIC uint8_t
-qla1280_getbyte(uint8_t *port)
-{
-    uint8_t ret;
+	if (mb[3] != 0) {
+		printk(" Sync: period %d, offset %d",
+		       (mb[3] & 0xff), (mb[3] >> 8));
+		if (mb[2] & BIT_13)
+			printk(", Wide");
+		if ((mb[2] & BIT_5) && ((mb[6] >> 8) & 0xff) >= 2)
+			printk(", DT");
+	} else
+		printk(" Async");
 
-#if MEMORY_MAPPED_IO
-    ret = *port;
-#else
-    ret = inb((int)port);
-#endif
-
-    if (ql_debug_print)
-    {
-        qla1280_print("qla1280_getbyte: address = ");
-        qla1280_output_number((uint32_t)port, 16);
-        qla1280_print(" data = 0x");
-        qla1280_output_number((uint32_t)ret, 16);
-        qla1280_print("\n\r");
-    }
-
-    return(ret);
+	if (DEV_SIMPLE_TAGS(device))
+		printk(", Tagged queuing: depth %d", device->queue_depth);
+	printk("\n");
 }
 
-/*
- *  Get word from I/O port
- */
-STATIC uint16_t
-qla1280_getword(uint16_t *port)
-{
-    uint16_t ret;
 
-#if MEMORY_MAPPED_IO
-    ret = *port;
-#else
-    ret = inw((int)port);
-#endif
-
-    if (ql_debug_print)
-    {
-        qla1280_print("qla1280_getword: address = ");
-        qla1280_output_number((uint32_t)port, 16);
-        qla1280_print(" data = 0x");
-        qla1280_output_number((uint32_t)ret, 16);
-        qla1280_print("\n\r");
-    }
-
-    return(ret);
-}
-
-/*
- *  Get double word from I/O port
- */
-STATIC uint32_t
-qla1280_getdword(uint32_t *port)
+#if DEBUG_QLA1280
+static void
+__qla1280_dump_buffer(char *b, int size)
 {
-    uint32_t ret;
+	int cnt;
+	u8 c;
 
-#if MEMORY_MAPPED_IO
-    ret = *port;
-#else
-    ret = inl((int)port);
-#endif
+	printk(KERN_DEBUG " 0   1   2   3   4   5   6   7   8   9   Ah  "
+	       "Bh  Ch  Dh  Eh  Fh\n");
+	printk(KERN_DEBUG "---------------------------------------------"
+	       "------------------\n");
 
-    if (ql_debug_print)
-    {
-        qla1280_print("qla1280_getdword: address = ");
-        qla1280_output_number((uint32_t)port, 16);
-        qla1280_print(" data = 0x");
-        qla1280_output_number((uint32_t)ret, 16);
-        qla1280_print("\n\r");
-    }
+	for (cnt = 0; cnt < size;) {
+		c = *b++;
 
-    return(ret);
-}
-
-/*
- *  Send byte to I/O port
- */
-STATIC void
-qla1280_putbyte(uint8_t *port, uint8_t data)
-{
-#if MEMORY_MAPPED_IO
-    *port = data;
-#else
-    outb(data, (int)port);
-#endif
-
-    if (ql_debug_print)
-    {
-        qla1280_print("qla1280_putbyte: address = ");
-        qla1280_output_number((uint32_t)port, 16);
-        qla1280_print(" data = 0x");
-        qla1280_output_number((uint32_t)data, 16);
-        qla1280_print("\n\r");
-    }
-}
-
-/*
- *  Send word to I/O port
- */
-STATIC void
-qla1280_putword(uint16_t *port, uint16_t data)
-{
-#if MEMORY_MAPPED_IO
-    *port = data;
-#else
-#ifdef _LINUX_IOPORTS
-    outw(data, (int)port);
-#else
-    outw((int)port, data);
-#endif
-#endif
-
-    if (ql_debug_print)
-    {
-        qla1280_print("qla1280_putword: address = ");
-        qla1280_output_number((uint32_t)port, 16);
-        qla1280_print(" data = 0x");
-        qla1280_output_number((uint32_t)data, 16);
-        qla1280_print("\n\r");
-    }
-}
-
-/*
- *  Send double word to I/O port
- */
-STATIC void
-qla1280_putdword(uint32_t *port, uint32_t data)
-{
-#if MEMORY_MAPPED_IO
-    *port = data;
-#else
-#ifdef _LINUX_IOPORTS
-    outl(data,(int)port);
-#else
-    outl((int)port, data);
-#endif
-#endif
-
-    if (ql_debug_print)
-    {
-        qla1280_print("qla1280_putdword: address = ");
-        qla1280_output_number((uint32_t)port, 16);
-        qla1280_print(" data = 0x");
-        qla1280_output_number((uint32_t)data, 16);
-        qla1280_print("\n\r");
-    }
-}
-
-/*
- * Dummy function to prevent warnings for
- * declared and unused debug functions
- */
-void
-qla1280_debug(void)
-{
-    qla1280_getbyte(0);
-    qla1280_getword(0);
-    qla1280_getdword(0);
-    qla1280_putbyte(0, 0);
-    qla1280_putword(0, 0);
-    qla1280_putdword(0, 0);
+		printk("0x%02x", c);
+		cnt++;
+		if (!(cnt % 16))
+			printk("\n");
+		else
+			printk(" ");
+	}
+	if (cnt % 16)
+		printk("\n");
 }
 
-/*
- *  Out character to COM2 port.
- *      PORT must be at standard address for COM2 = 0x2F8,
- *      or COM1 = 0x3F8
- */
-#define OUTB(addr,data)   outb((data),(addr))
-
-STATIC void
-qla1280_putc(uint8_t c)
-{
-#ifdef QL_DEBUG_CONSOLE
-    printk("%c", c);
-#else
-    int     com_addr              = 0x2f8;
-    int     hardware_flow_control = 1;
-    int     software_flow_control = 0;
-    uint8_t data;
-
-    /* Wait for transmitter holding and shift registers for empty. */
-    do
-    {
-        data = inb(com_addr+5);
-    }while (!(data & BIT_6));
-
-    /*
-    * Set BAUD rate for COM2 to 19200 (0x6)
-    */
-
-    /* Select rate divisor. */
-    OUTB(com_addr+3, 0x83); 
-
-    /* BAUD rate divisor LSB. */
-    OUTB(com_addr, 0xc);                    /* 0xC = 9600 baud */
-
-    /* BAUD rate divisor MSB. */
-    OUTB(com_addr+1, 0);
-
-    /* Set No parity, 8 bits, 1 stop bit and
-    select interrupt enable register. */
-    OUTB(com_addr+3, 3);
-
-    /* Disable interrupts. */
-    OUTB(com_addr+1, 0);
-
-    /* Set data terminal ready and request to send */
-    OUTB(com_addr+4,3);
-
-    if (hardware_flow_control)
-    {
-        /* Wait for clear-to-send and data-set-ready */
-        do
-        {
-            data = inb(com_addr+6) & (BIT_5 + BIT_4);
-        }while (data != (BIT_5 + BIT_4));
-    }
-    else if (software_flow_control)
-    {
-        /* Test for data ready. */
-        data = inb(com_addr+5);
-        if (data & BIT_0)
-        {
-            /* If XOFF */
-            data = inb(com_addr);
-            if (data == '\023')
-            {
-                /* Wait for XON */
-                do
-                {
-                    /* Wait for char */
-                    do
-                    {
-                        data = inb(com_addr+5);
-                    }while (!(data & BIT_0));
-                    data = inb(com_addr);
-                }while (data != '\021');
-            }
-        }
-    }
-
-    /* Output character. */
-    OUTB(com_addr, c);
-#endif
-}
-
-/*
- *  Out NULL terminated string to COM port.
- */
-STATIC void
-qla1280_print(caddr_t s)
-{
-    if (ql_debug_print)
-    {
-#ifdef QL_DEBUG_CONSOLE
-        printk("%s",s);
-#else
-        /* Output string. */
-        while (*s)
-            qla1280_putc(*s++);
-#endif
-    }
-}
-
-/*
- *  Output long number to COM port.
- */
-STATIC void
-qla1280_output_number(uint32_t n, uint8_t base)
-{
-    int8_t str[12];
-    int8_t *s     = &str[11];
-    int8_t output = 0;
-    int8_t hex    = FALSE;
-
-    if (ql_debug_print)
-    {
-        if (base == 10 || base == 16)
-        {
-            if (base == 16 && n > 9)
-                hex = TRUE;
-
-            *s = 0;
-            do
-            {
-                s--;
-                *s = n % base;
-                if (*s > 9)
-                    *s += 55;
-                else
-                    *s += '0';
-                n /= base;
-            }while (n);
-
-            for (; *s; s++)
-            {
-                if (*s != '0')
-                    output = 1;
-                if (output)
-                    qla1280_putc(*s);
-            }
-            if (!output)
-                qla1280_putc(*--s);
-
-            if (hex)
-                qla1280_putc('h');
-        }
-    }
-}
-
-STATIC void
-qla1280_dump_buffer(caddr_t b, uint32_t size)
-{
-    uint32_t cnt;
-    uint8_t c;
-
-    if (ql_debug_print)
-    {
-        qla1280_print(
-                " 0   1   2   3   4   5   6   7   8   9   Ah  Bh  Ch  Dh  Eh  Fh\n\r");
-        qla1280_print(
-                "---------------------------------------------------------------\n\r");
-
-        for (cnt = 0; cnt < size; )
-        {
-            c = *b++;
-            if (c < 16)
-                qla1280_putc(' ');
-            qla1280_output_number((uint32_t)c, 16);
-            cnt++;
-            if (!(cnt % 16))
-                qla1280_print("\n\r");
-            else if (c < 10)
-                qla1280_print("  ");
-            else
-                qla1280_putc(' ');
-        }
-        if (cnt % 16)
-            qla1280_print("\n\r");
-    }
-}
 /**************************************************************************
  *   ql1280_print_scsi_cmd
  *
  **************************************************************************/
-void qla1280_print_scsi_cmd(Scsi_Cmnd *cmd)
+static void
+__qla1280_print_scsi_cmd(Scsi_Cmnd * cmd)
 {
-    scsi_qla_host_t *ha;
-    struct Scsi_Host  *host = cmd->host;
-    srb_t           *sp;
-   /* struct scatterlist *sg; */
-
-    int i;
-    ha = (scsi_qla_host_t *) host->hostdata;
-
-    ql_debug_print = 1;
-    sp = (srb_t *) CMD_SP(cmd);
-    sprintf(debug_buff,"SCSI Command @= 0x%p, Handle=0x%p\n\r", cmd, CMD_HANDLE(cmd));
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"  chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n\r",
-            cmd->channel, cmd->target, cmd->lun, cmd->cmd_len);
-    qla1280_print(debug_buff);
-    qla1280_print(" CDB = ");
-    for (i = 0; i < cmd->cmd_len; i++)
-    {
-        sprintf(debug_buff,"0x%02x ", cmd->cmnd[i]);
-        qla1280_print(debug_buff);
-    }
-    sprintf(debug_buff,"  seg_cnt =%d\n\r",cmd->use_sg);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"  request buffer=0x%p, request buffer len=0x%x\n\r",cmd->request_buffer,cmd->request_bufflen);
-    qla1280_print(debug_buff);
-    /* if( cmd->use_sg )
-    {
-       sg = (struct scatterlist *) cmd->request_buffer;
-       qla1280_print("  SG buffer: \n\r");
-       qla1280_dump_buffer((caddr_t)sg, (cmd->use_sg*sizeof(struct scatterlist)) );
-    } */
-    sprintf(debug_buff,"  tag=%d, flags=0x%x, transfersize=0x%x \n\r", 
-            cmd->tag, cmd->flags,cmd->transfersize );
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"  Pid=%d, SP=0x%p\n\r", (int)cmd->pid, CMD_SP(cmd));
-    qla1280_print(debug_buff);
-    sprintf(debug_buff,"  r_start=0x%lx, u_start=0x%lx\n\r",sp->r_start,sp->u_start);
-    qla1280_print(debug_buff);
-    sprintf(debug_buff," underflow size = 0x%x, direction=0x%x, req.cmd=0x%x \n\r", cmd->underflow, sp->dir,cmd->request.cmd);    
-    qla1280_print(debug_buff);
+	struct scsi_qla_host *ha;
+	struct Scsi_Host *host = CMD_HOST(cmd);
+	struct srb *sp;
+	/* struct scatterlist *sg; */
+
+	int i;
+	ha = (struct scsi_qla_host *)host->hostdata;
+
+	sp = (struct srb *)CMD_SP(cmd);
+	printk("SCSI Command @= 0x%p, Handle=0x%p\n", cmd, CMD_HANDLE(cmd));
+	printk("  chan=%d, target = 0x%02x, lun = 0x%02x, cmd_len = 0x%02x\n",
+	       SCSI_BUS_32(cmd), SCSI_TCN_32(cmd), SCSI_LUN_32(cmd),
+	       CMD_CDBLEN(cmd));
+	printk(" CDB = ");
+	for (i = 0; i < cmd->cmd_len; i++) {
+		printk("0x%02x ", cmd->cmnd[i]);
+	}
+	printk("  seg_cnt =%d\n", cmd->use_sg);
+	printk("  request buffer=0x%p, request buffer len=0x%x\n",
+	       cmd->request_buffer, cmd->request_bufflen);
+	/* if (cmd->use_sg)
+	   {
+	   sg = (struct scatterlist *) cmd->request_buffer;
+	   printk("  SG buffer: \n");
+	   qla1280_dump_buffer(1, (char *)sg, (cmd->use_sg*sizeof(struct scatterlist)));
+	   } */
+	printk("  tag=%d, flags=0x%x, transfersize=0x%x \n",
+	       cmd->tag, cmd->flags, cmd->transfersize);
+	printk("  Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd));
+	printk(" underflow size = 0x%x, direction=0x%x\n",
+	       cmd->underflow, sp->dir);
 }
+
 /**************************************************************************
  *   ql1280_dump_device
  *
  **************************************************************************/
-void
-ql1280_dump_device(scsi_qla_host_t *ha)
+static void
+ql1280_dump_device(struct scsi_qla_host *ha)
 {
 
-    Scsi_Cmnd       *cp;
-    srb_t           *sp;
-    int i;
-    qla1280_print("Outstanding Commands on controller:\n\r");   
-    for ( i=0; i < MAX_OUTSTANDING_COMMANDS; i++ )
-    {
-        if( (sp = ha->outstanding_cmds[i]) == NULL )
-            continue;
-        if( (cp = sp->cmd) == NULL )
-            continue;
-        qla1280_print_scsi_cmd(cp);
-    }
+	Scsi_Cmnd *cp;
+	struct srb *sp;
+	int i;
 
-}
-#endif
+	printk(KERN_DEBUG "Outstanding Commands on controller:\n");
 
-#ifdef  QLA1280_UNUSED 
-/**************************************************************************
- *   ql1280_dump_regs
- *
- **************************************************************************/
-static void qla1280_dump_regs(struct Scsi_Host *host)
-{
-    printk("Mailbox registers:\n");
-    printk("qla1280 : mbox 0 0x%04x \n", inw(host->io_port + 0x70));
-    printk("qla1280 : mbox 1 0x%04x \n", inw(host->io_port + 0x72));
-    printk("qla1280 : mbox 2 0x%04x \n", inw(host->io_port + 0x74));
-    printk("qla1280 : mbox 3 0x%04x \n", inw(host->io_port + 0x76));
-    printk("qla1280 : mbox 4 0x%04x \n", inw(host->io_port + 0x78));
-    printk("qla1280 : mbox 5 0x%04x \n", inw(host->io_port + 0x7a));
+	for (i = 0; i < MAX_OUTSTANDING_COMMANDS; i++) {
+		if ((sp = ha->outstanding_cmds[i]) == NULL)
+			continue;
+		if ((cp = sp->cmd) == NULL)
+			continue;
+		qla1280_print_scsi_cmd(1, cp);
+	}
 }
 #endif
 
 
+enum tokens {
+	TOKEN_NVRAM,
+	TOKEN_SYNC,
+	TOKEN_WIDE,
+	TOKEN_PPR,
+	TOKEN_VERBOSE,
+	TOKEN_DEBUG,
+};
+
+struct setup_tokens {
+	char *token;
+	int val;
+};
+
+static struct setup_tokens setup_token[] __initdata = 
+{
+	{ "nvram", TOKEN_NVRAM },
+	{ "sync", TOKEN_SYNC },
+	{ "wide", TOKEN_WIDE },
+	{ "ppr", TOKEN_PPR },
+	{ "verbose", TOKEN_VERBOSE },
+	{ "debug", TOKEN_DEBUG },
+};
+
 
-#if  STOP_ON_ERROR 
 /**************************************************************************
- *   ql1280_panic
+ *   qla1280_setup
  *
+ *   Handle boot parameters. This really needs to be changed so one
+ *   can specify per adapter parameters.
  **************************************************************************/
-static void qla1280_panic(char *cp, struct Scsi_Host *host)
+static int __init
+qla1280_setup(char *s)
 {
-    scsi_qla_host_t *ha;
-    long  *fp;
+	char *cp, *ptr;
+	unsigned long val;
+	int toke;
+
+	cp = s;
+
+	while (cp && (ptr = strchr(cp, ':'))) {
+		ptr++;
+		if (!strcmp(ptr, "yes")) {
+			val = 0x10000;
+			ptr += 3;
+		} else if (!strcmp(ptr, "no")) {
+ 			val = 0;
+			ptr += 2;
+		} else
+			val = simple_strtoul(ptr, &ptr, 0);
+
+		switch ((toke = qla1280_get_token(cp))) {
+		case TOKEN_NVRAM:
+			if (!val)
+				driver_setup.no_nvram = 1;
+			break;
+		case TOKEN_SYNC:
+			if (!val)
+				driver_setup.no_sync = 1;
+			else if (val != 0x10000)
+				driver_setup.sync_mask = val;
+			break;
+		case TOKEN_WIDE:
+			if (!val)
+				driver_setup.no_wide = 1;
+			else if (val != 0x10000)
+				driver_setup.wide_mask = val;
+			break;
+		case TOKEN_PPR:
+			if (!val)
+				driver_setup.no_ppr = 1;
+			else if (val != 0x10000)
+				driver_setup.ppr_mask = val;
+			break;
+		case TOKEN_VERBOSE:
+			qla1280_verbose = val;
+			break;
+		default:
+			printk(KERN_INFO "qla1280: unknown boot option %s\n",
+			       cp);
+		}
 
-    ha = (scsi_qla_host_t *) host->hostdata;
-    printk("qla1280 - PANIC:  %s\n",cp);
-    printk("Current time=0x%lx\n", jiffies);
-    printk("Number of pending commands =0x%lx\n", ha->actthreads);
-    printk("Number of SCSI queued commands =0x%lx\n", ha->qthreads);
-    printk("Number of free entries = (%d)\n",ha->req_q_cnt);
-    printk("Request Queue @ 0x%lx, Response Queue @ 0x%lx\n",
-                        ha->request_dma,
-                        ha->response_dma);
-    printk("Request In Ptr %d\n", ha->req_ring_index );
-    fp = (long *) &ha->flags;
-    printk("HA flags =0x%lx\n", *fp);
-    DEBUG2(ql_debug_print = 1;)
-    /* DEBUG2(ql1280_dump_device((scsi_qla_host_t *) host->hostdata)); */
-#ifdef  QLA1280_UNUSED 
-    qla1280_dump_regs(host);
-#endif
-    sti();  
-    panic("Ooops");  
-    /* cli(); 
-    for(;;)
-    { 
-        barrier();
-    sti();  
-    }
-    */
+		cp = strchr(ptr, ';');
+		if (cp)
+			cp++;
+		else {
+			break;
+		}
+	}
+	return 1;
 }
-#endif
 
-#ifdef  QLA1280_UNUSED 
-static void qla1280_set_flags(char * s)
+
+static int
+qla1280_get_token(char *str)
 {
+	char *sep;
+	long ret = -1;
+	int i, len;
+
+	len = sizeof(setup_token)/sizeof(struct setup_tokens);
+
+	sep = strchr(str, ':');
+
+	if (sep) {
+		for (i = 0; i < len; i++){
+
+			if (!strncmp(setup_token[i].token, str, (sep - str))) {
+				ret =  setup_token[i].val;
+				break;
+			}
+		}
+	}
+
+	return ret;
 }
+
+
+static Scsi_Host_Template driver_template = {
+	.proc_info		= qla1280_proc_info,
+	.name			= "Qlogic ISP 1280/12160",
+	.detect			= qla1280_detect,
+	.release		= qla1280_release,
+	.info			= qla1280_info,
+	.queuecommand		= qla1280_queuecommand,
+#if LINUX_VERSION_CODE >= 0x020545
+	.slave_configure	= qla1280_slave_configure,
+#endif
+	.eh_abort_handler	= qla1280_eh_abort,
+	.eh_device_reset_handler= qla1280_eh_device_reset,
+	.eh_bus_reset_handler	= qla1280_eh_bus_reset,
+	.eh_host_reset_handler	= qla1280_eh_adapter_reset,
+	.bios_param		= qla1280_biosparam,
+	.can_queue		= 255,
+	.this_id		= -1,
+	.sg_tablesize		= SG_ALL,
+	.cmd_per_lun		= 3,
+	.use_clustering		= ENABLE_CLUSTERING,
+#if LINUX_VERSION_CODE < 0x020545
+	.use_new_eh_code	= 1,
 #endif
+};
 
-/**************************************************************************
- *   qla1280_setup
- *
- *   Handle Linux boot parameters. This routine allows for assigning a value
- *   to a parameter with a ':' between the parameter and the value.
- *   ie. qla1280=max_reqs:0x0A,verbose
- **************************************************************************/
-void
-qla1280_setup(char *s, int *dummy)
-{
-    char *end, *str, *cp;
+#include "scsi_module.c"
 
-#ifdef  QLA1280_UNUSED 
-    static struct
-    {
-        const char *name;
-        int      siz;
-        void  (*func)();
-        int   arg;
-    } options[] =
-    {
-        { "dump_regs", 9,  &qla1280_dump_regs, 0 
-        },
-        { "verbose", 7, &qla1280_set_flags, 0x1 
-        },
-        { "",    0, NULL, 0 
-        }
-    };
-#endif
-
-    printk("scsi: Processing Option str = %s\n", s);
-    end = strchr(s, '\0');
-    /* locate command */
-    str = s;
-    for( cp = s; *cp && cp != end; cp++ ) 
-    {
-       cp = qla1280_get_token(cp, str);
-       printk("scsi: token str = %s\n", str);
-       /* if found execute routine */
-
-    }
-    
-}
-
-static char	*qla1280_get_token(char *cmdline, char *str )
-{
-    register	char 	*cp = cmdline;
-
-        /* skip preceeding spaces */
-        while(strchr(cp,' '))
-            ++cp;
-        /* symbol starts here */
-        str = cp;
-        /* skip char if not a space or : */
-        while (*cp && !( strchr(cp,' ') || strchr(cp,':'))  )
-            cp++;
-        *cp = '\0';
-        return( cp );
-}
-MODULE_LICENSE("GPL");
 
 /*
  * Overrides for Emacs so that we almost follow Linus's tabbing style.
@@ -6821,15 +5164,7 @@
  * of the file.
  * ---------------------------------------------------------------------------
  * Local variables:
- * c-indent-level: 2
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -2
- * c-argdecl-indent: 2
- * c-label-offset: -2
- * c-continued-statement-offset: 2
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
+ * c-basic-offset: 8
  * tab-width: 8
  * End:
  */
-
diff -urN linux-2.4.23-pre6/drivers/scsi/qla1280.h linux-2.4.23-pre7/drivers/scsi/qla1280.h
--- linux-2.4.23-pre6/drivers/scsi/qla1280.h	2001-09-17 13:16:31.000000000 -0700
+++ linux-2.4.23-pre7/drivers/scsi/qla1280.h	2003-10-09 17:48:22.000000000 -0700
@@ -1,1447 +1,963 @@
-/*************************************************************************
- *                  QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP1x80/1x160 device driver for Linux 2.3.x (redhat 6.x).
- *
- * COPYRIGHT (C) 1996-2000 QLOGIC CORPORATION    
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the Qlogic's Linux Software License.
- *
- * This program is WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistribution's or source code must retain the above copyright
- *    notice, this list of conditions, and the following disclaimer,
- *    without modification, immediately at the beginning of the file.
- * 2. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- *****************************************************************************/
- 
-/*************************************************************************************
-			QLOGIC CORPORATION SOFTWARE
-           "GNU" GENERAL PUBLIC LICENSE
-    TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION
-                 AND MODIFICATION
-
-This GNU General Public License ("License") applies solely to QLogic Linux 
-Software ("Software") and may be distributed under the terms of this License.  
- 
-1. You may copy and distribute verbatim copies of the Software's source code as 
-you receive it, in any medium, provided that you conspicuously and appropriately 
-publish on each copy an appropriate copyright notice and disclaimer of warranty;
-keep intact all the notices that refer to this License and to the absence of any
-warranty; and give any other recipients of the Software a copy of this License along
-with the Software. 
-
-You may charge a fee for the physical act of transferring a copy, and you may at your
-option offer warranty protection in exchange for a fee.
- 
-2. You may modify your copy or copies of the Software or any portion of it, thus forming
-a work based on the Software, and copy and distribute such modifications or work under
-the terms of Section 1 above, provided that you also meet all of these conditions:
- 
-* a) You must cause the modified files to carry prominent notices stating that you
-changed the files and the date of any change. 
-
-* b) You must cause any work that you distribute or publish that in whole or in part
-contains or is derived from the Software or any part thereof, to be licensed as a
-whole at no charge to all third parties under the terms of this License. 
-
-* c) If the modified Software normally reads commands interactively when run, you
-must cause it, when started running for such interactive use in the most ordinary way,
-to print or display an announcement including an appropriate copyright notice and a 
-notice that there is no warranty (or else, saying that you provide a warranty) and that
-users may redistribute the Software under these conditions, and telling the user how to
-view a copy of this License. (Exception:if the Software itself is interactive but does 
-not normally print such an announcement, your work based on the Software is not required
-to print an announcement.) 
-
-These requirements apply to the modified work as a whole. If identifiable sections of
-that work are not derived from the Software, and can be reasonably considered independent
-and separate works in themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works. But when you distribute the same
-sections as part of a whole which is a work based on the Software, the distribution of the
-whole must be on the terms of this License, whose permissions for other licensees extend
-to the entire whole, and thus to each and every part regardless of who wrote it. 
-
-3. You may copy and distribute the Software (or a work based on it, under Section 2) in 
-object code or executable form under the terms of Sections 1 and 2 above provided that
-you also do one of the following: 
-
-* a) Accompany it with the complete corresponding machine-readable source code, which must
-be distributed under the terms of Sections 1 and 2 above on a medium customarily used for
-software interchange; or, 
-
-* b) Accompany it with a written offer, valid for at least three years, to give any third
-party, for a charge no more than your cost of physically performing source distribution,
-a complete machine-readable copy of the corresponding source code, to be distributed under
-the terms of Sections 1 and 2 above on a medium customarily used for software interchange;
-or,
-
-* c) Accompany it with the information you received as to the offer to distribute 
-corresponding source code. (This alternative is allowed only for noncommercial distribution
-and only if you received the Software in object code or executable form with such an offer,
-in accord with Subsection b above.) 
-
-The source code for a work means the preferred form of the work for making modifications
-to it. For an executable work, complete source code means all the source code for all 
-modules it contains, plus any associated interface definition files, plus the scripts used
-to control compilation and installation of the executable.     
-
-If distribution of executable or object code is made by offering access to copy from a 
-designated place, then offering equivalent access to copy the source code from the same
-place counts as distribution of the source code, even though third parties are not 
-compelled to copy the source along with the object code. 
-
-4. You may not copy, modify, sublicense, or distribute the Software except as expressly 
-provided under this License. Any attempt otherwise to copy, modify, sublicense or 
-distribute the Software is void, and will automatically terminate your rights under this
-License. However, parties who have received copies, or rights, from you under this License
-will not have their licenses terminated so long as such parties remain in full compliance. 
-
-5. This license grants you world wide, royalty free non-exclusive rights to modify or 
-distribute the Software or its derivative works. These actions are prohibited by law 
-if you do not accept this License. Therefore, by modifying or distributing the Software
-(or any work based on the Software), you indicate your acceptance of this License to do
-so, and all its terms and conditions for copying, distributing or modifying the Software
-or works based on it.
- 
-6. Each time you redistribute the Software (or any work based on the Software), the 
-recipient automatically receives a license from the original licensor to copy, distribute
-or modify the Software subject to these terms and conditions. You may not impose any 
-further restrictions on the recipients' exercise of the rights granted herein. You are
-not responsible for enforcing compliance by third parties to this License.
- 
-7. If, as a consequence of a court judgment or allegation of patent infringement or for
-any other reason (not limited to patent issues), conditions are imposed on you 
-(whether by court order, agreement or otherwise) that contradict the conditions of this
-License, they do not excuse you from the conditions of this License. If you cannot 
-distribute so as to satisfy simultaneously your obligations under this License 
-and any other pertinent obligations, then as a consequence you may not distribute the
-Software at all.    
-
-If any portion of this section is held invalid or unenforceable under any particular 
-circumstance, the balance of the section is intended to apply and the section as a whole
-is intended to apply in other circumstances. 
-NO WARRANTY
-
-11. THE SOFTWARE IS PROVIDED WITHOUT A WARRANTY OF ANY KIND. THERE IS NO 
-WARRANTY FOR THE SOFTWARE, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 
-OTHER PARTIES PROVIDE THE SOFTWARE "AS IS" WITHOUT WARRANTY OF ANY KIND, 
-EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE 
-ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE SOFTWARE IS WITH YOU. 
-SHOULD THE SOFTWARE PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL 
-NECESSARY SERVICING, REPAIR OR CORRECTION.
- 
-12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 
-REDISTRIBUTE THE SOFTWARE AS PERMITTED ABOVE, BE LIABLE TO YOU FOR 
-DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL 
-DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE SOFTWARE (INCLUDING 
-BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR 
-LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE SOFTWARE TO 
-OPERATE WITH ANY OTHER SOFTWARES), EVEN IF SUCH HOLDER OR OTHER PARTY HAS 
-BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 
-END OF TERMS AND CONDITIONS 
-
-*************************************************************************************/ 
-
- 
-#ifndef _IO_HBA_QLA1280_H           /* wrapper symbol for kernel use */
-#define _IO_HBA_QLA1280_H           /* subject to change without notice */
+/******************************************************************************
+*                  QLOGIC LINUX SOFTWARE
+*
+* QLogic ISP1280 (Ultra2) /12160 (Ultra3) SCSI driver
+* Copyright (C) 2000 Qlogic Corporation
+* (www.qlogic.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, 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.
+*
+******************************************************************************/
 
-#if defined(__cplusplus)
-extern "C" {
-#endif
+#ifndef	_IO_HBA_QLA1280_H	/* wrapper symbol for kernel use */
+#define	_IO_HBA_QLA1280_H	/* subject to change without notice */
 
-#include <linux/version.h>
-
-/*
- * Enable define statement to ignore Data Underrun Errors,
- * remove define statement to enable detection.
- */
-/* #define  DATA_UNDERRUN_ERROR_DISABLE */
-
-/*
- * Driver debug definitions.
- */
-/* #define QL_DEBUG_LEVEL_1 */       /* Output register accesses to COM2. */
-/* #define QL_DEBUG_LEVEL_2 */           /* Output error msgs to COM2. */
-/* #define QL_DEBUG_LEVEL_3 */          /* Output function trace msgs to COM2. */
-/* #define QL_DEBUG_LEVEL_4 */       /* Output NVRAM trace msgs to COM2. */
-/* #define QL_DEBUG_LEVEL_5 */         /* Output ring trace msgs to COM2. */
-/* #define QL_DEBUG_LEVEL_6 */      /* Output WATCHDOG timer trace to COM2. */
-/* #define QL_DEBUG_LEVEL_7 */      /* Output RISC load trace msgs to COM2. */
-
-#define QL_DEBUG_CONSOLE              /* Output to console instead of COM2. */
-
-#ifndef TRUE
-#  define TRUE 1
-#endif
-#ifndef FALSE
-#  define FALSE 0
-#endif
-
-
-#ifndef KERNEL_VERSION
-#  define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
-#endif
-
-#if LINUX_VERSION_CODE <= KERNEL_VERSION(2,1,92)
-#  if defined(__sparc_v9__) || defined(__powerpc__)
-#    error "PPC and Sparc platforms are only support under 2.1.92 and above"
-#  endif
-#endif
-
-
-/* 
- * Locking
- */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
-#  include <linux/spinlock.h>
-#  include <linux/smp.h>
-#  define cpuid smp_processor_id()
-#  if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-#    define DRIVER_LOCK_INIT \
-       spin_lock_init(&ha->spin_lock);
-#    define DRIVER_LOCK \
-       if(!ha->cpu_lock_count[cpuid]) { \
-         spin_lock_irqsave(&ha->spin_lock, cpu_flags); \
-         ha->cpu_lock_count[cpuid]++; \
-       } else { \
-         ha->cpu_lock_count[cpuid]++; \
-       }
-#    define DRIVER_UNLOCK \
-       if(--ha->cpu_lock_count[cpuid] == 0) \
-         spin_unlock_irqrestore(&ha->spin_lock, cpu_flags);
-#  else
-#    define DRIVER_LOCK_INIT
-#    define DRIVER_LOCK
-#    define DRIVER_UNLOCK
-#  endif 
-#else
-#  define cpuid 0
-#  define DRIVER_LOCK_INIT
-#  define DRIVER_LOCK \
-       save_flags(cpu_flags); \
-       cli();
-#  define DRIVER_UNLOCK \
-       restore_flags(cpu_flags);
-#  define le32_to_cpu(x) (x)
-#  define cpu_to_le32(x) (x)
-#endif
+#ifndef HOSTS_C			/* included in hosts.c */
 
 /*
  * Data bit definitions.
  */
-#define BIT_0   0x1
-#define BIT_1   0x2
-#define BIT_2   0x4
-#define BIT_3   0x8
-#define BIT_4   0x10
-#define BIT_5   0x20
-#define BIT_6   0x40
-#define BIT_7   0x80
-#define BIT_8   0x100
-#define BIT_9   0x200
-#define BIT_10  0x400
-#define BIT_11  0x800
-#define BIT_12  0x1000
-#define BIT_13  0x2000
-#define BIT_14  0x4000
-#define BIT_15  0x8000
-#define BIT_16  0x10000
-#define BIT_17  0x20000
-#define BIT_18  0x40000
-#define BIT_19  0x80000
-#define BIT_20  0x100000
-#define BIT_21  0x200000
-#define BIT_22  0x400000
-#define BIT_23  0x800000
-#define BIT_24  0x1000000
-#define BIT_25  0x2000000
-#define BIT_26  0x4000000
-#define BIT_27  0x8000000
-#define BIT_28  0x10000000
-#define BIT_29  0x20000000
-#define BIT_30  0x40000000
-#define BIT_31  0x80000000
-
-/*
- * Common size type definitions
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
-typedef unsigned char  uint8_t; 
-typedef unsigned short uint16_t; 
-typedef unsigned long  uint32_t; 
-typedef char  int8_t; 
-typedef short int16_t; 
-typedef long  int32_t; 
-#endif
-
-/*
- *  Local Macro Definitions.
- */
-#if defined(QL_DEBUG_LEVEL_1) || defined(QL_DEBUG_LEVEL_2) || \
-    defined(QL_DEBUG_LEVEL_3) || defined(QL_DEBUG_LEVEL_4) || \
-    defined(QL_DEBUG_LEVEL_5) || defined(QL_DEBUG_LEVEL_6) || \
-    defined(QL_DEBUG_LEVEL_7)
-    #define QL_DEBUG_ROUTINES
-#endif
-
-/*
- * I/O port macros
-*/
-#define LINUX_IOPORTS                     /* Linux in/out routines are define*/
-                                          /* differently from other OSs      */
-/* #define MEMORY_MAPPED_IO */            /* Enable memory mapped I/O */
-#undef MEMORY_MAPPED_IO            /* Disable memory mapped I/O */
-
-#ifdef QL_DEBUG_LEVEL_1
-#define RD_REG_BYTE(addr)         qla1280_getbyte((uint8_t *)addr)
-#define RD_REG_WORD(addr)         qla1280_getword((uint16_t *)addr)
-#define RD_REG_DWORD(addr)        qla1280_getdword((uint32_t *)addr)
-#define WRT_REG_BYTE(addr, data)  qla1280_putbyte((uint8_t *)addr, data)
-#define WRT_REG_WORD(addr, data)  qla1280_putword((uint16_t *)addr, data)
-#define WRT_REG_DWORD(addr, data) qla1280_putdword((uint32_t *)addr, data)
-#else  /* QL_DEBUG_LEVEL_1 */
-#ifdef MEMORY_MAPPED_IO
-       #define RD_REG_BYTE(addr)         readb((unsigned long) (addr)
-       #define RD_REG_WORD(addr)         readw((unsigned long) (addr)
-       #define RD_REG_DWORD(addr)        readl((unsigned long) (addr)
-       #define WRT_REG_BYTE(addr, data)  writeb((data), (unsigned long) (addr))
-       #define WRT_REG_WORD(addr, data)  writew((data), (unsigned long) (addr))
-       #define WRT_REG_DWORD(addr, data) writel((data), (unsigned long) (addr))
-#else   /* MEMORY_MAPPED_IO */
-#define RD_REG_BYTE(addr)         (inb((unsigned long)addr))
-#define RD_REG_WORD(addr)         (inw((unsigned long)addr))
-#define RD_REG_DWORD(addr)        (inl((unsigned long)addr))
-#ifdef LINUX_IOPORTS
-/* Parameters are reversed in Linux */
-#define WRT_REG_BYTE(addr, data)  (outb(data,(unsigned long)addr))
-#define WRT_REG_WORD(addr, data)  (outw(data,(unsigned long)addr))
-#define WRT_REG_DWORD(addr, data) (outl(data,(unsigned long)addr))
-#else
-#define WRT_REG_BYTE(addr, data)  (outb((unsigned long)addr, data))
-#define WRT_REG_WORD(addr, data)  (outw((unsigned long)addr, data))
-#define WRT_REG_DWORD(addr, data) (outl((unsigned long)addr, data))
-#endif
-#endif  /* MEMORY_MAPPED_IO */
-#endif    /* QL_DEBUG_LEVEL_1 */
+#define BIT_0	0x1
+#define BIT_1	0x2
+#define BIT_2	0x4
+#define BIT_3	0x8
+#define BIT_4	0x10
+#define BIT_5	0x20
+#define BIT_6	0x40
+#define BIT_7	0x80
+#define BIT_8	0x100
+#define BIT_9	0x200
+#define BIT_10	0x400
+#define BIT_11	0x800
+#define BIT_12	0x1000
+#define BIT_13	0x2000
+#define BIT_14	0x4000
+#define BIT_15	0x8000
+#define BIT_16	0x10000
+#define BIT_17	0x20000
+#define BIT_18	0x40000
+#define BIT_19	0x80000
+#define BIT_20	0x100000
+#define BIT_21	0x200000
+#define BIT_22	0x400000
+#define BIT_23	0x800000
+#define BIT_24	0x1000000
+#define BIT_25	0x2000000
+#define BIT_26	0x4000000
+#define BIT_27	0x8000000
+#define BIT_28	0x10000000
+#define BIT_29	0x20000000
+#define BIT_30	0x40000000
+#define BIT_31	0x80000000
+
+#if MEMORY_MAPPED_IO
+#define RD_REG_WORD(addr)		readw(addr)
+#define WRT_REG_WORD(addr, data)	writew(data, addr)
+#else				/* MEMORY_MAPPED_IO */
+#define RD_REG_WORD(addr)		inw((unsigned long)addr)
+#define WRT_REG_WORD(addr, data)	outw(data, (unsigned long)addr)
+#endif				/* MEMORY_MAPPED_IO */
 
 /*
  * Host adapter default definitions.
  */
-#define MAX_BUSES       2             /* 2 */
-#define MAX_B_BITS      1
+#define MAX_BUSES	2	/* 2 */
+#define MAX_B_BITS	1
 
-#define MAX_TARGETS     16             /* 16 */
-#define MAX_T_BITS      4              /* 4 */
+#define MAX_TARGETS	16	/* 16 */
+#define MAX_T_BITS	4	/* 4 */
 
-#define MAX_LUNS        8              /* 32 */
-#define MAX_L_BITS      3               /* 5 */
+#define MAX_LUNS	8	/* 32 */
+#define MAX_L_BITS	3	/* 5 */
 
 /*
  * Watchdog time quantum
  */
-#define QLA1280_WDG_TIME_QUANTUM   5    /* In seconds */
+#define QLA1280_WDG_TIME_QUANTUM	5	/* In seconds */
 
 /* Command retry count (0-65535) */
-#define COMMAND_RETRY_COUNT   255
+#define COMMAND_RETRY_COUNT		255
 
-/* Maximum outstanding commands in ISP queues (1-65535) */
-#define MAX_OUTSTANDING_COMMANDS   512
+/* Maximum outstanding commands in ISP queues */
+#define MAX_OUTSTANDING_COMMANDS	512
+#define INVALID_HANDLE			(MAX_OUTSTANDING_COMMANDS + 2)
 
 /* ISP request and response entry counts (37-65535) */
-#define REQUEST_ENTRY_CNT       256     /* Number of request entries. */
-#define RESPONSE_ENTRY_CNT      16      /* Number of response entries. */
-
-/* Maximum equipage per controller */
-#define MAX_EQ          (MAX_BUSES * MAX_TARGETS * MAX_LUNS)
+#define REQUEST_ENTRY_CNT		256 /* Number of request entries. */
+#define RESPONSE_ENTRY_CNT		16  /* Number of response entries. */
 
 /* Number of segments 1 - 65535 */
-#define SG_SEGMENTS     32             /* Cmd entry + 6 continuations */
-
+#define SG_SEGMENTS			32  /* Cmd entry + 6 continuations */
 
 /*
- * SCSI Request Block structure
+ * SCSI Request Block structure  (sp)  that is placed
+ * on cmd->SCp location of every I/O
  */
-typedef struct srb
-{
-    Scsi_Cmnd  *cmd;                 /* (4) SCSI command block */
-    struct srb  *s_next;             /* (4) Next block on LU queue */
-    struct srb  *s_prev;             /* (4) Previous block on LU queue */
-    uint8_t     flags;               /* (1) Status flags. */
-    uint8_t     dir;                 /* direction of transfer */
-    uint8_t     unused[2];
-    u_long      r_start;             /* jiffies at start of request */
-    u_long      u_start;             /* jiffies when sent to F/W    */
-}srb_t;
+struct srb {
+	Scsi_Cmnd *cmd;		/* (4/8) SCSI command block */
+	struct srb *s_next;	/* (4/8) Next block on LU queue */
+	struct srb *s_prev;	/* (4/8) Previous block on LU queue */
+	uint8_t flags;		/* (1) Status flags. */
+	uint8_t dir;		/* direction of transfer */
+	/*
+	 * This should be moved around to save space.
+	 */
+	dma_addr_t saved_dma_handle;	/* for unmap of single transfers */
+	/* NOTE: the sp->cmd will be NULL when this completion is
+	 * called, so you should know the scsi_cmnd when using this */
+	struct completion *wait;
+};
 
 /*
  * SRB flag definitions
  */
-#define SRB_TIMEOUT     BIT_0           /* Command timed out */
-#define SRB_SENT        BIT_1           /* Command sent to ISP */
-#define SRB_ABORT_PENDING     BIT_2     /* Command abort sent to device */
-#define SRB_ABORTED     BIT_3           /* Command aborted command already */
-
+#define SRB_TIMEOUT		BIT_0	/* Command timed out */
+#define SRB_SENT		BIT_1	/* Command sent to ISP */
+#define SRB_ABORT_PENDING	BIT_2	/* Command abort sent to device */
+#define SRB_ABORTED		BIT_3	/* Command aborted command already */
 
 /*
  * Logical Unit Queue structure
  */
-typedef struct scsi_lu
-{
-    srb_t           *q_first;           /* First block on LU queue */
-    srb_t           *q_last;            /* Last block on LU queue */
-    uint8_t         q_flag;             /* LU queue state flags */
-    uint8_t         q_sense[16];        /* sense data */
-    u_long          io_cnt;             /* total xfer count */
-    u_long          resp_time;          /* total response time (start - finish) */
-    u_long          act_time;           /* total actived time (minus queuing time) */
-    u_long          w_cnt;              /* total writes */
-    u_long          r_cnt;              /* total reads */
-    uint16_t        q_outcnt;           /* Pending jobs for this LU */
-#if QL1280_TARGET_MODE_SUPPORT
-    void            (*q_func)();        /* Target driver event handler */
-    int32_t         q_param;            /* Target driver event param */
-    uint8_t         q_lock;            /* Device Queue Lock */
-#endif
-}scsi_lu_t;
-
-/*
- * Logical Unit flags 
- */
-#define QLA1280_QBUSY   BIT_0
-#define QLA1280_QWAIT   BIT_1
-#define QLA1280_QSUSP   BIT_2
-#define QLA1280_QSENSE  BIT_3           /* Sense data cache valid */
-#define QLA1280_QRESET  BIT_4
-#define QLA1280_QHBA    BIT_5
-#define QLA1280_BSUSP   BIT_6           /* controller is suspended */
-#define QLA1280_BREM    BIT_7           /* controller is removed */
-
-/*
- *  ISP PCI Configuration Register Set
- */
-typedef volatile struct
-{
-    uint16_t vendor_id;                 /* 0x0 */
-    uint16_t device_id;                 /* 0x2 */
-    uint16_t command;                   /* 0x4 */
-    uint16_t status;                    /* 0x6 */
-    uint8_t revision_id;                /* 0x8 */
-    uint8_t programming_interface;      /* 0x9 */
-    uint8_t sub_class;                  /* 0xa */
-    uint8_t base_class;                 /* 0xb */
-    uint8_t cache_line;                 /* 0xc */
-    uint8_t latency_timer;              /* 0xd */
-    uint8_t header_type;                /* 0xe */
-    uint8_t bist;                       /* 0xf */
-    uint32_t base_port;                  /* 0x10 */
-    uint32_t mem_base_addr;              /* 0x14 */
-    uint32_t base_addr[4];               /* 0x18-0x24 */
-    uint32_t reserved_1[2];              /* 0x28-0x2c */
-    uint16_t expansion_rom;             /* 0x30 */
-    uint32_t reserved_2[2];              /* 0x34-0x38 */
-    uint8_t interrupt_line;             /* 0x3c */
-    uint8_t interrupt_pin;              /* 0x3d */
-    uint8_t min_grant;                  /* 0x3e */
-    uint8_t max_latency;                /* 0x3f */
-}config_reg_t;
+struct scsi_lu {
+	struct srb *q_first;	/* First block on LU queue */
+	struct srb *q_last;	/* Last block on LU queue */
+	uint8_t q_flag;		/* LU queue state flags */
+	uint8_t q_sense[16];	/* sense data */
+	unsigned long io_cnt;	/* total xfer count */
+	unsigned long resp_time;/* total response time (start - finish) */
+	unsigned long act_time;	/* total actived time (minus queuing time) */
+	unsigned long w_cnt;	/* total writes */
+	unsigned long r_cnt;	/* total reads */
+	uint16_t q_outcnt;	/* Pending jobs for this LU */
+};
+
+/*
+ * Logical Unit flags
+ */
+#define QLA1280_QBUSY	BIT_0
+#define QLA1280_QWAIT	BIT_1
+#define QLA1280_QSUSP	BIT_2
+#define QLA1280_QSENSE	BIT_3	/* Sense data cache valid */
+#define QLA1280_QRESET	BIT_4
+#define QLA1280_QHBA	BIT_5
+#define QLA1280_BSUSP	BIT_6	/* controller is suspended */
+#define QLA1280_BREM	BIT_7	/* controller is removed */
 
 /*
  *  ISP I/O Register Set structure definitions.
  */
-typedef volatile struct
-{
-    uint16_t id_l;                      /* ID low */
-    uint16_t id_h;                      /* ID high */
-    uint16_t cfg_0;                     /* Configuration 0 */
-    uint16_t cfg_1;                     /* Configuration 1 */
-    uint16_t ictrl;                     /* Interface control */
-        #define ISP_RESET       BIT_0   /* ISP soft reset */
-        #define ISP_EN_INT      BIT_1   /* ISP enable interrupts. */
-        #define ISP_EN_RISC     BIT_2   /* ISP enable RISC interrupts. */
-    uint16_t istatus;                   /* Interface status */
-        #define PCI_64BIT_SLOT  BIT_14  /* PCI 64-bit slot indicator. */
-        #define RISC_INT        BIT_2   /* RISC interrupt */
-        #define PCI_INT         BIT_1   /* PCI interrupt */
-    uint16_t semaphore;                 /* Semaphore */
-    uint16_t nvram;                     /* NVRAM register. */
-        #define NV_DESELECT     0
-        #define NV_CLOCK        BIT_0
-        #define NV_SELECT       BIT_1
-        #define NV_DATA_OUT     BIT_2
-        #define NV_DATA_IN      BIT_3
-    uint16_t flash_data;                /* Flash BIOS data */
-    uint16_t flash_address;             /* Flash BIOS address */
-
-    uint16_t unused_1[0x2e];            /* 0x14-0x6f Gap */
-
-    uint16_t mailbox0;                  /* Mailbox 0 */
-    uint16_t mailbox1;                  /* Mailbox 1 */
-    uint16_t mailbox2;                  /* Mailbox 2 */
-    uint16_t mailbox3;                  /* Mailbox 3 */
-    uint16_t mailbox4;                  /* Mailbox 4 */
-    uint16_t mailbox5;                  /* Mailbox 5 */
-    uint16_t mailbox6;                  /* Mailbox 6 */
-    uint16_t mailbox7;                  /* Mailbox 7 */
-
-    uint16_t unused_2[0x20];            /* 0x80-0xbf Gap */
-
-    uint16_t host_cmd;                  /* Host command and control */
-        #define HOST_INT      BIT_7     /* host interrupt bit */
-        #define BIOS_ENABLE   BIT_0
-
-    uint16_t unused_6[0x5];             /* 0xc2-0xcb Gap */
-
-    uint16_t gpio_data;
-    uint16_t gpio_enable;
-
-    uint16_t unused_7[0x11];			/* d0-f0	*/
-    uint16_t scsiControlPins;           /* f2 */
-
-}device_reg_t;
+struct device_reg {
+	uint16_t id_l;		/* ID low */
+	uint16_t id_h;		/* ID high */
+	uint16_t cfg_0;		/* Configuration 0 */
+	uint16_t cfg_1;		/* Configuration 1 */
+	uint16_t ictrl;		/* Interface control */
+#define ISP_RESET        BIT_0	/* ISP soft reset */
+#define ISP_EN_INT       BIT_1	/* ISP enable interrupts. */
+#define ISP_EN_RISC      BIT_2	/* ISP enable RISC interrupts. */
+#define ISP_FLASH_ENABLE BIT_8	/* Flash BIOS Read/Write enable */
+#define ISP_FLASH_UPPER  BIT_9	/* Flash upper bank select */
+	uint16_t istatus;	/* Interface status */
+#define PCI_64BIT_SLOT   BIT_14	/* PCI 64-bit slot indicator. */
+#define RISC_INT         BIT_2	/* RISC interrupt */
+#define PCI_INT          BIT_1	/* PCI interrupt */
+	uint16_t semaphore;	/* Semaphore */
+	uint16_t nvram;		/* NVRAM register. */
+#define NV_DESELECT     0
+#define NV_CLOCK        BIT_0
+#define NV_SELECT       BIT_1
+#define NV_DATA_OUT     BIT_2
+#define NV_DATA_IN      BIT_3
+	uint16_t flash_data;	/* Flash BIOS data */
+	uint16_t flash_address;	/* Flash BIOS address */
+
+	uint16_t unused_1[0x2e];	/* 0x14-0x6f Gap */
+
+	uint16_t mailbox0;	/* Mailbox 0 */
+	uint16_t mailbox1;	/* Mailbox 1 */
+	uint16_t mailbox2;	/* Mailbox 2 */
+	uint16_t mailbox3;	/* Mailbox 3 */
+	uint16_t mailbox4;	/* Mailbox 4 */
+	uint16_t mailbox5;	/* Mailbox 5 */
+	uint16_t mailbox6;	/* Mailbox 6 */
+	uint16_t mailbox7;	/* Mailbox 7 */
+
+	uint16_t unused_2[0x20];/* 0x80-0xbf Gap */
+
+	uint16_t host_cmd;	/* Host command and control */
+#define HOST_INT      BIT_7	/* host interrupt bit */
+#define BIOS_ENABLE   BIT_0
+
+	uint16_t unused_6[0x5];	/* 0xc2-0xcb Gap */
+
+	uint16_t gpio_data;
+	uint16_t gpio_enable;
+
+	uint16_t unused_7[0x11];	/* d0-f0 */
+	uint16_t scsiControlPins;	/* f2 */
+};
 
-#define MAILBOX_REGISTER_COUNT  8
+#define MAILBOX_REGISTER_COUNT	8
 
 /*
  *  ISP product identification definitions in mailboxes after reset.
  */
-#define PROD_ID_1           0x4953
-#define PROD_ID_2           0x0000
-#define PROD_ID_2a          0x5020
-#define PROD_ID_3           0x2020
-#define PROD_ID_4           0x1
+#define PROD_ID_1		0x4953
+#define PROD_ID_2		0x0000
+#define PROD_ID_2a		0x5020
+#define PROD_ID_3		0x2020
+#define PROD_ID_4		0x1
 
 /*
  * ISP host command and control register command definitions
  */
-#define HC_RESET_RISC       0x1000      /* Reset RISC */
-#define HC_PAUSE_RISC       0x2000      /* Pause RISC */
-#define HC_RELEASE_RISC     0x3000      /* Release RISC from reset. */
-#define HC_SET_HOST_INT     0x5000      /* Set host interrupt */
-#define HC_CLR_HOST_INT     0x6000      /* Clear HOST interrupt */
-#define HC_CLR_RISC_INT     0x7000      /* Clear RISC interrupt */
-#define HC_DISABLE_BIOS     0x9000      /* Disable BIOS. */
+#define HC_RESET_RISC		0x1000	/* Reset RISC */
+#define HC_PAUSE_RISC		0x2000	/* Pause RISC */
+#define HC_RELEASE_RISC		0x3000	/* Release RISC from reset. */
+#define HC_SET_HOST_INT		0x5000	/* Set host interrupt */
+#define HC_CLR_HOST_INT		0x6000	/* Clear HOST interrupt */
+#define HC_CLR_RISC_INT		0x7000	/* Clear RISC interrupt */
+#define HC_DISABLE_BIOS		0x9000	/* Disable BIOS. */
 
 /*
  * ISP mailbox Self-Test status codes
  */
-#define MBS_FRM_ALIVE       0           /* Firmware Alive. */
-#define MBS_CHKSUM_ERR      1           /* Checksum Error. */
-#define MBS_SHADOW_LD_ERR   2           /* Shadow Load Error. */
-#define MBS_BUSY            4           /* Busy. */
+#define MBS_FRM_ALIVE		0	/* Firmware Alive. */
+#define MBS_CHKSUM_ERR		1	/* Checksum Error. */
+#define MBS_SHADOW_LD_ERR	2	/* Shadow Load Error. */
+#define MBS_BUSY		4	/* Busy. */
 
 /*
  * ISP mailbox command complete status codes
  */
-#define MBS_CMD_CMP         0x4000      /* Command Complete. */
-#define MBS_INV_CMD         0x4001      /* Invalid Command. */
-#define MBS_HOST_INF_ERR    0x4002      /* Host Interface Error. */
-#define MBS_TEST_FAILED     0x4003      /* Test Failed. */
-#define MBS_CMD_ERR         0x4005      /* Command Error. */
-#define MBS_CMD_PARAM_ERR   0x4006      /* Command Parameter Error. */
+#define MBS_CMD_CMP		0x4000	/* Command Complete. */
+#define MBS_INV_CMD		0x4001	/* Invalid Command. */
+#define MBS_HOST_INF_ERR	0x4002	/* Host Interface Error. */
+#define MBS_TEST_FAILED		0x4003	/* Test Failed. */
+#define MBS_CMD_ERR		0x4005	/* Command Error. */
+#define MBS_CMD_PARAM_ERR	0x4006	/* Command Parameter Error. */
 
 /*
  * ISP mailbox asynchronous event status codes
  */
-#define MBA_ASYNC_EVENT         0x8000  /* Asynchronous event. */
-#define MBA_BUS_RESET           0x8001  /* SCSI Bus Reset. */
-#define MBA_SYSTEM_ERR          0x8002  /* System Error. */
-#define MBA_REQ_TRANSFER_ERR    0x8003  /* Request Transfer Error. */
-#define MBA_RSP_TRANSFER_ERR    0x8004  /* Response Transfer Error. */
-#define MBA_WAKEUP_THRES        0x8005  /* Request Queue Wake-up. */
-#define MBA_TIMEOUT_RESET       0x8006  /* Execution Timeout Reset. */
-#define MBA_DEVICE_RESET        0x8007  /* Bus Device Reset. */
-#define MBA_BUS_MODE_CHANGE     0x800E  /* SCSI bus mode transition. */
-#define MBA_SCSI_COMPLETION     0x8020  /* Completion response. */
+#define MBA_ASYNC_EVENT		0x8000	/* Asynchronous event. */
+#define MBA_BUS_RESET		0x8001	/* SCSI Bus Reset. */
+#define MBA_SYSTEM_ERR		0x8002	/* System Error. */
+#define MBA_REQ_TRANSFER_ERR	0x8003	/* Request Transfer Error. */
+#define MBA_RSP_TRANSFER_ERR	0x8004	/* Response Transfer Error. */
+#define MBA_WAKEUP_THRES	0x8005	/* Request Queue Wake-up. */
+#define MBA_TIMEOUT_RESET	0x8006	/* Execution Timeout Reset. */
+#define MBA_DEVICE_RESET	0x8007	/* Bus Device Reset. */
+#define MBA_BUS_MODE_CHANGE	0x800E	/* SCSI bus mode transition. */
+#define MBA_SCSI_COMPLETION	0x8020	/* Completion response. */
 
 /*
  * ISP mailbox commands
  */
-#define MBC_NOP                     0       /* No Operation. */
-#define MBC_LOAD_RAM                1       /* Load RAM. */
-#define MBC_EXECUTE_FIRMWARE        2       /* Execute firmware. */
-#define MBC_WRITE_RAM_WORD          4       /* Write ram word. */
-#define MBC_READ_RAM_WORD           5       /* Read ram word. */
-#define MBC_MAILBOX_REGISTER_TEST   6       /* Wrap incoming mailboxes */
-#define MBC_VERIFY_CHECKSUM         7       /* Verify checksum. */
-#define MBC_ABOUT_FIRMWARE          8       /* Get firmware revision. */
-#define MBC_INIT_REQUEST_QUEUE      0x10    /* Initialize request queue. */
-#define MBC_INIT_RESPONSE_QUEUE     0x11    /* Initialize response queue. */
-#define MBC_EXECUTE_IOCB            0x12    /* Execute IOCB command. */
-#define MBC_ABORT_COMMAND           0x15    /* Abort IOCB command. */
-#define MBC_ABORT_DEVICE            0x16    /* Abort device (ID/LUN). */
-#define MBC_ABORT_TARGET            0x17    /* Abort target (ID). */
-#define MBC_BUS_RESET               0x18    /* SCSI bus reset. */
-#define MBC_GET_RETRY_COUNT         0x22    /* Get retry count and delay. */
-#define MBC_GET_TARGET_PARAMETERS   0x28    /* Get target parameters. */
-#define MBC_SET_INITIATOR_ID        0x30    /* Set initiator SCSI ID. */
-#define MBC_SET_SELECTION_TIMEOUT   0x31    /* Set selection timeout. */
-#define MBC_SET_RETRY_COUNT         0x32    /* Set retry count and delay. */
-#define MBC_SET_TAG_AGE_LIMIT       0x33    /* Set tag age limit. */
-#define MBC_SET_CLOCK_RATE          0x34    /* Set clock rate. */
-#define MBC_SET_ACTIVE_NEGATION     0x35    /* Set active negation state. */
-#define MBC_SET_ASYNC_DATA_SETUP    0x36    /* Set async data setup time. */
-#define MBC_SET_PCI_CONTROL         0x37    /* Set BUS control parameters. */
-#define MBC_SET_TARGET_PARAMETERS   0x38    /* Set target parameters. */
-#define MBC_SET_DEVICE_QUEUE        0x39    /* Set device queue parameters */
-#define MBC_SET_SYSTEM_PARAMETER    0x45    /* Set system parameter word. */
-#define MBC_SET_FIRMWARE_FEATURES   0x4A    /* Set firmware feature word. */
-#define MBC_INIT_REQUEST_QUEUE_A64  0x52    /* Initialize request queue A64 */
-#define MBC_INIT_RESPONSE_QUEUE_A64 0x53    /* Initialize response q A64. */
-#define MBC_ENABLE_TARGET_MODE      0x55    /* Enable target mode. */
+#define MBC_NOP				0	/* No Operation */
+#define MBC_LOAD_RAM			1	/* Load RAM */
+#define MBC_EXECUTE_FIRMWARE		2	/* Execute firmware */
+#define MBC_DUMP_RAM			3	/* Dump RAM contents */
+#define MBC_WRITE_RAM_WORD		4	/* Write ram word */
+#define MBC_READ_RAM_WORD		5	/* Read ram word */
+#define MBC_MAILBOX_REGISTER_TEST	6	/* Wrap incoming mailboxes */
+#define MBC_VERIFY_CHECKSUM		7	/* Verify checksum */
+#define MBC_ABOUT_FIRMWARE		8	/* Get firmware revision */
+#define MBC_INIT_REQUEST_QUEUE		0x10	/* Initialize request queue */
+#define MBC_INIT_RESPONSE_QUEUE		0x11	/* Initialize response queue */
+#define MBC_EXECUTE_IOCB		0x12	/* Execute IOCB command */
+#define MBC_ABORT_COMMAND		0x15	/* Abort IOCB command */
+#define MBC_ABORT_DEVICE		0x16	/* Abort device (ID/LUN) */
+#define MBC_ABORT_TARGET		0x17	/* Abort target (ID) */
+#define MBC_BUS_RESET			0x18	/* SCSI bus reset */
+#define MBC_GET_RETRY_COUNT		0x22	/* Get retry count and delay */
+#define MBC_GET_TARGET_PARAMETERS	0x28	/* Get target parameters */
+#define MBC_SET_INITIATOR_ID		0x30	/* Set initiator SCSI ID */
+#define MBC_SET_SELECTION_TIMEOUT	0x31	/* Set selection timeout */
+#define MBC_SET_RETRY_COUNT		0x32	/* Set retry count and delay */
+#define MBC_SET_TAG_AGE_LIMIT		0x33	/* Set tag age limit */
+#define MBC_SET_CLOCK_RATE		0x34	/* Set clock rate */
+#define MBC_SET_ACTIVE_NEGATION		0x35	/* Set active negation state */
+#define MBC_SET_ASYNC_DATA_SETUP	0x36	/* Set async data setup time */
+#define MBC_SET_PCI_CONTROL		0x37	/* Set BUS control parameters */
+#define MBC_SET_TARGET_PARAMETERS	0x38	/* Set target parameters */
+#define MBC_SET_DEVICE_QUEUE		0x39	/* Set device queue parameters */
+#define MBC_SET_RESET_DELAY_PARAMETERS	0x3A	/* Set reset delay parameters */
+#define MBC_SET_SYSTEM_PARAMETER	0x45	/* Set system parameter word */
+#define MBC_SET_FIRMWARE_FEATURES	0x4A	/* Set firmware feature word */
+#define MBC_INIT_REQUEST_QUEUE_A64	0x52	/* Initialize request queue A64 */
+#define MBC_INIT_RESPONSE_QUEUE_A64	0x53	/* Initialize response q A64 */
+#define MBC_ENABLE_TARGET_MODE		0x55	/* Enable target mode */
+#define MBC_SET_DATA_OVERRUN_RECOVERY	0x5A	/* Set data overrun recovery mode */
 
 /*
  * ISP Get/Set Target Parameters mailbox command control flags.
  */
-#define TP_RENEGOTIATE          BIT_8   /* Renegotiate on error. */
-#define TP_STOP_QUEUE           BIT_9   /* Stop que on check condition */
-#define TP_AUTO_REQUEST_SENSE   BIT_10  /* Automatic request sense. */
-#define TP_TAGGED_QUEUE         BIT_11  /* Tagged queuing. */
-#define TP_SYNC                 BIT_12  /* Synchronous data transfers. */
-#define TP_WIDE                 BIT_13  /* Wide data transfers. */
-#define TP_PARITY               BIT_14  /* Parity checking. */
-#define TP_DISCONNECT           BIT_15  /* Disconnect privilege. */
+#define TP_PPR			BIT_5	/* PPR */
+#define TP_RENEGOTIATE		BIT_8	/* Renegotiate on error. */
+#define TP_STOP_QUEUE           BIT_9	/* Stop que on check condition */
+#define TP_AUTO_REQUEST_SENSE   BIT_10	/* Automatic request sense. */
+#define TP_TAGGED_QUEUE         BIT_11	/* Tagged queuing. */
+#define TP_SYNC                 BIT_12	/* Synchronous data transfers. */
+#define TP_WIDE                 BIT_13	/* Wide data transfers. */
+#define TP_PARITY               BIT_14	/* Parity checking. */
+#define TP_DISCONNECT           BIT_15	/* Disconnect privilege. */
 
 /*
  * NVRAM Command values.
  */
-#define NV_START_BIT            BIT_2
-#define NV_WRITE_OP             (BIT_26+BIT_24)
-#define NV_READ_OP              (BIT_26+BIT_25)
-#define NV_ERASE_OP             (BIT_26+BIT_25+BIT_24)
-#define NV_MASK_OP              (BIT_26+BIT_25+BIT_24)
-#define NV_DELAY_COUNT          10
-
-/*
- *  QLogic ISP1280 NVRAM structure definition.
- */
-typedef struct
-{
-    uint8_t id[4];                                  /* 0, 1, 2, 3 */
-    uint8_t version;                                /* 4 */
-
-    struct
-    {
-        uint8_t bios_configuration_mode     :2;
-        uint8_t bios_disable                :1;
-        uint8_t selectable_scsi_boot_enable :1;
-        uint8_t cd_rom_boot_enable          :1;
-        uint8_t disable_loading_risc_code   :1;
-        uint8_t enable_64bit_addressing     :1;
-        uint8_t unused_7                    :1;
-    }cntr_flags_1;                                  /* 5 */
-
-    struct
-    {
-        uint8_t boot_lun_number    :5;
-        uint8_t scsi_bus_number    :1;
-        uint8_t unused_6           :1;
-        uint8_t unused_7           :1;
-        uint8_t boot_target_number :4;
-        uint8_t unused_12          :1;
-        uint8_t unused_13          :1;
-        uint8_t unused_14          :1;
-        uint8_t unused_15          :1;
-    }cntr_flags_2;                                  /* 6, 7 */
-
-    uint16_t unused_8;                              /* 8, 9 */
-    uint16_t unused_10;                             /* 10, 11 */
-    uint16_t unused_12;                             /* 12, 13 */
-    uint16_t unused_14;                              /* 14, 15 */
-
-    union
-    {
-        uint8_t c;
-        struct
-        {
-            uint8_t reserved        :2;
-            uint8_t burst_enable    :1;
-            uint8_t reserved_1      :1;
-            uint8_t fifo_threshold  :4;
-        }f;
-    }isp_config;                                    /* 16 */
-
-    /* Termination
-     * 0 = Disable, 1 = high only, 3 = Auto term
-     */
-    union
-    {
-        uint8_t c;
-        struct
-        {
-            uint8_t scsi_bus_1_control  :2;
-            uint8_t scsi_bus_0_control  :2;
-            uint8_t unused_0            :1;
-            uint8_t unused_1            :1;
-            uint8_t unused_2            :1;
-            uint8_t auto_term_support   :1;
-        }f;
-    }termination;                                   /* 17 */
-
-    uint16_t isp_parameter;                         /* 18, 19 */
-
-    union
-    {
-        uint16_t w;
-        struct
-        {
-            uint8_t enable_fast_posting       :1;
-            uint8_t report_lvd_bus_transition :1;
-            uint8_t unused_2                  :1;
-            uint8_t unused_3                  :1;
-            uint8_t unused_4                  :1;
-            uint8_t unused_5                  :1;
-            uint8_t unused_6                  :1;
-            uint8_t unused_7                  :1;
-            uint8_t unused_8                  :1;
-            uint8_t unused_9                  :1;
-            uint8_t unused_10                 :1;
-            uint8_t unused_11                 :1;
-            uint8_t unused_12                 :1;
-            uint8_t unused_13                 :1;
-            uint8_t unused_14                 :1;
-            uint8_t unused_15                 :1;
-        }f;
-    }firmware_feature;                              /* 20, 21 */
-
-    uint16_t unused_22;                             /* 22, 23 */
-
-    struct
-    {
-        struct
-        {
-            uint8_t initiator_id       :4;
-            uint8_t scsi_reset_disable :1;
-            uint8_t scsi_bus_size      :1;
-            uint8_t scsi_bus_type      :1;
-            uint8_t unused_7           :1;
-        }config_1;                                  /* 24 */
-
-        uint8_t bus_reset_delay;                    /* 25 */
-        uint8_t retry_count;                        /* 26 */
-        uint8_t retry_delay;                        /* 27 */
-
-        struct
-        {
-            uint8_t async_data_setup_time     :4;
-            uint8_t req_ack_active_negation   :1;
-            uint8_t data_line_active_negation :1;
-            uint8_t unused_6                  :1;
-            uint8_t unused_7                  :1;
-        }config_2;                                  /* 28 */
-
-        uint8_t unused_29;                          /* 29 */
-
-        uint16_t selection_timeout;                 /* 30, 31 */
-        uint16_t max_queue_depth;                   /* 32, 33 */
-
-        uint16_t unused_34;                         /* 34, 35 */
-        uint16_t unused_36;                         /* 36, 37 */
-        uint16_t unused_38;                         /* 38, 39 */
-
-        struct
-        {
-            union
-            {
-                uint8_t c;
-                struct
-                {
-                    uint8_t renegotiate_on_error :1;
-                    uint8_t stop_queue_on_check  :1;
-                    uint8_t auto_request_sense   :1;
-                    uint8_t tag_queuing          :1;
-                    uint8_t sync_data_transfers  :1;
-                    uint8_t wide_data_transfers  :1;
-                    uint8_t parity_checking      :1;
-                    uint8_t disconnect_allowed   :1;
-                }f;
-            }parameter;                             /* 40 */
-
-            uint8_t execution_throttle;             /* 41 */
-            uint8_t sync_period;                    /* 42 */
-
-            struct
-            {
-                uint8_t sync_offset   :4;
-                uint8_t device_enable :1;
-                uint8_t lun_disable   :1;
-                uint8_t unused_6      :1;
-                uint8_t unused_7      :1;
-            }flags;                                 /* 43 */
-
-            uint16_t unused_44;                     /* 44, 45 */
-        }target[MAX_TARGETS];
-    }bus[MAX_BUSES];
-
-    uint16_t unused_248;                        /* 248, 249 */
-
-    uint16_t subsystem_id[2];                   /* 250, 251, 252, 253 */
-
-    uint8_t  unused_254;                        /* 254 */
-
-    uint8_t chksum;                             /* 255 */
-}nvram_t;
-
-/*
- *  QLogic ISP12160 NVRAM structure definition.
- */
-typedef struct
-{
-    uint8_t id[4];                                  /* 0, 1, 2, 3 */
-    uint8_t version;                                /* 4 */
-    /* Host/Bios Flags */ 
-    struct
-    {
-        uint8_t bios_configuration_mode     :2;
-        uint8_t bios_disable                :1;
-        uint8_t selectable_scsi_boot_enable :1;
-        uint8_t cd_rom_boot_enable          :1;
-        uint8_t disable_loading_risc_code   :1;
-        uint8_t unused_6                    :1;
-        uint8_t unused_7                    :1;
-    }cntr_flags_1;                                  /* 5 */
-    /* Selectable Boot Support */
-    struct
-    {
-        uint8_t boot_lun_number    :5;
-        uint8_t scsi_bus_number    :1;
-        uint8_t unused_6           :1;
-        uint8_t unused_7           :1;
-        uint8_t boot_target_number :4;
-        uint8_t unused_12          :1;
-        uint8_t unused_13          :1;
-        uint8_t unused_14          :1;
-        uint8_t unused_15          :1;
-    }cntr_flags_2;                                  /* 6, 7 */
-
-    uint16_t unused_8;                              /* 8, 9 */
-    uint16_t unused_10;                             /* 10, 11 */
-    uint16_t unused_12;                             /* 12, 13 */
-    uint16_t unused_14;                              /* 14, 15 */
-
-    /* ISP Config Parameters */
-    union
-    {
-        uint8_t c;  
-        struct
-        {
-            uint8_t reserved        :2;
-            uint8_t burst_enable    :1;
-            uint8_t reserved_1      :1;
-            uint8_t fifo_threshold  :4;
-        }f;
-    }isp_config;                                    /* 16 */
-
-    /* Termination
-     * 0 = Disable, 1 = high only, 3 = Auto term
-     */
-    union
-    {
-        uint8_t c;
-        struct
-        {
-            uint8_t scsi_bus_1_control  :2;
-            uint8_t scsi_bus_0_control  :2;
-            uint8_t unused_0            :1;
-            uint8_t unused_1            :1;
-            uint8_t unused_2            :1;
-            uint8_t auto_term_support   :1;
-        }f;
-    }termination;                                   /* 17 */
-								/* Auto Term - 3                          */
-								/* High Only - 1 (GPIO2 = 1 & GPIO3 = 0)  */
-								/* Disable - 0 (GPIO2 = 0 & GPIO3 = X)    */
-
-    uint16_t isp_parameter;                         /* 18, 19 */
-
-    union
-    {
-        uint16_t w;
-        struct
-        {
-            uint8_t enable_fast_posting       :1;
-            uint8_t report_lvd_bus_transition :1;
-            uint8_t unused_2                  :1;
-            uint8_t unused_3                  :1;
-            uint8_t unused_4                  :1;
-            uint8_t unused_5                  :1;
-            uint8_t unused_6                  :1;
-            uint8_t unused_7                  :1;
-            uint8_t unused_8                  :1;
-            uint8_t unused_9                  :1;
-            uint8_t unused_10                 :1;
-            uint8_t unused_11                 :1;
-            uint8_t unused_12                 :1;
-            uint8_t unused_13                 :1;
-            uint8_t unused_14                 :1;
-            uint8_t unused_15                 :1;
-        }f;
-    }firmware_feature;                              /* 20, 21 */
-
-    uint16_t unused_22;                             /* 22, 23 */
-
-    struct
-    {
-        struct
-        {
-            uint8_t initiator_id       :4;
-            uint8_t scsi_reset_disable :1;
-            uint8_t scsi_bus_size      :1;
-            uint8_t scsi_bus_type      :1;
-            uint8_t unused_7           :1;
-        }config_1;                                  /* 24 */
-
-        uint8_t bus_reset_delay;                    /* 25 */
-        uint8_t retry_count;                        /* 26 */
-        uint8_t retry_delay;                        /* 27 */
-                /* Adapter Capabilities bits */
-        struct
-        {
-            uint8_t async_data_setup_time     :4;
-            uint8_t req_ack_active_negation   :1;
-            uint8_t data_line_active_negation :1;
-            uint8_t unused_6                  :1;
-            uint8_t unused_7                  :1;
-        }config_2;                                  /* 28 */
-
-        uint8_t unused_29;                          /* 29 */
-
-        uint16_t selection_timeout;                 /* 30, 31 */
-        uint16_t max_queue_depth;                   /* 32, 33 */
-
-        uint16_t unused_34;                         /* 34, 35 */
-        uint16_t unused_36;                         /* 36, 37 */
-        uint16_t unused_38;                         /* 38, 39 */
-
-        struct
-        {
-            union
-            {
-                uint8_t c;
-                struct
-                {
-                    uint8_t renegotiate_on_error :1;
-                    uint8_t stop_queue_on_check  :1;
-                    uint8_t auto_request_sense   :1;
-                    uint8_t tag_queuing          :1;
-                    uint8_t sync_data_transfers  :1;
-                    uint8_t wide_data_transfers  :1;
-                    uint8_t parity_checking      :1;
-                    uint8_t disconnect_allowed   :1;
-                }f;
-            }parameter;                             /* 40 */
-
-            uint8_t execution_throttle;             /* 41 */
-            uint8_t sync_period;                    /* 42 */
-
-            struct
-            {
-                uint8_t sync_offset   :5;
-                uint8_t device_enable :1;
-                uint8_t unused_6      :1;
-                uint8_t unused_7      :1;
-                uint8_t	ppr_options	  :4;
-                uint8_t	ppr_bus_width :2;
-	            uint8_t	unused_8	  :1;
-	            uint8_t	enable_ppr	  :1;  
-            }flags;                                 /* 43, 44 */
-
-            uint8_t unused_45;                     /* 45 */
-        }target[MAX_TARGETS];
-    }bus[MAX_BUSES];
+#define NV_START_BIT		BIT_2
+#define NV_WRITE_OP		(BIT_26 | BIT_24)
+#define NV_READ_OP		(BIT_26 | BIT_25)
+#define NV_ERASE_OP		(BIT_26 | BIT_25 | BIT_24)
+#define NV_MASK_OP		(BIT_26 | BIT_25 | BIT_24)
+#define NV_DELAY_COUNT		10
+
+/*
+ *  QLogic ISP1280/ISP12160 NVRAM structure definition.
+ */
+struct nvram {
+	uint8_t id0;		/* 0 */
+	uint8_t id1;		/* 1 */
+	uint8_t id2;		/* 2 */
+	uint8_t id3;		/* 3 */
+	uint8_t version;	/* 4 */
+
+	struct {
+		uint8_t bios_configuration_mode:2;
+		uint8_t bios_disable:1;
+		uint8_t selectable_scsi_boot_enable:1;
+		uint8_t cd_rom_boot_enable:1;
+		uint8_t disable_loading_risc_code:1;
+		uint8_t enable_64bit_addressing:1;
+		uint8_t unused_7:1;
+	} cntr_flags_1;		/* 5 */
+
+	struct {
+		uint16_t boot_lun_number:5;
+		uint16_t scsi_bus_number:1;
+		uint16_t unused_6:1;
+		uint16_t unused_7:1;
+		uint16_t boot_target_number:4;
+		uint16_t unused_12:1;
+		uint16_t unused_13:1;
+		uint16_t unused_14:1;
+		uint16_t unused_15:1;
+	} cntr_flags_2;		/* 6, 7 */
+
+	uint16_t unused_8;	/* 8, 9 */
+	uint16_t unused_10;	/* 10, 11 */
+	uint16_t unused_12;	/* 12, 13 */
+	uint16_t unused_14;	/* 14, 15 */
+
+	union {
+		uint8_t c;
+		struct {
+			uint8_t reserved:2;
+			uint8_t burst_enable:1;
+			uint8_t reserved_1:1;
+			uint8_t fifo_threshold:4;
+		} f;
+	} isp_config;		/* 16 */
+
+	/* Termination
+	 * 0 = Disable, 1 = high only, 3 = Auto term
+	 */
+	union {
+		uint8_t c;
+		struct {
+			uint8_t scsi_bus_1_control:2;
+			uint8_t scsi_bus_0_control:2;
+			uint8_t unused_0:1;
+			uint8_t unused_1:1;
+			uint8_t unused_2:1;
+			uint8_t auto_term_support:1;
+		} f;
+	} termination;		/* 17 */
+
+	uint16_t isp_parameter;	/* 18, 19 */
+
+	union {
+		uint16_t w;
+		struct {
+			uint16_t enable_fast_posting:1;
+			uint16_t report_lvd_bus_transition:1;
+			uint16_t unused_2:1;
+			uint16_t unused_3:1;
+			uint16_t disable_iosbs_with_bus_reset_status:1;
+			uint16_t disable_synchronous_backoff:1;
+			uint16_t unused_6:1;
+			uint16_t synchronous_backoff_reporting:1;
+			uint16_t disable_reselection_fairness:1;
+			uint16_t unused_9:1;
+			uint16_t unused_10:1;
+			uint16_t unused_11:1;
+			uint16_t unused_12:1;
+			uint16_t unused_13:1;
+			uint16_t unused_14:1;
+			uint16_t unused_15:1;
+		} f;
+	} firmware_feature;	/* 20, 21 */
+
+	uint16_t unused_22;	/* 22, 23 */
+
+	struct {
+		struct {
+			uint8_t initiator_id:4;
+			uint8_t scsi_reset_disable:1;
+			uint8_t scsi_bus_size:1;
+			uint8_t scsi_bus_type:1;
+			uint8_t unused_7:1;
+		} config_1;	/* 24 */
+
+		uint8_t bus_reset_delay;	/* 25 */
+		uint8_t retry_count;	/* 26 */
+		uint8_t retry_delay;	/* 27 */
+
+		struct {
+			uint8_t async_data_setup_time:4;
+			uint8_t req_ack_active_negation:1;
+			uint8_t data_line_active_negation:1;
+			uint8_t unused_6:1;
+			uint8_t unused_7:1;
+		} config_2;	/* 28 */
+
+		uint8_t unused_29;	/* 29 */
+
+		uint16_t selection_timeout;	/* 30, 31 */
+		uint16_t max_queue_depth;	/* 32, 33 */
+
+		uint16_t unused_34;	/* 34, 35 */
+		uint16_t unused_36;	/* 36, 37 */
+		uint16_t unused_38;	/* 38, 39 */
+
+		struct {
+			union {
+				uint8_t c;
+				struct {
+					uint8_t renegotiate_on_error:1;
+					uint8_t stop_queue_on_check:1;
+					uint8_t auto_request_sense:1;
+					uint8_t tag_queuing:1;
+					uint8_t enable_sync:1;
+					uint8_t enable_wide:1;
+					uint8_t parity_checking:1;
+					uint8_t disconnect_allowed:1;
+				} f;
+			} parameter;	/* 40 */
+
+			uint8_t execution_throttle;	/* 41 */
+			uint8_t sync_period;	/* 42 */
+
+			union {		/* 43 */
+				uint8_t flags_43;
+				struct {
+					uint8_t sync_offset:4;
+					uint8_t device_enable:1;
+					uint8_t lun_disable:1;
+					uint8_t unused_6:1;
+					uint8_t unused_7:1;
+				} flags1x80;
+				struct {
+					uint8_t sync_offset:5;
+					uint8_t device_enable:1;
+					uint8_t unused_6:1;
+					uint8_t unused_7:1;
+				} flags1x160;
+			} flags;
+			union {	/* PPR flags for the 1x160 controllers */
+				uint8_t unused_44;
+				struct {
+					uint8_t ppr_options:4;
+					uint8_t ppr_bus_width:2;
+					uint8_t unused_8:1;
+					uint8_t enable_ppr:1;
+				} flags;	/* 44 */
+			} ppr_1x160;
+			uint8_t unused_45;	/* 45 */
+		} target[MAX_TARGETS];
+	} bus[MAX_BUSES];
+
+	uint16_t unused_248;	/* 248, 249 */
+
+	uint16_t subsystem_id[2];	/* 250, 251, 252, 253 */
+
+	union {				/* 254 */
+		uint8_t unused_254;
+		uint8_t system_id_pointer;
+	} sysid_1x160;
 
-    uint16_t unused_248;                        /* 248, 249 */
-
-    uint16_t subsystem_id[2];                   /* 250, 251, 252, 253 */
-
-    uint8_t  System_Id_Pointer;                   /* 254 */
-
-    uint8_t chksum;                             /* 255 */
-}nvram160_t;
+	uint8_t chksum;		/* 255 */
+};
 
 /*
  * ISP queue - command entry structure definition.
  */
-#define MAX_CMDSZ   12                  /* SCSI maximum CDB size. */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define COMMAND_TYPE    1       /* Command entry */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t handle;                    /* System handle. */
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  target;                    /* SCSI ID */
-    uint16_t cdb_len;                   /* SCSI command length. */
-    uint16_t control_flags;             /* Control flags. */
-    uint16_t reserved;
-    uint16_t timeout;                   /* Command timeout. */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint8_t  scsi_cdb[MAX_CMDSZ];       /* SCSI command words. */
-    uint32_t dseg_0_address;            /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address;            /* Data segment 1 address. */
-    uint32_t dseg_1_length;             /* Data segment 1 length. */
-    uint32_t dseg_2_address;            /* Data segment 2 address. */
-    uint32_t dseg_2_length;             /* Data segment 2 length. */
-    uint32_t dseg_3_address;            /* Data segment 3 address. */
-    uint32_t dseg_3_length;             /* Data segment 3 length. */
-}cmd_entry_t;
+#define MAX_CMDSZ	12		/* SCSI maximum CDB size. */
+struct cmd_entry {
+	uint8_t entry_type;		/* Entry type. */
+#define COMMAND_TYPE    1		/* Command entry */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+	uint32_t handle;		/* System handle. */
+	uint8_t lun;			/* SCSI LUN */
+	uint8_t target;			/* SCSI ID */
+	uint16_t cdb_len;		/* SCSI command length. */
+	uint16_t control_flags;		/* Control flags. */
+	uint16_t reserved;
+	uint16_t timeout;		/* Command timeout. */
+	uint16_t dseg_count;		/* Data segment count. */
+	uint8_t scsi_cdb[MAX_CMDSZ];	/* SCSI command words. */
+	uint32_t dseg_0_address;	/* Data segment 0 address. */
+	uint32_t dseg_0_length;		/* Data segment 0 length. */
+	uint32_t dseg_1_address;	/* Data segment 1 address. */
+	uint32_t dseg_1_length;		/* Data segment 1 length. */
+	uint32_t dseg_2_address;	/* Data segment 2 address. */
+	uint32_t dseg_2_length;		/* Data segment 2 length. */
+	uint32_t dseg_3_address;	/* Data segment 3 address. */
+	uint32_t dseg_3_length;		/* Data segment 3 length. */
+};
 
 /*
  * ISP queue - continuation entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define CONTINUE_TYPE   2       /* Continuation entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved;                  /* Reserved */
-    uint32_t dseg_0_address;            /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address;            /* Data segment 1 address. */
-    uint32_t dseg_1_length;             /* Data segment 1 length. */
-    uint32_t dseg_2_address;            /* Data segment 2 address. */
-    uint32_t dseg_2_length;             /* Data segment 2 length. */
-    uint32_t dseg_3_address;            /* Data segment 3 address. */
-    uint32_t dseg_3_length;             /* Data segment 3 length. */
-    uint32_t dseg_4_address;            /* Data segment 4 address. */
-    uint32_t dseg_4_length;             /* Data segment 4 length. */
-    uint32_t dseg_5_address;            /* Data segment 5 address. */
-    uint32_t dseg_5_length;             /* Data segment 5 length. */
-    uint32_t dseg_6_address;            /* Data segment 6 address. */
-    uint32_t dseg_6_length;             /* Data segment 6 length. */
-}cont_entry_t;
+struct cont_entry {
+	uint8_t entry_type;		/* Entry type. */
+#define CONTINUE_TYPE   2		/* Continuation entry. */
+	uint8_t entry_count;		/* Entry count. */
+	uint8_t sys_define;		/* System defined. */
+	uint8_t entry_status;		/* Entry Status. */
+	uint32_t reserved;		/* Reserved */
+	uint32_t dseg_0_address;	/* Data segment 0 address. */
+	uint32_t dseg_0_length;		/* Data segment 0 length. */
+	uint32_t dseg_1_address;	/* Data segment 1 address. */
+	uint32_t dseg_1_length;		/* Data segment 1 length. */
+	uint32_t dseg_2_address;	/* Data segment 2 address. */
+	uint32_t dseg_2_length;		/* Data segment 2 length. */
+	uint32_t dseg_3_address;	/* Data segment 3 address. */
+	uint32_t dseg_3_length;		/* Data segment 3 length. */
+	uint32_t dseg_4_address;	/* Data segment 4 address. */
+	uint32_t dseg_4_length;		/* Data segment 4 length. */
+	uint32_t dseg_5_address;	/* Data segment 5 address. */
+	uint32_t dseg_5_length;		/* Data segment 5 length. */
+	uint32_t dseg_6_address;	/* Data segment 6 address. */
+	uint32_t dseg_6_length;		/* Data segment 6 length. */
+};
 
 /*
  * ISP queue - status entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define STATUS_TYPE     3       /* Status entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-        #define RF_CONT         BIT_0   /* Continuation. */
-        #define RF_FULL         BIT_1   /* Full */
-        #define RF_BAD_HEADER   BIT_2   /* Bad header. */
-        #define RF_BAD_PAYLOAD  BIT_3   /* Bad payload. */
-    uint32_t handle;                    /* System handle. */
-    uint16_t scsi_status;               /* SCSI status. */
-    uint16_t comp_status;               /* Completion status. */
-    uint16_t state_flags;               /* State flags. */
-        #define SF_TRANSFER_CMPL BIT_14  /* Transfer Complete. */
-        #define SF_GOT_SENSE    BIT_13   /* Got Sense */
-        #define SF_GOT_STATUS    BIT_12   /* Got Status */
-        #define SF_TRANSFERRED_DATA BIT_11  /* Transferred data */
-        #define SF_SENT_CDB   BIT_10     /* Send CDB */
-        #define SF_GOT_TARGET  BIT_9   /*  */
-        #define SF_GOT_BUS     BIT_8   /*  */
-    uint16_t status_flags;              /* Status flags. */
-    uint16_t time;                      /* Time. */
-    uint16_t req_sense_length;          /* Request sense data length. */
-    uint32_t residual_length;           /* Residual transfer length. */
-    uint16_t reserved[4];
-    uint8_t  req_sense_data[32];        /* Request sense data. */
-}sts_entry_t, response_t;
+struct response {
+	uint8_t entry_type;	/* Entry type. */
+#define STATUS_TYPE     3	/* Status entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t sys_define;	/* System defined. */
+	uint8_t entry_status;	/* Entry Status. */
+#define RF_CONT         BIT_0	/* Continuation. */
+#define RF_FULL         BIT_1	/* Full */
+#define RF_BAD_HEADER   BIT_2	/* Bad header. */
+#define RF_BAD_PAYLOAD  BIT_3	/* Bad payload. */
+	uint32_t handle;	/* System handle. */
+	uint16_t scsi_status;	/* SCSI status. */
+	uint16_t comp_status;	/* Completion status. */
+	uint16_t state_flags;	/* State flags. */
+#define SF_TRANSFER_CMPL BIT_14	/* Transfer Complete. */
+#define SF_GOT_SENSE    BIT_13	/* Got Sense */
+#define SF_GOT_STATUS    BIT_12	/* Got Status */
+#define SF_TRANSFERRED_DATA BIT_11	/* Transferred data */
+#define SF_SENT_CDB   BIT_10	/* Send CDB */
+#define SF_GOT_TARGET  BIT_9	/*  */
+#define SF_GOT_BUS     BIT_8	/*  */
+	uint16_t status_flags;	/* Status flags. */
+	uint16_t time;		/* Time. */
+	uint16_t req_sense_length;	/* Request sense data length. */
+	uint32_t residual_length;	/* Residual transfer length. */
+	uint16_t reserved[4];
+	uint8_t req_sense_data[32];	/* Request sense data. */
+};
 
 /*
  * ISP queue - marker entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define MARKER_TYPE     4       /* Marker entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved;
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  target;                    /* SCSI ID */
-    uint8_t  modifier;                  /* Modifier (7-0). */
-        #define MK_SYNC_ID_LUN      0   /* Synchronize ID/LUN */
-        #define MK_SYNC_ID          1   /* Synchronize ID */
-        #define MK_SYNC_ALL         2   /* Synchronize all ID/LUN */
-    uint8_t  reserved_1[53];
-}mrk_entry_t;
+struct mrk_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define MARKER_TYPE     4	/* Marker entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t sys_define;	/* System defined. */
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved;
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t target;		/* SCSI ID */
+	uint8_t modifier;	/* Modifier (7-0). */
+#define MK_SYNC_ID_LUN      0	/* Synchronize ID/LUN */
+#define MK_SYNC_ID          1	/* Synchronize ID */
+#define MK_SYNC_ALL         2	/* Synchronize all ID/LUN */
+	uint8_t reserved_1[53];
+};
 
 /*
  * ISP queue - extended command entry structure definition.
+ *
+ * Unused by the driver!
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define EXTENDED_CMD_TYPE  5    /* Extended command entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t handle;                    /* System handle. */
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  target;                    /* SCSI ID */
-    uint16_t cdb_len;                   /* SCSI command length. */
-    uint16_t control_flags;             /* Control flags. */
-    uint16_t reserved;
-    uint16_t timeout;                   /* Command timeout. */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint8_t  scsi_cdb[88];              /* SCSI command words. */
-}ecmd_entry_t;
+struct ecmd_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define EXTENDED_CMD_TYPE  5	/* Extended command entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t sys_define;	/* System defined. */
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t handle;	/* System handle. */
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t target;		/* SCSI ID */
+	uint16_t cdb_len;	/* SCSI command length. */
+	uint16_t control_flags;	/* Control flags. */
+	uint16_t reserved;
+	uint16_t timeout;	/* Command timeout. */
+	uint16_t dseg_count;	/* Data segment count. */
+	uint8_t scsi_cdb[88];	/* SCSI command words. */
+};
 
 /*
  * ISP queue - 64-Bit addressing, command entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define COMMAND_A64_TYPE 9      /* Command A64 entry */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t handle;                    /* System handle. */
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  target;                    /* SCSI ID */
-    uint16_t cdb_len;                   /* SCSI command length. */
-    uint16_t control_flags;             /* Control flags. */
-    uint16_t reserved;
-    uint16_t timeout;                   /* Command timeout. */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint8_t  scsi_cdb[MAX_CMDSZ];       /* SCSI command words. */
-    uint32_t reserved_1[2];             /* unused */
-    uint32_t dseg_0_address[2];         /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address[2];         /* Data segment 1 address. */
-    uint32_t dseg_1_length;             /* Data segment 1 length. */
-}cmd_a64_entry_t, request_t;
+typedef struct {
+	uint8_t entry_type;	/* Entry type. */
+#define COMMAND_A64_TYPE 9	/* Command A64 entry */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t sys_define;	/* System defined. */
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t handle;	/* System handle. */
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t target;		/* SCSI ID */
+	uint16_t cdb_len;	/* SCSI command length. */
+	uint16_t control_flags;	/* Control flags. */
+	uint16_t reserved;
+	uint16_t timeout;	/* Command timeout. */
+	uint16_t dseg_count;	/* Data segment count. */
+	uint8_t scsi_cdb[MAX_CMDSZ];	/* SCSI command words. */
+	uint32_t reserved_1[2];	/* unused */
+	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
+	uint32_t dseg_0_length;	/* Data segment 0 length. */
+	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
+	uint32_t dseg_1_length;	/* Data segment 1 length. */
+} cmd_a64_entry_t, request_t;
 
 /*
  * ISP queue - 64-Bit addressing, continuation entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define CONTINUE_A64_TYPE 0xA   /* Continuation A64 entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  sys_define;                /* System defined. */
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t dseg_0_address[2];         /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address[2];         /* Data segment 1 address. */
-    uint32_t dseg_1_length;             /* Data segment 1 length. */
-    uint32_t dseg_2_address[2];         /* Data segment 2 address. */
-    uint32_t dseg_2_length;             /* Data segment 2 length. */
-    uint32_t dseg_3_address[2];         /* Data segment 3 address. */
-    uint32_t dseg_3_length;             /* Data segment 3 length. */
-    uint32_t dseg_4_address[2];         /* Data segment 4 address. */
-    uint32_t dseg_4_length;             /* Data segment 4 length. */
-}cont_a64_entry_t;
+struct cont_a64_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define CONTINUE_A64_TYPE 0xA	/* Continuation A64 entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t sys_define;	/* System defined. */
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
+	uint32_t dseg_0_length;	/* Data segment 0 length. */
+	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
+	uint32_t dseg_1_length;	/* Data segment 1 length. */
+	uint32_t dseg_2_address[2];	/* Data segment 2 address. */
+	uint32_t dseg_2_length;	/* Data segment 2 length. */
+	uint32_t dseg_3_address[2];	/* Data segment 3 address. */
+	uint32_t dseg_3_length;	/* Data segment 3 length. */
+	uint32_t dseg_4_address[2];	/* Data segment 4 address. */
+	uint32_t dseg_4_length;	/* Data segment 4 length. */
+};
 
 /*
  * ISP queue - enable LUN entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define ENABLE_LUN_TYPE 0xB     /* Enable LUN entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status not used. */
-    uint32_t reserved_2;
-    uint16_t lun;                       /* Bit 15 is bus number. */
-    uint16_t reserved_4;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  reserved_5;
-    uint8_t  command_count;             /* Number of ATIOs allocated. */
-    uint8_t  immed_notify_count;        /* Number of Immediate Notify */
-                                        /* entries allocated. */
-    uint8_t  group_6_length;            /* SCSI CDB length for group 6 */
-                                        /* commands (2-26). */
-    uint8_t  group_7_length;            /* SCSI CDB length for group 7 */
-                                        /* commands (2-26). */
-    uint16_t timeout;                   /* 0 = 30 seconds, 0xFFFF = disable */
-    uint16_t reserved_6[20];
-}elun_entry_t;
+struct elun_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define ENABLE_LUN_TYPE 0xB	/* Enable LUN entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status not used. */
+	uint32_t reserved_2;
+	uint16_t lun;		/* Bit 15 is bus number. */
+	uint16_t reserved_4;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t reserved_5;
+	uint8_t command_count;	/* Number of ATIOs allocated. */
+	uint8_t immed_notify_count;	/* Number of Immediate Notify */
+	/* entries allocated. */
+	uint8_t group_6_length;	/* SCSI CDB length for group 6 */
+	/* commands (2-26). */
+	uint8_t group_7_length;	/* SCSI CDB length for group 7 */
+	/* commands (2-26). */
+	uint16_t timeout;	/* 0 = 30 seconds, 0xFFFF = disable */
+	uint16_t reserved_6[20];
+};
 
 /*
  * ISP queue - modify LUN entry structure definition.
+ *
+ * Unused by the driver!
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define MODIFY_LUN_TYPE 0xC     /* Modify LUN entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  reserved_3;
-    uint8_t  operators;
-    uint8_t  reserved_4;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  reserved_5;
-    uint8_t  command_count;             /* Number of ATIOs allocated. */
-    uint8_t  immed_notify_count;        /* Number of Immediate Notify */
-                                        /* entries allocated. */
-    uint16_t reserved_6;
-    uint16_t timeout;                   /* 0 = 30 seconds, 0xFFFF = disable */
-    uint16_t reserved_7[20];
-}modify_lun_entry_t;
+struct modify_lun_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define MODIFY_LUN_TYPE 0xC	/* Modify LUN entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t reserved_3;
+	uint8_t operators;
+	uint8_t reserved_4;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t reserved_5;
+	uint8_t command_count;	/* Number of ATIOs allocated. */
+	uint8_t immed_notify_count;	/* Number of Immediate Notify */
+	/* entries allocated. */
+	uint16_t reserved_6;
+	uint16_t timeout;	/* 0 = 30 seconds, 0xFFFF = disable */
+	uint16_t reserved_7[20];
+};
 
 /*
  * ISP queue - immediate notify entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define IMMED_NOTIFY_TYPE 0xD   /* Immediate notify entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;
-    uint8_t  initiator_id;
-    uint8_t  reserved_3;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  reserved_4;
-    uint8_t  tag_value;                 /* Received queue tag message value */
-    uint8_t  tag_type;                  /* Received queue tag message type */
-                                        /* entries allocated. */
-    uint16_t seq_id;
-    uint8_t  scsi_msg[8];               /* SCSI message not handled by ISP */
-    uint16_t reserved_5[8];
-    uint8_t  sense_data[18];
-}notify_entry_t;
+struct notify_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define IMMED_NOTIFY_TYPE 0xD	/* Immediate notify entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;
+	uint8_t initiator_id;
+	uint8_t reserved_3;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t reserved_4;
+	uint8_t tag_value;	/* Received queue tag message value */
+	uint8_t tag_type;	/* Received queue tag message type */
+	/* entries allocated. */
+	uint16_t seq_id;
+	uint8_t scsi_msg[8];	/* SCSI message not handled by ISP */
+	uint16_t reserved_5[8];
+	uint8_t sense_data[18];
+};
 
 /*
  * ISP queue - notify acknowledge entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define NOTIFY_ACK_TYPE 0xE     /* Notify acknowledge entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;
-    uint8_t  initiator_id;
-    uint8_t  reserved_3;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  event;
-    uint16_t seq_id;
-    uint16_t reserved_4[22];
-}nack_entry_t;
+struct nack_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define NOTIFY_ACK_TYPE 0xE	/* Notify acknowledge entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;
+	uint8_t initiator_id;
+	uint8_t reserved_3;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t event;
+	uint16_t seq_id;
+	uint16_t reserved_4[22];
+};
 
 /*
  * ISP queue - Accept Target I/O (ATIO) entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define ACCEPT_TGT_IO_TYPE 6    /* Accept target I/O entry. */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;
-    uint8_t  initiator_id;
-    uint8_t  cdb_len;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  scsi_status;
-    uint8_t  tag_value;                 /* Received queue tag message value */
-    uint8_t  tag_type;                  /* Received queue tag message type */
-    uint8_t  cdb[26];
-    uint8_t  sense_data[18];
-}atio_entry_t;
+struct atio_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define ACCEPT_TGT_IO_TYPE 6	/* Accept target I/O entry. */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;
+	uint8_t initiator_id;
+	uint8_t cdb_len;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t scsi_status;
+	uint8_t tag_value;	/* Received queue tag message value */
+	uint8_t tag_type;	/* Received queue tag message type */
+	uint8_t cdb[26];
+	uint8_t sense_data[18];
+};
 
 /*
  * ISP queue - Continue Target I/O (CTIO) entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define CONTINUE_TGT_IO_TYPE 7  /* CTIO entry */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  initiator_id;
-    uint8_t  reserved_3;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  scsi_status;
-    uint8_t  tag_value;                 /* Received queue tag message value */
-    uint8_t  tag_type;                  /* Received queue tag message type */
-    uint32_t transfer_length;
-    uint32_t residual;
-    uint16_t timeout;                   /* 0 = 30 seconds, 0xFFFF = disable */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint32_t dseg_0_address;            /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address;            /* Data segment 1 address. */
-    uint32_t dseg_1_length;             /* Data segment 1 length. */
-    uint32_t dseg_2_address;            /* Data segment 2 address. */
-    uint32_t dseg_2_length;             /* Data segment 2 length. */
-    uint32_t dseg_3_address;            /* Data segment 3 address. */
-    uint32_t dseg_3_length;             /* Data segment 3 length. */
-}ctio_entry_t;
+struct ctio_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define CONTINUE_TGT_IO_TYPE 7	/* CTIO entry */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t initiator_id;
+	uint8_t reserved_3;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t scsi_status;
+	uint8_t tag_value;	/* Received queue tag message value */
+	uint8_t tag_type;	/* Received queue tag message type */
+	uint32_t transfer_length;
+	uint32_t residual;
+	uint16_t timeout;	/* 0 = 30 seconds, 0xFFFF = disable */
+	uint16_t dseg_count;	/* Data segment count. */
+	uint32_t dseg_0_address;	/* Data segment 0 address. */
+	uint32_t dseg_0_length;	/* Data segment 0 length. */
+	uint32_t dseg_1_address;	/* Data segment 1 address. */
+	uint32_t dseg_1_length;	/* Data segment 1 length. */
+	uint32_t dseg_2_address;	/* Data segment 2 address. */
+	uint32_t dseg_2_length;	/* Data segment 2 length. */
+	uint32_t dseg_3_address;	/* Data segment 3 address. */
+	uint32_t dseg_3_length;	/* Data segment 3 length. */
+};
 
 /*
  * ISP queue - CTIO returned entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define CTIO_RET_TYPE   7       /* CTIO return entry */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  initiator_id;
-    uint8_t  reserved_3;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  scsi_status;
-    uint8_t  tag_value;                 /* Received queue tag message value */
-    uint8_t  tag_type;                  /* Received queue tag message type */
-    uint32_t transfer_length;
-    uint32_t residual;
-    uint16_t timeout;                   /* 0 = 30 seconds, 0xFFFF = disable */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint32_t dseg_0_address;            /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address;            /* Data segment 1 address. */
-    uint16_t dseg_1_length;             /* Data segment 1 length. */
-    uint8_t  sense_data[18];
-}ctio_ret_entry_t;
+struct ctio_ret_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define CTIO_RET_TYPE   7	/* CTIO return entry */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t initiator_id;
+	uint8_t reserved_3;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t scsi_status;
+	uint8_t tag_value;	/* Received queue tag message value */
+	uint8_t tag_type;	/* Received queue tag message type */
+	uint32_t transfer_length;
+	uint32_t residual;
+	uint16_t timeout;	/* 0 = 30 seconds, 0xFFFF = disable */
+	uint16_t dseg_count;	/* Data segment count. */
+	uint32_t dseg_0_address;	/* Data segment 0 address. */
+	uint32_t dseg_0_length;	/* Data segment 0 length. */
+	uint32_t dseg_1_address;	/* Data segment 1 address. */
+	uint16_t dseg_1_length;	/* Data segment 1 length. */
+	uint8_t sense_data[18];
+};
 
 /*
  * ISP queue - CTIO A64 entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define CTIO_A64_TYPE 0xF       /* CTIO A64 entry */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  initiator_id;
-    uint8_t  reserved_3;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  scsi_status;
-    uint8_t  tag_value;                 /* Received queue tag message value */
-    uint8_t  tag_type;                  /* Received queue tag message type */
-    uint32_t transfer_length;
-    uint32_t residual;
-    uint16_t timeout;                   /* 0 = 30 seconds, 0xFFFF = disable */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint32_t reserved_4[2];
-    uint32_t dseg_0_address[2];         /* Data segment 0 address. */
-    uint32_t dseg_0_length;             /* Data segment 0 length. */
-    uint32_t dseg_1_address[2];         /* Data segment 1 address. */
-    uint32_t dseg_1_length;             /* Data segment 1 length. */
-}ctio_a64_entry_t;
+struct ctio_a64_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define CTIO_A64_TYPE 0xF	/* CTIO A64 entry */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t initiator_id;
+	uint8_t reserved_3;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t scsi_status;
+	uint8_t tag_value;	/* Received queue tag message value */
+	uint8_t tag_type;	/* Received queue tag message type */
+	uint32_t transfer_length;
+	uint32_t residual;
+	uint16_t timeout;	/* 0 = 30 seconds, 0xFFFF = disable */
+	uint16_t dseg_count;	/* Data segment count. */
+	uint32_t reserved_4[2];
+	uint32_t dseg_0_address[2];	/* Data segment 0 address. */
+	uint32_t dseg_0_length;	/* Data segment 0 length. */
+	uint32_t dseg_1_address[2];	/* Data segment 1 address. */
+	uint32_t dseg_1_length;	/* Data segment 1 length. */
+};
 
 /*
  * ISP queue - CTIO returned entry structure definition.
  */
-typedef struct
-{
-    uint8_t  entry_type;                /* Entry type. */
-        #define CTIO_A64_RET_TYPE 0xF   /* CTIO A64 returned entry */
-    uint8_t  entry_count;               /* Entry count. */
-    uint8_t  reserved_1;
-    uint8_t  entry_status;              /* Entry Status. */
-    uint32_t reserved_2;
-    uint8_t  lun;                       /* SCSI LUN */
-    uint8_t  initiator_id;
-    uint8_t  reserved_3;
-    uint8_t  target_id;
-    uint32_t option_flags;
-    uint8_t  status;
-    uint8_t  scsi_status;
-    uint8_t  tag_value;                 /* Received queue tag message value */
-    uint8_t  tag_type;                  /* Received queue tag message type */
-    uint32_t transfer_length;
-    uint32_t residual;
-    uint16_t timeout;                   /* 0 = 30 seconds, 0xFFFF = disable */
-    uint16_t dseg_count;                /* Data segment count. */
-    uint16_t reserved_4[7];
-    uint8_t  sense_data[18];
-}ctio_a64_ret_entry_t;
+struct ctio_a64_ret_entry {
+	uint8_t entry_type;	/* Entry type. */
+#define CTIO_A64_RET_TYPE 0xF	/* CTIO A64 returned entry */
+	uint8_t entry_count;	/* Entry count. */
+	uint8_t reserved_1;
+	uint8_t entry_status;	/* Entry Status. */
+	uint32_t reserved_2;
+	uint8_t lun;		/* SCSI LUN */
+	uint8_t initiator_id;
+	uint8_t reserved_3;
+	uint8_t target_id;
+	uint32_t option_flags;
+	uint8_t status;
+	uint8_t scsi_status;
+	uint8_t tag_value;	/* Received queue tag message value */
+	uint8_t tag_type;	/* Received queue tag message type */
+	uint32_t transfer_length;
+	uint32_t residual;
+	uint16_t timeout;	/* 0 = 30 seconds, 0xFFFF = disable */
+	uint16_t dseg_count;	/* Data segment count. */
+	uint16_t reserved_4[7];
+	uint8_t sense_data[18];
+};
 
 /*
  * ISP request and response queue entry sizes
  */
-#define RESPONSE_ENTRY_SIZE     (sizeof(response_t))
-#define REQUEST_ENTRY_SIZE      (sizeof(request_t))
+#define RESPONSE_ENTRY_SIZE	(sizeof(struct response))
+#define REQUEST_ENTRY_SIZE	(sizeof(request_t))
 
 /*
  * ISP status entry - completion status definitions.
  */
-#define CS_COMPLETE         0x0         /* No errors */
-#define CS_INCOMPLETE       0x1         /* Incomplete transfer of cmd. */
-#define CS_DMA              0x2         /* A DMA direction error. */
-#define CS_TRANSPORT        0x3         /* Transport error. */
-#define CS_RESET            0x4         /* SCSI bus reset occurred */
-#define CS_ABORTED          0x5         /* System aborted command. */
-#define CS_TIMEOUT          0x6         /* Timeout error. */
-#define CS_DATA_OVERRUN     0x7         /* Data overrun. */
-#define CS_COMMAND_OVERRUN  0x8         /* Command Overrun. */
-#define CS_STATUS_OVERRUN   0x9         /* Status Overrun. */
-#define CS_BAD_MSG          0xA         /* Bad msg after status phase. */
-#define CS_NO_MSG_OUT       0xB         /* No msg out after selection. */
-#define CS_EXTENDED_ID      0xC         /* Extended ID failed. */
-#define CS_IDE_MSG          0xD         /* Target rejected IDE msg. */
-#define CS_ABORT_MSG        0xE         /* Target rejected abort msg. */
-#define CS_REJECT_MSG       0xF         /* Target rejected reject msg. */
-#define CS_NOP_MSG          0x10        /* Target rejected NOP msg. */
-#define CS_PARITY_MSG       0x11        /* Target rejected parity msg. */
-#define CS_DEV_RESET_MSG    0x12        /* Target rejected dev rst msg. */
-#define CS_ID_MSG           0x13        /* Target rejected ID msg. */
-#define CS_FREE             0x14        /* Unexpected bus free. */
-#define CS_DATA_UNDERRUN    0x15        /* Data Underrun. */
-#define CS_TRANACTION_1     0x18        /* Transaction error 1 */
-#define CS_TRANACTION_2     0x19        /* Transaction error 2 */
-#define CS_TRANACTION_3     0x1a        /* Transaction error 3 */
-#define CS_INV_ENTRY_TYPE   0x1b        /* Invalid entry type */
-#define CS_DEV_QUEUE_FULL   0x1c        /* Device queue full */
-#define CS_PHASED_SKIPPED   0x1d        /* SCSI phase skipped */
-#define CS_ARS_FAILED       0x1e        /* ARS failed */
-#define CS_LVD_BUS_ERROR    0x21        /* LVD bus error */
-#define CS_BAD_PAYLOAD      0x80        /* Driver defined */
-#define CS_UNKNOWN          0x81        /* Driver defined */
-#define CS_RETRY            0x82        /* Driver defined */
+#define CS_COMPLETE         0x0	/* No errors */
+#define CS_INCOMPLETE       0x1	/* Incomplete transfer of cmd. */
+#define CS_DMA              0x2	/* A DMA direction error. */
+#define CS_TRANSPORT        0x3	/* Transport error. */
+#define CS_RESET            0x4	/* SCSI bus reset occurred */
+#define CS_ABORTED          0x5	/* System aborted command. */
+#define CS_TIMEOUT          0x6	/* Timeout error. */
+#define CS_DATA_OVERRUN     0x7	/* Data overrun. */
+#define CS_COMMAND_OVERRUN  0x8	/* Command Overrun. */
+#define CS_STATUS_OVERRUN   0x9	/* Status Overrun. */
+#define CS_BAD_MSG          0xA	/* Bad msg after status phase. */
+#define CS_NO_MSG_OUT       0xB	/* No msg out after selection. */
+#define CS_EXTENDED_ID      0xC	/* Extended ID failed. */
+#define CS_IDE_MSG          0xD	/* Target rejected IDE msg. */
+#define CS_ABORT_MSG        0xE	/* Target rejected abort msg. */
+#define CS_REJECT_MSG       0xF	/* Target rejected reject msg. */
+#define CS_NOP_MSG          0x10	/* Target rejected NOP msg. */
+#define CS_PARITY_MSG       0x11	/* Target rejected parity msg. */
+#define CS_DEV_RESET_MSG    0x12	/* Target rejected dev rst msg. */
+#define CS_ID_MSG           0x13	/* Target rejected ID msg. */
+#define CS_FREE             0x14	/* Unexpected bus free. */
+#define CS_DATA_UNDERRUN    0x15	/* Data Underrun. */
+#define CS_TRANACTION_1     0x18	/* Transaction error 1 */
+#define CS_TRANACTION_2     0x19	/* Transaction error 2 */
+#define CS_TRANACTION_3     0x1a	/* Transaction error 3 */
+#define CS_INV_ENTRY_TYPE   0x1b	/* Invalid entry type */
+#define CS_DEV_QUEUE_FULL   0x1c	/* Device queue full */
+#define CS_PHASED_SKIPPED   0x1d	/* SCSI phase skipped */
+#define CS_ARS_FAILED       0x1e	/* ARS failed */
+#define CS_LVD_BUS_ERROR    0x21	/* LVD bus error */
+#define CS_BAD_PAYLOAD      0x80	/* Driver defined */
+#define CS_UNKNOWN          0x81	/* Driver defined */
+#define CS_RETRY            0x82	/* Driver defined */
 
 /*
  * ISP status entry - SCSI status byte bit definitions.
@@ -1454,282 +970,143 @@
 /*
  * ISP target entries - Option flags bit definitions.
  */
-#define OF_ENABLE_TAG       BIT_1       /* Tagged queue action enable */
-#define OF_DATA_IN          BIT_6       /* Data in to initiator */
-                                        /*  (data from target to initiator) */
-#define OF_DATA_OUT         BIT_7       /* Data out from initiator */
-                                        /*  (data from initiator to target) */
+#define OF_ENABLE_TAG       BIT_1	/* Tagged queue action enable */
+#define OF_DATA_IN          BIT_6	/* Data in to initiator */
+					/*  (data from target to initiator) */
+#define OF_DATA_OUT         BIT_7	/* Data out from initiator */
+					/*  (data from initiator to target) */
 #define OF_NO_DATA          (BIT_7 | BIT_6)
-#define OF_DISC_DISABLED    BIT_15      /* Disconnects disabled */
-#define OF_DISABLE_SDP      BIT_24      /* Disable sending save data ptr */
-#define OF_SEND_RDP         BIT_26      /* Send restore data pointers msg */
-#define OF_FORCE_DISC       BIT_30      /* Disconnects mandatory */
-#define OF_SSTS             BIT_31      /* Send SCSI status */
-
-#if QL1280_TARGET_MODE_SUPPORT
-/*
- * Target Read/Write buffer structure.
- */
-#define TARGET_DATA_OFFSET  4
-#define TARGET_DATA_SIZE    0x2000      /* 8K */
-#define TARGET_INQ_OFFSET   (TARGET_DATA_OFFSET + TARGET_DATA_SIZE)
-#define TARGET_SENSE_SIZE   18
-#define TARGET_BUF_SIZE     36
-
-typedef struct
-{
-    uint8_t         hdr[4];
-    uint8_t         data[TARGET_DATA_SIZE];
-    struct ident    inq;
-}tgt_t;
-#endif
+#define OF_DISC_DISABLED    BIT_15	/* Disconnects disabled */
+#define OF_DISABLE_SDP      BIT_24	/* Disable sending save data ptr */
+#define OF_SEND_RDP         BIT_26	/* Send restore data pointers msg */
+#define OF_FORCE_DISC       BIT_30	/* Disconnects mandatory */
+#define OF_SSTS             BIT_31	/* Send SCSI status */
+
 
 /*
- * BUS parameters/settings structure
- */
-typedef struct
-{
-    uint8_t     id;                    /* Host adapter SCSI id */
-    uint8_t     bus_reset_delay;       /* SCSI bus reset delay. */
-    uint8_t     failed_reset_count;    /* number of time reset failed */
-	uint8_t     unused;
-    uint16_t    device_enables;        /* Device enable bits. */
-    uint16_t    lun_disables;          /* LUN disable bits. */
-    uint16_t    qtag_enables;          /* Tag queue enables. */
-    uint16_t    hiwat;                 /* High water mark per device. */
-    uint8_t     reset_marker       :1;
-    uint8_t     disable_scsi_reset :1;
-    uint8_t     scsi_bus_dead      :1; /* SCSI Bus is Dead, when 5 back to back resets failed */
+ * BUS parameters/settings structure - UNUSED
+ */
+struct bus_param {
+	uint8_t id;		/* Host adapter SCSI id */
+	uint8_t bus_reset_delay;	/* SCSI bus reset delay. */
+	uint8_t failed_reset_count;	/* number of time reset failed */
+	uint8_t unused;
+	uint16_t device_enables;	/* Device enable bits. */
+	uint16_t lun_disables;	/* LUN disable bits. */
+	uint16_t qtag_enables;	/* Tag queue enables. */
+	uint16_t hiwat;		/* High water mark per device. */
+	uint8_t reset_marker:1;
+	uint8_t disable_scsi_reset:1;
+	uint8_t scsi_bus_dead:1;	/* SCSI Bus is Dead, when 5 back to back resets failed */
+};
+
+
+struct qla_driver_setup {
+	uint32_t no_sync:1;
+	uint32_t no_wide:1;
+	uint32_t no_ppr:1;
+	uint32_t no_nvram:1;
+	uint16_t sync_mask;
+	uint16_t wide_mask;
+	uint16_t ppr_mask;
+};
 
-}bus_param_t;
 
 /*
  * Linux Host Adapter structure
  */
-typedef struct scsi_qla_host
-{
-    /* Linux adapter configuration data */
-    struct Scsi_Host *host;             /* pointer to host data */
-    struct scsi_qla_host   *next;
-    device_reg_t     *iobase;           /* Base Memory-mapped I/O address */
-    uint8_t          pci_bus;
-    uint8_t          pci_device_fn;
-    uint8_t          devnum;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
-    struct pci_dev *pdev;
+struct scsi_qla_host {
+	/* Linux adapter configuration data */
+	struct Scsi_Host *host;	/* pointer to host data */
+	struct scsi_qla_host *next;
+	struct device_reg *iobase;	/* Base Memory-mapped I/O address */
+
+	unsigned char *mmpbase;	/* memory mapped address */
+	unsigned long host_no;
+	unsigned long instance;
+	struct pci_dev *pdev;
+	uint32_t device_id;
+	uint8_t pci_bus;
+	uint8_t pci_device_fn;
+	uint8_t devnum;
+	uint8_t revision;
+	uint8_t ports;
+
+	unsigned long actthreads;
+	unsigned long isr_count;	/* Interrupt count */
+	unsigned long spurious_int;
+
+	/* Outstandings ISP commands. */
+	struct srb *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
+
+	/* BUS configuration data */
+	struct bus_param bus_settings[MAX_BUSES];
+
+#if 0
+	/* bottom half run queue */
+	struct tq_struct run_qla_bh;
 #endif
-    volatile unsigned char  *mmpbase;      /* memory mapped address */
-    unsigned long            host_no;
-    unsigned long            instance;
-    uint8_t           revision;
-    uint8_t           ports;
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,0)
-    spinlock_t               spin_lock;
-#endif
-    volatile unsigned char   cpu_lock_count[NR_CPUS];
-    unsigned long            actthreads;
-    unsigned long            qthreads;
-    unsigned long            isr_count;        /* Interrupt count */
-    unsigned long            spurious_int;
-
-    uint32_t           device_id;
-
-    /* Outstandings ISP commands. */
-    srb_t           *outstanding_cmds[MAX_OUTSTANDING_COMMANDS];
 
-    /* BUS configuration data */
-    bus_param_t bus_settings[MAX_BUSES];
-
-    /* Device LUN queues. */
-    scsi_lu_t       *dev[MAX_EQ];      /* Logical unit queues */
+	/* Received ISP mailbox data. */
+	volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
 
 #ifdef UNUSED
-    /* Interrupt lock, and data */
-    uint8_t          intr_lock;         /* Lock for interrupt locking */
+	struct timer_list dev_timer[MAX_TARGETS];
 #endif
 
-    /* bottom half run queue */
-    struct tq_struct run_qla_bh;
-
-    /* Received ISP mailbox data. */
-    volatile uint16_t mailbox_out[MAILBOX_REGISTER_COUNT];
-
-#ifdef UNUSED
-    /* ISP ring lock, rings, and indexes */
-    uint8_t          ring_lock;         /* ISP ring lock */
-    struct timer_list        dev_timer[MAX_TARGETS];
+	dma_addr_t request_dma;		/* Physical Address */
+	request_t *request_ring;	/* Base virtual address */
+	request_t *request_ring_ptr;	/* Current address. */
+	uint16_t req_ring_index;	/* Current index. */
+	uint16_t req_q_cnt;		/* Number of available entries. */
+
+	dma_addr_t response_dma;	/* Physical address. */
+	struct response *response_ring;	/* Base virtual address */
+	struct response *response_ring_ptr;	/* Current address. */
+	uint16_t rsp_ring_index;	/* Current index. */
+
+#if WATCHDOGTIMER
+	/* Watchdog queue, lock and total timer */
+	uint8_t watchdog_q_lock;	/* Lock for watchdog queue */
+	struct srb *wdg_q_first;	/* First job on watchdog queue */
+	struct srb *wdg_q_last;	/* Last job on watchdog queue */
+	uint32_t total_timeout;	/* Total timeout (quantum count) */
+	uint32_t watchdogactive;
 #endif
 
-    request_t       req[REQUEST_ENTRY_CNT+1];
-    response_t      res[RESPONSE_ENTRY_CNT+1];
-    unsigned long   request_dma;        /* Physical address. */
-    request_t       *request_ring;      /* Base virtual address */
-    request_t       *request_ring_ptr;  /* Current address. */
-    uint16_t        req_ring_index;     /* Current index. */
-    uint16_t        req_q_cnt;          /* Number of available entries. */
-
-    unsigned long   response_dma;       /* Physical address. */
-    response_t      *response_ring;     /* Base virtual address */
-    response_t      *response_ring_ptr; /* Current address. */
-    uint16_t        rsp_ring_index;     /* Current index. */
-
-#if QL1280_TARGET_MODE_SUPPORT
-    /* Target buffer and sense data. */
-    uint32_t        tbuf_dma;           /* Physical address. */
-    tgt_t           *tbuf;
-    uint32_t        tsense_dma;         /* Physical address. */
-    uint8_t         *tsense;
-#endif
+	struct srb *done_q_first;	/* First job on done queue */
+	struct srb *done_q_last;	/* Last job on done queue */
 
-#if  WATCHDOGTIMER
-    /* Watchdog queue, lock and total timer */
-    uint8_t          watchdog_q_lock;   /* Lock for watchdog queue */
-    srb_t           *wdg_q_first;       /* First job on watchdog queue */
-    srb_t           *wdg_q_last;        /* Last job on watchdog queue */
-    uint32_t         total_timeout;     /* Total timeout (quantum count) */
-    uint32_t         watchdogactive;
-#endif
-
-    srb_t           *done_q_first;       /* First job on done queue */
-    srb_t           *done_q_last;        /* Last job on done queue */
+	struct completion *mailbox_wait;
 
-    volatile struct
-    {
-        uint32_t     watchdog_enabled        :1;   /* 0 */
-        uint32_t     mbox_int                :1;   /* 1 */
-        uint32_t     mbox_busy               :1;   /* 2 */
-        uint32_t     online                  :1;   /* 3 */
-        uint32_t     reset_marker            :1;   /* 4 */
-        uint32_t     isp_abort_needed        :1;   /* 5 */
-        uint32_t     pci_64bit_slot          :1;   /* 6 */
-        uint32_t     disable_host_adapter    :1;   /* 7 */
-        uint32_t     reset_active            :1;   /* 8 */
-        uint32_t     abort_isp_active        :1;   /* 9 */
-        uint32_t     disable_risc_code_load  :1;   /* 10 */
-        uint32_t     enable_64bit_addressing :1;   /* 11 */
-#define QLA1280_IN_ISR_BIT      12
-        uint32_t     in_isr                  :1;   /* 12 */
-        uint32_t     in_abort                :1;   /* 13 */
-        uint32_t     in_reset                :1;   /* 14 */
-       uint32_t     dpc                     :1;   /* 15 */
-       uint32_t     dpc_sched               :1;   /* 16 */
-       uint32_t     interrupts_on               :1;   /* 17 */
-    }flags;
+	volatile struct {
+		uint32_t mbox_busy:1;			/* 0 */
+		uint32_t online:1;			/* 1 */
+		uint32_t reset_marker:1;		/* 2 */
+		uint32_t disable_host_adapter:1;	/* 4 */
+		uint32_t reset_active:1;		/* 5 */
+		uint32_t abort_isp_active:1;		/* 6 */
+		uint32_t disable_risc_code_load:1;	/* 7 */
+		uint32_t enable_64bit_addressing:1;	/* 8 */
+		uint32_t in_reset:1;			/* 9 */
+		uint32_t ints_enabled:1;
+		uint32_t ignore_nvram:1;
+#ifdef __ia64__
+		uint32_t use_pci_vchannel:1;
+#endif
+	} flags;
 
-}scsi_qla_host_t;
+	struct nvram nvram;
+	int nvram_valid;
+};
 
 /*
  * Macros to help code, maintain, etc.
  */
-#define SUBDEV(b, t, l)  ( (b << (MAX_T_BITS + MAX_L_BITS)) | (t << MAX_L_BITS) | l)
-#define LU_Q(ha, b, t, l)  (ha->dev[SUBDEV(b, t, l)])
-
-/*
- * Locking Macro Definitions
- *
- * LOCK/UNLOCK definitions are lock/unlock primitives for multi-processor
- * or spl/splx for uniprocessor.
- */
-#define QLA1280_HIER   HBA_HIER_BASE  /* Locking hierarchy base for hba */
-
-#define QLA1280_WATCHDOG_Q_LOCK(ha, p)   
-#define QLA1280_WATCHDOG_Q_UNLOCK(ha, p) 
-
-#define QLA1280_SCSILU_LOCK(q)  
-#define QLA1280_SCSILU_UNLOCK(q) 
-
-#define QLA1280_INTR_LOCK(ha)
-#define QLA1280_INTR_UNLOCK(ha)     
+#define SUBDEV(b, t, l)		((b << (MAX_T_BITS + MAX_L_BITS)) | (t << MAX_L_BITS) | l)
+#define LU_Q(ha, b, t, l)	(ha->dev[SUBDEV(b, t, l)])
 
-#define QLA1280_RING_LOCK(ha)  
-#define QLA1280_RING_UNLOCK(ha)   
-
-#if defined(__cplusplus)
-}
-#endif
-/*
- *  Linux - SCSI Driver Interface Function Prototypes.
- */
-int qla1280_proc_info ( char *, char **, off_t, int, int, int);
-const char * qla1280_info(struct Scsi_Host *host);
-int qla1280_detect(Scsi_Host_Template *);
-int qla1280_release(struct Scsi_Host *);
-const char * qla1280_info(struct Scsi_Host *);
-int qla1280_queuecommand(Scsi_Cmnd *, void (* done)(Scsi_Cmnd *));
-int qla1280_abort(Scsi_Cmnd *);
-int qla1280_reset(Scsi_Cmnd *, unsigned int);
-int qla1280_biosparam(Disk *, kdev_t, int[]);
-void qla1280_intr_handler(int, void *, struct pt_regs *);
-void qla1280_setup(char *s, int *dummy);
-#if defined(__386__)
-#  define QLA1280_BIOSPARAM  qla1280_biosparam
-#else
-#  define QLA1280_BIOSPARAM  NULL
-#endif
-
-/*
- * Scsi_Host_template (see hosts.h) 
- * Device driver Interfaces to mid-level SCSI driver.
- */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,95)
-/* This interface is now obsolete !!! */ 
-#define QLA1280_LINUX_TEMPLATE {		                 \
-        next:           NULL,                                    \
-        usage_count:    NULL,                                    \
-	proc_dir:		NULL,          	                 \
-	proc_info:		NULL,	                         \
-	name:			"Qlogic ISP 1280",               \
-	detect:			qla1280_detect,	                 \
-	release:		qla1280_release,                 \
-	info:			qla1280_info,	                 \
-        command:        NULL,                                    \
-	queuecommand:	qla1280_queuecommand,	                 \
-	abort:			qla1280_abort,	                 \
-	reset:			qla1280_reset,	                 \
-        slave_attach:   NULL,                                    \
-	bios_param:		QLA1280_BIOSPARAM,               \
-	can_queue:		255, /* MAX_OUTSTANDING_COMMANDS */   \
-	this_id:		-1,  /* scsi id of host adapter */        \
-	sg_tablesize:	SG_ALL,	 \
-	cmd_per_lun:	3,	  /* max commands per lun */	       \
-	present:	    0,    /* number of 1280s present */	       \
-	unchecked_isa_dma: 0, /* no memeory DMA restrictions */    \
-	use_clustering:	ENABLE_CLUSTERING			               \
-}
-#else
-
-#define QLA1280_LINUX_TEMPLATE {		                 \
-	next: NULL,						\
-	module: NULL,						\
-	proc_dir: NULL,						\
-	proc_info: qla1280_proc_info,				\
-	name:			"Qlogic ISP 1280\1080",               \
-	detect: qla1280_detect,					\
-	release: qla1280_release,				\
-	info: qla1280_info,					\
-	ioctl: NULL,						\
-	command: NULL,						\
-	queuecommand: qla1280_queuecommand,			\
-	eh_strategy_handler: NULL,				\
-	eh_abort_handler: NULL,					\
-	eh_device_reset_handler: NULL,				\
-	eh_bus_reset_handler: NULL,				\
-	eh_host_reset_handler: NULL,				\
-	abort: qla1280_abort,					\
-	reset: qla1280_reset,					\
-	slave_attach: NULL,					\
-	bios_param: QLA1280_BIOSPARAM,				\
-	can_queue: 255,		/* max simultaneous cmds      */\
-	this_id: -1,		/* scsi id of host adapter    */\
-	sg_tablesize: SG_ALL,	/* max scatter-gather cmds    */\
-	cmd_per_lun: 3,		/* cmds per lun (linked cmds) */\
-	present: 0,		/* number of 7xxx's present   */\
-	unchecked_isa_dma: 0,	/* no memory DMA restrictions */\
-	use_clustering: ENABLE_CLUSTERING,			\
-	use_new_eh_code: 0,					\
-	emulated: 0					        \
-}
-#endif
+#endif				/* HOSTS_C */
 
 
-#endif /* _IO_HBA_QLA1280_H */
+#endif				/* _IO_HBA_QLA1280_H */
diff -urN linux-2.4.23-pre6/drivers/scsi/sym53c8xx_2/Makefile linux-2.4.23-pre7/drivers/scsi/sym53c8xx_2/Makefile
--- linux-2.4.23-pre6/drivers/scsi/sym53c8xx_2/Makefile	2001-11-09 15:22:54.000000000 -0800
+++ linux-2.4.23-pre7/drivers/scsi/sym53c8xx_2/Makefile	2003-10-09 17:48:22.000000000 -0700
@@ -1,14 +1,14 @@
-# File: drivers/sym53c8xx/Makefile
+# File: drivers/scsi/sym53c8xx_2/Makefile
 # Makefile for the NCR/SYMBIOS/LSI 53C8XX PCI SCSI controllers driver.
 
-list-multi := sym53c8xx.o
-sym53c8xx-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_misc.o sym_nvram.o
-obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx.o
+list-multi := sym53c8xx_2.o
+sym53c8xx_2-objs := sym_fw.o sym_glue.o sym_hipd.o sym_malloc.o sym_misc.o sym_nvram.o
+obj-$(CONFIG_SCSI_SYM53C8XX_2) := sym53c8xx_2.o
 
 EXTRA_CFLAGS += -I.
 
-sym53c8xx.o: $(sym53c8xx-objs)
-	$(LD) -r -o $@ $(sym53c8xx-objs)
+sym53c8xx_2.o: $(sym53c8xx_2-objs)
+	$(LD) -r -o $@ $(sym53c8xx_2-objs)
 
 include $(TOPDIR)/Rules.make
 
diff -urN linux-2.4.23-pre6/drivers/sound/.indent.pro linux-2.4.23-pre7/drivers/sound/.indent.pro
--- linux-2.4.23-pre6/drivers/sound/.indent.pro	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/sound/.indent.pro	1997-09-30 08:46:46.000000000 -0700
@@ -0,0 +1,8 @@
+-bad 
+-bap 
+-nfca
+-bl 
+-psl 
+-di16
+-lp
+-ip5
diff -urN linux-2.4.23-pre6/drivers/sound/.version linux-2.4.23-pre7/drivers/sound/.version
--- linux-2.4.23-pre6/drivers/sound/.version	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/sound/.version	1997-11-09 23:01:54.000000000 -0800
@@ -0,0 +1,2 @@
+3.8s
+0x030804
diff -urN linux-2.4.23-pre6/drivers/usb/Config.in linux-2.4.23-pre7/drivers/usb/Config.in
--- linux-2.4.23-pre6/drivers/usb/Config.in	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/Config.in	2003-10-09 17:48:22.000000000 -0700
@@ -110,4 +110,7 @@
       dep_tristate '  Alcatel Speedtouch USB support' CONFIG_USB_SPEEDTOUCH $CONFIG_ATM $CONFIG_USB
    fi
 fi
+
+source drivers/usb/gadget/Config.in
+
 endmenu
diff -urN linux-2.4.23-pre6/drivers/usb/devio.c linux-2.4.23-pre7/drivers/usb/devio.c
--- linux-2.4.23-pre6/drivers/usb/devio.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/devio.c	2003-10-09 17:48:22.000000000 -0700
@@ -1114,7 +1114,7 @@
                        usb_driver_release_interface (driver, ifp);
                        up (&driver->serialize);
                } else
-                       return -ENODATA;
+                       retval = -ENODATA;
                break;
 
        /* let kernel drivers try to (re)bind to the interface */
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/Config.in linux-2.4.23-pre7/drivers/usb/gadget/Config.in
--- linux-2.4.23-pre6/drivers/usb/gadget/Config.in	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/Config.in	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,69 @@
+#
+# USB device-side configuration
+# for 2.4 kbuild, drivers/usb/gadget/Config.in
+#
+# Long term, this likely doesn't all belong in one directory
+# Plan to split it up eventually.
+#
+mainmenu_option next_comment
+comment 'Support for USB gadgets'
+
+bool 'Support for USB Gadgets' CONFIG_USB_GADGET
+if [ "$CONFIG_USB_GADGET" = "y" ]; then
+  
+  #
+  # really want _exactly one_ device controller driver at a time,
+  # since they control compile options for gadget drivers.
+  #
+  comment 'USB Peripheral Controller Drivers'
+  
+  # assume all the dependencies may be undefined ("== true", yeech)
+  if [ "$CONFIG_PCI" = "y" ] ; then
+    tristate '  NetChip 2280 support' CONFIG_USB_NET2280
+    define_tristate CONFIG_USB_GADGET_CONTROLLER $CONFIG_USB_NET2280
+  fi
+
+  if [ "$CONFIG_USB_GADGET_CONTROLLER" = "y" -o "$CONFIG_USB_GADGET_CONTROLLER" = "m" ] ; then
+
+  #
+  # no reason not to enable more than one gadget driver module, but
+  # for static linking that would make no sense since the usb model
+  # has exactly one of these upstream connections and only one
+  # lowest-level driver can control it.
+  #
+  # gadget drivers are compiled to work on specific hardware, since
+  #
+  # (a) gadget driver need hardware-specific configuration, like what
+  #     endpoint names and numbers to use, maxpacket sizes, etc
+  #
+  # (b) specific hardware features like iso endpoints may be required
+  #
+  comment 'USB Gadget Drivers'
+
+  dep_tristate '  Gadget Zero (DEVELOPMENT)' CONFIG_USB_ZERO $CONFIG_USB_GADGET_CONTROLLER
+  if [ "$CONFIG_USB_ZERO" = "y" -o "$CONFIG_USB_ZERO" = "m" ]; then
+      if [ "$CONFIG_USB_NET2280" = "y" -o "$CONFIG_USB_NET2280" = "m" ]; then
+  	define_bool CONFIG_USB_ZERO_NET2280 y
+      fi
+      if [ "$CONFIG_USB_PXA2XX" = "y" -o "$CONFIG_USB_PXA2XX" = "m" ]; then
+  	define_bool CONFIG_USB_ZERO_PXA2XX y
+      fi
+      # ...
+  fi
+  
+  dep_tristate '  Ethernet Gadget (EXPERIMENTAL)' CONFIG_USB_ETH $CONFIG_USB_GADGET_CONTROLLER
+  if [ "$CONFIG_USB_ETH" = "y" -o "$CONFIG_USB_ETH" = "m" ]; then
+      if [ "$CONFIG_USB_NET2280" = "y" -o "$CONFIG_USB_NET2280" = "m" ]; then
+  	define_bool CONFIG_USB_ETH_NET2280 y
+      fi
+      if [ "$CONFIG_USB_PXA2XX" = "y" -o "$CONFIG_USB_PXA2XX" = "m" ]; then
+  	define_bool CONFIG_USB_ETH_PXA2XX y
+      fi
+      # ...
+  fi
+  
+  # ... or other gadget drivers:  printer class, storage, hid, etc ...
+
+  fi
+fi
+endmenu
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/Makefile linux-2.4.23-pre7/drivers/usb/gadget/Makefile
--- linux-2.4.23-pre6/drivers/usb/gadget/Makefile	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/Makefile	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,31 @@
+#
+# Makefile for USB peripheral controller and gadget drivers
+# for kbuild 2.4
+#
+
+# for static linking
+O_TARGET	:= built-in.o
+
+list-multi			:= g_zero.o g_ether.o
+
+obj-$(CONFIG_USB_NET2280)	+= net2280.o
+
+# only one of these may be statically linked ...
+controller-$(CONFIG_USB_NET2280)	+= net2280.o
+
+# ... and only one of these, too; kbuild/kconfig don't help though.
+g_zero-objs			:= zero.o usbstring.o
+obj-$(CONFIG_USB_ZERO)		+= g_zero.o
+
+g_ether-objs			:= ether.o usbstring.o
+obj-$(CONFIG_USB_ETH)		+= g_ether.o
+
+
+export-objs :=			$(controller-y) $(controller-m)
+
+include $(TOPDIR)/Rules.make
+
+g_zero.o: $(g_zero-objs)
+	$(LD) -r -o $@ $(g_zero-objs)
+g_ether.o: $(g_ether-objs)
+	$(LD) -r -o $@ $(g_ether-objs)
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/ether.c linux-2.4.23-pre7/drivers/usb/gadget/ether.c
--- linux-2.4.23-pre6/drivers/usb/gadget/ether.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/ether.c	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,1879 @@
+/*
+ * ether.c -- Ethernet gadget driver, with CDC and non-CDC options
+ *
+ * Copyright (C) 2003 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+
+#define DEBUG 1
+// #define VERBOSE
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/uts.h>
+#include <linux/version.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include <asm/unaligned.h>
+
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+
+#include <linux/random.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * Ethernet gadget driver -- with CDC and non-CDC options
+ *
+ * CDC Ethernet is the standard USB solution for sending Ethernet frames
+ * using USB.  Real hardware tends to use the same framing protocol but look
+ * different for control features.  And Microsoft pushes their own approach
+ * (RNDIS) instead of the standard.
+ *
+ * There's some hardware that can't talk CDC.  We make that hardware
+ * implement a "minimalist" vendor-agnostic CDC core:  same framing, but
+ * link-level setup only requires activating the configuration.
+ */
+
+#define DRIVER_DESC		"Ethernet Gadget"
+#define DRIVER_VERSION		"Bastille Day 2003"
+
+static const char shortname [] = "ether";
+static const char driver_desc [] = DRIVER_DESC;
+
+#define MIN_PACKET	sizeof(struct ethhdr)
+#define	MAX_PACKET	ETH_DATA_LEN	/* biggest packet we'll rx/tx */
+#define RX_EXTRA	20		/* guard against rx overflows */
+
+/* FIXME allow high speed jumbograms */
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef container_of
+#define container_of		list_entry
+#endif
+
+/* 2.5 modified and renamed these */
+
+#define work_struct		tq_struct
+#define INIT_WORK		INIT_TQUEUE
+#define schedule_work		schedule_task
+#define	flush_scheduled_work	flush_scheduled_tasks
+
+/*-------------------------------------------------------------------------*/
+
+struct eth_dev {
+	spinlock_t		lock;
+	struct usb_gadget	*gadget;
+	struct usb_request	*req;		/* for control responses */
+
+	u8			config;
+	struct usb_ep		*in_ep, *out_ep, *status_ep;
+	const struct usb_endpoint_descriptor
+				*in, *out, *status;
+	struct list_head	tx_reqs, rx_reqs;
+
+	struct net_device	*net;
+	struct net_device_stats	stats;
+	atomic_t		tx_qlen;
+
+	struct work_struct	work;
+	unsigned long		todo;
+#define	WORK_RX_MEMORY		0
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* This driver keeps a variable number of requests queued, more at
+ * high speeds.  (Numbers are just educated guesses, untuned.)
+ * Shrink the queue if memory is tight, or make it bigger to
+ * handle bigger traffic bursts between IRQs (assuming hw dma queues)
+ */
+
+static unsigned qmult = 4;
+
+#define HS_FACTOR	5
+
+#define qlen(gadget) \
+	(qmult*((gadget->speed == USB_SPEED_HIGH) ? HS_FACTOR : 1))
+
+/* defer IRQs on highspeed TX */
+#define TX_DELAY	8
+
+
+MODULE_PARM (qmult, "i");
+MODULE_PARM_DESC (qmult, "rx/tx buffering factor");
+
+/*-------------------------------------------------------------------------*/
+
+/* Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with a protocol-incompatible driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures.
+ */
+#define DRIVER_VENDOR_NUM	0x0525		/* NetChip */
+#define DRIVER_PRODUCT_NUM	0xa4a1		/* Linux-USB Ethernet Gadget */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * hardware-specific configuration, controlled by which device
+ * controller driver was configured.
+ *
+ * CHIP ... hardware identifier
+ * DRIVER_VERSION_NUM ... alerts the host side driver to differences
+ * EP0_MAXPACKET ... controls packetization of control requests
+ * EP_*_NAME ... which endpoints do we use for which purpose?
+ * EP_*_NUM ... numbers for them (often limited by hardware)
+ * HIGHSPEED ... define if ep0 and descriptors need high speed support
+ * MAX_USB_POWER ... define if we use other than 100 mA bus current
+ * SELFPOWER ... unless we can run on bus power, USB_CONFIG_ATT_SELFPOWER
+ * WAKEUP ... if hardware supports remote wakeup AND we will issue the
+ * 	usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP
+ *
+ * hw_optimize(gadget) ... for any hardware tweaks we want to kick in
+ * 	before we enable our endpoints
+ *
+ * add other defines for other portability issues, like hardware that
+ * for some reason doesn't handle full speed bulk maxpacket of 64.
+ */
+
+#define DEV_CONFIG_VALUE	3	/* some hardware cares */
+
+/* #undef on hardware that can't implement CDC */
+#define	DEV_CONFIG_CDC
+
+/*
+ * NetChip 2280, PCI based.
+ *
+ * use DMA with fat fifos for all data traffic, PIO for the status channel
+ * where its 64 byte maxpacket ceiling is no issue.
+ *
+ * performance note:  only PIO needs per-usb-packet IRQs (ep0, ep-e, ep-f)
+ * otherwise IRQs are per-Ethernet-packet unless TX_DELAY and chaining help.
+ */
+#ifdef	CONFIG_USB_ETH_NET2280
+#define CHIP			"net2280"
+#define DRIVER_VERSION_NUM	0x0111
+#define EP0_MAXPACKET		64
+static const char EP_OUT_NAME [] = "ep-a";
+#define EP_OUT_NUM	1
+static const char EP_IN_NAME [] = "ep-b";
+#define EP_IN_NUM	2
+static const char EP_STATUS_NAME [] = "ep-f";
+#define EP_STATUS_NUM	3
+#define HIGHSPEED
+/* specific hardware configs could be bus-powered */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* supports remote wakeup, but this driver doesn't */
+
+extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode);
+
+static inline void hw_optimize (struct usb_gadget *gadget)
+{
+	/* we can have bigger ep-a/ep-b fifos (2KB each, 4 USB packets
+	 * for highspeed bulk) because we're not using ep-c/ep-d.
+	 */
+	net2280_set_fifo_mode (gadget, 1);
+}
+#endif
+
+/*
+ * PXA-2xx UDC:  widely used in second gen Linux-capable ARM PDAs
+ * and other products.
+ *
+ * multiple interfaces (or altsettings) aren't usable.  so this hardware
+ * can't implement CDC, which needs both capabilities.
+ */
+#ifdef	CONFIG_USB_ETH_PXA2XX
+#undef	DEV_CONFIG_CDC
+#define CHIP			"pxa2xx"
+#define DRIVER_VERSION_NUM	0x0113
+#define EP0_MAXPACKET		16
+static const char EP_OUT_NAME [] = "ep2out-bulk";
+#define EP_OUT_NUM	2
+static const char EP_IN_NAME [] = "ep1in-bulk";
+#define EP_IN_NUM	1
+/* doesn't support bus-powered operation */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* supports remote wakeup, but this driver doesn't */
+
+/* no hw optimizations to apply */
+#define hw_optimize(g) do {} while (0);
+#endif
+
+/*
+ * SA-1100 UDC:  widely used in first gen Linux-capable PDAs.
+ *
+ * can't have a notification endpoint, since there are only the two
+ * bulk-capable ones.  the CDC spec allows that.
+ */
+#ifdef	CONFIG_USB_ETH_SA1100
+#define CHIP			"sa1100"
+#define DRIVER_VERSION_NUM	0x0115
+#define EP0_MAXPACKET		8
+static const char EP_OUT_NAME [] = "ep1out-bulk";
+#define EP_OUT_NUM	1
+static const char EP_IN_NAME [] = "ep2in-bulk";
+#define EP_IN_NUM	2
+// EP_STATUS_NUM is undefined
+/* doesn't support bus-powered operation */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* doesn't support remote wakeup? */
+
+/* no hw optimizations to apply */
+#define hw_optimize(g) do {} while (0);
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef EP0_MAXPACKET
+#	error Configure some USB peripheral controller driver!
+#endif
+
+/* We normally expect hardware that can talk CDC.  That involves
+ * using multiple interfaces and altsettings, and maybe a status
+ * interrupt.  Driver binding to be done according to USB-IF class,
+ * though you can use different VENDOR and PRODUCT numbers if you
+ * want (and they're officially assigned).
+ * 
+ * For hardware that can't talk CDC, we use the same vendor ID that
+ * ARM Linux has used for ethernet-over-usb, both with sa1100 and
+ * with pxa250.  We're protocol-compatible, if the host-side drivers
+ * use the endpoint descriptors.  DRIVER_VERSION_NUM is nonzero, so
+ * drivers that need to hard-wire endpoint numbers have a hook.
+ */
+#ifdef	DEV_CONFIG_CDC
+#define	DEV_CONFIG_CLASS	USB_CLASS_COMM
+#else	
+#define	DEV_CONFIG_CLASS	USB_CLASS_VENDOR_SPEC
+#undef	EP_STATUS_NUM
+#undef	DRIVER_VENDOR_NUM
+#undef	DRIVER_PRODUCT_NUM
+#define	DRIVER_VENDOR_NUM	0x049f
+#define	DRIVER_PRODUCT_NUM	0x505a
+#endif /* CONFIG_CDC_ETHER */
+
+/* power usage is config specific.
+ * hardware that supports remote wakeup defaults to disabling it.
+ */
+
+#ifndef	SELFPOWER
+/* default: say we rely on bus power */
+#define SELFPOWER	0
+/* else:
+ * - SELFPOWER value must be USB_CONFIG_ATT_SELFPOWER
+ * - MAX_USB_POWER may be nonzero.
+ */
+#endif
+
+#ifndef	MAX_USB_POWER
+/* any hub supports this steady state bus power consumption */
+#define MAX_USB_POWER	100	/* mA */
+#endif
+
+#ifndef	WAKEUP
+/* default: this driver won't do remote wakeup */
+#define WAKEUP		0
+/* else value must be USB_CONFIG_ATT_WAKEUP */
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#define xprintk(d,level,fmt,args...) \
+	printk(level "%s %s: " fmt , shortname , (d)->gadget->dev.bus_id , \
+		## args)
+
+#ifdef DEBUG
+#undef DEBUG
+#define DEBUG(dev,fmt,args...) \
+	xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DEBUG(dev,fmt,args...) \
+	do { } while (0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDEBUG	DEBUG
+#else
+#define VDEBUG(dev,fmt,args...) \
+	do { } while (0)
+#endif /* DEBUG */
+
+#define ERROR(dev,fmt,args...) \
+	xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+	xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+	xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-------------------------------------------------------------------------*/
+
+/* USB DRIVER HOOKUP (to the hardware driver, below us), mostly
+ * ep0 implementation:  descriptors, config management, setup().
+ * also optional class-specific notification interrupt transfer.
+ */
+
+/*
+ * DESCRIPTORS ... most are static, but strings and (full) configuration
+ * descriptors are built on demand.  Notice how most of the cdc descriptors
+ * aren't needed in the "minimalist" mode.
+ */
+
+#define STRING_MANUFACTURER		1
+#define STRING_PRODUCT			2
+#define STRING_ETHADDR			3
+#define STRING_DATA			4
+#define STRING_CONTROL			5
+
+#define USB_BUFSIZ	256		/* holds our biggest descriptor */
+
+/*
+ * This device advertises one configuration.
+ */
+static const struct usb_device_descriptor
+device_desc = {
+	.bLength =		sizeof device_desc,
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
+
+	.bDeviceClass =		DEV_CONFIG_CLASS,
+	.bDeviceSubClass =	0,
+	.bDeviceProtocol =	0,
+	.bMaxPacketSize0 =	EP0_MAXPACKET,
+
+	.idVendor =		__constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
+	.idProduct =		__constant_cpu_to_le16 (DRIVER_PRODUCT_NUM),
+	.bcdDevice =		__constant_cpu_to_le16 (DRIVER_VERSION_NUM),
+	.iManufacturer =	STRING_MANUFACTURER,
+	.iProduct =		STRING_PRODUCT,
+	.bNumConfigurations =	1,
+};
+
+static const struct usb_config_descriptor
+eth_config = {
+	.bLength =		sizeof eth_config,
+	.bDescriptorType =	USB_DT_CONFIG,
+
+	/* compute wTotalLength on the fly */
+#ifdef	DEV_CONFIG_CDC
+	.bNumInterfaces =	2,
+#else
+	.bNumInterfaces =	1,
+#endif
+	.bConfigurationValue =	DEV_CONFIG_VALUE,
+	.iConfiguration =	STRING_PRODUCT,
+	.bmAttributes =		USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP,
+	.bMaxPower =		(MAX_USB_POWER + 1) / 2,
+};
+
+#ifdef	DEV_CONFIG_CDC
+
+/*
+ * Compared to the "minimalist" non-CDC model, the CDC model adds
+ * three class descriptors, two interface descrioptors, and a status
+ * endpoint.  Both have a "data" interface and two bulk endpoints.
+ * There are also differences in how control requests are handled.
+ */
+
+/* master comm interface optionally has a status notification endpoint */
+
+static const struct usb_interface_descriptor
+control_intf = {
+	.bLength =		sizeof control_intf,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bInterfaceNumber =	0,
+#ifdef	EP_STATUS_NUM
+	.bNumEndpoints =	1,
+#else
+	.bNumEndpoints =	0,
+#endif
+	.bInterfaceClass =	USB_CLASS_COMM,
+	.bInterfaceSubClass =	6,	/* ethernet control model */
+	.bInterfaceProtocol =	0,
+	.iInterface =		STRING_CONTROL,
+};
+
+/* "Header Functional Descriptor" from CDC spec  5.2.3.1 */
+struct header_desc {
+	u8	bLength;
+	u8	bDescriptorType;
+	u8	bDescriptorSubType;
+
+	u16	bcdCDC;
+} __attribute__ ((packed));
+
+static const struct header_desc header_desc = {
+	.bLength =		sizeof header_desc,
+	.bDescriptorType =	0x24,
+	.bDescriptorSubType =	0,
+
+	.bcdCDC =		__constant_cpu_to_le16 (0x0110),
+};
+
+/* "Union Functional Descriptor" from CDC spec 5.2.3.X */
+struct union_desc {
+	u8	bLength;
+	u8	bDescriptorType;
+	u8	bDescriptorSubType;
+
+	u8	bMasterInterface0;
+	u8	bSlaveInterface0;
+	/* ... and there could be other slave interfaces */
+} __attribute__ ((packed));
+
+static const struct union_desc union_desc = {
+	.bLength =		sizeof union_desc,
+	.bDescriptorType =	0x24,
+	.bDescriptorSubType =	6,
+
+	.bMasterInterface0 =	0,	/* index of control interface */
+	.bSlaveInterface0 =	1,	/* index of DATA interface */
+};
+
+/* "Ethernet Networking Functional Descriptor" from CDC spec 5.2.3.16 */
+struct ether_desc {
+	u8	bLength;
+	u8	bDescriptorType;
+	u8	bDescriptorSubType;
+
+	u8	iMACAddress;
+	u32	bmEthernetStatistics;
+	u16	wMaxSegmentSize;
+	u16	wNumberMCFilters;
+	u8	bNumberPowerFilters;
+} __attribute__ ((packed));
+
+static const struct ether_desc ether_desc = {
+	.bLength =		sizeof ether_desc,
+	.bDescriptorType =	0x24,
+	.bDescriptorSubType =	0x0f,
+
+	/* this descriptor actually adds value, surprise! */
+	.iMACAddress =		STRING_ETHADDR,
+	.bmEthernetStatistics =	__constant_cpu_to_le32 (0), /* no statistics */
+	.wMaxSegmentSize =	__constant_cpu_to_le16 (MAX_PACKET + ETH_HLEN),
+	.wNumberMCFilters =	__constant_cpu_to_le16 (0),
+	.bNumberPowerFilters =	0,
+};
+
+#ifdef	EP_STATUS_NUM
+
+/* include the status endpoint if we can, even though it's optional.
+ *
+ * some drivers (like current Linux cdc-ether!) "need" it to exist even
+ * if they ignore the connect/disconnect notifications that real aether
+ * can provide.  more advanced cdc configurations might want to support
+ * encapsulated commands (vendor-specific, using control-OUT).
+ */
+ 
+#define LOG2_STATUS_INTERVAL_MSEC	6
+#define STATUS_BYTECOUNT		16	/* 8 byte header + data */
+static const struct usb_endpoint_descriptor
+fs_status_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_STATUS_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (STATUS_BYTECOUNT),
+	.bInterval =		1 << LOG2_STATUS_INTERVAL_MSEC,
+};
+#endif
+
+/* the default data interface has no endpoints ... */
+
+static const struct usb_interface_descriptor
+data_nop_intf = {
+	.bLength =		sizeof data_nop_intf,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bInterfaceNumber =	1,
+	.bAlternateSetting =	0,
+	.bNumEndpoints =	0,
+	.bInterfaceClass =	USB_CLASS_CDC_DATA,
+	.bInterfaceSubClass =	0,
+	.bInterfaceProtocol =	0,
+	.iInterface =		STRING_DATA,
+};
+
+/* ... but the "real" data interface has two full speed bulk endpoints */
+
+static const struct usb_interface_descriptor
+data_intf = {
+	.bLength =		sizeof data_intf,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bInterfaceNumber =	1,
+	.bAlternateSetting =	1,
+	.bNumEndpoints =	2,
+	.bInterfaceClass =	USB_CLASS_CDC_DATA,
+	.bInterfaceSubClass =	0,
+	.bInterfaceProtocol =	0,
+	.iInterface =		STRING_DATA,
+};
+#else
+
+/*
+ * "Minimalist" non-CDC option is a simple vendor-neutral model that most
+ * full speed controllers can handle:  one interface, two bulk endpoints.
+ */
+
+static const struct usb_interface_descriptor
+data_intf = {
+	.bLength =		sizeof data_intf,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bInterfaceNumber =	0,
+	.bAlternateSetting =	0,
+	.bNumEndpoints =	2,
+	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
+	.bInterfaceSubClass =	0,
+	.bInterfaceProtocol =	0,
+	.iInterface =		STRING_DATA,
+};
+
+#endif	/* DEV_CONFIG_CDC */
+
+
+static const struct usb_endpoint_descriptor
+fs_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (64),
+};
+
+static const struct usb_endpoint_descriptor
+fs_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_OUT_NUM,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (64),
+};
+
+#ifdef	HIGHSPEED
+
+/*
+ * usb 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+ */
+
+#ifdef	EP_STATUS_NUM
+static const struct usb_endpoint_descriptor
+hs_status_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_STATUS_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_INT,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (STATUS_BYTECOUNT),
+	.bInterval =		LOG2_STATUS_INTERVAL_MSEC + 3,
+};
+#endif
+
+static const struct usb_endpoint_descriptor
+hs_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (512),
+	.bInterval =		1,
+};
+
+static const struct usb_endpoint_descriptor
+hs_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_OUT_NUM,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (512),
+	.bInterval =		1,
+};
+
+static const struct usb_qualifier_descriptor
+dev_qualifier = {
+	.bLength =		sizeof dev_qualifier,
+	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
+
+	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
+	.bDeviceClass =		DEV_CONFIG_CLASS,
+
+	/* assumes ep0 uses the same value for both speeds ... */
+	.bMaxPacketSize0 =	EP0_MAXPACKET,
+
+	.bNumConfigurations =	1,
+};
+
+/* maxpacket and other transfer characteristics vary by speed. */
+#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))
+
+#else
+
+/* if there's no high speed support, maxpacket doesn't change. */
+#define ep_desc(g,hs,fs) fs
+
+#endif	/* !HIGHSPEED */
+
+/*-------------------------------------------------------------------------*/
+
+/* descriptors that are built on-demand */
+
+#ifdef	DEV_CONFIG_CDC
+/* address that the host will use ... usually assigned at random */
+static char				ethaddr [2 * ETH_ALEN + 1];
+#endif
+
+/* static strings, in iso 8859/1 */
+static struct usb_string		strings [] = {
+	{ STRING_MANUFACTURER,	UTS_SYSNAME " " UTS_RELEASE "/" CHIP, },
+	{ STRING_PRODUCT,	driver_desc, },
+#ifdef	DEV_CONFIG_CDC
+	{ STRING_ETHADDR,	ethaddr, },
+	{ STRING_CONTROL,	"CDC Communications Control", },
+#endif
+	{ STRING_DATA,		"Ethernet Data", },
+	{  }		/* end of list */
+};
+
+static struct usb_gadget_strings	stringtab = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= strings,
+};
+
+/*
+ * one config, two interfaces:  control, data.
+ * complications: class descriptors, and an altsetting.
+ */
+static int
+config_buf (enum usb_device_speed speed, u8 *buf, u8 type, unsigned index)
+{
+	const unsigned	config_len = USB_DT_CONFIG_SIZE
+#ifdef DEV_CONFIG_CDC
+				+ 2 * USB_DT_INTERFACE_SIZE
+				+ sizeof header_desc
+				+ sizeof union_desc
+				+ sizeof ether_desc
+#ifdef	EP_STATUS_NUM
+				+ USB_DT_ENDPOINT_SIZE
+#endif
+#endif /* DEV_CONFIG_CDC */
+				+ USB_DT_INTERFACE_SIZE
+				+ 2 * USB_DT_ENDPOINT_SIZE;
+
+#ifdef HIGHSPEED
+	int		hs;
+#endif
+	/* a single configuration must always be index 0 */
+	if (index > 0)
+		return -EINVAL;
+	if (config_len > USB_BUFSIZ)
+		return -EDOM;
+
+	/* config (or other speed config) */
+	memcpy (buf, &eth_config, USB_DT_CONFIG_SIZE);
+	buf [1] = type;
+	((struct usb_config_descriptor *) buf)->wTotalLength
+		= __constant_cpu_to_le16 (config_len);
+	buf += USB_DT_CONFIG_SIZE;
+#ifdef	HIGHSPEED
+	hs = (speed == USB_SPEED_HIGH);
+	if (type == USB_DT_OTHER_SPEED_CONFIG)
+		hs = !hs;
+#endif
+
+#ifdef DEV_CONFIG_CDC
+	/* control interface, class descriptors, optional status endpoint */
+	memcpy (buf, &control_intf, USB_DT_INTERFACE_SIZE);
+	buf += USB_DT_INTERFACE_SIZE;
+
+	memcpy (buf, &header_desc, sizeof header_desc);
+	buf += sizeof header_desc;
+	memcpy (buf, &union_desc, sizeof union_desc);
+	buf += sizeof union_desc;
+	memcpy (buf, &ether_desc, sizeof ether_desc);
+	buf += sizeof ether_desc;
+
+#ifdef	EP_STATUS_NUM
+#ifdef	HIGHSPEED
+	if (hs)
+		memcpy (buf, &hs_status_desc, USB_DT_ENDPOINT_SIZE);
+	else
+#endif	/* HIGHSPEED */
+		memcpy (buf, &fs_status_desc, USB_DT_ENDPOINT_SIZE);
+	buf += USB_DT_ENDPOINT_SIZE;
+#endif	/* EP_STATUS_NUM */
+
+	/* default data altsetting has no endpoints */
+	memcpy (buf, &data_nop_intf, USB_DT_INTERFACE_SIZE);
+	buf += USB_DT_INTERFACE_SIZE;
+#endif /* DEV_CONFIG_CDC */
+
+	/* the "real" data interface has two endpoints */
+	memcpy (buf, &data_intf, USB_DT_INTERFACE_SIZE);
+	buf += USB_DT_INTERFACE_SIZE;
+#ifdef HIGHSPEED
+	if (hs) {
+		memcpy (buf, &hs_source_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		memcpy (buf, &hs_sink_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+	} else
+#endif
+	{
+		memcpy (buf, &fs_source_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		memcpy (buf, &fs_sink_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+	}
+
+	return config_len;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void eth_start (struct eth_dev *dev, int gfp_flags);
+static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags);
+
+static int
+set_ether_config (struct eth_dev *dev, int gfp_flags)
+{
+	int			result = 0;
+	struct usb_ep		*ep;
+	struct usb_gadget	*gadget = dev->gadget;
+
+	gadget_for_each_ep (ep, gadget) {
+		const struct usb_endpoint_descriptor	*d;
+
+#ifdef	DEV_CONFIG_CDC
+		/* With CDC,  the host isn't allowed to use these two data
+		 * endpoints in the default altsetting for the interface.
+		 * so we don't activate them yet.
+		 */
+
+		/* one endpoint writes data back IN to the host */
+		if (strcmp (ep->name, EP_IN_NAME) == 0) {
+			d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
+			ep->driver_data = dev;
+			dev->in_ep = ep;
+			dev->in = d;
+			continue;
+
+		/* one endpoint just reads OUT packets */
+		} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
+			d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
+			ep->driver_data = dev;
+			dev->out_ep = ep;
+			dev->out = d;
+			continue;
+		}
+
+#ifdef	EP_STATUS_NUM
+		/* optional status/notification endpoint */
+		else if (strcmp (ep->name, EP_STATUS_NAME) == 0) {
+			d = ep_desc (gadget, &hs_status_desc, &fs_status_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				dev->status_ep = ep;
+				dev->status = d;
+				continue;
+			}
+		}
+#endif
+
+#else	/* !CONFIG_CDC_ETHER */
+
+		/* non-CDC is simpler:  if the device is there,
+		 * it's live with rx and tx endpoints.
+		 */
+		/* one endpoint writes data back IN to the host */
+		if (strcmp (ep->name, EP_IN_NAME) == 0) {
+			d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				dev->in_ep = ep;
+				dev->in = d;
+				continue;
+			}
+
+		/* one endpoint just reads OUT packets */
+		} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
+			d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				dev->out_ep = ep;
+				dev->out = d;
+				continue;
+			}
+		}
+
+#endif /* !CONFIG_CDC_ETHER */
+
+		/* ignore any other endpoints */
+		else
+			continue;
+
+		/* stop on error */
+		ERROR (dev, "can't enable %s, result %d\n", ep->name, result);
+		break;
+	}
+	if (!result && (!dev->in_ep || !dev->out_ep))
+		result = -ENODEV;
+
+	if (result == 0)
+		result = alloc_requests (dev, qlen (gadget), gfp_flags);
+
+#ifndef	DEV_CONFIG_CDC
+	if (result == 0) {
+		netif_carrier_on (dev->net);
+		if (netif_running (dev->net))
+			eth_start (dev, GFP_ATOMIC);
+	} else {
+		(void) usb_ep_disable (dev->in_ep);
+		dev->in_ep = 0;
+		dev->in = 0;
+		(void) usb_ep_disable (dev->out_ep);
+		dev->out_ep = 0;
+		dev->out = 0;
+	}
+#endif /* !CONFIG_CDC_ETHER */
+
+	if (result == 0)
+		DEBUG (dev, "qlen %d\n", qlen (gadget));
+
+	/* caller is responsible for cleanup on error */
+	return result;
+}
+
+static void eth_reset_config (struct eth_dev *dev)
+{
+	if (dev->config == 0)
+		return;
+
+	DEBUG (dev, "%s\n", __FUNCTION__);
+
+	netif_stop_queue (dev->net);
+	netif_carrier_off (dev->net);
+
+	/* just disable endpoints, forcing completion of pending i/o.
+	 * all our completion handlers free their requests in this case.
+	 */
+	if (dev->in_ep) {
+		usb_ep_disable (dev->in_ep);
+		dev->in_ep = 0;
+	}
+	if (dev->out_ep) {
+		usb_ep_disable (dev->out_ep);
+		dev->out_ep = 0;
+	}
+#ifdef	EP_STATUS_NUM
+	if (dev->status_ep) {
+		usb_ep_disable (dev->status_ep);
+		dev->status_ep = 0;
+	}
+#endif
+	dev->config = 0;
+}
+
+/* change our operational config.  must agree with the code
+ * that returns config descriptors, and altsetting code.
+ */
+static int
+eth_set_config (struct eth_dev *dev, unsigned number, int gfp_flags)
+{
+	int			result = 0;
+	struct usb_gadget	*gadget = dev->gadget;
+
+	if (number == dev->config)
+		return 0;
+
+#ifdef CONFIG_USB_ETH_SA1100
+	if (dev->config && atomic_read (&dev->tx_qlen) != 0) {
+		/* tx fifo is full, but we can't clear it...*/
+		INFO (dev, "can't change configurations\n");
+		return -ESPIPE;
+	}
+#endif
+	eth_reset_config (dev);
+	hw_optimize (gadget);
+
+	switch (number) {
+	case DEV_CONFIG_VALUE:
+		result = set_ether_config (dev, gfp_flags);
+		break;
+	default:
+		result = -EINVAL;
+		/* FALL THROUGH */
+	case 0:
+		return result;
+	}
+
+	if (result)
+		eth_reset_config (dev);
+	else {
+		char *speed;
+
+		switch (gadget->speed) {
+		case USB_SPEED_FULL:	speed = "full"; break;
+#ifdef HIGHSPEED
+		case USB_SPEED_HIGH:	speed = "high"; break;
+#endif
+		default: 		speed = "?"; break;
+		}
+
+		dev->config = number;
+		INFO (dev, "%s speed config #%d: %s\n", speed, number,
+				driver_desc);
+	}
+	return result;
+}
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	EP_STATUS_NUM
+
+/* section 3.8.2 table 11 of the CDC spec lists Ethernet notifications */
+#define CDC_NOTIFY_NETWORK_CONNECTION	0x00	/* required; 6.3.1 */
+#define CDC_NOTIFY_SPEED_CHANGE		0x2a	/* required; 6.3.8 */
+
+struct cdc_notification {
+	u8	bmRequestType;
+	u8	bNotificationType;
+	u16	wValue;
+	u16	wIndex;
+	u16	wLength;
+
+	/* SPEED_CHANGE data looks like this */
+	u32	data [2];
+};
+
+static void eth_status_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	struct cdc_notification	*event = req->buf;
+	int			value = req->status;
+	struct eth_dev		*dev = ep->driver_data;
+
+	/* issue the second notification if host reads the first */
+	if (event->bNotificationType == CDC_NOTIFY_NETWORK_CONNECTION
+			&& value == 0) {
+		event->bmRequestType = 0xA1;
+		event->bNotificationType = CDC_NOTIFY_SPEED_CHANGE;
+		event->wValue = __constant_cpu_to_le16 (0);
+		event->wIndex = __constant_cpu_to_le16 (1);
+		event->wLength = __constant_cpu_to_le16 (8);
+
+		/* SPEED_CHANGE data is up/down speeds in bits/sec */
+		event->data [0] = event->data [1] =
+			(dev->gadget->speed == USB_SPEED_HIGH)
+				? (13 * 512 * 8 * 1000 * 8)
+				: (19 *  64 * 1 * 1000 * 8);
+
+		req->length = 16;
+		value = usb_ep_queue (ep, req, GFP_ATOMIC);
+		DEBUG (dev, "send SPEED_CHANGE --> %d\n", value);
+		if (value == 0)
+			return;
+	} else
+		DEBUG (dev, "event %02x --> %d\n",
+			event->bNotificationType, value);
+
+	/* free when done */
+	usb_ep_free_buffer (ep, req->buf, req->dma, 16);
+	usb_ep_free_request (ep, req);
+}
+
+static void issue_start_status (struct eth_dev *dev)
+{
+	struct usb_request	*req;
+	struct cdc_notification	*event;
+	int			value;
+ 
+	DEBUG (dev, "%s, flush old status first\n", __FUNCTION__);
+
+	/* flush old status
+	 *
+	 * FIXME ugly idiom, maybe we'd be better with just
+	 * a "cancel the whole queue" primitive since any
+	 * unlink-one primitive has way too many error modes.
+	 * here, we "know" toggle is already clear...
+	 */
+	usb_ep_disable (dev->status_ep);
+	usb_ep_enable (dev->status_ep, dev->status);
+
+	/* FIXME make these allocations static like dev->req */
+	req = usb_ep_alloc_request (dev->status_ep, GFP_ATOMIC);
+	if (req == 0) {
+		DEBUG (dev, "status ENOMEM\n");
+		return;
+	}
+	req->buf = usb_ep_alloc_buffer (dev->status_ep, 16,
+				&dev->req->dma, GFP_ATOMIC);
+	if (req->buf == 0) {
+		DEBUG (dev, "status buf ENOMEM\n");
+free_req:
+		usb_ep_free_request (dev->status_ep, req);
+		return;
+	}
+
+	/* 3.8.1 says to issue first NETWORK_CONNECTION, then
+	 * a SPEED_CHANGE.  could be useful in some configs.
+	 */
+	event = req->buf;
+	event->bmRequestType = 0xA1;
+	event->bNotificationType = CDC_NOTIFY_NETWORK_CONNECTION;
+	event->wValue = __constant_cpu_to_le16 (1);	/* connected */
+	event->wIndex = __constant_cpu_to_le16 (1);
+	event->wLength = 0;
+
+	req->length = 8;
+	req->complete = eth_status_complete;
+	value = usb_ep_queue (dev->status_ep, req, GFP_ATOMIC);
+	if (value < 0) {
+		DEBUG (dev, "status buf queue --> %d\n", value);
+		usb_ep_free_buffer (dev->status_ep,
+				req->buf, dev->req->dma, 16);
+		goto free_req;
+	}
+}
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+static void eth_setup_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	if (req->status || req->actual != req->length)
+		DEBUG ((struct eth_dev *) ep->driver_data,
+				"setup complete --> %d, %d/%d\n",
+				req->status, req->actual, req->length);
+}
+
+/* see section 3.8.2 table 10 of the CDC spec for more ethernet
+ * requests, mostly for filters (multicast, pm) and statistics
+ */
+#define CDC_SET_ETHERNET_PACKET_FILTER	0x43	/* required */
+
+/*
+ * The setup() callback implements all the ep0 functionality that's not
+ * handled lower down.  CDC has a number of less-common features:
+ *
+ *  - two interfaces:  control, and ethernet data
+ *  - data interface has two altsettings:  default, and active
+ *  - class-specific descriptors for the control interface
+ *  - a mandatory class-specific control request
+ */
+static int
+eth_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+{
+	struct eth_dev		*dev = get_gadget_data (gadget);
+	struct usb_request	*req = dev->req;
+	int			value = -EOPNOTSUPP;
+
+	/* descriptors just go into the pre-allocated ep0 buffer,
+	 * while config change events may enable network traffic.
+	 */
+	switch (ctrl->bRequest) {
+
+	case USB_REQ_GET_DESCRIPTOR:
+		if (ctrl->bRequestType != USB_DIR_IN)
+			break;
+		switch (ctrl->wValue >> 8) {
+
+		case USB_DT_DEVICE:
+			value = min (ctrl->wLength, (u16) sizeof device_desc);
+			memcpy (req->buf, &device_desc, value);
+			break;
+#ifdef HIGHSPEED
+		case USB_DT_DEVICE_QUALIFIER:
+			value = min (ctrl->wLength, (u16) sizeof dev_qualifier);
+			memcpy (req->buf, &dev_qualifier, value);
+			break;
+
+		case USB_DT_OTHER_SPEED_CONFIG:
+			// FALLTHROUGH
+#endif /* HIGHSPEED */
+		case USB_DT_CONFIG:
+			value = config_buf (gadget->speed, req->buf,
+					ctrl->wValue >> 8,
+					ctrl->wValue & 0xff);
+			if (value >= 0)
+				value = min (ctrl->wLength, (u16) value);
+			break;
+
+		case USB_DT_STRING:
+			value = usb_gadget_get_string (&stringtab,
+					ctrl->wValue & 0xff, req->buf);
+			if (value >= 0)
+				value = min (ctrl->wLength, (u16) value);
+			break;
+		}
+		break;
+
+	case USB_REQ_SET_CONFIGURATION:
+		if (ctrl->bRequestType != 0)
+			break;
+		spin_lock (&dev->lock);
+		value = eth_set_config (dev, ctrl->wValue, GFP_ATOMIC);
+		spin_unlock (&dev->lock);
+		break;
+#ifdef	CONFIG_USB_ETH_PXA2XX
+	/* PXA UDC prevents us from using SET_INTERFACE in normal ways.
+	 * And it hides GET_CONFIGURATION and GET_INTERFACE too.
+	 */
+	case USB_REQ_SET_INTERFACE:
+		spin_lock (&dev->lock);
+		value = eth_set_config (dev, DEV_CONFIG_VALUE, GFP_ATOMIC);
+		spin_unlock (&dev->lock);
+		break;
+
+#else	/* hardware that that stays out of our way */
+	case USB_REQ_GET_CONFIGURATION:
+		if (ctrl->bRequestType != USB_DIR_IN)
+			break;
+		*(u8 *)req->buf = dev->config;
+		value = min (ctrl->wLength, (u16) 1);
+		break;
+
+	case USB_REQ_SET_INTERFACE:
+		if (ctrl->bRequestType != USB_RECIP_INTERFACE
+				|| !dev->config
+				|| ctrl->wIndex > 1)
+			break;
+		spin_lock (&dev->lock);
+		switch (ctrl->wIndex) {
+		case 0:		/* control/master intf */
+			if (ctrl->wValue != 0)
+				break;
+#ifdef	EP_STATUS_NUM
+			if (dev->status_ep) {
+				usb_ep_disable (dev->status_ep);
+				usb_ep_enable (dev->status_ep, dev->status);
+			}
+#endif
+			value = 0;
+			break;
+		case 1:		/* data intf */
+			if (ctrl->wValue > 1)
+				break;
+			usb_ep_disable (dev->in_ep);
+			usb_ep_disable (dev->out_ep);
+
+			/* CDC requires the data transfers not be done from
+			 * the default interface setting ... also, setting
+			 * the non-default interface clears filters etc.
+			 */
+			if (ctrl->wValue == 1) {
+				usb_ep_enable (dev->in_ep, dev->in);
+				usb_ep_enable (dev->out_ep, dev->out);
+				netif_carrier_on (dev->net);
+#ifdef	EP_STATUS_NUM
+				issue_start_status (dev);
+#endif
+				if (netif_running (dev->net))
+					eth_start (dev, GFP_ATOMIC);
+			} else {
+				netif_stop_queue (dev->net);
+				netif_carrier_off (dev->net);
+			}
+			value = 0;
+			break;
+		}
+		spin_unlock (&dev->lock);
+		break;
+	case USB_REQ_GET_INTERFACE:
+		if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE)
+				|| !dev->config
+				|| ctrl->wIndex > 1)
+			break;
+
+		/* if carrier is on, data interface is active. */
+		*(u8 *)req->buf =
+			((ctrl->wIndex == 1) && netif_carrier_ok (dev->net))
+				? 1
+				: 0,
+		value = min (ctrl->wLength, (u16) 1);
+		break;
+#endif
+
+#ifdef DEV_CONFIG_CDC
+	case CDC_SET_ETHERNET_PACKET_FILTER:
+		/* see 6.2.30: no data, wIndex = interface,
+		 * wValue = packet filter bitmap
+		 */
+		if (ctrl->bRequestType != (USB_TYPE_CLASS|USB_RECIP_INTERFACE)
+				|| ctrl->wLength != 0
+				|| ctrl->wIndex > 1)
+		DEBUG (dev, "NOP packet filter %04x\n", ctrl->wValue);
+		/* NOTE: table 62 has 5 filter bits to reduce traffic,
+		 * and we "must" support multicast and promiscuous.
+		 * this NOP implements a bad filter...
+		 */
+		value = 0;
+		break;
+#endif /* DEV_CONFIG_CDC */
+
+	default:
+		VDEBUG (dev,
+			"unknown control req%02x.%02x v%04x i%04x l%d\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+	}
+
+	/* respond with data transfer before status phase? */
+	if (value >= 0) {
+		req->length = value;
+		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
+		if (value < 0) {
+			DEBUG (dev, "ep_queue --> %d\n", value);
+			req->status = 0;
+			eth_setup_complete (gadget->ep0, req);
+		}
+	}
+
+	/* host either stalls (value < 0) or reports success */
+	return value;
+}
+
+static void
+eth_disconnect (struct usb_gadget *gadget)
+{
+	struct eth_dev		*dev = get_gadget_data (gadget);
+	unsigned long		flags;
+
+	spin_lock_irqsave (&dev->lock, flags);
+	netif_stop_queue (dev->net);
+	netif_carrier_off (dev->net);
+	eth_reset_config (dev);
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	/* next we may get setup() calls to enumerate new connections;
+	 * or an unbind() during shutdown (including removing module).
+	 */
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* NETWORK DRIVER HOOKUP (to the layer above this driver) */
+
+static int eth_change_mtu (struct net_device *net, int new_mtu)
+{
+	struct eth_dev	*dev = (struct eth_dev *) net->priv;
+
+	if (new_mtu <= MIN_PACKET || new_mtu > MAX_PACKET)
+		return -ERANGE;
+	/* no zero-length packet read wanted after mtu-sized packets */
+	if (((new_mtu + sizeof (struct ethhdr)) % dev->in_ep->maxpacket) == 0)
+		return -EDOM;
+	net->mtu = new_mtu;
+	return 0;
+}
+
+static struct net_device_stats *eth_get_stats (struct net_device *net)
+{
+	return &((struct eth_dev *) net->priv)->stats;
+}
+
+static int eth_ethtool_ioctl (struct net_device *net, void *useraddr)
+{
+	struct eth_dev	*dev = (struct eth_dev *) net->priv;
+	u32		cmd;
+
+	if (get_user (cmd, (u32 *)useraddr))
+		return -EFAULT;
+	switch (cmd) {
+
+	case ETHTOOL_GDRVINFO: {	/* get driver info */
+		struct ethtool_drvinfo		info;
+
+		memset (&info, 0, sizeof info);
+		info.cmd = ETHTOOL_GDRVINFO;
+		strncpy (info.driver, shortname, sizeof info.driver);
+		strncpy (info.version, DRIVER_VERSION, sizeof info.version);
+		strncpy (info.fw_version, CHIP, sizeof info.fw_version);
+		strncpy (info.bus_info, dev->gadget->dev.bus_id,
+			sizeof info.bus_info);
+		if (copy_to_user (useraddr, &info, sizeof (info)))
+			return -EFAULT;
+		return 0;
+		}
+
+	case ETHTOOL_GLINK: {		/* get link status */
+		struct ethtool_value	edata = { ETHTOOL_GLINK };
+
+		edata.data = (dev->gadget->speed != USB_SPEED_UNKNOWN);
+		if (copy_to_user (useraddr, &edata, sizeof (edata)))
+			return -EFAULT;
+		return 0;
+		}
+
+	}
+	/* Note that the ethtool user space code requires EOPNOTSUPP */
+	return -EOPNOTSUPP;
+}
+
+static int eth_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
+{
+	switch (cmd) {
+	case SIOCETHTOOL:
+		return eth_ethtool_ioctl (net, (void *)rq->ifr_data);
+	default:
+		return -EOPNOTSUPP;
+	}
+}
+
+static void defer_kevent (struct eth_dev *dev, int flag)
+{
+	if (test_and_set_bit (flag, &dev->todo))
+		return;
+	if (!schedule_work (&dev->work))
+		ERROR (dev, "kevent %d may have been dropped\n", flag);
+	else
+		DEBUG (dev, "kevent %d scheduled\n", flag);
+}
+
+static void rx_complete (struct usb_ep *ep, struct usb_request *req);
+
+static int
+rx_submit (struct eth_dev *dev, struct usb_request *req, int gfp_flags)
+{
+	struct sk_buff		*skb;
+	int			retval = 0;
+	size_t			size;
+
+	size = (sizeof (struct ethhdr) + dev->net->mtu + RX_EXTRA);
+
+	if ((skb = alloc_skb (size, gfp_flags)) == 0) {
+		DEBUG (dev, "no rx skb\n");
+		defer_kevent (dev, WORK_RX_MEMORY);
+		list_add (&req->list, &dev->rx_reqs);
+		return -ENOMEM;
+	}
+
+	req->buf = skb->data;
+	req->length = size;
+	req->complete = rx_complete;
+	req->context = skb;
+
+	retval = usb_ep_queue (dev->out_ep, req, gfp_flags);
+	if (retval == -ENOMEM)
+		defer_kevent (dev, WORK_RX_MEMORY);
+	if (retval) {
+		DEBUG (dev, "rx submit --> %d\n", retval);
+		dev_kfree_skb_any (skb);
+		list_add (&req->list, &dev->rx_reqs);
+	}
+	return retval;
+}
+
+static void rx_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	struct sk_buff	*skb = req->context;
+	struct eth_dev	*dev = ep->driver_data;
+	int		status = req->status;
+
+	switch (status) {
+
+	/* normal completion */
+	case 0:
+		skb_put (skb, req->actual);
+		if (MIN_PACKET > skb->len
+				|| skb->len > (MAX_PACKET + ETH_HLEN)) {
+			dev->stats.rx_errors++;
+			dev->stats.rx_length_errors++;
+			DEBUG (dev, "rx length %d\n", skb->len);
+			break;
+		}
+
+		skb->dev = dev->net;
+		skb->protocol = eth_type_trans (skb, dev->net);
+		dev->stats.rx_packets++;
+		dev->stats.rx_bytes += skb->len;
+
+		/* no buffer copies needed, unless hardware can't
+		 * use skb buffers.
+		 */
+		status = netif_rx (skb);
+		skb = 0;
+		break;
+
+	/* software-driven interface shutdown */
+	case -ECONNRESET:		// unlink
+	case -ESHUTDOWN:		// disconnect etc
+		VDEBUG (dev, "rx shutdown, code %d\n", status);
+		goto quiesce;
+
+	/* for hardware automagic (such as pxa) */
+	case -ECONNABORTED:		// endpoint reset
+		DEBUG (dev, "rx %s reset\n", ep->name);
+		defer_kevent (dev, WORK_RX_MEMORY);
+quiesce:
+		dev_kfree_skb_any (skb);
+		goto clean;
+
+	/* data overrun */
+	case -EOVERFLOW:
+		dev->stats.rx_over_errors++;
+		// FALLTHROUGH
+	    
+	default:
+		dev->stats.rx_errors++;
+		DEBUG (dev, "rx status %d\n", status);
+		break;
+	}
+
+	if (skb)
+		dev_kfree_skb_any (skb);
+	if (!netif_running (dev->net)) {
+clean:
+		list_add (&req->list, &dev->rx_reqs);
+		req = 0;
+	}
+	if (req)
+		rx_submit (dev, req, GFP_ATOMIC);
+}
+
+static int prealloc (struct list_head *list, struct usb_ep *ep,
+			unsigned n, int gfp_flags)
+{
+	unsigned		i;
+	struct usb_request	*req;
+
+	if (!n)
+		return -ENOMEM;
+
+	/* queue/recycle up to N requests */
+	i = n;
+	list_for_each_entry (req, list, list) {
+		if (i-- == 0)
+			goto extra;
+	}
+	while (i--) {
+		req = usb_ep_alloc_request (ep, gfp_flags);
+		if (!req)
+			return list_empty (list) ? -ENOMEM : 0;
+		list_add (&req->list, list);
+	}
+	return 0;
+
+extra:
+	/* free extras */
+	for (;;) {
+		struct list_head	*next;
+
+		next = req->list.next;
+		list_del (&req->list);
+		usb_ep_free_request (ep, req);
+
+		if (next == list)
+			break;
+
+		req = container_of (next, struct usb_request, list);
+	}
+	return 0;
+}
+
+static int alloc_requests (struct eth_dev *dev, unsigned n, int gfp_flags)
+{
+	int status;
+
+	status = prealloc (&dev->tx_reqs, dev->in_ep, n, gfp_flags);
+	if (status < 0)
+		goto fail;
+	status = prealloc (&dev->rx_reqs, dev->out_ep, n, gfp_flags);
+	if (status < 0)
+		goto fail;
+	return 0;
+fail:
+	DEBUG (dev, "can't alloc requests\n");
+	return status;
+}
+
+static void rx_fill (struct eth_dev *dev, int gfp_flags)
+{
+	struct usb_request	*req;
+
+	clear_bit (WORK_RX_MEMORY, &dev->todo);
+
+	/* fill unused rxq slots with some skb */
+	while (!list_empty (&dev->rx_reqs)) {
+		req = container_of (dev->rx_reqs.next,
+				struct usb_request, list);
+		list_del_init (&req->list);
+		if (rx_submit (dev, req, gfp_flags) < 0) {
+			defer_kevent (dev, WORK_RX_MEMORY);
+			return;
+		}
+	}
+}
+
+static void eth_work (void *_dev)
+{
+	struct eth_dev		*dev = _dev;
+
+	if (test_bit (WORK_RX_MEMORY, &dev->todo)) {
+		if (netif_running (dev->net))
+			rx_fill (dev, GFP_KERNEL);
+		else
+			clear_bit (WORK_RX_MEMORY, &dev->todo);
+	}
+
+	if (dev->todo)
+		DEBUG (dev, "work done, flags = 0x%lx\n", dev->todo);
+}
+
+static void tx_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	struct sk_buff	*skb = req->context;
+	struct eth_dev	*dev = ep->driver_data;
+
+	switch (req->status) {
+	default:
+		dev->stats.tx_errors++;
+		VDEBUG (dev, "tx err %d\n", req->status);
+		/* FALLTHROUGH */
+	case -ECONNRESET:		// unlink
+	case -ESHUTDOWN:		// disconnect etc
+		break;
+	case 0:
+		dev->stats.tx_bytes += skb->len;
+	}
+	dev->stats.tx_packets++;
+
+	list_add (&req->list, &dev->tx_reqs);
+	dev_kfree_skb_any (skb);
+
+	atomic_dec (&dev->tx_qlen);
+	if (netif_carrier_ok (dev->net))
+		netif_wake_queue (dev->net);
+}
+
+static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
+{
+	struct eth_dev		*dev = (struct eth_dev *) net->priv;
+	int			length = skb->len;
+	int			retval;
+	struct usb_request	*req = 0;
+
+	req = container_of (dev->tx_reqs.next, struct usb_request, list);
+	list_del (&req->list);
+	if (list_empty (&dev->tx_reqs))
+		netif_stop_queue (net);
+
+	/* no buffer copies needed, unless the network stack did it
+	 * or the hardware can't use skb buffers.
+	 */
+	req->buf = skb->data;
+	req->context = skb;
+	req->complete = tx_complete;
+
+#ifdef	CONFIG_USB_ETH_SA1100
+	/* don't demand zlp (req->zero) support from all hardware */
+	if ((length % dev->in_ep->maxpacket) == 0)
+		length++;
+#else
+	/* use zlp framing on tx for strict CDC-Ether conformance,
+	 * though any robust network rx path ignores extra padding.
+	 */
+	req->zero = 1;
+#endif
+	req->length = length;
+
+#ifdef	HIGHSPEED
+	/* throttle highspeed IRQ rate back slightly */
+	req->no_interrupt = (dev->gadget->speed == USB_SPEED_HIGH)
+		? ((atomic_read (&dev->tx_qlen) % TX_DELAY) != 0)
+		: 0;
+#endif
+
+	retval = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC);
+	switch (retval) {
+	default:
+		DEBUG (dev, "tx queue err %d\n", retval);
+		break;
+	case 0:
+		net->trans_start = jiffies;
+		atomic_inc (&dev->tx_qlen);
+	}
+
+	if (retval) {
+		dev->stats.tx_dropped++;
+		dev_kfree_skb_any (skb);
+		if (list_empty (&dev->tx_reqs))
+			netif_start_queue (net);
+		list_add (&req->list, &dev->tx_reqs);
+	}
+	return 0;
+}
+
+static void eth_start (struct eth_dev *dev, int gfp_flags)
+{
+	DEBUG (dev, "%s\n", __FUNCTION__);
+
+	/* fill the rx queue */
+	rx_fill (dev, gfp_flags);
+
+	/* and open the tx floodgates */ 
+	atomic_set (&dev->tx_qlen, 0);
+	netif_wake_queue (dev->net);
+}
+
+static int eth_open (struct net_device *net)
+{
+	struct eth_dev		*dev = (struct eth_dev *) net->priv;
+
+	DEBUG (dev, "%s\n", __FUNCTION__);
+	if (netif_carrier_ok (dev->net))
+		eth_start (dev, GFP_KERNEL);
+	return 0;
+}
+
+static int eth_stop (struct net_device *net)
+{
+	struct eth_dev		*dev = (struct eth_dev *) net->priv;
+
+	DEBUG (dev, "%s\n", __FUNCTION__);
+	netif_stop_queue (net);
+
+	DEBUG (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld\n",
+		dev->stats.rx_packets, dev->stats.tx_packets, 
+		dev->stats.rx_errors, dev->stats.tx_errors
+		);
+
+	/* ensure there are no more active requests */
+	if (dev->gadget->speed != USB_SPEED_UNKNOWN) {
+		usb_ep_disable (dev->in_ep);
+		usb_ep_disable (dev->out_ep);
+		if (netif_carrier_ok (dev->net)) {
+			DEBUG (dev, "host still using in/out endpoints\n");
+			usb_ep_enable (dev->in_ep, dev->in);
+			usb_ep_enable (dev->out_ep, dev->out);
+		}
+#ifdef	EP_STATUS_NUM
+		usb_ep_disable (dev->status_ep);
+		usb_ep_enable (dev->status_ep, dev->status);
+#endif
+	}
+
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+eth_unbind (struct usb_gadget *gadget)
+{
+	struct eth_dev		*dev = get_gadget_data (gadget);
+	struct usb_request	*req;
+
+	DEBUG (dev, "unbind\n");
+
+	/* we've already been disconnected ... no i/o is active */
+	if (dev->req) {
+		usb_ep_free_buffer (gadget->ep0,
+				dev->req->buf, dev->req->dma,
+				USB_BUFSIZ);
+		usb_ep_free_request (gadget->ep0, dev->req);
+		dev->req = 0;
+	}
+
+	while (!list_empty (&dev->tx_reqs)) {
+		req = container_of (dev->tx_reqs.next,
+					struct usb_request, list);
+		list_del (&req->list);
+		usb_ep_free_request (dev->in_ep, req);
+	}
+	while (!list_empty (&dev->rx_reqs)) {
+		req = container_of (dev->rx_reqs.next,
+					struct usb_request, list);
+		list_del (&req->list);
+		usb_ep_free_request (dev->out_ep, req);
+	}
+
+	unregister_netdev (dev->net);
+	dev_put (dev->net);
+
+	/* assuming we used keventd, it must quiesce too */
+	flush_scheduled_work ();
+	set_gadget_data (gadget, 0);
+}
+
+static int
+eth_bind (struct usb_gadget *gadget)
+{
+	struct eth_dev		*dev;
+	struct net_device	*net;
+	int			status = -ENOMEM;
+#ifdef	DEV_CONFIG_CDC
+	u8			node_id [ETH_ALEN];
+
+	/* just one upstream link at a time */
+	if (ethaddr [0] != 0)
+		return -ENODEV;
+#endif
+
+ 	net = alloc_etherdev (sizeof *dev);
+ 	if (!net)
+		return status;
+	dev = net->priv;
+	spin_lock_init (&dev->lock);
+	INIT_WORK (&dev->work, eth_work, dev);
+	INIT_LIST_HEAD (&dev->tx_reqs);
+	INIT_LIST_HEAD (&dev->rx_reqs);
+
+	/* network device setup */
+	dev->net = net;
+	SET_MODULE_OWNER (net);
+	net->priv = dev;
+	strcpy (net->name, "usb%d");
+	ether_setup (net);
+
+	/* one random address for the gadget device ... both of these could
+	 * reasonably come from an id prom or a module parameter.
+	 */
+	get_random_bytes (net->dev_addr, ETH_ALEN);
+	net->dev_addr [0] &= 0xfe;	// clear multicast bit
+	net->dev_addr [0] |= 0x02;	// set local assignment bit (IEEE802)
+
+#ifdef	DEV_CONFIG_CDC
+	/* ... another address for the host, on the other end of the
+	 * link, gets exported through CDC (see CDC spec table 41)
+	 */
+	get_random_bytes (node_id, sizeof node_id);
+	node_id [0] &= 0xfe;	// clear multicast bit
+	node_id [0] |= 0x02;    // set local assignment bit (IEEE802)
+	snprintf (ethaddr, sizeof ethaddr, "%02X%02X%02X%02X%02X%02X",
+		node_id [0], node_id [1], node_id [2],
+		node_id [3], node_id [4], node_id [5]);
+#endif
+
+	net->change_mtu = eth_change_mtu;
+	net->get_stats = eth_get_stats;
+	net->hard_start_xmit = eth_start_xmit;
+	net->open = eth_open;
+	net->stop = eth_stop;
+	// watchdog_timeo, tx_timeout ...
+	// set_multicast_list
+	net->do_ioctl = eth_ioctl;
+
+	/* preallocate control response and buffer */
+	dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
+	if (!dev->req)
+		goto fail;
+	dev->req->complete = eth_setup_complete;
+	dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
+				&dev->req->dma, GFP_KERNEL);
+	if (!dev->req->buf) {
+		usb_ep_free_request (gadget->ep0, dev->req);
+		goto fail;
+	}
+
+	/* finish hookup to lower layer ... */
+	dev->gadget = gadget;
+	set_gadget_data (gadget, dev);
+	gadget->ep0->driver_data = dev;
+	INFO (dev, "%s, " CHIP ", version: " DRIVER_VERSION "\n", driver_desc);
+#ifdef	DEV_CONFIG_CDC
+	INFO (dev, "CDC host enet %s\n", ethaddr);
+#endif
+	
+	/* two kinds of host-initiated state changes:
+	 *  - iff DATA transfer is active, carrier is "on"
+	 *  - tx queueing enabled if open *and* carrier is "on"
+	 */
+	netif_stop_queue (dev->net);
+	netif_carrier_off (dev->net);
+
+ 	// SET_NETDEV_DEV (dev->net, &gadget->dev);
+ 	status = register_netdev (dev->net);
+ 	if (status == 0)
+ 		return status;
+fail:
+	eth_unbind (gadget);
+	return status;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_gadget_driver eth_driver = {
+#ifdef HIGHSPEED
+	.speed		= USB_SPEED_HIGH,
+#else
+	.speed		= USB_SPEED_FULL,
+#endif
+	.function	= (char *) driver_desc,
+	.bind		= eth_bind,
+	.unbind		= eth_unbind,
+
+	.setup		= eth_setup,
+	.disconnect	= eth_disconnect,
+
+	.driver 	= {
+		.name		= (char *) shortname,
+		// .shutdown = ...
+		// .suspend = ...
+		// .resume = ...
+	},
+};
+
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_AUTHOR ("David Brownell");
+MODULE_LICENSE ("GPL");
+
+
+static int __init init (void)
+{
+	return usb_gadget_register_driver (&eth_driver);
+}
+module_init (init);
+
+static void __exit cleanup (void)
+{
+	usb_gadget_unregister_driver (&eth_driver);
+}
+module_exit (cleanup);
+
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/net2280.c linux-2.4.23-pre7/drivers/usb/gadget/net2280.c
--- linux-2.4.23-pre6/drivers/usb/gadget/net2280.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/net2280.c	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,2731 @@
+/*
+ * Driver for the NetChip 2280 USB device controller.
+ * Specs and errata are available from <http://www.netchip.com>.
+ *
+ * NetChip Technology Inc. supported the development of this driver.
+ *
+ *
+ * CODE STATUS HIGHLIGHTS
+ *
+ * Used with a gadget driver like "zero.c" this enumerates fine to Windows
+ * or Linux hosts; handles disconnect, reconnect, and reset, for full or
+ * high speed operation; and passes USB-IF "chapter 9" tests.
+ *
+ * Handles standard stress loads from the Linux "usbtest" driver, with
+ * either DMA (default) or PIO (use_dma=n) used for ep-{a,b,c,d}.  Testing
+ * with "ttcp" (and the "ether.c" driver) behaves nicely too.
+ *
+ * DMA is enabled by default.  Drivers using transfer queues might use
+ * DMA chaining to remove IRQ latencies between transfers.  (Except when
+ * short OUT transfers happen.)  Drivers can use the req->no_interrupt
+ * hint to completely eliminate some IRQs, if a later IRQ is guaranteed
+ * and DMA chaining is enabled.
+ *
+ * Note that almost all the errata workarounds here are only needed for
+ * rev1 chips.  Rev1a silicon (0110) fixes almost all of them.
+ */
+
+#define USE_DMA_CHAINING
+
+
+/*
+ * Copyright (C) 2003 David Brownell
+ * Copyright (C) 2003 NetChip Technologies
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#define DEBUG	1
+// #define	VERBOSE		/* extra debug messages (success too) */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/version.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+
+
+#define	DRIVER_DESC		"NetChip 2280 USB Peripheral Controller"
+#define	DRIVER_VERSION		"Bastille Day 2003"
+
+#define	DMA_ADDR_INVALID	(~(dma_addr_t)0)
+#define	EP_DONTUSE		13	/* nonzero */
+
+#define USE_RDK_LEDS		/* GPIO pins control three LEDs */
+
+
+static const char driver_name [] = "net2280";
+static const char driver_desc [] = DRIVER_DESC;
+
+static const char ep0name [] = "ep0";
+static const char *ep_name [] = {
+	ep0name,
+	"ep-a", "ep-b", "ep-c", "ep-d",
+	"ep-e", "ep-f",
+};
+
+static int use_dma = 1;
+
+/* mode 0 == ep-{a,b,c,d} 1K fifo each
+ * mode 1 == ep-{a,b} 2K fifo each, ep-{c,d} unavailable
+ * mode 2 == ep-a 2K fifo, ep-{b,c} 1K each, ep-d unavailable
+ */
+static ushort fifo_mode = 0;
+
+MODULE_PARM (use_dma, "i");
+MODULE_PARM_DESC (use_dma, "true to use dma controllers");
+
+MODULE_PARM (fifo_mode, "h");
+MODULE_PARM_DESC (fifo_mode, "net2280 fifo mode");
+
+
+#define	DIR_STRING(bAddress) (((bAddress) & USB_DIR_IN) ? "in" : "out")
+
+#if defined(USE_SYSFS_DEBUG_FILES) || defined (DEBUG)
+static char *type_string (u8 bmAttributes)
+{
+	switch ((bmAttributes) & USB_ENDPOINT_XFERTYPE_MASK) {
+	case USB_ENDPOINT_XFER_BULK:	return "bulk";
+	case USB_ENDPOINT_XFER_ISOC:	return "iso";
+	case USB_ENDPOINT_XFER_INT:	return "intr";
+	};
+	return "control";
+}
+#endif
+
+#include "net2280.h"
+
+#define valid_bit	__constant_cpu_to_le32 (1 << VALID_BIT)
+#define dma_done_ie	__constant_cpu_to_le32 (1 << DMA_DONE_INTERRUPT_ENABLE)
+
+/*-------------------------------------------------------------------------*/
+
+static int
+net2280_enable (struct usb_ep *_ep, const struct usb_endpoint_descriptor *desc)
+{
+	struct net2280		*dev;
+	struct net2280_ep	*ep;
+	u32			max, tmp;
+	unsigned long		flags;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || !desc || ep->desc || _ep->name == ep0name
+			|| desc->bDescriptorType != USB_DT_ENDPOINT)
+		return -EINVAL;
+	dev = ep->dev;
+	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	/* erratum 0119 workaround ties up an endpoint number */
+	if ((desc->bEndpointAddress & 0x0f) == EP_DONTUSE)
+		return -EDOM;
+
+	/* sanity check ep-e/ep-f since their fifos are small */
+	max = le16_to_cpu (desc->wMaxPacketSize) & 0x1fff;
+	if (ep->num > 4 && max > 64)
+		return -ERANGE;
+
+	spin_lock_irqsave (&dev->lock, flags);
+	_ep->maxpacket = max & 0x7ff;
+	ep->desc = desc;
+
+	/* ep_reset() has already been called */
+	ep->stopped = 0;
+
+	/* set speed-dependent max packet; may kick in high bandwidth */
+	set_idx_reg (dev->regs, REG_EP_MAXPKT (dev, ep->num), max);
+
+	/* FIFO lines can't go to different packets.  PIO is ok, so
+	 * use it instead of troublesome (non-bulk) multi-packet DMA.
+	 */
+	if (ep->is_in && ep->dma && (max % 4) != 0) {
+		DEBUG (ep->dev, "%s, no IN dma for maxpacket %d\n",
+			ep->ep.name, ep->ep.maxpacket);
+		ep->dma = 0;
+	}
+
+	/* set type, direction, address; reset fifo counters */
+	writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat);
+	tmp = (desc->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
+	if (tmp == USB_ENDPOINT_XFER_INT) {
+		/* not just because of erratum 0105; avoid ever
+		 * kicking in the "toggle-irrelevant" mode.
+		 */
+		tmp = USB_ENDPOINT_XFER_BULK;
+	} else if (tmp == USB_ENDPOINT_XFER_BULK) {
+		/* catch some particularly blatant driver bugs */
+		if ((dev->gadget.speed == USB_SPEED_HIGH
+					&& max != 512)
+				|| (dev->gadget.speed == USB_SPEED_FULL
+					&& max > 64))
+			return -ERANGE;
+	}
+	ep->is_iso = (tmp == USB_ENDPOINT_XFER_ISOC) ? 1 : 0;
+	tmp <<= ENDPOINT_TYPE;
+	tmp |= desc->bEndpointAddress;
+	tmp |= (4 << ENDPOINT_BYTE_COUNT);	/* default full fifo lines */
+	tmp |= 1 << ENDPOINT_ENABLE;
+	wmb ();
+
+	/* for OUT transfers, block the rx fifo until a read is posted */
+	ep->is_in = (tmp & USB_DIR_IN) != 0;
+	if (!ep->is_in)
+		writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+
+	writel (tmp, &ep->regs->ep_cfg);
+
+#ifdef NET2280_DMA_OUT_WORKAROUND
+	if (!ep->is_in)
+		ep->dma = 0;
+#endif
+
+	/* enable irqs */
+	if (!ep->dma) {				/* pio, per-packet */
+		tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0);
+		writel (tmp, &dev->regs->pciirqenb0);
+
+		tmp = (1 << DATA_PACKET_RECEIVED_INTERRUPT_ENABLE)
+			| (1 << DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE)
+			| readl (&ep->regs->ep_irqenb);
+		writel (tmp, &ep->regs->ep_irqenb);
+	} else {				/* dma, per-request */
+		tmp = (1 << (8 + ep->num));	/* completion */
+		tmp |= readl (&dev->regs->pciirqenb1);
+		writel (tmp, &dev->regs->pciirqenb1);
+
+		/* for short OUT transfers, dma completions can't
+		 * advance the queue; do it pio-style, by hand.
+		 * NOTE erratum 0112 workaround #2
+		 */
+		if ((desc->bEndpointAddress & USB_DIR_IN) == 0) {
+			tmp = (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE);
+			writel (tmp, &ep->regs->ep_irqenb);
+
+			tmp = (1 << ep->num) | readl (&dev->regs->pciirqenb0);
+			writel (tmp, &dev->regs->pciirqenb0);
+		}
+	}
+
+	tmp = desc->bEndpointAddress;
+	DEBUG (dev, "enabled %s (ep%d%s-%s) %s max %04x\n",
+		_ep->name, tmp & 0x0f, DIR_STRING (tmp),
+		type_string (desc->bmAttributes),
+		ep->dma ? "dma" : "pio", max);
+
+	/* pci writes may still be posted */
+	spin_unlock_irqrestore (&dev->lock, flags);
+	return 0;
+}
+
+static int handshake (u32 *ptr, u32 mask, u32 done, int usec)
+{
+	u32	result;
+
+	do {
+		result = readl (ptr);
+		if (result == ~(u32)0)		/* "device unplugged" */
+			return -ENODEV;
+		result &= mask;
+		if (result == done)
+			return 0;
+		udelay (1);
+		usec--;
+	} while (usec > 0);
+	return -ETIMEDOUT;
+}
+
+static struct usb_ep_ops net2280_ep_ops;
+
+static void ep_reset (struct net2280_regs *regs, struct net2280_ep *ep)
+{
+	u32		tmp;
+
+	ep->desc = 0;
+	INIT_LIST_HEAD (&ep->queue);
+
+	ep->ep.maxpacket = ~0;
+	ep->ep.ops = &net2280_ep_ops;
+
+	/* disable the dma, irqs, endpoint... */
+	if (ep->dma) {
+		writel (0, &ep->dma->dmactl);
+		writel (  (1 << DMA_SCATTER_GATHER_DONE_INTERRUPT)
+			| (1 << DMA_TRANSACTION_DONE_INTERRUPT)
+			| (1 << DMA_ABORT)
+			, &ep->dma->dmastat);
+
+		tmp = readl (&regs->pciirqenb0);
+		tmp &= ~(1 << ep->num);
+		writel (tmp, &regs->pciirqenb0);
+	} else {
+		tmp = readl (&regs->pciirqenb1);
+		tmp &= ~(1 << (8 + ep->num));	/* completion */
+		writel (tmp, &regs->pciirqenb1);
+	}
+	writel (0, &ep->regs->ep_irqenb);
+
+	/* init to our chosen defaults, notably so that we NAK OUT
+	 * packets until the driver queues a read (+note erratum 0112)
+	 */
+	writel (  (1 << SET_NAK_OUT_PACKETS_MODE)
+		| (1 << SET_NAK_OUT_PACKETS)
+		| (1 << CLEAR_EP_HIDE_STATUS_PHASE)
+		| (1 << CLEAR_INTERRUPT_MODE)
+		| (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
+		| (1 << CLEAR_ENDPOINT_TOGGLE)
+		| (1 << CLEAR_ENDPOINT_HALT)
+		, &ep->regs->ep_rsp);
+
+	/* scrub most status bits, and flush any fifo state */
+	writel (  (1 << TIMEOUT)
+		| (1 << USB_STALL_SENT)
+		| (1 << USB_IN_NAK_SENT)
+		| (1 << USB_IN_ACK_RCVD)
+		| (1 << USB_OUT_PING_NAK_SENT)
+		| (1 << USB_OUT_ACK_SENT)
+		| (1 << FIFO_OVERFLOW)
+		| (1 << FIFO_UNDERFLOW)
+		| (1 << FIFO_FLUSH)
+		| (1 << SHORT_PACKET_OUT_DONE_INTERRUPT)
+		| (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)
+		| (1 << DATA_PACKET_RECEIVED_INTERRUPT)
+		| (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)
+		| (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+		| (1 << DATA_IN_TOKEN_INTERRUPT)
+		, &ep->regs->ep_stat);
+
+	/* fifo size is handled separately */
+}
+
+static void nuke (struct net2280_ep *);
+
+static int net2280_disable (struct usb_ep *_ep)
+{
+	struct net2280_ep	*ep;
+	unsigned long		flags;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || !ep->desc || _ep->name == ep0name)
+		return -EINVAL;
+
+	spin_lock_irqsave (&ep->dev->lock, flags);
+	nuke (ep);
+	ep_reset (ep->dev->regs, ep);
+
+	VDEBUG (ep->dev, "disabled %s %s\n",
+			ep->dma ? "dma" : "pio", _ep->name);
+
+	/* synch memory views with the device */
+	(void) readl (&ep->regs->ep_cfg);
+
+	if (use_dma && !ep->dma && ep->num >= 1 && ep->num <= 4)
+		ep->dma = &ep->dev->dma [ep->num - 1];
+
+	spin_unlock_irqrestore (&ep->dev->lock, flags);
+	return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_request *
+net2280_alloc_request (struct usb_ep *_ep, int gfp_flags)
+{
+	struct net2280_ep	*ep;
+	struct net2280_request	*req;
+
+	if (!_ep)
+		return 0;
+	ep = container_of (_ep, struct net2280_ep, ep);
+
+	req = kmalloc (sizeof *req, gfp_flags);
+	if (!req)
+		return 0;
+
+	memset (req, 0, sizeof *req);
+	req->req.dma = DMA_ADDR_INVALID;
+	INIT_LIST_HEAD (&req->queue);
+
+	/* this dma descriptor may be swapped with the previous dummy */
+	if (ep->dma) {
+		struct net2280_dma	*td;
+
+		td = pci_pool_alloc (ep->dev->requests, gfp_flags,
+				&req->td_dma);
+		if (!td) {
+			kfree (req);
+			return 0;
+		}
+		td->dmacount = 0;	/* not VALID */
+		td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+		req->td = td;
+	}
+	return &req->req;
+}
+
+static void
+net2280_free_request (struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct net2280_ep	*ep;
+	struct net2280_request	*req;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || !_req)
+		return;
+
+	req = container_of (_req, struct net2280_request, req);
+	WARN_ON (!list_empty (&req->queue));
+	if (req->td)
+		pci_pool_free (ep->dev->requests, req->td, req->td_dma);
+	kfree (req);
+}
+
+/*-------------------------------------------------------------------------*/
+
+#undef USE_KMALLOC
+
+/* many common platforms have dma-coherent caches, which means that it's
+ * safe to use kmalloc() memory for all i/o buffers without using any
+ * cache flushing calls.  (unless you're trying to share cache lines
+ * between dma and non-dma activities, which is a slow idea in any case.)
+ *
+ * other platforms need more care, with 2.5 having a moderately general
+ * solution (which falls down for allocations smaller than one page)
+ * that improves significantly on the 2.4 PCI allocators by removing
+ * the restriction that memory never be freed in_interrupt().
+ */
+#if	defined(CONFIG_X86)
+#define USE_KMALLOC
+
+#elif	defined(CONFIG_PPC) && !defined(CONFIG_NOT_COHERENT_CACHE)
+#define USE_KMALLOC
+
+/* FIXME there are other cases, including an x86-64 one ...  */
+#endif
+
+/* allocating buffers this way eliminates dma mapping overhead, which
+ * on some platforms will mean eliminating a per-io buffer copy.  with
+ * some kinds of system caches, further tweaks may still be needed.
+ */
+static void *
+net2280_alloc_buffer (
+	struct usb_ep		*_ep,
+	unsigned		bytes,
+	dma_addr_t		*dma,
+	int			gfp_flags
+)
+{
+	void			*retval;
+	struct net2280_ep	*ep;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep)
+		return 0;
+
+	*dma = DMA_ADDR_INVALID;
+	if (ep->dma) {
+#if	defined(USE_KMALLOC)
+		retval = kmalloc (bytes, gfp_flags);
+		if (retval)
+			*dma = virt_to_phys (retval);
+
+#elif	LINUX_VERSION_CODE > KERNEL_VERSION(2,5,58)
+#warning Using dma_alloc_consistent even with sub-page allocations
+		/* the main problem with this call is that it wastes memory
+		 * on typical 1/N page allocations: it allocates 1-N pages.
+		 */
+		retval = dma_alloc_coherent (&ep->dev->pdev->dev,
+				bytes, dma, gfp_flags);
+#else
+#error No dma-coherent memory allocator is available
+		/* pci_alloc_consistent works, but pci_free_consistent()
+		 * isn't safe in_interrupt().  plus, in addition to the
+		 * 1/Nth page weakness, it doesn't understand gfp_flags.
+		 */
+#endif
+	} else
+		retval = kmalloc (bytes, gfp_flags);
+
+	return retval;
+}
+
+static void
+net2280_free_buffer (
+	struct usb_ep *_ep,
+	void *buf,
+	dma_addr_t dma,
+	unsigned bytes
+) {
+	/* free memory into the right allocator */
+#ifndef	USE_KMALLOC
+	if (dma != DMA_ADDR_INVALID)
+		dma_free_coherent (ep->dev->pdev, bytes, dma);
+	else
+#endif
+		kfree (buf);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* load a packet into the fifo we use for usb IN transfers.
+ * works for all endpoints.
+ *
+ * NOTE: pio with ep-a..ep-d could stuff multiple packets into the fifo
+ * at a time, but this code is simpler because it knows it only writes
+ * one packet.  ep-a..ep-d should use dma instead.
+ */
+static void
+write_fifo (struct net2280_ep *ep, struct usb_request *req)
+{
+	struct net2280_ep_regs	*regs = ep->regs;
+	u8			*buf;
+	u32			tmp;
+	unsigned		count, total;
+
+	/* INVARIANT:  fifo is currently empty. (testable) */
+
+	if (req) {
+		buf = req->buf + req->actual;
+		prefetch (buf);
+		total = req->length - req->actual;
+	} else {
+		total = 0;
+		buf = 0;
+	}
+
+	/* write just one packet at a time */
+	count = min (ep->ep.maxpacket, total);
+	VDEBUG (ep->dev, "write %s fifo (IN) %d bytes%s req %p\n",
+			ep->ep.name, count,
+			(count != ep->ep.maxpacket) ? " (short)" : "",
+			req);
+	while (count >= 4) {
+		/* NOTE be careful if you try to align these. fifo lines
+		 * should normally be full (4 bytes) and successive partial
+		 * lines are ok only in certain cases.
+		 */
+		tmp = get_unaligned ((u32 *)buf);
+		cpu_to_le32s (&tmp);
+		writel (tmp, &regs->ep_data);
+		buf += 4;
+		count -= 4;
+	}
+
+	/* last fifo entry is "short" unless we wrote a full packet */
+	if (total < ep->ep.maxpacket) {
+		tmp = count ? get_unaligned ((u32 *)buf) : count;
+		cpu_to_le32s (&tmp);
+		set_fifo_bytecount (ep, count & 0x03);
+		writel (tmp, &regs->ep_data);
+	}
+
+	/* pci writes may still be posted */
+}
+
+/* work around erratum 0106: PCI and USB race over the OUT fifo.
+ * caller guarantees chiprev 0100, out endpoint is NAKing, and
+ * there's no real data in the fifo.
+ */
+static void out_flush (struct net2280_ep *ep)
+{
+	u32	*statp, tmp;
+
+	ASSERT_OUT_NAKING (ep);
+
+	statp = &ep->regs->ep_stat;
+	writel (  (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+		| (1 << DATA_PACKET_RECEIVED_INTERRUPT)
+		, statp);
+	writel ((1 << FIFO_FLUSH), statp);
+	mb ();
+	tmp = readl (statp);
+	if (tmp & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+			/* high speed did bulk NYET; fifo isn't filling */
+			&& ep->dev->gadget.speed == USB_SPEED_FULL) {
+		unsigned	usec;
+
+		usec = 50;		/* 64 byte bulk/interrupt */
+		handshake (statp, (1 << USB_OUT_PING_NAK_SENT),
+				(1 << USB_OUT_PING_NAK_SENT), usec);
+		/* NAK done; now CLEAR_NAK_OUT_PACKETS is safe */
+	}
+}
+
+/* unload packet(s) from the fifo we use for usb OUT transfers.
+ * returns true iff the request completed, because of short packet
+ * or the request buffer having filled with full packets.
+ *
+ * for ep-a..ep-d this will read multiple packets out when they
+ * have been accepted.
+ */
+static int
+read_fifo (struct net2280_ep *ep, struct net2280_request *req)
+{
+	struct net2280_ep_regs	*regs = ep->regs;
+	u8			*buf = req->req.buf + req->req.actual;
+	unsigned		count, tmp, is_short;
+	unsigned		cleanup = 0, prevent = 0;
+
+	/* erratum 0106 ... packets coming in during fifo reads might
+	 * be incompletely rejected.  not all cases have workarounds.
+	 */
+	if (ep->dev->chiprev == 0x0100) {
+		tmp = readl (&ep->regs->ep_stat);
+		if ((tmp & (1 << NAK_OUT_PACKETS)))
+			/* cleanup = 1 */;
+		else if ((tmp & (1 << FIFO_FULL))
+				/* don't break hs PING protocol ... */
+				|| ep->dev->gadget.speed == USB_SPEED_FULL) {
+			start_out_naking (ep);
+			prevent = 1;
+		}
+		/* else: hope we don't see the problem */
+	}
+
+	/* never overflow the rx buffer. the fifo reads packets until
+	 * it sees a short one; we might not be ready for them all.
+	 */
+	prefetchw (buf);
+	count = readl (&regs->ep_avail);
+	tmp = req->req.length - req->req.actual;
+	if (count > tmp) {
+		/* as with DMA, data overflow gets flushed */
+		if ((tmp % ep->ep.maxpacket) != 0) {
+			ERROR (ep->dev,
+				"%s out fifo %d bytes, expected %d\n",
+				ep->ep.name, count, tmp);
+			req->req.status = -EOVERFLOW;
+			cleanup = 1;
+		}
+		count = tmp;
+	}
+	req->req.actual += count;
+
+	is_short = (count == 0) || ((count % ep->ep.maxpacket) != 0);
+
+	VDEBUG (ep->dev, "read %s fifo (OUT) %d bytes%s%s%s req %p %d/%d\n",
+			ep->ep.name, count, is_short ? " (short)" : "",
+			cleanup ? " flush" : "", prevent ? " nak" : "",
+			req, req->req.actual, req->req.length);
+
+	while (count >= 4) {
+		tmp = readl (&regs->ep_data);
+		cpu_to_le32s (&tmp);
+		put_unaligned (tmp, (u32 *)buf);
+		buf += 4;
+		count -= 4;
+	}
+	if (count) {
+		tmp = readl (&regs->ep_data);
+		cpu_to_le32s (&tmp);
+		do {
+			*buf++ = (u8) tmp;
+			tmp >>= 8;
+		} while (--count);
+	}
+	if (cleanup)
+		out_flush (ep);
+	if (prevent) {
+		writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+		(void) readl (&ep->regs->ep_rsp);
+	}
+
+	return is_short || ((req->req.actual == req->req.length)
+				&& !req->req.zero);
+}
+
+/* fill out dma descriptor to match a given request */
+static inline void
+fill_dma_desc (struct net2280_ep *ep, struct net2280_request *req, int valid)
+{
+	struct net2280_dma	*td = req->td;
+	u32			dmacount = req->req.length;
+
+	/* don't let DMA continue after a short OUT packet,
+	 * so overruns can't affect the next transfer.
+	 * in case of overruns on max-size packets, we can't
+	 * stop the fifo from filling but we can flush it.
+	 */
+	if (ep->is_in)
+		dmacount |= (1 << DMA_DIRECTION);
+	else
+		dmacount |= (1 << END_OF_CHAIN);
+
+	req->valid = valid;
+	if (valid)
+		dmacount |= (1 << VALID_BIT);
+#ifdef USE_DMA_CHAINING
+	if (!req->req.no_interrupt)
+#endif
+		dmacount |= (1 << DMA_DONE_INTERRUPT_ENABLE);
+
+	/* td->dmadesc = previously set by caller */
+	td->dmaaddr = cpu_to_le32p (&req->req.dma);
+
+	/* 2280 may be polling VALID_BIT through ep->dma->dmadesc */
+	wmb ();
+	td->dmacount = cpu_to_le32p (&dmacount);
+}
+
+static const u32 dmactl_default =
+		  (1 << DMA_CLEAR_COUNT_ENABLE)
+		/* erratum 0116 workaround part 1 (use POLLING) */
+		| (POLL_100_USEC << DESCRIPTOR_POLLING_RATE)
+		| (1 << DMA_VALID_BIT_POLLING_ENABLE)
+		| (1 << DMA_VALID_BIT_ENABLE)
+		| (1 << DMA_SCATTER_GATHER_ENABLE)
+		/* erratum 0116 workaround part 2 (no AUTOSTART) */
+		| (1 << DMA_ENABLE);
+
+static inline void spin_stop_dma (struct net2280_dma_regs *dma)
+{
+	handshake (&dma->dmactl, (1 << DMA_ENABLE), 0, 50);
+}
+
+static inline void stop_dma (struct net2280_dma_regs *dma)
+{
+	writel (dmactl_default & ~(1 << DMA_ENABLE), &dma->dmactl);
+	spin_stop_dma (dma);
+}
+
+static void start_dma (struct net2280_ep *ep, struct net2280_request *req)
+{
+	u32			tmp;
+	int			clear_nak = 0;
+	struct net2280_dma_regs	*dma = ep->dma;
+
+	/* FIXME can't use DMA for ZLPs */
+
+	/* previous OUT packet might have been short */
+	if (!ep->is_in && ((tmp = readl (&ep->regs->ep_stat))
+		 		& (1 << NAK_OUT_PACKETS)) != 0) {
+		writel ((1 << SHORT_PACKET_TRANSFERRED_INTERRUPT),
+			&ep->regs->ep_stat);
+
+		tmp = readl (&ep->regs->ep_avail);
+		if (tmp == 0)
+			clear_nak = 1;
+		else {
+			/* transfer all/some fifo data */
+			writel (req->req.dma, &dma->dmaaddr);
+			tmp = min (tmp, req->req.length);
+
+			/* dma irq, faking scatterlist status */
+			req->td->dmacount = cpu_to_le32 (req->req.length - tmp);
+			writel ((1 << DMA_DONE_INTERRUPT_ENABLE)
+				| tmp, &dma->dmacount);
+
+			writel ((1 << DMA_ENABLE), &dma->dmactl);
+			writel ((1 << DMA_START), &dma->dmastat);
+			return;
+		}
+	}
+
+	/* on this path we know there's no dma queue (yet) */
+	WARN_ON (readl (&dma->dmactl) & (1 << DMA_ENABLE));
+	tmp = dmactl_default;
+
+	/* force packet boundaries between dma requests, but prevent the
+	 * controller from automagically writing a last "short" packet
+	 * (zero length) unless the driver explicitly said to do that.
+	 */
+	if (ep->is_in) {
+		if (likely ((req->req.length % ep->ep.maxpacket) != 0
+				|| req->req.zero)) {
+			tmp |= (1 << DMA_FIFO_VALIDATE);
+			ep->in_fifo_validate = 1;
+		} else
+			ep->in_fifo_validate = 0;
+	}
+
+	/* init req->td, pointing to the current dummy */
+	req->td->dmadesc = cpu_to_le32 (ep->td_dma);
+	fill_dma_desc (ep, req, 1);
+
+#ifdef USE_DMA_CHAINING
+	writel (  (1 << VALID_BIT)
+		| (ep->is_in << DMA_DIRECTION)
+		| 0, &dma->dmacount);
+#else
+	req->td->dmacount |= __constant_cpu_to_le32 (1 << END_OF_CHAIN);
+#endif
+
+	writel (req->td_dma, &dma->dmadesc);
+	writel (tmp, &dma->dmactl);
+
+	/* erratum 0116 workaround part 3:  pci arbiter away from net2280 */
+	(void) readl (&ep->dev->pci->pcimstctl);
+
+	writel ((1 << DMA_START), &dma->dmastat);
+
+	/* recover from previous short read; erratum 0112 workaround #1 */
+	if (clear_nak)
+		writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+}
+
+static inline void
+queue_dma (struct net2280_ep *ep, struct net2280_request *req, int valid)
+{
+	struct net2280_dma	*end;
+	dma_addr_t		tmp;
+
+	/* swap new dummy for old, link; fill and maybe activate */
+	end = ep->dummy;
+	ep->dummy = req->td;
+	req->td = end;
+
+	tmp = ep->td_dma;
+	ep->td_dma = req->td_dma;
+	req->td_dma = tmp;
+
+	end->dmadesc = cpu_to_le32 (ep->td_dma);
+
+	fill_dma_desc (ep, req, valid);
+}
+
+static void
+done (struct net2280_ep *ep, struct net2280_request *req, int status)
+{
+	struct net2280		*dev;
+	unsigned		stopped = ep->stopped;
+
+	list_del_init (&req->queue);
+
+	if (req->req.status == -EINPROGRESS)
+		req->req.status = status;
+	else
+		status = req->req.status;
+
+	dev = ep->dev;
+	if (req->mapped) {
+		pci_unmap_single (dev->pdev, req->req.dma, req->req.length,
+			ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+		req->req.dma = DMA_ADDR_INVALID;
+		req->mapped = 0;
+	}
+
+	if (status && status != -ESHUTDOWN)
+		VDEBUG (dev, "complete %s req %p stat %d len %u/%u\n",
+			ep->ep.name, &req->req, status,
+			req->req.actual, req->req.length);
+
+	/* don't modify queue heads during completion callback */
+	ep->stopped = 1;
+	spin_unlock (&dev->lock);
+	req->req.complete (&ep->ep, &req->req);
+	spin_lock (&dev->lock);
+	ep->stopped = stopped;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+net2280_queue (struct usb_ep *_ep, struct usb_request *_req, int gfp_flags)
+{
+	struct net2280_request	*req;
+	struct net2280_ep	*ep;
+	struct net2280		*dev;
+	unsigned long		flags;
+
+	/* we always require a cpu-view buffer, so that we can
+	 * always use pio (as fallback or whatever).
+	 */
+	req = container_of (_req, struct net2280_request, req);
+	if (!_req || !_req->complete || !_req->buf
+			|| !list_empty (&req->queue))
+		return -EINVAL;
+	if (_req->length > (~0 & DMA_BYTE_COUNT_MASK))
+		return -EDOM;
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || (!ep->desc && ep->num != 0))
+		return -EINVAL;
+	dev = ep->dev;
+	if (!dev->driver || dev->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	/* FIXME implement PIO fallback for ZLPs with DMA */
+	if (ep->dma && _req->length == 0)
+		return -EOPNOTSUPP;
+
+	/* set up dma mapping in case the caller didn't */
+	if (ep->dma && _req->dma == DMA_ADDR_INVALID) {
+		_req->dma = pci_map_single (dev->pdev, _req->buf, _req->length,
+			ep->is_in ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
+		req->mapped = 1;
+	}
+
+#if 0
+	VDEBUG (dev, "%s queue req %p, len %d buf %p\n",
+			_ep->name, _req, _req->length, _req->buf);
+#endif
+
+	spin_lock_irqsave (&dev->lock, flags);
+
+	_req->status = -EINPROGRESS;
+	_req->actual = 0;
+	req->dma_done = 0;
+
+	/* kickstart this i/o queue? */
+	if (list_empty (&ep->queue) && !ep->stopped) {
+		/* use DMA if the endpoint supports it, else pio */
+		if (ep->dma)
+			start_dma (ep, req);
+		else {
+			/* maybe there's no control data, just status ack */
+			if (ep->num == 0 && _req->length == 0) {
+				allow_status (ep);
+				done (ep, req, 0);
+				VDEBUG (dev, "%s status ack\n", ep->ep.name);
+				goto done;
+			}
+
+			/* PIO ... stuff the fifo, or unblock it.  */
+			if (ep->is_in)
+				write_fifo (ep, _req);
+			else if (list_empty (&ep->queue)) {
+				u32	s;
+
+				/* OUT FIFO might have packet(s) buffered */
+				s = readl (&ep->regs->ep_stat);
+				if ((s & (1 << FIFO_EMPTY)) == 0) {
+					/* note:  _req->short_not_ok is
+					 * ignored here since PIO _always_
+					 * stops queue advance here, and
+					 * _req->status doesn't change for
+					 * short reads (only _req->actual)
+					 */
+					if (read_fifo (ep, req)) {
+						done (ep, req, 0);
+						if (ep->num == 0)
+							allow_status (ep);
+						/* don't queue it */
+						req = 0;
+					} else
+						s = readl (&ep->regs->ep_stat);
+				}
+
+				/* don't NAK, let the fifo fill */
+				if (req && (s & (1 << NAK_OUT_PACKETS)))
+					writel ((1 << CLEAR_NAK_OUT_PACKETS),
+							&ep->regs->ep_rsp);
+			}
+		}
+
+	} else if (ep->dma) {
+		int	valid = 1;
+
+		if (ep->is_in) {
+			int	expect;
+
+			/* preventing magic zlps is per-engine state, not
+			 * per-transfer; irq logic must recover hiccups.
+			 */
+			expect = likely (req->req.zero
+				|| (req->req.length % ep->ep.maxpacket) != 0);
+			if (expect != ep->in_fifo_validate)
+				valid = 0;
+		}
+		queue_dma (ep, req, valid);
+
+	} /* else the irq handler advances the queue. */
+
+	if (req)
+		list_add_tail (&req->queue, &ep->queue);
+done:
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	/* pci writes may still be posted */
+	return 0;
+}
+
+static inline void
+dma_done (
+	struct net2280_ep *ep,
+	struct net2280_request *req,
+	u32 dmacount,
+	int status
+)
+{
+	req->req.actual = req->req.length - (DMA_BYTE_COUNT_MASK & dmacount);
+	rmb ();
+	done (ep, req, status);
+}
+
+static void scan_dma_completions (struct net2280_ep *ep)
+{
+	/* only look at descriptors that were "naturally" retired,
+	 * so fifo and list head state won't matter
+	 */
+	while (!list_empty (&ep->queue)) {
+		struct net2280_request	*req;
+		u32			tmp;
+
+		req = list_entry (ep->queue.next,
+				struct net2280_request, queue);
+		if (!req->valid)
+			break;
+		rmb ();
+		tmp = le32_to_cpup (&req->td->dmacount);
+		if ((tmp & (1 << VALID_BIT)) != 0)
+			break;
+
+		/* SHORT_PACKET_TRANSFERRED_INTERRUPT handles "usb-short"
+		 * packets, including overruns, even when the transfer was
+		 * exactly the length requested (dmacount now zero).
+		 * FIXME there's an overrun case here too, where we expect
+		 * a short packet but receive a max length one (won't NAK).
+		 */
+		if (!ep->is_in && (req->req.length % ep->ep.maxpacket) != 0) {
+			req->dma_done = 1;
+			break;
+		}
+		dma_done (ep, req, tmp, 0);
+	}
+}
+
+static void restart_dma (struct net2280_ep *ep)
+{
+	struct net2280_request	*req;
+
+	if (ep->stopped)
+		return;
+	req = list_entry (ep->queue.next, struct net2280_request, queue);
+
+#ifdef USE_DMA_CHAINING
+	/* the 2280 will be processing the queue unless queue hiccups after
+	 * the previous transfer:
+	 *  IN:   wanted automagic zlp, head doesn't (or vice versa)
+	 *  OUT:  was "usb-short", we must restart.
+	 */
+	if (!req->valid) {
+		struct net2280_request	*entry, *prev = 0;
+		int			qmode, reqmode, done = 0;
+
+		DEBUG (ep->dev, "%s dma hiccup td %p\n", ep->ep.name, req->td);
+		qmode = likely (req->req.zero
+			|| (req->req.length % ep->ep.maxpacket) != 0);
+		list_for_each_entry (entry, &ep->queue, queue) {
+			u32		dmacount;
+
+			if (entry != req)
+				continue;
+			dmacount = entry->td->dmacount;
+			if (!done) {
+				reqmode = likely (entry->req.zero
+					|| (entry->req.length
+						% ep->ep.maxpacket) != 0);
+				if (reqmode == qmode) {
+					entry->valid = 1;
+					dmacount |= valid_bit;
+					entry->td->dmacount = dmacount;
+					prev = entry;
+					continue;
+				} else {
+					prev->td->dmacount |= dma_done_ie;
+					done = 1;
+				}
+			}
+
+			/* walk the rest of the queue so unlinks behave */
+			entry->valid = 0;
+			dmacount &= ~valid_bit;
+			entry->td->dmacount = dmacount;
+			prev = entry;
+		}
+		start_dma (ep, req);
+	} else if (!ep->is_in
+			&& (readl (&ep->regs->ep_stat)
+				& (1 << NAK_OUT_PACKETS)) != 0)
+		start_dma (ep, req);
+#else
+	start_dma (ep, req);
+#endif
+}
+
+static inline void abort_dma (struct net2280_ep *ep)
+{
+	/* abort the current transfer */
+	writel ((1 << DMA_ABORT), &ep->dma->dmastat);
+
+	/* collect completed transfers (except the current one) */
+	scan_dma_completions (ep);
+}
+
+/* dequeue ALL requests */
+static void nuke (struct net2280_ep *ep)
+{
+	struct net2280_request	*req;
+
+	/* called with spinlock held */
+	ep->stopped = 1;
+	if (ep->dma)
+		abort_dma (ep);
+	while (!list_empty (&ep->queue)) {
+		req = list_entry (ep->queue.next,
+				struct net2280_request,
+				queue);
+		done (ep, req, -ESHUTDOWN);
+	}
+}
+
+/* dequeue JUST ONE request */
+static int net2280_dequeue (struct usb_ep *_ep, struct usb_request *_req)
+{
+	struct net2280_ep	*ep;
+	struct net2280_request	*req;
+	unsigned long		flags;
+	u32			dmactl;
+	int			stopped;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	req = container_of (_req, struct net2280_request, req);
+	if (!_ep || (!ep->desc && ep->num != 0) || !_req)
+		return -EINVAL;
+
+	spin_lock_irqsave (&ep->dev->lock, flags);
+	stopped = ep->stopped;
+
+	/* pause dma while we scan the queue */
+	dmactl = 0;
+	ep->stopped = 1;
+	if (ep->dma) {
+		dmactl = readl (&ep->dma->dmactl);
+		writel (dmactl & ~(1 << DMA_ENABLE), &ep->dma->dmactl);
+		/* force synch, clean any completed requests */
+		spin_stop_dma (ep->dma);
+		scan_dma_completions (ep);
+	}
+
+	/* queue head may be partially complete. */
+	if (ep->queue.next == &req->queue) {
+		if (ep->dma) {
+			DEBUG (ep->dev, "unlink (%s) dma\n", _ep->name);
+			_req->status = -ECONNRESET;
+			abort_dma (ep);
+			if (likely (ep->queue.next == &req->queue))
+				dma_done (ep, req,
+					le32_to_cpup (&req->td->dmacount),
+					-ECONNRESET);
+		} else {
+			DEBUG (ep->dev, "unlink (%s) pio\n", _ep->name);
+			done (ep, req, -ECONNRESET);
+		}
+		req = 0;
+
+#ifdef USE_DMA_CHAINING
+	/* patch up hardware chaining data */
+	} else if (ep->dma) {
+		if (req->queue.prev == ep->queue.next) {
+			writel (le32_to_cpu (req->td->dmadesc),
+				&ep->dma->dmadesc);
+			if (req->td->dmacount & dma_done_ie)
+				writel (readl (&ep->dma->dmacount)
+						| dma_done_ie,
+					&ep->dma->dmacount);
+		} else {
+			struct net2280_request	*prev;
+
+			prev = list_entry (req->queue.prev,
+				struct net2280_request, queue);
+			prev->td->dmadesc = req->td->dmadesc;
+			if (req->td->dmacount & dma_done_ie)
+				prev->td->dmacount |= dma_done_ie;
+		}
+#endif
+	}
+
+	if (req)
+		done (ep, req, -ECONNRESET);
+	ep->stopped = stopped;
+
+	if (ep->dma) {
+		/* turn off dma on inactive queues */
+		if (list_empty (&ep->queue))
+			stop_dma (ep->dma);
+		else if (!ep->stopped) {
+			/* resume current request, or start new one */
+			if (req)
+				writel (dmactl, &ep->dma->dmactl);
+			else
+				start_dma (ep, list_entry (ep->queue.next,
+					struct net2280_request, queue));
+		}
+	}
+
+	spin_unlock_irqrestore (&ep->dev->lock, flags);
+	return req ? 0 : -EOPNOTSUPP;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static int
+net2280_set_halt (struct usb_ep *_ep, int value)
+{
+	struct net2280_ep	*ep;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || (!ep->desc && ep->num != 0))
+		return -EINVAL;
+	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+	if (ep->desc /* not ep0 */ && (ep->desc->bmAttributes & 0x03)
+						== USB_ENDPOINT_XFER_ISOC)
+		return -EINVAL;
+
+	VDEBUG (ep->dev, "%s %s halt\n", _ep->name, value ? "set" : "clear");
+
+	/* set/clear, then synch memory views with the device */
+	if (value) {
+		if (ep->num == 0)
+			ep->dev->protocol_stall = 1;
+		else
+			set_halt (ep);
+	} else
+		clear_halt (ep);
+	(void) readl (&ep->regs->ep_rsp);
+
+	return 0;
+}
+
+static int
+net2280_fifo_status (struct usb_ep *_ep)
+{
+	struct net2280_ep	*ep;
+	u32			avail;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || (!ep->desc && ep->num != 0))
+		return -ENODEV;
+	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
+		return -ESHUTDOWN;
+
+	avail = readl (&ep->regs->ep_avail) & ((1 << 12) - 1);
+	if (avail > ep->fifo_size)
+		return -EOVERFLOW;
+	if (ep->is_in)
+		avail = ep->fifo_size - avail;
+	return avail;
+}
+
+static void
+net2280_fifo_flush (struct usb_ep *_ep)
+{
+	struct net2280_ep	*ep;
+
+	ep = container_of (_ep, struct net2280_ep, ep);
+	if (!_ep || (!ep->desc && ep->num != 0))
+		return;
+	if (!ep->dev->driver || ep->dev->gadget.speed == USB_SPEED_UNKNOWN)
+		return;
+
+	writel ((1 << FIFO_FLUSH), &ep->regs->ep_stat);
+	(void) readl (&ep->regs->ep_rsp);
+}
+
+static struct usb_ep_ops net2280_ep_ops = {
+	.enable		= net2280_enable,
+	.disable	= net2280_disable,
+
+	.alloc_request	= net2280_alloc_request,
+	.free_request	= net2280_free_request,
+
+	.alloc_buffer	= net2280_alloc_buffer,
+	.free_buffer	= net2280_free_buffer,
+
+	.queue		= net2280_queue,
+	.dequeue	= net2280_dequeue,
+
+	.set_halt	= net2280_set_halt,
+	.fifo_status	= net2280_fifo_status,
+	.fifo_flush	= net2280_fifo_flush,
+};
+
+/*-------------------------------------------------------------------------*/
+
+static int net2280_get_frame (struct usb_gadget *_gadget)
+{
+	struct net2280		*dev;
+	unsigned long		flags;
+	u16			retval;
+
+	if (!_gadget)
+		return -ENODEV;
+	dev = container_of (_gadget, struct net2280, gadget);
+	spin_lock_irqsave (&dev->lock, flags);
+	retval = get_idx_reg (dev->regs, REG_FRAME) & 0x03ff;
+	spin_unlock_irqrestore (&dev->lock, flags);
+	return retval;
+}
+
+static int net2280_wakeup (struct usb_gadget *_gadget)
+{
+	struct net2280		*dev;
+
+	if (!_gadget)
+		return 0;
+	dev = container_of (_gadget, struct net2280, gadget);
+	writel (1 << GENERATE_RESUME, &dev->usb->usbstat);
+
+	/* pci writes may still be posted */
+	return 0;
+}
+
+static const struct usb_gadget_ops net2280_ops = {
+	.get_frame	= net2280_get_frame,
+	.wakeup		= net2280_wakeup,
+
+	// .set_selfpowered = net2280_set_selfpowered,
+};
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	USE_SYSFS_DEBUG_FILES
+
+/* "function" sysfs attribute */
+static ssize_t
+show_function (struct device *_dev, char *buf)
+{
+	struct net2280	*dev = dev_get_drvdata (_dev);
+
+	if (!dev->driver
+			|| !dev->driver->function
+			|| strlen (dev->driver->function) > PAGE_SIZE)
+		return 0;
+	return snprintf (buf, PAGE_SIZE, "%s\n", dev->driver->function);
+}
+static DEVICE_ATTR (function, S_IRUGO, show_function, NULL);
+
+static ssize_t
+show_registers (struct device *_dev, char *buf)
+{
+	struct net2280		*dev;
+	char			*next;
+	unsigned		size, t;
+	unsigned long		flags;
+	int			i;
+	u32			t1, t2;
+	char			*s;
+
+	dev = dev_get_drvdata (_dev);
+	next = buf;
+	size = PAGE_SIZE;
+	spin_lock_irqsave (&dev->lock, flags);
+
+	if (dev->driver)
+		s = dev->driver->driver.name;
+	else
+		s = "(none)";
+
+	/* Main Control Registers */
+	t = snprintf (next, size, "%s version " DRIVER_VERSION
+			", chiprev %04x\n"
+			"devinit %03x fifoctl %08x gadget '%s'\n"
+			"pci irqenb0 %02x irqenb1 %08x "
+			"irqstat0 %04x irqstat1 %08x\n",
+			driver_name, dev->chiprev,
+			readl (&dev->regs->devinit),
+			readl (&dev->regs->fifoctl),
+			s,
+			readl (&dev->regs->pciirqenb0),
+			readl (&dev->regs->pciirqenb1),
+			readl (&dev->regs->irqstat0),
+			readl (&dev->regs->irqstat1));
+	size -= t;
+	next += t;
+
+	/* USB Control Registers */
+	t1 = readl (&dev->usb->usbctl);
+	t2 = readl (&dev->usb->usbstat);
+	if (t1 & (1 << VBUS_PIN)) {
+		if (t2 & (1 << HIGH_SPEED))
+			s = "high speed";
+		else if (dev->gadget.speed == USB_SPEED_UNKNOWN)
+			s = "powered";
+		else
+			s = "full speed";
+		/* full speed bit (6) not working?? */
+	} else
+			s = "not attached";
+	t = snprintf (next, size,
+			"stdrsp %08x usbctl %08x usbstat %08x "
+				"addr 0x%02x (%s)\n",
+			readl (&dev->usb->stdrsp), t1, t2,
+			readl (&dev->usb->ouraddr), s);
+	size -= t;
+	next += t;
+
+	/* PCI Master Control Registers */
+
+	/* DMA Control Registers */
+
+	/* Configurable EP Control Registers */
+	for (i = 0; i < 7; i++) {
+		struct net2280_ep	*ep;
+
+		ep = &dev->ep [i];
+		if (i && !ep->desc)
+			continue;
+
+		t1 = readl (&ep->regs->ep_cfg);
+		t2 = readl (&ep->regs->ep_rsp) & 0xff;
+		t = snprintf (next, size,
+				"%s\tcfg %05x rsp (%02x) %s%s%s%s%s%s%s%s"
+					"irqenb %02x\n",
+				ep->ep.name, t1, t2,
+				(t2 & (1 << CLEAR_NAK_OUT_PACKETS))
+					? "NAK " : "",
+				(t2 & (1 << CLEAR_EP_HIDE_STATUS_PHASE))
+					? "hide " : "",
+				(t2 & (1 << CLEAR_EP_FORCE_CRC_ERROR))
+					? "CRC " : "",
+				(t2 & (1 << CLEAR_INTERRUPT_MODE))
+					? "interrupt " : "",
+				(t2 & (1<<CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE))
+					? "status " : "",
+				(t2 & (1 << CLEAR_NAK_OUT_PACKETS_MODE))
+					? "NAKmode " : "",
+				(t2 & (1 << CLEAR_ENDPOINT_TOGGLE))
+					? "DATA1 " : "DATA0 ",
+				(t2 & (1 << CLEAR_ENDPOINT_HALT))
+					? "HALT " : "",
+				readl (&ep->regs->ep_irqenb));
+		size -= t;
+		next += t;
+
+		t = snprintf (next, size,
+				"\tstat %08x avail %04x "
+				"(ep%d%s-%s)%s\n",
+				readl (&ep->regs->ep_stat),
+				readl (&ep->regs->ep_avail),
+				t1 & 0x0f, DIR_STRING (t1),
+				type_string (t1 >> 8),
+				ep->stopped ? "*" : "");
+		size -= t;
+		next += t;
+
+		if (!ep->dma)
+			continue;
+
+		t = snprintf (next, size,
+				"  dma\tctl %08x stat %08x count %08x\n"
+				"\taddr %08x desc %08x\n",
+				readl (&ep->dma->dmactl),
+				readl (&ep->dma->dmastat),
+				readl (&ep->dma->dmacount),
+				readl (&ep->dma->dmaaddr),
+				readl (&ep->dma->dmadesc));
+		size -= t;
+		next += t;
+
+	}
+
+	/* Indexed Registers */
+		// none yet 
+
+	/* Statistics */
+	t = snprintf (next, size, "irqs:  ");
+	size -= t;
+	next += t;
+	for (i = 0; i < 7; i++) {
+		struct net2280_ep	*ep;
+
+		ep = &dev->ep [i];
+		if (i && !ep->irqs)
+			continue;
+		t = snprintf (next, size, " %s/%ld", ep->ep.name, ep->irqs);
+		size -= t;
+		next += t;
+
+	}
+	t = snprintf (next, size, "\n");
+	size -= t;
+	next += t;
+
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	return PAGE_SIZE - size;
+}
+static DEVICE_ATTR (registers, S_IRUGO, show_registers, NULL);
+
+static ssize_t
+show_queues (struct device *_dev, char *buf)
+{
+	struct net2280		*dev;
+	char			*next;
+	unsigned		size;
+	unsigned long		flags;
+	int			i;
+
+	dev = dev_get_drvdata (_dev);
+	next = buf;
+	size = PAGE_SIZE;
+	spin_lock_irqsave (&dev->lock, flags);
+
+	for (i = 0; i < 7; i++) {
+		struct net2280_ep		*ep = &dev->ep [i];
+		struct net2280_request		*req;
+		int				t;
+
+		if (i != 0) {
+			const struct usb_endpoint_descriptor	*d;
+
+			d = ep->desc;
+			if (!d)
+				continue;
+			t = d->bEndpointAddress;
+			t = snprintf (next, size,
+				"%s (ep%d%s-%s) max %04x %s\n",
+				ep->ep.name, t & USB_ENDPOINT_NUMBER_MASK,
+				(t & USB_DIR_IN) ? "in" : "out",
+				({ char *val;
+				 switch (d->bmAttributes & 0x03) {
+				 case USB_ENDPOINT_XFER_BULK:
+				 	val = "bulk"; break;
+				 case USB_ENDPOINT_XFER_INT:
+				 	val = "intr"; break;
+				 default:
+				 	val = "iso"; break;
+				 }; val; }),
+				le16_to_cpu (d->wMaxPacketSize) & 0x1fff,
+				ep->dma ? "dma" : "pio"
+				);
+		} else /* ep0 should only have one transfer queued */
+			t = snprintf (next, size, "ep0 max 64 pio %s\n",
+					ep->is_in ? "in" : "out");
+		if (t <= 0 || t > size)
+			goto done;
+		size -= t;
+		next += t;
+
+		if (list_empty (&ep->queue)) {
+			t = snprintf (next, size, "\t(nothing queued)\n");
+			if (t <= 0 || t > size)
+				goto done;
+			size -= t;
+			next += t;
+			continue;
+		}
+		list_for_each_entry (req, &ep->queue, queue) {
+			if (ep->dma && req->td_dma == readl (&ep->dma->dmadesc))
+				t = snprintf (next, size,
+					"\treq %p len %d/%d "
+					"buf %p (dmacount %08x)\n",
+					&req->req, req->req.actual,
+					req->req.length, req->req.buf,
+					readl (&ep->dma->dmacount));
+			else
+				t = snprintf (next, size,
+					"\treq %p len %d/%d buf %p\n",
+					&req->req, req->req.actual,
+					req->req.length, req->req.buf);
+			if (t <= 0 || t > size)
+				goto done;
+			size -= t;
+			next += t;
+		}
+	}
+
+done:
+	spin_unlock_irqrestore (&dev->lock, flags);
+	return PAGE_SIZE - size;
+}
+static DEVICE_ATTR (queues, S_IRUGO, show_queues, NULL);
+
+
+#else
+
+#define device_create_file(a,b)	do {} while (0)
+#define device_remove_file	device_create_file
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* another driver-specific mode might be a request type doing dma
+ * to/from another device fifo instead of to/from memory.
+ */
+
+static void set_fifo_mode (struct net2280 *dev, int mode)
+{
+	/* keeping high bits preserves BAR2 */
+	writel ((0xffff << PCI_BASE2_RANGE) | mode, &dev->regs->fifoctl);
+
+	/* always ep-{a,b,e,f} ... maybe not ep-c or ep-d */
+	INIT_LIST_HEAD (&dev->gadget.ep_list);
+	list_add_tail (&dev->ep [1].ep.ep_list, &dev->gadget.ep_list);
+	list_add_tail (&dev->ep [2].ep.ep_list, &dev->gadget.ep_list);
+	switch (mode) {
+	case 0:
+		list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list);
+		list_add_tail (&dev->ep [4].ep.ep_list, &dev->gadget.ep_list);
+		dev->ep [1].fifo_size = dev->ep [2].fifo_size = 1024;
+		break;
+	case 1:
+		dev->ep [1].fifo_size = dev->ep [2].fifo_size = 2048;
+		break;
+	case 2:
+		list_add_tail (&dev->ep [3].ep.ep_list, &dev->gadget.ep_list);
+		dev->ep [1].fifo_size = 2048;
+		dev->ep [2].fifo_size = 1024;
+		break;
+	}
+	/* fifo sizes for ep0, ep-c, ep-d, ep-e, and ep-f never change */
+	list_add_tail (&dev->ep [5].ep.ep_list, &dev->gadget.ep_list);
+	list_add_tail (&dev->ep [6].ep.ep_list, &dev->gadget.ep_list);
+}
+
+/**
+ * net2280_set_fifo_mode - change allocation of fifo buffers
+ * @gadget: access to the net2280 device that will be updated
+ * @mode: 0 for default, four 1kB buffers (ep-a through ep-d);
+ * 	1 for two 2kB buffers (ep-a and ep-b only);
+ * 	2 for one 2kB buffer (ep-a) and two 1kB ones (ep-b, ep-c).
+ *
+ * returns zero on success, else negative errno.  when this succeeds,
+ * the contents of gadget->ep_list may have changed.
+ *
+ * you may only call this function when endpoints a-d are all disabled.
+ * use it whenever extra hardware buffering can help performance, such
+ * as before enabling "high bandwidth" interrupt endpoints that use
+ * maxpacket bigger than 512 (when double buffering would otherwise
+ * be unavailable).
+ */
+int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode)
+{
+	int			i;
+	struct net2280		*dev;
+	int			status = 0;
+	unsigned long		flags;
+
+	if (!gadget)
+		return -ENODEV;
+	dev = container_of (gadget, struct net2280, gadget);
+
+	spin_lock_irqsave (&dev->lock, flags);
+
+	for (i = 1; i <= 4; i++)
+		if (dev->ep [i].desc) {
+			status = -EINVAL;
+			break;
+		}
+	if (mode < 0 || mode > 2)
+		status = -EINVAL;
+	if (status == 0)
+		set_fifo_mode (dev, mode);
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	if (status == 0) {
+		if (mode == 1)
+			DEBUG (dev, "fifo:  ep-a 2K, ep-b 2K\n");
+		else if (mode == 2)
+			DEBUG (dev, "fifo:  ep-a 2K, ep-b 1K, ep-c 1K\n");
+		/* else all are 1K */
+	}
+	return status;
+}
+EXPORT_SYMBOL (net2280_set_fifo_mode);
+
+/*-------------------------------------------------------------------------*/
+
+/* keeping it simple:
+ * - one bus driver, initted first;
+ * - one function driver, initted second
+ *
+ * most of the work to support multiple net2280 controllers would
+ * be to associate this gadget driver (yes?) with all of them, or
+ * perhaps to bind specific drivers to specific devices.
+ */
+
+static struct net2280	*the_controller;
+
+static void usb_reset (struct net2280 *dev)
+{
+	u32	tmp;
+
+	/* force immediate bus disconnect, and synch through pci */
+	writel (0, &dev->usb->usbctl);
+	dev->gadget.speed = USB_SPEED_UNKNOWN;
+	(void) readl (&dev->usb->usbctl);
+
+	net2280_led_init (dev);
+
+	/* disable automatic responses, and irqs */
+	writel (0, &dev->usb->stdrsp);
+	writel (0, &dev->regs->pciirqenb0);
+	writel (0, &dev->regs->pciirqenb1);
+
+	/* clear old dma and irq state */
+	for (tmp = 0; tmp < 4; tmp++) {
+		writel ((1 << DMA_ABORT), &dev->dma [tmp].dmastat);
+		stop_dma (&dev->dma [tmp]);
+	}
+	writel (~0, &dev->regs->irqstat0),
+	writel (~(1 << SUSPEND_REQUEST_INTERRUPT), &dev->regs->irqstat1),
+
+	/* reset, and enable pci */
+	tmp = readl (&dev->regs->devinit)
+		| (1 << PCI_ENABLE)
+		| (1 << FIFO_SOFT_RESET)
+		| (1 << USB_SOFT_RESET)
+		| (1 << M8051_RESET);
+	writel (tmp, &dev->regs->devinit);
+
+	/* standard fifo and endpoint allocations */
+	set_fifo_mode (dev, (fifo_mode <= 2) ? fifo_mode : 0);
+}
+
+static void usb_reinit (struct net2280 *dev)
+{
+	u32	tmp;
+	int	init_dma;
+
+	/* use_dma changes are ignored till next device re-init */
+	init_dma = use_dma;
+
+	/* basic endpoint init */
+	for (tmp = 0; tmp < 7; tmp++) {
+		struct net2280_ep	*ep = &dev->ep [tmp];
+
+		ep->ep.name = ep_name [tmp];
+		ep->dev = dev;
+		ep->num = tmp;
+
+		if (tmp > 0 && tmp <= 4) {
+			ep->fifo_size = 1024;
+			if (init_dma)
+				ep->dma = &dev->dma [tmp - 1];
+		} else
+			ep->fifo_size = 64;
+		ep->regs = &dev->epregs [tmp];
+		ep_reset (dev->regs, ep);
+	}
+	dev->ep [0].ep.maxpacket = 64;
+	dev->ep [5].ep.maxpacket = 64;
+	dev->ep [6].ep.maxpacket = 64;
+
+	dev->gadget.ep0 = &dev->ep [0].ep;
+	dev->ep [0].stopped = 0;
+	INIT_LIST_HEAD (&dev->gadget.ep0->ep_list);
+
+	/* we want to prevent lowlevel/insecure access from the USB host,
+	 * but erratum 0119 means this enable bit is ignored
+	 */
+	for (tmp = 0; tmp < 5; tmp++)
+		writel (EP_DONTUSE, &dev->dep [tmp].dep_cfg);
+}
+
+static void ep0_start (struct net2280 *dev)
+{
+	writel (  (1 << CLEAR_EP_HIDE_STATUS_PHASE)
+		| (1 << CLEAR_NAK_OUT_PACKETS)
+		| (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
+		, &dev->epregs [0].ep_rsp);
+
+	/*
+	 * hardware optionally handles a bunch of standard requests
+	 * that the API hides from drivers anyway.  have it do so.
+	 * endpoint status/features are handled in software, to
+	 * help pass tests for some dubious behavior.
+	 */
+	writel (  (1 << SET_TEST_MODE)
+		| (1 << SET_ADDRESS)
+		| (1 << DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP)
+		| (1 << GET_DEVICE_STATUS)
+		| (1 << GET_INTERFACE_STATUS)
+		, &dev->usb->stdrsp);
+	writel (  (1 << USB_ROOT_PORT_WAKEUP_ENABLE)
+		| (1 << SELF_POWERED_USB_DEVICE)
+		| (1 << REMOTE_WAKEUP_SUPPORT)
+		| (1 << USB_DETECT_ENABLE)
+		| (1 << DEVICE_REMOTE_WAKEUP_ENABLE)
+		, &dev->usb->usbctl);
+
+	/* enable irqs so we can see ep0 and general operation  */
+	writel (  (1 << SETUP_PACKET_INTERRUPT_ENABLE)
+		| (1 << ENDPOINT_0_INTERRUPT_ENABLE)
+		, &dev->regs->pciirqenb0);
+	writel (  (1 << PCI_INTERRUPT_ENABLE)
+		| (1 << PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE)
+		| (1 << PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE)
+		| (1 << PCI_RETRY_ABORT_INTERRUPT_ENABLE)
+		| (1 << VBUS_INTERRUPT_ENABLE)
+		| (1 << ROOT_PORT_RESET_INTERRUPT_ENABLE)
+		, &dev->regs->pciirqenb1);
+
+	/* don't leave any writes posted */
+	(void) readl (&dev->usb->usbctl);
+}
+
+/* when a driver is successfully registered, it will receive
+ * control requests including set_configuration(), which enables
+ * non-control requests.  then usb traffic follows until a
+ * disconnect is reported.  then a host may connect again, or
+ * the driver might get unbound.
+ */
+int usb_gadget_register_driver (struct usb_gadget_driver *driver)
+{
+	struct net2280		*dev = the_controller;
+	int			retval;
+	unsigned		i;
+
+	/* insist on high speed support from the driver, since
+	 * (dev->usb->xcvrdiag & FORCE_FULL_SPEED_MODE)
+	 * "must not be used in normal operation"
+	 */
+	if (!driver
+			|| driver->speed != USB_SPEED_HIGH
+			|| !driver->bind
+			|| !driver->unbind
+			|| !driver->setup)
+		return -EINVAL;
+	if (!dev)
+		return -ENODEV;
+	if (dev->driver)
+		return -EBUSY;
+
+	for (i = 0; i < 7; i++)
+		dev->ep [i].irqs = 0;
+
+	/* hook up the driver ... */
+	dev->driver = driver;
+	retval = driver->bind (&dev->gadget);
+	if (retval) {
+		DEBUG (dev, "bind to driver %s --> %d\n",
+				driver->driver.name, retval);
+		dev->driver = 0;
+		return retval;
+	}
+
+	/* ... then enable host detection and ep0; and we're ready
+	 * for set_configuration as well as eventual disconnect.
+	 */
+	net2280_led_active (dev, 1);
+	ep0_start (dev);
+
+	DEBUG (dev, "%s ready, usbctl %08x stdrsp %08x\n",
+			driver->driver.name,
+			readl (&dev->usb->usbctl),
+			readl (&dev->usb->stdrsp));
+
+	/* pci writes may still be posted */
+	return 0;
+}
+EXPORT_SYMBOL (usb_gadget_register_driver);
+
+static void
+stop_activity (struct net2280 *dev, struct usb_gadget_driver *driver)
+{
+	int			i;
+
+	/* don't disconnect if it's not connected */
+	if (dev->gadget.speed == USB_SPEED_UNKNOWN)
+		driver = 0;
+
+	/* stop hardware; prevent new request submissions;
+	 * and kill any outstanding requests.
+	 */
+	usb_reset (dev);
+	for (i = 0; i < 7; i++)
+		nuke (&dev->ep [i]);
+
+	/* report disconnect; the driver is already quiesced */
+	if (driver) {
+		spin_unlock (&dev->lock);
+		driver->disconnect (&dev->gadget);
+		spin_lock (&dev->lock);
+	}
+
+	usb_reinit (dev);
+}
+
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver)
+{
+	struct net2280	*dev = the_controller;
+	unsigned long	flags;
+
+	if (!dev)
+		return -ENODEV;
+	if (!driver || driver != dev->driver)
+		return -EINVAL;
+
+	spin_lock_irqsave (&dev->lock, flags);
+	stop_activity (dev, driver);
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	driver->unbind (&dev->gadget);
+	dev->driver = 0;
+
+	net2280_led_active (dev, 0);
+
+	DEBUG (dev, "unregistered driver '%s'\n", driver->driver.name);
+	return 0;
+}
+EXPORT_SYMBOL (usb_gadget_unregister_driver);
+
+
+/*-------------------------------------------------------------------------*/
+
+/* handle ep0, ep-e, ep-f with 64 byte packets: packet per irq.
+ * also works for dma-capable endpoints, in pio mode or just
+ * to manually advance the queue after short OUT transfers.
+ */
+static void handle_ep_small (struct net2280_ep *ep)
+{
+	struct net2280_request	*req;
+	u32			t;
+	/* 0 error, 1 mid-data, 2 done */
+	int			mode = 1;
+
+	if (!list_empty (&ep->queue))
+		req = list_entry (ep->queue.next,
+			struct net2280_request, queue);
+	else
+		req = 0;
+
+	/* ack all, and handle what we care about */
+	t = readl (&ep->regs->ep_stat);
+	ep->irqs++;
+#if 0
+	VDEBUG (ep->dev, "%s ack ep_stat %08x, req %p\n",
+			ep->ep.name, t, req ? &req->req : 0);
+#endif
+	writel (t & ~(1 << NAK_OUT_PACKETS), &ep->regs->ep_stat);
+
+	/* for ep0, monitor token irqs to catch data stage length errors
+	 * and to synchronize on status.
+	 *
+	 * also, to defer reporting of protocol stalls ... here's where
+	 * data or status first appears, handling stalls here should never
+	 * cause trouble on the host side..
+	 *
+	 * control requests could be slightly faster without token synch for
+	 * status, but status can jam up that way.
+	 */
+	if (unlikely (ep->num == 0)) {
+		if (ep->is_in) {
+			/* status; stop NAKing */
+			if (t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT)) {
+				if (ep->dev->protocol_stall) {
+					ep->stopped = 1;
+					set_halt (ep);
+				}
+				mode = 2;
+			/* reply to extra IN data tokens with a zlp */
+			} else if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) {
+				if (ep->dev->protocol_stall) {
+					ep->stopped = 1;
+					set_halt (ep);
+					mode = 2;
+				} else if (!req && ep->stopped)
+					write_fifo (ep, 0);
+			}
+		} else {
+			/* status; stop NAKing */
+			if (t & (1 << DATA_IN_TOKEN_INTERRUPT)) {
+				if (ep->dev->protocol_stall) {
+					ep->stopped = 1;
+					set_halt (ep);
+				}
+				mode = 2;
+			/* an extra OUT token is an error */
+			} else if (((t & (1 << DATA_OUT_PING_TOKEN_INTERRUPT))
+					&& req
+					&& req->req.actual == req->req.length)
+					|| !req) {
+				ep->dev->protocol_stall = 1;
+				set_halt (ep);
+				ep->stopped = 1;
+				if (req)
+					done (ep, req, -EOVERFLOW);
+				req = 0;
+			}
+		}
+	}
+
+	if (unlikely (!req))
+		return;
+
+	/* manual DMA queue advance after short OUT */
+	if (likely (ep->dma != 0)) {
+		if (t & (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)) {
+			u32	count;
+
+			/* TRANSFERRED works around OUT_DONE erratum 0112.
+			 * we expect (N <= maxpacket) bytes; host wrote M.
+			 * iff (M < N) we won't ever see a DMA interrupt.
+			 */
+			count = readl (&ep->dma->dmacount);
+			count &= DMA_BYTE_COUNT_MASK;
+			if (!req->dma_done) {
+				/* dma can finish with the FIFO non-empty,
+				 * on (M > N) errors.
+				 */
+				while (count && (t & (1 << FIFO_EMPTY)) == 0) {
+					cpu_relax ();
+					t = readl (&ep->regs->ep_stat);
+					count = readl (&ep->dma->dmacount);
+					count &= DMA_BYTE_COUNT_MASK;
+				}
+			}
+
+			/* stop DMA, leave ep NAKing */
+			writel ((1 << DMA_ABORT), &ep->dma->dmastat);
+			spin_stop_dma (ep->dma);
+
+			/* buffer might have been too small */
+			t = readl (&ep->regs->ep_avail);
+			if (t != 0)
+				DEBUG (ep->dev, "%s dma, discard %d len %d\n",
+						ep->ep.name, t, count);
+			dma_done (ep, req, count, t ? -EOVERFLOW : 0);
+
+			/* also flush to prevent erratum 0106 trouble */
+			if (t || ep->dev->chiprev == 0x0100)
+				out_flush (ep);
+
+			/* restart dma (still NAKing OUT!) if needed */
+			if (!list_empty (&ep->queue))
+				restart_dma (ep);
+		} else
+			DEBUG (ep->dev, "%s dma ep_stat %08x ??\n",
+					ep->ep.name, t);
+		return;
+
+	/* data packet(s) received (in the fifo, OUT) */
+	} else if (t & (1 << DATA_PACKET_RECEIVED_INTERRUPT)) {
+		if (read_fifo (ep, req) && ep->num != 0)
+			mode = 2;
+
+	/* data packet(s) transmitted (IN) */
+	} else if (t & (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)) {
+		unsigned	len;
+
+		len = req->req.length - req->req.actual;
+		len = min (ep->ep.maxpacket, len);
+		req->req.actual += len;
+
+		/* if we wrote it all, we're usually done */
+		if (req->req.actual == req->req.length) {
+			if (ep->num == 0) {
+				/* wait for control status */
+				if (mode != 2)
+					req = 0;
+			} else if (!req->req.zero || len != ep->ep.maxpacket)
+				mode = 2;
+		}
+
+	/* there was nothing to do ...  */
+	} else if (mode == 1)
+		return;
+
+	/* done */
+	if (mode == 2) {
+		/* stream endpoints often resubmit/unlink in completion */
+		done (ep, req, 0);
+
+		/* maybe advance queue to next request */
+		if (ep->num == 0) {
+			/* NOTE:  net2280 could let gadget driver start the
+			 * status stage later. since not all controllers let
+			 * them control that, the api doesn't (yet) allow it.
+			 */
+			if (!ep->stopped)
+				allow_status (ep);
+			req = 0;
+		} else {
+			if (!list_empty (&ep->queue) && !ep->stopped)
+				req = list_entry (ep->queue.next,
+					struct net2280_request, queue);
+			else
+				req = 0;
+			if (req && !ep->is_in)
+				stop_out_naking (ep);
+		}
+	}
+
+	/* is there a buffer for the next packet?
+	 * for best streaming performance, make sure there is one.
+	 */
+	if (req && !ep->stopped) {
+
+		/* load IN fifo with next packet (may be zlp) */
+		if (t & (1 << DATA_PACKET_TRANSMITTED_INTERRUPT))
+			write_fifo (ep, &req->req);
+	}
+}
+
+static struct net2280_ep *
+get_ep_by_addr (struct net2280 *dev, u16 wIndex)
+{
+	struct net2280_ep	*ep;
+
+	if ((wIndex & USB_ENDPOINT_NUMBER_MASK) == 0)
+		return &dev->ep [0];
+	list_for_each_entry (ep, &dev->gadget.ep_list, ep.ep_list) {
+		u8	bEndpointAddress;
+
+		if (!ep->desc)
+			continue;
+		bEndpointAddress = ep->desc->bEndpointAddress;
+		if ((wIndex ^ bEndpointAddress) & USB_DIR_IN)
+			continue;
+		if ((wIndex & 0x0f) == (bEndpointAddress & 0x0f))
+			return ep;
+	}
+	return 0;
+}
+
+static void handle_stat0_irqs (struct net2280 *dev, u32 stat)
+{
+	struct net2280_ep	*ep;
+	u32			num, scratch;
+
+	/* most of these don't need individual acks */
+	stat &= ~(1 << INTA_ASSERTED);
+	if (!stat)
+		return;
+	// DEBUG (dev, "irqstat0 %04x\n", stat);
+
+	/* starting a control request? */
+	if (unlikely (stat & (1 << SETUP_PACKET_INTERRUPT))) {
+		union {
+			u32			raw [2];
+			struct usb_ctrlrequest	r;
+		} u;
+		int				tmp = 0;
+		struct net2280_request		*req;
+
+		if (dev->gadget.speed == USB_SPEED_UNKNOWN) {
+			if (readl (&dev->usb->usbstat) & (1 << HIGH_SPEED))
+				dev->gadget.speed = USB_SPEED_HIGH;
+			else
+				dev->gadget.speed = USB_SPEED_FULL;
+			net2280_led_speed (dev, dev->gadget.speed);
+			DEBUG (dev, "%s speed\n",
+				(dev->gadget.speed == USB_SPEED_HIGH)
+					? "high" : "full");
+		}
+
+		ep = &dev->ep [0];
+		ep->irqs++;
+
+		/* make sure any leftover request state is cleared */
+		stat &= ~(1 << ENDPOINT_0_INTERRUPT);
+		while (!list_empty (&ep->queue)) {
+			req = list_entry (ep->queue.next,
+					struct net2280_request, queue);
+			done (ep, req, (req->req.actual == req->req.length)
+						? 0 : -EPROTO);
+		}
+		ep->stopped = 0;
+		dev->protocol_stall = 0;
+		writel (  (1 << TIMEOUT)
+			| (1 << USB_STALL_SENT)
+			| (1 << USB_IN_NAK_SENT)
+			| (1 << USB_IN_ACK_RCVD)
+			| (1 << USB_OUT_PING_NAK_SENT)
+			| (1 << USB_OUT_ACK_SENT)
+			| (1 << FIFO_OVERFLOW)
+			| (1 << FIFO_UNDERFLOW)
+			| (1 << SHORT_PACKET_OUT_DONE_INTERRUPT)
+			| (1 << SHORT_PACKET_TRANSFERRED_INTERRUPT)
+			| (1 << DATA_PACKET_RECEIVED_INTERRUPT)
+			| (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)
+			| (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+			| (1 << DATA_IN_TOKEN_INTERRUPT)
+			, &ep->regs->ep_stat);
+		u.raw [0] = readl (&dev->usb->setup0123);
+		u.raw [1] = readl (&dev->usb->setup4567);
+		
+		cpu_to_le32s (&u.raw [0]);
+		cpu_to_le32s (&u.raw [1]);
+
+		le16_to_cpus (&u.r.wValue);
+		le16_to_cpus (&u.r.wIndex);
+		le16_to_cpus (&u.r.wLength);
+
+		/* ack the irq */
+		writel (1 << SETUP_PACKET_INTERRUPT, &dev->regs->irqstat0);
+		stat ^= (1 << SETUP_PACKET_INTERRUPT);
+
+		/* watch control traffic at the token level, and force
+		 * synchronization before letting the status stage happen.
+		 * FIXME ignore tokens we'll NAK, until driver responds.
+		 * that'll mean a lot less irqs for some drivers.
+		 */
+		ep->is_in = (u.r.bRequestType & USB_DIR_IN) != 0;
+		if (ep->is_in)
+			scratch = (1 << DATA_PACKET_TRANSMITTED_INTERRUPT)
+				| (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+				| (1 << DATA_IN_TOKEN_INTERRUPT);
+		else
+			scratch = (1 << DATA_PACKET_RECEIVED_INTERRUPT)
+				| (1 << DATA_OUT_PING_TOKEN_INTERRUPT)
+				| (1 << DATA_IN_TOKEN_INTERRUPT);
+		writel (scratch, &dev->epregs [0].ep_irqenb);
+
+		/* we made the hardware handle most lowlevel requests;
+		 * everything else goes uplevel to the gadget code.
+		 */
+		switch (u.r.bRequest) {
+		case USB_REQ_GET_STATUS: {
+			struct net2280_ep	*e;
+			u16			status;
+
+			/* hw handles device and interface status */
+			if (u.r.bRequestType != (USB_DIR_IN|USB_RECIP_ENDPOINT))
+				goto delegate;
+			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0
+					|| u.r.wLength > 2)
+				goto do_stall;
+
+			if (readl (&e->regs->ep_rsp)
+					& (1 << SET_ENDPOINT_HALT))
+				status = __constant_cpu_to_le16 (1);
+			else
+				status = __constant_cpu_to_le16 (0);
+
+			/* don't bother with a request object! */
+			writel (0, &dev->epregs [0].ep_irqenb);
+			set_fifo_bytecount (ep, u.r.wLength);
+			writel (status, &dev->epregs [0].ep_data);
+			allow_status (ep);
+			VDEBUG (dev, "%s stat %02x\n", ep->ep.name, status);
+			goto next_endpoints;
+			}
+			break;
+		case USB_REQ_CLEAR_FEATURE: {
+			struct net2280_ep	*e;
+
+			/* hw handles device features */
+			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
+				goto delegate;
+			if (u.r.wValue != 0 /* HALT feature */
+					|| u.r.wLength != 0)
+				goto do_stall;
+			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
+				goto do_stall;
+			clear_halt (e);
+			allow_status (ep);
+			VDEBUG (dev, "%s clear halt\n", ep->ep.name);
+			goto next_endpoints;
+			}
+			break;
+		case USB_REQ_SET_FEATURE: {
+			struct net2280_ep	*e;
+
+			/* hw handles device features */
+			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
+				goto delegate;
+			if (u.r.wValue != 0 /* HALT feature */
+					|| u.r.wLength != 0)
+				goto do_stall;
+			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
+				goto do_stall;
+			set_halt (e);
+			allow_status (ep);
+			VDEBUG (dev, "%s set halt\n", ep->ep.name);
+			goto next_endpoints;
+			}
+			break;
+		default:
+delegate:
+			VDEBUG (dev, "setup %02x.%02x v%04x i%04x "
+				"ep_cfg %08x\n",
+				u.r.bRequestType, u.r.bRequest,
+				u.r.wValue, u.r.wIndex,
+				readl (&ep->regs->ep_cfg));
+			spin_unlock (&dev->lock);
+			tmp = dev->driver->setup (&dev->gadget, &u.r);
+			spin_lock (&dev->lock);
+		}
+
+		/* stall ep0 on error */
+		if (tmp < 0) {
+do_stall:
+			VDEBUG (dev, "req %02x.%02x protocol STALL; stat %d\n",
+					u.r.bRequestType, u.r.bRequest, tmp);
+			dev->protocol_stall = 1;
+		}
+
+		/* some in/out token irq should follow; maybe stall then.
+		 * driver must queue a request (even zlp) or halt ep0
+		 * before the host times out.
+		 */
+	}
+
+next_endpoints:
+	/* endpoint data irq ? */
+	scratch = stat & 0x7f;
+	stat &= ~0x7f;
+	for (num = 0; scratch; num++) {
+		u32		t;
+
+		/* do this endpoint's FIFO and queue need tending? */
+		t = 1 << num;
+		if ((scratch & t) == 0)
+			continue;
+		scratch ^= t;
+
+		ep = &dev->ep [num];
+		handle_ep_small (ep);
+	}
+
+	if (stat)
+		DEBUG (dev, "unhandled irqstat0 %08x\n", stat);
+}
+
+#define DMA_INTERRUPTS ( \
+		  (1 << DMA_D_INTERRUPT) \
+		| (1 << DMA_C_INTERRUPT) \
+		| (1 << DMA_B_INTERRUPT) \
+		| (1 << DMA_A_INTERRUPT))
+#define	PCI_ERROR_INTERRUPTS ( \
+		  (1 << PCI_MASTER_ABORT_RECEIVED_INTERRUPT) \
+		| (1 << PCI_TARGET_ABORT_RECEIVED_INTERRUPT) \
+		| (1 << PCI_RETRY_ABORT_INTERRUPT))
+
+static void handle_stat1_irqs (struct net2280 *dev, u32 stat)
+{
+	struct net2280_ep	*ep;
+	u32			tmp, num, scratch;
+
+	/* after disconnect there's nothing else to do! */
+	tmp = (1 << VBUS_INTERRUPT) | (1 << ROOT_PORT_RESET_INTERRUPT);
+	if (stat & tmp) {
+		writel (tmp, &dev->regs->irqstat1);
+		if (((stat & (1 << ROOT_PORT_RESET_INTERRUPT)) != 0
+			|| (readl (&dev->usb->usbctl) & (1 << VBUS_PIN)) == 0
+			) && dev->gadget.speed != USB_SPEED_UNKNOWN) {
+			DEBUG (dev, "disconnect %s\n",
+					dev->driver->driver.name);
+			stop_activity (dev, dev->driver);
+			ep0_start (dev);
+			return;
+		}
+		stat &= ~tmp;
+
+		/* vBUS can bounce ... one of many reasons to ignore the
+		 * notion of hotplug events on bus connect/disconnect!
+		 */
+		if (!stat)
+			return;
+	}
+
+	/* NOTE: we don't actually suspend the hardware; that starts to
+	 * interact with PCI power management, and needs something like a
+	 * controller->suspend() call to clear SUSPEND_REQUEST_INTERRUPT.
+	 * we shouldn't see resume interrupts.
+	 * for rev 0100, this also avoids erratum 0102.
+	 */
+	tmp = (1 << SUSPEND_REQUEST_CHANGE_INTERRUPT);
+	if (stat & tmp) {
+		if (dev->driver->suspend)
+			dev->driver->suspend (&dev->gadget);
+		stat &= ~tmp;
+	}
+	stat &= ~(1 << SUSPEND_REQUEST_INTERRUPT);
+
+	/* clear any other status/irqs */
+	if (stat)
+		writel (stat, &dev->regs->irqstat1);
+
+	/* some status we can just ignore */
+	stat &= ~((1 << CONTROL_STATUS_INTERRUPT)
+			| (1 << RESUME_INTERRUPT)
+			| (1 << SOF_INTERRUPT));
+	if (!stat)
+		return;
+	// DEBUG (dev, "irqstat1 %08x\n", stat);
+
+	/* DMA status, for ep-{a,b,c,d} */
+	scratch = stat & DMA_INTERRUPTS;
+	stat &= ~DMA_INTERRUPTS;
+	scratch >>= 9;
+	for (num = 0; scratch; num++) {
+		struct net2280_dma_regs	*dma;
+
+		tmp = 1 << num;
+		if ((tmp & scratch) == 0)
+			continue;
+		scratch ^= tmp;
+
+		ep = &dev->ep [num + 1];
+		dma = ep->dma;
+
+		if (!dma)
+			continue;
+
+		/* clear ep's dma status */
+		tmp = readl (&dma->dmastat);
+		writel (tmp, &dma->dmastat);
+
+#ifdef USE_DMA_CHAINING
+		/* chaining should stop only on error (which?)
+		 * or (stat0 codepath) short OUT transfer.
+		 */
+#else
+		if ((tmp & (1 << DMA_TRANSACTION_DONE_INTERRUPT)) == 0) {
+			DEBUG (ep->dev, "%s no xact done? %08x\n",
+				ep->ep.name, tmp);
+			continue;
+		}
+		stop_dma (ep->dma);
+#endif
+
+		/* OUT transfers terminate when the data from the
+		 * host is in our memory.  Process whatever's done.
+		 * On this path, we know transfer's last packet wasn't
+		 * less than req->length. NAK_OUT_PACKETS may be set,
+		 * or the FIFO may already be holding new packets.
+		 *
+		 * IN transfers can linger in the FIFO for a very
+		 * long time ... we ignore that for now, accounting
+		 * precisely (like PIO does) needs per-packet irqs
+		 */
+		scan_dma_completions (ep);
+
+		/* disable dma on inactive queues; else maybe restart */
+		if (list_empty (&ep->queue)) {
+#ifdef USE_DMA_CHAINING
+			stop_dma (ep->dma);
+#endif
+		} else {
+			tmp = readl (&dma->dmactl);
+			if ((tmp & (1 << DMA_SCATTER_GATHER_ENABLE)) == 0
+					|| (tmp & (1 << DMA_ENABLE)) == 0)
+				restart_dma (ep);
+#ifdef USE_DMA_CHAINING
+			else if (ep->desc->bEndpointAddress & USB_DIR_IN) {
+				struct net2280_request	*req;
+				u32			dmacount;
+
+				/* the descriptor at the head of the chain
+				 * may still have VALID_BIT clear; that's
+				 * used to trigger changing DMA_FIFO_VALIDATE
+				 * (affects automagic zlp writes).
+				 */
+				req = list_entry (ep->queue.next,
+						struct net2280_request, queue);
+				dmacount = req->td->dmacount;
+				dmacount &= __constant_cpu_to_le32 (
+						(1 << VALID_BIT)
+						| DMA_BYTE_COUNT_MASK);
+				if (dmacount && (dmacount & valid_bit) == 0) {
+					stop_dma (ep->dma);
+					restart_dma (ep);
+				}
+			}
+#endif
+		}
+		ep->irqs++;
+	}
+
+	/* NOTE:  there are other PCI errors we might usefully notice.
+	 * if they appear very often, here's where to try recovering.
+	 */
+	if (stat & PCI_ERROR_INTERRUPTS) {
+		ERROR (dev, "pci dma error; stat %08x\n", stat);
+		stat &= ~PCI_ERROR_INTERRUPTS;
+		/* these are fatal errors, but "maybe" they won't
+		 * happen again ...
+		 */
+		stop_activity (dev, dev->driver);
+		ep0_start (dev);
+		stat = 0;
+	}
+
+	if (stat)
+		DEBUG (dev, "unhandled irqstat1 %08x\n", stat);
+}
+
+static irqreturn_t net2280_irq (int irq, void *_dev, struct pt_regs * r)
+{
+	struct net2280		*dev = _dev;
+
+	spin_lock (&dev->lock);
+
+	/* handle disconnect, dma, and more */
+	handle_stat1_irqs (dev, readl (&dev->regs->irqstat1));
+
+	/* control requests and PIO */
+	handle_stat0_irqs (dev, readl (&dev->regs->irqstat0));
+
+	spin_unlock (&dev->lock);
+
+	return IRQ_HANDLED;
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* tear down the binding between this driver and the pci device */
+
+static void net2280_remove (struct pci_dev *pdev)
+{
+	struct net2280		*dev = pci_get_drvdata (pdev);
+
+	/* start with the driver above us */
+	if (dev->driver) {
+		/* should have been done already by driver model core */
+		WARN (dev, "pci remove, driver '%s' is still registered\n",
+				dev->driver->driver.name);
+		usb_gadget_unregister_driver (dev->driver);
+	}
+
+	/* then clean up the resources we allocated during probe() */
+	net2280_led_shutdown (dev);
+	if (dev->requests) {
+		int		i;
+		for (i = 1; i < 5; i++) {
+			if (!dev->ep [i].dummy)
+				continue;
+			pci_pool_free (dev->requests, dev->ep [i].dummy,
+					dev->ep [i].td_dma);
+		}
+		pci_pool_destroy (dev->requests);
+	}
+	if (dev->got_irq)
+		free_irq (pdev->irq, dev);
+	if (dev->regs)
+		iounmap (dev->regs);
+	if (dev->region)
+		release_mem_region (pci_resource_start (pdev, 0),
+				pci_resource_len (pdev, 0));
+	if (dev->enabled)
+		pci_disable_device (pdev);
+	pci_set_drvdata (pdev, 0);
+
+	INFO (dev, "unbind from pci %s\n", pdev->slot_name);
+
+	kfree (dev);
+	the_controller = 0;
+}
+
+/* wrap this driver around the specified device, but
+ * don't respond over USB until a gadget driver binds to us.
+ */
+
+static int net2280_probe (struct pci_dev *pdev, const struct pci_device_id *id)
+{
+	struct net2280		*dev;
+	unsigned long		resource, len;
+	void			*base = 0;
+	int			retval, i;
+	char			buf [8], *bufp;
+
+	/* if you want to support more than one controller in a system,
+	 * usb_gadget_driver_{register,unregister}() must change.
+	 */
+	if (the_controller) {
+		WARN (the_controller, "ignoring %s\n", pdev->slot_name);
+		return -EBUSY;
+	}
+
+	/* alloc, and start init */
+	dev = kmalloc (sizeof *dev, SLAB_KERNEL);
+	if (dev == NULL){
+		retval = -ENOMEM;
+		goto done;
+	}
+
+	memset (dev, 0, sizeof *dev);
+	spin_lock_init (&dev->lock);
+	dev->pdev = pdev;
+	dev->gadget.ops = &net2280_ops;
+
+	dev->gadget.dev.bus_id = pdev->slot_name;
+	dev->gadget.name = driver_name;
+
+	/* now all the pci goodies ... */
+	if (pci_enable_device (pdev) < 0) {
+   	        retval = -ENODEV;
+		goto done;
+	}
+	dev->enabled = 1;
+
+	/* BAR 0 holds all the registers
+	 * BAR 1 is 8051 memory; unused here (note erratum 0103)
+	 * BAR 2 is fifo memory; unused here
+	 */
+	resource = pci_resource_start (pdev, 0);
+	len = pci_resource_len (pdev, 0);
+	if (!request_mem_region (resource, len, driver_name)) {
+		DEBUG (dev, "controller already in use\n");
+		retval = -EBUSY;
+		goto done;
+	}
+	dev->region = 1;
+
+	base = ioremap_nocache (resource, len);
+	if (base == NULL) {
+		DEBUG (dev, "can't map memory\n");
+		retval = -EFAULT;
+		goto done;
+	}
+	dev->regs = (struct net2280_regs *) base;
+	dev->usb = (struct net2280_usb_regs *) (base + 0x0080);
+	dev->pci = (struct net2280_pci_regs *) (base + 0x0100);
+	dev->dma = (struct net2280_dma_regs *) (base + 0x0180);
+	dev->dep = (struct net2280_dep_regs *) (base + 0x0200);
+	dev->epregs = (struct net2280_ep_regs *) (base + 0x0300);
+
+	/* put into initial config, link up all endpoints */
+	usb_reset (dev);
+	usb_reinit (dev);
+
+	/* irq setup after old hardware is cleaned up */
+	if (!pdev->irq) {
+		ERROR (dev, "No IRQ.  Check PCI setup!\n");
+		retval = -ENODEV;
+		goto done;
+	}
+#ifndef __sparc__
+	snprintf (buf, sizeof buf, "%d", pdev->irq);
+	bufp = buf;
+#else
+	bufp = __irq_itoa(pdev->irq);
+#endif
+	if (request_irq (pdev->irq, net2280_irq, SA_SHIRQ, driver_name, dev)
+			!= 0) {
+		ERROR (dev, "request interrupt %s failed\n", bufp);
+		retval = -EBUSY;
+		goto done;
+	}
+	dev->got_irq = 1;
+
+	/* DMA setup */
+	dev->requests = pci_pool_create ("requests", pdev,
+		sizeof (struct net2280_dma),
+		0 /* no alignment requirements */,
+		0 /* or page-crossing issues */,
+		SLAB_KERNEL /* 2.4 only */ );
+	if (!dev->requests) {
+		DEBUG (dev, "can't get request pool\n");
+		retval = -ENOMEM;
+		goto done;
+	}
+	for (i = 1; i < 5; i++) {
+		struct net2280_dma	*td;
+
+		td = pci_pool_alloc (dev->requests, GFP_KERNEL,
+				&dev->ep [i].td_dma);
+		if (!td) {
+			DEBUG (dev, "can't get dummy %d\n", i);
+			retval = -ENOMEM;
+			goto done;
+		}
+		td->dmacount = 0;	/* not VALID */
+		td->dmaaddr = __constant_cpu_to_le32 (DMA_ADDR_INVALID);
+		dev->ep [i].dummy = td;
+	}
+
+	/* enable lower-overhead pci memory bursts during DMA */
+	writel ((1 << PCI_RETRY_ABORT_ENABLE)
+			| (1 << DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE)
+			| (1 << DMA_READ_MULTIPLE_ENABLE)
+			| (1 << DMA_READ_LINE_ENABLE)
+			, &dev->pci->pcimstctl);
+	/* erratum 0115 shouldn't appear: Linux inits PCI_LATENCY_TIMER */
+	pci_set_master (pdev);
+#ifdef	HAVE_PCI_SET_MWI
+	pci_set_mwi (pdev);
+#endif
+
+	/* ... also flushes any posted pci writes */
+	dev->chiprev = get_idx_reg (dev->regs, REG_CHIPREV) & 0xffff;
+
+	/* done */
+	pci_set_drvdata (pdev, dev);
+	INFO (dev, "%s\n", driver_desc);
+	INFO (dev, "irq %s, pci mem %p, chip rev %04x\n",
+			bufp, base, dev->chiprev);
+	bufp = DRIVER_VERSION
+#ifndef USE_DMA_CHAINING
+		" (no dma chain)"
+#endif
+#ifdef NET2280_DMA_OUT_WORKAROUND
+		" (no dma out)"
+#endif
+		;
+	INFO (dev, "version: %s\n", bufp);
+	the_controller = dev;
+
+	return 0;
+
+done:
+	if (dev)
+		net2280_remove (pdev);
+	return retval;
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+static struct pci_device_id pci_ids [] = { {
+	.class = 	((PCI_CLASS_SERIAL_USB << 8) | 0xfe),
+	.class_mask = 	~0,
+	.vendor =	0x17cc,
+	.device =	0x2280,
+	.subvendor =	PCI_ANY_ID,
+	.subdevice =	PCI_ANY_ID,
+
+}, { /* end: all zeroes */ }
+};
+MODULE_DEVICE_TABLE (pci, pci_ids);
+
+/* pci driver glue; this is a "new style" PCI driver module */
+static struct pci_driver net2280_pci_driver = {
+	.name =		(char *) driver_name,
+	.id_table =	pci_ids,
+
+	.probe =	net2280_probe,
+	.remove =	net2280_remove,
+
+	/* FIXME add power management support */
+};
+
+MODULE_DESCRIPTION (DRIVER_DESC);
+MODULE_AUTHOR ("David Brownell");
+MODULE_LICENSE ("GPL");
+
+static int __init init (void)
+{
+	return pci_module_init (&net2280_pci_driver);
+}
+module_init (init);
+
+static void __exit cleanup (void)
+{
+	pci_unregister_driver (&net2280_pci_driver);
+}
+module_exit (cleanup);
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/net2280.h linux-2.4.23-pre7/drivers/usb/gadget/net2280.h
--- linux-2.4.23-pre6/drivers/usb/gadget/net2280.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/net2280.h	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,755 @@
+/*
+ * NetChip 2280 high/full speed USB device controller.
+ * Unlike many such controllers, this one talks PCI.
+ */
+
+/*
+ * Copyright (C) 2002 NetChip Technology, Inc. (http://www.netchip.com)
+ * Copyright (C) 2003 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*-------------------------------------------------------------------------*/
+
+/* NET2280 MEMORY MAPPED REGISTERS
+ *
+ * The register layout came from the chip documentation, and the bit
+ * number definitions were extracted from chip specification.
+ *
+ * Use the shift operator ('<<') to build bit masks, with readl/writel
+ * to access the registers through PCI.
+ */
+
+/* main registers, BAR0 + 0x0000 */
+struct net2280_regs {
+	// offset 0x0000
+	u32		devinit;
+#define     LOCAL_CLOCK_FREQUENCY                               8
+#define     FORCE_PCI_RESET                                     7
+#define     PCI_ID                                              6
+#define     PCI_ENABLE                                          5
+#define     FIFO_SOFT_RESET                                     4
+#define     CFG_SOFT_RESET                                      3
+#define     PCI_SOFT_RESET                                      2
+#define     USB_SOFT_RESET                                      1
+#define     M8051_RESET                                         0
+	u32		eectl;
+#define     EEPROM_ADDRESS_WIDTH                                23
+#define     EEPROM_CHIP_SELECT_ACTIVE                           22
+#define     EEPROM_PRESENT                                      21
+#define     EEPROM_VALID                                        20
+#define     EEPROM_BUSY                                         19
+#define     EEPROM_CHIP_SELECT_ENABLE                           18
+#define     EEPROM_BYTE_READ_START                              17
+#define     EEPROM_BYTE_WRITE_START                             16
+#define     EEPROM_READ_DATA                                    8
+#define     EEPROM_WRITE_DATA                                   0
+	u32		eeclkfreq;
+	u32		_unused0;
+	// offset 0x0010
+
+	u32		pciirqenb0;		/* interrupt PCI master ... */
+#define     SETUP_PACKET_INTERRUPT_ENABLE                       7
+#define     ENDPOINT_F_INTERRUPT_ENABLE                         6
+#define     ENDPOINT_E_INTERRUPT_ENABLE                         5
+#define     ENDPOINT_D_INTERRUPT_ENABLE                         4
+#define     ENDPOINT_C_INTERRUPT_ENABLE                         3
+#define     ENDPOINT_B_INTERRUPT_ENABLE                         2
+#define     ENDPOINT_A_INTERRUPT_ENABLE                         1
+#define     ENDPOINT_0_INTERRUPT_ENABLE                         0
+	u32		pciirqenb1;
+#define     PCI_INTERRUPT_ENABLE                                31
+#define     POWER_STATE_CHANGE_INTERRUPT_ENABLE                 27
+#define     PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE                26
+#define     PCI_PARITY_ERROR_INTERRUPT_ENABLE                   25
+#define     PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE          20
+#define     PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE          19
+#define     PCI_TARGET_ABORT_ASSERTED_INTERRUPT_ENABLE          18
+#define     PCI_RETRY_ABORT_INTERRUPT_ENABLE                    17
+#define     PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE              16
+#define     GPIO_INTERRUPT_ENABLE                               13
+#define     DMA_D_INTERRUPT_ENABLE                              12
+#define     DMA_C_INTERRUPT_ENABLE                              11
+#define     DMA_B_INTERRUPT_ENABLE                              10
+#define     DMA_A_INTERRUPT_ENABLE                              9
+#define     EEPROM_DONE_INTERRUPT_ENABLE                        8
+#define     VBUS_INTERRUPT_ENABLE                               7
+#define     CONTROL_STATUS_INTERRUPT_ENABLE                     6
+#define     ROOT_PORT_RESET_INTERRUPT_ENABLE                    4
+#define     SUSPEND_REQUEST_INTERRUPT_ENABLE                    3
+#define     SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE             2
+#define     RESUME_INTERRUPT_ENABLE                             1
+#define     SOF_INTERRUPT_ENABLE                                0
+	u32		cpu_irqenb0;		/* ... or onboard 8051 */
+#define     SETUP_PACKET_INTERRUPT_ENABLE                       7
+#define     ENDPOINT_F_INTERRUPT_ENABLE                         6
+#define     ENDPOINT_E_INTERRUPT_ENABLE                         5
+#define     ENDPOINT_D_INTERRUPT_ENABLE                         4
+#define     ENDPOINT_C_INTERRUPT_ENABLE                         3
+#define     ENDPOINT_B_INTERRUPT_ENABLE                         2
+#define     ENDPOINT_A_INTERRUPT_ENABLE                         1
+#define     ENDPOINT_0_INTERRUPT_ENABLE                         0
+	u32		cpu_irqenb1;
+#define     CPU_INTERRUPT_ENABLE                                31
+#define     POWER_STATE_CHANGE_INTERRUPT_ENABLE                 27
+#define     PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE                26
+#define     PCI_PARITY_ERROR_INTERRUPT_ENABLE                   25
+#define     PCI_INTA_INTERRUPT_ENABLE                           24
+#define     PCI_PME_INTERRUPT_ENABLE                            23
+#define     PCI_SERR_INTERRUPT_ENABLE                           22
+#define     PCI_PERR_INTERRUPT_ENABLE                           21
+#define     PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE          20
+#define     PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE          19
+#define     PCI_RETRY_ABORT_INTERRUPT_ENABLE                    17
+#define     PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE              16
+#define     GPIO_INTERRUPT_ENABLE                               13
+#define     DMA_D_INTERRUPT_ENABLE                              12
+#define     DMA_C_INTERRUPT_ENABLE                              11
+#define     DMA_B_INTERRUPT_ENABLE                              10
+#define     DMA_A_INTERRUPT_ENABLE                              9
+#define     EEPROM_DONE_INTERRUPT_ENABLE                        8
+#define     VBUS_INTERRUPT_ENABLE                               7
+#define     CONTROL_STATUS_INTERRUPT_ENABLE                     6
+#define     ROOT_PORT_RESET_INTERRUPT_ENABLE                    4
+#define     SUSPEND_REQUEST_INTERRUPT_ENABLE                    3
+#define     SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE             2
+#define     RESUME_INTERRUPT_ENABLE                             1
+#define     SOF_INTERRUPT_ENABLE                                0
+
+	// offset 0x0020
+	u32		_unused1;
+	u32		usbirqenb1;
+#define     USB_INTERRUPT_ENABLE                                31
+#define     POWER_STATE_CHANGE_INTERRUPT_ENABLE                 27
+#define     PCI_ARBITER_TIMEOUT_INTERRUPT_ENABLE                26
+#define     PCI_PARITY_ERROR_INTERRUPT_ENABLE                   25
+#define     PCI_INTA_INTERRUPT_ENABLE                           24
+#define     PCI_PME_INTERRUPT_ENABLE                            23
+#define     PCI_SERR_INTERRUPT_ENABLE                           22
+#define     PCI_PERR_INTERRUPT_ENABLE                           21
+#define     PCI_MASTER_ABORT_RECEIVED_INTERRUPT_ENABLE          20
+#define     PCI_TARGET_ABORT_RECEIVED_INTERRUPT_ENABLE          19
+#define     PCI_RETRY_ABORT_INTERRUPT_ENABLE                    17
+#define     PCI_MASTER_CYCLE_DONE_INTERRUPT_ENABLE              16
+#define     GPIO_INTERRUPT_ENABLE                               13
+#define     DMA_D_INTERRUPT_ENABLE                              12
+#define     DMA_C_INTERRUPT_ENABLE                              11
+#define     DMA_B_INTERRUPT_ENABLE                              10
+#define     DMA_A_INTERRUPT_ENABLE                              9
+#define     EEPROM_DONE_INTERRUPT_ENABLE                        8
+#define     VBUS_INTERRUPT_ENABLE                               7
+#define     CONTROL_STATUS_INTERRUPT_ENABLE                     6
+#define     ROOT_PORT_RESET_INTERRUPT_ENABLE                    4
+#define     SUSPEND_REQUEST_INTERRUPT_ENABLE                    3
+#define     SUSPEND_REQUEST_CHANGE_INTERRUPT_ENABLE             2
+#define     RESUME_INTERRUPT_ENABLE                             1
+#define     SOF_INTERRUPT_ENABLE                                0
+	u32		irqstat0;
+#define     INTA_ASSERTED                                       12
+#define     SETUP_PACKET_INTERRUPT                              7
+#define     ENDPOINT_F_INTERRUPT                                6
+#define     ENDPOINT_E_INTERRUPT                                5
+#define     ENDPOINT_D_INTERRUPT                                4
+#define     ENDPOINT_C_INTERRUPT                                3
+#define     ENDPOINT_B_INTERRUPT                                2
+#define     ENDPOINT_A_INTERRUPT                                1
+#define     ENDPOINT_0_INTERRUPT                                0
+	u32		irqstat1;
+#define     POWER_STATE_CHANGE_INTERRUPT                        27
+#define     PCI_ARBITER_TIMEOUT_INTERRUPT                       26
+#define     PCI_PARITY_ERROR_INTERRUPT                          25
+#define     PCI_INTA_INTERRUPT                                  24
+#define     PCI_PME_INTERRUPT                                   23
+#define     PCI_SERR_INTERRUPT                                  22
+#define     PCI_PERR_INTERRUPT                                  21
+#define     PCI_MASTER_ABORT_RECEIVED_INTERRUPT                 20
+#define     PCI_TARGET_ABORT_RECEIVED_INTERRUPT                 19
+#define     PCI_RETRY_ABORT_INTERRUPT                           17
+#define     PCI_MASTER_CYCLE_DONE_INTERRUPT                     16
+#define     GPIO_INTERRUPT                                      13
+#define     DMA_D_INTERRUPT                                     12
+#define     DMA_C_INTERRUPT                                     11
+#define     DMA_B_INTERRUPT                                     10
+#define     DMA_A_INTERRUPT                                     9
+#define     EEPROM_DONE_INTERRUPT                               8
+#define     VBUS_INTERRUPT                                      7
+#define     CONTROL_STATUS_INTERRUPT                            6
+#define     ROOT_PORT_RESET_INTERRUPT                           4
+#define     SUSPEND_REQUEST_INTERRUPT                           3
+#define     SUSPEND_REQUEST_CHANGE_INTERRUPT                    2
+#define     RESUME_INTERRUPT                                    1
+#define     SOF_INTERRUPT                                       0
+	// offset 0x0030
+	u32		idxaddr;
+	u32		idxdata;
+	u32		fifoctl;
+#define     PCI_BASE2_RANGE                                     16
+#define     IGNORE_FIFO_AVAILABILITY                            3
+#define     PCI_BASE2_SELECT                                    2
+#define     FIFO_CONFIGURATION_SELECT                           0
+	u32		_unused2;
+	// offset 0x0040
+	u32		memaddr;
+#define     START                                               28
+#define     DIRECTION                                           27
+#define     FIFO_DIAGNOSTIC_SELECT                              24
+#define     MEMORY_ADDRESS                                      0
+	u32		memdata0;
+	u32		memdata1;
+	u32		_unused3;
+	// offset 0x0050
+	u32		gpioctl;
+#define     GPIO3_LED_SELECT                                    12
+#define     GPIO3_INTERRUPT_ENABLE                              11
+#define     GPIO2_INTERRUPT_ENABLE                              10
+#define     GPIO1_INTERRUPT_ENABLE                              9
+#define     GPIO0_INTERRUPT_ENABLE                              8
+#define     GPIO3_OUTPUT_ENABLE                                 7
+#define     GPIO2_OUTPUT_ENABLE                                 6
+#define     GPIO1_OUTPUT_ENABLE                                 5
+#define     GPIO0_OUTPUT_ENABLE                                 4
+#define     GPIO3_DATA                                          3
+#define     GPIO2_DATA                                          2
+#define     GPIO1_DATA                                          1
+#define     GPIO0_DATA                                          0
+	u32		gpiostat;
+#define     GPIO3_INTERRUPT                                     3
+#define     GPIO2_INTERRUPT                                     2
+#define     GPIO1_INTERRUPT                                     1
+#define     GPIO0_INTERRUPT                                     0
+} __attribute__ ((packed));
+
+/* usb control, BAR0 + 0x0080 */
+struct net2280_usb_regs {
+	// offset 0x0080
+	u32		stdrsp;
+#define     STALL_UNSUPPORTED_REQUESTS                          31
+#define     SET_TEST_MODE                                       16
+#define     GET_OTHER_SPEED_CONFIGURATION                       15
+#define     GET_DEVICE_QUALIFIER                                14
+#define     SET_ADDRESS                                         13
+#define     ENDPOINT_SET_CLEAR_HALT                             12
+#define     DEVICE_SET_CLEAR_DEVICE_REMOTE_WAKEUP               11
+#define     GET_STRING_DESCRIPTOR_2                             10
+#define     GET_STRING_DESCRIPTOR_1                             9
+#define     GET_STRING_DESCRIPTOR_0                             8
+#define     GET_SET_INTERFACE                                   6
+#define     GET_SET_CONFIGURATION                               5
+#define     GET_CONFIGURATION_DESCRIPTOR                        4
+#define     GET_DEVICE_DESCRIPTOR                               3
+#define     GET_ENDPOINT_STATUS                                 2
+#define     GET_INTERFACE_STATUS                                1
+#define     GET_DEVICE_STATUS                                   0
+	u32		prodvendid;
+#define     PRODUCT_ID                                          16
+#define     VENDOR_ID                                           0
+	u32		relnum;
+	u32		usbctl;
+#define     SERIAL_NUMBER_INDEX                                 16
+#define     PRODUCT_ID_STRING_ENABLE                            13
+#define     VENDOR_ID_STRING_ENABLE                             12
+#define     USB_ROOT_PORT_WAKEUP_ENABLE                         11
+#define     VBUS_PIN                                            10
+#define     TIMED_DISCONNECT                                    9
+#define     SUSPEND_IMMEDIATELY                                 7
+#define     SELF_POWERED_USB_DEVICE                             6
+#define     REMOTE_WAKEUP_SUPPORT                               5
+#define     PME_POLARITY                                        4
+#define     USB_DETECT_ENABLE                                   3
+#define     PME_WAKEUP_ENABLE                                   2
+#define     DEVICE_REMOTE_WAKEUP_ENABLE                         1
+#define     SELF_POWERED_STATUS                                 0
+	// offset 0x0090
+	u32		usbstat;
+#define     HIGH_SPEED                                          7
+#define     FULL_SPEED                                          6
+#define     GENERATE_RESUME                                     5
+#define     GENERATE_DEVICE_REMOTE_WAKEUP                       4
+	u32		xcvrdiag;
+#define     FORCE_HIGH_SPEED_MODE                               31
+#define     FORCE_FULL_SPEED_MODE                               30
+#define     USB_TEST_MODE                                       24
+#define     LINE_STATE                                          16
+#define     TRANSCEIVER_OPERATION_MODE                          2
+#define     TRANSCEIVER_SELECT                                  1
+#define     TERMINATION_SELECT                                  0
+	u32		setup0123;
+	u32		setup4567;
+	// offset 0x0090
+	u32		_unused0;
+	u32		ouraddr;
+#define     FORCE_IMMEDIATE                                     7
+#define     OUR_USB_ADDRESS                                     0
+	u32		ourconfig;
+} __attribute__ ((packed));
+
+/* pci control, BAR0 + 0x0100 */
+struct net2280_pci_regs {
+	// offset 0x0100
+	u32		 pcimstctl;
+#define     PCI_ARBITER_PARK_SELECT                             13
+#define     PCI_MULTI LEVEL_ARBITER                             12
+#define     PCI_RETRY_ABORT_ENABLE                              11
+#define     DMA_MEMORY_WRITE_AND_INVALIDATE_ENABLE              10
+#define     DMA_READ_MULTIPLE_ENABLE                            9
+#define     DMA_READ_LINE_ENABLE                                8
+#define     PCI_MASTER_COMMAND_SELECT                           6
+#define         MEM_READ_OR_WRITE                                   0
+#define         IO_READ_OR_WRITE                                    1
+#define         CFG_READ_OR_WRITE                                   2
+#define     PCI_MASTER_START                                    5
+#define     PCI_MASTER_READ_WRITE                               4
+#define         PCI_MASTER_WRITE                                    0
+#define         PCI_MASTER_READ                                     1
+#define     PCI_MASTER_BYTE_WRITE_ENABLES                       0
+	u32		 pcimstaddr;
+	u32		 pcimstdata;
+	u32		 pcimststat;
+#define     PCI_ARBITER_CLEAR                                   2
+#define     PCI_EXTERNAL_ARBITER                                1
+#define     PCI_HOST_MODE                                       0
+} __attribute__ ((packed));
+
+/* dma control, BAR0 + 0x0180 ... array of four structs like this,
+ * for channels 0..3.  see also struct net2280_dma:  descriptor
+ * that can be loaded into some of these registers.
+ */
+struct net2280_dma_regs {	/* [11.7] */
+	// offset 0x0180, 0x01a0, 0x01c0, 0x01e0, 
+	u32		dmactl;
+#define     DMA_SCATTER_GATHER_DONE_INTERRUPT_ENABLE            25
+#define     DMA_CLEAR_COUNT_ENABLE                              21
+#define     DESCRIPTOR_POLLING_RATE                             19
+#define         POLL_CONTINUOUS                                     0
+#define         POLL_1_USEC                                         1
+#define         POLL_100_USEC                                       2
+#define         POLL_1_MSEC                                         3
+#define     DMA_VALID_BIT_POLLING_ENABLE                        18
+#define     DMA_VALID_BIT_ENABLE                                17
+#define     DMA_SCATTER_GATHER_ENABLE                           16
+#define     DMA_OUT_AUTO_START_ENABLE                           4
+#define     DMA_PREEMPT_ENABLE                                  3
+#define     DMA_FIFO_VALIDATE                                   2
+#define     DMA_ENABLE                                          1
+#define     DMA_ADDRESS_HOLD                                    0
+	u32		dmastat;
+#define     DMA_SCATTER_GATHER_DONE_INTERRUPT                   25
+#define     DMA_TRANSACTION_DONE_INTERRUPT                      24
+#define     DMA_ABORT                                           1
+#define     DMA_START                                           0
+	u32		_unused0 [2];
+	// offset 0x0190, 0x01b0, 0x01d0, 0x01f0, 
+	u32		dmacount;
+#define     VALID_BIT                                           31
+#define     DMA_DIRECTION                                       30
+#define     DMA_DONE_INTERRUPT_ENABLE                           29
+#define     END_OF_CHAIN                                        28
+#define         DMA_BYTE_COUNT_MASK                                 ((1<<24)-1)
+#define     DMA_BYTE_COUNT                                      0
+	u32		dmaaddr;
+	u32		dmadesc;
+	u32		_unused1;
+} __attribute__ ((packed));
+
+/* dedicated endpoint registers, BAR0 + 0x0200 */
+
+struct net2280_dep_regs {	/* [11.8] */
+	// offset 0x0200, 0x0210, 0x220, 0x230, 0x240
+	u32		dep_cfg;
+	// offset 0x0204, 0x0214, 0x224, 0x234, 0x244
+	u32		dep_rsp;
+	u32		_unused [2];
+} __attribute__ ((packed));
+
+/* configurable endpoint registers, BAR0 + 0x0300 ... array of seven structs
+ * like this, for ep0 then the configurable endpoints A..F
+ * ep0 reserved for control; E and F have only 64 bytes of fifo
+ */
+struct net2280_ep_regs {	/* [11.9] */
+	// offset 0x0300, 0x0320, 0x0340, 0x0360, 0x0380, 0x03a0, 0x03c0
+	u32		ep_cfg;
+#define     ENDPOINT_BYTE_COUNT                                 16
+#define     ENDPOINT_ENABLE                                     10
+#define     ENDPOINT_TYPE                                       8
+#define     ENDPOINT_DIRECTION                                  7
+#define     ENDPOINT_NUMBER                                     0
+	u32		ep_rsp;
+#define     SET_NAK_OUT_PACKETS                                 15
+#define     SET_EP_HIDE_STATUS_PHASE                            14
+#define     SET_EP_FORCE_CRC_ERROR                              13
+#define     SET_INTERRUPT_MODE                                  12
+#define     SET_CONTROL_STATUS_PHASE_HANDSHAKE                  11
+#define     SET_NAK_OUT_PACKETS_MODE                            10
+#define     SET_ENDPOINT_TOGGLE                                 9
+#define     SET_ENDPOINT_HALT                                   8
+#define     CLEAR_NAK_OUT_PACKETS                               7
+#define     CLEAR_EP_HIDE_STATUS_PHASE                          6
+#define     CLEAR_EP_FORCE_CRC_ERROR                            5
+#define     CLEAR_INTERRUPT_MODE                                4
+#define     CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE                3
+#define     CLEAR_NAK_OUT_PACKETS_MODE                          2
+#define     CLEAR_ENDPOINT_TOGGLE                               1
+#define     CLEAR_ENDPOINT_HALT                                 0
+	u32		ep_irqenb;
+#define     SHORT_PACKET_OUT_DONE_INTERRUPT_ENABLE              6
+#define     SHORT_PACKET_TRANSFERRED_INTERRUPT_ENABLE           5
+#define     DATA_PACKET_RECEIVED_INTERRUPT_ENABLE               3
+#define     DATA_PACKET_TRANSMITTED_INTERRUPT_ENABLE            2
+#define     DATA_OUT_PING_TOKEN_INTERRUPT_ENABLE                1
+#define     DATA_IN_TOKEN_INTERRUPT_ENABLE                      0
+	u32		ep_stat;
+#define     FIFO_VALID_COUNT                                    24
+#define     HIGH_BANDWIDTH_OUT_TRANSACTION_PID                  22
+#define     TIMEOUT                                             21
+#define     USB_STALL_SENT                                      20
+#define     USB_IN_NAK_SENT                                     19
+#define     USB_IN_ACK_RCVD                                     18
+#define     USB_OUT_PING_NAK_SENT                               17
+#define     USB_OUT_ACK_SENT                                    16
+#define     FIFO_OVERFLOW                                       13
+#define     FIFO_UNDERFLOW                                      12
+#define     FIFO_FULL                                           11
+#define     FIFO_EMPTY                                          10
+#define     FIFO_FLUSH                                          9
+#define     SHORT_PACKET_OUT_DONE_INTERRUPT                     6
+#define     SHORT_PACKET_TRANSFERRED_INTERRUPT                  5
+#define     NAK_OUT_PACKETS                                     4
+#define     DATA_PACKET_RECEIVED_INTERRUPT                      3
+#define     DATA_PACKET_TRANSMITTED_INTERRUPT                   2
+#define     DATA_OUT_PING_TOKEN_INTERRUPT                       1
+#define     DATA_IN_TOKEN_INTERRUPT                             0
+	// offset 0x0310, 0x0330, 0x0350, 0x0370, 0x0390, 0x03b0, 0x03d0
+	u32		ep_avail;
+	u32		ep_data;
+	u32		_unused0 [2];
+} __attribute__ ((packed));
+
+/*-------------------------------------------------------------------------*/
+
+#ifdef	__KERNEL__
+
+/* indexed registers [11.10] are accessed indirectly
+ * caller must own the device lock.
+ */
+
+static inline u32
+get_idx_reg (struct net2280_regs *regs, u32 index)
+{
+	writel (index, &regs->idxaddr);
+	/* NOTE:  synchs device/cpu memory views */
+	return readl (&regs->idxdata);
+}
+
+static inline void
+set_idx_reg (struct net2280_regs *regs, u32 index, u32 value)
+{
+	writel (index, &regs->idxaddr);
+	writel (value, &regs->idxdata);
+	/* posted, may not be visible yet */
+}
+
+#endif	/* __KERNEL__ */
+
+
+#define REG_DIAG		0x0
+#define     RETRY_COUNTER                                       16
+#define     FORCE_PCI_SERR                                      11
+#define     FORCE_PCI_INTERRUPT                                 10
+#define     FORCE_USB_INTERRUPT                                 9
+#define     FORCE_CPU_INTERRUPT                                 8
+#define     ILLEGAL_BYTE_ENABLES                                5
+#define     FAST_TIMES                                          4
+#define     FORCE_RECEIVE_ERROR                                 2
+#define     FORCE_TRANSMIT_CRC_ERROR                            0
+#define REG_FRAME		0x02	/* from last sof */
+#define REG_CHIPREV		0x03	/* in bcd */
+#define	REG_HS_NAK_RATE		0x0a	/* NAK per N uframes */
+
+#define	CHIPREV_1	0x0100
+#define	CHIPREV_1A	0x0110
+
+#ifdef	__KERNEL__
+
+/* ep a-f highspeed and fullspeed maxpacket, addresses
+ * computed from ep->num
+ */
+#define REG_EP_MAXPKT(dev,num) (((num) + 1) * 0x10 + \
+		(((dev)->gadget.speed == USB_SPEED_HIGH) ? 0 : 1))
+
+/*-------------------------------------------------------------------------*/
+
+/* [8.3] for scatter/gather i/o
+ * use struct net2280_dma_regs bitfields
+ */
+struct net2280_dma {
+	u32		dmacount;
+	u32		dmaaddr;		/* the buffer */
+	u32		dmadesc;		/* next dma descriptor */
+	u32		_reserved;
+} __attribute__ ((aligned (16)));
+
+/*-------------------------------------------------------------------------*/
+
+/* DRIVER DATA STRUCTURES and UTILITIES */
+
+struct net2280_ep {
+	struct usb_ep				ep;
+	struct net2280_ep_regs			*regs;
+	struct net2280_dma_regs			*dma;
+	struct net2280_dma			*dummy;
+	dma_addr_t				td_dma;	/* of dummy */
+	struct net2280				*dev;
+	unsigned long				irqs;
+
+	/* analogous to a host-side qh */
+	struct list_head			queue;
+	const struct usb_endpoint_descriptor	*desc;
+	unsigned				num : 8,
+						fifo_size : 12,
+						in_fifo_validate : 1,
+						stopped : 1,
+						is_in : 1,
+						is_iso : 1;
+};
+
+static inline void allow_status (struct net2280_ep *ep)
+{
+	/* ep0 only */
+	writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
+		| (1 << CLEAR_NAK_OUT_PACKETS_MODE)
+		, &ep->regs->ep_rsp);
+	ep->stopped = 1;
+}
+
+/* count (<= 4) bytes in the next fifo write will be valid */
+static inline void set_fifo_bytecount (struct net2280_ep *ep, unsigned count)
+{
+	writeb (count, 2 + (u8 *) &ep->regs->ep_cfg);
+}
+
+struct net2280_request {
+	struct usb_request		req;
+	struct net2280_dma		*td;
+	dma_addr_t			td_dma;
+	struct list_head		queue;
+	unsigned			mapped : 1,
+					dma_done : 1,
+					valid : 1;
+};
+
+struct net2280 {
+	/* each pci device provides one gadget, several endpoints */
+	struct usb_gadget		gadget;
+	spinlock_t			lock;
+	struct net2280_ep		ep [7];
+	struct usb_gadget_driver 	*driver;
+	unsigned			enabled : 1,
+					protocol_stall : 1,
+					got_irq : 1,
+					region : 1,
+					selfpowered : 1;
+	u16				chiprev;
+
+	/* pci state used to access those endpoints */
+	struct pci_dev			*pdev;
+	struct net2280_regs		*regs;
+	struct net2280_usb_regs		*usb;
+	struct net2280_pci_regs		*pci;
+	struct net2280_dma_regs		*dma;
+	struct net2280_dep_regs		*dep;
+	struct net2280_ep_regs		*epregs;
+
+	struct pci_pool			*requests;
+	// statistics...
+};
+
+static inline void set_halt (struct net2280_ep *ep)
+{
+	/* ep0 and bulk/intr endpoints */
+	writel (  (1 << CLEAR_CONTROL_STATUS_PHASE_HANDSHAKE)
+		    /* set NAK_OUT for erratum 0114 */
+		| ((ep->dev->chiprev == CHIPREV_1) << SET_NAK_OUT_PACKETS)
+		| (1 << SET_ENDPOINT_HALT)
+		, &ep->regs->ep_rsp);
+}
+
+static inline void clear_halt (struct net2280_ep *ep)
+{
+	/* ep0 and bulk/intr endpoints */
+	writel (  (1 << CLEAR_ENDPOINT_HALT)
+		| (1 << CLEAR_ENDPOINT_TOGGLE)
+		    /* unless the gadget driver left a short packet in the
+		     * fifo, this reverses the erratum 0114 workaround.
+		     */
+		| ((ep->dev->chiprev == CHIPREV_1) << CLEAR_NAK_OUT_PACKETS)
+		, &ep->regs->ep_rsp);
+}
+
+#ifdef USE_RDK_LEDS
+
+static inline void net2280_led_init (struct net2280 *dev)
+{
+	/* LED3 (green) is on during USB activity. note erratum 0113. */
+	writel ((1 << GPIO3_LED_SELECT)
+		| (1 << GPIO3_OUTPUT_ENABLE)
+		| (1 << GPIO2_OUTPUT_ENABLE)
+		| (1 << GPIO1_OUTPUT_ENABLE)
+		| (1 << GPIO0_OUTPUT_ENABLE)
+		, &dev->regs->gpioctl);
+}
+
+/* indicate speed with bi-color LED 0/1 */
+static inline
+void net2280_led_speed (struct net2280 *dev, enum usb_device_speed speed)
+{
+	u32	val = readl (&dev->regs->gpioctl);
+	switch (speed) {
+	case USB_SPEED_HIGH:		/* green */
+		val &= ~(1 << GPIO0_DATA);
+		val |= (1 << GPIO1_DATA);
+		break;
+	case USB_SPEED_FULL:		/* red */
+		val &= ~(1 << GPIO1_DATA);
+		val |= (1 << GPIO0_DATA);
+		break;
+	default:			/* (off/black) */
+		val &= ~((1 << GPIO1_DATA) | (1 << GPIO0_DATA));
+		break;
+	}
+	writel (val, &dev->regs->gpioctl);
+}
+
+/* indicate power with LED 2 */
+static inline void net2280_led_active (struct net2280 *dev, int is_active)
+{
+	u32	val = readl (&dev->regs->gpioctl);
+
+	// FIXME this LED never seems to turn on.
+	if (is_active)
+		val |= GPIO2_DATA;
+	else
+		val &= ~GPIO2_DATA;
+	writel (val, &dev->regs->gpioctl);
+}
+static inline void net2280_led_shutdown (struct net2280 *dev)
+{
+	/* turn off all four GPIO*_DATA bits */
+	writel (readl (&dev->regs->gpioctl) & ~0x0f,
+			&dev->regs->gpioctl);
+}
+
+#else
+
+#define net2280_led_init(dev)		do { } while (0)
+#define net2280_led_speed(dev, speed)	do { } while (0)
+#define net2280_led_shutdown(dev)	do { } while (0)
+
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#define xprintk(dev,level,fmt,args...) \
+	printk(level "%s %s: " fmt , driver_name , \
+			dev->pdev->slot_name , ## args)
+
+#ifdef DEBUG
+#undef DEBUG
+#define DEBUG(dev,fmt,args...) \
+	xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DEBUG(dev,fmt,args...) \
+	do { } while (0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDEBUG DEBUG
+#else
+#define VDEBUG(dev,fmt,args...) \
+	do { } while (0)
+#endif	/* VERBOSE */
+
+#define ERROR(dev,fmt,args...) \
+	xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+	xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+	xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-------------------------------------------------------------------------*/
+
+static inline void start_out_naking (struct net2280_ep *ep)
+{
+	/* NOTE:  hardware races lurk here, and PING protocol issues */
+	writel ((1 << SET_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+	/* synch with device */
+	readl (&ep->regs->ep_rsp);
+}
+
+#ifdef DEBUG
+static inline void assert_out_naking (struct net2280_ep *ep, const char *where)
+{
+	u32	tmp = readl (&ep->regs->ep_stat);
+
+	if ((tmp & (1 << NAK_OUT_PACKETS)) == 0) {
+		DEBUG (ep->dev, "%s %s %08x !NAK\n",
+				ep->ep.name, where, tmp);
+		writel ((1 << SET_NAK_OUT_PACKETS),
+			&ep->regs->ep_rsp);
+	}
+}
+#define ASSERT_OUT_NAKING(ep) assert_out_naking(ep,__FUNCTION__)
+#else
+#define ASSERT_OUT_NAKING(ep) do {} while (0)
+#endif
+
+static inline void stop_out_naking (struct net2280_ep *ep)
+{
+	u32	tmp;
+
+	tmp = readl (&ep->regs->ep_stat);
+	if ((tmp & (1 << NAK_OUT_PACKETS)) != 0)
+		writel ((1 << CLEAR_NAK_OUT_PACKETS), &ep->regs->ep_rsp);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* 2.5 and 2.4.older portability changes ... */
+
+#ifndef container_of
+#define	container_of	list_entry
+#endif
+
+#ifndef likely
+#define likely(x) (x)
+#define unlikely(x) (x)
+#endif
+
+#ifndef BUG_ON
+#define BUG_ON(condition) do { if (unlikely((condition)!=0)) BUG(); } while(0)
+#endif
+
+#ifndef WARN_ON
+#define	WARN_ON(x)	do { } while (0)
+#endif
+
+#ifndef	IRQ_NONE
+typedef void irqreturn_t;
+#define IRQ_NONE
+#define IRQ_HANDLED
+#define IRQ_RETVAL(x)
+#endif
+
+#endif	/* __KERNEL__ */
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/usbstring.c linux-2.4.23-pre7/drivers/usb/gadget/usbstring.c
--- linux-2.4.23-pre6/drivers/usb/gadget/usbstring.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/usbstring.c	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2003 David Brownell
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/string.h>
+#include <linux/version.h>
+
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+
+
+/**
+ * usb_gadget_get_string - fill out a string descriptor 
+ * @table: of c strings using iso latin/1 characters
+ * @id: string id, from low byte of wValue in get string descriptor
+ * @buf: at least 256 bytes
+ *
+ * Finds the iso latin/1 string matching the ID, and converts it into a
+ * string descriptor in utf16-le.
+ * Returns length of descriptor (always even) or negative errno
+ *
+ * If your driver needs stings in multiple languages, you'll need to
+ * to use some alternate solution for languages where the ISO 8859/1
+ * (latin/1) character set can't be used.  For example, they can't be
+ * used with Chinese (Big5, GB2312, etc), Japanese, Korean, or many other
+ * languages.  You'd likely "switch (wIndex) { ... }"  in your ep0
+ * string descriptor logic, using this routine in cases where "western
+ * european" characters suffice for the strings being returned.
+ */
+int
+usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf)
+{
+	struct usb_string	*s;
+	int			len;
+
+	/* descriptor 0 has the language id */
+	if (id == 0) {
+		buf [0] = 4;
+		buf [1] = USB_DT_STRING;
+		buf [2] = (u8) table->language;
+		buf [3] = (u8) (table->language >> 8);
+		return 4;
+	}
+	for (s = table->strings; s && s->s; s++)
+		if (s->id == id)
+			break;
+
+	/* unrecognized: stall. */
+	if (!s || !s->s)
+		return -EINVAL;
+
+	/* string descriptors have length, tag, then UTF16-LE text */
+	len = min ((size_t) 126, strlen (s->s));
+	buf [0] = (len + 1) * 2;
+	buf [1] = USB_DT_STRING;
+	memset (buf + 2, 0, 2 * len);	/* zero all the high bytes */
+	while (len) {
+		buf [2 * len] = s->s [len - 1];
+		len--;
+	}
+	return buf [0];
+}
+
diff -urN linux-2.4.23-pre6/drivers/usb/gadget/zero.c linux-2.4.23-pre7/drivers/usb/gadget/zero.c
--- linux-2.4.23-pre6/drivers/usb/gadget/zero.c	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/gadget/zero.c	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,1261 @@
+/*
+ * zero.c -- Gadget Zero, for USB development
+ *
+ * Copyright (C) 2003 David Brownell
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions, and the following disclaimer,
+ *    without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The names of the above-listed copyright holders may not be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * ALTERNATIVELY, this software may be distributed under the terms of the
+ * GNU General Public License ("GPL") as published by the Free Software
+ * Foundation, either version 2 of that License or (at your option) any
+ * later version.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+/*
+ * Gadget Zero only needs two bulk endpoints, and is an example of how you
+ * can write a hardware-agnostic gadget driver running inside a USB device.
+ *
+ * Hardware details are visible (see CONFIG_USB_ZERO_* below) but don't
+ * affect most of the driver.
+ *
+ * Use it with the Linux host/master side "usbtest" driver to get a basic
+ * functional test of your device-side usb stack, or with "usb-skeleton".
+ *
+ * It supports two similar configurations.  One sinks whatever the usb host
+ * writes, and in return sources zeroes.  The other loops whatever the host
+ * writes back, so the host can read it.  Module options include:
+ *
+ *   buflen=N		default N=4096, buffer size used
+ *   qlen=N		default N=32, how many buffers in the loopback queue
+ *   loopdefault	default false, list loopback config first
+ *
+ * Many drivers will only have one configuration, letting them be much
+ * simpler if they also don't support high speed operation (like this
+ * driver does).
+ */
+
+#define DEBUG 1
+// #define VERBOSE
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/sched.h>
+#include <linux/slab.h>
+#include <linux/smp_lock.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/timer.h>
+#include <linux/list.h>
+#include <linux/interrupt.h>
+#include <linux/uts.h>
+#include <linux/version.h>
+
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/system.h>
+#include <asm/unaligned.h>
+
+#include <linux/usb_ch9.h>
+#include <linux/usb_gadget.h>
+
+
+/*-------------------------------------------------------------------------*/
+
+#define DRIVER_VERSION		"Bastille Day 2003"
+
+static const char shortname [] = "zero";
+static const char longname [] = "Gadget Zero";
+
+static const char source_sink [] = "source and sink data";
+static const char loopback [] = "loop input to output";
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * hardware-specific configuration, controlled by which device
+ * controller driver was configured.
+ *
+ * CHIP ... hardware identifier
+ * DRIVER_VERSION_NUM ... alerts the host side driver to differences
+ * EP0_MAXPACKET ... controls packetization of control requests
+ * EP_*_NAME ... which endpoints do we use for which purpose?
+ * EP_*_NUM ... numbers for them (often limited by hardware)
+ * HIGHSPEED ... define if ep0 and descriptors need high speed support
+ * MAX_USB_POWER ... define if we use other than 100 mA bus current
+ * SELFPOWER ... unless we can run on bus power, USB_CONFIG_ATT_SELFPOWER
+ * WAKEUP ... if hardware supports remote wakeup AND we will issue the
+ * 	usb_gadget_wakeup() call to initiate it, USB_CONFIG_ATT_WAKEUP
+ *
+ * hw_optimize(gadget) ... for any hardware tweaks we want to kick in
+ * 	before we enable our endpoints
+ *
+ * add other defines for other portability issues, like hardware that
+ * for some reason doesn't handle full speed bulk maxpacket of 64.
+ */
+
+/*
+ * DRIVER_VERSION_NUM 0x0000 (?):  Martin Diehl's ezusb an21/fx code
+ */
+
+/*
+ * NetChip 2280, PCI based.
+ *
+ * This has half a dozen configurable endpoints, four with dedicated
+ * DMA channels to manage their FIFOs.  It supports high speed.
+ * Those endpoints can be arranged in any desired configuration.
+ */
+#ifdef	CONFIG_USB_ZERO_NET2280
+#define CHIP			"net2280"
+#define DRIVER_VERSION_NUM	0x0111
+#define EP0_MAXPACKET		64
+static const char EP_OUT_NAME [] = "ep-a";
+#define EP_OUT_NUM	2
+static const char EP_IN_NAME [] = "ep-b";
+#define EP_IN_NUM	2
+#define HIGHSPEED
+/* specific hardware configs could be bus-powered */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* supports remote wakeup, but this driver doesn't */
+
+extern int net2280_set_fifo_mode (struct usb_gadget *gadget, int mode);
+
+static inline void hw_optimize (struct usb_gadget *gadget)
+{
+	/* we can have bigger ep-a/ep-b fifos (2KB each, 4 packets
+	 * for highspeed bulk) because we're not using ep-c/ep-d.
+	 */
+	net2280_set_fifo_mode (gadget, 1);
+}
+#endif
+
+/*
+ * PXA-2xx UDC:  widely used in second gen Linux-capable PDAs.
+ *
+ * This has fifteen fixed-function full speed endpoints, and it
+ * can support all USB transfer types.
+ *
+ * These supports three or four configurations, with fixed numbers.
+ * The hardware interprets SET_INTERFACE, net effect is that you
+ * can't use altsettings or reset the interfaces independently.
+ * So stick to a single interface.
+ */
+#ifdef	CONFIG_USB_ZERO_PXA2XX
+#define CHIP			"pxa2xx"
+#define DRIVER_VERSION_NUM	0x0113
+#define EP0_MAXPACKET		16
+static const char EP_OUT_NAME [] = "ep12out-bulk";
+#define EP_OUT_NUM	12
+static const char EP_IN_NAME [] = "ep11in-bulk";
+#define EP_IN_NUM	11
+/* doesn't support bus-powered operation */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* supports remote wakeup, but this driver doesn't */
+
+/* no hw optimizations to apply */
+#define hw_optimize(g) do {} while (0);
+#endif
+
+/*
+ * SA-1100 UDC:  widely used in first gen Linux-capable PDAs.
+ *
+ * This has only two fixed function endpoints, which can only
+ * be used for bulk (or interrupt) transfers.  (Plus control.)
+ *
+ * Since it can't flush its TX fifos without disabling the UDC,
+ * the current configuration or altsettings can't change except
+ * in special situations.  So this is a case of "choose it right
+ * during enumeration" ...
+ */
+#ifdef	CONFIG_USB_ZERO_SA1100
+#define CHIP			"sa1100"
+#define DRIVER_VERSION_NUM	0x0115
+#define EP0_MAXPACKET		8
+static const char EP_OUT_NAME [] = "ep1out-bulk";
+#define EP_OUT_NUM	1
+static const char EP_IN_NAME [] = "ep2in-bulk";
+#define EP_IN_NUM	2
+/* doesn't support bus-powered operation */
+#define SELFPOWER USB_CONFIG_ATT_SELFPOWER
+/* doesn't support remote wakeup? */
+
+/* no hw optimizations to apply */
+#define hw_optimize(g) do {} while (0);
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+#ifndef EP0_MAXPACKET
+#	error Configure some USB peripheral controller driver!
+#endif
+
+/* power usage is config specific.
+ * hardware that supports remote wakeup defaults to disabling it.
+ */
+
+#ifndef	SELFPOWER
+/* default: say we rely on bus power */
+#define SELFPOWER	0
+/* else:
+ * - SELFPOWER value must be USB_CONFIG_ATT_SELFPOWER
+ * - MAX_USB_POWER may be nonzero.
+ */
+#endif
+
+#ifndef	MAX_USB_POWER
+/* any hub supports this steady state bus power consumption */
+#define MAX_USB_POWER	100	/* mA */
+#endif
+
+#ifndef	WAKEUP
+/* default: this driver won't do remote wakeup */
+#define WAKEUP		0
+/* else value must be USB_CONFIG_ATT_WAKEUP */
+#endif
+
+/*-------------------------------------------------------------------------*/
+
+/* big enough to hold our biggest descriptor */
+#define USB_BUFSIZ	256
+
+struct zero_dev {
+	spinlock_t		lock;
+	struct usb_gadget	*gadget;
+	struct usb_request	*req;		/* for control responses */
+
+	/* when configured, we have one of two configs:
+	 * - source data (in to host) and sink it (out from host)
+	 * - or loop it back (out from host back in to host)
+	 */
+	u8			config;
+	struct usb_ep		*in_ep, *out_ep;
+};
+
+#define xprintk(d,level,fmt,args...) \
+	printk(level "%s %s: " fmt , shortname , (d)->gadget->dev.bus_id , \
+		## args)
+
+#ifdef DEBUG
+#undef DEBUG
+#define DEBUG(dev,fmt,args...) \
+	xprintk(dev , KERN_DEBUG , fmt , ## args)
+#else
+#define DEBUG(dev,fmt,args...) \
+	do { } while (0)
+#endif /* DEBUG */
+
+#ifdef VERBOSE
+#define VDEBUG	DEBUG
+#else
+#define VDEBUG(dev,fmt,args...) \
+	do { } while (0)
+#endif /* DEBUG */
+
+#define ERROR(dev,fmt,args...) \
+	xprintk(dev , KERN_ERR , fmt , ## args)
+#define WARN(dev,fmt,args...) \
+	xprintk(dev , KERN_WARNING , fmt , ## args)
+#define INFO(dev,fmt,args...) \
+	xprintk(dev , KERN_INFO , fmt , ## args)
+
+/*-------------------------------------------------------------------------*/
+
+static unsigned buflen = 4096;
+static unsigned qlen = 32;
+static unsigned pattern = 0;
+
+/*
+ * Normally the "loopback" configuration is second (index 1) so
+ * it's not the default.  Here's where to change that order, to
+ * work better with hosts (like Linux ... for now!) where config
+ * changes are problematic.
+ */
+static int loopdefault = 0;
+
+
+MODULE_PARM (buflen, "i");
+MODULE_PARM_DESC (buflen, "size of i/o buffers");
+
+MODULE_PARM (qlen, "i");
+MODULE_PARM_DESC (qlen, "depth of loopback buffering");
+
+MODULE_PARM (pattern, "i");
+MODULE_PARM_DESC (pattern, "0 for default all-zeroes, 1 for mod63");
+
+MODULE_PARM (loopdefault, "b");
+MODULE_PARM_DESC (loopdefault, "true to have default config be loopback");
+
+/*-------------------------------------------------------------------------*/
+
+/* Thanks to NetChip Technologies for donating this product ID.
+ *
+ * DO NOT REUSE THESE IDs with any other driver!!  Ever!!
+ * Instead:  allocate your own, using normal USB-IF procedures.
+ */
+#define DRIVER_VENDOR_NUM	0x0525		/* NetChip */
+#define DRIVER_PRODUCT_NUM	0xa4a0		/* Linux-USB "Gadget Zero" */
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * DESCRIPTORS ... most are static, but strings and (full)
+ * configuration descriptors are built on demand.
+ */
+
+#define STRING_MANUFACTURER		25
+#define STRING_PRODUCT			42
+#define STRING_SERIAL			101
+#define STRING_SOURCE_SINK		250
+#define STRING_LOOPBACK			251
+
+/*
+ * This device advertises two configurations; these numbers work
+ * on a pxa250 as well as more flexible hardware.
+ */
+#define	CONFIG_SOURCE_SINK	3
+#define	CONFIG_LOOPBACK		2
+
+static const struct usb_device_descriptor
+device_desc = {
+	.bLength =		sizeof device_desc,
+	.bDescriptorType =	USB_DT_DEVICE,
+
+	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
+	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
+	.bMaxPacketSize0 =	EP0_MAXPACKET,
+
+	.idVendor =		__constant_cpu_to_le16 (DRIVER_VENDOR_NUM),
+	.idProduct =		__constant_cpu_to_le16 (DRIVER_PRODUCT_NUM),
+	.bcdDevice =		__constant_cpu_to_le16 (DRIVER_VERSION_NUM),
+	.iManufacturer =	STRING_MANUFACTURER,
+	.iProduct =		STRING_PRODUCT,
+	.iSerialNumber =	STRING_SERIAL,
+	.bNumConfigurations =	2,
+};
+
+static const struct usb_config_descriptor
+source_sink_config = {
+	.bLength =		sizeof source_sink_config,
+	.bDescriptorType =	USB_DT_CONFIG,
+
+	/* compute wTotalLength on the fly */
+	.bNumInterfaces =	1,
+	.bConfigurationValue =	CONFIG_SOURCE_SINK,
+	.iConfiguration =	STRING_SOURCE_SINK,
+	.bmAttributes =		USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP,
+	.bMaxPower =		(MAX_USB_POWER + 1) / 2,
+};
+
+static const struct usb_config_descriptor
+loopback_config = {
+	.bLength =		sizeof loopback_config,
+	.bDescriptorType =	USB_DT_CONFIG,
+
+	/* compute wTotalLength on the fly */
+	.bNumInterfaces =	1,
+	.bConfigurationValue =	CONFIG_LOOPBACK,
+	.iConfiguration =	STRING_LOOPBACK,
+	.bmAttributes =		USB_CONFIG_ATT_ONE | SELFPOWER | WAKEUP,
+	.bMaxPower =		(MAX_USB_POWER + 1) / 2,
+};
+
+/* one interface in each configuration */
+
+static const struct usb_interface_descriptor
+source_sink_intf = {
+	.bLength =		sizeof source_sink_intf,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bNumEndpoints =	2,
+	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
+	.iInterface =		STRING_SOURCE_SINK,
+};
+
+static const struct usb_interface_descriptor
+loopback_intf = {
+	.bLength =		sizeof loopback_intf,
+	.bDescriptorType =	USB_DT_INTERFACE,
+
+	.bNumEndpoints =	2,
+	.bInterfaceClass =	USB_CLASS_VENDOR_SPEC,
+	.iInterface =		STRING_LOOPBACK,
+};
+
+/* two full speed bulk endpoints; their use is config-dependent */
+
+static const struct usb_endpoint_descriptor
+fs_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (64),
+};
+
+static const struct usb_endpoint_descriptor
+fs_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_OUT_NUM,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (64),
+};
+
+#ifdef	HIGHSPEED
+
+/*
+ * usb 2.0 devices need to expose both high speed and full speed
+ * descriptors, unless they only run at full speed.
+ *
+ * that means alternate endpoint descriptors (bigger packets)
+ * and a "device qualifier" ... plus more construction options
+ * for the config descriptor.
+ */
+
+static const struct usb_endpoint_descriptor
+hs_source_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_IN_NUM | USB_DIR_IN,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (512),
+};
+
+static const struct usb_endpoint_descriptor
+hs_sink_desc = {
+	.bLength =		USB_DT_ENDPOINT_SIZE,
+	.bDescriptorType =	USB_DT_ENDPOINT,
+
+	.bEndpointAddress =	EP_OUT_NUM,
+	.bmAttributes =		USB_ENDPOINT_XFER_BULK,
+	.wMaxPacketSize =	__constant_cpu_to_le16 (512),
+};
+
+static const struct usb_qualifier_descriptor
+dev_qualifier = {
+	.bLength =		sizeof dev_qualifier,
+	.bDescriptorType =	USB_DT_DEVICE_QUALIFIER,
+
+	.bcdUSB =		__constant_cpu_to_le16 (0x0200),
+	.bDeviceClass =		USB_CLASS_VENDOR_SPEC,
+
+	/* assumes ep0 uses the same value for both speeds ... */
+	.bMaxPacketSize0 =	EP0_MAXPACKET,
+
+	.bNumConfigurations =	2,
+};
+
+/* maxpacket and other transfer characteristics vary by speed. */
+#define ep_desc(g,hs,fs) (((g)->speed==USB_SPEED_HIGH)?(hs):(fs))
+
+#else
+
+/* if there's no high speed support, maxpacket doesn't change. */
+#define ep_desc(g,hs,fs) fs
+
+#endif	/* !HIGHSPEED */
+
+static char				serial [40];
+
+/* static strings, in iso 8859/1 */
+static struct usb_string		strings [] = {
+	{ STRING_MANUFACTURER, UTS_SYSNAME " " UTS_RELEASE " with " CHIP, },
+	{ STRING_PRODUCT, longname, },
+	{ STRING_SERIAL, serial, },
+	{ STRING_LOOPBACK, loopback, },
+	{ STRING_SOURCE_SINK, source_sink, },
+	{  }			/* end of list */
+};
+
+static struct usb_gadget_strings	stringtab = {
+	.language	= 0x0409,	/* en-us */
+	.strings	= strings,
+};
+
+/*
+ * config descriptors are also handcrafted.  these must agree with code
+ * that sets configurations, and with code managing interfaces and their
+ * altsettings.  other complexity may come from:
+ *
+ *  - high speed support, including "other speed config" rules
+ *  - multiple configurations
+ *  - interfaces with alternate settings
+ *  - embedded class or vendor-specific descriptors
+ *
+ * this handles high speed, and has a second config that could as easily
+ * have been an alternate interface setting (on most hardware).
+ *
+ * NOTE:  to demonstrate (and test) more USB capabilities, this driver
+ * should include an altsetting to test interrupt transfers, including
+ * high bandwidth modes at high speed.  (Maybe work like Intel's test
+ * device?)
+ */
+static int
+config_buf (enum usb_device_speed speed,
+		u8 *buf, u8 type, unsigned index)
+{
+	int		is_source_sink;
+	const unsigned	config_len = USB_DT_CONFIG_SIZE
+				+ USB_DT_INTERFACE_SIZE
+				+ 2 * USB_DT_ENDPOINT_SIZE;
+#ifdef HIGHSPEED
+	int		hs;
+#endif
+	/* two configurations will always be index 0 and index 1 */
+	if (index > 1)
+		return -EINVAL;
+	if (config_len > USB_BUFSIZ)
+		return -EDOM;
+	is_source_sink = loopdefault ? (index == 1) : (index == 0);
+
+	/* config (or other speed config) */
+	if (is_source_sink)
+		memcpy (buf, &source_sink_config, USB_DT_CONFIG_SIZE);
+	else
+		memcpy (buf, &loopback_config, USB_DT_CONFIG_SIZE);
+	buf [1] = type;
+	((struct usb_config_descriptor *) buf)->wTotalLength
+		= __constant_cpu_to_le16 (config_len);
+	buf += USB_DT_CONFIG_SIZE;
+
+	/* one interface */
+	if (is_source_sink)
+		memcpy (buf, &source_sink_intf, USB_DT_INTERFACE_SIZE);
+	else
+		memcpy (buf, &loopback_intf, USB_DT_INTERFACE_SIZE);
+	buf += USB_DT_INTERFACE_SIZE;
+
+	/* the endpoints in that interface (at that speed) */
+#ifdef HIGHSPEED
+	hs = (speed == USB_SPEED_HIGH);
+	if (type == USB_DT_OTHER_SPEED_CONFIG)
+		hs = !hs;
+	if (hs) {
+		memcpy (buf, &hs_source_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		memcpy (buf, &hs_sink_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+	} else
+#endif
+	{
+		memcpy (buf, &fs_source_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+		memcpy (buf, &fs_sink_desc, USB_DT_ENDPOINT_SIZE);
+		buf += USB_DT_ENDPOINT_SIZE;
+	}
+
+	return config_len;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_request *
+alloc_ep_req (struct usb_ep *ep, unsigned length)
+{
+	struct usb_request	*req;
+
+	req = usb_ep_alloc_request (ep, GFP_ATOMIC);
+	if (req) {
+		req->length = length;
+		req->buf = usb_ep_alloc_buffer (ep, length,
+				&req->dma, GFP_ATOMIC);
+		if (!req->buf) {
+			usb_ep_free_request (ep, req);
+			req = 0;
+		}
+	}
+	return req;
+}
+
+static void free_ep_req (struct usb_ep *ep, struct usb_request *req)
+{
+	if (req->buf)
+		usb_ep_free_buffer (ep, req->buf, req->dma, req->length);
+	usb_ep_free_request (ep, req);
+}
+
+/*-------------------------------------------------------------------------*/
+
+/* optionally require specific source/sink data patterns  */
+
+static inline int
+check_read_data (
+	struct zero_dev		*dev,
+	struct usb_ep		*ep,
+	struct usb_request	*req
+)
+{
+	unsigned	i;
+	u8		*buf = req->buf;
+
+	for (i = 0; i < req->actual; i++, buf++) {
+		switch (pattern) {
+		/* all-zeroes has no synchronization issues */
+		case 0:
+			if (*buf == 0)
+				continue;
+			break;
+		/* mod63 stays in sync with short-terminated transfers,
+		 * or otherwise when host and gadget agree on how large
+		 * each usb transfer request should be.  resync is done
+		 * with set_interface or set_config.
+		 */
+		case 1:
+			if (*buf == (u8)(i % 63))
+				continue;
+			break;
+		}
+		ERROR (dev, "bad OUT byte, buf [%d] = %d\n", i, *buf);
+		usb_ep_set_halt (ep);
+		return -EINVAL;
+	}
+	return 0;
+}
+
+static inline void
+reinit_write_data (
+	struct zero_dev		*dev,
+	struct usb_ep		*ep,
+	struct usb_request	*req
+)
+{
+	unsigned	i;
+	u8		*buf = req->buf;
+
+	switch (pattern) {
+	case 0:
+		memset (req->buf, 0, req->length);
+		break;
+	case 1:
+		for  (i = 0; i < req->length; i++)
+			*buf++ = (u8) (i % 63);
+		break;
+	}
+}
+
+/* if there is only one request in the queue, there'll always be an
+ * irq delay between end of one request and start of the next.
+ * that prevents using hardware dma queues.
+ */
+static void source_sink_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	struct zero_dev	*dev = ep->driver_data;
+	int		status = req->status;
+
+	switch (status) {
+
+	case 0: 			/* normal completion? */
+		if (ep == dev->out_ep)
+			check_read_data (dev, ep, req);
+		else
+			reinit_write_data (dev, ep, req);
+		break;
+
+	/* this endpoint is normally active while we're configured */
+	case -ECONNABORTED: 		/* hardware forced ep reset */
+	case -ECONNRESET:		/* request dequeued */
+	case -ESHUTDOWN:		/* disconnect from host */
+		VDEBUG (dev, "%s gone (%d), %d/%d\n", ep->name, status,
+				req->actual, req->length);
+		if (ep == dev->out_ep)
+			check_read_data (dev, ep, req);
+		free_ep_req (ep, req);
+		return;
+
+	case -EOVERFLOW:		/* buffer overrun on read means that
+					 * we didn't provide a big enough
+					 * buffer.
+					 */
+	default:
+#if 1
+		DEBUG (dev, "%s complete --> %d, %d/%d\n", ep->name,
+				status, req->actual, req->length);
+#endif
+	case -EREMOTEIO:		/* short read */
+		break;
+	}
+
+	status = usb_ep_queue (ep, req, GFP_ATOMIC);
+	if (status) {
+		ERROR (dev, "kill %s:  resubmit %d bytes --> %d\n",
+				ep->name, req->length, status);
+		usb_ep_set_halt (ep);
+		/* FIXME recover later ... somehow */
+	}
+}
+
+static struct usb_request *
+source_sink_start_ep (struct usb_ep *ep, int gfp_flags)
+{
+	struct usb_request	*req;
+	int			status;
+
+	req = alloc_ep_req (ep, buflen);
+	if (!req)
+		return 0;
+
+	memset (req->buf, 0, req->length);
+	req->complete = source_sink_complete;
+
+	if (strcmp (ep->name, EP_IN_NAME) == 0)
+		reinit_write_data (ep->driver_data, ep, req);
+
+	status = usb_ep_queue (ep, req, gfp_flags);
+	if (status) {
+		struct zero_dev	*dev = ep->driver_data;
+
+		ERROR (dev, "start %s --> %d\n", ep->name, status);
+		free_ep_req (ep, req);
+		req = 0;
+	}
+
+	return req;
+}
+
+static int
+set_source_sink_config (struct zero_dev *dev, int gfp_flags)
+{
+	int			result = 0;
+	struct usb_ep		*ep;
+	struct usb_gadget	*gadget = dev->gadget;
+
+	gadget_for_each_ep (ep, gadget) {
+		const struct usb_endpoint_descriptor	*d;
+
+		/* one endpoint writes (sources) zeroes in (to the host) */
+		if (strcmp (ep->name, EP_IN_NAME) == 0) {
+			d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				if (source_sink_start_ep (ep, gfp_flags) != 0) {
+					dev->in_ep = ep;
+					continue;
+				}
+				usb_ep_disable (ep);
+				result = -EIO;
+			}
+
+		/* one endpoint reads (sinks) anything out (from the host) */
+		} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
+			d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				if (source_sink_start_ep (ep, gfp_flags) != 0) {
+					dev->out_ep = ep;
+					continue;
+				}
+				usb_ep_disable (ep);
+				result = -EIO;
+			}
+
+		/* ignore any other endpoints */
+		} else
+			continue;
+
+		/* stop on error */
+		ERROR (dev, "can't start %s, result %d\n", ep->name, result);
+		break;
+	}
+	if (result == 0)
+		DEBUG (dev, "buflen %d\n", buflen);
+
+	/* caller is responsible for cleanup on error */
+	return result;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void loopback_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	struct zero_dev	*dev = ep->driver_data;
+	int		status = req->status;
+
+	switch (status) {
+
+	case 0: 			/* normal completion? */
+		if (ep == dev->out_ep) {
+			/* loop this OUT packet back IN to the host */
+			req->zero = (req->actual < req->length);
+			req->length = req->actual;
+			status = usb_ep_queue (dev->in_ep, req, GFP_ATOMIC);
+			if (status == 0)
+				return;
+
+			/* "should never get here" */
+			ERROR (dev, "can't loop %s to %s: %d\n",
+				ep->name, dev->in_ep->name,
+				status);
+		}
+
+		/* queue the buffer for some later OUT packet */
+		req->length = buflen;
+		status = usb_ep_queue (dev->out_ep, req, GFP_ATOMIC);
+		if (status == 0)
+			return;
+
+		/* "should never get here" */
+		/* FALLTHROUGH */
+
+	default:
+		ERROR (dev, "%s loop complete --> %d, %d/%d\n", ep->name,
+				status, req->actual, req->length);
+		/* FALLTHROUGH */
+
+	/* NOTE:  since this driver doesn't maintain an explicit record
+	 * of requests it submitted (just maintains qlen count), we
+	 * rely on the hardware driver to clean up on disconnect or
+	 * endpoint disable.
+	 */
+	case -ECONNABORTED: 		/* hardware forced ep reset */
+	case -ECONNRESET:		/* request dequeued */
+	case -ESHUTDOWN:		/* disconnect from host */
+		free_ep_req (ep, req);
+		return;
+	}
+}
+
+static int
+set_loopback_config (struct zero_dev *dev, int gfp_flags)
+{
+	int			result = 0;
+	struct usb_ep		*ep;
+	struct usb_gadget	*gadget = dev->gadget;
+
+	gadget_for_each_ep (ep, gadget) {
+		const struct usb_endpoint_descriptor	*d;
+
+		/* one endpoint writes data back IN to the host */
+		if (strcmp (ep->name, EP_IN_NAME) == 0) {
+			d = ep_desc (gadget, &hs_source_desc, &fs_source_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				dev->in_ep = ep;
+				continue;
+			}
+
+		/* one endpoint just reads OUT packets */
+		} else if (strcmp (ep->name, EP_OUT_NAME) == 0) {
+			d = ep_desc (gadget, &hs_sink_desc, &fs_sink_desc);
+			result = usb_ep_enable (ep, d);
+			if (result == 0) {
+				ep->driver_data = dev;
+				dev->out_ep = ep;
+				continue;
+			}
+
+		/* ignore any other endpoints */
+		} else
+			continue;
+
+		/* stop on error */
+		ERROR (dev, "can't enable %s, result %d\n", ep->name, result);
+		break;
+	}
+
+	/* allocate a bunch of read buffers and queue them all at once.
+	 * we buffer at most 'qlen' transfers; fewer if any need more
+	 * than 'buflen' bytes each.
+	 */
+	if (result == 0) {
+		struct usb_request	*req;
+		unsigned		i;
+
+		ep = dev->out_ep;
+		for (i = 0; i < qlen && result == 0; i++) {
+			req = alloc_ep_req (ep, buflen);
+			if (req) {
+				req->complete = loopback_complete;
+				result = usb_ep_queue (ep, req, GFP_ATOMIC);
+				if (result)
+					DEBUG (dev, "%s queue req --> %d\n",
+							ep->name, result);
+			} else
+				result = -ENOMEM;
+		}
+	}
+	if (result == 0)
+		DEBUG (dev, "qlen %d, buflen %d\n", qlen, buflen);
+
+	/* caller is responsible for cleanup on error */
+	return result;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void zero_reset_config (struct zero_dev *dev)
+{
+	if (dev->config == 0)
+		return;
+
+	DEBUG (dev, "reset config\n");
+
+	/* just disable endpoints, forcing completion of pending i/o.
+	 * all our completion handlers free their requests in this case.
+	 */
+	if (dev->in_ep) {
+		usb_ep_disable (dev->in_ep);
+		dev->in_ep = 0;
+	}
+	if (dev->out_ep) {
+		usb_ep_disable (dev->out_ep);
+		dev->out_ep = 0;
+	}
+	dev->config = 0;
+}
+
+/* change our operational config.  this code must agree with the code
+ * that returns config descriptors, and altsetting code.
+ *
+ * it's also responsible for power management interactions. some
+ * configurations might not work with our current power sources.
+ *
+ * note that some device controller hardware will constrain what this
+ * code can do, perhaps by disallowing more than one configuration or
+ * by limiting configuration choices (like the pxa2xx).
+ */
+static int
+zero_set_config (struct zero_dev *dev, unsigned number, int gfp_flags)
+{
+	int			result = 0;
+	struct usb_gadget	*gadget = dev->gadget;
+
+	if (number == dev->config)
+		return 0;
+
+#ifdef CONFIG_USB_ZERO_SA1100
+	if (dev->config) {
+		/* tx fifo is full, but we can't clear it...*/
+		INFO (dev, "can't change configurations\n");
+		return -ESPIPE;
+	}
+#endif
+	zero_reset_config (dev);
+	hw_optimize (gadget);
+
+	switch (number) {
+	case CONFIG_SOURCE_SINK:
+		result = set_source_sink_config (dev, gfp_flags);
+		break;
+	case CONFIG_LOOPBACK:
+		result = set_loopback_config (dev, gfp_flags);
+		break;
+	default:
+		result = -EINVAL;
+		/* FALL THROUGH */
+	case 0:
+		return result;
+	}
+
+	if (!result && (!dev->in_ep || !dev->out_ep))
+		result = -ENODEV;
+	if (result)
+		zero_reset_config (dev);
+	else {
+		char *speed;
+
+		switch (gadget->speed) {
+		case USB_SPEED_LOW:	speed = "low"; break;
+		case USB_SPEED_FULL:	speed = "full"; break;
+		case USB_SPEED_HIGH:	speed = "high"; break;
+		default: 		speed = "?"; break;
+		}
+
+		dev->config = number;
+		INFO (dev, "%s speed config #%d: %s\n", speed, number,
+				(number == CONFIG_SOURCE_SINK)
+					? source_sink : loopback);
+	}
+	return result;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void zero_setup_complete (struct usb_ep *ep, struct usb_request *req)
+{
+	if (req->status || req->actual != req->length)
+		DEBUG ((struct zero_dev *) ep->driver_data,
+				"setup complete --> %d, %d/%d\n",
+				req->status, req->actual, req->length);
+}
+
+/*
+ * The setup() callback implements all the ep0 functionality that's
+ * not handled lower down, in hardware or the hardware driver (like
+ * device and endpoint feature flags, and their status).  It's all
+ * housekeeping for the gadget function we're implementing.  Most of
+ * the work is in config-specific setup.
+ */
+static int
+zero_setup (struct usb_gadget *gadget, const struct usb_ctrlrequest *ctrl)
+{
+	struct zero_dev		*dev = get_gadget_data (gadget);
+	struct usb_request	*req = dev->req;
+	int			value = -EOPNOTSUPP;
+
+	/* usually this stores reply data in the pre-allocated ep0 buffer,
+	 * but config change events will reconfigure hardware.
+	 */
+	switch (ctrl->bRequest) {
+
+	case USB_REQ_GET_DESCRIPTOR:
+		if (ctrl->bRequestType != USB_DIR_IN)
+			break;
+		switch (ctrl->wValue >> 8) {
+
+		case USB_DT_DEVICE:
+			value = min (ctrl->wLength, (u16) sizeof device_desc);
+			memcpy (req->buf, &device_desc, value);
+			break;
+#ifdef HIGHSPEED
+		case USB_DT_DEVICE_QUALIFIER:
+			value = min (ctrl->wLength, (u16) sizeof dev_qualifier);
+			memcpy (req->buf, &dev_qualifier, value);
+			break;
+
+		case USB_DT_OTHER_SPEED_CONFIG:
+			// FALLTHROUGH
+#endif /* HIGHSPEED */
+		case USB_DT_CONFIG:
+			value = config_buf (gadget->speed, req->buf,
+					ctrl->wValue >> 8,
+					ctrl->wValue & 0xff);
+			if (value >= 0)
+				value = min (ctrl->wLength, (u16) value);
+			break;
+
+		case USB_DT_STRING:
+			/* wIndex == language code.
+			 * this driver only handles one language, you can
+			 * add others even if they don't use iso8859/1
+			 */
+			value = usb_gadget_get_string (&stringtab,
+					ctrl->wValue & 0xff, req->buf);
+			if (value >= 0)
+				value = min (ctrl->wLength, (u16) value);
+			break;
+		}
+		break;
+
+	/* currently two configs, two speeds */
+	case USB_REQ_SET_CONFIGURATION:
+		if (ctrl->bRequestType != 0)
+			break;
+		spin_lock (&dev->lock);
+		value = zero_set_config (dev, ctrl->wValue, GFP_ATOMIC);
+		spin_unlock (&dev->lock);
+		break;
+	case USB_REQ_GET_CONFIGURATION:
+		if (ctrl->bRequestType != USB_DIR_IN)
+			break;
+		*(u8 *)req->buf = dev->config;
+		value = min (ctrl->wLength, (u16) 1);
+		break;
+
+	/* until we add altsetting support, or other interfaces,
+	 * only 0/0 are possible.  pxa2xx only supports 0/0 (poorly)
+	 * and already killed pending endpoint I/O.
+	 */
+	case USB_REQ_SET_INTERFACE:
+		if (ctrl->bRequestType != USB_RECIP_INTERFACE)
+			break;
+		spin_lock (&dev->lock);
+		if (dev->config && ctrl->wIndex == 0 && ctrl->wValue == 0) {
+			u8		config = dev->config;
+
+			/* resets interface configuration, forgets about
+			 * previous transaction state (queued bufs, etc)
+			 * and re-inits endpoint state (toggle etc)
+			 * no response queued, just zero status == success.
+			 * if we had more than one interface we couldn't
+			 * use this "reset the config" shortcut.
+			 */
+			zero_reset_config (dev);
+			zero_set_config (dev, config, GFP_ATOMIC);
+			value = 0;
+		}
+		spin_unlock (&dev->lock);
+		break;
+	case USB_REQ_GET_INTERFACE:
+		if (ctrl->bRequestType != (USB_DIR_IN|USB_RECIP_INTERFACE))
+			break;
+		if (!dev->config)
+			break;
+		if (ctrl->wIndex != 0) {
+			value = -EDOM;
+			break;
+		}
+		*(u8 *)req->buf = 0;
+		value = min (ctrl->wLength, (u16) 1);
+		break;
+
+	default:
+		VDEBUG (dev,
+			"unknown control req%02x.%02x v%04x i%04x l%d\n",
+			ctrl->bRequestType, ctrl->bRequest,
+			ctrl->wValue, ctrl->wIndex, ctrl->wLength);
+	}
+
+	/* respond with data transfer before status phase? */
+	if (value >= 0) {
+		req->length = value;
+		value = usb_ep_queue (gadget->ep0, req, GFP_ATOMIC);
+		if (value < 0) {
+			DEBUG (dev, "ep_queue --> %d\n", value);
+			req->status = 0;
+			zero_setup_complete (gadget->ep0, req);
+		}
+	}
+
+	/* device either stalls (value < 0) or reports success */
+	return value;
+}
+
+static void
+zero_disconnect (struct usb_gadget *gadget)
+{
+	struct zero_dev		*dev = get_gadget_data (gadget);
+	unsigned long		flags;
+
+	spin_lock_irqsave (&dev->lock, flags);
+	zero_reset_config (dev);
+
+	/* a more significant application might have some non-usb
+	 * activities to quiesce here, saving resources like power
+	 * or pushing the notification up a network stack.
+	 */
+	spin_unlock_irqrestore (&dev->lock, flags);
+
+	/* next we may get setup() calls to enumerate new connections;
+	 * or an unbind() during shutdown (including removing module).
+	 */
+}
+
+/*-------------------------------------------------------------------------*/
+
+static void
+zero_unbind (struct usb_gadget *gadget)
+{
+	struct zero_dev		*dev = get_gadget_data (gadget);
+
+	DEBUG (dev, "unbind\n");
+
+	/* we've already been disconnected ... no i/o is active */
+	if (dev->req)
+		free_ep_req (gadget->ep0, dev->req);
+	kfree (dev);
+	set_gadget_data (gadget, 0);
+}
+
+static int
+zero_bind (struct usb_gadget *gadget)
+{
+	struct zero_dev		*dev;
+
+	dev = kmalloc (sizeof *dev, SLAB_KERNEL);
+	if (!dev)
+		return -ENOMEM;
+	memset (dev, 0, sizeof *dev);
+	spin_lock_init (&dev->lock);
+	dev->gadget = gadget;
+	set_gadget_data (gadget, dev);
+
+	/* preallocate control response and buffer */
+	dev->req = usb_ep_alloc_request (gadget->ep0, GFP_KERNEL);
+	if (!dev->req)
+		goto enomem;
+	dev->req->buf = usb_ep_alloc_buffer (gadget->ep0, USB_BUFSIZ,
+				&dev->req->dma, GFP_KERNEL);
+	if (!dev->req->buf)
+		goto enomem;
+
+	dev->req->complete = zero_setup_complete;
+
+	gadget->ep0->driver_data = dev;
+
+	INFO (dev, "%s, version: " DRIVER_VERSION "\n", longname);
+	return 0;
+
+enomem:
+	zero_unbind (gadget);
+	return -ENOMEM;
+}
+
+/*-------------------------------------------------------------------------*/
+
+static struct usb_gadget_driver zero_driver = {
+#ifdef HIGHSPEED
+	.speed		= USB_SPEED_HIGH,
+#else
+	.speed		= USB_SPEED_FULL,
+#endif
+	.function	= (char *) longname,
+	.bind		= zero_bind,
+	.unbind		= zero_unbind,
+
+	.setup		= zero_setup,
+	.disconnect	= zero_disconnect,
+
+	.driver 	= {
+		.name		= (char *) shortname,
+		// .shutdown = ...
+		// .suspend = ...
+		// .resume = ...
+	},
+};
+
+MODULE_AUTHOR ("David Brownell");
+MODULE_LICENSE ("Dual BSD/GPL");
+
+
+static int __init init (void)
+{
+	/* a real value would likely come through some id prom
+	 * or module option.  this one takes at least two packets.
+	 */
+	strncpy (serial, "0123456789.0123456789.0123456789", sizeof serial);
+	serial [sizeof serial - 1] = 0;
+
+	return usb_gadget_register_driver (&zero_driver);
+}
+module_init (init);
+
+static void __exit cleanup (void)
+{
+	usb_gadget_unregister_driver (&zero_driver);
+}
+module_exit (cleanup);
+
diff -urN linux-2.4.23-pre6/drivers/usb/mdc800.c linux-2.4.23-pre7/drivers/usb/mdc800.c
--- linux-2.4.23-pre6/drivers/usb/mdc800.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/mdc800.c	2003-10-09 17:48:22.000000000 -0700
@@ -726,8 +726,10 @@
 		else
 		{
 			/* memcpy Bytes */
-			if (copy_to_user(ptr, &mdc800->out [mdc800->out_ptr], sts))
+			if (copy_to_user(ptr, &mdc800->out [mdc800->out_ptr], sts)) {
+				up (&mdc800->io_lock);
 				return -EFAULT;
+			}
 			ptr+=sts;
 			left-=sts;
 			mdc800->out_ptr+=sts;
diff -urN linux-2.4.23-pre6/drivers/usb/serial/ftdi_sio.c linux-2.4.23-pre7/drivers/usb/serial/ftdi_sio.c
--- linux-2.4.23-pre6/drivers/usb/serial/ftdi_sio.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/ftdi_sio.c	2003-10-09 17:48:22.000000000 -0700
@@ -17,6 +17,11 @@
  * See http://ftdi-usb-sio.sourceforge.net for upto date testing info
  *	and extra documentation
  *
+ * (21/Sep/2003) Ian Abbott
+ *      Added VID/PID for Omnidirectional Control Technology US101 USB to
+ *      RS-232 adapter (also rebadged as Dick Smith Electronics XH6381).
+ *      VID/PID supplied by Donald Gordon.
+ *
  * (19/Aug/2003) Ian Abbott
  *      Omitted some paranoid checks in write bulk callback that don't matter.
  *
@@ -325,6 +330,7 @@
 	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0, 0x3ff) },
 	{ USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0, 0x3ff) },
+	{ USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0, 0x3ff) },
 	{ }						/* Terminating entry */
 };
 
@@ -397,6 +403,7 @@
 	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_7_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(SEALEVEL_VID, SEALEVEL_2803_8_PID, 0x400, 0xffff) },
 	{ USB_DEVICE_VER(IDTECH_VID, IDTECH_IDT1221U_PID, 0x400, 0xffff) },
+	{ USB_DEVICE_VER(OCT_VID, OCT_US101_PID, 0x400, 0xffff) },
 	{ }						/* Terminating entry */
 };
 
@@ -482,6 +489,7 @@
 	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_7_PID) },
 	{ USB_DEVICE(SEALEVEL_VID, SEALEVEL_2803_8_PID) },
 	{ USB_DEVICE(IDTECH_VID, IDTECH_IDT1221U_PID) },
+	{ USB_DEVICE(OCT_VID, OCT_US101_PID) },
 	{ USB_DEVICE_VER(FTDI_VID, FTDI_HE_TIRA1_PID, 0x400, 0xffff) },
 	{ USB_DEVICE(FTDI_VID, FTDI_USB_UIRT_PID) },
 	{ }						/* Terminating entry */
diff -urN linux-2.4.23-pre6/drivers/usb/serial/ftdi_sio.h linux-2.4.23-pre7/drivers/usb/serial/ftdi_sio.h
--- linux-2.4.23-pre6/drivers/usb/serial/ftdi_sio.h	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/ftdi_sio.h	2003-10-09 17:48:22.000000000 -0700
@@ -133,6 +133,13 @@
 #define IDTECH_VID		0x0ACD	/* ID TECH Vendor ID */
 #define IDTECH_IDT1221U_PID	0x0300	/* IDT1221U USB to RS-232 adapter */
 
+/*
+ * Definitions for Omnidirectional Control Technology, Inc. devices
+ */
+#define OCT_VID			0x0B39	/* OCT vendor ID */
+/* Note: OCT US101 is also rebadged as Dick Smith Electronics (NZ) XH6381 */
+#define OCT_US101_PID		0x0421	/* OCT US101 USB to RS-232 */
+
 /* Commands */
 #define FTDI_SIO_RESET 		0 /* Reset the port */
 #define FTDI_SIO_MODEM_CTRL 	1 /* Set the modem control register */
diff -urN linux-2.4.23-pre6/drivers/usb/serial/ipaq.c linux-2.4.23-pre7/drivers/usb/serial/ipaq.c
--- linux-2.4.23-pre6/drivers/usb/serial/ipaq.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/ipaq.c	2003-10-09 17:48:22.000000000 -0700
@@ -332,7 +332,7 @@
 	usb_serial_debug_data (__FILE__, __FUNCTION__, urb->actual_length, data);
 
 	tty = port->tty;
-	if (urb->actual_length) {
+	if (tty && urb->actual_length) {
 		for (i = 0; i < urb->actual_length ; ++i) {
 			/* if we insert more than TTY_FLIPBUF_SIZE characters, we drop them. */
 			if(tty->flip.count >= TTY_FLIPBUF_SIZE) {
diff -urN linux-2.4.23-pre6/drivers/usb/serial/keyspan.c linux-2.4.23-pre7/drivers/usb/serial/keyspan.c
--- linux-2.4.23-pre6/drivers/usb/serial/keyspan.c	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/keyspan.c	2003-10-09 17:48:22.000000000 -0700
@@ -28,6 +28,9 @@
 
   Change History
 
+  	2003sep04	LPM (Keyspan) add support for new single port product USA19HS.
+				Improve setup message handling for all devices.
+
 	2003Apr16	LPM (Keyspan) fix delayed control message resend for multi-port
 				'Open' case. Fix 'mpr' entries in keyspan.h (previously broken)
 
@@ -174,6 +177,7 @@
 	int		baud;
 	int		old_baud;
 	unsigned int	cflag;
+	unsigned int	old_cflag;
 	enum		{flow_none, flow_cts, flow_xon} flow_control;
 	int		rts_state;	/* Handshaking pins (outputs) */
 	int		dtr_state;
@@ -189,11 +193,12 @@
 
 	
 /* Include Keyspan message headers.  All current Keyspan Adapters
-   make use of one of three message formats which are referred
-   to as USA-26, USA-28 and USA-49 by Keyspan and within this driver. */
+   make use of one of four message formats which are referred
+   to as USA-26, USA-28 and USA-49, USA-90 by Keyspan and within this driver. */
 #include "keyspan_usa26msg.h"
 #include "keyspan_usa28msg.h"
 #include "keyspan_usa49msg.h"
+#include "keyspan_usa90msg.h"
 	
 
 /* Functions used by new usb-serial code. */
@@ -327,8 +332,8 @@
 	return -ENOIOCTLCMD;
 }
 
-	/* Write function is generic for the three protocols used
-	   with only a minor change for usa49 required */
+	/* Write function is similar for the four protocols used
+	   with only a minor change for usa90 (usa19hs) required */
 static int keyspan_write(struct usb_serial_port *port, int from_user, 
 			 const unsigned char *buf, int count)
 {
@@ -337,18 +342,27 @@
 	int				flip;
 	int 				left, todo;
 	struct urb			*this_urb;
-	int 				err;
+	int 				err, maxDataLen, dataOffset;
 
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = p_priv->device_details;
 
+	if (d_details->msg_format == msg_usa90) {
+   		maxDataLen = 64;
+		dataOffset = 0;
+	}
+	else {
+			maxDataLen = 63;
+			dataOffset = 1;
+	}
+	
 	dbg("%s - for port %d (%d chars [%x]), flip=%d",
 	    __FUNCTION__, port->number, count, buf[0], p_priv->out_flip);
 
 	for (left = count; left > 0; left -= todo) {
 		todo = left;
-		if (todo > 63)
-			todo = 63;
+		if (todo > maxDataLen)
+			todo = maxDataLen;
 
 		flip = p_priv->out_flip;
 	
@@ -371,20 +385,20 @@
 			break;
 		}
 
-		/* First byte in buffer is "last flag" - unused so
+		/* First byte in buffer is "last flag" (except for usa19hx) - unused so
 		   for now so set to zero */
 		((char *)this_urb->transfer_buffer)[0] = 0;
 
 		if (from_user) {
-			if (copy_from_user(this_urb->transfer_buffer + 1, buf, todo))
+			if (copy_from_user(this_urb->transfer_buffer + dataOffset, buf, todo))
 				return -EFAULT;
 		} else {
-			memcpy (this_urb->transfer_buffer + 1, buf, todo);
+			memcpy (this_urb->transfer_buffer + dataOffset, buf, todo);
 		}
 		buf += todo;
 
 		/* send the data out the bulk port */
-		this_urb->transfer_buffer_length = todo + 1;
+		this_urb->transfer_buffer_length = todo + dataOffset;
 
 		this_urb->transfer_flags &= ~USB_ASYNC_UNLINK;
 		this_urb->dev = port->serial->dev;
@@ -424,9 +438,12 @@
 	if (urb->actual_length) {
 		/* 0x80 bit is error flag */
 		if ((data[0] & 0x80) == 0) {
-			/* no error on any byte */
+			/* no errors on individual bytes, only possible overrun err*/
+			if (data[0] & RXERROR_OVERRUN)
+					err = TTY_OVERRUN;
+			else err = 0;
 			for (i = 1; i < urb->actual_length ; ++i) {
-				tty_insert_flip_char(tty, data[i], 0);
+				tty_insert_flip_char(tty, data[i], err);
 			}
 		} else {
 			/* some bytes had errors, every byte has status */
@@ -455,7 +472,7 @@
 	return;
 }
 
-	/* Outdat handling is common for usa26, usa28 and usa49 messages */
+	/* Outdat handling is common for all devices */
 static void	usa2x_outdat_callback(struct urb *urb)
 {
 	struct usb_serial_port *port;
@@ -561,7 +578,7 @@
 }
 
 
-static void     usa28_indat_callback(struct urb *urb)
+static void usa28_indat_callback(struct urb *urb)
 {
 	int                     i, err;
 	struct usb_serial_port  *port;
@@ -848,28 +865,171 @@
 }
 
 
+static void	usa90_indat_callback(struct urb *urb)
+{
+	int			i, err;
+	int			endpoint;
+	struct usb_serial_port	*port;
+	struct keyspan_port_private	 	*p_priv;
+	struct tty_struct	*tty;
+	unsigned char 		*data = urb->transfer_buffer;
+
+	dbg ("%s", __FUNCTION__); 
+
+	endpoint = usb_pipeendpoint(urb->pipe);
+
+
+	if (urb->status) {
+		dbg("%s - nonzero status: %x on endpoint %d.",
+		    __FUNCTION__, urb->status, endpoint);
+		return;
+	}
+
+	port = (struct usb_serial_port *) urb->context;
+	p_priv = (struct keyspan_port_private *)(port->private);
+
+	tty = port->tty;
+	if (urb->actual_length) {
+	
+		/* if current mode is DMA, looks like usa28 format
+	   		otherwise looks like usa26 data format */
+
+		if (p_priv->baud > 57600) {
+			for (i = 0; i < urb->actual_length ; ++i) 
+				tty_insert_flip_char(tty, data[i], 0);
+		}
+		else {
+			
+			/* 0x80 bit is error flag */
+			if ((data[0] & 0x80) == 0) {
+				/* no errors on individual bytes, only possible overrun err*/
+				if (data[0] & RXERROR_OVERRUN)
+						err = TTY_OVERRUN;
+				else err = 0;
+				for (i = 1; i < urb->actual_length ; ++i) 
+					tty_insert_flip_char(tty, data[i], err);
+			
+			} 
+			else {
+			/* some bytes had errors, every byte has status */
+				dbg("%s - RX error!!!!", __FUNCTION__);
+				for (i = 0; i + 1 < urb->actual_length; i += 2) {
+					int stat = data[i], flag = 0;
+					if (stat & RXERROR_OVERRUN)
+						flag |= TTY_OVERRUN;
+					if (stat & RXERROR_FRAMING)
+						flag |= TTY_FRAME;
+					if (stat & RXERROR_PARITY)
+						flag |= TTY_PARITY;
+					/* XXX should handle break (0x10) */
+					tty_insert_flip_char(tty, data[i+1], flag);
+				}
+			}
+		}
+		tty_flip_buffer_push(tty);
+	}
+				
+	/* Resubmit urb so we continue receiving */
+	urb->dev = port->serial->dev;
+	if (port->open_count)
+		if ((err = usb_submit_urb(urb)) != 0) {
+			dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
+		}
+	return;
+}
+
+
+static void	usa90_instat_callback(struct urb *urb)
+{
+	unsigned char 				*data = urb->transfer_buffer;
+	struct keyspan_usa90_portStatusMessage	*msg;
+	struct usb_serial			*serial;
+	struct usb_serial_port			*port;
+	struct keyspan_port_private	 	*p_priv;
+	int old_dcd_state, err;
+
+	serial = (struct usb_serial *) urb->context;
+
+	if (urb->status) {
+		dbg("%s - nonzero status: %x", __FUNCTION__, urb->status);
+		return;
+	}
+	if (urb->actual_length < 14) {
+		dbg("%s - %d byte report??", __FUNCTION__, urb->actual_length);
+		goto exit;
+	}
+
+	msg = (struct keyspan_usa90_portStatusMessage *)data;
+
+	/* Now do something useful with the data */
+
+	port = &serial->port[0];
+	p_priv = (struct keyspan_port_private *)(port->private);
+	
+	/* Update handshaking pin state information */
+	old_dcd_state = p_priv->dcd_state;
+	p_priv->cts_state = ((msg->cts) ? 1 : 0);
+	p_priv->dsr_state = ((msg->dsr) ? 1 : 0);
+	p_priv->dcd_state = ((msg->dcd) ? 1 : 0);
+	p_priv->ri_state = ((msg->ri) ? 1 : 0);
+
+	if (port->tty && !C_CLOCAL(port->tty)
+	    && old_dcd_state != p_priv->dcd_state) {
+		if (old_dcd_state)
+			tty_hangup(port->tty);
+		/*  else */
+		/*	wake_up_interruptible(&p_priv->open_wait); */
+	}
+	
+	/* Resubmit urb so we continue receiving */
+	urb->dev = serial->dev;
+	if ((err = usb_submit_urb(urb)) != 0) {
+		dbg("%s - resubmit read urb failed. (%d)", __FUNCTION__, err);
+	}
+exit:
+	;
+}
+
+static void	usa90_outcont_callback(struct urb *urb)
+{
+	struct usb_serial_port *port;
+	struct keyspan_port_private *p_priv;
+
+	port = (struct usb_serial_port *) urb->context;
+	p_priv = (struct keyspan_port_private *)(port->private);
+
+	if (p_priv->resend_cont) {
+		dbg ("%s - sending setup", __FUNCTION__); 
+		keyspan_usa90_send_setup(port->serial, port, p_priv->resend_cont - 1);
+	}
+}
+
 
 static int keyspan_write_room (struct usb_serial_port *port)
 {
 	struct keyspan_port_private	*p_priv;
 	const struct keyspan_device_details	*d_details;
-	int				flip;
+	int				flip,dataLen;
 	struct urb			*this_urb;
 
 	dbg("%s", __FUNCTION__);
 	p_priv = (struct keyspan_port_private *)(port->private);
 	d_details = p_priv->device_details;
 
+	if (d_details->msg_format == msg_usa90)
+   		dataLen = 64;
+	else dataLen = 63;
+
 	flip = p_priv->out_flip;
 
 	/* Check both endpoints to see if any are available. */
 	if ((this_urb = p_priv->out_urbs[flip]) != 0) {
 		if (this_urb->status != -EINPROGRESS)
-			return (63);
+			return (dataLen);
 		flip = (flip + 1) & d_details->outdat_endp_flip;        
 		if ((this_urb = p_priv->out_urbs[flip]) != 0) 
 			if (this_urb->status != -EINPROGRESS)
-				return (63);
+				return (dataLen);
 	}
 	return (0);
 }
@@ -888,20 +1048,25 @@
 	struct usb_serial 		*serial = port->serial;
 	const struct keyspan_device_details	*d_details;
 	int				i, err;
+	int				baud_rate, device_port;
 	struct urb			*urb;
+	unsigned int	cflag;
 
 	s_priv = (struct keyspan_serial_private *)(serial->private);
 	p_priv = (struct keyspan_port_private *)(port->private);
-	d_details = s_priv->device_details;
+	d_details = p_priv->device_details;
 	
 	dbg("%s - port%d.", __FUNCTION__, port->number); 
 
-	p_priv = (struct keyspan_port_private *)(port->private);
-	
 	/* Set some sane defaults */
 	p_priv->rts_state = 1;
 	p_priv->dtr_state = 1;
+	p_priv->baud = 9600;
 
+	/* force baud and lcr to be set on open */
+	p_priv->old_baud = 0;
+	p_priv->old_cflag = 0;
+	
 	p_priv->out_flip = 0;
 	p_priv->in_flip = 0;
 
@@ -910,7 +1075,10 @@
 		if ((urb = p_priv->in_urbs[i]) == NULL)
 			continue;
 		urb->dev = serial->dev;
-		usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0);
+
+		/* make sure endpoint data toggle is synchronized with the device */
+		
+		usb_clear_halt(urb->dev, urb->pipe);
 
 		if ((err = usb_submit_urb(urb)) != 0) {
 			dbg("%s - submit urb %d failed (%d)", __FUNCTION__, i, err);
@@ -925,12 +1093,29 @@
 		/* usb_settoggle(urb->dev, usb_pipeendpoint(urb->pipe), usb_pipeout(urb->pipe), 0); */
 	}
 
-	// if the device is a USA49x, determine whether it is an W or WLC model
-	// and set the baud clock accordingly
+	/* get the terminal config for the setup message now so we don't 
+	 * need to send 2 of them */
+
+	cflag = port->tty->termios->c_cflag;
+	device_port = port->number - port->serial->minor;
+
+	/* Baud rate calculation takes baud rate as an integer
+	   so other rates can be generated if desired. */
+	baud_rate = tty_get_baud_rate(port->tty);
+	/* If no match or invalid, leave as default */		
+	if (baud_rate >= 0
+	    && d_details->calculate_baud_rate(baud_rate, d_details->baudclk,
+				NULL, NULL, NULL, device_port) == KEYSPAN_BAUD_RATE_OK) {
+		p_priv->baud = baud_rate;
+	}
+
+	/* set CTS/RTS handshake etc. */
+	p_priv->cflag = cflag;
+	p_priv->flow_control = (cflag & CRTSCTS)? flow_cts: flow_none;
 
 	keyspan_send_setup(port, 1);
 	//mdelay(100);
-	keyspan_set_termios(port, NULL);
+	//keyspan_set_termios(port, NULL);
 
 	return (0);
 }
@@ -965,7 +1150,7 @@
 		keyspan_send_setup(port, 2);
 		/* pilot-xfer seems to work best with this delay */
 		mdelay(100);
-		keyspan_set_termios(port, NULL);
+		// keyspan_set_termios(port, NULL);
 	}
 
 	/*while (p_priv->outcont_urb->status == -EINPROGRESS) {
@@ -1160,6 +1345,14 @@
 		.outdat_callback =	usa2x_outdat_callback,
 		.inack_callback =	usa49_inack_callback,
 		.outcont_callback =	usa49_outcont_callback,
+	}, {
+		/* msg_usa90 callbacks */
+		.instat_callback =	usa90_instat_callback,
+		.glocont_callback =	usa28_glocont_callback,		
+		.indat_callback =	usa90_indat_callback,
+		.outdat_callback =	usa2x_outdat_callback,
+		.inack_callback =	usa28_inack_callback,
+		.outcont_callback =	usa90_outcont_callback,
 	}
 };
 
@@ -1283,6 +1476,41 @@
 	return (KEYSPAN_BAUD_RATE_OK);
 }
 
+/* usa19hs function doesn't require prescaler */
+static int keyspan_usa19hs_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
+				   u8 *rate_low, u8 *prescaler, int portnum)
+{
+	u32 	b16,	/* baud rate times 16 (actual rate used internally) */
+			div;	/* divisor */	
+		
+	dbg ("%s - %d.", __FUNCTION__, baud_rate);
+
+		/* prevent divide by zero...  */
+	if( (b16 = (baud_rate * 16L)) == 0) 
+		return (KEYSPAN_INVALID_BAUD_RATE);
+	
+
+
+		/* calculate the divisor */
+	if( (div = (baudclk / b16)) == 0) 
+		return (KEYSPAN_INVALID_BAUD_RATE);
+
+	if(div > 0xffff) 
+		return (KEYSPAN_INVALID_BAUD_RATE);
+
+		/* return the counter values if non-null */
+	if (rate_low) 
+		*rate_low = (u8) (div & 0xff);
+	
+	if (rate_hi) 
+		*rate_hi = (u8) ((div >> 8) & 0xff);
+	
+	if (rate_low && rate_hi) 
+		dbg ("%s - %d %02x %02x.", __FUNCTION__, baud_rate, *rate_hi, *rate_low);
+	
+	return (KEYSPAN_BAUD_RATE_OK);
+}
+
 static int keyspan_usa19w_calc_baud(u32 baud_rate, u32 baudclk, u8 *rate_hi,
 				    u8 *rate_low, u8 *prescaler, int portnum)
 {
@@ -1435,6 +1663,7 @@
 		p_priv->resend_cont = reset_port + 1;
 	if (this_urb->status == -EINPROGRESS) {
 		/*  dbg ("%s - already writing", __FUNCTION__); */
+		mdelay(5);
 		return(-1);
 	}
 
@@ -1585,6 +1814,7 @@
 		p_priv->resend_cont = reset_port + 1;
 	if (this_urb->status == -EINPROGRESS) {
 		dbg ("%s already writing", __FUNCTION__);
+		mdelay(5);
 		return(-1);
 	}
 
@@ -1717,6 +1947,7 @@
 		p_priv->resend_cont = reset_port + 1;
 	if (this_urb->status == -EINPROGRESS) {
 		/*  dbg ("%s - already writing", __FUNCTION__); */
+		mdelay(5);
 		return(-1);
 	}
 
@@ -1845,6 +2076,144 @@
 	return (0);
 }
 
+static int keyspan_usa90_send_setup(struct usb_serial *serial,
+				    struct usb_serial_port *port,
+				    int reset_port)
+{
+	struct keyspan_usa90_portControlMessage	msg;		
+	struct keyspan_serial_private 		*s_priv;
+	struct keyspan_port_private 		*p_priv;
+	const struct keyspan_device_details	*d_details;
+	struct urb				*this_urb;
+	int 					err;
+	u8						prescaler;
+
+	dbg ("%s", __FUNCTION__);
+
+	s_priv = (struct keyspan_serial_private *)(serial->private);
+	p_priv = (struct keyspan_port_private *)(port->private);
+	d_details = s_priv->device_details;
+
+	/* only do something if we have a bulk out endpoint */
+	if ((this_urb = p_priv->outcont_urb) == NULL) {
+		dbg("%s - oops no urb.", __FUNCTION__);
+		return -1;
+	}
+
+	/* Save reset port val for resend.
+	   Don't overwrite resend for open/close condition. */
+	if ((reset_port + 1) > p_priv->resend_cont)
+		p_priv->resend_cont = reset_port + 1;
+	if (this_urb->status == -EINPROGRESS) {
+		dbg ("%s already writing", __FUNCTION__);
+		mdelay(5);
+		return(-1);
+	}
+
+	memset(&msg, 0, sizeof (struct keyspan_usa90_portControlMessage));
+
+	/* Only set baud rate if it's changed */	
+	if (p_priv->old_baud != p_priv->baud) {
+		p_priv->old_baud = p_priv->baud;
+		msg.setClocking = 0x01;
+		if (d_details->calculate_baud_rate
+		    (p_priv->baud, d_details->baudclk, &msg.baudHi,
+		     &msg.baudLo, &prescaler, 0) == KEYSPAN_INVALID_BAUD_RATE ) {
+			dbg("%s - Invalid baud rate %d requested, using 9600.", __FUNCTION__,
+			    p_priv->baud);
+			p_priv->baud = 9600;
+			d_details->calculate_baud_rate (p_priv->baud, d_details->baudclk, 
+				&msg.baudHi, &msg.baudLo, &prescaler, 0);
+		}
+		msg.setRxMode = 1;
+		msg.setTxMode = 1;
+	}
+
+	/* modes must always be correctly specified */
+	if (p_priv->baud > 57600)
+	{
+		msg.rxMode = RXMODE_DMA;
+		msg.txMode = TXMODE_DMA;
+	}
+	else
+	{
+		msg.rxMode = RXMODE_BYHAND;
+		msg.txMode = TXMODE_BYHAND;
+	}
+
+	msg.lcr = (p_priv->cflag & CSTOPB)? STOPBITS_678_2: STOPBITS_5678_1;
+	switch (p_priv->cflag & CSIZE) {
+	case CS5:
+		msg.lcr |= USA_DATABITS_5;
+		break;
+	case CS6:
+		msg.lcr |= USA_DATABITS_6;
+		break;
+	case CS7:
+		msg.lcr |= USA_DATABITS_7;
+		break;
+	case CS8:
+		msg.lcr |= USA_DATABITS_8;
+		break;
+	}
+	if (p_priv->cflag & PARENB) {
+		/* note USA_PARITY_NONE == 0 */
+		msg.lcr |= (p_priv->cflag & PARODD)?
+			USA_PARITY_ODD: USA_PARITY_EVEN;
+	}
+	if (p_priv->old_cflag != p_priv->cflag) {
+		p_priv->old_cflag = p_priv->cflag;
+		msg.setLcr = 0x01;
+	}
+
+	if (p_priv->flow_control == flow_cts)
+		msg.txFlowControl = TXFLOW_CTS;
+	msg.setTxFlowControl = 0x01;
+	msg.setRxFlowControl = 0x01;
+	
+	msg.rxForwardingLength = 16;
+	msg.rxForwardingTimeout = 16;	
+	msg.txAckSetting = 0;
+	msg.xonChar = 17;
+	msg.xoffChar = 19;
+
+	/* Opening port */ 
+	if (reset_port == 1) {
+		msg.portEnabled = 1;
+		msg.rxFlush = 1;
+		msg.txBreak = (p_priv->break_on);
+	}
+	/* Closing port */
+	else if (reset_port == 2) {
+		msg.portEnabled = 0;
+	}
+	/* Sending intermediate configs */
+	else {
+		if (port->open_count)
+			msg.portEnabled = 1;
+		msg.txBreak = (p_priv->break_on);
+	}
+
+	/* Do handshaking outputs */	
+	msg.setRts = 0x01;
+	msg.rts = p_priv->rts_state;
+
+	msg.setDtr = 0x01;
+	msg.dtr = p_priv->dtr_state;
+		
+	p_priv->resend_cont = 0;
+	memcpy (this_urb->transfer_buffer, &msg, sizeof(msg));
+	
+	/* send the data out the device on control endpoint */
+	this_urb->transfer_buffer_length = sizeof(msg);
+
+	this_urb->dev = serial->dev;
+	if ((err = usb_submit_urb(this_urb)) != 0) {
+		dbg("%s - usb_submit_urb(setup) failed (%d)", __FUNCTION__, err);
+	}
+	return (0);
+}
+
 static void keyspan_send_setup(struct usb_serial_port *port, int reset_port)
 {
 	struct usb_serial *serial = port->serial;
@@ -1866,9 +2235,13 @@
 	case msg_usa49:
 		keyspan_usa49_send_setup(serial, port, reset_port);
 		break;
+	case msg_usa90:
+		keyspan_usa90_send_setup(serial, port, reset_port);
+		break;
 	}
 }
 
+
 /* Gets called by the "real" driver (ie once firmware is loaded
    and renumeration has taken place. */
 static int keyspan_startup (struct usb_serial *serial)
diff -urN linux-2.4.23-pre6/drivers/usb/serial/keyspan.h linux-2.4.23-pre7/drivers/usb/serial/keyspan.h
--- linux-2.4.23-pre6/drivers/usb/serial/keyspan.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/keyspan.h	2003-10-09 17:48:22.000000000 -0700
@@ -77,6 +77,10 @@
 					 u8 *rate_hi, u8 *rate_low,
 					 u8 *prescaler, int portnum);
 
+static int  keyspan_usa19hs_calc_baud	(u32 baud_rate, u32 baudclk,
+					 u8 *rate_hi, u8 *rate_low,
+					 u8 *prescaler, int portnum);
+
 static int  keyspan_usa28_send_setup	(struct usb_serial *serial,
 					 struct usb_serial_port *port,
 					 int reset_port);
@@ -87,6 +91,9 @@
 					 struct usb_serial_port *port,
 					 int reset_port);
 
+static int  keyspan_usa90_send_setup	(struct usb_serial *serial,
+					 struct usb_serial_port *port,
+					 int reset_port);
 
 /* Struct used for firmware - increased size of data section
    to allow Keyspan's 'C' firmware struct to be used unmodified */
@@ -178,6 +185,7 @@
 #define	KEYSPAN_USA18X_BAUDCLK			(12000000L)	/* a guess */
 #define	KEYSPAN_USA19_BAUDCLK			(12000000L)
 #define	KEYSPAN_USA19W_BAUDCLK			(24000000L)
+#define	KEYSPAN_USA19HS_BAUDCLK			(14769231L)
 #define	KEYSPAN_USA28_BAUDCLK			(1843200L)
 #define	KEYSPAN_USA28X_BAUDCLK			(12000000L)
 #define	KEYSPAN_USA49W_BAUDCLK			(48000000L)
@@ -210,6 +218,7 @@
 #define	keyspan_usa18x_product_id		0x0112
 #define	keyspan_usa19_product_id		0x0107
 #define	keyspan_usa19qi_product_id		0x010c
+#define	keyspan_usa19hs_product_id		0x0121
 #define	keyspan_mpr_product_id			0x011c
 #define	keyspan_usa19qw_product_id		0x0119
 #define	keyspan_usa19w_product_id		0x0108
@@ -225,7 +234,7 @@
 	/* product ID value */
 	int	product_id;
 
-	enum	{msg_usa26, msg_usa28, msg_usa49} msg_format;
+	enum	{msg_usa26, msg_usa28, msg_usa49, msg_usa90} msg_format;
 
 		/* Number of physical ports */
 	int	num_ports;
@@ -361,6 +370,22 @@
 	baudclk:		KEYSPAN_USA19W_BAUDCLK,
 };
 
+static const struct keyspan_device_details usa19hs_device_details = {
+	product_id:		keyspan_usa19hs_product_id,
+	msg_format:		msg_usa90,
+	num_ports:		1,
+	indat_endp_flip:	0,
+	outdat_endp_flip:	0,
+	indat_endpoints:	{0x81},
+	outdat_endpoints:	{0x01},
+	inack_endpoints:	{-1},
+	outcont_endpoints:	{0x02},
+	instat_endpoint:	0x82,
+	glocont_endpoint:	-1,
+	calculate_baud_rate:	keyspan_usa19hs_calc_baud,
+	baudclk:		KEYSPAN_USA19HS_BAUDCLK,
+};
+
 static const struct keyspan_device_details usa28_device_details = {
 	product_id:		keyspan_usa28_product_id,
 	msg_format:		msg_usa28,
@@ -450,6 +475,7 @@
 	&mpr_device_details,
 	&usa19qw_device_details,
 	&usa19w_device_details,
+	&usa19hs_device_details,
 	&usa28_device_details,
 	&usa28x_device_details,
 	&usa28xa_device_details,
@@ -477,6 +503,7 @@
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19hs_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa28x_product_id) },
@@ -512,6 +539,7 @@
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qi_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19qw_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19w_product_id) },
+	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_usa19hs_product_id) },
 	{ USB_DEVICE(KEYSPAN_VENDOR_ID, keyspan_mpr_product_id) },
 	{ } /* Terminating entry */
 };
@@ -547,8 +575,8 @@
 	name:			"Keyspan 1 port adapter",
 	id_table:		keyspan_1port_ids,
 	num_interrupt_in:	NUM_DONT_CARE,
-	num_bulk_in:		3,
-	num_bulk_out:		4,
+	num_bulk_in:		NUM_DONT_CARE,
+	num_bulk_out:		NUM_DONT_CARE,
 	num_ports:		1,
 	open:			keyspan_open,
 	close:			keyspan_close,
diff -urN linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa26msg.h linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa26msg.h
--- linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa26msg.h	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa26msg.h	2003-10-09 17:48:22.000000000 -0700
@@ -4,7 +4,7 @@
 	Copyright (C) 1998-2000 InnoSys Incorporated.  All Rights Reserved
 	This file is available under a BSD-style copyright
 
-	Keyspan USB Async Firmware to run on Anchor EZ-USB
+	Keyspan USB Async Message Formats for the USA28X
 
 	Redistribution and use in source and binary forms, with or without
 	modification, are permitted provided that the following conditions are
@@ -19,11 +19,7 @@
 
         	This file is available under a BSD-style copyright
 
-	2. Redistributions in binary form must reproduce the above copyright
-   	notice, this list of conditions and the following disclaimer in the
-   	documentation and/or other materials provided with the distribution.
-
-	3. The name of InnoSys Incorprated may not be used to endorse or promote
+	2. The name of InnoSys Incorporated may not be used to endorse or promote
    	products derived from this software without specific prior written
    	permission.
 
diff -urN linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa28msg.h linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa28msg.h
--- linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa28msg.h	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa28msg.h	2003-10-09 17:48:22.000000000 -0700
@@ -4,7 +4,7 @@
 	Copyright (C) 1998-2000 InnoSys Incorporated.  All Rights Reserved
 	This file is available under a BSD-style copyright
 
-	Keyspan USB Async Firmware to run on Anchor EZ-USB
+	Keyspan USB Async Message Formats for the USA26X
 
 	Redistribution and use in source and binary forms, with or without
 	modification, are permitted provided that the following conditions are
@@ -19,11 +19,7 @@
 
         	This file is available under a BSD-style copyright
 
-	2. Redistributions in binary form must reproduce the above copyright
-   	notice, this list of conditions and the following disclaimer in the
-   	documentation and/or other materials provided with the distribution.
-
-	3. The name of InnoSys Incorprated may not be used to endorse or promote
+	2. The name of InnoSys Incorporated may not be used to endorse or promote
    	products derived from this software without specific prior written
    	permission.
 
diff -urN linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa49msg.h linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa49msg.h
--- linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa49msg.h	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa49msg.h	2003-10-09 17:48:22.000000000 -0700
@@ -4,7 +4,7 @@
 	Copyright (C) 1998-2000 InnoSys Incorporated.  All Rights Reserved
 	This file is available under a BSD-style copyright
 
-	Keyspan USB Async Firmware to run on Anchor EZ-USB
+	Keyspan USB Async Message Formats for the USA49W
 
 	Redistribution and use in source and binary forms, with or without
 	modification, are permitted provided that the following conditions are
@@ -19,11 +19,7 @@
 
         	This file is available under a BSD-style copyright
 
-	2. Redistributions in binary form must reproduce the above copyright
-   	notice, this list of conditions and the following disclaimer in the
-   	documentation and/or other materials provided with the distribution.
-
-	3. The name of InnoSys Incorprated may not be used to endorse or promote
+	2. The name of InnoSys Incorporated may not be used to endorse or promote
    	products derived from this software without specific prior written
    	permission.
 
diff -urN linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa90msg.h linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa90msg.h
--- linux-2.4.23-pre6/drivers/usb/serial/keyspan_usa90msg.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/drivers/usb/serial/keyspan_usa90msg.h	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,198 @@
+/*
+	usa90msg.h
+
+	Copyright (c) 1998-2003 InnoSys Incorporated.  All Rights Reserved
+	This file is available under a BSD-style copyright
+
+	Keyspan USB Async Message Formats for the USA19HS
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions are
+	met:
+
+	1. Redistributions of source code must retain this licence text
+   	without modification, this list of conditions, and the following
+   	disclaimer.  The following copyright notice must appear immediately at
+   	the beginning of all source files:
+
+        	Copyright (c) 1998-2003 InnoSys Incorporated.  All Rights Reserved
+
+        	This file is available under a BSD-style copyright
+
+	2. The name of InnoSys Incorprated may not be used to endorse or promote
+   	products derived from this software without specific prior written
+   	permission.
+
+	THIS SOFTWARE IS PROVIDED BY INNOSYS CORP. ``AS IS'' AND ANY EXPRESS OR
+	IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+	OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+	NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+	INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+	(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+	SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+	CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+	LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+	OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+	SUCH DAMAGE.    
+
+	Revisions:
+
+	2003feb14		add setTxMode/txMode  and cancelRxXoff to portControl
+	2003mar21		change name of PARITY_0/1 to add MARK/SPACE
+*/
+
+#ifndef	__USA90MSG__
+#define	__USA90MSG__
+
+struct keyspan_usa90_portControlMessage
+{
+	/*
+		there are three types of "commands" sent in the control message:
+
+		1.	configuration changes which must be requested by setting
+			the corresponding "set" flag (and should only be requested
+			when necessary, to reduce overhead on the device):
+	*/
+
+	u8	setClocking,	// host requests baud rate be set
+		baudLo,			// host does baud divisor calculation
+		baudHi,			// host does baud divisor calculation 
+		
+		setLcr,			// host requests lcr be set
+		lcr,			// use PARITY, STOPBITS, DATABITS below
+		
+		setRxMode,		// set receive mode
+		rxMode,			// RXMODE_DMA or RXMODE_BYHAND
+
+		setTxMode,		// set transmit mode
+		txMode,			// TXMODE_DMA or TXMODE_BYHAND
+
+		setTxFlowControl,	// host requests tx flow control be set
+		txFlowControl	,	// use TX_FLOW... bits below
+		setRxFlowControl,	// host requests rx flow control be set
+		rxFlowControl,	// use RX_FLOW... bits below
+		sendXoff,		// host requests XOFF transmitted immediately
+		sendXon,		// host requests XON char transmitted
+		xonChar,		// specified in current character format
+		xoffChar,		// specified in current character format
+
+		sendChar,		// host requests char transmitted immediately
+		txChar,			// character to send
+
+		setRts,			// host requests RTS output be set
+		rts,			// 1=on, 0=off
+		setDtr, 		// host requests DTR output be set
+		dtr;			// 1=on, 0=off
+
+	
+	/*
+		2.	configuration data which is simply used as is 
+			and must be specified correctly in every host message.
+	*/
+
+	u8	rxForwardingLength,  // forward when this number of chars available
+		rxForwardingTimeout, // (1-31 in ms)
+		txAckSetting;	   // 0=don't ack, 1=normal, 2-255 TBD...
+	/*
+		3.	Firmware states which cause actions if they change					
+		and must be specified correctly in every host message.
+	*/
+
+	u8	portEnabled,	// 0=disabled, 1=enabled
+		txFlush,		// 0=normal, 1=toss outbound data
+		txBreak,		// 0=break off, 1=break on
+		loopbackMode;	// 0=no loopback, 1=loopback enabled
+
+	/*
+		4.	commands which are flags only; these are processed in order
+			(so that, e.g., if rxFlush and rxForward flags are set, the
+			port will have no data to forward); any non-zero value 
+			is respected
+	*/
+
+	u8	rxFlush,		// toss inbound data
+		rxForward,		// forward all inbound data, NOW (as if fwdLen==1)
+		cancelRxXoff,	// cancel any receive XOFF state (_txXoff)
+		returnStatus;	// return current status NOW
+};
+
+// defines for bits in lcr
+#define		USA_DATABITS_5		0x00
+#define		USA_DATABITS_6		0x01
+#define		USA_DATABITS_7		0x02
+#define		USA_DATABITS_8		0x03
+#define		STOPBITS_5678_1		0x00	// 1 stop bit for all byte sizes
+#define		STOPBITS_5_1p5		0x04	// 1.5 stop bits for 5-bit byte
+#define		STOPBITS_678_2		0x04	// 2 stop bits for 6-8 bit byte
+#define		USA_PARITY_NONE		0x00
+#define		USA_PARITY_ODD		0x08
+#define		USA_PARITY_EVEN		0x18
+#define		PARITY_MARK_1  		0x28   	// force parity MARK
+#define		PARITY_SPACE_0 		0x38	// force parity SPACE
+
+#define		TXFLOW_CTS			0x04	
+#define		TXFLOW_DSR			0x08
+#define		TXFLOW_XOFF			0x01	
+#define		TXFLOW_XOFF_ANY		0x02	
+#define		TXFLOW_XOFF_BITS	(TXFLOW_XOFF | TXFLOW_XOFF_ANY)
+
+#define		RXFLOW_XOFF			0x10	
+#define		RXFLOW_RTS			0x20	
+#define		RXFLOW_DTR			0x40
+#define		RXFLOW_DSR_SENSITIVITY	0x80
+
+#define		RXMODE_BYHAND		0x00	
+#define		RXMODE_DMA			0x02	
+
+#define		TXMODE_BYHAND		0x00	
+#define		TXMODE_DMA			0x02	
+
+
+// all things called "StatusMessage" are sent on the status endpoint
+
+struct keyspan_usa90_portStatusMessage	
+{
+	u8	msr,			// reports the actual MSR register
+		cts,			// reports CTS pin
+		dcd,			// reports DCD pin
+		dsr,			// reports DSR pin
+		ri,				// reports RI pin
+		_txXoff,		// port is in XOFF state (we received XOFF)
+		rxBreak,		// reports break state
+		rxOverrun,		// count of overrun errors (since last reported)
+		rxParity,		// count of parity errors (since last reported)
+		rxFrame,		// count of frame errors (since last reported)
+		portState,		// PORTSTATE_xxx bits (useful for debugging)
+		messageAck,		// message acknowledgement
+		charAck,		// character acknowledgement
+		controlResponse;	// (value = returnStatus) a control message has been processed 
+};
+
+// bits in RX data message when STAT byte is included
+
+#define	RXERROR_OVERRUN		0x02
+#define	RXERROR_PARITY		0x04
+#define	RXERROR_FRAMING		0x08
+#define	RXERROR_BREAK		0x10
+
+#define	PORTSTATE_ENABLED	0x80
+#define	PORTSTATE_TXFLUSH	0x01
+#define	PORTSTATE_TXBREAK	0x02
+#define	PORTSTATE_LOOPBACK 	0x04
+
+// MSR bits
+
+#define MSR_dCTS	  		0x01		// CTS has changed since last report	
+#define MSR_dDSR	  		0x02
+#define MSR_dRI				0x04
+#define MSR_dDCD	  		0x08
+
+#define MSR_CTS				0x10	  	// current state of CTS
+#define MSR_DSR				0x20
+#define MSR_RI				0x40
+#define MSR_DCD				0x80
+
+// ie: the maximum length of an endpoint buffer
+#define		MAX_DATA_LEN			64
+
+#endif
diff -urN linux-2.4.23-pre6/drivers/usb/serial/pl2303.c linux-2.4.23-pre7/drivers/usb/serial/pl2303.c
--- linux-2.4.23-pre6/drivers/usb/serial/pl2303.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/pl2303.c	2003-10-09 17:48:22.000000000 -0700
@@ -76,6 +76,7 @@
 	{ USB_DEVICE(TRIPP_VENDOR_ID, TRIPP_PRODUCT_ID) },
 	{ USB_DEVICE(RADIOSHACK_VENDOR_ID, RADIOSHACK_PRODUCT_ID) },
 	{ USB_DEVICE(DCU10_VENDOR_ID, DCU10_PRODUCT_ID) },
+	{ USB_DEVICE(SITECOM_VENDOR_ID, SITECOM_PRODUCT_ID) },
 	{ }					/* Terminating entry */
 };
 
diff -urN linux-2.4.23-pre6/drivers/usb/serial/pl2303.h linux-2.4.23-pre7/drivers/usb/serial/pl2303.h
--- linux-2.4.23-pre6/drivers/usb/serial/pl2303.h	2003-06-13 07:51:37.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/serial/pl2303.h	2003-10-09 17:48:22.000000000 -0700
@@ -37,3 +37,6 @@
 
 #define DCU10_VENDOR_ID		0x0731
 #define DCU10_PRODUCT_ID	0x0528
+
+#define SITECOM_VENDOR_ID	0x6189
+#define SITECOM_PRODUCT_ID	0x2068
diff -urN linux-2.4.23-pre6/drivers/usb/speedtch.c linux-2.4.23-pre7/drivers/usb/speedtch.c
--- linux-2.4.23-pre6/drivers/usb/speedtch.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/speedtch.c	2003-10-09 17:48:22.000000000 -0700
@@ -21,7 +21,9 @@
  ******************************************************************************/
 
 /*
- *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@wanadoo.fr)
+ *  Written by Johan Verrept, maintained by Duncan Sands (duncan.sands@free.fr)
+ *
+ *  1.7+:	- See the check-in logs
  *
  *  1.6:	- No longer opens a connection if the firmware is not loaded
  *  		- Added support for the speedtouch 330
@@ -83,6 +85,11 @@
 
 #include <linux/usb.h>
 
+#ifdef DEBUG
+#define DEBUG_ON(x)	BUG_ON(x)
+#else
+#define DEBUG_ON(x)	do { if (x); } while (0)
+#endif
 
 #ifdef VERBOSE_DEBUG
 static int udsl_print_packet (const unsigned char *data, int len);
@@ -93,9 +100,9 @@
 #define vdbg(arg...)
 #endif
 
-#define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@wanadoo.fr>"
+#define DRIVER_AUTHOR	"Johan Verrept, Duncan Sands <duncan.sands@free.fr>"
 #define DRIVER_DESC	"Alcatel SpeedTouch USB driver"
-#define DRIVER_VERSION	"1.6"
+#define DRIVER_VERSION	"1.7"
 
 static const char udsl_driver_name [] = "speedtch";
 
@@ -181,8 +188,7 @@
 	struct atm_vcc *vcc;
 
 	/* raw cell reassembly */
-	struct sk_buff *skb;
-	unsigned int max_pdu;
+	struct sk_buff *sarb;
 };
 
 /* send */
@@ -306,12 +312,10 @@
 {
 	struct udsl_vcc_data *cached_vcc = NULL;
 	struct atm_vcc *vcc;
-	struct sk_buff *skb;
+	struct sk_buff *sarb;
 	struct udsl_vcc_data *vcc_data;
 	int cached_vci = 0;
 	unsigned int i;
-	unsigned int length;
-	unsigned int pdu_length;
 	int pti;
 	int vci;
 	short cached_vpi = 0;
@@ -336,74 +340,73 @@
 		}
 
 		vcc = vcc_data->vcc;
+		sarb = vcc_data->sarb;
 
-		if (!vcc_data->skb && !(vcc_data->skb = dev_alloc_skb (vcc_data->max_pdu))) {
-			dbg ("udsl_extract_cells: no memory for skb (vcc: 0x%p)!", vcc);
-			if (pti)
-				atomic_inc (&vcc->stats->rx_err);
-			continue;
-		}
-
-		skb = vcc_data->skb;
-
-		if (skb->len + ATM_CELL_PAYLOAD > vcc_data->max_pdu) {
-			dbg ("udsl_extract_cells: buffer overrun (max_pdu: %u, skb->len %u, vcc: 0x%p)", vcc_data->max_pdu, skb->len, vcc);
+		if (sarb->tail + ATM_CELL_PAYLOAD > sarb->end) {
+			dbg ("udsl_extract_cells: buffer overrun (sarb->len %u, vcc: 0x%p)!", sarb->len, vcc);
 			/* discard cells already received */
-			skb_trim (skb, 0);
-			BUG_ON (vcc_data->max_pdu < ATM_CELL_PAYLOAD);
+			skb_trim (sarb, 0);
 		}
 
-		memcpy (skb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
-		__skb_put (skb, ATM_CELL_PAYLOAD);
+		memcpy (sarb->tail, source + ATM_CELL_HEADER, ATM_CELL_PAYLOAD);
+		__skb_put (sarb, ATM_CELL_PAYLOAD);
 
 		if (pti) {
+			struct sk_buff *skb;
+			unsigned int length;
+			unsigned int pdu_length;
+
 			length = (source [ATM_CELL_SIZE - 6] << 8) + source [ATM_CELL_SIZE - 5];
 
 			/* guard against overflow */
 			if (length > ATM_MAX_AAL5_PDU) {
-				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)", length, vcc);
-				goto drop;
+				dbg ("udsl_extract_cells: bogus length %u (vcc: 0x%p)!", length, vcc);
+				atomic_inc (&vcc->stats->rx_err);
+				goto out;
 			}
 
 			pdu_length = UDSL_NUM_CELLS (length) * ATM_CELL_PAYLOAD;
 
-			if (skb->len < pdu_length) {
-				dbg ("udsl_extract_cells: bogus pdu_length %u (skb->len: %u, vcc: 0x%p)", pdu_length, skb->len, vcc);
-				goto drop;
+			if (sarb->len < pdu_length) {
+				dbg ("udsl_extract_cells: bogus pdu_length %u (sarb->len: %u, vcc: 0x%p)!", pdu_length, sarb->len, vcc);
+				atomic_inc (&vcc->stats->rx_err);
+				goto out;
 			}
 
-			if (crc32_be (~0, skb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
-				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)", vcc);
-				goto drop;
+			if (crc32_be (~0, sarb->tail - pdu_length, pdu_length) != 0xc704dd7b) {
+				dbg ("udsl_extract_cells: packet failed crc check (vcc: 0x%p)!", vcc);
+				atomic_inc (&vcc->stats->rx_err);
+				goto out;
 			}
 
-			if (!atm_charge (vcc, skb->truesize)) {
-				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)", skb->truesize);
-				goto drop_no_stats; /* atm_charge increments rx_drop */
-			}
+			vdbg ("udsl_extract_cells: got packet (length: %u, pdu_length: %u, vcc: 0x%p)", length, pdu_length, vcc);
 
-			/* now that we are sure to send the skb, it is ok to change skb->data */
-			if (skb->len > pdu_length)
-				skb_pull (skb, skb->len - pdu_length); /* discard initial junk */
+			if (!(skb = dev_alloc_skb (length))) {
+				dbg ("udsl_extract_cells: no memory for skb (length: %u)!", length);
+				atomic_inc (&vcc->stats->rx_drop);
+				goto out;
+			}
 
-			skb_trim (skb, length); /* drop zero padding and trailer */
+			vdbg ("udsl_extract_cells: allocated new sk_buff (skb: 0x%p, skb->truesize: %u)", skb, skb->truesize);
 
-			atomic_inc (&vcc->stats->rx);
+			if (!atm_charge (vcc, skb->truesize)) {
+				dbg ("udsl_extract_cells: failed atm_charge (skb->truesize: %u)!", skb->truesize);
+				dev_kfree_skb (skb);
+				goto out; /* atm_charge increments rx_drop */
+			}
 
-			PACKETDEBUG (skb->data, skb->len);
+			memcpy (skb->data, sarb->tail - pdu_length, length);
+			__skb_put (skb, length);
 
 			vdbg ("udsl_extract_cells: sending skb 0x%p, skb->len %u, skb->truesize %u", skb, skb->len, skb->truesize);
 
-			vcc->push (vcc, skb);
-
-			vcc_data->skb = NULL;
+			PACKETDEBUG (skb->data, skb->len);
 
-			continue;
+			vcc->push (vcc, skb);
 
-drop:
-			atomic_inc (&vcc->stats->rx_err);
-drop_no_stats:
-			skb_trim (skb, 0);
+			atomic_inc (&vcc->stats->rx);
+out:
+			skb_trim (sarb, 0);
 		}
 	}
 }
@@ -497,7 +500,7 @@
 		memset (target, 0, ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER);
 		target += ATM_CELL_PAYLOAD - ATM_AAL5_TRAILER;
 
-		BUG_ON (--ctrl->num_cells);
+		DEBUG_ON (--ctrl->num_cells);
 	}
 
 	memcpy (target, ctrl->aal5_trailer, ATM_AAL5_TRAILER);
@@ -534,7 +537,7 @@
 
 	vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
 
-	BUG_ON (buf->filled_cells > rcv_buf_size);
+	DEBUG_ON (buf->filled_cells > rcv_buf_size);
 
 	/* may not be in_interrupt() */
 	spin_lock_irqsave (&instance->receive_lock, flags);
@@ -865,6 +868,7 @@
 {
 	struct udsl_instance_data *instance = vcc->dev->dev_data;
 	struct udsl_vcc_data *new;
+	unsigned int max_pdu;
 
 	dbg ("udsl_atm_open: vpi %hd, vci %d", vpi, vci);
 
@@ -877,8 +881,10 @@
 		return -EINVAL;
 
 	/* only support AAL5 */
-	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU))
+	if ((vcc->qos.aal != ATM_AAL5) || (vcc->qos.rxtp.max_sdu < 0) || (vcc->qos.rxtp.max_sdu > ATM_MAX_AAL5_PDU)) {
+		dbg ("udsl_atm_open: unsupported ATM type %d!", vcc->qos.aal);
 		return -EINVAL;
+	}
 
 	if (!instance->firmware_loaded) {
 		dbg ("udsl_atm_open: firmware not loaded!");
@@ -888,11 +894,13 @@
 	down (&instance->serialize); /* vs self, udsl_atm_close */
 
 	if (udsl_find_vcc (instance, vpi, vci)) {
+		dbg ("udsl_atm_open: %hd/%d already in use!", vpi, vci);
 		up (&instance->serialize);
 		return -EADDRINUSE;
 	}
 
 	if (!(new = kmalloc (sizeof (struct udsl_vcc_data), GFP_KERNEL))) {
+		dbg ("udsl_atm_open: no memory for vcc_data!");
 		up (&instance->serialize);
 		return -ENOMEM;
 	}
@@ -901,7 +909,15 @@
 	new->vcc = vcc;
 	new->vpi = vpi;
 	new->vci = vci;
-	new->max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
+
+	/* udsl_extract_cells requires at least one cell */
+	max_pdu = max (1, UDSL_NUM_CELLS (vcc->qos.rxtp.max_sdu)) * ATM_CELL_PAYLOAD;
+	if (!(new->sarb = alloc_skb (max_pdu, GFP_KERNEL))) {
+		dbg ("udsl_atm_open: no memory for SAR buffer!");
+	        kfree (new);
+		up (&instance->serialize);
+		return -ENOMEM;
+	}
 
 	vcc->dev_data = new;
 	vcc->vpi = vpi;
@@ -919,7 +935,7 @@
 
 	tasklet_schedule (&instance->receive_tasklet);
 
-	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, new->max_pdu);
+	dbg ("udsl_atm_open: allocated vcc data 0x%p (max_pdu: %u)", new, max_pdu);
 
 	return 0;
 }
@@ -946,9 +962,8 @@
 	list_del (&vcc_data->list);
 	tasklet_enable (&instance->receive_tasklet);
 
-	if (vcc_data->skb)
-		dev_kfree_skb (vcc_data->skb);
-	vcc_data->skb = NULL;
+	kfree_skb (vcc_data->sarb);
+	vcc_data->sarb = NULL;
 
 	kfree (vcc_data);
 	vcc->dev_data = NULL;
@@ -1205,15 +1220,14 @@
 
 	for (i = 0; i < num_rcv_urbs; i++)
 		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
-			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d!", i, result);
 
 	/* wait for completion handlers to finish */
 	do {
 		count = 0;
 		spin_lock_irq (&instance->receive_lock);
 		list_for_each (pos, &instance->spare_receivers)
-			if (++count > num_rcv_urbs)
-				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+			DEBUG_ON (++count > num_rcv_urbs);
 		spin_unlock_irq (&instance->receive_lock);
 
 		dbg ("udsl_usb_disconnect: found %u spare receivers", count);
@@ -1242,15 +1256,14 @@
 
 	for (i = 0; i < num_snd_urbs; i++)
 		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
-			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
+			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d!", i, result);
 
 	/* wait for completion handlers to finish */
 	do {
 		count = 0;
 		spin_lock_irq (&instance->send_lock);
 		list_for_each (pos, &instance->spare_senders)
-			if (++count > num_snd_urbs)
-				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
+			DEBUG_ON (++count > num_snd_urbs);
 		spin_unlock_irq (&instance->send_lock);
 
 		dbg ("udsl_usb_disconnect: found %u spare senders", count);
@@ -1289,11 +1302,9 @@
 
 static int __init udsl_usb_init (void)
 {
-	struct sk_buff *skb; /* dummy for sizeof */
-
 	dbg ("udsl_usb_init: driver version " DRIVER_VERSION);
 
-	if (sizeof (struct udsl_control) > sizeof (skb->cb)) {
+	if (sizeof (struct udsl_control) > sizeof (((struct sk_buff *)0)->cb)) {
 		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
 		return -EIO;
 	}
diff -urN linux-2.4.23-pre6/drivers/usb/storage/protocol.c linux-2.4.23-pre7/drivers/usb/storage/protocol.c
--- linux-2.4.23-pre6/drivers/usb/storage/protocol.c	2003-08-25 04:44:42.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/storage/protocol.c	2003-10-09 17:48:22.000000000 -0700
@@ -237,6 +237,10 @@
 	 * a unsigned char cmnd[12], so we know we have storage available
 	 */
 
+	/* Pad the ATAPI command with zeros */
+	for (; srb->cmd_len<12; srb->cmd_len++)
+		srb->cmnd[srb->cmd_len] = 0;
+
 	/* set command length to 12 bytes (this affects the transport layer) */
 	srb->cmd_len = 12;
 
diff -urN linux-2.4.23-pre6/drivers/usb/storage/unusual_devs.h linux-2.4.23-pre7/drivers/usb/storage/unusual_devs.h
--- linux-2.4.23-pre6/drivers/usb/storage/unusual_devs.h	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/storage/unusual_devs.h	2003-10-09 17:48:22.000000000 -0700
@@ -289,7 +289,7 @@
 UNUSUAL_DEV(  0x057b, 0x0000, 0x0000, 0x0299, 
 		"Y-E Data",
 		"Flashbuster-U",
-		US_SC_UFI,  US_PR_CB, NULL,
+		US_SC_DEVICE,  US_PR_CB, NULL,
 		US_FL_SINGLE_LUN),
 
 UNUSUAL_DEV(  0x057b, 0x0000, 0x0300, 0x9999, 
@@ -394,6 +394,12 @@
 		"Dimage F300",
 		US_SC_SCSI, US_PR_BULK, NULL, 0 ),
 
+/* Reported by Miguel A. Fosas <amn3s1a@ono.com> */
+UNUSUAL_DEV(  0x0686, 0x4017, 0x0001, 0x0001,
+                "Minolta",
+                "DIMAGE E223",
+                US_SC_SCSI, US_PR_DEVICE, NULL, 0 ),
+
 UNUSUAL_DEV(  0x0693, 0x0002, 0x0100, 0x0100, 
 		"Hagiwara",
 		"FlashGate SmartMedia",
@@ -542,7 +548,7 @@
  * - They don't like the INQUIRY command. So we must handle this command
  *   of the SCSI layer ourselves.
  */
-UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x9009,
+UNUSUAL_DEV( 0x07cf, 0x1001, 0x1000, 0x5009,
 		"Casio",
 		"QV DigitalCamera",
 		US_SC_8070, US_PR_CB, NULL,
diff -urN linux-2.4.23-pre6/drivers/usb/usbnet.c linux-2.4.23-pre7/drivers/usb/usbnet.c
--- linux-2.4.23-pre6/drivers/usb/usbnet.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/usbnet.c	2003-10-09 17:48:22.000000000 -0700
@@ -133,6 +133,7 @@
 #include <linux/etherdevice.h>
 #include <linux/random.h>
 #include <linux/ethtool.h>
+#include <linux/mii.h>
 #include <linux/tqueue.h>
 #include <asm/uaccess.h>
 #include <asm/unaligned.h>
@@ -157,6 +158,7 @@
 
 /* minidrivers _could_ be individually configured */
 #define	CONFIG_USB_AN2720
+#define	CONFIG_USB_AX8817X
 #define	CONFIG_USB_BELKIN
 #define	CONFIG_USB_EPSON2888
 #define	CONFIG_USB_GENESYS
@@ -227,6 +229,7 @@
 	struct net_device	net;
 	struct net_device_stats	stats;
 	int			msg_level;
+	struct mii_if_info	mii;
 
 #ifdef CONFIG_USB_NET1080
 	u16			packet_id;
@@ -254,6 +257,10 @@
 #define FLAG_FRAMING_GL	0x0002		/* genelink batches packets */
 #define FLAG_FRAMING_Z	0x0004		/* zaurus adds a trailer */
 #define FLAG_NO_SETINT	0x0010		/* device can't set_interface() */
+#define FLAG_ETHER	0x0020		/* maybe use "eth%d" names */
+
+	/* init device ... can sleep, or cause probe() failure */
+	int	(*bind)(struct usbnet *, struct usb_device *);
 
 	/* reset device ... can sleep */
 	int	(*reset)(struct usbnet *);
@@ -275,6 +282,8 @@
 	int		in;		/* rx endpoint */
 	int		out;		/* tx endpoint */
 	int		epsize;
+
+	unsigned long	data;		/* Misc driver specific data */
 };
 
 // we record the state for each of our queued skbs
@@ -305,6 +314,8 @@
 #define	RUN_CONTEXT (in_irq () ? "in_irq" \
 			: (in_interrupt () ? "in_interrupt" : "can sleep"))
 
+static struct ethtool_ops usbnet_ethtool_ops;
+
 /* mostly for PDA style devices, which are always present */
 static int always_connected (struct usbnet *dev)
 {
@@ -405,6 +416,306 @@
 
 #endif	/* CONFIG_USB_AN2720 */
 
+
+#ifdef CONFIG_USB_AX8817X
+/* ASIX AX8817X based USB 2.0 Ethernet Devices */
+
+#define HAVE_HARDWARE
+#define NEED_MII
+
+#include <linux/crc32.h>
+
+#define AX_CMD_SET_SW_MII		0x06
+#define AX_CMD_READ_MII_REG		0x07
+#define AX_CMD_WRITE_MII_REG		0x08
+#define AX_CMD_SET_HW_MII		0x0a
+#define AX_CMD_WRITE_RX_CTL		0x10
+#define AX_CMD_READ_IPG012		0x11
+#define AX_CMD_WRITE_IPG0		0x12
+#define AX_CMD_WRITE_IPG1		0x13
+#define AX_CMD_WRITE_IPG2		0x14
+#define AX_CMD_WRITE_MULTI_FILTER	0x16
+#define AX_CMD_READ_NODE_ID		0x17
+#define AX_CMD_READ_PHY_ID		0x19
+#define AX_CMD_WRITE_MEDIUM_MODE	0x1b
+#define AX_CMD_WRITE_GPIOS		0x1f
+
+#define AX_MCAST_FILTER_SIZE		8
+#define AX_MAX_MCAST			64
+
+static int ax8817x_read_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+			    u16 size, void *data)
+{
+	return usb_control_msg(
+		dev->udev,
+		usb_rcvctrlpipe(dev->udev, 0),
+		cmd,
+		USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value,
+		index,
+		data,
+		size,
+		CONTROL_TIMEOUT_JIFFIES);
+}
+
+static int ax8817x_write_cmd(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+			     u16 size, void *data)
+{
+	return usb_control_msg(
+		dev->udev,
+		usb_sndctrlpipe(dev->udev, 0),
+		cmd,
+		USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE,
+		value,
+		index,
+		data,
+		size,
+		CONTROL_TIMEOUT_JIFFIES);
+}
+
+static void ax8817x_async_cmd_callback(struct urb *urb)
+{
+	struct usb_ctrlrequest *req = (struct usb_ctrlrequest *)urb->context;
+
+	if (urb->status < 0)
+		printk(KERN_DEBUG "ax8817x_async_cmd_callback() failed with %d",
+			urb->status);
+
+	kfree(req);
+	usb_free_urb(urb);
+}
+
+static void ax8817x_write_cmd_async(struct usbnet *dev, u8 cmd, u16 value, u16 index,
+				    u16 size, void *data)
+{
+	struct usb_ctrlrequest *req;
+	int status;
+	struct urb *urb;
+
+	if ((urb = ALLOC_URB(0, GFP_ATOMIC)) == NULL) {
+		devdbg(dev, "Error allocating URB in write_cmd_async!");
+		return;
+	}
+
+	if ((req = kmalloc(sizeof(struct usb_ctrlrequest), GFP_ATOMIC)) == NULL) {
+		devdbg(dev, "Failed to allocate memory for control request");
+		usb_free_urb(urb);
+		return;
+	}
+
+	req->bRequestType = USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE;
+	req->bRequest = cmd;
+	req->wValue = cpu_to_le16(value);
+	req->wIndex = cpu_to_le16(index); 
+	req->wLength = cpu_to_le16(size);
+
+	usb_fill_control_urb(urb, dev->udev,
+			     usb_sndctrlpipe(dev->udev, 0),
+			     (void *)req, data, size,
+			     ax8817x_async_cmd_callback, req);
+
+	if((status = SUBMIT_URB(urb, GFP_ATOMIC)) < 0)
+		devdbg(dev, "Error submitting the control message: status=%d", status);
+}
+
+static void ax8817x_set_multicast(struct net_device *net)
+{
+	struct usbnet *dev = (struct usbnet *) net->priv;
+	u8 rx_ctl = 0x8c;
+
+	if (net->flags & IFF_PROMISC) {
+		rx_ctl |= 0x01;
+	} else if (net->flags & IFF_ALLMULTI
+		   || net->mc_count > AX_MAX_MCAST) {
+		rx_ctl |= 0x02;
+	} else if (net->mc_count == 0) {
+		/* just broadcast and directed */
+	} else {
+		struct dev_mc_list *mc_list = net->mc_list;
+		u8 *multi_filter;
+		u32 crc_bits;
+		int i;
+
+		multi_filter = kmalloc(AX_MCAST_FILTER_SIZE, GFP_ATOMIC);
+		if (multi_filter == NULL) {
+			/* Oops, couldn't allocate a buffer for setting the multicast
+			   filter. Try all multi mode. */
+			rx_ctl |= 0x02;
+		} else {
+			memset(multi_filter, 0, AX_MCAST_FILTER_SIZE);
+
+			/* Build the multicast hash filter. */
+			for (i = 0; i < net->mc_count; i++) {
+				crc_bits =
+				    ether_crc(ETH_ALEN,
+					      mc_list->dmi_addr) >> 26;
+				multi_filter[crc_bits >> 3] |=
+				    1 << (crc_bits & 7);
+				mc_list = mc_list->next;
+			}
+
+			ax8817x_write_cmd_async(dev, AX_CMD_WRITE_MULTI_FILTER, 0, 0,
+					   AX_MCAST_FILTER_SIZE, multi_filter);
+
+			rx_ctl |= 0x10;
+		}
+	}
+
+	ax8817x_write_cmd_async(dev, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0, NULL);
+}
+
+static int ax8817x_mdio_read(struct net_device *netdev, int phy_id, int loc)
+{
+	struct usbnet *dev = netdev->priv;
+	u16 res;
+	u8 buf[4];
+
+	ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+	ax8817x_read_cmd(dev, AX_CMD_READ_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
+	ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+
+	return res & 0xffff;
+}
+
+static void ax8817x_mdio_write(struct net_device *netdev, int phy_id, int loc, int val)
+{
+	struct usbnet *dev = netdev->priv;
+	u16 res = val;
+	u8 buf[4];
+
+	ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+	ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG, phy_id, (__u16)loc, 2, (u16 *)&res);
+	ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+}
+
+static int ax8817x_bind(struct usbnet *dev, struct usb_device *intf)
+{
+	int ret;
+	u8 buf[6];
+	u16 *buf16 = (u16 *) buf;
+	int i;
+	unsigned long gpio_bits = dev->driver_info->data;
+
+	dev->in = usb_rcvbulkpipe(dev->udev, 3);
+	dev->out = usb_sndbulkpipe(dev->udev, 2);
+
+	/* Toggle the GPIOs in a manufacturer/model specific way */
+	for (i = 2; i >= 0; i--) {
+		if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_GPIOS,
+				       (gpio_bits >> (i * 8)) & 0xff, 0, 0,
+				       buf)) < 0)
+			return ret;
+		wait_ms(5);
+        }
+                                                                                
+	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf)) < 0) {
+		dbg("send AX_CMD_WRITE_RX_CTL failed: %d", ret);
+		return ret;
+	}
+
+	/* Get the MAC address */
+	memset(buf, 0, ETH_ALEN);
+	if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_NODE_ID, 0, 0, 6, buf)) < 0) {
+		dbg("read AX_CMD_READ_NODE_ID failed: %d", ret);
+		return ret;
+	}
+	memcpy(dev->net.dev_addr, buf, ETH_ALEN);
+
+	/* Get IPG values */
+	if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_IPG012, 0, 0, 3, buf)) < 0) {
+		dbg("Error reading IPG values: %d", ret);
+		return ret;
+	}
+
+	for(i = 0;i < 3;i++) {
+		ax8817x_write_cmd(dev, AX_CMD_WRITE_IPG0 + i, 0, 0, 1, &buf[i]);
+	}
+
+	/* Get the PHY id */
+	if ((ret = ax8817x_read_cmd(dev, AX_CMD_READ_PHY_ID, 0, 0, 2, buf)) < 0) {
+		dbg("error on read AX_CMD_READ_PHY_ID: %02x", ret);
+		return ret;
+	} else if (ret < 2) {
+		/* this should always return 2 bytes */
+		dbg("AX_CMD_READ_PHY_ID returned less than 2 bytes: ret=%02x", ret);
+		return -EIO;
+	}
+
+	/* Initialize MII structure */
+	dev->mii.dev = &dev->net;
+	dev->mii.mdio_read = ax8817x_mdio_read;
+	dev->mii.mdio_write = ax8817x_mdio_write;
+	dev->mii.phy_id_mask = 0x3f;
+	dev->mii.reg_num_mask = 0x1f;
+	dev->mii.phy_id = buf[1];
+
+	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_SW_MII, 0, 0, 0, &buf)) < 0) {
+		dbg("Failed to go to software MII mode: %02x", ret);
+		return ret;
+	}
+
+	*buf16 = cpu_to_le16(BMCR_RESET);
+	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,
+				     dev->mii.phy_id, MII_BMCR, 2, buf16)) < 0) {
+		dbg("Failed to write MII reg - MII_BMCR: %02x", ret);
+		return ret;
+	}
+
+	/* Advertise that we can do full-duplex pause */
+	*buf16 = cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400);
+	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,
+			   	     dev->mii.phy_id, MII_ADVERTISE, 
+				     2, buf16)) < 0) {
+		dbg("Failed to write MII_REG advertisement: %02x", ret);
+		return ret;
+	}
+
+	*buf16 = cpu_to_le16(BMCR_ANENABLE | BMCR_ANRESTART);
+	if ((ret = ax8817x_write_cmd(dev, AX_CMD_WRITE_MII_REG,
+			  	     dev->mii.phy_id, MII_BMCR, 
+				     2, buf16)) < 0) {
+		dbg("Failed to write MII reg autonegotiate: %02x", ret);
+		return ret;
+	}
+
+	if ((ret = ax8817x_write_cmd(dev, AX_CMD_SET_HW_MII, 0, 0, 0, &buf)) < 0) {
+		dbg("Failed to set hardware MII: %02x", ret);
+		return ret;
+	}
+
+	dev->net.set_multicast_list = ax8817x_set_multicast;
+
+	return 0;
+}
+
+static const struct driver_info ax8817x_info = {
+	.description = "ASIX AX8817x USB 2.0 Ethernet",
+	.bind = ax8817x_bind,
+	.flags =  FLAG_ETHER,
+	.data = 0x00130103,
+};
+
+static const struct driver_info dlink_dub_e100_info = {
+	.description = "DLink DUB-E100 USB Ethernet",
+	.bind = ax8817x_bind,
+	.flags =  FLAG_ETHER,
+	.data = 0x009f9d9f,
+};
+
+static const struct driver_info netgear_fa120_info = {
+	.description = "Netgear FA-120 USB Ethernet",
+	.bind = ax8817x_bind,
+	.flags =  FLAG_ETHER,
+	.data = 0x00130103,
+};
+
+static const struct driver_info hawking_uf200_info = {
+	.description = "Hawking UF200 USB Ethernet",
+	.bind = ax8817x_bind,
+	.flags =  FLAG_ETHER,
+	.data = 0x001f1d1f,
+};
+#endif /* CONFIG_USB_AX8817X */
 
 
 #ifdef	CONFIG_USB_BELKIN
@@ -1779,74 +2090,56 @@
 
 /*-------------------------------------------------------------------------*/
 
-static int usbnet_ethtool_ioctl (struct net_device *net, void *useraddr)
+static void usbnet_get_drvinfo (struct net_device *net, struct ethtool_drvinfo *info)
 {
-	struct usbnet	*dev = (struct usbnet *) net->priv;
-	u32		cmd;
+	struct usbnet *dev = net->priv;
 
-	if (get_user (cmd, (u32 *)useraddr))
-		return -EFAULT;
-	switch (cmd) {
-
-	case ETHTOOL_GDRVINFO: {	/* get driver info */
-		struct ethtool_drvinfo		info;
-
-		memset (&info, 0, sizeof info);
-		info.cmd = ETHTOOL_GDRVINFO;
-		strncpy (info.driver, driver_name, sizeof info.driver);
-		strncpy (info.version, DRIVER_VERSION, sizeof info.version);
-		strncpy (info.fw_version, dev->driver_info->description,
-			sizeof info.fw_version);
-		usb_make_path (dev->udev, info.bus_info, sizeof info.bus_info);
-		if (copy_to_user (useraddr, &info, sizeof (info)))
-			return -EFAULT;
-		return 0;
-		}
+	strncpy (info->driver, driver_name, sizeof info->driver);
+	strncpy (info->version, DRIVER_VERSION, sizeof info->version);
+	strncpy (info->fw_version, dev->driver_info->description,
+		sizeof info->fw_version);
+	usb_make_path (dev->udev, info->bus_info, sizeof info->bus_info);
+}
 
-	case ETHTOOL_GLINK: 		/* get link status */
-		if (dev->driver_info->check_connect) {
-			struct ethtool_value	edata = { ETHTOOL_GLINK };
-
-			edata.data = dev->driver_info->check_connect (dev) == 0;
-			if (copy_to_user (useraddr, &edata, sizeof (edata)))
-				return -EFAULT;
-			return 0;
-		}
-		break;
+static u32 usbnet_get_link (struct net_device *net)
+{
+	struct usbnet *dev = net->priv;
 
-	case ETHTOOL_GMSGLVL: {		/* get message-level */
-		struct ethtool_value	edata = {ETHTOOL_GMSGLVL};
+	/* If a check_connect is defined, return it's results */
+	if (dev->driver_info->check_connect)
+		return dev->driver_info->check_connect (dev) == 0;
 
-		edata.data = dev->msg_level;
-		if (copy_to_user (useraddr, &edata, sizeof (edata)))
-			return -EFAULT;
-		return 0;
-		}
+	/* Otherwise, we're up to avoid breaking scripts */
+	return 1;
+}
 
-	case ETHTOOL_SMSGLVL: {		/* set message-level */
-		struct ethtool_value	edata;
+static u32 usbnet_get_msglevel (struct net_device *net)
+{
+	struct usbnet *dev = net->priv;
 
-		if (copy_from_user (&edata, useraddr, sizeof (edata)))
-			return -EFAULT;
-		dev->msg_level = edata.data;
-		return 0;
-		}
-	
-	/* could also map RINGPARAM to RX/TX QLEN */
+	return dev->msg_level;
+}
 
-	}
-	/* Note that the ethtool user space code requires EOPNOTSUPP */
-	return -EOPNOTSUPP;
+static void usbnet_set_msglevel (struct net_device *net, u32 level)
+{
+	struct usbnet *dev = net->priv;
+
+	dev->msg_level = level;
 }
 
 static int usbnet_ioctl (struct net_device *net, struct ifreq *rq, int cmd)
 {
-	switch (cmd) {
-	case SIOCETHTOOL:
-		return usbnet_ethtool_ioctl (net, (void *)rq->ifr_data);
-	default:
-		return -EOPNOTSUPP;
+#ifdef NEED_MII
+	{
+	struct usbnet *dev = (struct usbnet *)net->priv;
+
+	if (dev->mii.mdio_read != NULL && dev->mii.mdio_write != NULL)
+		return generic_mii_ioctl(&dev->mii,
+				(struct mii_ioctl_data *) &rq->ifr_data,
+				cmd, NULL);
 	}
+#endif
+	return -EOPNOTSUPP;
 }
 
 /*-------------------------------------------------------------------------*/
@@ -2155,6 +2448,7 @@
 	struct net_device 		*net;
 	struct driver_info		*info;
 	int				altnum = 0;
+	int				status;
 
 	info = (struct driver_info *) prod->driver_info;
 
@@ -2221,22 +2515,27 @@
 	net->watchdog_timeo = TX_TIMEOUT_JIFFIES;
 	net->tx_timeout = usbnet_tx_timeout;
 	net->do_ioctl = usbnet_ioctl;
+	net->ethtool_ops = &usbnet_ethtool_ops;
 
-	// get rx/tx params from descriptors; avoid compiled-in details
-	if (!info->in || !info->out) {
-		int status = get_endpoints (dev,
-					udev->actconfig->interface + ifnum);
-		if (status < 0) {
-			err ("get_endpoints failed, %d", status);
-			kfree (dev);
-			return 0;
-		}
-	} else {
+	// allow device-specific bind/init procedures
+	// NOTE net->name still not usable ...
+	if (info->bind) {
+		status = info->bind (dev, udev);
+		// heuristic:  "usb%d" for links we know are two-host,
+		// else "eth%d" when there's reasonable doubt.  userspace
+		// can rename the link if it knows better.
+		if ((dev->driver_info->flags & FLAG_ETHER) != 0
+				&& (net->dev_addr [0] & 0x02) == 0)
+			strcpy (net->name, "eth%d");
+	} else if (!info->in || info->out)
+		status = get_endpoints (dev, udev->actconfig->interface + ifnum);
+	else {
 		dev->in = usb_rcvbulkpipe (udev, info->in);
 		dev->out = usb_sndbulkpipe (udev, info->out);
-		dev->maxpacket = info->epsize;
 	}
 
+	dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
+
 	register_netdev (&dev->net);
 	devinfo (dev, "register usbnet usb-%s-%s, %s",
 		udev->bus->bus_name, udev->devpath,
@@ -2274,6 +2573,30 @@
 },
 #endif
 
+#ifdef CONFIG_USB_AX8817X
+{
+	// Linksys USB200M
+	USB_DEVICE (0x077b, 0x2226),
+	.driver_info =	(unsigned long) &ax8817x_info,
+}, {
+	// Netgear FA120
+	USB_DEVICE (0x0846, 0x1040),
+	.driver_info =	(unsigned long) &netgear_fa120_info,
+}, {
+	// DLink DUB-E100
+	USB_DEVICE (0x2001, 0x1a00),
+	.driver_info =	(unsigned long) &dlink_dub_e100_info,
+}, {
+	// Intellinet, ST Lab USB Ethernet
+	USB_DEVICE (0x0b95, 0x1720),
+	.driver_info =	(unsigned long) &ax8817x_info,
+}, {
+	// Hawking UF200, TrendNet TU2-ET100
+	USB_DEVICE (0x07b8, 0x420a),
+	.driver_info =	(unsigned long) &hawking_uf200_info,
+}, 
+#endif
+
 #ifdef	CONFIG_USB_BELKIN
 {
 	USB_DEVICE (0x050d, 0x0004),	// Belkin
@@ -2415,6 +2738,13 @@
 	.disconnect =	usbnet_disconnect,
 };
 
+/* Default ethtool_ops assigned.  Devices can override in their bind() routine */
+static struct ethtool_ops usbnet_ethtool_ops = {
+	.get_drvinfo		= usbnet_get_drvinfo,
+	.get_link		= usbnet_get_link,
+	.get_msglevel		= usbnet_get_msglevel,
+	.set_msglevel		= usbnet_set_msglevel,
+};
 /*-------------------------------------------------------------------------*/
 
 static int __init usbnet_init (void)
diff -urN linux-2.4.23-pre6/drivers/usb/vicam.c linux-2.4.23-pre7/drivers/usb/vicam.c
--- linux-2.4.23-pre6/drivers/usb/vicam.c	2003-10-09 17:48:18.000000000 -0700
+++ linux-2.4.23-pre7/drivers/usb/vicam.c	2003-10-09 17:48:22.000000000 -0700
@@ -1004,8 +1004,10 @@
 	if (count > cam->framebuf_size)
 		count = cam->framebuf_size;
 
-	if (copy_to_user(buf, cam->framebuf, count))
+	if (copy_to_user(buf, cam->framebuf, count)) {
+		up(&cam->busy_lock);
 		return -EFAULT;
+	}
 
 	if (count != cam->framebuf_size)
 		cam->framebuf_read_start = count;
diff -urN linux-2.4.23-pre6/drivers/video/q40fb.c linux-2.4.23-pre7/drivers/video/q40fb.c
--- linux-2.4.23-pre6/drivers/video/q40fb.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/drivers/video/q40fb.c	2003-10-09 17:48:22.000000000 -0700
@@ -148,6 +148,8 @@
 		return -EINVAL;
 	if(var->activate!=FB_ACTIVATE_NOW)
 		return -EINVAL;
+// ignore broken tools trying to set these values
+#if 0
 	if(var->pixclock!=0)
 		return -EINVAL;
 	if(var->left_margin!=0)
@@ -162,6 +164,7 @@
 		return -EINVAL;
 	if(var->vmode!=FB_VMODE_NONINTERLACED)
 		return -EINVAL;
+#endif
 
 	return 0;
 
diff -urN linux-2.4.23-pre6/fs/Config.in linux-2.4.23-pre7/fs/Config.in
--- linux-2.4.23-pre6/fs/Config.in	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.23-pre7/fs/Config.in	2003-10-09 17:48:22.000000000 -0700
@@ -72,9 +72,13 @@
 
 bool '/proc file system support' CONFIG_PROC_FS
 
+# For some reason devfs corrupts memory badly on x86-64. Disable it 
+# for now.
+if [ "$CONFIG_X86_64" != "y" ] ; then
 dep_bool '/dev file system support (EXPERIMENTAL)' CONFIG_DEVFS_FS $CONFIG_EXPERIMENTAL
 dep_bool '  Automatically mount at boot' CONFIG_DEVFS_MOUNT $CONFIG_DEVFS_FS
 dep_bool '  Debug devfs' CONFIG_DEVFS_DEBUG $CONFIG_DEVFS_FS
+fi
 
 # It compiles as a module for testing only.  It should not be used
 # as a module in general.  If we make this "tristate", a bunch of people
diff -urN linux-2.4.23-pre6/fs/buffer.c linux-2.4.23-pre7/fs/buffer.c
--- linux-2.4.23-pre6/fs/buffer.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/fs/buffer.c	2003-10-09 17:48:22.000000000 -0700
@@ -88,6 +88,13 @@
 static int osync_buffers_list(struct list_head *);
 static void __refile_buffer(struct buffer_head *);
 
+/*
+ * A global sysctl-controlled flag which puts the machine into "laptop mode"
+ */
+int laptop_mode;
+
+static DECLARE_WAIT_QUEUE_HEAD(kupdate_wait);
+
 /* This is used by some architectures to estimate available memory. */
 atomic_t buffermem_pages = ATOMIC_INIT(0);
 
@@ -1016,7 +1023,7 @@
 	dirty *= 100;
 	dirty_limit = tot * bdf_prm.b_un.nfract_stop_bdflush;
 
-	if (dirty > dirty_limit)
+	if (!laptop_mode && dirty > dirty_limit)
 		return 0;
 	return 1;
 }
@@ -1066,6 +1073,8 @@
 void mark_buffer_dirty(struct buffer_head *bh)
 {
 	if (!atomic_set_buffer_dirty(bh)) {
+		if (block_dump)
+			printk("%s: dirtied buffer\n", current->comm);
 		__mark_dirty(bh);
 		balance_dirty();
 	}
@@ -1077,6 +1086,12 @@
 }
 EXPORT_SYMBOL(set_buffer_flushtime);
 
+inline int get_buffer_flushtime(void)
+{
+	return bdf_prm.b_un.interval;
+}
+EXPORT_SYMBOL(get_buffer_flushtime);
+
 /*
  * A buffer may need to be moved from one buffer list to another
  * (e.g. in case it is not shared any more). Handle this.
@@ -2860,6 +2875,12 @@
 	wake_up_interruptible(&bdflush_wait);
 }
 
+void wakeup_kupdate(void)
+{
+	if (waitqueue_active(&kupdate_wait))
+		wake_up(&kupdate_wait);
+}
+
 /* 
  * Here we attempt to write back old buffers.  We also try to flush inodes 
  * and supers as well, since this function is essentially "update", and 
@@ -2880,7 +2901,9 @@
 
 		spin_lock(&lru_list_lock);
 		bh = lru_list[BUF_DIRTY];
-		if (!bh || time_before(jiffies, bh->b_flushtime))
+		if (!bh)
+			break;
+		if (time_before(jiffies, bh->b_flushtime) && !laptop_mode)
 			break;
 		if (write_some_buffers(NODEV))
 			continue;
@@ -3028,33 +3051,41 @@
 	complete((struct completion *)startup);
 
 	for (;;) {
+		DECLARE_WAITQUEUE(wait, tsk);
+
+		add_wait_queue(&kupdate_wait, &wait);
+
 		/* update interval */
 		interval = bdf_prm.b_un.interval;
 		if (interval) {
 			tsk->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(interval);
 		} else {
-		stop_kupdate:
 			tsk->state = TASK_STOPPED;
 			schedule(); /* wait for SIGCONT */
 		}
+		remove_wait_queue(&kupdate_wait, &wait);
 		/* check for sigstop */
 		if (signal_pending(tsk)) {
-			int stopped = 0;
+			int sig, stopped = 0;
+			struct siginfo info;
+
 			spin_lock_irq(&tsk->sigmask_lock);
-			if (sigismember(&tsk->pending.signal, SIGSTOP)) {
-				sigdelset(&tsk->pending.signal, SIGSTOP);
+			sig = dequeue_signal(&current->blocked, &info);
+			if (sig == SIGSTOP)
 				stopped = 1;
-			}
-			recalc_sigpending(tsk);
 			spin_unlock_irq(&tsk->sigmask_lock);
-			if (stopped)
-				goto stop_kupdate;
+			if (stopped) {
+				tsk->state = TASK_STOPPED;
+				schedule(); /* wait for SIGCONT */
+			}
 		}
 #ifdef DEBUG
 		printk(KERN_DEBUG "kupdate() activated...\n");
 #endif
 		sync_old_buffers();
+		if (laptop_mode)
+			fsync_dev(NODEV);
 		run_task_queue(&tq_disk);
 	}
 }
diff -urN linux-2.4.23-pre6/fs/exec.c linux-2.4.23-pre7/fs/exec.c
--- linux-2.4.23-pre6/fs/exec.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/fs/exec.c	2003-10-09 17:48:22.000000000 -0700
@@ -426,11 +426,6 @@
 	struct mm_struct * mm, * old_mm;
 
 	old_mm = current->mm;
-	if (old_mm && atomic_read(&old_mm->mm_users) == 1) {
-		mm_release();
-		exit_mmap(old_mm);
-		return 0;
-	}
 
 	mm = mm_alloc();
 	if (mm) {
diff -urN linux-2.4.23-pre6/fs/fcntl.c linux-2.4.23-pre7/fs/fcntl.c
--- linux-2.4.23-pre6/fs/fcntl.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/fs/fcntl.c	2003-10-09 17:48:22.000000000 -0700
@@ -11,6 +11,7 @@
 #include <linux/smp_lock.h>
 #include <linux/slab.h>
 #include <linux/iobuf.h>
+#include <linux/ptrace.h>
 
 #include <asm/poll.h>
 #include <asm/siginfo.h>
@@ -293,6 +294,7 @@
 			 * to fix this will be in libc.
 			 */
 			err = filp->f_owner.pid;
+			force_successful_syscall_return();
 			break;
 		case F_SETOWN:
 			lock_kernel();
diff -urN linux-2.4.23-pre6/fs/jbd/journal.c linux-2.4.23-pre7/fs/jbd/journal.c
--- linux-2.4.23-pre6/fs/jbd/journal.c	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.23-pre7/fs/jbd/journal.c	2003-10-09 17:48:22.000000000 -0700
@@ -705,7 +705,7 @@
 	init_MUTEX(&journal->j_checkpoint_sem);
 	init_MUTEX(&journal->j_sem);
 
-	journal->j_commit_interval = (HZ * 5);
+	journal->j_commit_interval = get_buffer_flushtime();
 
 	/* The journal is marked for error until we succeed with recovery! */
 	journal->j_flags = JFS_ABORT;
diff -urN linux-2.4.23-pre6/fs/namespace.c linux-2.4.23-pre7/fs/namespace.c
--- linux-2.4.23-pre6/fs/namespace.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/fs/namespace.c	2003-10-09 17:48:22.000000000 -0700
@@ -110,7 +110,7 @@
 	mnt->mnt_parent = mntget(nd->mnt);
 	mnt->mnt_mountpoint = dget(nd->dentry);
 	list_add(&mnt->mnt_hash, mount_hashtable+hash(nd->mnt, nd->dentry));
-	list_add(&mnt->mnt_child, &nd->mnt->mnt_mounts);
+	list_add_tail(&mnt->mnt_child, &nd->mnt->mnt_mounts);
 	nd->dentry->d_mounted++;
 }
 
diff -urN linux-2.4.23-pre6/fs/proc/base.c linux-2.4.23-pre7/fs/proc/base.c
--- linux-2.4.23-pre6/fs/proc/base.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/fs/proc/base.c	2003-10-09 17:48:22.000000000 -0700
@@ -476,7 +476,24 @@
 }
 #endif
 
+static loff_t mem_lseek(struct file * file, loff_t offset, int orig)
+{
+	switch (orig) {
+	case 0:
+		file->f_pos = offset;
+		break;
+	case 1:
+		file->f_pos += offset;
+		break;
+	default:
+		return -EINVAL;
+	}
+	force_successful_syscall_return();
+	return file->f_pos;
+}
+
 static struct file_operations proc_mem_operations = {
+	llseek:		mem_lseek,
 	read:		mem_read,
 	write:		mem_write,
 	open:		mem_open,
@@ -518,8 +535,10 @@
 		
 	inode = dentry->d_inode;
 	path = d_path(dentry, mnt, tmp, PAGE_SIZE);
-	if (IS_ERR(path))
+	if (IS_ERR(path)) {
+		free_page((unsigned long)tmp);
 		return PTR_ERR(path);
+	}
 	len = tmp + PAGE_SIZE - 1 - path;
 
 	if (len < buflen)
diff -urN linux-2.4.23-pre6/fs/proc/proc_devtree.c linux-2.4.23-pre7/fs/proc/proc_devtree.c
--- linux-2.4.23-pre6/fs/proc/proc_devtree.c	2000-05-21 20:34:37.000000000 -0700
+++ linux-2.4.23-pre7/fs/proc/proc_devtree.c	2003-10-09 17:48:22.000000000 -0700
@@ -59,11 +59,14 @@
 		 * Unfortunately proc_register puts each new entry
 		 * at the beginning of the list.  So we rearrange them.
 		 */
-		ent = create_proc_read_entry(pp->name, S_IRUGO, de,
-					     property_read_proc, pp);
+		ent = create_proc_read_entry(pp->name, strncmp(pp->name, "security-", 9) ?
+					     S_IRUGO : S_IRUSR, de, property_read_proc, pp);
 		if (ent == 0)
 			break;
-		ent->size = pp->length;
+		if (!strncmp(pp->name, "security-", 9))
+		     ent->size = 0; /* don't leak number of password chars */
+		else
+		     ent->size = pp->length;
 		*lastp = ent;
 		lastp = &ent->next;
 	}
diff -urN linux-2.4.23-pre6/fs/proc/proc_misc.c linux-2.4.23-pre7/fs/proc/proc_misc.c
--- linux-2.4.23-pre6/fs/proc/proc_misc.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/fs/proc/proc_misc.c	2003-10-09 17:48:22.000000000 -0700
@@ -430,6 +430,9 @@
 };
 #endif /* !CONFIG_X86 */
 
+extern struct file_operations proc_ioports_operations;
+extern struct file_operations proc_iomem_operations;
+
 static int filesystems_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -444,13 +447,6 @@
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-static int ioports_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = get_ioport_list(page);
-	return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
 static int cmdline_read_proc(char *page, char **start, off_t off,
 				 int count, int *eof, void *data)
 {
@@ -495,13 +491,6 @@
 	return proc_calc_metrics(page, start, off, count, eof, len);
 }
 
-static int memory_read_proc(char *page, char **start, off_t off,
-				 int count, int *eof, void *data)
-{
-	int len = get_mem_list(page);
-	return proc_calc_metrics(page, start, off, count, eof, len);
-}
-
 /*
  * This function accesses profiling information. The returned data is
  * binary: the sampling step and the actual contents of the profile
@@ -625,14 +614,12 @@
 #endif
 		{"filesystems",	filesystems_read_proc},
 		{"dma",		dma_read_proc},
-		{"ioports",	ioports_read_proc},
 		{"cmdline",	cmdline_read_proc},
 #ifdef CONFIG_SGI_DS1286
 		{"rtc",		ds1286_read_proc},
 #endif
 		{"locks",	locks_read_proc},
 		{"swaps",	swaps_read_proc},
-		{"iomem",	memory_read_proc},
 		{"execdomains",	execdomains_read_proc},
 		{NULL,}
 	};
@@ -649,6 +636,8 @@
 #if defined(CONFIG_X86)
 	create_seq_entry("interrupts", 0, &proc_interrupts_operations);
 #endif
+	create_seq_entry("ioports", 0, &proc_ioports_operations);
+	create_seq_entry("iomem", 0, &proc_iomem_operations);
 	create_seq_entry("partitions", 0, &proc_partitions_operations);
 	create_seq_entry("slabinfo",S_IWUSR|S_IRUGO,&proc_slabinfo_operations);
 #ifdef CONFIG_MODULES
diff -urN linux-2.4.23-pre6/fs/quota_v1.c linux-2.4.23-pre7/fs/quota_v1.c
--- linux-2.4.23-pre6/fs/quota_v1.c	2003-08-25 04:44:43.000000000 -0700
+++ linux-2.4.23-pre7/fs/quota_v1.c	2003-10-09 17:48:22.000000000 -0700
@@ -17,7 +17,7 @@
 	m->dqb_curinodes = d->dqb_curinodes;
 	m->dqb_bhardlimit = d->dqb_bhardlimit;
 	m->dqb_bsoftlimit = d->dqb_bsoftlimit;
-	m->dqb_curspace = d->dqb_curblocks << QUOTABLOCK_BITS;
+	m->dqb_curspace = ((qsize_t)d->dqb_curblocks) << QUOTABLOCK_BITS;
 	m->dqb_itime = d->dqb_itime;
 	m->dqb_btime = d->dqb_btime;
 }
diff -urN linux-2.4.23-pre6/include/asm-alpha/ptrace.h linux-2.4.23-pre7/include/asm-alpha/ptrace.h
--- linux-2.4.23-pre6/include/asm-alpha/ptrace.h	1999-07-12 07:49:36.000000000 -0700
+++ linux-2.4.23-pre7/include/asm-alpha/ptrace.h	2003-10-09 17:48:22.000000000 -0700
@@ -70,6 +70,12 @@
 #define user_mode(regs) (((regs)->ps & 8) != 0)
 #define instruction_pointer(regs) ((regs)->pc)
 extern void show_regs(struct pt_regs *);
+
+#define alpha_task_regs(task) \
+  ((struct pt_regs *)((long)(task) + 2*PAGE_SIZE) - 1)
+
+#define force_successful_syscall_return() (alpha_task_regs(current)->r0 = 0)
+
 #endif
 
 #endif
diff -urN linux-2.4.23-pre6/include/asm-i386/edd.h linux-2.4.23-pre7/include/asm-i386/edd.h
--- linux-2.4.23-pre6/include/asm-i386/edd.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/include/asm-i386/edd.h	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,172 @@
+/*
+ * linux/include/asm-i386/edd.h
+ *  Copyright (C) 2002 Dell Computer Corporation
+ *  by Matt Domsch <Matt_Domsch@dell.com>
+ *
+ * structures and definitions for the int 13h, ax={41,48}h
+ * BIOS Enhanced Disk Drive Services
+ * This is based on the T13 group document D1572 Revision 0 (August 14 2002)
+ * available at http://www.t13.org/docs2002/d1572r0.pdf.  It is
+ * very similar to D1484 Revision 3 http://www.t13.org/docs2002/d1484r3.pdf
+ *
+ * In a nutshell, arch/i386/boot/setup.S populates a scratch table
+ * in the empty_zero_block that contains a list of BIOS-enumerated
+ * boot devices.
+ * In arch/i386/kernel/setup.c, this information is
+ * transferred into the edd structure, and in arch/i386/kernel/edd.c, that
+ * information is used to identify BIOS boot disk.  The code in setup.S
+ * is very sensitive to the size of these structures.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License v2.0 as published by
+ * the Free Software Foundation
+ *
+ * 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 _ASM_I386_EDD_H
+#define _ASM_I386_EDD_H
+
+#define EDDNR 0x1e9		/* addr of number of edd_info structs at EDDBUF
+				   in empty_zero_block - treat this as 1 byte  */
+#define EDDBUF	0x600		/* addr of edd_info structs in empty_zero_block */
+#define EDDMAXNR 6		/* number of edd_info structs starting at EDDBUF  */
+#define EDDEXTSIZE 4		/* change these if you muck with the structures */
+#define EDDPARMSIZE 74
+#define CHECKEXTENSIONSPRESENT 0x41
+#define GETDEVICEPARAMETERS 0x48
+#define EDDMAGIC1 0x55AA
+#define EDDMAGIC2 0xAA55
+
+#ifndef __ASSEMBLY__
+
+#define EDD_EXT_FIXED_DISK_ACCESS           (1 << 0)
+#define EDD_EXT_DEVICE_LOCKING_AND_EJECTING (1 << 1)
+#define EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT (1 << 2)
+#define EDD_EXT_64BIT_EXTENSIONS            (1 << 3)
+
+#define EDD_INFO_DMA_BOUNDRY_ERROR_TRANSPARENT (1 << 0)
+#define EDD_INFO_GEOMETRY_VALID                (1 << 1)
+#define EDD_INFO_REMOVABLE                     (1 << 2)
+#define EDD_INFO_WRITE_VERIFY                  (1 << 3)
+#define EDD_INFO_MEDIA_CHANGE_NOTIFICATION     (1 << 4)
+#define EDD_INFO_LOCKABLE                      (1 << 5)
+#define EDD_INFO_NO_MEDIA_PRESENT              (1 << 6)
+#define EDD_INFO_USE_INT13_FN50                (1 << 7)
+
+struct edd_device_params {
+	u16 length;
+	u16 info_flags;
+	u32 num_default_cylinders;
+	u32 num_default_heads;
+	u32 sectors_per_track;
+	u64 number_of_sectors;
+	u16 bytes_per_sector;
+	u32 dpte_ptr;		/* 0xFFFFFFFF for our purposes */
+	u16 key;		/* = 0xBEDD */
+	u8 device_path_info_length;	/* = 44 */
+	u8 reserved2;
+	u16 reserved3;
+	u8 host_bus_type[4];
+	u8 interface_type[8];
+	union {
+		struct {
+			u16 base_address;
+			u16 reserved1;
+			u32 reserved2;
+		} __attribute__ ((packed)) isa;
+		struct {
+			u8 bus;
+			u8 slot;
+			u8 function;
+			u8 channel;
+			u32 reserved;
+		} __attribute__ ((packed)) pci;
+		/* pcix is same as pci */
+		struct {
+			u64 reserved;
+		} __attribute__ ((packed)) ibnd;
+		struct {
+			u64 reserved;
+		} __attribute__ ((packed)) xprs;
+		struct {
+			u64 reserved;
+		} __attribute__ ((packed)) htpt;
+		struct {
+			u64 reserved;
+		} __attribute__ ((packed)) unknown;
+	} interface_path;
+	union {
+		struct {
+			u8 device;
+			u8 reserved1;
+			u16 reserved2;
+			u32 reserved3;
+			u64 reserved4;
+		} __attribute__ ((packed)) ata;
+		struct {
+			u8 device;
+			u8 lun;
+			u8 reserved1;
+			u8 reserved2;
+			u32 reserved3;
+			u64 reserved4;
+		} __attribute__ ((packed)) atapi;
+		struct {
+			u16 id;
+			u64 lun;
+			u16 reserved1;
+			u32 reserved2;
+		} __attribute__ ((packed)) scsi;
+		struct {
+			u64 serial_number;
+			u64 reserved;
+		} __attribute__ ((packed)) usb;
+		struct {
+			u64 eui;
+			u64 reserved;
+		} __attribute__ ((packed)) i1394;
+		struct {
+			u64 wwid;
+			u64 lun;
+		} __attribute__ ((packed)) fibre;
+		struct {
+			u64 identity_tag;
+			u64 reserved;
+		} __attribute__ ((packed)) i2o;
+		struct {
+			u32 array_number;
+			u32 reserved1;
+			u64 reserved2;
+		} __attribute((packed)) raid;
+		struct {
+			u8 device;
+			u8 reserved1;
+			u16 reserved2;
+			u32 reserved3;
+			u64 reserved4;
+		} __attribute__ ((packed)) sata;
+		struct {
+			u64 reserved1;
+			u64 reserved2;
+		} __attribute__ ((packed)) unknown;
+	} device_path;
+	u8 reserved4;
+	u8 checksum;
+} __attribute__ ((packed));
+
+struct edd_info {
+	u8 device;
+	u8 version;
+	u16 interface_support;
+	struct edd_device_params params;
+} __attribute__ ((packed));
+
+extern struct edd_info edd[EDDMAXNR];
+extern unsigned char eddnr;
+#endif				/*!__ASSEMBLY__ */
+
+#endif				/* _ASM_I386_EDD_H */
diff -urN linux-2.4.23-pre6/include/asm-ia64/ptrace.h linux-2.4.23-pre7/include/asm-ia64/ptrace.h
--- linux-2.4.23-pre6/include/asm-ia64/ptrace.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/asm-ia64/ptrace.h	2003-10-09 17:48:22.000000000 -0700
@@ -248,11 +248,10 @@
   extern void ia64_increment_ip (struct pt_regs *pt);
   extern void ia64_decrement_ip (struct pt_regs *pt);
 
-static inline void
-force_successful_syscall_return (void)
-{
-	ia64_task_regs(current)->r8 = 0;
-}
+#define force_successful_syscall_return()		\
+	do {						\
+		ia64_task_regs(current)->r8 = 0;	\
+	} while (0)
 
 #endif /* !__KERNEL__ */
 
diff -urN linux-2.4.23-pre6/include/asm-m68k/dvma.h linux-2.4.23-pre7/include/asm-m68k/dvma.h
--- linux-2.4.23-pre6/include/asm-m68k/dvma.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.23-pre7/include/asm-m68k/dvma.h	2003-10-09 17:48:22.000000000 -0700
@@ -110,7 +110,7 @@
 /* Linux DMA information structure, filled during probe. */
 struct Linux_SBus_DMA {
 	struct Linux_SBus_DMA *next;
-	struct linux_sbus_device *SBus_dev;
+	struct sbus_dev *SBus_dev;
 	struct sparc_dma_registers *regs;
 
 	/* Status, misc info */
diff -urN linux-2.4.23-pre6/include/asm-m68k/system.h linux-2.4.23-pre7/include/asm-m68k/system.h
--- linux-2.4.23-pre6/include/asm-m68k/system.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.23-pre7/include/asm-m68k/system.h	2003-10-09 17:48:22.000000000 -0700
@@ -42,8 +42,9 @@
   register void *_next __asm__ ("a1") = (next); \
   register void *_last __asm__ ("d1"); \
   __asm__ __volatile__("jbsr " SYMBOL_NAME_STR(resume) \
-		       : "=d" (_last) : "a" (_prev), "a" (_next) \
-		       : "d0", /* "d1", */ "d2", "d3", "d4", "d5", "a0", "a1"); \
+		       : "=a" (_prev), "=a" (_next), "=d" (_last) \
+		       : "0" (_prev), "1" (_next)		  \
+		       : "d0", "d2", "d3", "d4", "d5"); \
   (last) = _last; \
 }
 
diff -urN linux-2.4.23-pre6/include/asm-x86_64/acpi.h linux-2.4.23-pre7/include/asm-x86_64/acpi.h
--- linux-2.4.23-pre6/include/asm-x86_64/acpi.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/asm-x86_64/acpi.h	2003-10-09 17:48:22.000000000 -0700
@@ -115,18 +115,6 @@
 #endif
 #ifdef CONFIG_X86_IO_APIC
 extern int acpi_ioapic;
-extern int skip_ioapic_setup;
-
-static inline void disable_ioapic_setup(void)
-{
-	
-	skip_ioapic_setup = 1;
-}
-
-static inline int ioapic_setup_disabled(void)
-{
-	return skip_ioapic_setup;
-}
 #else
 static inline void disable_ioapic_setup(void)
 { }
diff -urN linux-2.4.23-pre6/include/asm-x86_64/apic.h linux-2.4.23-pre7/include/asm-x86_64/apic.h
--- linux-2.4.23-pre6/include/asm-x86_64/apic.h	2003-06-13 07:51:38.000000000 -0700
+++ linux-2.4.23-pre7/include/asm-x86_64/apic.h	2003-10-09 17:48:22.000000000 -0700
@@ -102,4 +102,17 @@
 #define esr_disable 0
 extern unsigned boot_cpu_id;
 
+extern int skip_ioapic_setup;
+
+static inline void disable_ioapic_setup(void)
+{
+	
+	skip_ioapic_setup = 1;
+}
+
+static inline int ioapic_setup_disabled(void)
+{
+	return skip_ioapic_setup;
+}
+
 #endif /* __ASM_APIC_H */
diff -urN linux-2.4.23-pre6/include/linux/fs.h linux-2.4.23-pre7/include/linux/fs.h
--- linux-2.4.23-pre6/include/linux/fs.h	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/fs.h	2003-10-09 17:48:22.000000000 -0700
@@ -1255,6 +1255,7 @@
 }
 
 extern void set_buffer_flushtime(struct buffer_head *);
+extern inline int get_buffer_flushtime(void);
 extern void balance_dirty(void);
 extern int check_disk_change(kdev_t);
 extern int invalidate_inodes(struct super_block *);
@@ -1445,8 +1446,10 @@
 	return get_hash_table(sb->s_dev, block, sb->s_blocksize);
 }
 extern void wakeup_bdflush(void);
+extern void wakeup_kupdate(void);
 extern void put_unused_buffer_head(struct buffer_head * bh);
 extern struct buffer_head * get_unused_buffer_head(int async);
+extern int block_dump;
 
 extern int brw_page(int, struct page *, kdev_t, int [], int);
 
diff -urN linux-2.4.23-pre6/include/linux/in.h linux-2.4.23-pre7/include/linux/in.h
--- linux-2.4.23-pre6/include/linux/in.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/in.h	2003-10-09 17:48:22.000000000 -0700
@@ -137,29 +137,29 @@
 
 struct group_req
 {
-	__u32			gr_interface;	/* interface index */
-	struct sockaddr_storage	gr_group;	/* group address */
+	__u32				 gr_interface;	/* interface index */
+	struct __kernel_sockaddr_storage gr_group;	/* group address */
 };
 
 struct group_source_req
 {
-	__u32			gsr_interface;	/* interface index */
-	struct sockaddr_storage	gsr_group;	/* group address */
-	struct sockaddr_storage	gsr_source;	/* source address */
+	__u32				 gsr_interface;	/* interface index */
+	struct __kernel_sockaddr_storage gsr_group;	/* group address */
+	struct __kernel_sockaddr_storage gsr_source;	/* source address */
 };
 
 struct group_filter
 {
-	__u32			gf_interface;	/* interface index */
-	struct sockaddr_storage	gf_group;	/* multicast address */
-	__u32			gf_fmode;	/* filter mode */
-	__u32			gf_numsrc;	/* number of sources */
-	struct sockaddr_storage	gf_slist[1];	/* interface index */
+	__u32				 gf_interface;	/* interface index */
+	struct __kernel_sockaddr_storage gf_group;	/* multicast address */
+	__u32				 gf_fmode;	/* filter mode */
+	__u32				 gf_numsrc;	/* number of sources */
+	struct __kernel_sockaddr_storage gf_slist[1];	/* interface index */
 };
 
 #define GROUP_FILTER_SIZE(numsrc) \
-	(sizeof(struct group_filter) - sizeof(struct sockaddr_storage) \
-	+ (numsrc) * sizeof(struct sockaddr_storage))
+	(sizeof(struct group_filter) - sizeof(struct __kernel_sockaddr_storage) \
+	+ (numsrc) * sizeof(struct __kernel_sockaddr_storage))
 
 struct in_pktinfo
 {
diff -urN linux-2.4.23-pre6/include/linux/ioport.h linux-2.4.23-pre7/include/linux/ioport.h
--- linux-2.4.23-pre6/include/linux/ioport.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/include/linux/ioport.h	2003-10-09 17:48:22.000000000 -0700
@@ -83,8 +83,6 @@
 extern struct resource ioport_resource;
 extern struct resource iomem_resource;
 
-extern int get_resource_list(struct resource *, char *buf, int size);
-
 extern int check_resource(struct resource *root, unsigned long, unsigned long);
 extern int request_resource(struct resource *root, struct resource *new);
 extern int release_resource(struct resource *new);
@@ -111,9 +109,6 @@
 extern int __check_region(struct resource *, unsigned long, unsigned long);
 extern void __release_region(struct resource *, unsigned long, unsigned long);
 
-#define get_ioport_list(buf)	get_resource_list(&ioport_resource, buf, PAGE_SIZE)
-#define get_mem_list(buf)	get_resource_list(&iomem_resource, buf, PAGE_SIZE)
-
 #define HAVE_AUTOIRQ
 extern void autoirq_setup(int waittime);
 extern int autoirq_report(int waittime);
diff -urN linux-2.4.23-pre6/include/linux/mm.h linux-2.4.23-pre7/include/linux/mm.h
--- linux-2.4.23-pre6/include/linux/mm.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/mm.h	2003-10-09 17:48:22.000000000 -0700
@@ -322,9 +322,11 @@
 #define TryLockPage(page)	test_and_set_bit(PG_locked, &(page)->flags)
 #define PageChecked(page)	test_bit(PG_checked, &(page)->flags)
 #define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
+#define ClearPageChecked(page)	clear_bit(PG_checked, &(page)->flags)
 #define PageLaunder(page)	test_bit(PG_launder, &(page)->flags)
 #define SetPageLaunder(page)	set_bit(PG_launder, &(page)->flags)
 #define ClearPageLaunder(page)	clear_bit(PG_launder, &(page)->flags)
+#define ClearPageArch1(page)	clear_bit(PG_arch_1, &(page)->flags)
 
 /*
  * The zone field is never updated after free_area_init_core()
diff -urN linux-2.4.23-pre6/include/linux/netdevice.h linux-2.4.23-pre7/include/linux/netdevice.h
--- linux-2.4.23-pre6/include/linux/netdevice.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/netdevice.h	2003-10-09 17:48:22.000000000 -0700
@@ -204,7 +204,7 @@
 	(HH_DATA_MOD - ((__len) & (HH_DATA_MOD - 1)))
 #define HH_DATA_ALIGN(__len) \
 	(((__len)+(HH_DATA_MOD-1))&~(HH_DATA_MOD - 1))
-	unsigned long	hh_data[HH_DATA_ALIGN(LL_MAX_HEADER)];
+	unsigned long	hh_data[HH_DATA_ALIGN(LL_MAX_HEADER) / sizeof(long)];
 };
 
 /* These flag bits are private to the generic network queueing
diff -urN linux-2.4.23-pre6/include/linux/netfilter_ipv4/ip_conntrack_tuple.h linux-2.4.23-pre7/include/linux/netfilter_ipv4/ip_conntrack_tuple.h
--- linux-2.4.23-pre6/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2002-02-25 11:38:13.000000000 -0800
+++ linux-2.4.23-pre7/include/linux/netfilter_ipv4/ip_conntrack_tuple.h	2003-10-09 17:48:22.000000000 -0700
@@ -62,6 +62,14 @@
 	} dst;
 };
 
+/* This is optimized opposed to a memset of the whole structure.  Everything we
+ * really care about is the  source/destination unions */
+#define IP_CT_TUPLE_U_BLANK(tuple) 				\
+	do {							\
+		(tuple)->src.u.all = 0;				\
+		(tuple)->dst.u.all = 0;				\
+	} while (0)
+
 enum ip_conntrack_dir
 {
 	IP_CT_DIR_ORIGINAL,
diff -urN linux-2.4.23-pre6/include/linux/netfilter_ipv4/ip_nat_rule.h linux-2.4.23-pre7/include/linux/netfilter_ipv4/ip_nat_rule.h
--- linux-2.4.23-pre6/include/linux/netfilter_ipv4/ip_nat_rule.h	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/include/linux/netfilter_ipv4/ip_nat_rule.h	2003-10-09 17:48:22.000000000 -0700
@@ -14,5 +14,10 @@
 			    const struct net_device *out,
 			    struct ip_conntrack *ct,
 			    struct ip_nat_info *info);
+
+extern unsigned int
+alloc_null_binding(struct ip_conntrack *conntrack,
+		   struct ip_nat_info *info,
+		   unsigned int hooknum);
 #endif
 #endif /* _IP_NAT_RULE_H */
diff -urN linux-2.4.23-pre6/include/linux/pci.h linux-2.4.23-pre7/include/linux/pci.h
--- linux-2.4.23-pre6/include/linux/pci.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/pci.h	2003-10-09 17:48:22.000000000 -0700
@@ -628,7 +628,6 @@
 #define HAVE_PCI_SET_MWI
 int pci_set_mwi(struct pci_dev *dev);
 void pci_clear_mwi(struct pci_dev *dev);
-int pci_generic_prep_mwi(struct pci_dev *dev);
 int pci_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_dac_set_dma_mask(struct pci_dev *dev, u64 mask);
 int pci_assign_resource(struct pci_dev *dev, int i);
diff -urN linux-2.4.23-pre6/include/linux/ptrace.h linux-2.4.23-pre7/include/linux/ptrace.h
--- linux-2.4.23-pre6/include/linux/ptrace.h	2001-09-14 15:55:17.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/ptrace.h	2003-10-09 17:48:22.000000000 -0700
@@ -23,4 +23,22 @@
 
 #include <asm/ptrace.h>
 
+#ifdef __KERNEL__
+
+#ifndef force_successful_syscall_return
+/*
+ * System call handlers that, upon successful completion, need to return a
+ * negative value should call force_successful_syscall_return() right before
+ * returning.  On architectures where the syscall convention provides for a
+ * separate error flag (e.g., alpha, ia64, ppc{,64}, sparc{,64}, possibly
+ * others), this macro can be used to ensure that the error flag will not get
+ * set.  On architectures which do not support a separate error flag, the macro
+ * is a no-op and the spurious error condition needs to be filtered out by some
+ * other means (e.g., in user-level, by passing an extra argument to the
+ * syscall handler, or something along those lines).
+ */
+#define force_successful_syscall_return() do { } while (0)
+#endif
+#endif
+
 #endif
diff -urN linux-2.4.23-pre6/include/linux/socket.h linux-2.4.23-pre7/include/linux/socket.h
--- linux-2.4.23-pre6/include/linux/socket.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/socket.h	2003-10-09 17:48:22.000000000 -0700
@@ -1,6 +1,21 @@
 #ifndef _LINUX_SOCKET_H
 #define _LINUX_SOCKET_H
 
+/*
+ * Desired design of maximum size and alignment (see RFC2553)
+ */
+#define _K_SS_MAXSIZE	128	/* Implementation specific max size */
+#define _K_SS_ALIGNSIZE	(__alignof__ (struct sockaddr *))
+				/* Implementation specific desired alignment */
+
+struct __kernel_sockaddr_storage {
+	unsigned short	ss_family;		/* address family */
+	/* Following field(s) are implementation specific */
+	char		__data[_K_SS_MAXSIZE - sizeof(unsigned short)];
+				/* space to achieve desired size, */
+				/* _SS_MAXSIZE value minus size of ss_family */
+} __attribute__ ((aligned(_K_SS_ALIGNSIZE)));	/* force desired alignment */
+
 #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)
 
 #include <asm/socket.h>			/* arch-dependent defines	*/
@@ -24,20 +39,7 @@
 	int		l_linger;	/* How long to linger for	*/
 };
 
-/*
- * Desired design of maximum size and alignment (see RFC2553)
- */
-#define _SS_MAXSIZE	128	/* Implementation specific max size */
-#define _SS_ALIGNSIZE	(__alignof__ (struct sockaddr *))
-				/* Implementation specific desired alignment */
-
-struct sockaddr_storage {
-	sa_family_t	ss_family;		/* address family */
-	/* Following field(s) are implementation specific */
-	char		__data[_SS_MAXSIZE - sizeof(sa_family_t)];
-				/* space to achieve desired size, */
-				/* _SS_MAXSIZE value minus size of ss_family */
-} __attribute__ ((aligned(_SS_ALIGNSIZE)));	/* force desired alignment */
+#define sockaddr_storage __kernel_sockaddr_storage
 
 /*
  *	As we do 4.4BSD message passing we use a 4.4BSD message passing
diff -urN linux-2.4.23-pre6/include/linux/sysctl.h linux-2.4.23-pre7/include/linux/sysctl.h
--- linux-2.4.23-pre6/include/linux/sysctl.h	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/sysctl.h	2003-10-09 17:48:22.000000000 -0700
@@ -154,6 +154,8 @@
 	VM_GFP_DEBUG=18,        /* debug GFP failures */
 	VM_CACHE_SCAN_RATIO=19, /* part of the inactive cache list to scan */
 	VM_MAPPED_RATIO=20,     /* amount of unfreeable pages that triggers swapout */
+	VM_LAPTOP_MODE=21,	/* kernel in laptop flush mode */
+	VM_BLOCK_DUMP=22,	/* dump fs activity to log */
 };
 
 
@@ -245,6 +247,7 @@
 	NET_IPV4_NEIGH=17,
 	NET_IPV4_ROUTE=18,
 	NET_IPV4_FIB_HASH=19,
+	NET_IPV4_NETFILTER=20,
 
 	NET_IPV4_TCP_TIMESTAMPS=33,
 	NET_IPV4_TCP_WINDOW_SCALING=34,
@@ -357,6 +360,24 @@
 	NET_IPV4_CONF_MEDIUM_ID=14,
 };
 
+/* /proc/sys/net/ipv4/netfilter */
+enum
+{
+	NET_IPV4_NF_CONNTRACK_MAX=1,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT=2,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV=3,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED=4,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT=5,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT=6,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK=7,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT=8,
+	NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE=9,
+	NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT=10,
+	NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM=11,
+	NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT=12,
+	NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT=13,
+};
+ 
 /* /proc/sys/net/ipv6 */
 enum {
 	NET_IPV6_CONF=16,
diff -urN linux-2.4.23-pre6/include/linux/usb_ch9.h linux-2.4.23-pre7/include/linux/usb_ch9.h
--- linux-2.4.23-pre6/include/linux/usb_ch9.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/include/linux/usb_ch9.h	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,315 @@
+/*
+ * This file holds USB constants and structures that are needed for USB
+ * device APIs.  These are used by the USB device model, which is defined
+ * in chapter 9 of the USB 2.0 specification.  Linux has several APIs in C
+ * that need these:
+ *
+ * - the master/host side Linux-USB kernel driver API;
+ * - the "usbfs" user space API; and
+ * - (eventually) a Linux "gadget" slave/device side driver API.
+ *
+ * USB 2.0 adds an additional "On The Go" (OTG) mode, which lets systems
+ * act either as a USB master/host or as a USB slave/device.  That means
+ * the master and slave side APIs will benefit from working well together.
+ */
+
+#ifndef __LINUX_USB_CH9_H
+#define __LINUX_USB_CH9_H
+
+#include <asm/types.h>		/* __u8 etc */
+
+/*-------------------------------------------------------------------------*/
+
+/* CONTROL REQUEST SUPPORT */
+
+/*
+ * USB directions
+ *
+ * This bit flag is used in endpoint descriptors' bEndpointAddress field.
+ * It's also one of three fields in control requests bRequestType.
+ */
+#define USB_DIR_OUT			0		/* to device */
+#define USB_DIR_IN			0x80		/* to host */
+
+/*
+ * USB types, the second of three bRequestType fields
+ */
+#define USB_TYPE_MASK			(0x03 << 5)
+#define USB_TYPE_STANDARD		(0x00 << 5)
+#define USB_TYPE_CLASS			(0x01 << 5)
+#define USB_TYPE_VENDOR			(0x02 << 5)
+#define USB_TYPE_RESERVED		(0x03 << 5)
+
+/*
+ * USB recipients, the third of three bRequestType fields
+ */
+#define USB_RECIP_MASK			0x1f
+#define USB_RECIP_DEVICE		0x00
+#define USB_RECIP_INTERFACE		0x01
+#define USB_RECIP_ENDPOINT		0x02
+#define USB_RECIP_OTHER			0x03
+
+/*
+ * Standard requests, for the bRequest field of a SETUP packet.
+ *
+ * These are qualified by the bRequestType field, so that for example
+ * TYPE_CLASS or TYPE_VENDOR specific feature flags could be retrieved
+ * by a GET_STATUS request.
+ */
+#define USB_REQ_GET_STATUS		0x00
+#define USB_REQ_CLEAR_FEATURE		0x01
+#define USB_REQ_SET_FEATURE		0x03
+#define USB_REQ_SET_ADDRESS		0x05
+#define USB_REQ_GET_DESCRIPTOR		0x06
+#define USB_REQ_SET_DESCRIPTOR		0x07
+#define USB_REQ_GET_CONFIGURATION	0x08
+#define USB_REQ_SET_CONFIGURATION	0x09
+#define USB_REQ_GET_INTERFACE		0x0A
+#define USB_REQ_SET_INTERFACE		0x0B
+#define USB_REQ_SYNCH_FRAME		0x0C
+
+
+/**
+ * struct usb_ctrlrequest - SETUP data for a USB device control request
+ * @bRequestType: matches the USB bmRequestType field
+ * @bRequest: matches the USB bRequest field
+ * @wValue: matches the USB wValue field (le16 byte order)
+ * @wIndex: matches the USB wIndex field (le16 byte order)
+ * @wLength: matches the USB wLength field (le16 byte order)
+ *
+ * This structure is used to send control requests to a USB device.  It matches
+ * the different fields of the USB 2.0 Spec section 9.3, table 9-2.  See the
+ * USB spec for a fuller description of the different fields, and what they are
+ * used for.
+ *
+ * Note that the driver for any interface can issue control requests.
+ * For most devices, interfaces don't coordinate with each other, so
+ * such requests may be made at any time.
+ */
+struct usb_ctrlrequest {
+	__u8 bRequestType;
+	__u8 bRequest;
+	__u16 wValue;
+	__u16 wIndex;
+	__u16 wLength;
+} __attribute__ ((packed));
+
+/*-------------------------------------------------------------------------*/
+
+/*
+ * STANDARD DESCRIPTORS ... as returned by GET_DESCRIPTOR, or
+ * (rarely) accepted by SET_DESCRIPTOR.
+ *
+ * Note that all multi-byte values here are encoded in little endian
+ * byte order "on the wire".  But when exposed through Linux-USB APIs,
+ * they've been converted to cpu byte order.
+ */
+
+/*
+ * Descriptor types ... USB 2.0 spec table 9.5
+ */
+#define USB_DT_DEVICE			0x01
+#define USB_DT_CONFIG			0x02
+#define USB_DT_STRING			0x03
+#define USB_DT_INTERFACE		0x04
+#define USB_DT_ENDPOINT			0x05
+#define USB_DT_DEVICE_QUALIFIER		0x06
+#define USB_DT_OTHER_SPEED_CONFIG	0x07
+#define USB_DT_INTERFACE_POWER		0x08
+
+/* All standard descriptors have these 2 fields at the beginning */
+struct usb_descriptor_header {
+	__u8  bLength;
+	__u8  bDescriptorType;
+} __attribute__ ((packed));
+
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_DEVICE: Device descriptor */
+struct usb_device_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u16 bcdUSB;
+	__u8  bDeviceClass;
+	__u8  bDeviceSubClass;
+	__u8  bDeviceProtocol;
+	__u8  bMaxPacketSize0;
+	__u16 idVendor;
+	__u16 idProduct;
+	__u16 bcdDevice;
+	__u8  iManufacturer;
+	__u8  iProduct;
+	__u8  iSerialNumber;
+	__u8  bNumConfigurations;
+} __attribute__ ((packed));
+
+#define USB_DT_DEVICE_SIZE		18
+
+
+/*
+ * Device and/or Interface Class codes
+ * as found in bDeviceClass or bInterfaceClass
+ * and defined by www.usb.org documents
+ */
+#define USB_CLASS_PER_INTERFACE		0	/* for DeviceClass */
+#define USB_CLASS_AUDIO			1
+#define USB_CLASS_COMM			2
+#define USB_CLASS_HID			3
+#define USB_CLASS_PHYSICAL		5
+#define USB_CLASS_STILL_IMAGE		6
+#define USB_CLASS_PRINTER		7
+#define USB_CLASS_MASS_STORAGE		8
+#define USB_CLASS_HUB			9
+#define USB_CLASS_CDC_DATA		0x0a
+#define USB_CLASS_CSCID			0x0b	/* chip+ smart card */
+#define USB_CLASS_CONTENT_SEC		0x0d	/* content security */
+#define USB_CLASS_APP_SPEC		0xfe
+#define USB_CLASS_VENDOR_SPEC		0xff
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_CONFIG: Configuration descriptor information.
+ *
+ * USB_DT_OTHER_SPEED_CONFIG is the same descriptor, except that the
+ * descriptor type is different.  Highspeed-capable devices can look
+ * different depending on what speed they're currently running.  Only
+ * devices with a USB_DT_DEVICE_QUALIFIER have any OTHER_SPEED_CONFIG
+ * descriptors.
+ */
+struct usb_config_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u16 wTotalLength;
+	__u8  bNumInterfaces;
+	__u8  bConfigurationValue;
+	__u8  iConfiguration;
+	__u8  bmAttributes;
+	__u8  bMaxPower;
+} __attribute__ ((packed));
+
+#define USB_DT_CONFIG_SIZE		9
+
+/* from config descriptor bmAttributes */
+#define USB_CONFIG_ATT_ONE		(1 << 7)	/* must be set */
+#define USB_CONFIG_ATT_SELFPOWER	(1 << 6)	/* self powered */
+#define USB_CONFIG_ATT_WAKEUP		(1 << 5)	/* can wakeup */
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_STRING: String descriptor */
+struct usb_string_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u16 wData[1];		/* UTF-16LE encoded */
+} __attribute__ ((packed));
+
+/* note that "string" zero is special, it holds language codes that
+ * the device supports, not Unicode characters.
+ */
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_INTERFACE: Interface descriptor */
+struct usb_interface_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  bInterfaceNumber;
+	__u8  bAlternateSetting;
+	__u8  bNumEndpoints;
+	__u8  bInterfaceClass;
+	__u8  bInterfaceSubClass;
+	__u8  bInterfaceProtocol;
+	__u8  iInterface;
+} __attribute__ ((packed));
+
+#define USB_DT_INTERFACE_SIZE		9
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_ENDPOINT: Endpoint descriptor */
+struct usb_endpoint_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u8  bEndpointAddress;
+	__u8  bmAttributes;
+	__u16 wMaxPacketSize;
+	__u8  bInterval;
+
+	// NOTE:  these two are _only_ in audio endpoints.
+	// use USB_DT_ENDPOINT*_SIZE in bLength, not sizeof.
+	__u8  bRefresh;
+	__u8  bSynchAddress;
+} __attribute__ ((packed));
+
+#define USB_DT_ENDPOINT_SIZE		7
+#define USB_DT_ENDPOINT_AUDIO_SIZE	9	/* Audio extension */
+
+
+/*
+ * Endpoints
+ */
+#define USB_ENDPOINT_NUMBER_MASK	0x0f	/* in bEndpointAddress */
+#define USB_ENDPOINT_DIR_MASK		0x80
+
+#define USB_ENDPOINT_XFERTYPE_MASK	0x03	/* in bmAttributes */
+#define USB_ENDPOINT_XFER_CONTROL	0
+#define USB_ENDPOINT_XFER_ISOC		1
+#define USB_ENDPOINT_XFER_BULK		2
+#define USB_ENDPOINT_XFER_INT		3
+
+
+/*-------------------------------------------------------------------------*/
+
+/* USB_DT_DEVICE_QUALIFIER: Device Qualifier descriptor */
+struct usb_qualifier_descriptor {
+	__u8  bLength;
+	__u8  bDescriptorType;
+
+	__u16 bcdUSB;
+	__u8  bDeviceClass;
+	__u8  bDeviceSubClass;
+	__u8  bDeviceProtocol;
+	__u8  bMaxPacketSize0;
+	__u8  bNumConfigurations;
+	__u8  bRESERVED;
+} __attribute__ ((packed));
+
+
+/*-------------------------------------------------------------------------*/
+
+/* USB 2.0 defines three speeds, here's how Linux identifies them */
+
+enum usb_device_speed {
+	USB_SPEED_UNKNOWN = 0,			/* enumerating */
+	USB_SPEED_LOW, USB_SPEED_FULL,		/* usb 1.1 */
+	USB_SPEED_HIGH				/* usb 2.0 */
+};
+
+enum usb_device_state {
+	/* NOTATTACHED isn't in the USB spec, and this state acts
+	 * the same as ATTACHED ... but it's clearer this way.
+	 */
+	USB_STATE_NOTATTACHED = 0,
+
+	/* the chapter 9 device states */
+	USB_STATE_ATTACHED,
+	USB_STATE_POWERED,
+	USB_STATE_DEFAULT,			/* limited function */
+	USB_STATE_ADDRESS,
+	USB_STATE_CONFIGURED,			/* most functions */
+
+	USB_STATE_SUSPENDED
+
+	/* NOTE:  there are actually four different SUSPENDED
+	 * states, returning to POWERED, DEFAULT, ADDRESS, or
+	 * CONFIGURED respectively when SOF tokens flow again.
+	 */
+};
+
+#endif	/* __LINUX_USB_CH9_H */
diff -urN linux-2.4.23-pre6/include/linux/usb_gadget.h linux-2.4.23-pre7/include/linux/usb_gadget.h
--- linux-2.4.23-pre6/include/linux/usb_gadget.h	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/include/linux/usb_gadget.h	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,719 @@
+/*
+ * <linux/usb_gadget.h>
+ *
+ * We call the USB code inside a Linux-based peripheral device a "gadget"
+ * driver, except for the hardware-specific bus glue.  One USB host can
+ * master many USB gadgets, but the gadgets are only slaved to one host.
+ *
+ *
+ * (c) Copyright 2002-2003 by David Brownell
+ * All Rights Reserved.
+ *
+ * This software is licensed under the GNU GPL version 2.
+ */
+
+#ifndef __LINUX_USB_GADGET_H
+#define __LINUX_USB_GADGET_H
+
+#ifdef __KERNEL__
+
+struct usb_ep;
+
+/**
+ * struct usb_request - describes one i/o request
+ * @buf: Buffer used for data.  Always provide this; some controllers
+ * 	only use PIO, or don't use DMA for some endpoints.
+ * @dma: DMA address corresponding to 'buf'.  If you don't set this
+ * 	field, and the usb controller needs one, it is responsible
+ * 	for mapping and unmapping the buffer.
+ * @length: Length of that data
+ * @no_interrupt: If true, hints that no completion irq is needed.
+ *	Helpful sometimes with deep request queues.
+ * @zero: If true, when writing data, makes the last packet be "short"
+ *     by adding a zero length packet as needed;
+ * @short_not_ok: When reading data, makes short packets be
+ *     treated as errors (queue stops advancing till cleanup).
+ * @complete: Function called when request completes
+ * @context: For use by the completion callback
+ * @list: For use by the gadget driver.
+ * @status: Reports completion code, zero or a negative errno.
+ * 	Normally, faults block the transfer queue from advancing until
+ * 	the completion callback returns.
+ * 	Code "-ESHUTDOWN" indicates completion caused by device disconnect,
+ * 	or when the driver disabled the endpoint.
+ * @actual: Reports actual bytes transferred.  For reads (OUT
+ * 	transfers) this may be less than the requested length.  If the
+ * 	short_not_ok flag is set, short reads are treated as errors
+ * 	even when status otherwise indicates successful completion.
+ * 	Note that for writes (IN transfers) the data bytes may still
+ * 	reside in a device-side FIFO.
+ *
+ * These are allocated/freed through the endpoint they're used with.  The
+ * hardware's driver can add extra per-request data to the memory it returns,
+ * which often avoids separate memory allocations (potential failures),
+ * later when the request is queued.
+ *
+ * Request flags affect request handling, such as whether a zero length
+ * packet is written (the "zero" flag), whether a short read should be
+ * treated as an error (blocking request queue advance, the "short_not_ok"
+ * flag), or hinting that an interrupt is not required (the "no_interrupt"
+ * flag, for use with deep request queues).
+ *
+ * Bulk endpoints can use any size buffers, and can also be used for interrupt
+ * transfers. interrupt-only endpoints can be much less functional.
+ */
+	// NOTE this is analagous to 'struct urb' on the host side,
+	// except that it's thinner and promotes more pre-allocation.
+	//
+	// ISSUE should this be allocated through the device?
+
+struct usb_request {
+	void			*buf;
+	unsigned		length;
+	dma_addr_t		dma;
+
+	unsigned		no_interrupt : 1,
+				zero : 1,
+				short_not_ok : 1;
+
+	void			(*complete)(struct usb_ep *ep,
+					struct usb_request *req);
+	void			*context;
+	struct list_head	list;
+
+	int			status;
+	unsigned		actual;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/* endpoint-specific parts of the api to the usb controller hardware.
+ * unlike the urb model, (de)multiplexing layers are not required.
+ * (so this api could slash overhead if used on the host side...)
+ *
+ * note that device side usb controllers commonly differ in how many
+ * endpoints they support, as well as their capabilities.
+ */
+struct usb_ep_ops {
+	int (*enable) (struct usb_ep *ep,
+		const struct usb_endpoint_descriptor *desc);
+	int (*disable) (struct usb_ep *ep);
+
+	struct usb_request *(*alloc_request) (struct usb_ep *ep,
+		int gfp_flags);
+	void (*free_request) (struct usb_ep *ep, struct usb_request *req);
+
+	void *(*alloc_buffer) (struct usb_ep *ep, unsigned bytes,
+		dma_addr_t *dma, int gfp_flags);
+	void (*free_buffer) (struct usb_ep *ep, void *buf, dma_addr_t dma,
+		unsigned bytes);
+	// NOTE:  on 2.5, drivers may also use dma_map() and
+	// dma_sync_single() to manage dma overhead. 
+
+	int (*queue) (struct usb_ep *ep, struct usb_request *req,
+		int gfp_flags);
+	int (*dequeue) (struct usb_ep *ep, struct usb_request *req);
+
+	int (*set_halt) (struct usb_ep *ep, int value);
+	int (*fifo_status) (struct usb_ep *ep);
+	void (*fifo_flush) (struct usb_ep *ep);
+};
+
+/**
+ * struct usb_ep - device side representation of USB endpoint
+ * @name:identifier for the endpoint, such as "ep-a" or "ep9in-bulk"
+ * @ep_list:the gadget's ep_list holds all of its endpoints
+ * @maxpacket:the maximum packet size used on this endpoint, as
+ * 	configured when the endpoint was enabled.
+ * @driver_data:for use by the gadget driver.  all other fields are
+ * 	read-only to gadget drivers.
+ *
+ * the bus controller driver lists all the general purpose endpoints in
+ * gadget->ep_list.  the control endpoint (gadget->ep0) is not in that list,
+ * and is accessed only in response to a driver setup() callback.
+ */
+struct usb_ep {
+	void			*driver_data;
+
+	const char		*name;
+	const struct usb_ep_ops	*ops;
+	struct list_head	ep_list;
+	unsigned		maxpacket : 16;
+};
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * usb_ep_enable - configure endpoint, making it usable
+ * @ep:the endpoint being configured.  may not be the endpoint named "ep0".
+ * 	drivers discover endpoints through the ep_list of a usb_gadget.
+ * @desc:descriptor for desired behavior.  caller guarantees this pointer
+ * 	remains valid until the endpoint is disabled; the data byte order
+ * 	is little-endian (usb-standard).
+ *
+ * when configurations are set, or when interface settings change, the driver
+ * will enable or disable the relevant endpoints.  while it is enabled, an
+ * endpoint may be used for i/o until the driver receives a disconnect() from
+ * the host or until the endpoint is disabled.
+ *
+ * the ep0 implementation (which calls this routine) must ensure that the
+ * hardware capabilities of each endpoint match the descriptor provided
+ * for it.  for example, an endpoint named "ep2in-bulk" would be usable
+ * for interrupt transfers as well as bulk, but it likely couldn't be used
+ * for iso transfers or for endpoint 14.  some endpoints are fully
+ * configurable, with more generic names like "ep-a".  (remember that for
+ * USB, "in" means "towards the USB master".)
+ *
+ * returns zero, or a negative error code.
+ */
+static inline int
+usb_ep_enable (struct usb_ep *ep, const struct usb_endpoint_descriptor *desc)
+{
+	return ep->ops->enable (ep, desc);
+}
+
+/**
+ * usb_ep_disable - endpoint is no longer usable
+ * @ep:the endpoint being unconfigured.  may not be the endpoint named "ep0".
+ *
+ * no other task may be using this endpoint when this is called.
+ * any pending and uncompleted requests will complete with status
+ * indicating disconnect (-ESHUTDOWN) before this call returns.
+ * gadget drivers must call usb_ep_enable() again before queueing
+ * requests to the endpoint.
+ *
+ * returns zero, or a negative error code.
+ */
+static inline int
+usb_ep_disable (struct usb_ep *ep)
+{
+	return ep->ops->disable (ep);
+}
+
+/**
+ * usb_ep_alloc_request - allocate a request object to use with this endpoint
+ * @ep:the endpoint to be used with with the request
+ * @gfp_flags:GFP_* flags to use
+ *
+ * Request objects must be allocated with this call, since they normally
+ * need controller-specific setup and may even need endpoint-specific
+ * resources such as allocation of DMA descriptors.
+ * Requests may be submitted with usb_ep_queue(), and receive a single
+ * completion callback.  Free requests with usb_ep_free_request(), when
+ * they are no longer needed.
+ *
+ * Returns the request, or null if one could not be allocated.
+ */
+static inline struct usb_request *
+usb_ep_alloc_request (struct usb_ep *ep, int gfp_flags)
+{
+	return ep->ops->alloc_request (ep, gfp_flags);
+}
+
+/**
+ * usb_ep_free_request - frees a request object
+ * @ep:the endpoint associated with the request
+ * @req:the request being freed
+ *
+ * Reverses the effect of usb_ep_alloc_request().
+ * Caller guarantees the request is not queued, and that it will
+ * no longer be requeued (or otherwise used).
+ */
+static inline void
+usb_ep_free_request (struct usb_ep *ep, struct usb_request *req)
+{
+	ep->ops->free_request (ep, req);
+}
+
+/**
+ * usb_ep_alloc_buffer - allocate an I/O buffer
+ * @ep:the endpoint associated with the buffer
+ * @len:length of the desired buffer
+ * @dma:pointer to the buffer's DMA address; must be valid
+ * @gfp_flags:GFP_* flags to use
+ *
+ * Returns a new buffer, or null if one could not be allocated.
+ * The buffer is suitably aligned for dma, if that endpoint uses DMA,
+ * and the caller won't have to care about dma-inconsistency
+ * or any hidden "bounce buffer" mechanism.  No additional per-request
+ * DMA mapping will be required for such buffers.
+ * Free it later with usb_ep_free_buffer().
+ *
+ * You don't need to use this call to allocate I/O buffers unless you
+ * want to make sure drivers don't incur costs for such "bounce buffer"
+ * copies or per-request DMA mappings.
+ */
+static inline void *
+usb_ep_alloc_buffer (struct usb_ep *ep, unsigned len, dma_addr_t *dma,
+	int gfp_flags)
+{
+	return ep->ops->alloc_buffer (ep, len, dma, gfp_flags);
+}
+
+/**
+ * usb_ep_free_buffer - frees an i/o buffer
+ * @ep:the endpoint associated with the buffer
+ * @buf:CPU view address of the buffer
+ * @dma:the buffer's DMA address
+ * @len:length of the buffer
+ *
+ * reverses the effect of usb_ep_alloc_buffer().
+ * caller guarantees the buffer will no longer be accessed
+ */
+static inline void
+usb_ep_free_buffer (struct usb_ep *ep, void *buf, dma_addr_t dma, unsigned len)
+{
+	ep->ops->free_buffer (ep, buf, dma, len);
+}
+
+/**
+ * usb_ep_queue - queues (submits) an I/O request to an endpoint.
+ * @ep:the endpoint associated with the request
+ * @req:the request being submitted
+ * @gfp_flags: GFP_* flags to use in case the lower level driver couldn't
+ * 	pre-allocate all necessary memory with the request.
+ *
+ * This tells the device controller to perform the specified request through
+ * that endpoint (reading or writing a buffer).  When the request completes,
+ * including being canceled by usb_ep_dequeue(), the request's completion
+ * routine is called to return the request to the driver.  Any endpoint
+ * (except control endpoints like ep0) may have more than one transfer
+ * request queued; they complete in FIFO order.  Once a gadget driver
+ * submits a request, that request may not be examined or modified until it
+ * is given back to that driver through the completion callback.
+ *
+ * Each request is turned into one or more packets.  The controller driver
+ * never merges adjacent requests into the same packet.  OUT transfers
+ * will sometimes use data that's already buffered in the hardware.
+ *
+ * Bulk endpoints can queue any amount of data; the transfer is packetized
+ * automatically.  The last packet will be short if the request doesn't fill it
+ * out completely.  Zero length packets (ZLPs) should be avoided in portable
+ * protocols since not all usb hardware can successfully handle zero length
+ * packets.  (ZLPs may be explicitly written, and may be implicitly written if
+ * the request 'zero' flag is set.)  Bulk endpoints may also be used
+ * for interrupt transfers; but the reverse is not true, and some endpoints
+ * won't support every interrupt transfer.  (Such as 768 byte packets.)
+ *
+ * Interrupt-only endpoints are less functional than bulk endpoints, for
+ * example by not supporting queueing or not handling buffers that are
+ * larger than the endpoint's maxpacket size.  They may also treat data
+ * toggle differently.
+ *
+ * Control endpoints ... after getting a setup() callback, the driver queues
+ * one response (even if it would be zero length).  That enables the
+ * status ack, after transfering data as specified in the response.  Setup
+ * functions may return negative error codes to generate protocol stalls.
+ * (Note that some USB device controllers disallow protocol stall responses
+ * in some cases.)  When control responses are deferred (the response is
+ * written after the setup callback returns), then usb_ep_set_halt() may be
+ * used on ep0 to trigger protocol stalls.
+ *
+ * For periodic endpoints, like interrupt or isochronous ones, the usb host
+ * arranges to poll once per interval, and the gadget driver usually will
+ * have queued some data to transfer at that time.
+ *
+ * Returns zero, or a negative error code.  Endpoints that are not enabled
+ * report errors; errors will also be
+ * reported when the usb peripheral is disconnected.
+ */
+static inline int
+usb_ep_queue (struct usb_ep *ep, struct usb_request *req, int gfp_flags)
+{
+	return ep->ops->queue (ep, req, gfp_flags);
+}
+
+/**
+ * usb_ep_dequeue - dequeues (cancels, unlinks) an I/O request from an endpoint
+ * @ep:the endpoint associated with the request
+ * @req:the request being canceled
+ *
+ * if the request is still active on the endpoint, it is dequeued and its
+ * completion routine is called (with status -ECONNRESET); else a negative
+ * error code is returned.
+ *
+ * note that some hardware can't clear out write fifos (to unlink the request
+ * at the head of the queue) except as part of disconnecting from usb.  such
+ * restrictions prevent drivers from supporting configuration changes,
+ * even to configuration zero (a "chapter 9" requirement).
+ */
+static inline int usb_ep_dequeue (struct usb_ep *ep, struct usb_request *req)
+{
+	return ep->ops->dequeue (ep, req);
+}
+
+/**
+ * usb_ep_set_halt - sets the endpoint halt feature.
+ * @ep: the non-isochronous endpoint being stalled
+ *
+ * Use this to stall an endpoint, perhaps as an error report.
+ * Except for control endpoints,
+ * the endpoint stays halted (will not stream any data) until the host
+ * clears this feature; drivers may need to empty the endpoint's request
+ * queue first, to make sure no inappropriate transfers happen.
+ *
+ * Note that while an endpoint CLEAR_FEATURE will be invisible to the
+ * gadget driver, a SET_INTERFACE will not be.  To reset endpoints for the
+ * current altsetting, see usb_ep_clear_halt().  When switching altsettings,
+ * it's simplest to use usb_ep_enable() or usb_ep_disable() for the endpoints.
+ *
+ * Returns zero, or a negative error code.  On success, this call sets
+ * underlying hardware state that blocks data transfers.
+ */
+static inline int
+usb_ep_set_halt (struct usb_ep *ep)
+{
+	return ep->ops->set_halt (ep, 1);
+}
+
+/**
+ * usb_ep_clear_halt - clears endpoint halt, and resets toggle
+ * @ep:the bulk or interrupt endpoint being reset
+ *
+ * Use this when responding to the standard usb "set interface" request,
+ * for endpoints that aren't reconfigured, after clearing any other state
+ * in the endpoint's i/o queue.
+ *
+ * Returns zero, or a negative error code.  On success, this call clears
+ * the underlying hardware state reflecting endpoint halt and data toggle.
+ * Note that some hardware can't support this request (like pxa2xx_udc),
+ * and accordingly can't correctly implement interface altsettings.
+ */
+static inline int
+usb_ep_clear_halt (struct usb_ep *ep)
+{
+	return ep->ops->set_halt (ep, 0);
+}
+
+/**
+ * usb_ep_fifo_status - returns number of bytes in fifo, or error
+ * @ep: the endpoint whose fifo status is being checked.
+ *
+ * FIFO endpoints may have "unclaimed data" in them in certain cases,
+ * such as after aborted transfers.  Hosts may not have collected all
+ * the IN data written by the gadget driver, as reported by a request
+ * completion.  The gadget driver may not have collected all the data
+ * written OUT to it by the host.  Drivers that need precise handling for
+ * fault reporting or recovery may need to use this call.
+ *
+ * This returns the number of such bytes in the fifo, or a negative
+ * errno if the endpoint doesn't use a FIFO or doesn't support such
+ * precise handling.
+ */
+static inline int
+usb_ep_fifo_status (struct usb_ep *ep)
+{
+	if (ep->ops->fifo_status)
+		return ep->ops->fifo_status (ep);
+	else
+		return -EOPNOTSUPP;
+}
+
+/**
+ * usb_ep_fifo_flush - flushes contents of a fifo
+ * @ep: the endpoint whose fifo is being flushed.
+ *
+ * This call may be used to flush the "unclaimed data" that may exist in
+ * an endpoint fifo after abnormal transaction terminations.  The call
+ * must never be used except when endpoint is not being used for any
+ * protocol translation.
+ */
+static inline void
+usb_ep_fifo_flush (struct usb_ep *ep)
+{
+	if (ep->ops->fifo_flush)
+		ep->ops->fifo_flush (ep);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+struct usb_gadget;
+
+/* the rest of the api to the controller hardware: device operations,
+ * which don't involve endpoints (or i/o).
+ */
+struct usb_gadget_ops {
+	int	(*get_frame)(struct usb_gadget *);
+	int	(*wakeup)(struct usb_gadget *);
+	int	(*set_selfpowered) (struct usb_gadget *, int value);
+	int	(*ioctl)(struct usb_gadget *,
+				unsigned code, unsigned long param);
+};
+
+/**
+ * struct usb_gadget - represents a usb slave device
+ * @ep0: Endpoint zero, used when reading or writing responses to
+ * 	driver setup() requests
+ * @ep_list: List of other endpoints supported by the device.
+ * @speed: Speed of current connection to USB host.
+ * @name: Identifies the controller hardware type.  Used in diagnostics
+ * 	and sometimes configuration.
+ *
+ * Gadgets have a mostly-portable "gadget driver" implementing device
+ * functions, handling all usb configurations and interfaces.  They
+ * also have a hardware-specific driver (accessed through ops vectors),
+ * which insulates the gadget driver from hardware details and packages
+ * the hardware endpoints through generic i/o queues.
+ *
+ * Except for the driver data, all fields in this structure are
+ * read-only to the gadget driver.  That driver data is part of the
+ * "driver model" infrastructure in 2.5 (and later) kernels, and for
+ * earlier systems is grouped in a similar structure that's not known
+ * to the rest of the kernel.
+ */
+struct usb_gadget {
+	/* readonly to gadget driver */
+	const struct usb_gadget_ops	*ops;
+	struct usb_ep			*ep0;
+	struct list_head		ep_list;	/* of usb_ep */
+	enum usb_device_speed		speed;
+	const char			*name;
+
+	struct __gadget_device {
+		const char		*bus_id;
+		void			*driver_data;
+	} dev;
+};
+
+static inline void set_gadget_data (struct usb_gadget *gadget, void *data)
+	{ gadget->dev.driver_data = data; }
+static inline void *get_gadget_data (struct usb_gadget *gadget)
+	{ return gadget->dev.driver_data; }
+
+
+/* iterates the non-control endpoints; 'tmp' is a struct usb_ep pointer */
+#define gadget_for_each_ep(tmp,gadget) \
+	list_for_each_entry(tmp, &(gadget)->ep_list, ep_list)
+
+#ifndef list_for_each_entry
+/* not available in 2.4.18 */
+#define list_for_each_entry(pos, head, member)				\
+	for (pos = list_entry((head)->next, typeof(*pos), member),	\
+		     prefetch(pos->member.next);			\
+	     &pos->member != (head); 					\
+	     pos = list_entry(pos->member.next, typeof(*pos), member),	\
+		     prefetch(pos->member.next))
+#endif
+
+
+/**
+ * usb_gadget_frame_number - returns the current frame number
+ * @gadget: controller that reports the frame number
+ *
+ * Returns the usb frame number, normally eleven bits from a SOF packet,
+ * or negative errno if this device doesn't support this capability.
+ */
+static inline int usb_gadget_frame_number (struct usb_gadget *gadget)
+{
+	return gadget->ops->get_frame (gadget);
+}
+
+/**
+ * usb_gadget_wakeup - tries to wake up the host connected to this gadget
+ * @gadget: controller used to wake up the host
+ *
+ * Returns zero on success, else negative error code if the hardware
+ * doesn't support such attempts, or its support has not been enabled
+ * by the usb host.  Drivers must return device descriptors that report
+ * their ability to support this, or hosts won't enable it.
+ */
+static inline int usb_gadget_wakeup (struct usb_gadget *gadget)
+{
+	if (!gadget->ops->wakeup)
+		return -EOPNOTSUPP;
+	return gadget->ops->wakeup (gadget);
+}
+
+/**
+ * usb_gadget_set_selfpowered - sets the device selfpowered feature.
+ * @gadget:the device being declared as self-powered
+ *
+ * this affects the device status reported by the hardware driver
+ * to reflect that it now has a local power supply.
+ *
+ * returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_set_selfpowered (struct usb_gadget *gadget)
+{
+	if (!gadget->ops->set_selfpowered)
+		return -EOPNOTSUPP;
+	return gadget->ops->set_selfpowered (gadget, 1);
+}
+
+/**
+ * usb_gadget_clear_selfpowered - clear the device selfpowered feature.
+ * @gadget:the device being declared as bus-powered
+ *
+ * this affects the device status reported by the hardware driver.
+ * some hardware may not support bus-powered operation, in which
+ * case this feature's value can never change.
+ *
+ * returns zero on success, else negative errno.
+ */
+static inline int
+usb_gadget_clear_selfpowered (struct usb_gadget *gadget)
+{
+	if (!gadget->ops->set_selfpowered)
+		return -EOPNOTSUPP;
+	return gadget->ops->set_selfpowered (gadget, 0);
+}
+
+
+/*-------------------------------------------------------------------------*/
+
+/**
+ * struct usb_gadget_driver - driver for usb 'slave' devices
+ * @function: String describing the gadget's function
+ * @speed: Highest speed the driver handles.
+ * @bind: Invoked when the driver is bound to a gadget, usually
+ * 	after registering the driver.
+ * 	At that point, ep0 is fully initialized, and ep_list holds
+ * 	the currently-available endpoints.
+ * 	Called in a context that permits sleeping.
+ * @setup: Invoked for ep0 control requests that aren't handled by
+ * 	the hardware level driver. Most calls must be handled by
+ * 	the gadget driver, including descriptor and configuration
+ * 	management.  The 16 bit members of the setup data are in
+ * 	cpu order. Called in_interrupt; this may not sleep.  Driver
+ *	queues a response to ep0, or returns negative to stall.
+ * @disconnect: Invoked after all transfers have been stopped,
+ * 	when the host is disconnected.  May be called in_interrupt; this
+ * 	may not sleep.  Some devices can't detect disconnect, so this might
+ *	not be called except as part of controller shutdown.
+ * @unbind: Invoked when the driver is unbound from a gadget,
+ * 	usually from rmmod (after a disconnect is reported).
+ * 	Called in a context that permits sleeping.
+ * @suspend: Invoked on USB suspend.  May be called in_interrupt.
+ * @resume: Invoked on USB resume.  May be called in_interrupt.
+ *
+ * Devices are disabled till a gadget driver successfully bind()s, which
+ * means the driver will handle setup() requests needed to enumerate (and
+ * meet "chapter 9" requirements) then do some useful work.
+ *
+ * Drivers use hardware-specific knowledge to configure the usb hardware.
+ * endpoint addressing is only one of several hardware characteristics that
+ * are in descriptors the ep0 implementation returns from setup() calls.
+ *
+ * Except for ep0 implementation, most driver code shouldn't need change to
+ * run on top of different usb controllers.  It'll use endpoints set up by
+ * that ep0 implementation.
+ *
+ * The usb controller driver handles a few standard usb requests.  Those
+ * include set_address, and feature flags for devices, interfaces, and
+ * endpoints (the get_status, set_feature, and clear_feature requests).
+ *
+ * Accordingly, the driver's setup() callback must always implement all
+ * get_descriptor requests, returning at least a device descriptor and
+ * a configuration descriptor.  Drivers must make sure the endpoint
+ * descriptors match any hardware constraints. Some hardware also constrains
+ * other descriptors. (The pxa250 allows only configurations 1, 2, or 3).
+ *
+ * The driver's setup() callback must also implement set_configuration,
+ * and should also implement set_interface, get_configuration, and
+ * get_interface.  Setting a configuration (or interface) is where
+ * endpoints should be activated or (config 0) shut down.
+ *
+ * (Note that only the default control endpoint is supported.  Neither
+ * hosts nor devices generally support control traffic except to ep0.)
+ *
+ * Most devices will ignore USB suspend/resume operations, and so will
+ * not provide those callbacks.  However, some may need to change modes
+ * when the host is not longer directing those activities.  For example,
+ * local controls (buttons, dials, etc) may need to be re-enabled since
+ * the (remote) host can't do that any longer; or an error state might
+ * be cleared, to make the device behave identically whether or not
+ * power is maintained.
+ */
+struct usb_gadget_driver {
+	char			*function;
+	enum usb_device_speed	speed;
+	int			(*bind)(struct usb_gadget *);
+	void			(*unbind)(struct usb_gadget *);
+	int			(*setup)(struct usb_gadget *,
+					const struct usb_ctrlrequest *);
+	void			(*disconnect)(struct usb_gadget *);
+	void			(*suspend)(struct usb_gadget *);
+	void			(*resume)(struct usb_gadget *);
+
+	// FIXME support safe rmmod
+	struct __gadget_driver {
+		const char	*name;
+		void		*driver_data;
+	} driver;
+};
+
+
+
+/*-------------------------------------------------------------------------*/
+
+/* driver modules register and unregister, as usual.
+ * these calls must be made in a context that can sleep.
+ *
+ * these will usually be implemented directly by the hardware-dependent
+ * usb bus interface driver, which will only support a single driver.
+ */
+
+/**
+ * usb_gadget_register_driver - register a gadget driver
+ * @driver:the driver being registered
+ *
+ * Call this in your gadget driver's module initialization function,
+ * to tell the underlying usb controller driver about your driver.
+ * The driver's bind() function will be called to bind it to a
+ * gadget.  This function must be called in a context that can sleep.
+ */
+int usb_gadget_register_driver (struct usb_gadget_driver *driver);
+
+/**
+ * usb_gadget_unregister_driver - unregister a gadget driver
+ * @driver:the driver being unregistered
+ *
+ * Call this in your gadget driver's module cleanup function,
+ * to tell the underlying usb controller that your driver is
+ * going away.  If the controller is connected to a USB host,
+ * it will first disconnect().  The driver is also requested
+ * to unbind() and clean up any device state, before this procedure
+ * finally returns.
+ * This function must be called in a context that can sleep.
+ */
+int usb_gadget_unregister_driver (struct usb_gadget_driver *driver);
+
+/*-------------------------------------------------------------------------*/
+
+/* utility to simplify dealing with string descriptors */
+
+/**
+ * struct usb_string - wraps a C string and its USB id
+ * @id:the (nonzero) ID for this string
+ * @s:the string, in ISO-8859/1 characters
+ *
+ * If you're using usb_gadget_get_string(), use this to wrap a string
+ * together with its ID.
+ */
+struct usb_string {
+	u8			id;
+	const char		*s;
+};
+
+/**
+ * struct usb_gadget_strings - a set of USB strings in a given language
+ * @language:identifies the strings' language (0x0409 for en-us)
+ * @strings:array of strings with their ids
+ *
+ * If you're using usb_gadget_get_string(), use this to wrap all the
+ * strings for a given language.
+ */
+struct usb_gadget_strings {
+	u16			language;	/* 0x0409 for en-us */
+	struct usb_string	*strings;
+};
+
+/* put descriptor for string with that id into buf (buflen >= 256) */
+int usb_gadget_get_string (struct usb_gadget_strings *table, int id, u8 *buf);
+
+
+#endif  /* __KERNEL__ */
+
+#endif	/* __LINUX_USB_GADGET_H */
diff -urN linux-2.4.23-pre6/include/linux/videodev.h linux-2.4.23-pre7/include/linux/videodev.h
--- linux-2.4.23-pre6/include/linux/videodev.h	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/include/linux/videodev.h	2003-10-09 17:48:22.000000000 -0700
@@ -4,32 +4,25 @@
 #include <linux/types.h>
 #include <linux/version.h>
 
-#if 0
-/*
- * v4l2 is still work-in-progress, integration planed for 2.5.x
- *   v4l2 project homepage:   http://www.thedirks.org/v4l2/
- *   patches available from:  http://bytesex.org/patches/
- */ 
-# define HAVE_V4L2 1
-# include <linux/videodev2.h>
-#else
-# undef HAVE_V4L2
-#endif
-
 #ifdef __KERNEL__
 
 #include <linux/poll.h>
+#include <linux/mm.h>
 #include <linux/devfs_fs_kernel.h>
 
 struct video_device
 {
-	struct module *owner;
-     	char name[32];
- 	int type;       /* v4l1 */
- 	int type2;      /* v4l2 */
+	/* device info */
+	char name[32];
+	int type;       /* v4l1 */
+	int type2;      /* v4l2 */
 	int hardware;
 	int minor;
 
+	/* device ops + callbacks */
+	struct file_operations *fops;
+	void (*release)(struct video_device *vfd);
+
 	/* old, obsolete interface -- dropped in 2.5.x, don't use it */
 	int (*open)(struct video_device *, int mode);
 	void (*close)(struct video_device *);
@@ -40,28 +33,50 @@
 	int (*mmap)(struct video_device *, const char *, unsigned long);
 	int (*initialize)(struct video_device *);       
 
- 	/* new interface -- we will use file_operations directly
- 	 * like soundcore does. */
- 	struct file_operations *fops;
-	void *priv;		/* Used to be 'private' but that upsets C++ */
-
-	/* for videodev.c intenal usage -- don't touch */
-	int users;
-	struct semaphore lock;
-	devfs_handle_t devfs_handle;
+#if 1 /* to be removed in 2.7.x */
+	/* obsolete -- fops->owner is used instead */
+	struct module *owner;
+	/* dev->driver_data will be used instead some day.
+	 * Use the video_{get|set}_drvdata() helper functions,
+	 * so the switch over will be transparent for you.
+	 * Or use {pci|usb}_{get|set}_drvdata() directly. */
+	void *priv;
+#endif
+
+	/* for videodev.c intenal usage -- please don't touch */
+	int users;                     /* video_exclusive_{open|close} ... */
+	struct semaphore lock;         /* ... helper function uses these   */
+	devfs_handle_t devfs_handle;   /* devfs */
 };
 
 #define VIDEO_MAJOR	81
-extern int video_register_device(struct video_device *, int type, int nr);
 
 #define VFL_TYPE_GRABBER	0
 #define VFL_TYPE_VBI		1
 #define VFL_TYPE_RADIO		2
 #define VFL_TYPE_VTX		3
 
+extern int video_register_device(struct video_device *, int type, int nr);
 extern void video_unregister_device(struct video_device *);
 extern struct video_device* video_devdata(struct file*);
 
+
+/* helper functions to alloc / release struct video_device, the
+   later can be used for video_device->release() */
+struct video_device *video_device_alloc(void);
+void video_device_release(struct video_device *vfd);
+
+/* helper functions to access driver private data. */
+static inline void *video_get_drvdata(struct video_device *dev)
+{
+	return dev->priv;
+}
+
+static inline void video_set_drvdata(struct video_device *dev, void *data)
+{
+	dev->priv = data;
+}
+
 extern int video_exclusive_open(struct inode *inode, struct file *file);
 extern int video_exclusive_release(struct inode *inode, struct file *file);
 extern int video_usercopy(struct inode *inode, struct file *file,
@@ -403,9 +418,8 @@
 #define VID_HARDWARE_PWC	31	/* Philips webcams */
 #define VID_HARDWARE_MEYE	32	/* Sony Vaio MotionEye cameras */
 #define VID_HARDWARE_CPIA2	33
-#define VID_HARDWARE_VICAM	34	/* ViCam, 3Com Homeconnect */
+#define VID_HARDWARE_VICAM      34
 #define VID_HARDWARE_SF16FMR2	35
-
 #endif /* __LINUX_VIDEODEV_H */
 
 /*
diff -urN linux-2.4.23-pre6/init/main.c linux-2.4.23-pre7/init/main.c
--- linux-2.4.23-pre6/init/main.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/init/main.c	2003-10-09 17:48:22.000000000 -0700
@@ -545,6 +545,12 @@
 #endif
 }
 
+static void run_init_process(char *init_filename)
+{
+	argv_init[0] = init_filename;
+	execve(init_filename, argv_init, envp_init);
+}
+
 extern void prepare_namespace(void);
 
 static int init(void * unused)
@@ -587,10 +593,12 @@
 	 */
 
 	if (execute_command)
-		execve(execute_command,argv_init,envp_init);
-	execve("/sbin/init",argv_init,envp_init);
-	execve("/etc/init",argv_init,envp_init);
-	execve("/bin/init",argv_init,envp_init);
-	execve("/bin/sh",argv_init,envp_init);
+		run_init_process(execute_command);
+
+	run_init_process("/sbin/init");
+	run_init_process("/etc/init");
+	run_init_process("/bin/init");
+	run_init_process("/bin/sh");
+
 	panic("No init found.  Try passing init= option to kernel.");
 }
diff -urN linux-2.4.23-pre6/kernel/resource.c linux-2.4.23-pre7/kernel/resource.c
--- linux-2.4.23-pre6/kernel/resource.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/kernel/resource.c	2003-10-09 17:48:22.000000000 -0700
@@ -13,6 +13,7 @@
 #include <linux/init.h>
 #include <linux/slab.h>
 #include <linux/spinlock.h>
+#include <linux/seq_file.h>
 #include <asm/io.h>
 
 struct resource ioport_resource = { "PCI IO", 0x0000, IO_SPACE_LIMIT, IORESOURCE_IO };
@@ -20,48 +21,92 @@
 
 static rwlock_t resource_lock = RW_LOCK_UNLOCKED;
 
-/*
- * This generates reports for /proc/ioports and /proc/iomem
- */
-static char * do_resource_list(struct resource *entry, const char *fmt, int offset, char *buf, char *end)
+enum { MAX_IORES_LEVEL = 5 };
+
+static void *r_next(struct seq_file *m, void *v, loff_t *pos)
 {
-	if (offset < 0)
-		offset = 0;
+	struct resource *p = v;
+	(*pos)++;
+	if (p->child)
+		return p->child;
+	while (!p->sibling && p->parent)
+		p = p->parent;
+	return p->sibling;
+}
 
-	while (entry) {
-		const char *name = entry->name;
-		unsigned long from, to;
-
-		if ((int) (end-buf) < 80)
-			return buf;
-
-		from = entry->start;
-		to = entry->end;
-		if (!name)
-			name = "<BAD>";
-
-		buf += sprintf(buf, fmt + offset, from, to, name);
-		if (entry->child)
-			buf = do_resource_list(entry->child, fmt, offset-2, buf, end);
-		entry = entry->sibling;
-	}
+static void *r_start(struct seq_file *m, loff_t *pos)
+{
+	struct resource *p = m->private;
+	loff_t l = 0;
+	read_lock(&resource_lock);
+	for (p = p->child; p && l < *pos; p = r_next(m, p, &l))
+		;
+	return p;
+}
 
-	return buf;
+static void r_stop(struct seq_file *m, void *v)
+{
+	read_unlock(&resource_lock);
 }
 
-int get_resource_list(struct resource *root, char *buf, int size)
+static int r_show(struct seq_file *m, void *v)
 {
-	char *fmt;
-	int retval;
+	struct resource *root = m->private;
+	struct resource *r = v, *p;
+	int width = root->end < 0x10000 ? 4 : 8;
+	int depth;
 
-	fmt = "        %08lx-%08lx : %s\n";
-	if (root->end < 0x10000)
-		fmt = "        %04lx-%04lx : %s\n";
-	read_lock(&resource_lock);
-	retval = do_resource_list(root->child, fmt, 8, buf, buf + size) - buf;
-	read_unlock(&resource_lock);
-	return retval;
-}	
+	for (depth = 0, p = r; depth < MAX_IORES_LEVEL; depth++, p = p->parent)
+		if (p->parent == root)
+			break;
+	seq_printf(m, "%*s%0*lx-%0*lx : %s\n",
+			depth * 2, "",
+			width, r->start,
+			width, r->end,
+			r->name ? r->name : "<BAD>");
+	return 0;
+}
+
+static struct seq_operations resource_op = {
+	.start	= r_start,
+	.next	= r_next,
+	.stop	= r_stop,
+	.show	= r_show,
+};
+
+static int ioports_open(struct inode *inode, struct file *file)
+{
+	int res = seq_open(file, &resource_op);
+	if (!res) {
+		struct seq_file *m = file->private_data;
+		m->private = &ioport_resource;
+	}
+	return res;
+}
+
+static int iomem_open(struct inode *inode, struct file *file)
+{
+	int res = seq_open(file, &resource_op);
+	if (!res) {
+		struct seq_file *m = file->private_data;
+		m->private = &iomem_resource;
+	}
+	return res;
+}
+
+struct file_operations proc_ioports_operations = {
+	.open		= ioports_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
+
+struct file_operations proc_iomem_operations = {
+	.open		= iomem_open,
+	.read		= seq_read,
+	.llseek		= seq_lseek,
+	.release	= seq_release,
+};
 
 /* Return the conflict entry if you can't request it */
 static struct resource * __request_resource(struct resource *root, struct resource *new)
diff -urN linux-2.4.23-pre6/kernel/sysctl.c linux-2.4.23-pre7/kernel/sysctl.c
--- linux-2.4.23-pre6/kernel/sysctl.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/kernel/sysctl.c	2003-10-09 17:48:22.000000000 -0700
@@ -53,6 +53,8 @@
 extern int core_setuid_ok;
 extern char core_pattern[];
 extern int cad_pid;
+extern int laptop_mode;
+extern int block_dump;
 
 /* this is needed for the proc_dointvec_minmax for [fs_]overflow UID and GID */
 static int maxolduid = 65535;
@@ -306,6 +308,10 @@
 	&vm_max_readahead,sizeof(int), 0644, NULL, &proc_dointvec},
 	{VM_MAX_MAP_COUNT, "max_map_count",
 	 &max_map_count, sizeof(int), 0644, NULL, &proc_dointvec},
+	{VM_LAPTOP_MODE, "laptop_mode",
+	 &laptop_mode, sizeof(int), 0644, NULL, &proc_dointvec},
+	{VM_BLOCK_DUMP, "block_dump",
+	 &block_dump, sizeof(int), 0644, NULL, &proc_dointvec},
 	{0}
 };
 
diff -urN linux-2.4.23-pre6/mm/filemap.c linux-2.4.23-pre7/mm/filemap.c
--- linux-2.4.23-pre6/mm/filemap.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/mm/filemap.c	2003-10-09 17:48:22.000000000 -0700
@@ -165,6 +165,8 @@
 
 			if (mapping && mapping->host)
 				mark_inode_dirty_pages(mapping->host);
+			if (block_dump)
+				printk(KERN_DEBUG "%s: dirtied page\n", current->comm);
 		}
 	}
 }
@@ -654,10 +656,19 @@
 	struct address_space *mapping, unsigned long offset,
 	struct page **hash)
 {
-	unsigned long flags;
-
-	flags = page->flags & ~(1 << PG_uptodate | 1 << PG_error | 1 << PG_dirty | 1 << PG_referenced | 1 << PG_arch_1 | 1 << PG_checked);
-	page->flags = flags | (1 << PG_locked);
+	/*
+	 * Yes this is inefficient, however it is needed.  The problem
+	 * is that we could be adding a page to the swap cache while
+	 * another CPU is also modifying page->flags, so the updates
+	 * really do need to be atomic.  -- Rik
+	 */
+	ClearPageUptodate(page);
+	ClearPageError(page);
+	ClearPageDirty(page);
+	ClearPageReferenced(page);
+	ClearPageArch1(page);
+	ClearPageChecked(page);
+	LockPage(page);
 	page_cache_get(page);
 	page->index = offset;
 	add_page_to_inode_queue(mapping, page);
diff -urN linux-2.4.23-pre6/mm/memory.c linux-2.4.23-pre7/mm/memory.c
--- linux-2.4.23-pre6/mm/memory.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/mm/memory.c	2003-10-09 17:48:22.000000000 -0700
@@ -1287,7 +1287,8 @@
 	 */
 	/* Only go through if we didn't race with anybody else... */
 	if (pte_none(*page_table)) {
-		++mm->rss;
+		if (!PageReserved(new_page))
+			++mm->rss;
 		flush_page_to_ram(new_page);
 		flush_icache_page(vma, new_page);
 		entry = mk_pte(new_page, vma->vm_page_prot);
diff -urN linux-2.4.23-pre6/mm/mmap.c linux-2.4.23-pre7/mm/mmap.c
--- linux-2.4.23-pre6/mm/mmap.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/mm/mmap.c	2003-10-09 17:48:22.000000000 -0700
@@ -1041,6 +1041,9 @@
 	if (!len)
 		return addr;
 
+	if ((addr + len) > TASK_SIZE || (addr + len) < addr)
+		return -EINVAL;
+
 	/*
 	 * mlock MCL_FUTURE?
 	 */
diff -urN linux-2.4.23-pre6/mm/page_alloc.c linux-2.4.23-pre7/mm/page_alloc.c
--- linux-2.4.23-pre6/mm/page_alloc.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/mm/page_alloc.c	2003-10-09 17:48:22.000000000 -0700
@@ -109,7 +109,8 @@
 		BUG();
 	if (PageActive(page))
 		BUG();
-	page->flags &= ~((1<<PG_referenced) | (1<<PG_dirty));
+	ClearPageReferenced(page);
+	ClearPageDirty(page);
 
 	if (current->flags & PF_FREE_PAGES)
 		goto local_freelist;
diff -urN linux-2.4.23-pre6/net/8021q/vlan_dev.c linux-2.4.23-pre7/net/8021q/vlan_dev.c
--- linux-2.4.23-pre6/net/8021q/vlan_dev.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/8021q/vlan_dev.c	2003-10-09 17:48:22.000000000 -0700
@@ -75,7 +75,11 @@
 static inline struct sk_buff *vlan_check_reorder_header(struct sk_buff *skb)
 {
 	if (VLAN_DEV_INFO(skb->dev)->flags & 1) {
-		skb = skb_share_check(skb, GFP_ATOMIC);
+		if (skb_shared(skb) || skb_cloned(skb)) {
+			struct sk_buff *nskb = skb_copy(skb, GFP_ATOMIC);
+			kfree(skb);
+			skb = nskb;
+		}
 		if (skb) {
 			/* Lifted from Gleb's VLAN code... */
 			memmove(skb->data - ETH_HLEN,
diff -urN linux-2.4.23-pre6/net/ipv4/igmp.c linux-2.4.23-pre7/net/ipv4/igmp.c
--- linux-2.4.23-pre6/net/ipv4/igmp.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/igmp.c	2003-10-09 17:48:22.000000000 -0700
@@ -1374,8 +1374,9 @@
 	sf_markstate(pmc);
 #endif
 	if (!delta) {
+		err = -EINVAL;
 		if (!pmc->sfcount[sfmode])
-			return -EINVAL;
+			goto out_unlock;
 		pmc->sfcount[sfmode]--;
 	}
 	err = 0;
@@ -1406,6 +1407,7 @@
 		igmp_ifc_event(pmc->interface);
 #endif
 	}
+out_unlock:
 	spin_unlock_bh(&pmc->lock);
 	return err;
 }
diff -urN linux-2.4.23-pre6/net/ipv4/ip_gre.c linux-2.4.23-pre7/net/ipv4/ip_gre.c
--- linux-2.4.23-pre6/net/ipv4/ip_gre.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/ip_gre.c	2003-10-09 17:48:22.000000000 -0700
@@ -807,8 +807,6 @@
 			tunnel->err_count = 0;
 	}
 
-	skb->h.raw = skb->nh.raw;
-
 	max_headroom = ((tdev->hard_header_len+15)&~15)+ gre_hlen;
 
 	if (skb_headroom(skb) < max_headroom || skb_cloned(skb) || skb_shared(skb)) {
@@ -827,6 +825,7 @@
 		old_iph = skb->nh.iph;
 	}
 
+	skb->h.raw = skb->nh.raw;
 	skb->nh.raw = skb_push(skb, gre_hlen);
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	dst_release(skb->dst);
diff -urN linux-2.4.23-pre6/net/ipv4/ipip.c linux-2.4.23-pre7/net/ipv4/ipip.c
--- linux-2.4.23-pre6/net/ipv4/ipip.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/ipip.c	2003-10-09 17:48:22.000000000 -0700
@@ -603,8 +603,6 @@
 			tunnel->err_count = 0;
 	}
 
-	skb->h.raw = skb->nh.raw;
-
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
@@ -626,6 +624,7 @@
 		old_iph = skb->nh.iph;
 	}
 
+	skb->h.raw = skb->nh.raw;
 	skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	dst_release(skb->dst);
diff -urN linux-2.4.23-pre6/net/ipv4/ipvs/ip_vs_conn.c linux-2.4.23-pre7/net/ipv4/ipvs/ip_vs_conn.c
--- linux-2.4.23-pre6/net/ipv4/ipvs/ip_vs_conn.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/ipvs/ip_vs_conn.c	2003-10-09 17:48:22.000000000 -0700
@@ -903,9 +903,8 @@
 			skb_realloc_headroom(skb, max_headroom);
 		if (!new_skb) {
 			ip_rt_put(rt);
-			kfree_skb(skb);
 			IP_VS_ERR_RL("ip_vs_tunnel_xmit(): no memory\n");
-			return -EINVAL;
+			return NF_DROP;
 		}
 		kfree_skb(skb);
 		skb = new_skb;
diff -urN linux-2.4.23-pre6/net/ipv4/ipvs/ip_vs_ftp.c linux-2.4.23-pre7/net/ipv4/ipvs/ip_vs_ftp.c
--- linux-2.4.23-pre6/net/ipv4/ipvs/ip_vs_ftp.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/ipvs/ip_vs_ftp.c	2003-10-09 17:48:22.000000000 -0700
@@ -88,39 +88,46 @@
 				  __u32 *addr, __u16 *port,
 				  char **start, char **end)
 {
-	unsigned char p1,p2,p3,p4,p5,p6;
+	unsigned char p[6];
+	int i = 0;
 
-	while (data < data_limit) {
-		if (strnicmp(data, pattern, plen) != 0) {
-			data++;
-			continue;
+	if (data_limit - data < plen) {
+		/* check if there is partial match */
+		if (strnicmp(data, pattern, data_limit - data) == 0)
+			return -1;
+		else
+			return 0;
+	}
+
+	if (strnicmp(data, pattern, plen) != 0) {
+		return 0;
+	}
+	*start = data + plen;
+
+	for (data = *start; *data != term; data++) {
+		if (data == data_limit)
+			return -1;
+	}
+	*end = data;
+
+	memset(p, 0, sizeof(p));
+	for (data = *start; data != *end; data++) {
+		if (*data >= '0' && *data <= '9') {
+			p[i] = p[i]*10 + *data - '0';
+		} else if (*data == ',' && i < 5) {
+			i++;
+		} else {
+			/* unexpected character */
+			return -1;
 		}
-		*start = data+plen;
-		p1 = simple_strtoul(data+plen, &data, 10);
-		if (*data != ',')
-			continue;
-		p2 = simple_strtoul(data+1, &data, 10);
-		if (*data != ',')
-			continue;
-		p3 = simple_strtoul(data+1, &data, 10);
-		if (*data != ',')
-			continue;
-		p4 = simple_strtoul(data+1, &data, 10);
-		if (*data != ',')
-			continue;
-		p5 = simple_strtoul(data+1, &data, 10);
-		if (*data != ',')
-			continue;
-		p6 = simple_strtoul(data+1, &data, 10);
-		if (*data != term)
-			continue;
-
-		*end = data;
-		*addr = (p4<<24) | (p3<<16) | (p2<<8) | p1;
-		*port = (p6<<8) | p5;
-		return 1;
 	}
-	return 0;
+
+	if (i != 5)
+		return -1;
+
+	*addr = (p[3]<<24) | (p[2]<<16) | (p[1]<<8) | p[0];
+	*port = (p[5]<<8) | p[4];
+	return 1;
 }
 
 
@@ -165,7 +172,7 @@
 					   SERVER_STRING,
 					   sizeof(SERVER_STRING)-1, ')',
 					   &from, &port,
-					   &start, &end) == 0)
+					   &start, &end) != 1)
 			return 0;
 
 		IP_VS_DBG(1-debug, "PASV response (%u.%u.%u.%u:%d) -> "
@@ -265,7 +272,7 @@
 	data = data_start = (char *)th + (th->doff << 2);
 	data_limit = skb->tail;
 
-	while (data < data_limit) {
+	while (data <= data_limit - 6) {
 		if (strnicmp(data, "PASV\r\n", 6) == 0) {
 			IP_VS_DBG(1-debug, "got PASV at %d of %d\n",
 				  data - data_start,
@@ -283,13 +290,10 @@
 	 * then create a new connection entry for the coming data
 	 * connection.
 	 */
-	data = data_start;
-	data_limit = skb->h.raw + skb->len - 18;
-
-	if (ip_vs_ftp_get_addrport(data, data_limit,
+	if (ip_vs_ftp_get_addrport(data_start, data_limit,
 				   CLIENT_STRING, sizeof(CLIENT_STRING)-1,
 				   '\r', &to, &port,
-				   &start, &end) == 0)
+				   &start, &end) != 1)
 		return 0;
 
 	IP_VS_DBG(1-debug, "PORT %u.%u.%u.%u:%d detected\n",
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_core.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_core.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_core.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_core.c	2003-10-09 17:48:22.000000000 -0700
@@ -60,7 +60,7 @@
 LIST_HEAD(protocol_list);
 static LIST_HEAD(helpers);
 unsigned int ip_conntrack_htable_size = 0;
-static int ip_conntrack_max = 0;
+int ip_conntrack_max = 0;
 static atomic_t ip_conntrack_count = ATOMIC_INIT(0);
 struct list_head *ip_conntrack_hash;
 static kmem_cache_t *ip_conntrack_cachep;
@@ -308,7 +308,7 @@
 static void
 destroy_conntrack(struct nf_conntrack *nfct)
 {
-	struct ip_conntrack *ct = (struct ip_conntrack *)nfct;
+	struct ip_conntrack *ct = (struct ip_conntrack *)nfct, *master = NULL;
 	struct ip_conntrack_protocol *proto;
 
 	DEBUGP("destroy_conntrack(%p)\n", ct);
@@ -335,12 +335,15 @@
 			/* can't call __unexpect_related here,
 			 * since it would screw up expect_list */
 			list_del(&ct->master->expected_list);
-			ip_conntrack_put(ct->master->expectant);
+			master = ct->master->expectant;
 		}
 		kfree(ct->master);
 	}
 	WRITE_UNLOCK(&ip_conntrack_lock);
 
+	if (master)
+		ip_conntrack_put(master);
+
 	DEBUGP("destroy_conntrack: returning ct=%p to slab\n", ct);
 	kmem_cache_free(ip_conntrack_cachep, ct);
 	atomic_dec(&ip_conntrack_count);
@@ -1305,9 +1308,14 @@
 getorigdst(struct sock *sk, int optval, void *user, int *len)
 {
 	struct ip_conntrack_tuple_hash *h;
-	struct ip_conntrack_tuple tuple = { { sk->rcv_saddr, { .tcp = { sk->sport } } },
-					    { sk->daddr, { .tcp = { sk->dport } },
-					      IPPROTO_TCP } };
+	struct ip_conntrack_tuple tuple;
+
+	IP_CT_TUPLE_U_BLANK(&tuple);
+	tuple.src.ip = sk->rcv_saddr;
+	tuple.src.u.tcp.port = sk->sport;
+	tuple.dst.ip = sk->daddr;
+	tuple.dst.u.tcp.port = sk->dport;
+	tuple.dst.protonum = IPPROTO_TCP;
 
 	/* We only do TCP at the moment: is there a better way? */
 	if (strcmp(sk->prot->name, "TCP") != 0) {
@@ -1351,29 +1359,6 @@
     SO_ORIGINAL_DST, SO_ORIGINAL_DST+1, &getorigdst,
     0, NULL };
 
-#define NET_IP_CONNTRACK_MAX 2089
-#define NET_IP_CONNTRACK_MAX_NAME "ip_conntrack_max"
-
-#ifdef CONFIG_SYSCTL
-static struct ctl_table_header *ip_conntrack_sysctl_header;
-
-static ctl_table ip_conntrack_table[] = {
-	{ NET_IP_CONNTRACK_MAX, NET_IP_CONNTRACK_MAX_NAME, &ip_conntrack_max,
-	  sizeof(ip_conntrack_max), 0644,  NULL, proc_dointvec },
- 	{ 0 }
-};
-
-static ctl_table ip_conntrack_dir_table[] = {
-	{NET_IPV4, "ipv4", NULL, 0, 0555, ip_conntrack_table, 0, 0, 0, 0, 0},
-	{ 0 }
-};
-
-static ctl_table ip_conntrack_root_table[] = {
-	{CTL_NET, "net", NULL, 0, 0555, ip_conntrack_dir_table, 0, 0, 0, 0, 0},
-	{ 0 }
-};
-#endif /*CONFIG_SYSCTL*/
-
 static int kill_all(const struct ip_conntrack *i, void *data)
 {
 	return 1;
@@ -1383,9 +1368,6 @@
    supposed to kill the mall. */
 void ip_conntrack_cleanup(void)
 {
-#ifdef CONFIG_SYSCTL
-	unregister_sysctl_table(ip_conntrack_sysctl_header);
-#endif
 	ip_ct_attach = NULL;
 	/* This makes sure all current packets have passed through
            netfilter framework.  Roll on, two-stage module
@@ -1464,25 +1446,10 @@
 	for (i = 0; i < ip_conntrack_htable_size; i++)
 		INIT_LIST_HEAD(&ip_conntrack_hash[i]);
 
-/* This is fucking braindead.  There is NO WAY of doing this without
-   the CONFIG_SYSCTL unless you don't want to detect errors.
-   Grrr... --RR */
-#ifdef CONFIG_SYSCTL
-	ip_conntrack_sysctl_header
-		= register_sysctl_table(ip_conntrack_root_table, 0);
-	if (ip_conntrack_sysctl_header == NULL) {
-		goto err_free_ct_cachep;
-	}
-#endif /*CONFIG_SYSCTL*/
-
 	/* For use by ipt_REJECT */
 	ip_ct_attach = ip_conntrack_attach;
 	return ret;
 
-#ifdef CONFIG_SYSCTL
-err_free_ct_cachep:
-	kmem_cache_destroy(ip_conntrack_cachep);
-#endif /*CONFIG_SYSCTL*/
 err_free_hash:
 	vfree(ip_conntrack_hash);
 err_unreg_sockopt:
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_irc.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_irc.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_irc.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_irc.c	2003-10-09 17:48:22.000000000 -0700
@@ -192,7 +192,10 @@
 			DEBUGP("DCC bound ip/port: %u.%u.%u.%u:%u\n",
 				HIPQUAD(dcc_ip), dcc_port);
 
-			if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)) {
+			/* dcc_ip can be the internal OR external (NAT'ed) IP
+			 * Tiago Sousa <mirage@kaotik.org> */
+			if (ct->tuplehash[dir].tuple.src.ip != htonl(dcc_ip)
+			    && ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.ip != htonl(dcc_ip)) {
 				if (net_ratelimit())
 					printk(KERN_WARNING
 						"Forged DCC command from "
@@ -218,7 +221,7 @@
 
 			exp->tuple = ((struct ip_conntrack_tuple)
 				{ { 0, { 0 } },
-				  { htonl(dcc_ip), { .tcp = { htons(dcc_port) } },
+				  { ct->tuplehash[dir].tuple.src.ip, { .tcp = { htons(dcc_port) } },
 				    IPPROTO_TCP }});
 			exp->mask = ((struct ip_conntrack_tuple)
 				{ { 0, { 0 } },
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_generic.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_generic.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2003-10-09 17:48:22.000000000 -0700
@@ -4,7 +4,7 @@
 #include <linux/netfilter.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
 
-#define GENERIC_TIMEOUT (600*HZ)
+unsigned long ip_ct_generic_timeout = 600*HZ;
 
 static int generic_pkt_to_tuple(const void *datah, size_t datalen,
 				struct ip_conntrack_tuple *tuple)
@@ -43,7 +43,7 @@
 		       struct iphdr *iph, size_t len,
 		       enum ip_conntrack_info conntrackinfo)
 {
-	ip_ct_refresh(conntrack, GENERIC_TIMEOUT);
+	ip_ct_refresh(conntrack, ip_ct_generic_timeout);
 	return NF_ACCEPT;
 }
 
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_icmp.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2002-11-28 15:53:15.000000000 -0800
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2003-10-09 17:48:22.000000000 -0700
@@ -6,7 +6,7 @@
 #include <linux/icmp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
 
-#define ICMP_TIMEOUT (30*HZ)
+unsigned long ip_ct_icmp_timeout = 30*HZ;
 
 #if 0
 #define DEBUGP printk
@@ -82,7 +82,7 @@
 			ct->timeout.function((unsigned long)ct);
 	} else {
 		atomic_inc(&ct->proto.icmp.count);
-		ip_ct_refresh(ct, ICMP_TIMEOUT);
+		ip_ct_refresh(ct, ip_ct_icmp_timeout);
 	}
 
 	return NF_ACCEPT;
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_tcp.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-10-09 17:48:22.000000000 -0700
@@ -49,20 +49,28 @@
 #define HOURS * 60 MINS
 #define DAYS * 24 HOURS
 
-
-static unsigned long tcp_timeouts[]
-= { 30 MINS, 	/*	TCP_CONNTRACK_NONE,	*/
-    5 DAYS,	/*	TCP_CONNTRACK_ESTABLISHED,	*/
-    2 MINS,	/*	TCP_CONNTRACK_SYN_SENT,	*/
-    60 SECS,	/*	TCP_CONNTRACK_SYN_RECV,	*/
-    2 MINS,	/*	TCP_CONNTRACK_FIN_WAIT,	*/
-    2 MINS,	/*	TCP_CONNTRACK_TIME_WAIT,	*/
-    10 SECS,	/*	TCP_CONNTRACK_CLOSE,	*/
-    60 SECS,	/*	TCP_CONNTRACK_CLOSE_WAIT,	*/
-    30 SECS,	/*	TCP_CONNTRACK_LAST_ACK,	*/
-    2 MINS,	/*	TCP_CONNTRACK_LISTEN,	*/
-};
-
+unsigned long ip_ct_tcp_timeout_syn_sent =      2 MINS;
+unsigned long ip_ct_tcp_timeout_syn_recv =     60 SECS;
+unsigned long ip_ct_tcp_timeout_established =   5 DAYS;
+unsigned long ip_ct_tcp_timeout_fin_wait =      2 MINS;
+unsigned long ip_ct_tcp_timeout_close_wait =    3 DAYS;
+unsigned long ip_ct_tcp_timeout_last_ack =     30 SECS;
+unsigned long ip_ct_tcp_timeout_time_wait =     2 MINS;
+unsigned long ip_ct_tcp_timeout_close =        10 SECS;
+
+static unsigned long * tcp_timeouts[]
+= { 0,                                 /*      TCP_CONNTRACK_NONE */
+    &ip_ct_tcp_timeout_established,    /*      TCP_CONNTRACK_ESTABLISHED,      */
+    &ip_ct_tcp_timeout_syn_sent,       /*      TCP_CONNTRACK_SYN_SENT, */
+    &ip_ct_tcp_timeout_syn_recv,       /*      TCP_CONNTRACK_SYN_RECV, */
+    &ip_ct_tcp_timeout_fin_wait,       /*      TCP_CONNTRACK_FIN_WAIT, */
+    &ip_ct_tcp_timeout_time_wait,      /*      TCP_CONNTRACK_TIME_WAIT,        */
+    &ip_ct_tcp_timeout_close,          /*      TCP_CONNTRACK_CLOSE,    */
+    &ip_ct_tcp_timeout_close_wait,     /*      TCP_CONNTRACK_CLOSE_WAIT,       */
+    &ip_ct_tcp_timeout_last_ack,       /*      TCP_CONNTRACK_LAST_ACK, */
+    0,                                 /*      TCP_CONNTRACK_LISTEN */
+ };
+ 
 #define sNO TCP_CONNTRACK_NONE
 #define sES TCP_CONNTRACK_ESTABLISHED
 #define sSS TCP_CONNTRACK_SYN_SENT
@@ -203,7 +211,7 @@
 			set_bit(IPS_ASSURED_BIT, &conntrack->status);
 
 		WRITE_UNLOCK(&tcp_lock);
-		ip_ct_refresh(conntrack, tcp_timeouts[newconntrack]);
+		ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
 	}
 
 	return NF_ACCEPT;
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_udp.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_udp.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-10-09 17:48:22.000000000 -0700
@@ -6,8 +6,8 @@
 #include <linux/udp.h>
 #include <linux/netfilter_ipv4/ip_conntrack_protocol.h>
 
-#define UDP_TIMEOUT (30*HZ)
-#define UDP_STREAM_TIMEOUT (180*HZ)
+unsigned long ip_ct_udp_timeout = 30*HZ;
+unsigned long ip_ct_udp_timeout_stream = 180*HZ;
 
 static int udp_pkt_to_tuple(const void *datah, size_t datalen,
 			    struct ip_conntrack_tuple *tuple)
@@ -52,11 +52,11 @@
 	/* If we've seen traffic both ways, this is some kind of UDP
 	   stream.  Extend timeout. */
 	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
-		ip_ct_refresh(conntrack, UDP_STREAM_TIMEOUT);
+		ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
 		/* Also, more likely to be important, and not a probe */
 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
 	} else
-		ip_ct_refresh(conntrack, UDP_TIMEOUT);
+		ip_ct_refresh(conntrack, ip_ct_udp_timeout);
 
 	return NF_ACCEPT;
 }
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_standalone.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_standalone.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_conntrack_standalone.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_conntrack_standalone.c	2003-10-09 17:48:22.000000000 -0700
@@ -7,6 +7,7 @@
 /* (c) 1999 Paul `Rusty' Russell.  Licenced under the GNU General
    Public Licence. */
 
+#include <linux/config.h>
 #include <linux/types.h>
 #include <linux/ip.h>
 #include <linux/netfilter.h>
@@ -16,6 +17,9 @@
 #include <linux/proc_fs.h>
 #include <linux/version.h>
 #include <linux/brlock.h>
+#ifdef CONFIG_SYSCTL
+#include <linux/sysctl.h>
+#endif
 #include <net/checksum.h>
 
 #define ASSERT_READ_LOCK(x) MUST_BE_READ_LOCKED(&ip_conntrack_lock)
@@ -239,6 +243,98 @@
 static struct nf_hook_ops ip_conntrack_local_in_ops
 = { { NULL, NULL }, ip_confirm, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_LAST-1 };
 
+/* Sysctl support */
+
+#ifdef CONFIG_SYSCTL
+
+/* From ip_conntrack_core.c */
+extern int ip_conntrack_max;
+
+/* From ip_conntrack_proto_tcp.c */
+extern unsigned long ip_ct_tcp_timeout_syn_sent;
+extern unsigned long ip_ct_tcp_timeout_syn_recv;
+extern unsigned long ip_ct_tcp_timeout_established;
+extern unsigned long ip_ct_tcp_timeout_fin_wait;
+extern unsigned long ip_ct_tcp_timeout_close_wait;
+extern unsigned long ip_ct_tcp_timeout_last_ack;
+extern unsigned long ip_ct_tcp_timeout_time_wait;
+extern unsigned long ip_ct_tcp_timeout_close;
+
+/* From ip_conntrack_proto_udp.c */
+extern unsigned long ip_ct_udp_timeout;
+extern unsigned long ip_ct_udp_timeout_stream;
+
+/* From ip_conntrack_proto_icmp.c */
+extern unsigned long ip_ct_icmp_timeout;
+
+/* From ip_conntrack_proto_icmp.c */
+extern unsigned long ip_ct_generic_timeout;
+
+static struct ctl_table_header *ip_ct_sysctl_header;
+
+static ctl_table ip_ct_sysctl_table[] = {
+	{NET_IPV4_NF_CONNTRACK_MAX, "ip_conntrack_max",
+	 &ip_conntrack_max, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_SENT, "ip_conntrack_tcp_timeout_syn_sent",
+	 &ip_ct_tcp_timeout_syn_sent, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_SYN_RECV, "ip_conntrack_tcp_timeout_syn_recv",
+	 &ip_ct_tcp_timeout_syn_recv, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_ESTABLISHED, "ip_conntrack_tcp_timeout_established",
+	 &ip_ct_tcp_timeout_established, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_FIN_WAIT, "ip_conntrack_tcp_timeout_fin_wait",
+	 &ip_ct_tcp_timeout_fin_wait, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE_WAIT, "ip_conntrack_tcp_timeout_close_wait",
+	 &ip_ct_tcp_timeout_close_wait, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_LAST_ACK, "ip_conntrack_tcp_timeout_last_ack",
+	 &ip_ct_tcp_timeout_last_ack, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_TIME_WAIT, "ip_conntrack_tcp_timeout_time_wait",
+	 &ip_ct_tcp_timeout_time_wait, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_TCP_TIMEOUT_CLOSE, "ip_conntrack_tcp_timeout_close",
+	 &ip_ct_tcp_timeout_close, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT, "ip_conntrack_udp_timeout",
+	 &ip_ct_udp_timeout, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_UDP_TIMEOUT_STREAM, "ip_conntrack_udp_timeout_stream",
+	 &ip_ct_udp_timeout_stream, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_ICMP_TIMEOUT, "ip_conntrack_icmp_timeout",
+	 &ip_ct_icmp_timeout, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{NET_IPV4_NF_CONNTRACK_GENERIC_TIMEOUT, "ip_conntrack_generic_timeout",
+	 &ip_ct_generic_timeout, sizeof(unsigned int), 0644, NULL,
+	 &proc_dointvec_jiffies},
+	{0}
+};
+
+#define NET_IP_CONNTRACK_MAX 2089
+
+static ctl_table ip_ct_netfilter_table[] = {
+	{NET_IPV4_NETFILTER, "netfilter", NULL, 0, 0555, ip_ct_sysctl_table, 0, 0, 0, 0, 0},
+	{NET_IP_CONNTRACK_MAX, "ip_conntrack_max",
+	 &ip_conntrack_max, sizeof(int), 0644, NULL,
+	 &proc_dointvec},
+	{0}
+};
+
+static ctl_table ip_ct_ipv4_table[] = {
+	{NET_IPV4, "ipv4", NULL, 0, 0555, ip_ct_netfilter_table, 0, 0, 0, 0, 0},
+	{0}
+};
+
+static ctl_table ip_ct_net_table[] = {
+	{CTL_NET, "net", NULL, 0, 0555, ip_ct_ipv4_table, 0, 0, 0, 0, 0},
+	{0}
+};
+#endif
 static int init_or_cleanup(int init)
 {
 	struct proc_dir_entry *proc;
@@ -274,10 +370,20 @@
 		printk("ip_conntrack: can't register local in hook.\n");
 		goto cleanup_inoutandlocalops;
 	}
+#ifdef CONFIG_SYSCTL
+	ip_ct_sysctl_header = register_sysctl_table(ip_ct_net_table, 0);
+	if (ip_ct_sysctl_header == NULL) {
+		printk("ip_conntrack: can't register to sysctl.\n");
+		goto cleanup;
+	}
+#endif
 
 	return ret;
 
  cleanup:
+#ifdef CONFIG_SYSCTL
+ 	unregister_sysctl_table(ip_ct_sysctl_header);
+#endif
 	nf_unregister_hook(&ip_conntrack_local_in_ops);
  cleanup_inoutandlocalops:
 	nf_unregister_hook(&ip_conntrack_out_ops);
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_core.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_core.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_core.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_core.c	2003-10-09 17:48:22.000000000 -0700
@@ -515,12 +515,14 @@
 	struct ip_conntrack_tuple new_tuple, inv_tuple, reply;
 	struct ip_conntrack_tuple orig_tp;
 	struct ip_nat_info *info = &conntrack->nat.info;
+	int in_hashes = info->initialized;
 
 	MUST_BE_WRITE_LOCKED(&ip_nat_lock);
 	IP_NF_ASSERT(hooknum == NF_IP_PRE_ROUTING
 		     || hooknum == NF_IP_POST_ROUTING
 		     || hooknum == NF_IP_LOCAL_OUT);
 	IP_NF_ASSERT(info->num_manips < IP_NAT_MAX_MANIPS);
+	IP_NF_ASSERT(!(info->initialized & (1 << HOOK2MANIP(hooknum))));
 
 	/* What we've got will look like inverse of reply. Normally
 	   this is what is in the conntrack, except for prior
@@ -637,6 +639,14 @@
 
 	/* It's done. */
 	info->initialized |= (1 << HOOK2MANIP(hooknum));
+
+	if (in_hashes) {
+		IP_NF_ASSERT(info->bysource.conntrack);
+		replace_in_hashes(conntrack, info);
+	} else {
+		place_in_hashes(conntrack, info);
+	}
+
 	return NF_ACCEPT;
 }
 
@@ -755,11 +765,6 @@
 	enum ip_conntrack_dir dir = CTINFO2DIR(ctinfo);
 	int is_tcp = (*pskb)->nh.iph->protocol == IPPROTO_TCP;
 
-	/* Skip everything and don't call helpers if there are no
-	 * manips for this connection */
-	if (info->num_manips == 0)
-		return NF_ACCEPT;
-
 	/* Need nat lock to protect against modification, but neither
 	   conntrack (referenced) and helper (deleted with
 	   synchronize_bh()) can vanish. */
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_helper.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_helper.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_helper.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_helper.c	2003-10-09 17:48:22.000000000 -0700
@@ -195,16 +195,11 @@
 		skb_trim(*skb, newlen);
 	}
 
-	/* fix checksum information */
-
 	iph->tot_len = htons(newlen);
-	(*skb)->csum = csum_partial((char *)tcph + tcph->doff*4,
-				    newtcplen - tcph->doff*4, 0);
-
+	/* fix checksum information */
 	tcph->check = 0;
 	tcph->check = tcp_v4_check(tcph, newtcplen, iph->saddr, iph->daddr,
-				   csum_partial((char *)tcph, tcph->doff*4,
-					   (*skb)->csum));
+				   csum_partial((char *)tcph, newtcplen, 0));
 	ip_send_check(iph);
 
 	return 1;
@@ -299,18 +294,12 @@
 	iph->tot_len = htons(newlen);
 
 	/* fix udp checksum if udp checksum was previously calculated */
-	if ((*skb)->csum != 0) {
-		(*skb)->csum = csum_partial((char *)udph +
-					    sizeof(struct udphdr),
-					    newudplen - sizeof(struct udphdr),
-					    0);
-
+	if (udph->check != 0) {
 		udph->check = 0;
 		udph->check = csum_tcpudp_magic(iph->saddr, iph->daddr,
 						newudplen, IPPROTO_UDP,
 						csum_partial((char *)udph,
-							 sizeof(struct udphdr),
-							(*skb)->csum));
+						             newudplen, 0));
 	}
 
 	ip_send_check(iph);
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_rule.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_rule.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_rule.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_rule.c	2003-10-09 17:48:22.000000000 -0700
@@ -230,7 +230,7 @@
 	return 1;
 }
 
-static inline unsigned int
+inline unsigned int
 alloc_null_binding(struct ip_conntrack *conntrack,
 		   struct ip_nat_info *info,
 		   unsigned int hooknum)
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_standalone.c linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_standalone.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ip_nat_standalone.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ip_nat_standalone.c	2003-10-09 17:48:22.000000000 -0700
@@ -115,7 +115,6 @@
 		/* Seen it before?  This can happen for loopback, retrans,
 		   or local packets.. */
 		if (!(info->initialized & (1 << maniptype))) {
-			int in_hashes = info->initialized;
 			unsigned int ret;
 
 			if (ct->master
@@ -126,9 +125,10 @@
 			} else {
 #ifdef CONFIG_IP_NF_NAT_LOCAL
 				/* LOCAL_IN hook doesn't have a chain!  */
-				if (hooknum == NF_IP_LOCAL_IN) {
-					ret = NF_ACCEPT;
-				} else
+				if (hooknum == NF_IP_LOCAL_IN)
+					ret = alloc_null_binding(ct, info,
+								 hooknum);
+				else
 #endif
 				ret = ip_nat_rule_find(pskb, hooknum, in, out,
 						       ct, info);
@@ -138,13 +138,6 @@
 				WRITE_UNLOCK(&ip_nat_lock);
 				return ret;
 			}
-
-			if (in_hashes) {
-				IP_NF_ASSERT(info->bysource.conntrack);
-				replace_in_hashes(ct, info);
-			} else {
-				place_in_hashes(ct, info);
-			}
 		} else
 			DEBUGP("Already setup manip %s for ct %p\n",
 			       maniptype == IP_NAT_MANIP_SRC ? "SRC" : "DST",
@@ -195,6 +188,7 @@
 	return ip_nat_fn(hooknum, pskb, in, out, okfn);
 }
 
+#ifdef CONFIG_IP_NF_NAT_LOCAL
 static unsigned int
 ip_nat_local_fn(unsigned int hooknum,
 		struct sk_buff **pskb,
@@ -220,6 +214,7 @@
 		return ip_route_me_harder(pskb) == 0 ? ret : NF_DROP;
 	return ret;
 }
+#endif
 
 /* We must be after connection tracking and before packet filtering. */
 
@@ -229,11 +224,12 @@
 /* After packet filtering, change source */
 static struct nf_hook_ops ip_nat_out_ops
 = { { NULL, NULL }, ip_nat_out, PF_INET, NF_IP_POST_ROUTING, NF_IP_PRI_NAT_SRC};
+
+#ifdef CONFIG_IP_NF_NAT_LOCAL
 /* Before packet filtering, change destination */
 static struct nf_hook_ops ip_nat_local_out_ops
 = { { NULL, NULL }, ip_nat_local_fn, PF_INET, NF_IP_LOCAL_OUT, NF_IP_PRI_NAT_DST };
-
-#ifdef CONFIG_IP_NF_NAT_LOCAL
+/* After packet filtering, change source for reply packets of LOCAL_OUT DNAT */
 static struct nf_hook_ops ip_nat_local_in_ops
 = { { NULL, NULL }, ip_nat_fn, PF_INET, NF_IP_LOCAL_IN, NF_IP_PRI_NAT_SRC };
 #endif
@@ -301,12 +297,12 @@
 		printk("ip_nat_init: can't register out hook.\n");
 		goto cleanup_inops;
 	}
+#ifdef CONFIG_IP_NF_NAT_LOCAL
 	ret = nf_register_hook(&ip_nat_local_out_ops);
 	if (ret < 0) {
 		printk("ip_nat_init: can't register local out hook.\n");
 		goto cleanup_outops;
 	}
-#ifdef CONFIG_IP_NF_NAT_LOCAL
 	ret = nf_register_hook(&ip_nat_local_in_ops);
 	if (ret < 0) {
 		printk("ip_nat_init: can't register local in hook.\n");
@@ -323,9 +319,9 @@
 #ifdef CONFIG_IP_NF_NAT_LOCAL
 	nf_unregister_hook(&ip_nat_local_in_ops);
  cleanup_localoutops:
-#endif
 	nf_unregister_hook(&ip_nat_local_out_ops);
  cleanup_outops:
+#endif
 	nf_unregister_hook(&ip_nat_out_ops);
  cleanup_inops:
 	nf_unregister_hook(&ip_nat_in_ops);
diff -urN linux-2.4.23-pre6/net/ipv4/netfilter/ipt_unclean.c linux-2.4.23-pre7/net/ipv4/netfilter/ipt_unclean.c
--- linux-2.4.23-pre6/net/ipv4/netfilter/ipt_unclean.c	2003-06-13 07:51:39.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/netfilter/ipt_unclean.c	2003-10-09 17:48:22.000000000 -0700
@@ -259,6 +259,24 @@
 #define	TH_ECE	0x40
 #define	TH_CWR	0x80
 
+/* table of valid flag combinations - ECE and CWR are always valid */
+static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
+{
+	[TH_SYN]			= 1,
+	[TH_SYN|TH_ACK]			= 1,
+	[TH_RST]			= 1,
+	[TH_RST|TH_ACK]			= 1,
+	[TH_RST|TH_ACK|TH_PUSH]		= 1,
+	[TH_FIN|TH_ACK]			= 1,
+	[TH_ACK]			= 1,
+	[TH_ACK|TH_PUSH]		= 1,
+	[TH_ACK|TH_URG]			= 1,
+	[TH_ACK|TH_URG|TH_PUSH]		= 1,
+	[TH_FIN|TH_ACK|TH_PUSH]		= 1,
+	[TH_FIN|TH_ACK|TH_URG]		= 1,
+	[TH_FIN|TH_ACK|TH_URG|TH_PUSH]	= 1
+};
+
 /* TCP-specific checks. */
 static int
 check_tcp(const struct iphdr *iph,
@@ -330,19 +348,7 @@
 
 	/* CHECK: TCP flags. */
 	tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
-	if (tcpflags != TH_SYN
-	    && tcpflags != (TH_SYN|TH_ACK)
-		&& tcpflags != TH_RST
-	    && tcpflags != (TH_RST|TH_ACK)
-	    && tcpflags != (TH_RST|TH_ACK|TH_PUSH)
-	    && tcpflags != (TH_FIN|TH_ACK)
-	    && tcpflags != TH_ACK
-	    && tcpflags != (TH_ACK|TH_PUSH)
-	    && tcpflags != (TH_ACK|TH_URG)
-	    && tcpflags != (TH_ACK|TH_URG|TH_PUSH)
-	    && tcpflags != (TH_FIN|TH_ACK|TH_PUSH)
-	    && tcpflags != (TH_FIN|TH_ACK|TH_URG)
-	    && tcpflags != (TH_FIN|TH_ACK|TH_URG|TH_PUSH)) {
+	if (!tcp_valid_flags[tcpflags]) {
 		limpk("TCP flags bad: %u\n", tcpflags);
 		return 0;
 	}
diff -urN linux-2.4.23-pre6/net/ipv4/tcp_ipv4.c linux-2.4.23-pre7/net/ipv4/tcp_ipv4.c
--- linux-2.4.23-pre6/net/ipv4/tcp_ipv4.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/tcp_ipv4.c	2003-10-09 17:48:22.000000000 -0700
@@ -189,7 +189,9 @@
 		if (sk != sk2 &&
 		    sk2->reuse <= 1 &&
 		    !ipv6_only_sock(sk2) &&
-		    sk->bound_dev_if == sk2->bound_dev_if) {
+		    (!sk->bound_dev_if ||
+		     !sk2->bound_dev_if ||
+		     sk->bound_dev_if == sk2->bound_dev_if)) {
 			if (!sk_reuse	||
 			    !sk2->reuse	||
 			    sk2->state == TCP_LISTEN) {
diff -urN linux-2.4.23-pre6/net/ipv4/udp.c linux-2.4.23-pre7/net/ipv4/udp.c
--- linux-2.4.23-pre6/net/ipv4/udp.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv4/udp.c	2003-10-09 17:48:22.000000000 -0700
@@ -164,7 +164,9 @@
 			if (sk2->num == snum &&
 			    sk2 != sk &&
 			    !ipv6_only_sock(sk2) &&
-			    sk2->bound_dev_if == sk->bound_dev_if &&
+			    (!sk2->bound_dev_if ||
+			     !sk->bound_dev_if ||
+			     sk2->bound_dev_if == sk->bound_dev_if) &&
 			    (!sk2->rcv_saddr ||
 			     !sk->rcv_saddr ||
 			     sk2->rcv_saddr == sk->rcv_saddr) &&
diff -urN linux-2.4.23-pre6/net/ipv6/mcast.c linux-2.4.23-pre7/net/ipv6/mcast.c
--- linux-2.4.23-pre6/net/ipv6/mcast.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv6/mcast.c	2003-10-09 17:48:22.000000000 -0700
@@ -2020,6 +2020,9 @@
 	struct ifmcaddr6 *i;
 	struct in6_addr maddr;
 
+	/* Deactivate timers */
+	ipv6_mc_down(idev);
+
 	/* Delete all-nodes address. */
 	ipv6_addr_all_nodes(&maddr);
 
diff -urN linux-2.4.23-pre6/net/ipv6/sit.c linux-2.4.23-pre7/net/ipv6/sit.c
--- linux-2.4.23-pre6/net/ipv6/sit.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv6/sit.c	2003-10-09 17:48:22.000000000 -0700
@@ -552,8 +552,6 @@
 			tunnel->err_count = 0;
 	}
 
-	skb->h.raw = skb->nh.raw;
-
 	/*
 	 * Okay, now see if we can stuff it in the buffer as-is.
 	 */
@@ -575,6 +573,7 @@
 		iph6 = skb->nh.ipv6h;
 	}
 
+	skb->h.raw = skb->nh.raw;
 	skb->nh.raw = skb_push(skb, sizeof(struct iphdr));
 	memset(&(IPCB(skb)->opt), 0, sizeof(IPCB(skb)->opt));
 	dst_release(skb->dst);
diff -urN linux-2.4.23-pre6/net/ipv6/tcp_ipv6.c linux-2.4.23-pre7/net/ipv6/tcp_ipv6.c
--- linux-2.4.23-pre6/net/ipv6/tcp_ipv6.c	2003-10-09 17:48:19.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv6/tcp_ipv6.c	2003-10-09 17:48:22.000000000 -0700
@@ -146,7 +146,9 @@
 			/* We must walk the whole port owner list in this case. -DaveM */
 			for( ; sk2 != NULL; sk2 = sk2->bind_next) {
 				if (sk != sk2 &&
-				    sk->bound_dev_if == sk2->bound_dev_if) {
+				    (!sk->bound_dev_if ||
+				     !sk2->bound_dev_if ||
+				     sk->bound_dev_if == sk2->bound_dev_if)) {
 					if (!sk_reuse	||
 					    !sk2->reuse	||
 					    sk2->state == TCP_LISTEN) {
diff -urN linux-2.4.23-pre6/net/ipv6/udp.c linux-2.4.23-pre7/net/ipv6/udp.c
--- linux-2.4.23-pre6/net/ipv6/udp.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/ipv6/udp.c	2003-10-09 17:48:22.000000000 -0700
@@ -108,7 +108,9 @@
 		     sk2 = sk2->next) {
 			if (sk2->num == snum &&
 			    sk2 != sk &&
-			    sk2->bound_dev_if == sk->bound_dev_if &&
+			    (!sk2->bound_dev_if ||
+			     !sk->bound_dev_if ||
+			     sk2->bound_dev_if == sk->bound_dev_if) &&
 			    ((!sk2->rcv_saddr && !ipv6_only_sock(sk)) ||
 			     (sk2->family == AF_INET6 && 
 			      ipv6_addr_any(&sk2->net_pinfo.af_inet6.rcv_saddr) &&
diff -urN linux-2.4.23-pre6/net/netlink/af_netlink.c linux-2.4.23-pre7/net/netlink/af_netlink.c
--- linux-2.4.23-pre6/net/netlink/af_netlink.c	2003-08-25 04:44:44.000000000 -0700
+++ linux-2.4.23-pre7/net/netlink/af_netlink.c	2003-10-09 17:48:22.000000000 -0700
@@ -846,8 +846,17 @@
 		size = NLMSG_SPACE(4 + NLMSG_ALIGN(nlh->nlmsg_len));
 
 	skb = alloc_skb(size, GFP_KERNEL);
-	if (!skb)
-		return;
+	if (!skb) {
+		struct sock *sk;
+
+		sk = netlink_lookup(in_skb->sk->protocol,
+				    NETLINK_CB(in_skb).pid);
+		if (sk) {
+			sk->err = ENOBUFS;
+			sk->error_report(sk);
+			sock_put(sk);
+		}
+	}
 
 	rep = __nlmsg_put(skb, NETLINK_CB(in_skb).pid, nlh->nlmsg_seq,
 			  NLMSG_ERROR, sizeof(struct nlmsgerr));
diff -urN linux-2.4.23-pre6/scripts/mkuboot.sh linux-2.4.23-pre7/scripts/mkuboot.sh
--- linux-2.4.23-pre6/scripts/mkuboot.sh	1969-12-31 16:00:00.000000000 -0800
+++ linux-2.4.23-pre7/scripts/mkuboot.sh	2003-10-09 17:48:22.000000000 -0700
@@ -0,0 +1,16 @@
+#!/bin/bash
+
+#
+# Build U-Boot image when `mkimage' tool is available.
+#
+
+MKIMAGE=$(type -path mkimage)
+
+if [ -z "${MKIMAGE}" ]; then
+	# Doesn't exist
+	echo '"mkimage" command not found - U-Boot images will not be built' >&2
+	exit 0;
+fi
+
+# Call "mkimage" to create U-Boot image
+${MKIMAGE} "$@"
