diff -Naur linux.2210/Documentation/Configure.help linux.2210.vw/Documentation/Configure.help
--- linux.2210/Documentation/Configure.help	Sun Jun 13 19:54:06 1999
+++ linux.2210.vw/Documentation/Configure.help	Wed Jul 28 08:56:41 1999
@@ -9681,6 +9681,12 @@
   you compiled aedsp16.o as a module you can specify this parameter as
   'mpu_irq=NN'.
 
+SGI Visual Workstation on-board audio
+CONFIG_SOUND_VWSND
+  Say Y or M if you have an SGI Visual Workstation and you want to
+  be able to use its on-board audio.  Read Documentation/sound/visws
+  for more info on this driver's capabilities.
+
 Ensoniq ES1370 based PCI sound cards
 CONFIG_SOUND_ES1370
   Say Y or M if you have a PCI sound card utilizing the Ensoniq
diff -Naur linux.2210/Documentation/sound/vwsnd linux.2210.vw/Documentation/sound/vwsnd
--- linux.2210/Documentation/sound/vwsnd	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/Documentation/sound/vwsnd	Wed Jul 28 08:56:41 1999
@@ -0,0 +1,285 @@
+vwsnd - Sound driver for the Silicon Graphics 320 and 540 Visual
+Workstations' onboard audio.
+
+Copyright 1999 Silicon Graphics, Inc.  All rights reserved.
+
+
+At the time of this writing, March 1999, there are two models of
+Visual Workstation, the 320 and the 540.  This document only describes
+those models.  Future Visual Workstation models may have different
+sound capabilities, and this driver will probably not work on those
+boxes.
+
+The Visual Workstation has an Analog Devices AD1843 "SoundComm" audio
+codec chip.  The AD1843 is accessed through the Cobalt I/O ASIC, also
+known as Lithium.  This driver programs both both chips.
+
+==============================================================================
+QUICK CONFIGURATION
+
+	# insmod soundcore
+	# insmod vwsnd
+
+==============================================================================
+I/O CONNECTIONS
+
+On the Visual Workstation, only three of the AD1843 inputs are hooked
+up.  The analog line in jacks are connected to the AD1843's AUX1
+input.  The CD audio lines are connected to the AD1843's AUX2 input.
+The microphone jack is connected to the AD1843's MIC input.  The mic
+jack is mono, but the signal is delivered to both the left and right
+MIC inputs.  You can record in stereo from the mic input, but you will
+get the same signal on both channels (within the limits of A/D
+accuracy).  Full scale on the Line input is +/- 2.0 V.  Full scale on
+the MIC input is 20 dB less, or +/- 0.2 V.
+
+The AD1843's LOUT1 outputs are connected to the Line Out jacks.  The
+AD1843's HPOUT outputs are connected to the speaker/headphone jack.
+LOUT2 is not connected.  Line out's maximum level is +/- 2.0 V peak to
+peak.  The speaker/headphone out's maximum is +/- 4.0 V peak to peak.
+
+The AD1843's PCM input channel and one of its output channels (DAC1)
+are connected to Lithium.  The other output channel (DAC2) is not
+connected.
+
+==============================================================================
+CAPABILITIES
+
+The AD1843 has PCM input and output (Pulse Code Modulation, also known
+as wavetable).  PCM input and output can be mono or stereo in any of
+four formats.  The formats are 16 bit signed and 8 bit unsigned,
+u-Law, and A-Law format.  Any sample rate from 4 KHz to 49 KHz is
+available, in 1 Hz increments.
+
+The AD1843 includes an analog mixer that can mix all three input
+signals (line, mic and CD) into the analog outputs.  The mixer has a
+separate gain control and mute switch for each input.
+
+There are two outputs, line out and speaker/headphone out.  They
+always produce the same signal, and the speaker always has 3 dB more
+gain than the line out.  The speaker/headphone output can be muted,
+but this driver does not export that function.
+
+The hardware can sync audio to the video clock, but this driver does
+not have a way to specify syncing to video.
+
+==============================================================================
+PROGRAMMING
+
+This section explains the API supported by the driver.  Also see the
+Open Sound Programming Guide at http://www.opensound.com/pguide/ .
+This section assumes familiarity with that document.
+
+The driver has two interfaces, an I/O interface and a mixer interface.
+There is no MIDI or sequencer capability.
+
+==============================================================================
+PROGRAMMING PCM I/O
+
+The I/O interface is usually accessed as /dev/audio or /dev/dsp.
+Using the standard Open Sound System (OSS) ioctl calls, the sample
+rate, number of channels, and sample format may be set within the
+limitations described above.  The driver supports triggering.  It also
+supports getting the input and output pointers with one-sample
+accuracy.  XXX GETISPACE and GETOSPACE aren't implemented yet.
+
+The SNDCTL_DSP_GETCAP ioctl returns these capabilities.
+
+	DSP_CAP_DUPLEX - driver supports full duplex.
+
+	DSP_CAP_TRIGGER - driver supports triggering.
+
+	not DSP_CAP_REALTIME - Not yet implemented.
+
+Memory mapping (mmap) is not implemented.
+
+When this driver is switched into or out of mu-Law or A-Law mode on
+output, it may produce an audible click.  This is unavoidable.  To
+prevent clicking, use signed 16-bit mode instead, and convert from
+mu-Law or A-Law format in software.
+
+==============================================================================
+PROGRAMMING THE MIXER INTERFACE
+
+The mixer interface is usually accessed as /dev/mixer.  It is accessed
+through ioctls.  The mixer allows the application to control gain or
+mute several audio signal paths, and also allows selection of the
+recording source.
+
+Each of the constants described here can be read using the
+MIXER_READ(SOUND_MIXER_xxx) ioctl.  Those that are not read-only can
+also be written using the MIXER_WRITE(SOUND_MIXER_xxx) ioctl.  In most
+cases, <sys/soundcard.h> defines constants SOUND_MIXER_READ_xxx and
+SOUND_MIXER_WRITE_xxx which work just as well.
+
+SOUND_MIXER_CAPS	Read-only
+
+This is a mask of optional driver capabilities that are implemented.
+This driver's only capability is SOUND_CAP_EXCL_INPUT, which means
+that only one recording source can be active at a time.
+
+SOUND_MIXER_DEVMASK	Read-only
+
+This is a mask of the sound channels.  This driver's channels are PCM,
+LINE, MIC, CD, and RECLEV.
+
+SOUND_MIXER_STEREODEVS	Read-only
+
+This is a mask of which sound channels are capable of stereo.  All
+channels are capable of stereo.  (But see caveat on MIC input in I/O
+CONNECTIONS section above).
+
+SOUND_MIXER_OUTMASK	Read-only
+
+This is a mask of channels that route inputs through to outputs.
+Those are LINE, MIC, and CD.
+
+SOUND_MIXER_RECMASK	Read-only
+
+This is a mask of channels that can be recording sources.  Those are
+PCM, LINE, MIC, CD.
+
+SOUND_MIXER_PCM		Default: 0x5757 (0 dB)
+
+This is the gain control for PCM output.  The left and right channel
+gain are controlled independently.  This gain control has 64 levels,
+which range from -82.5 dB to +12.0 dB in 1.5 dB steps.  Those 64
+levels are mapped onto 100 levels at the ioctl, see below.
+
+SOUND_MIXER_LINE	Default: 0x4a4a (0 dB)
+
+This is the gain control for mixing the Line In source into the
+outputs.  The left and right channel gain are controlled
+independently.  This gain control has 32 levels, which range from
+-34.5 dB to +12.0 dB in 1.5 dB steps.  Those 32 levels are mapped onto
+100 levels at the ioctl, see below.
+
+SOUND_MIXER_MIC		Default: 0x4a4a (0 dB)
+
+This is the gain control for mixing the MIC source into the outputs.
+The left and right channel gain are controlled independently.  This
+gain control has 32 levels, which range from -34.5 dB to +12.0 dB in
+1.5 dB steps.  Those 32 levels are mapped onto 100 levels at the
+ioctl, see below.
+
+SOUND_MIXER_CD		Default: 0x4a4a (0 dB)
+
+This is the gain control for mixing the CD audio source into the
+outputs.  The left and right channel gain are controlled
+independently.  This gain control has 32 levels, which range from
+-34.5 dB to +12.0 dB in 1.5 dB steps.  Those 32 levels are mapped onto
+100 levels at the ioctl, see below.
+
+SOUND_MIXER_RECLEV	 Default: 0 (0 dB)
+
+This is the gain control for PCM input (RECording LEVel).  The left
+and right channel gain are controlled independently.  This gain
+control has 16 levels, which range from 0 dB to +22.5 dB in 1.5 dB
+steps.  Those 16 levels are mapped onto 100 levels at the ioctl, see
+below.
+
+SOUND_MIXER_RECSRC	 Default: SOUND_MASK_LINE
+
+This is a mask of currently selected PCM input sources (RECording
+SouRCes).  Because the AD1843 can only have a single recording source
+at a time, only one bit at a time can be set in this mask.  The
+allowable values are SOUND_MASK_PCM, SOUND_MASK_LINE, SOUND_MASK_MIC,
+or SOUND_MASK_CD.  Selecting SOUND_MASK_PCM sets up internal
+resampling which is useful for loopback testing and for hardware
+sample rate conversion.  But software sample rate conversion is
+probably faster, so I don't know how useful that is.
+
+SOUND_MIXER_OUTSRC	DEFAULT: SOUND_MASK_LINE|SOUND_MASK_MIC|SOUND_MASK_CD
+
+This is a mask of sources that are currently passed through to the
+outputs.  Those sources whose bits are not set are muted.
+
+==============================================================================
+GAIN CONTROL
+
+There are five gain controls listed above.  Each has 16, 32, or 64
+steps.  Each control has 1.5 dB of gain per step.  Each control is
+stereo.
+
+The OSS defines the argument to a channel gain ioctl as having two
+components, left and right, each of which ranges from 0 to 100.  The
+two components are packed into the same word, with the left side gain
+in the least significant byte, and the right side gain in the second
+least significant byte.  In C, we would say this.
+
+	#include <assert.h>
+
+	...
+
+	 	assert(leftgain >= 0 && leftgain <= 100);
+		assert(rightgain >= 0 && rightgain <= 100);
+		arg = leftgain | rightgain << 8;
+
+So each OSS gain control has 101 steps.  But the hardware has 16, 32,
+or 64 steps.  The hardware steps are spread across the 101 OSS steps
+nearly evenly.  The conversion formulas are like this, given N equals
+16, 32, or 64.
+
+	int round = N/2 - 1;
+	OSS_gain_steps = (hw_gain_steps * 100 + round) / (N - 1);
+	hw_gain_steps = (OSS_gain_steps * (N - 1) + round) / 100;
+
+Here is a snippet of C code that will return the left and right gain
+of any channel in dB.  Pass it one of the predefined gain_desc_t
+structures to access any of the five channels' gains.
+
+	typedef struct gain_desc {
+		float min_gain;
+		float gain_step;
+		int nbits;
+		int chan;
+	} gain_desc_t;
+
+	const gain_desc_t gain_pcm    = { -82.5, 1.5, 6, SOUND_MIXER_PCM    };
+	const gain_desc_t gain_line   = { -34.5, 1.5, 5, SOUND_MIXER_LINE   };
+	const gain_desc_t gain_mic    = { -34.5, 1.5, 5, SOUND_MIXER_MIC    };
+	const gain_desc_t gain_cd     = { -34.5, 1.5, 5, SOUND_MIXER_CD     };
+	const gain_desc_t gain_reclev = {   0.0, 1.5, 4, SOUND_MIXER_RECLEV };
+
+	int get_gain_dB(int fd, const gain_desc_t *gp,
+			float *left, float *right)
+	{
+		int word;
+		int lg, rg;
+		int mask = (1 << gp->nbits) - 1;
+
+		if (ioctl(fd, MIXER_READ(gp->chan), &word) != 0)
+			return -1;	/* fail */
+		lg = word & 0xFF;
+		rg = word >> 8 & 0xFF;
+		lg = (lg * mask + mask / 2) / 100;
+		rg = (rg * mask + mask / 2) / 100;
+		*left = gp->min_gain + gp->gain_step * lg;
+		*right = gp->min_gain + gp->gain_step * rg;
+		return 0;
+	}	
+
+And here is the corresponding routine to set a channel's gain in dB.
+
+	int set_gain_dB(int fd, const gain_desc_t *gp, float left, float right)
+	{
+		float max_gain =
+			gp->min_gain + (1 << gp->nbits) * gp->gain_step;
+		float round = gp->gain_step / 2;
+		int mask = (1 << gp->nbits) - 1;
+		int word;
+		int lg, rg;
+
+		if (left < gp->min_gain || right < gp->min_gain)
+			return EINVAL;
+		lg = (left - gp->min_gain + round) / gp->gain_step;
+		rg = (right - gp->min_gain + round) / gp->gain_step;
+		if (lg >= (1 << gp->nbits) || rg >= (1 << gp->nbits))
+			return EINVAL;
+		lg = (100 * lg + mask / 2) / mask;
+		rg = (100 * rg + mask / 2) / mask;
+		word = lg | rg << 8;
+
+		return ioctl(fd, MIXER_WRITE(gp->chan), &word);
+	}
+
diff -Naur linux.2210/Makefile linux.2210.vw/Makefile
--- linux.2210/Makefile	Fri May 28 18:10:19 1999
+++ linux.2210.vw/Makefile	Wed Jul 28 08:56:41 1999
@@ -18,7 +18,7 @@
 HOSTCC  	=gcc
 HOSTCFLAGS	=-Wall -Wstrict-prototypes -O2 -fomit-frame-pointer
 
-CROSS_COMPILE 	=
+CROSS_COMPILE 	= 
 
 AS	=$(CROSS_COMPILE)as
 LD	=$(CROSS_COMPILE)ld
@@ -91,6 +91,11 @@
 ifdef CONFIG_SMP
 CFLAGS += -D__SMP__
 AFLAGS += -D__SMP__
+endif
+
+ifdef CONFIG_VISWS
+CFLAGS += -DCONFIG_VISWS_HACKS
+AFLAGS += -DCONFIG_VISWS_HACKS
 endif
 
 #
diff -Naur linux.2210/arch/i386/config.in linux.2210.vw/arch/i386/config.in
--- linux.2210/arch/i386/config.in	Mon Apr 26 13:49:17 1999
+++ linux.2210.vw/arch/i386/config.in	Wed Jul 28 08:56:41 1999
@@ -194,6 +194,8 @@
 fi
 endmenu
 
+source drivers/usb/Config.in
+
 mainmenu_option next_comment
 comment 'Kernel hacking'
 
diff -Naur linux.2210/arch/i386/kernel/bios32.c linux.2210.vw/arch/i386/kernel/bios32.c
--- linux.2210/arch/i386/kernel/bios32.c	Sat Apr 24 17:49:37 1999
+++ linux.2210.vw/arch/i386/kernel/bios32.c	Wed Jul 28 08:56:41 1999
@@ -352,6 +352,7 @@
  *
  * This should be close to trivial, but it isn't, because there are buggy
  * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
+ * XXX maybe Lithium is "buggy" this way as well?
  */
 __initfunc(int pci_sanity_check(struct pci_access *a))
 {
@@ -1145,7 +1146,12 @@
 				pci_write_config_word(dev, PCI_COMMAND, cmd);
 			}
 		}
-#if defined(CONFIG_X86_IO_APIC)
+#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC)
+#ifdef	CONFIG_X86_IO_APIC
+#define	PCI_IRQ(b,s,p)		IO_APIC_get_PCI_irq_vector(b,s,p)
+#elif	CONFIG_X86_VISWS_APIC
+#define	PCI_IRQ(b,s,p)		visws_get_PCI_irq_vector(b,s,p)
+#endif
 		/*
 		 * Recalculate IRQ numbers if we use the I/O APIC
 		 */
@@ -1157,13 +1163,14 @@
 			pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
 			if (pin) {
 				pin--;		/* interrupt pins are numbered starting from 1 */
-				irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin);
+				irq = PCI_IRQ(dev->bus->number,
+						PCI_SLOT(dev->devfn), pin);
 				if (irq < 0 && dev->bus->parent) { /* go back to the bridge */
 					struct pci_dev * bridge = dev->bus->self;
 
 					pin = (pin + PCI_SLOT(dev->devfn)) % 4;
-					irq = IO_APIC_get_PCI_irq_vector(bridge->bus->number, 
-							PCI_SLOT(bridge->devfn), pin);
+					irq = PCI_IRQ(bridge->bus->number, 
+						PCI_SLOT(bridge->devfn), pin);
 					if (irq >= 0)
 						printk(KERN_WARNING "PCI: using PPB(B%d,I%d,P%d) to get irq %d\n", 
 							bridge->bus->number, PCI_SLOT(bridge->devfn), pin, irq);
diff -Naur linux.2210/arch/i386/kernel/head.S linux.2210.vw/arch/i386/kernel/head.S
--- linux.2210/arch/i386/kernel/head.S	Thu Jan 14 22:57:25 1999
+++ linux.2210.vw/arch/i386/kernel/head.S	Wed Jul 28 08:56:41 1999
@@ -40,6 +40,12 @@
 ENTRY(stext)
 ENTRY(_stext)
 startup_32:
+#ifdef CONFIG_VISWS_HACKS
+	movl $0x101000,%eax
+	movl %eax,%cr3
+	lgdt gdt_descr
+	lidt idt_descr
+#endif
 /*
  * Set segments to known values
  */
diff -Naur linux.2210/arch/i386/kernel/i386_ksyms.c linux.2210.vw/arch/i386/kernel/i386_ksyms.c
--- linux.2210/arch/i386/kernel/i386_ksyms.c	Mon May 10 10:32:45 1999
+++ linux.2210.vw/arch/i386/kernel/i386_ksyms.c	Wed Jul 28 08:56:41 1999
@@ -115,3 +115,10 @@
 #ifdef CONFIG_VT
 EXPORT_SYMBOL(screen_info);
 #endif
+
+#ifdef CONFIG_VISWS_HACKS
+extern u_long sgivw_gfx_mem_phys;
+extern u_long sgivw_gfx_mem_size;
+EXPORT_SYMBOL(sgivw_gfx_mem_phys);
+EXPORT_SYMBOL(sgivw_gfx_mem_size);
+#endif
diff -Naur linux.2210/arch/i386/kernel/io_apic.c linux.2210.vw/arch/i386/kernel/io_apic.c
--- linux.2210/arch/i386/kernel/io_apic.c	Thu May  6 16:07:03 1999
+++ linux.2210.vw/arch/i386/kernel/io_apic.c	Wed Jul 28 08:56:41 1999
@@ -558,27 +558,6 @@
 	return 0;
 }
 
-int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 };
-
-static int __init assign_irq_vector(int irq)
-{
-	static int current_vector = IRQ0_TRAP_VECTOR, offset = 0;
-	if (IO_APIC_VECTOR(irq) > 0)
-		return IO_APIC_VECTOR(irq);
-	current_vector += 8;
-	if (current_vector > 0xFE) {
-		offset++;
-		current_vector = IRQ0_TRAP_VECTOR + offset;
-		printk("WARNING: ASSIGN_IRQ_VECTOR wrapped back to %02X\n",
-		       current_vector);
-	}
-	if (current_vector == SYSCALL_VECTOR)
-		panic("ran out of interrupt sources!");
-
-	IO_APIC_VECTOR(irq) = current_vector;
-	return current_vector;
-}
-
 void __init setup_IO_APIC_irqs(void)
 {
 	struct IO_APIC_route_entry entry;
@@ -985,7 +964,7 @@
 
 	if ((status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING) {
 		desc->status = status | IRQ_REPLAY;
-		send_IPI_self(IO_APIC_VECTOR(irq));
+		send_IPI_self(IRQ_VECTOR(irq));
 	}
 }
 
@@ -1175,7 +1154,7 @@
 	 * 0x80, because int 0x80 is hm, kind of importantish. ;)
 	 */
 	for (i = 0; i < NR_IRQS ; i++) {
-		if (IO_APIC_VECTOR(i) > 0) {
+		if (IRQ_VECTOR(i) > 0) {
 			if (IO_APIC_irq_trigger(i))
 				irq_desc[i].handler = &ioapic_level_irq_type;
 			else
@@ -1203,7 +1182,7 @@
 			irq_desc[i].handler = &no_irq_type;
 		}
 	}
-	init_IRQ_SMP();
+	init_IRQ_MORE_TRAPS();
 }
 
 /*
diff -Naur linux.2210/arch/i386/kernel/irq.c linux.2210.vw/arch/i386/kernel/irq.c
--- linux.2210/arch/i386/kernel/irq.c	Mon May 10 10:32:45 1999
+++ linux.2210.vw/arch/i386/kernel/irq.c	Wed Jul 28 08:56:41 1999
@@ -292,7 +292,7 @@
  */
 BUILD_16_IRQS(0x0)
 
-#ifdef CONFIG_X86_IO_APIC
+#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC)
 /*
  * The IO-APIC gives us many more interrupt sources. Most of these 
  * are unused but an SMP system is supposed to have enough memory ...
@@ -348,7 +348,7 @@
 static void (*interrupt[NR_IRQS])(void) = {
 	IRQLIST_16(0x0),
 
-#ifdef CONFIG_X86_IO_APIC
+#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC)
 	                 IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3),
 	IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7),
 	IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb),
@@ -955,6 +955,11 @@
  */
 unsigned long probe_irq_on(void)
 {
+#ifdef CONFIG_VISWS_HACKS
+/* XXX current startup/shutdown_cobalt_irq() code
+ * XXX will break if we use it this way
+ */
+#else
 	unsigned int i;
 	unsigned long delay;
 
@@ -993,7 +998,7 @@
 		}
 	}
 	spin_unlock_irq(&irq_controller_lock);
-
+#endif
 	return 0x12345678;
 }
 
@@ -1006,6 +1011,12 @@
 
 	nr_irqs = 0;
 	irq_found = 0;
+#ifdef CONFIG_VISWS_HACKS
+/* XXX we _could_ look in the 8259 and if we see what we
+ * XXX know is IDEn we can here return the proper
+ * XXX cobalt-direct entry... hmmm
+ */
+#else
 	spin_lock_irq(&irq_controller_lock);
 	for (i=0; i<NR_IRQS; i++) {
 		unsigned int status = irq_desc[i].status;
@@ -1025,9 +1036,34 @@
 
 	if (nr_irqs > 1)
 		irq_found = -irq_found;
+#endif
 	return irq_found;
 }
 
+#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC)
+
+int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 };
+
+int __init assign_irq_vector(int irq)
+{
+	static int current_vector = IRQ0_TRAP_VECTOR, offset = 0;
+	if (IRQ_VECTOR(irq) > 0)
+		return IRQ_VECTOR(irq);
+	current_vector += 8;
+	if (current_vector > 0xFE) {
+		offset++;
+		current_vector = IRQ0_TRAP_VECTOR + offset;
+		printk("WARNING: ASSIGN_IRQ_VECTOR wrapped back to %02X\n",
+		       current_vector);
+	}
+	if (current_vector == SYSCALL_VECTOR)
+		panic("ran out of interrupt sources!");
+
+	IRQ_VECTOR(irq) = current_vector;
+	return current_vector;
+}
+#endif
+
 void init_ISA_irqs (void)
 {
 	int i;
@@ -1055,11 +1091,6 @@
 {
 	int i;
 
-#ifndef CONFIG_X86_VISWS_APIC
-	init_ISA_irqs();
-#else
-	init_VISWS_APIC_irqs();
-#endif
 	/*
 	 * Cover the whole vector space, no vector can escape
 	 * us. (some of these will be overridden and become
@@ -1071,11 +1102,17 @@
 			set_intr_gate(vector, interrupt[i]);
 	}
 
+#ifndef CONFIG_X86_VISWS_APIC
+	init_ISA_irqs();
+#else
+	init_VISWS_APIC_irqs();
+#endif
+
 #ifdef __SMP__	
 
 	/*
 	  IRQ0 must be given a fixed assignment and initialized
-	  before init_IRQ_SMP.
+	  before init_IRQ_MORE_TRAPS.
 	*/
 	set_intr_gate(IRQ0_TRAP_VECTOR, interrupt[0]);
 
@@ -1117,13 +1154,52 @@
 #endif
 }
 
-#ifdef CONFIG_X86_IO_APIC
-__initfunc(void init_IRQ_SMP(void))
+#if defined(CONFIG_X86_IO_APIC) || defined(CONFIG_X86_VISWS_APIC)
+/*
+ * An IO-APIC PC has more traps if SMP.
+ * The Visual Workstation always has more traps (whether SMP or not).
+ */
+__initfunc(void init_IRQ_MORE_TRAPS(void))
 {
 	int i;
 	for (i = 0; i < NR_IRQS ; i++)
-		if (IO_APIC_VECTOR(i) > 0)
-			set_intr_gate(IO_APIC_VECTOR(i), interrupt[i]);
+		if (IRQ_VECTOR(i) > 0)
+			set_intr_gate(IRQ_VECTOR(i), interrupt[i]);
 }
-#endif
 
+/*
+ * Visual Workstation always uses the cpu/local APICs for interrupts.
+ * IO-APIC PCs use this only when SMP
+ */
+void __init enable_local_APIC(void)
+{
+	unsigned long value;
+
+ 	value = apic_read(APIC_SPIV);
+ 	value |= (1<<8);		/* Enable APIC (bit==1) */
+ 	value &= ~(1<<9);		/* Enable focus processor (bit==0) */
+	value |= 0xff;			/* Set spurious IRQ vector to 0xff */
+ 	apic_write(APIC_SPIV,value);
+
+	/*
+	 * Set Task Priority to 'accept all'
+	 */
+ 	value = apic_read(APIC_TASKPRI);
+ 	value &= ~APIC_TPRI_MASK;
+ 	apic_write(APIC_TASKPRI,value);
+
+	/*
+	 * Clear the logical destination ID, just to be safe.
+	 * also, put the APIC into flat delivery mode.
+	 */
+ 	value = apic_read(APIC_LDR);
+	value &= ~APIC_LDR_MASK;
+ 	apic_write(APIC_LDR,value);
+
+ 	value = apic_read(APIC_DFR);
+	value |= SET_APIC_DFR(0xf);
+ 	apic_write(APIC_DFR, value);
+
+	udelay(100);			/* B safe */
+}
+#endif
diff -Naur linux.2210/arch/i386/kernel/irq.h linux.2210.vw/arch/i386/kernel/irq.h
--- linux.2210/arch/i386/kernel/irq.h	Tue May 11 10:37:06 1999
+++ linux.2210.vw/arch/i386/kernel/irq.h	Wed Jul 28 14:25:55 1999
@@ -79,9 +79,10 @@
 
 extern irq_desc_t irq_desc[NR_IRQS];
 extern int irq_vector[NR_IRQS];
-#define IO_APIC_VECTOR(irq)	irq_vector[irq]
+#define IRQ_VECTOR(irq)	irq_vector[irq]
 
-extern void init_IRQ_SMP(void);
+extern int assign_irq_vector(int irq);
+extern void init_IRQ_MORE_TRAPS(void);
 extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *);
 extern int setup_x86_irq(unsigned int, struct irqaction *);
 
@@ -102,6 +103,7 @@
 extern void init_VISWS_APIC_irqs(void);
 extern void setup_IO_APIC(void);
 extern int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn);
+extern int visws_get_PCI_irq_vector(int bus, int slot, int fn);
 extern void make_8259A_irq(unsigned int irq);
 extern void send_IPI(int dest, int vector);
 extern void init_pic_mode(void);
diff -Naur linux.2210/arch/i386/kernel/process.c linux.2210.vw/arch/i386/kernel/process.c
--- linux.2210/arch/i386/kernel/process.c	Fri Apr 30 08:13:37 1999
+++ linux.2210.vw/arch/i386/kernel/process.c	Wed Jul 28 08:56:41 1999
@@ -168,6 +168,57 @@
 	return 0;
 }
 
+#ifdef CONFIG_VISWS
+
+#include <linux/pci.h>
+#include <asm/sgi-piix.h>
+
+static void
+visws_restart(void)
+{
+    /*
+     * This machine resets by poking this
+     * register on PIIX4.
+     */
+    outb(PIIX4_RESET_VAL, PIIX4_RESET_PORT);
+}
+
+static void
+visws_power_off(void)
+{
+    unsigned short pm_status;
+
+    /* 
+     * Clearing the event before the button is released seems to
+     * re-enable it, thus preventing shutdown.
+     */
+    while ((pm_status = inw(PMSTS_PORT)) & 0x100) {
+	outw(pm_status, PMSTS_PORT);
+    }
+
+    /* 
+     * Here's the magic write that actually sequences
+     * the PIIX4 to shutdown the power.
+     */
+    outw(PM_SUSPEND_ENABLE, PMCNTRL_PORT);
+
+    /*
+     * Need 10msec delay before generating special
+     * cycle so PIIX4 will shut down system.
+     */
+    udelay(10000);
+
+    /*
+     * PIIX4 has asserted stopclk and is waiting to see
+     * the stop special cycle.  Generate one of those
+     * by hand now.
+     */
+    pcibios_write_config_dword(PIIX4_BUS, SPECIAL_DEV, SPECIAL_REG,
+			       PIIX_SPECIAL_STOP);
+}
+#endif /* CONFIG_VISWS */
+
+
 /*
  * This routine reboots the machine by asking the keyboard
  * controller to pulse the reset-line low. We try that for a while,
@@ -279,6 +330,10 @@
 	init_pic_mode();
 #endif
 
+#ifdef CONFIG_VISWS
+	visws_restart();
+#endif /* CONFIG_VISWS */
+
 	if(!reboot_thru_bios) {
 		/* rebooting needs to touch the page at absolute addr 0 */
 		*((unsigned short *)__va(0x472)) = reboot_mode;
@@ -386,6 +441,9 @@
 
 void machine_power_off(void)
 {
+#ifdef CONFIG_VISWS
+	visws_power_off();
+#endif /* CONFIG_VISWS */
 #if defined(CONFIG_APM) && defined(CONFIG_APM_POWER_OFF)
 	apm_power_off();
 #endif
diff -Naur linux.2210/arch/i386/kernel/setup.c linux.2210.vw/arch/i386/kernel/setup.c
--- linux.2210/arch/i386/kernel/setup.c	Tue Jun  8 10:43:21 1999
+++ linux.2210.vw/arch/i386/kernel/setup.c	Wed Jul 28 08:56:41 1999
@@ -47,8 +47,11 @@
 #include <asm/system.h>
 #include <asm/io.h>
 #include <asm/smp.h>
-#include <asm/cobalt.h>
 #include <asm/msr.h>
+#ifdef CONFIG_VISWS
+#include <asm/sgi-cobalt.h>
+#include <asm/sgi-piix.h>
+#endif
 
 /*
  * Machine setup..
@@ -123,54 +126,17 @@
 char visws_board_type = -1;
 char visws_board_rev = -1;
 
-#define	PIIX_PM_START		0x0F80
-
-#define	SIO_GPIO_START		0x0FC0
-
-#define	SIO_PM_START		0x0FC8
-
-#define	PMBASE			PIIX_PM_START
-#define	GPIREG0			(PMBASE+0x30)
-#define	GPIREG(x)		(GPIREG0+((x)/8))
-#define	PIIX_GPI_BD_ID1		18
-#define	PIIX_GPI_BD_REG		GPIREG(PIIX_GPI_BD_ID1)
-
-#define	PIIX_GPI_BD_SHIFT	(PIIX_GPI_BD_ID1 % 8)
-
-#define	SIO_INDEX	0x2e
-#define	SIO_DATA	0x2f
-
-#define	SIO_DEV_SEL	0x7
-#define	SIO_DEV_ENB	0x30
-#define	SIO_DEV_MSB	0x60
-#define	SIO_DEV_LSB	0x61
-
-#define	SIO_GP_DEV	0x7
-
-#define	SIO_GP_BASE	SIO_GPIO_START
-#define	SIO_GP_MSB	(SIO_GP_BASE>>8)
-#define	SIO_GP_LSB	(SIO_GP_BASE&0xff)
-
-#define	SIO_GP_DATA1	(SIO_GP_BASE+0)
-
-#define	SIO_PM_DEV	0x8
-
-#define	SIO_PM_BASE	SIO_PM_START
-#define	SIO_PM_MSB	(SIO_PM_BASE>>8)
-#define	SIO_PM_LSB	(SIO_PM_BASE&0xff)
-#define	SIO_PM_INDEX	(SIO_PM_BASE+0)
-#define	SIO_PM_DATA	(SIO_PM_BASE+1)
-
-#define	SIO_PM_FER2	0x1
-
-#define	SIO_PM_GP_EN	0x80
+#ifdef CONFIG_VISWS_HACKS
+u_long sgivw_gfx_mem_phys = 0;
+u_long sgivw_gfx_mem_size = -1;
+#endif
 
 static void
 visws_get_board_type_and_rev(void)
 {
 	int raw;
 
-	visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_REG)
+	visws_board_type = (char)(inb_p(PIIX_GPI_BD_REG) & PIIX_GPI_BD_MASK)
 							 >> PIIX_GPI_BD_SHIFT;
 /*
  * Get Board rev.
@@ -222,29 +188,31 @@
 	raw = inb_p(SIO_GP_DATA1);
 	raw &= 0x7f;	/* 7 bits of valid board revision ID. */
 
-	if (visws_board_type == VISWS_320) {
+	switch (visws_board_type) {
+	case VISWS_320:
 		if (raw < 0x6) {
 			visws_board_rev = 4;
 		} else if (raw < 0xc) {
 			visws_board_rev = 5;
 		} else {
 			visws_board_rev = 6;
-	
 		}
-	} else if (visws_board_type == VISWS_540) {
-			visws_board_rev = 2;
-		} else {
-			visws_board_rev = raw;
-		}
-
-		printk("Silicon Graphics %s (rev %d)\n",
-			visws_board_type == VISWS_320 ? "320" :
-			(visws_board_type == VISWS_540 ? "540" :
-					"unknown"),
-					visws_board_rev);
+		break;
+	case VISWS_540:
+		visws_board_rev = 2;
+		break;
+	default:
+		visws_board_rev = raw;
+		break;
 	}
-#endif
 
+	printk("Silicon Graphics %s (rev %d)\n",
+		visws_board_type == VISWS_320 ? "320" :
+		(visws_board_type == VISWS_540 ? "540" :
+		"unknown"),
+				visws_board_rev);
+}
+#endif
 
 static char command_line[COMMAND_LINE_SIZE] = { 0, };
        char saved_command_line[COMMAND_LINE_SIZE];
@@ -257,9 +225,19 @@
 	int len = 0;
 
 #ifdef CONFIG_VISWS
+	/*
+	 * Except for COMMAND_LINE nothing presently (July 15, 1999) fills
+	 * out the PARAM block on a Visual Workstation.  We'll make this
+	 * explicit by skipping any code that looks in there.
+	 */
 	visws_get_board_type_and_rev();
-#endif
 
+#define MEGS 128	/* XXX HACK how to get mem config? */
+			/* XXX 128 will always work... smallest mem size */
+	printk("VISWS HACK: hard-wiring physical mem size to %dMb\n", MEGS);
+	memory_end = MEGS<<20; /* Happens to be PAGE_MASK safe */
+
+#else /* !CONFIG_VISWS */
  	ROOT_DEV = to_kdev_t(ORIG_ROOT_DEV);
  	drive_info = DRIVE_INFO;
  	screen_info = SCREEN_INFO;
@@ -284,6 +262,8 @@
 #endif
 
 	memory_end &= PAGE_MASK;
+
+
 #ifdef CONFIG_BLK_DEV_RAM
 	rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK;
 	rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0);
@@ -291,6 +271,7 @@
 #endif
 	if (!MOUNT_ROOT_RDONLY)
 		root_mountflags &= ~MS_RDONLY;
+#endif
 	memory_start = (unsigned long) &_end;
 	init_task.mm->start_code = PAGE_OFFSET;
 	init_task.mm->end_code = (unsigned long) &_etext;
@@ -323,6 +304,23 @@
 				}
 			}
 		}
+#ifdef CONFIG_VISWS_HACKS
+		/*
+		 * "gfxmem=XXX[kKmM]" overrides the default
+		 * graphics memory size
+		 */
+		if (c == ' ' && !memcmp(from,"gfxmem=",7)) {
+			if (to != command_line) to--;
+			sgivw_gfx_mem_size = simple_strtoul(from+7, &from, 0);
+			if ( *from == 'K' || *from == 'k' ) {
+				sgivw_gfx_mem_size <<= 10;
+				from++;
+			} else if ( *from == 'M' || *from == 'm' ) {
+				sgivw_gfx_mem_size <<= 20;
+				from++;
+			}
+		}
+#endif
 		c = *(from++);
 		if (!c)
 			break;
@@ -333,6 +331,28 @@
 	*to = '\0';
 	*cmdline_p = command_line;
 
+#ifdef CONFIG_VISWS_HACKS
+	#define VISWS_GFX_MEM_MEGS 16
+	if (sgivw_gfx_mem_size == -1)
+		sgivw_gfx_mem_size = VISWS_GFX_MEM_MEGS<<20;
+	/* truncate gfxmem size down to nearest megabyte */
+	sgivw_gfx_mem_size &= ~((1<<20)-1);
+	memory_end -= sgivw_gfx_mem_size;
+	printk("VISWS HACK: taking %ldMb for gfx memory -- leaving %ldMb for kernel\n",
+		sgivw_gfx_mem_size>>20, memory_end>>20);
+	sgivw_gfx_mem_phys = memory_end;
+	printk("sgivw_gfx_mem_phys %lx\n", sgivw_gfx_mem_phys);
+#endif
+
+#ifdef CONFIG_VISWS
+	/*
+	 * Using 'hlt' in cpu_idle() on a Visual Workstation can tickle
+	 * a h/w bug in memory refresh that can spontaneously reset
+	 * or even power-off the system.
+	 */
+	boot_cpu_data.hlt_works_ok = 0;
+#endif
+
 #define VMALLOC_RESERVE	(64 << 20)	/* 64MB for vmalloc */
 #define MAXMEM	((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
 
@@ -375,12 +395,13 @@
 	request_region(0xf0,0x10,"fpu");
 
 #ifdef CONFIG_VT
-#if defined(CONFIG_VGA_CONSOLE)
+#if defined(CONFIG_VGA_CONSOLE) && !defined(CONFIG_VISWS)
 	conswitchp = &vga_con;
 #elif defined(CONFIG_DUMMY_CONSOLE)
 	conswitchp = &dummy_con;
 #endif
 #endif
+
 	/*
 	 *	Check the bugs that will bite us before we get booting
 	 */
diff -Naur linux.2210/arch/i386/kernel/smp.c linux.2210.vw/arch/i386/kernel/smp.c
--- linux.2210/arch/i386/kernel/smp.c	Wed Jun  2 11:29:27 1999
+++ linux.2210.vw/arch/i386/kernel/smp.c	Wed Jul 28 14:26:24 1999
@@ -185,19 +185,6 @@
  * Intel MP BIOS table parsing routines:
  */
 
-#ifndef CONFIG_X86_VISWS_APIC
-/*
- *	Checksum an MP configuration block.
- */
-
-static int mpf_checksum(unsigned char *mp, int len)
-{
-	int sum=0;
-	while(len--)
-		sum+=*mp++;
-	return sum&0xFF;
-}
-
 /*
  *	Processor encoding in an MP configuration block
  */
@@ -225,6 +212,69 @@
 	return n;
 }
 
+static void __init smp_read_mpc_processor(struct mpc_config_processor *m)
+{
+	if (!(m->mpc_cpuflag&CPU_ENABLED)) {
+		return;
+	}
+	printk("Processor #%d %s APIC version %d\n",
+		m->mpc_apicid,
+		mpc_family((m->mpc_cpufeature&
+			CPU_FAMILY_MASK)>>8,
+			(m->mpc_cpufeature&
+				CPU_MODEL_MASK)>>4),
+		m->mpc_apicver);
+#ifdef SMP_DEBUG
+	if (m->mpc_featureflag&(1<<0))
+		printk("    Floating point unit present.\n");
+	if (m->mpc_featureflag&(1<<7))
+		printk("    Machine Exception supported.\n");
+	if (m->mpc_featureflag&(1<<8))
+		printk("    64 bit compare & exchange supported.\n");
+	if (m->mpc_featureflag&(1<<9))
+		printk("    Internal APIC present.\n");
+#endif
+	if (m->mpc_cpuflag&CPU_BOOTPROCESSOR)
+	{
+		SMP_PRINTK(("    Bootup CPU\n"));
+		boot_cpu_id=m->mpc_apicid;
+	}
+	else	/* Boot CPU already counted */
+		num_processors++;
+
+	if (m->mpc_apicid>NR_CPUS)
+		printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS);
+	else
+	{
+		int ver = m->mpc_apicver;
+
+		cpu_present_map|=(1<<m->mpc_apicid);
+		/*
+		 * Validate version
+		 */
+		if (ver == 0x0) {
+			printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
+			ver = 0x10;
+		}
+		apic_version[m->mpc_apicid] = ver;
+	}
+}
+
+#ifndef CONFIG_X86_VISWS_APIC
+/*
+ *	Checksum an MP configuration block.
+ */
+
+static int mpf_checksum(unsigned char *mp, int len)
+{
+	int sum=0;
+	while(len--)
+		sum+=*mp++;
+	return sum&0xFF;
+}
+
+
+
 /*
  *	Read the MPC
  */
@@ -280,52 +330,9 @@
 		{
 			case MP_PROCESSOR:
 			{
-				struct mpc_config_processor *m=
+				struct mpc_config_bus *m=
 					(struct mpc_config_processor *)mpt;
-				if (m->mpc_cpuflag&CPU_ENABLED)
-				{
-					printk("Processor #%d %s APIC version %d\n",
-						m->mpc_apicid,
-						mpc_family((m->mpc_cpufeature&
-							CPU_FAMILY_MASK)>>8,
-							(m->mpc_cpufeature&
-								CPU_MODEL_MASK)>>4),
-						m->mpc_apicver);
-#ifdef SMP_DEBUG
-					if (m->mpc_featureflag&(1<<0))
-						printk("    Floating point unit present.\n");
-					if (m->mpc_featureflag&(1<<7))
-						printk("    Machine Exception supported.\n");
-					if (m->mpc_featureflag&(1<<8))
-						printk("    64 bit compare & exchange supported.\n");
-					if (m->mpc_featureflag&(1<<9))
-						printk("    Internal APIC present.\n");
-#endif
-					if (m->mpc_cpuflag&CPU_BOOTPROCESSOR)
-					{
-						SMP_PRINTK(("    Bootup CPU\n"));
-						boot_cpu_id=m->mpc_apicid;
-					}
-					else	/* Boot CPU already counted */
-						num_processors++;
-
-					if (m->mpc_apicid>NR_CPUS)
-						printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS);
-					else
-					{
-						int ver = m->mpc_apicver;
-
-						cpu_present_map|=(1<<m->mpc_apicid);
-						/*
-						 * Validate version
-						 */
-						if (ver == 0x0) {
-							printk("BIOS bug, APIC version is 0 for CPU#%d! fixing up to 0x10. (tell your hw vendor)\n", m->mpc_apicid);
-							ver = 0x10;
-						}
-						apic_version[m->mpc_apicid] = ver;
-					}
-				}
+				smp_read_mpc_processor(m);
 				mpt+=sizeof(*m);
 				count+=sizeof(*m);
 				break;
@@ -608,17 +615,33 @@
 
 /*
  * The Visual Workstation is Intel MP compliant in the hardware
- * sense, but it doesnt have a BIOS(-configuration table).
+ * sense, but it doesn't have a completely MP compliant MP table.
  * No problem for Linux.
  */
+#define CO_CPU_NUM_PHYS	0x1e00
+#define	CO_CPU_TAB_PHYS (CO_CPU_NUM_PHYS + 2)
+
+#define CO_CPU_MAX	4
+
 void __init init_visws_smp(void)
 {
-	smp_found_config = 1;
+	struct mpc_config_processor *mp = (struct mpc_config_processor *)
+						(PAGE_OFFSET + CO_CPU_TAB_PHYS);
+	unsigned short ncpus = *(unsigned short*)
+						(PAGE_OFFSET + CO_CPU_NUM_PHYS);
+
+	if (ncpus > CO_CPU_MAX) {
+		printk("init_visws_smp: insane cpu count %d, addr %p\n",
+								ncpus, mp);
+		return;
+	}
 
-	cpu_present_map |= 2; /* or in id 1 */
-	apic_version[1] |= 0x10; /* integrated APIC */
-	apic_version[0] |= 0x10;
+	smp_found_config = 1;
 
+	while (ncpus--) {
+		smp_read_mpc_processor(mp++);
+	}
+	
 	mp_lapic_addr = APIC_DEFAULT_PHYS_BASE;
 } 
 
@@ -716,37 +739,6 @@
 	atomic_set(&smp_commenced,1);
 }
 
-void __init enable_local_APIC(void)
-{
-	unsigned long value;
-
- 	value = apic_read(APIC_SPIV);
- 	value |= (1<<8);		/* Enable APIC (bit==1) */
- 	value &= ~(1<<9);		/* Enable focus processor (bit==0) */
-	value |= 0xff;			/* Set spurious IRQ vector to 0xff */
- 	apic_write(APIC_SPIV,value);
-
-	/*
-	 * Set Task Priority to 'accept all'
-	 */
- 	value = apic_read(APIC_TASKPRI);
- 	value &= ~APIC_TPRI_MASK;
- 	apic_write(APIC_TASKPRI,value);
-
-	/*
-	 * Clear the logical destination ID, just to be safe.
-	 * also, put the APIC into flat delivery mode.
-	 */
- 	value = apic_read(APIC_LDR);
-	value &= ~APIC_LDR_MASK;
- 	apic_write(APIC_LDR,value);
-
- 	value = apic_read(APIC_DFR);
-	value |= SET_APIC_DFR(0xf);
- 	apic_write(APIC_DFR, value);
-
-	udelay(100);			/* B safe */
-}
 
 unsigned long __init init_smp_mappings(unsigned long memory_start)
 {
diff -Naur linux.2210/arch/i386/kernel/time.c linux.2210.vw/arch/i386/kernel/time.c
--- linux.2210/arch/i386/kernel/time.c	Thu Apr 29 11:53:41 1999
+++ linux.2210.vw/arch/i386/kernel/time.c	Wed Jul 28 08:56:41 1999
@@ -54,7 +54,7 @@
 #include <linux/config.h>
 
 #include <asm/fixmap.h>
-#include <asm/cobalt.h>
+#include <asm/sgi-cobalt.h>
 
 /*
  * for x86_do_profile()
@@ -680,9 +680,6 @@
 	/* Enable (unmask) the timer interrupt */
 	co_cpu_write(CO_CPU_CTRL, co_cpu_read(CO_CPU_CTRL) & ~CO_CTRL_TIMEMASK);
 
-	/* Wire cpu IDT entry to s/w handler (and Cobalt APIC to IDT) */
-	setup_x86_irq(CO_IRQ_TIMER, &irq0);
-#else
-	setup_x86_irq(0, &irq0);
 #endif
+	setup_x86_irq(0, &irq0);
 }
diff -Naur linux.2210/arch/i386/kernel/trampoline.S linux.2210.vw/arch/i386/kernel/trampoline.S
--- linux.2210/arch/i386/kernel/trampoline.S	Wed May  6 11:42:54 1998
+++ linux.2210.vw/arch/i386/kernel/trampoline.S	Wed Jul 28 08:56:41 1999
@@ -54,8 +54,13 @@
 	lmsw	%ax		# into protected mode
 	jmp	flush_instr
 flush_instr:
+#ifdef CONFIG_VISWS_HACKS
+	ljmpl	$__KERNEL_CS, $0x00100016
+				# jump to startup_32 + 0x16
+#else
 	ljmpl	$__KERNEL_CS, $0x00100000
 				# jump to startup_32
+#endif
 
 idt_48:
 	.word	0			# idt limit = 0
diff -Naur linux.2210/arch/i386/kernel/traps.c linux.2210.vw/arch/i386/kernel/traps.c
--- linux.2210/arch/i386/kernel/traps.c	Tue Feb 16 14:20:05 1999
+++ linux.2210.vw/arch/i386/kernel/traps.c	Wed Jul 28 08:56:41 1999
@@ -38,8 +38,8 @@
 
 #ifdef CONFIG_X86_VISWS_APIC
 #include <asm/fixmap.h>
-#include <asm/cobalt.h>
-#include <asm/lithium.h>
+#include <asm/sgi-cobalt.h>
+#include <asm/sgi-lithium.h>
 #endif
 
 #include "irq.h"
@@ -579,57 +579,6 @@
 }
 
 #ifdef CONFIG_X86_VISWS_APIC
-
-/*
- * On Rev 005 motherboards legacy device interrupt lines are wired directly
- * to Lithium from the 307.  But the PROM leaves the interrupt type of each
- * 307 logical device set appropriate for the 8259.  Later we'll actually use
- * the 8259, but for now we have to flip the interrupt types to
- * level triggered, active lo as required by Lithium.
- */
-
-#define	REG	0x2e	/* The register to read/write */
-#define	DEV	0x07	/* Register: Logical device select */
-#define	VAL	0x2f	/* The value to read/write */
-
-static void
-superio_outb(int dev, int reg, int val)
-{
-	outb(DEV, REG);
-	outb(dev, VAL);
-	outb(reg, REG);
-	outb(val, VAL);
-}
-
-static int __attribute__ ((unused))
-superio_inb(int dev, int reg)
-{
-	outb(DEV, REG);
-	outb(dev, VAL);
-	outb(reg, REG);
-	return inb(VAL);
-}
-
-#define	FLOP	3	/* floppy logical device */
-#define	PPORT	4	/* parallel logical device */
-#define	UART5	5	/* uart2 logical device (not wired up) */
-#define	UART6	6	/* uart1 logical device (THIS is the serial port!) */
-#define	IDEST	0x70	/* int. destination (which 307 IRQ line) reg. */
-#define	ITYPE	0x71	/* interrupt type register */
-
-/* interrupt type bits */
-#define	LEVEL	0x01	/* bit 0, 0 == edge triggered */
-#define	ACTHI	0x02	/* bit 1, 0 == active lo */
-
-static void
-superio_init(void)
-{
-	if (visws_board_type == VISWS_320 && visws_board_rev == 5) {
-		superio_outb(UART6, IDEST, 0);	/* 0 means no intr propagated */
-		printk("SGI 320 rev 5: disabling 307 uart1 interrupt\n");
-	}
-}
-
 static void
 lithium_init(void)
 {
@@ -640,22 +589,33 @@
 	printk("Lithium PCI Bridge B (PIIX4), Bus Number: %d\n",
 				li_pcib_read16(LI_PCI_BUSNUM) & 0xff);
 
-	/* XXX blindly enables all interrupts */
-	li_pcia_write16(LI_PCI_INTEN, 0xffff);
-	li_pcib_write16(LI_PCI_INTEN, 0xffff);
+	/* XXX blindly enables all device interrupts */
+	/* XXX even more blindly does not enable any error interrupts */
+	/* NOTE: Lithium error interrupts share LI_INTD */
+#define	A01234	(LI_INTA_0|LI_INTA_1|LI_INTA_2|LI_INTA_3|LI_INTA_4)
+#define	BCD	(LI_INTB|LI_INTC|LI_INTD)
+#define	ALLDEVS	(A01234|BCD)
+	li_pcia_write16(LI_PCI_INTEN, ALLDEVS);
+	li_pcib_write16(LI_PCI_INTEN, ALLDEVS);
 }
 
 static void
 cobalt_init(void)
 {
 	/*
-	 * On normal SMP PC this is used only with SMP, but we have to
-	 * use it and set it up here to start the Cobalt clock
+	 * On normal SMP PC the local APIC is used only with SMP.
+	 * On Visual Workstations all interrupts always go through
+	 * the local APIC including the clock which is why we have
+	 * initialize and enable the local APIC so early.
 	 */
 	set_fixmap(FIX_APIC_BASE, APIC_PHYS_BASE);
+	enable_local_APIC();
 	printk("Local APIC ID %lx\n", apic_read(APIC_ID));
 	printk("Local APIC Version %lx\n", apic_read(APIC_VERSION));
 
+	/*
+	 * And, now we go out to the Cobalt APIC and enable it.
+	 */
 	set_fixmap(FIX_CO_CPU, CO_CPU_PHYS);
 	printk("Cobalt Revision %lx\n", co_cpu_read(CO_CPU_REV));
 
@@ -702,7 +662,6 @@
 	load_TR(0);
 	load_ldt(0);
 #ifdef CONFIG_X86_VISWS_APIC
-	superio_init();
 	lithium_init();
 	cobalt_init();
 #endif
diff -Naur linux.2210/arch/i386/kernel/visws_apic.c linux.2210.vw/arch/i386/kernel/visws_apic.c
--- linux.2210/arch/i386/kernel/visws_apic.c	Thu May  6 16:12:23 1999
+++ linux.2210.vw/arch/i386/kernel/visws_apic.c	Wed Jul 28 08:56:41 1999
@@ -36,10 +36,18 @@
 #include <asm/delay.h>
 #include <asm/desc.h>
 
-#include <asm/cobalt.h>
+#include <asm/sgi-cobalt.h>
 
 #include "irq.h"
 
+#define LEGACY_IRQS
+#define SERIAL_HACK
+
+#ifndef CONFIG_SMP
+int skip_ioapic_setup; /* No IO-APIC to ever skip on Cobalt! */
+#endif
+
+#ifdef LEGACY_IRQS
 /*
  * This is the PIIX4-based 8259 that is wired up indirectly to Cobalt
  * -- not the manner expected by the normal 8259 code in irq.c.
@@ -51,8 +59,6 @@
  * controller. Device drivers only see the virtual interrupt sources.
  */
 
-#define	CO_IRQ_BASE	0x20	/* This is the 0x20 in init_IRQ()! */
-
 static void startup_piix4_master_irq(unsigned int irq);
 static void shutdown_piix4_master_irq(unsigned int irq);
 static void do_piix4_master_IRQ(unsigned int irq, struct pt_regs * regs);
@@ -81,6 +87,7 @@
 	enable_piix4_virtual_irq,
 	disable_piix4_virtual_irq
 };
+#endif
 
 /*
  * This is the SGI Cobalt (IO-)APIC:
@@ -90,7 +97,7 @@
 static void enable_cobalt_irq(unsigned int irq);
 static void disable_cobalt_irq(unsigned int irq);
 static void startup_cobalt_irq(unsigned int irq);
-#define shutdown_cobalt_irq disable_cobalt_irq
+static void shutdown_cobalt_irq(unsigned int irq);
 
 static struct hw_interrupt_type cobalt_irq_type = {
 	"Cobalt-APIC",
@@ -112,32 +119,87 @@
 
 /*
  * Cobalt (IO)-APIC functions to handle PCI devices.
+ *
+ * Correctness and clarity are prioritized over performance.
  */
 
-static void disable_cobalt_irq(unsigned int irq)
+static int
+co_apic_ide0_hack(void) /* terribly inefficiently extensible */
 {
-	/* XXX undo the APIC entry here? */
+	extern char visws_board_type;
+	extern char visws_board_rev;
 
-	/*
-	 * definitely, we do not want to have IRQ storms from
-	 * unused devices --mingo
-	 */
+	/* XXX really only for the 5 alpha boxes in Ken Nicholson's group! */
+	if (visws_board_type == VISWS_320 && visws_board_rev == 5) {
+		return 5;
+	}
+	return CO_APIC_IDE0;
 }
 
-static void enable_cobalt_irq(unsigned int irq)
+/*
+ * Returns Cobalt APIC entry for this irq
+ *
+ * 'irq' MUST be a cobalt-direct interrupt.  something's coded very wrong
+ * if we get here with a piix4-8259 irq
+ *
+ * Note: here we know that the ide driver defaults IDE{0,1} to IRQ 1{4,5}!
+ * A drag, because we need to check/map these aliases/warts in IRQ number space.
+ * (Ideally we'd rather give IDEx CO_IRQ(CO_APIC_IDEx), but there's no great way
+ * to implement probe_irq_on/off)
+ */
+static int is_co_apic(unsigned int irq)
 {
+	if (IS_CO_APIC(irq)) {
+		return CO_APIC(irq);
+	}
+	/* Here are those yucky aliases that wreak havoc on beauty */
+	switch (irq) {
+	case 0:			return CO_APIC_CPU;
+	case CO_IRQ_IDE0:	return co_apic_ide0_hack();
+	case CO_IRQ_IDE1:	return CO_APIC_IDE1;
+	default:		return -1;
+	}
+	/* NOTREACHED */
+}
+
+/* XXX ouch... is this really our only choice for masking this interrupt? */
+/* XXX not fully safe for 2 reasons:
+ *	1) should not touch an apic entry while (whole) apic is enabled
+ *	2) careful about storing to IRR bit (unless we know this intr is idle)
+ */
+static void disable_cobalt_irq(unsigned int irq)	/* disable_irq() */
+{
+	int ent = is_co_apic(irq);
+	if (ent == -1) {
+		return; /* could actually be a panic */
+	}
+
+	/* Note: h/w nada like read-mod-write!  Vec saved in IRQ_VECTOR() */
+	co_apic_write(CO_APIC_LO(ent), CO_APIC_MASK);
+	(void)co_apic_read(CO_APIC_LO(ent)); /* sync cpu to cobalt apic */
+}
+
+static void enable_cobalt_irq(unsigned int irq)		/* enable_irq() */
+{
+	int ent = is_co_apic(irq);
+	if (ent == -1) {
+		return; /* ALL irqs use do_cobalt_IRQ() which calls here */
+	}
+
+	/* Note: this clears the CO_APIC_MASK bit, and assumes _HI okay */
+	co_apic_write(CO_APIC_LO(ent), CO_APIC_LEVEL|IRQ_VECTOR(irq));
 }
 
 /*
  * Set the given Cobalt APIC Redirection Table entry to point
  * to the given IDT vector/index.
  */
-static void co_apic_set(int entry, int idtvec)
+static void co_apic_set(int entry, int irq)
 {
-	co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL | (CO_IRQ_BASE+idtvec));
+	printk("IRQ %d, Cobalt APIC Entry %d, IDT Vector %x: enabling\n",
+						irq, entry, IRQ_VECTOR(irq));
+	co_apic_write(CO_APIC_LO(entry), CO_APIC_LEVEL|IRQ_VECTOR(irq));
 	co_apic_write(CO_APIC_HI(entry), 0);
-
-	printk("Cobalt APIC Entry %d IDT Vector %d\n", entry, idtvec);
 }
 
 /*
@@ -145,48 +207,39 @@
  * map this to the Cobalt APIC entry where it's physically wired.
  * This is called via request_irq -> setup_x86_irq -> irq_desc->startup()
  */
-static void startup_cobalt_irq(unsigned int irq)
+static void startup_cobalt_irq(unsigned int irq)	/* request_irq() */
 {
+	int ent;
 	/*
-	 * These "irq"'s are wired to the same Cobalt APIC entries
-	 * for all (known) motherboard types/revs
+	 * Protect this code from probe_irq_on/off()
 	 */
-	switch (irq) {
-	case CO_IRQ_TIMER:	co_apic_set(CO_APIC_CPU, CO_IRQ_TIMER);
-				return;
+	if (irq_desc[irq].status & IRQ_AUTODETECT) {
+		return;
+	}
 
-	case CO_IRQ_ENET:	co_apic_set(CO_APIC_ENET, CO_IRQ_ENET);
-				return;
+#ifdef SERIAL_HACK
+	if (irq == 4) { /* XXX terrible hack for serial interrupt prob */
+		return; /* XXX fixed on factory h/w? */
+	}
+#endif
+	ent = is_co_apic(irq);
+	if (ent == -1) {
+		return; /* Could very well be a panic */
+	}
 
-	case CO_IRQ_SERIAL:	return; /* XXX move to piix4-8259 "virtual" */
+	co_apic_set(ent, irq);
+}
 
-	case CO_IRQ_8259:	co_apic_set(CO_APIC_8259, CO_IRQ_8259);
-				return;
-
-	case CO_IRQ_IDE:
-		switch (visws_board_type) {
-		case VISWS_320:
-			switch (visws_board_rev) {
-			case 5:
-				co_apic_set(CO_APIC_0_5_IDE0, CO_IRQ_IDE);
-				co_apic_set(CO_APIC_0_5_IDE1, CO_IRQ_IDE);
-					return;
-			case 6:
-				co_apic_set(CO_APIC_0_6_IDE0, CO_IRQ_IDE);
-				co_apic_set(CO_APIC_0_6_IDE1, CO_IRQ_IDE);
-					return;
-			}
-		case VISWS_540:
-			switch (visws_board_rev) {
-			case 2:
-				co_apic_set(CO_APIC_1_2_IDE0, CO_IRQ_IDE);
-					return;
-			}
-		}
-		break;
-	default:
-		panic("huh?");
+static void shutdown_cobalt_irq(unsigned int irq)	/* free_irq() */
+{
+#ifdef SERIAL_HACK
+	if (irq == 4) { /* XXX terrible hack for serial interrupt prob */
+		return; /* XXX fixed on factory h/w? */
 	}
+#endif
+	printk("IRQ %d, Cobalt APIC Entry %d, IDT Vector %x: masking\n",
+		irq, is_co_apic(irq), IRQ_VECTOR(irq));
+	disable_cobalt_irq(irq);
 }
 
 /*
@@ -200,7 +253,8 @@
 	spin_lock(&irq_controller_lock);
 	{
 		unsigned int status;
-		/* XXX APIC EOI? */
+		disable_cobalt_irq(irq);
+		apic_write(APIC_EOI, APIC_EIO_ACK);
 		status = desc->status & ~(IRQ_REPLAY | IRQ_WAITING);
 		action = NULL;
 		if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) {
@@ -217,9 +271,6 @@
 
 	handle_IRQ_event(irq, regs, action);
 
-	(void)co_cpu_read(CO_CPU_REV); /* Sync driver ack to its h/w */
-	apic_write(APIC_EOI, APIC_EIO_ACK); /* Send EOI to Cobalt APIC */
-
 	spin_lock(&irq_controller_lock);
 	{
 		unsigned int status = desc->status & ~IRQ_INPROGRESS;
@@ -230,13 +281,15 @@
 	spin_unlock(&irq_controller_lock);
 }
 
+#ifdef LEGACY_IRQS
 /*
  * PIIX4-8259 master/virtual functions to handle:
  *
  *	floppy
  *	parallel
  *	serial
- *	audio (?)
+ *	[ps2 kbd]
+ *	[ps2 mouse]
  *
  * None of these get Cobalt APIC entries, neither do they have IDT
  * entries. These interrupts are purely virtual and distributed from
@@ -252,6 +305,8 @@
 
 static void startup_piix4_master_irq(unsigned int irq)
 {
+	/* irq should only ever be CO_IRQ_8259 */
+
 	/* ICW1 */
 	outb(0x11, 0x20);
 	outb(0x11, 0xa0);
@@ -277,10 +332,6 @@
 
 static void shutdown_piix4_master_irq(unsigned int irq)
 {
-	/*
-	 * [we skip the 8259 magic here, not strictly necessary]
-	 */
-
 	shutdown_cobalt_irq(irq);
 }
 
@@ -324,6 +375,7 @@
 	 * handle this 'virtual interrupt' as a Cobalt one now.
 	 */
 	kstat.irqs[smp_processor_id()][irq]++;
+	kstat.irqs[smp_processor_id()][realirq]++;
 	do_cobalt_IRQ(realirq, regs);
 
 	spin_lock(&irq_controller_lock);
@@ -343,14 +395,9 @@
 
 static void enable_piix4_virtual_irq(unsigned int irq)
 {
-	/*
-	 * assumes this irq is one of the legacy devices
-	 */
-
 	unsigned int mask = inb(0x21);
  	mask &= ~(1 << irq);
 	outb(mask, 0x21);
-	enable_cobalt_irq(irq);
 }
 
 /*
@@ -358,52 +405,104 @@
  */
 static void disable_piix4_virtual_irq(unsigned int irq)
 {
-	unsigned int mask;
-
-	disable_cobalt_irq(irq);
-
-	mask = inb(0x21);
+	unsigned int mask = inb(0x21);
  	mask &= ~(1 << irq);
 	outb(mask, 0x21);
 }
 
 static struct irqaction master_action =
 		{ no_action, 0, 0, "PIIX4-8259", NULL, NULL };
+#endif
 
-void init_VISWS_APIC_irqs(void)
+/*
+ * Called from bios32.c:pcibios_fixup_devices()
+ * Our chance to fill in the proper irqs.
+ * XXX properly map bus num to _bridge_ num
+ * XXX a big table (indexed by bridge/slot/line) might really be easiest!
+ */
+int
+visws_get_PCI_irq_vector(int bus, int slot, int line)
+{
+#define BRIDGE_A	1	/* XXX simplistic bus numbering! */
+#define	BRIDGE_B	0	/* XXX simplistic bus numbering! */
+/* XXX note how we pass the bus number as the "bridge id" -- simplistic! */
+#define BASE(bridge)	((bridge) == BRIDGE_B ? \
+					CO_APIC_PCIB_BASE0 : \
+					CO_APIC_PCIA_BASE0)
+	if (bus == BRIDGE_B && slot == 4 && line == 3) {
+		return CO_IRQ(CO_APIC_PIIX4_USB); /* Breaks all patterns */
+	}
+	if (line == 0) { /* First pin spread down 1 APIC entry per slot */
+		return CO_IRQ(BASE(bus) + slot);
+	}
+	/* lines 1,2,3 from any slot is shared in this twirly pattern */
+	if (bus == BRIDGE_A) {
+		/* lines 1-3 from devices 0 1 rotate over 2 apic entries */
+		return CO_IRQ(CO_APIC_PCIA_BASE123 + ((slot + (line-1)) % 2));
+	} else { /* bus == BRIDGE_B */
+		/* lines 1-3 from devices 0-3 rotate over 3 apic entries */
+		if (slot == 0) slot = 3; /* same pattern */
+		return CO_IRQ(CO_APIC_PCIA_BASE123 + ((3-slot) + (line-1) % 3));
+	}
+	/* NOTREACHED */
+#undef BRIDGE_A
+#undef BRIDGE_B
+#undef BASE
+}
+
+/*
+ * Maps the combination of PIIX4 8259-pair irqs plus Cobalt APIC irqs
+ * to CPU IDT vectors.  Just initializes visws_irq_vector[] and IRQ_VEC(irq).
+ */
+#if (CO_IRQ_APIC0 + CO_APIC_LAST + 1) > NR_IRQS
+_NR_IRQS too small
+#endif
+
+
+void init_VISWS_APIC_irqs(void) /* init_IRQ() */
 {
 	int i;
 
-	for (i = 0; i < 16; i++) {
+	for (i = 0; i < CO_IRQ_APIC0 + CO_APIC_LAST + 1; i++) {
 		irq_desc[i].status = IRQ_DISABLED;
 		irq_desc[i].action = 0;
 		irq_desc[i].depth = 0;
 
-		/*
-		 * Cobalt IRQs are mapped to standard ISA
-		 * interrupt vectors:
-		 */
-		switch (i) {
-			/*
-			 * Only CO_IRQ_8259 will be raised
-			 * externally.
-			 */
-		case CO_IRQ_8259:
+		/* Some legacy irqs are handled specially */
+		/* This if/else "switch" must match co_apic_entry()! */
+		if (i == 0) { /* IRQ 0 is system clock -- Cobalt timer */
+			irq_desc[i].handler = &cobalt_irq_type;
+#ifdef SERIAL_HACK
+		} else if (i == 4) { /* serial hack! */
+			irq_desc[i].handler = &cobalt_irq_type;
+#endif
+		} else if (i == CO_IRQ_IDE0) {
+			irq_desc[i].handler = &cobalt_irq_type;
+		} else if (i == CO_IRQ_IDE1) {
+			irq_desc[i].handler = &cobalt_irq_type;
+#ifdef LEGACY_IRQS
+		} else if (i == CO_IRQ_8259) {
 			irq_desc[i].handler = &piix4_master_irq_type;
-			break;
-		case CO_IRQ_FLOPPY:
-		case CO_IRQ_PARLL:
+		} else if (i < CO_IRQ_APIC0) { /* normal legacy */
 			irq_desc[i].handler = &piix4_virtual_irq_type;
-			break;
-		default:
+#endif
+		} else if (IS_CO_APIC(i)) {
 			irq_desc[i].handler = &cobalt_irq_type;
-			break;
 		}
+		(void)assign_irq_vector(i);
 	}
 
+#ifdef LEGACY_IRQS
 	/*
 	 * The master interrupt is always present:
 	 */
 	setup_x86_irq(CO_IRQ_8259, &master_action);
-}
+#endif
 
+	/*
+	 * Enable IDT vectors for all valid IRQs.
+	 * All unused IDT vectors generate 'Unexpected interrupt',
+	 * see irq.c:strange_interrupt().
+	 */
+	init_IRQ_MORE_TRAPS();
+}
diff -Naur linux.2210/drivers/block/floppy.c linux.2210.vw/drivers/block/floppy.c
--- linux.2210/drivers/block/floppy.c	Wed Jun  9 16:42:49 1999
+++ linux.2210.vw/drivers/block/floppy.c	Wed Jul 28 08:56:41 1999
@@ -3589,11 +3589,21 @@
 
 	/* read drive info out of physical CMOS */
 	drive=0;
+#ifdef CONFIG_VISWS_HACKS
+printk("VISWS HACK: floppy drive 0 hardwired to 1.44Mb (cmos WAR)\n");
+	UDP->cmos = 4; /* drivers/block/README.fd */
+#else
 	if (!UDP->cmos)
 		UDP->cmos = FLOPPY0_TYPE;
+#endif
 	drive=1;
+#ifdef CONFIG_VISWS_HACKS
+printk("VISWS HACK: floppy drive 1 hardwired to (none) (cmos WAR)\n");
+	UDP->cmos = 16; /* means "no drive" */
+#else
 	if (!UDP->cmos && FLOPPY1_TYPE)
 		UDP->cmos = FLOPPY1_TYPE;
+#endif
 
 	/* XXX */
 	/* additional physical CMOS drive detection should go here */
diff -Naur linux.2210/drivers/block/ide-probe.c linux.2210.vw/drivers/block/ide-probe.c
--- linux.2210/drivers/block/ide-probe.c	Mon Mar 22 12:44:18 1999
+++ linux.2210.vw/drivers/block/ide-probe.c	Wed Jul 28 08:56:41 1999
@@ -409,8 +409,10 @@
 
 	if (hwif->noprobe)
 		return;
+#ifndef CONFIG_VISWS_HACKS
 	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
 		probe_cmos_for_drives (hwif);
+#endif
 	if ((hwif->chipset != ide_4drives || !hwif->mate->present)
 #if CONFIG_BLK_DEV_PDC4030
 	 && (hwif->chipset != ide_pdc4030 || hwif->channel == 0)
diff -Naur linux.2210/drivers/char/i2c.c linux.2210.vw/drivers/char/i2c.c
--- linux.2210/drivers/char/i2c.c	Thu Jan 14 22:53:02 1999
+++ linux.2210.vw/drivers/char/i2c.c	Wed Jul 28 08:56:41 1999
@@ -387,7 +387,10 @@
 		return bus->i2c_read(bus, addr);
 
 	i2c_start(bus);
-	i2c_sendbyte(bus,addr,0);
+	if (i2c_sendbyte(bus,addr,0)) {
+		i2c_stop(bus);
+		return -1;
+	}
 	ret = i2c_readbyte(bus,1);
 	i2c_stop(bus);
 	return ret;
diff -Naur linux.2210/drivers/char/serial.c linux.2210.vw/drivers/char/serial.c
--- linux.2210/drivers/char/serial.c	Tue Mar 23 13:13:58 1999
+++ linux.2210.vw/drivers/char/serial.c	Wed Jul 28 08:56:41 1999
@@ -100,7 +100,7 @@
 #undef SERIAL_DEBUG_FLOW
 #undef SERIAL_DEBUG_RS_WAIT_UNTIL_SENT
 
-#define RS_STROBE_TIME (10*HZ)
+#define RS_STROBE_TIME (HZ/10)
 #define RS_ISR_PASS_LIMIT 256
 
 #define IRQ_T(info) ((info->flags & ASYNC_SHARE_IRQ) ? SA_SHIRQ : SA_INTERRUPT)
diff -Naur linux.2210/drivers/scsi/Config.in linux.2210.vw/drivers/scsi/Config.in
--- linux.2210/drivers/scsi/Config.in	Wed Jun  9 16:59:34 1999
+++ linux.2210.vw/drivers/scsi/Config.in	Wed Jul 28 08:56:41 1999
@@ -122,6 +122,7 @@
 dep_tristate 'Qlogic FAS SCSI support' CONFIG_SCSI_QLOGIC_FAS $CONFIG_SCSI
 if [ "$CONFIG_PCI" = "y" ]; then
   dep_tristate 'Qlogic ISP SCSI support' CONFIG_SCSI_QLOGIC_ISP $CONFIG_SCSI
+  dep_tristate 'Qlogic 1X80 SCSI support' CONFIG_SCSI_QLOGIC_1X80 $CONFIG_SCSI
   dep_tristate 'Qlogic ISP FC SCSI support' CONFIG_SCSI_QLOGIC_FC $CONFIG_SCSI
 fi
 dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE $CONFIG_SCSI
diff -Naur linux.2210/drivers/scsi/Makefile linux.2210.vw/drivers/scsi/Makefile
--- linux.2210/drivers/scsi/Makefile	Thu Apr 29 11:53:41 1999
+++ linux.2210.vw/drivers/scsi/Makefile	Wed Jul 28 08:56:41 1999
@@ -282,6 +282,16 @@
   endif
 endif
 
+
+
+ifeq ($(CONFIG_SCSI_QLOGIC_1X80),y)
+L_OBJS += qla1280.o 
+else
+  ifeq ($(CONFIG_SCSI_QLOGIC_1X80),m)
+  M_OBJS += qla1280.o 
+  endif
+endif
+
 ifeq ($(CONFIG_SCSI_ACARD),y)
 L_OBJS += atp870u.o
 else
diff -Naur linux.2210/drivers/scsi/hosts.c linux.2210.vw/drivers/scsi/hosts.c
--- linux.2210/drivers/scsi/hosts.c	Mon Apr 12 09:51:04 1999
+++ linux.2210.vw/drivers/scsi/hosts.c	Wed Jul 28 08:56:41 1999
@@ -175,6 +175,10 @@
 #include "qlogicisp.h"
 #endif
 
+#ifdef CONFIG_SCSI_QLOGIC_1X80
+#include "qla1280host.h"
+#endif
+
 #ifdef CONFIG_SCSI_QLOGIC_FC
 #include "qlogicfc.h"
 #endif
@@ -487,6 +491,9 @@
 #endif
 #ifdef CONFIG_SCSI_QLOGIC_ISP
     QLOGICISP,
+#endif
+#ifdef CONFIG_SCSI_QLOGIC_1X80
+    QLA1280,
 #endif
 #ifdef CONFIG_SCSI_QLOGIC_FC
     QLOGICFC,
diff -Naur linux.2210/drivers/scsi/isp_fw.h linux.2210.vw/drivers/scsi/isp_fw.h
--- linux.2210/drivers/scsi/isp_fw.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/drivers/scsi/isp_fw.h	Wed Jul 28 08:56:41 1999
@@ -0,0 +1,1894 @@
+/************************************************************************
+ *									*
+ * 	         --- ISP1240/1080/1280 Initiator Firmware ---           *
+ *			      32 LUN Support				*
+ *									*
+ ************************************************************************
+ *                                                                      *
+ *                              NOTICE                                  *
+ *                                                                      *
+ *                 COPYRIGHT 1999 QLOGIC CORPORATION                    *
+ *                       ALL RIGHTS RESERVED                            *
+ *                                                                      *
+ * This computer program is CONFIDENTIAL  and contains TRADE SECRETS of *
+ * QLOGIC CORPORATION.  The  receipt or possession of this program does *
+ * not convey any rights to reproduce or disclose  its contents,  or to *
+ * manufacture, use, or sell anything that it may describe, in whole or *
+ * in part, without the specific written consent of QLOGIC CORPORATION. *
+ * Any reproduction of this program without the express written consent *
+ * of QLOGIC CORPORATION  is a violation of the copyright laws and  may *
+ * subject you to civil liability and criminal prosecution.             *
+ *									*
+ ************************************************************************
+ */
+
+
+/*
+ *	Firmware Version 8.09.00 (10:38 Apr 16, 1999)
+ */
+
+unsigned short ql12_risc_code_version = 8*1024+9;
+
+unsigned char ql12_firmware_version[] = {8,9,0};
+
+#define QL12_FW_VERSION_STRING "8.9.0"
+
+unsigned short ql12_risc_code_addr01 = 0x1000 ;
+
+unsigned short ql12_risc_code01[] = { 
+	0x0078, 0x1041, 0x0000, 0x39e3, 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,
+	0x7573, 0x746f, 0x6d65, 0x7220, 0x4e6f, 0x2e20, 0x3030, 0x2050,
+	0x726f, 0x6475, 0x6374, 0x204e, 0x6f2e, 0x2020, 0x3030, 0x2020,
+	0x2400, 0x20c9, 0x93ff, 0x2001, 0x04fc, 0x2004, 0xa086, 0x1080,
+	0x00c0, 0x1054, 0x2071, 0x0100, 0x70a0, 0x70a2, 0x20c1, 0x0010,
+	0x2089, 0x136a, 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,
+	0x0004, 0x70c7, 0x4953, 0x70cb, 0x5020, 0x70cf, 0x2020, 0x70d3,
+	0x0008, 0x2001, 0x04fe, 0x70d6, 0x20c1, 0x0021, 0x2019, 0x0000,
+	0x2009, 0xfeff, 0x2100, 0x200b, 0xa5a5, 0xa1ec, 0x7fff, 0x2d64,
+	0x206b, 0x0a0a, 0xaddc, 0x3fff, 0x2b54, 0x205b, 0x5050, 0x2114,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	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,
+	0x0210, 0xa801, 0x0014, 0x26e0, 0x873a, 0xfaa3, 0x19f2, 0x26e0,
+	0x18f2, 0x0014, 0xa20b, 0x0014, 0xa20d, 0x3806, 0x0210, 0x9d17,
+	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,
+	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
+};
+unsigned short   ql12_risc_code_length01 = 0x39e3;
+
diff -Naur linux.2210/drivers/scsi/qla1280.c linux.2210.vw/drivers/scsi/qla1280.c
--- linux.2210/drivers/scsi/qla1280.c	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/drivers/scsi/qla1280.c	Wed Jul 28 08:56:41 1999
@@ -0,0 +1,6514 @@
+/***************************************************************************
+ * QLogic ISP1280 device driver for Linux 2.0.36 (redhat 5.2).
+ *
+ * COPYRIGHT (C) 1996-1999 QLOGIC 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, 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; see the file COPYING.  If not, write to
+ * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ * 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, immediately at the beginning of the file.
+ * 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 the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * Where this Software is combined with software released under the terms of 
+ * the GNU Public License ("GPL") and the terms of the GPL would require the 
+ * combined work to also be released under the terms of the GPL, the terms
+ * and conditions of this License will apply in addition to those of the
+ * GPL with the exception of any terms or conditions of this License that
+ * conflict with, or are expressly prohibited by, the GPL.
+ *
+ *****************************************************************************/
+/****************************************************************************
+    Revision History:
+    Rev. 2.00       June 8, 1999      D Grigsby
+         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.  
+*****************************************************************************/
+
+
+#include <linux/config.h>        /* for CONFIG_PCI */
+#include <linux/version.h>	 /* for KERNEL_VERSION */
+#ifdef MODULE
+#include <linux/module.h>
+#endif
+
+#ifndef KERNEL_VERSION
+#  define KERNEL_VERSION(x,y,z) (((x)<<16)+((y)<<8)+(z))
+#endif
+
+#include <stdarg.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/segment.h>
+#include <asm/byteorder.h>
+#include <linux/types.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/kernel.h>
+#include <linux/ioport.h>
+#include <linux/delay.h>
+#include <linux/timer.h>
+#include <linux/sched.h>
+#include <linux/pci.h>
+#include <linux/proc_fs.h>
+#include <linux/blk.h>
+#include <linux/tqueue.h>
+#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"
+#include "qla1280.h"
+#include "qla1280host.h"
+#include "isp_fw.h"                     /* ISP RISC code */
+
+#include <linux/stat.h>
+#include <linux/malloc.h>        /* for kmalloc() */
+
+
+
+/*
+ * Compile time Options: 
+ *            0 - Disable and 1 - Enable 
+ */
+#define  QLA1280_64BIT_SUPPORT         0   /* 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 
+
+#define  DEBUG_QLA1280                 0    /* Debugging  */
+
+/*
+ * These macros to assist programming
+ */
+
+#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) (unsigned int)virt_to_bus((void *)(a))
+#if  QLA1280_64BIT_SUPPORT
+#define VIRT_TO_BUS_LOW(a) (unsigned int)(0xffffffff & virt_to_bus((void *)(a)))
+#define VIRT_TO_BUS_HIGH(a) (unsigned int)(0xffffffff & (virt_to_bus((void *)(a))>>32))
+#endif  /* QLA1280_64BIT_SUPPORT */
+
+#define STATIC     
+
+#define NVRAM_DELAY() udelay(500) /* 2 microsecond delay */
+
+#if 0 /* XXX BH */
+/*
+ *  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);
+#endif
+STATIC void qla1280_device_queue_depth(scsi_qla_host_t *, Scsi_Device *);
+
+/*
+ *  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);
+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);
+#endif
+
+/*
+ *  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);
+
+#if QL1280_TARGET_MODE_SUPPORT
+                 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;
+#endif
+#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)
+
+/* insmod qla1280 options=verbose" */
+MODULE_PARM(options, "s");  
+#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
+
+#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
+
+#if 0 /* XXX BH */
+#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
+
+
+/*
+ * Our directory Entry in /proc/scsi for the user to 
+ * access the driver. 
+ */
+
+/* Need to add in proc_fs.h     PROC_SCSI_QL1280 */
+#define PROC_SCSI_QL1280  PROC_SCSI_QLOGICISP
+
+struct proc_dir_entry proc_scsi_qla1280 = {
+    PROC_SCSI_QL1280, 7, "qla1280",                           
+    S_IFDIR | S_IRUGO | S_IXUGO, 2,
+    0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+/* We use the Scsi_Pointer structure that's included with each command
+ * SCSI_Cmnd as a scratchpad for our SRB.
+ *
+ * SCp will always point to the SRB structure (defined in qla1280.h).
+ * It is define as follows:
+ *  - SCp.ptr  -- > pointer back to the cmd
+ *  - SCp.this_residual --> used as forward pointer to next srb
+ *  - SCp.buffer --> used as backward pointer to next srb
+ *  - SCp.buffers_residual --> used as flags field
+ *  - SCp.have_data_in --> not used
+ *  - SCp.sent_command --> not used
+ *  - 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)
+
+/*****************************************/
+/*   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 NUM_OF_ISP_DEVICES        4
+
+#define QLA1280_VERSION      " 1.20-Beta"
+typedef struct _qlaboards 
+{
+   unsigned char   bdName[9];
+   unsigned long   device_id;
+   int   numPorts;
+} qla_boards_t;
+
+struct _qlaboards   QLBoardTbl[NUM_OF_ISP_DEVICES] = 
+{
+   /* Name ,  Board PCI Device ID,         Number of ports */
+  {"QLA1080 ", QLA1080_DEVICE_ID,           1},        
+  {"QLA1240 ", QLA1240_DEVICE_ID,           2},       
+  {"QLA1280 ", QLA1280_DEVICE_ID,           2},      
+  {"        ",                 0,           0}
+};
+
+static unsigned long qla1280_verbose = 1L;
+static scsi_qla_host_t *qla1280_hostlist = NULL;
+static int qla1280_buffer_size = 0;
+static char *qla1280_buffer = NULL;
+
+#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
+
+#if  DEBUG_QLA1280  
+#define COMTRACE(x)
+/* #define COMTRACE(x)     qla1280_putc(x); */
+#define DEBUG(x)	x
+#else
+#define DEBUG(x)
+#define COMTRACE(x)
+#endif
+
+#ifdef QL_DEBUG_LEVEL_2 
+#define DEBUG2(x)	x
+#else
+#define DEBUG2(x)
+#endif
+
+#define OFFSET(w)   (((uint32_t) &w) & 0xFFFF)                  /* 256 byte offsets */
+
+#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.                                     */
+/****************************************************************************/
+
+
+/*************************************************************************
+ *   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
+ *
+ * Description:
+ *   Return information to handle /proc support for the driver.
+ *
+ * buffer - ptrs to a page buffer
+ *
+ * Returns:
+ *************************************************************************/
+#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 
+int
+qla1280_proc_info ( char *buffer, char **start, off_t offset, int length, 
+                    int hostno, int inout)
+{
+  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%x,0x%lx,0x%x,0x%x\n",(int)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",ql12_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;
+    }
+  }
+
+  return (length);
+}
+
+
+/**************************************************************************
+ * 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.  
+ **************************************************************************/
+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, index, j;
+    unsigned int piobase;
+    unsigned char pci_bus, pci_devfn, pci_irq;
+    config_reg_t   *cfgp = 0;
+    device_reg_t   *reg;
+    char   *cp;
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
+    struct pci_dev *pdev = NULL;
+#endif
+
+    ENTER("qla1280_detect");
+
+#ifdef CHECKSRBSIZE
+    if (sizeof(srb_t) > sizeof(Scsi_Pointer) )
+    {
+      printk("Redefine SRB - its too big");
+      return 0;
+    }
+#endif
+
+#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(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())
+    {
+        bdp = &QLBoardTbl[0];
+        qla1280_hostlist = NULL;
+        template->proc_dir = &proc_scsi_qla1280;
+        for( i=0; bdp->device_id != 0 && i < NUM_OF_ISP_DEVICES; i++, bdp++ )
+        {
+            /* Try and find each different type of adapter we support */
+            index = 0;
+            while (!(pcibios_find_device(QLA1280_VENDOR_ID,
+                bdp->device_id,
+                index++, &pci_bus, &pci_devfn)) )
+            { /* found a adapter */
+                host = scsi_register(template, sizeof(scsi_qla_host_t)); 
+                ha = (scsi_qla_host_t *) host->hostdata;
+                for( j =0, cp = (char *)ha;  j < sizeof(scsi_qla_host_t); j++)
+                       *cp = 0;
+                /* Sanitize the information from PCI BIOS.  */
+#if 0
+                pcibios_read_config_byte(pci_bus, pci_devfn, OFFSET(cfgp->interrupt_line), &pci_irq);
+#else
+		pdev = pci_find_slot(pci_bus, pci_devfn);
+		pci_irq = pdev->irq;
+#endif
+                pcibios_read_config_dword(pci_bus, pci_devfn, OFFSET(cfgp->base_port), &piobase);
+                ha->pci_bus = pci_bus;
+                ha->pci_device_fn = pci_devfn;
+                ha->devnum = i;
+
+                host->io_port = (unsigned int) piobase;
+                host->io_port &= PCI_BASE_ADDRESS_IO_MASK;
+                host->irq = pci_irq;
+                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]);
+                ha->ports = bdp->numPorts; 
+                if( qla1280_verbose )
+                {
+                    printk("(scsi): Found a %s @ bus %2d, device %2d, irq %2d, iobase 0x%lx\n",
+                            bdp->bdName,pci_bus, (pci_devfn & 0xf8) >> 3, host->irq,host->io_port);
+                    printk("(scsi): Initializing Adapter; Please wait ...\n");
+                }
+
+                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->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 char *) ha->mmpbase;
+                host->max_id = MAX_TARGETS; 
+                host->max_channel = bdp->numPorts-1; 
+                host->max_lun = MAX_LUNS-1; 
+                ha->instance = num_hosts;
+                host->unique_id = ha->instance;
+                ha->next = NULL;
+
+                /* 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);
+                    continue;
+                }
+
+                /* 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);
+                    continue;
+                }
+
+                request_region(host->io_port, 0xff, "qla1280");
+
+                        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);
+
+                /* Enable chip interrupts. */
+                WRT_REG_WORD(&reg->ictrl, ISP_EN_INT + ISP_EN_RISC);
+                /* 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 */
+    } /* end of IF */
+
+    LEAVE("qla1280_detect");
+    return num_hosts; 
+}
+
+
+/**************************************************************************
+ *   qla1280_release
+ *   Free the passed in Scsi_Host memory structures prior to unloading the
+ *   module.
+ **************************************************************************/
+int
+qla1280_release(struct Scsi_Host *host)
+{
+    scsi_qla_host_t *ha = (scsi_qla_host_t *) host->hostdata;
+
+    ENTER("qla1280_release");
+
+    if( !ha->flags.online )
+        return(0);
+
+    /* turn-off interrupts on the card */
+    WRT_REG_WORD(&ha->iobase->ictrl, 0);
+
+    /* Detach interrupts */
+    if(host->irq)
+        free_irq(host->irq, ha);
+
+    /* release io space registers  */
+    if( host->io_port )
+        release_region(host->io_port, 0xff);
+
+#if MEMORY_MAPPED_IO
+    if(ha->mmpbase)
+    {
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+        vfree((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK));
+#else
+        iounmap((void *) (((unsigned long) ha->mmpbase) & PAGE_MASK));
+#endif
+    }
+#endif /* MEMORY_MAPPED_IO */
+    qla1280_mem_free(ha);
+
+    ENTER("qla1280_release");
+    return(0);
+}
+
+/**************************************************************************
+ *   qla1280_info
+ *     Return a string describing the driver.
+ **************************************************************************/
+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"
+            "        Version: %s, Firmware version: %s",
+            (char *)&bdp->bdName[0], ha->pci_bus, (ha->pci_device_fn & 0xf8) >> 3, host->irq,
+            QLA1280_VERSION,
+            QL12_FW_VERSION_STRING);
+    return(bp);
+}
+
+/**************************************************************************
+ *   qla1200_queuecommand
+ *     Queue a command to the controller.
+ *
+ * Note:
+ * The mid-level driver tries to ensures that queuecommand never gets invoked
+ * concurrently with itself or the interrupt handler (although the
+ * interrupt handler may call this routine as part of request-completion
+ * 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 *))
+{
+    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;
+    }
+
+
+#if DEBUG_QLA1280 
+    DEBUG3(qla1280_print_scsi_cmd(cmd));
+#endif /* DEBUG_QLA1280 */
+
+    /* 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);
+            queue_task(&ha->run_qla_bh,&tq_scheduler); 
+            ha->flags.dpc_sched = TRUE;
+            DRIVER_UNLOCK
+            return(0);
+        }
+    }
+
+    handle = MAX_OUTSTANDING_COMMANDS+1;
+    CMD_HANDLE(cmd) = (unsigned char *)handle;
+
+    sp->r_start = jiffies;                /* bookkeeping information */
+    ha->qthreads++;
+    qla1280_putq_t(q,sp);
+
+    DEBUG(sprintf(debug_buff,"qla1280: queueing SP=(0x%x), handle=(0x%x)\n\r",sp,handle));
+    DEBUG(qla1280_print(debug_buff));
+    /* we can take an unlimited number of SG elements */
+    host->sg_tablesize =  SG_ALL;
+
+
+    /* kick off a command */
+            DRIVER_LOCK
+        if (q->q_outcnt == 0)
+            qla1280_restart_queues(ha);
+    DRIVER_UNLOCK
+
+    LEAVE("qla1280_queuecommand");
+    return (0);
+}
+
+/**************************************************************************
+ *   qla1200_abort
+ *     Abort the speciifed SCSI command(s).
+ **************************************************************************/
+int
+qla1280_abort(Scsi_Cmnd *cmd)
+{
+    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
+
+    sp = (srb_t *) CMD_SP(cmd);
+    handle = (u_long) CMD_HANDLE(cmd);
+    if (qla1280_verbose)
+        printk("scsi(%d): ABORT Command=0x%x, handle=0x%lx\n",(int)ha->host_no,(int)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);
+}
+
+/**************************************************************************
+ * qla1200_reset
+ *    The reset function will reset the SCSI bus and abort any executing
+ *    commands. 
+ *
+ * Input:
+ *      cmd = Linux SCSI command packet of the command that cause the
+ *            bus reset.
+ *      flags = SCSI bus reset option flags (see scsi.h)
+ *
+ * Returns:
+ *      DID_RESET in cmd.host_byte of aborted command(s) 
+ *
+ * Note:
+ *      Resetting the bus always succeeds - is has to, otherwise the
+ *      kernel will panic! Try a surgical technique - sending a BUS
+ *      DEVICE RESET message - on the offending target before pulling
+ *      the SCSI bus reset line.
+ **************************************************************************/
+int
+qla1280_reset(Scsi_Cmnd *cmd, unsigned int flags)
+{
+    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%x, Handle=0x%lx, flags=0x%x\n",(int)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 );
+}
+
+/**************************************************************************
+ * qla1200_biosparam
+ *   Return the disk geometry for the given SCSI device.
+ **************************************************************************/
+int
+qla1280_biosparam(Disk *disk, kdev_t dev, int geom[])
+{
+    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);
+}
+/**************************************************************************
+ * qla1280_intr_handler
+ *   Handles the H/W interrupt
+ **************************************************************************/
+void qla1280_intr_handler(int irq, void *dev_id, struct pt_regs *regs)
+{
+#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')
+        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') 
+            queue_task_irq(&ha->run_qla_bh,&tq_scheduler); 
+            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);
+
+        COMTRACE('i')  
+        LEAVE_INTR("qla1280_intr_handler");
+}
+
+/**************************************************************************
+ *   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 .
+ **************************************************************************/
+void qla1280_do_dpc(void *p)
+{
+    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
+
+    COMTRACE('p')  
+#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,95)
+    spin_lock_irqsave(&io_request_lock, cpu_flags);
+#endif
+    if (ha->flags.isp_abort_needed)
+        qla1280_abort_isp(ha);
+
+    if (ha->flags.reset_marker)
+        qla1280_rst_aen(ha);
+
+    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
+}
+
+/**************************************************************************
+ *   qla1280_device_queue_depth
+ *
+ * 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
+ *   way is the default queue depth which is determined by whether
+ *   If it is defined, then it is used
+ *   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)
+{
+    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);
+    }
+
+}
+
+/**************************************************************************
+ *   qla1280_select_queue_depth
+ *
+ *   Sets the queue depth for each SCSI device hanging off the input
+ *   host adapter.  We use a queue depth of 2 for devices that do not
+ *   support tagged queueing.
+ **************************************************************************/
+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;
+
+    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  **
+**--------------------------*/
+
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,0)
+/*
+ * mdelay
+ *      Delay in milliseconds 
+ *
+ * Input:
+ *      milliseconds  = delay 
+ */
+STATIC inline void mdelay(int milliseconds)
+{
+    int i;
+
+    for(i=0; i<milliseconds; i++)
+        udelay(1000);
+}
+#endif
+
+/*
+ * qla1280_done
+ *      Process completed commands.
+ *
+ * Input:
+ *      ha           = adapter block pointer.
+ *      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);
+#endif
+        qla1280_next(ha, q, b);
+    }
+    DRIVER_UNLOCK 
+
+
+    COMTRACE('d') 
+    LEAVE("qla1280_done");
+}
+
+/*
+ * Translates a ISP error to a Linux SCSI error
+ */
+STATIC int qla1280_return_status( sts_entry_t *sts, Scsi_Cmnd       *cp)
+{
+    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 */
+
+    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;
+    }
+
+#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);
+#endif
+
+    LEAVE("qla1280_return_status");
+
+    return (sts->scsi_status & 0xff) | (host_status << 16);
+}
+
+/*
+ * qla1280_done_q_put
+ *      Place SRB command on done queue.
+ *
+ * Input:
+ *      sp           = srb pointer.
+ *      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%x<-(0x%x)\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");
+}
+
+/*
+ * 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%x<-(0x%x)\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
+}
+
+/*
+ * 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%x)->(0x%x)\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
+}
+
+/*
+ * qlc1280_mem_free
+ *      Frees adapter allocated memory.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ */
+STATIC void
+qla1280_mem_free(scsi_qla_host_t *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;
+    }
+
+    LEAVE("qlc1280_mem_free");
+}
+
+
+
+
+/****************************************************************************/
+/*                QLogic ISP1280 Hardware Support Functions.                */
+/****************************************************************************/
+
+/*
+ * qla1280_initialize_adapter
+ *      Initialize board.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * Returns:
+ *      0 = success
+ */
+STATIC uint8_t
+qla1280_initialize_adapter(scsi_qla_host_t *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)))
+            {
+                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");
+#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]; */
+
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_enable_tgt: entered\n\r");
+#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");
+#endif
+    return(status);
+}
+
+/*
+ * ISP Firmware Test
+ *      Checks if present version of RISC firmware is older than
+ *      driver firmware.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * Returns:
+ *      0 = firmware does not need to be loaded.
+ */
+STATIC uint8_t
+qla1280_isp_firmware(scsi_qla_host_t *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);
+        /*
+        *wptr = (u_short) qla1280_read_nvram_word(ha->host, (u_short) 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;
+        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;
+            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);
+}
+
+/*
+ * PCI configuration
+ *      Setup device PCI configuration registers.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * Returns:
+ *      0 = success.
+ */
+STATIC uint8_t
+qla1280_pci_config(scsi_qla_host_t *ha)
+{
+    uint8_t      status = 1;
+    uint32_t     command;
+#if MEMORY_MAPPED_IO
+    uint32_t  page_offset, base;
+    uint32_t   mmapbase;
+#endif
+    config_reg_t *creg = 0;
+    uint16_t     buf_wd;
+
+    ENTER("qla1280_pci_config");
+
+    /* Get command register. */
+    if (pcibios_read_config_word(ha->pci_bus,ha->pci_device_fn, 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;
+#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;
+#endif
+        if( pcibios_write_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->command), buf_wd) )
+        {
+            printk(KERN_WARNING "qla1280: Could not write config word.\n");
+        }
+        /* Get expansion ROM address. */
+        if (pcibios_read_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->expansion_rom), &buf_wd) == PCIBIOS_SUCCESSFUL)
+        {
+            /* Reset expansion ROM address decode enable. */
+            buf_wd &= ~BIT_0;
+            if (pcibios_write_config_word(ha->pci_bus,ha->pci_device_fn, OFFSET(creg->expansion_rom), buf_wd) == PCIBIOS_SUCCESSFUL)
+            {
+#if MEMORY_MAPPED_IO
+                /* Get memory mapped I/O address. */
+                pcibios_read_config_dword(ha->pci_bus, ha->pci_device_fn,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 */
+            }
+        }
+    }
+
+    LEAVE("qla1280_pci_config");
+    return(status);
+}
+
+/*
+ * Chip diagnostics
+ *      Test chip for proper operation.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * Returns:
+ *      0 = success.
+ */
+STATIC uint8_t
+qla1280_chip_diag(scsi_qla_host_t *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%x \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");
+#endif
+    return(status);
+}
+
+/*
+ * Setup chip
+ *      Load and start RISC firmware.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *
+ * 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
+    int i;
+#endif
+    uint16_t     cnt;
+    int          num;
+
+#ifdef QL_DEBUG_LEVEL_3
+    ENTER("qla1280_setup_chip");
+#endif
+
+    /* Load RISC code. */
+    risc_address      = ql12_risc_code_addr01;
+    risc_code_address = &ql12_risc_code01[0];
+    risc_code_size    = ql12_risc_code_length01;
+
+    DEBUG(printk("qla1280: DMAing RISC code (%d) words.\n",(int)risc_code_size));
+    DEBUG(sprintf(debug_buff,"qla1280_setup_chip:  Loading RISC code size =(%d).\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%x),%d,%d(0x%x).\n\r",risc_code_address,cnt,num,risc_address);)
+        DEBUG(qla1280_print(debug_buff));
+        BCOPY((caddr_t) risc_code_address,(caddr_t) ha->request_ring, (cnt <<1));
+        mb[0] = MBC_LOAD_RAM;
+        mb[1] = risc_address;
+        mb[3] = (uint16_t) (ha->request_dma & 0xffff);
+        mb[2] = (uint16_t) (ha->request_dma >> 16) & 0xffff;
+        mb[4] = cnt;
+        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;
+        }
+
+        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;
+        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;
+            qla1280_mailbox_command(ha, BIT_1|BIT_0, &mb[0]);
+        }
+#if defined(QL_DEBUG_LEVEL_2)
+        else
+            qla1280_print("qla1280_setup_chip: Failed checksum.\n");
+#endif
+    }
+
+#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");
+#endif
+    return(status);
+}
+
+/*
+ * Initialize rings
+ *
+ * Input:
+ *      ha                = adapter block pointer.
+ *      ha->request_ring  = request ring virtual address
+ *      ha->response_ring = response ring virtual address
+ *      ha->request_dma   = request ring physical address
+ *      ha->response_dma  = response ring physical address
+ *
+ * Returns:
+ *      0 = success.
+ */
+STATIC uint8_t
+qla1280_init_rings(scsi_qla_host_t *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[1] = REQUEST_ENTRY_CNT;
+    mb[3] = (uint16_t)ha->request_dma;
+    mb[2] = (uint16_t)(ha->request_dma >> 16);
+    mb[4] = 0;
+    mb[7] = 0;
+    mb[6] = 0;
+    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[1] = RESPONSE_ENTRY_CNT;
+        mb[3] = (uint16_t)ha->response_dma;
+        mb[2] = (uint16_t)(ha->response_dma >> 16);
+        mb[5] = 0;
+        mb[7] = 0;
+        mb[6] = 0;
+        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);
+}
+
+/*
+ * NVRAM configuration.
+ *
+ * Input:
+ *      ha                = adapter block pointer.
+ *      ha->request_ring  = request ring virtual address
+ *
+ * Output:
+ *      host adapters parameters in host adapter block
+ *
+ * Returns:
+ *      0 = success.
+ */
+STATIC uint8_t
+qla1280_nvram_config(scsi_qla_host_t *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;
+
+#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;
+    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++;
+    }
+#endif
+
+
+    /* 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"));
+#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;
+#endif
+
+
+        /* 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;
+            }
+        }
+
+#if  USE_NVRAM_DEFAULTS
+        status = 0;
+#else
+        status = 1;
+#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++)
+        {
+            /* 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);
+}
+
+/*
+ * Get NVRAM data word
+ *      Calculates word position in NVRAM and calls request routine to
+ *      get the word from NVRAM.
+ *
+ * Input:
+ *      ha      = adapter block pointer.
+ *      address = NVRAM word address.
+ *
+ * Returns:
+ *      data word.
+ */
+STATIC uint16_t
+qla1280_get_nvram_word(scsi_qla_host_t *ha, uint32_t address)
+{
+    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;
+
+#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
+
+#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);
+}
+
+/*
+ * NVRAM request
+ *      Sends read command to NVRAM and gets data from NVRAM.
+ *
+ * Input:
+ *      ha     = adapter block pointer.
+ *      nv_cmd = Bit 26     = start bit
+ *               Bit 25, 24 = opcode
+ *               Bit 23-16  = address
+ *               Bit 15-0   = write data
+ *
+ * Returns:
+ *      data word.
+ */
+STATIC uint16_t
+qla1280_nvram_request(scsi_qla_host_t *ha, uint32_t nv_cmd)
+{
+    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;
+
+    while (cnt--)
+        data |= RD_REG_WORD(&reg->nvram);
+}
+
+/*
+ * Mailbox Command
+ *      Issue mailbox command and waits for completion.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      mr = mailbox registers to load.
+ *      mb = data pointer for mailbox registers.
+ *
+ * Output:
+ *      mb[MAILBOX_REGISTER_COUNT] = returned mailbox data.
+ *
+ * Returns:
+ *      0 = success
+ */
+STATIC uint8_t
+qla1280_mailbox_command(scsi_qla_host_t *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");
+#endif
+    return(status);
+}
+
+/*
+ * qla1280_poll
+ *      Polls ISP for interrupts.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ */
+STATIC void
+qla1280_poll(scsi_qla_host_t *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);
+    }
+
+    if (done_q_first)
+        qla1280_done(ha, (srb_t **)&done_q_first, (srb_t **)&done_q_last);
+
+#ifdef QL_DEBUG_LEVEL_3
+    /* LEAVE("qla1280_poll"); */
+#endif
+}
+
+/*
+ * qla1280_bus_reset
+ *      Issue SCSI bus reset.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      b  = SCSI bus number.
+ *
+ * Returns:
+ *      0 = success
+ */
+STATIC uint8_t
+qla1280_bus_reset(scsi_qla_host_t *ha, uint8_t b)
+{
+    uint8_t     status;
+    uint16_t    mb[MAILBOX_REGISTER_COUNT];
+
+#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++;
+    }
+	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);
+}
+
+/*
+ * qla1280_device_reset
+ *      Issue bus device reset message to the target.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      b  = SCSI BUS number.
+ *      t  = SCSI ID.
+ *
+ * Returns:
+ *      0 = success
+ */
+STATIC uint8_t
+qla1280_device_reset(scsi_qla_host_t *ha, uint8_t b, uint32_t t)
+{
+    uint8_t     status;
+    uint16_t    mb[MAILBOX_REGISTER_COUNT];
+
+#ifdef QL_DEBUG_LEVEL_3
+    ENTER("qla1280_device_reset");
+#endif
+
+    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]);
+
+    /* Issue marker command. */
+    qla1280_marker(ha, b, t, 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);
+}
+
+/*
+ * qla1280_abort_device
+ *      Issue an abort message to the device
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      b  = SCSI BUS.
+ *      t  = SCSI ID.
+ *      l  = 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)
+{
+    uint8_t     status;
+    uint16_t    mb[MAILBOX_REGISTER_COUNT];
+
+#ifdef QL_DEBUG_LEVEL_3
+    ENTER("qla1280_abort_device");
+#endif
+
+    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]);
+
+    /* Issue marker command. */
+    qla1280_marker(ha, b, t, l, 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);
+}
+
+/*
+ * qla1280_abort_command
+ *      Abort command aborts a specified IOCB.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      sp = SB structure pointer.
+ *
+ * Returns:
+ *      0 = success
+ */
+STATIC uint8_t
+qla1280_abort_command(scsi_qla_host_t *ha, srb_t *sp)
+{
+    uint8_t         status;
+    uint16_t        mb[MAILBOX_REGISTER_COUNT];
+    uint32_t        b, t, l;
+    uint32_t        handle;
+
+#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);
+}
+
+/*
+ * qla1280_reset_adapter
+ *      Reset adapter.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ */
+STATIC void
+qla1280_reset_adapter(scsi_qla_host_t *ha)
+{
+    device_reg_t *reg = ha->iobase;
+
+#ifdef QL_DEBUG_LEVEL_3
+    ENTER("qla1280_reset_adapter");
+#endif
+
+    /* 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);
+
+#ifdef QL_DEBUG_LEVEL_3
+    LEAVE("qla1280_reset_adapter");
+#endif
+}
+
+/*
+ *  Issue marker command.
+ *      Function issues marker IOCB.
+ *
+ * Input:
+ *      ha   = adapter block pointer.
+ *      b    = SCSI BUS number
+ *      t    = SCSI ID
+ *      l    = 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)
+{
+    mrk_entry_t     *pkt;
+
+#ifdef QL_DEBUG_LEVEL_3
+    ENTER("qla1280_marker");
+#endif
+
+    /* 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;
+
+        /* Issue command to ISP */
+        qla1280_isp_cmd(ha);
+    }
+
+#ifdef QL_DEBUG_LEVEL_3
+    LEAVE("qla1280_marker");
+#endif
+}
+
+#if  QLA1280_64BIT_SUPPORT
+/*
+ * qla1280_64bit_start_scsi
+ *      The start SCSI is responsible for building request packets on
+ *      request ring and modifying ISP input pointer.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      sp = SB structure pointer.
+ *
+ * Returns:
+ *      0 = success, was able to issue command.
+ */
+STATIC uint8_t
+qla1280_64bit_start_scsi(scsi_qla_host_t *ha, srb_t *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;
+    paddr32_t       *addr32p;
+    caddr_t         data_ptr;
+    uint32_t        *dword_ptr;
+    uint32_t        timeout;
+
+#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 *) cnt;
+
+            /*
+            * Build command packet.
+            */
+            pkt = 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);
+            data_ptr = (uint8_t *) &(CMD_CDBP(cmd));
+            for (cnt = 0; cnt < pkt->cdb_len; cnt++)
+                pkt->scsi_cdb[cnt] = *data_ptr++;
+
+            /*
+            * 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--)
+                    {
+                        *dword_ptr++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_LOW(sg->address));
+                        *dword_ptr++ = (uint32_t) 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 = 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++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_LOW(sg->address));
+                            *dword_ptr++ = (uint32_t) 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++ = (uint32_t) cpu_to_le32(VIRT_TO_BUS_LOW(cmd->request_buffer));
+                    *dword_ptr++ = (uint32_t) 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)SDI_BUS_32(cmd), 10);
+                qla1280_print("t");
+                qla1280_output_number((uint32_t)SDI_TCN_32(cmd), 10);
+                qla1280_print("d");
+                qla1280_output_number((uint32_t)SDI_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);
+}
+#endif  /* QLA1280_64BIT_SUPPORT */
+
+/*
+ * qla1280_32bit_start_scsi
+ *      The start SCSI is responsible for building request packets on
+ *      request ring and modifying ISP input pointer.
+ *
+ *      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 
+ *      hold another 7 entries each.  The start routine determines if there
+ *      is eought empty slots then build the combination of requests to 
+ *      fulfill the OS request.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      sp = SCSI Request Block structure pointer.
+ *
+ * Returns:
+ *      0 = success, was able to issue command.
+ */
+STATIC uint8_t
+qla1280_32bit_start_scsi(scsi_qla_host_t *ha, srb_t *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 *) 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%x, 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%x, 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);
+}
+
+/*
+ * qla1280_req_pkt
+ *      Function is responsible for locking ring and
+ *      getting a zeroed out request packet.
+ *
+ * Input:
+ *      ha  = adapter block pointer.
+ *
+ * Returns:
+ *      0 = failed to get slot.
+ */
+STATIC request_t *
+qla1280_req_pkt(scsi_qla_host_t *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);
+
+    /* Release ring specific lock */
+    QLA1280_RING_UNLOCK(ha);
+
+#ifdef QL_DEBUG_LEVEL_3
+    LEAVE("qla1280_isp_cmd");
+#endif
+}
+
+/*
+ * 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;
+
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_enable_lun: entered\n\r");
+#endif
+
+    /* 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;
+
+    qla1280_isp_cmd(ha);
+    }
+    */
+    pkt = (elun_entry_t *)1;
+
+#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
+}
+
+#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.
+ *
+ * Input:
+ *      ha      = adapter block pointer.
+ *      inotify = immediate notify entry pointer.
+ */
+STATIC void
+qla1280_notify_ack(scsi_qla_host_t *ha, notify_entry_t *inotify)
+{
+    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);
+    }
+
+#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;
+
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_immed_notify: entered\n\r");
+#endif
+
+    /* 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;
+
+        /* Issue command to ISP */
+        qla1280_isp_cmd(ha);
+    }
+
+#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
+}
+
+/*
+ * qla1280_accept_io
+ *      Issue accept target I/O IOCB for LUN 0.
+ *
+ * Input:
+ *      ha = adapter block pointer.
+ *      ctio = ctio returned entry pointer.
+ */
+STATIC void
+qla1280_accept_io(scsi_qla_host_t *ha, ctio_ret_entry_t *ctio)
+{
+    atio_entry_t    *pkt;
+
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_accept_io: entered\n\r");
+#endif
+
+    /* 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;
+
+        /* 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
+}
+
+/*
+ * 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.                        */
+/****************************************************************************/
+
+/****************************************************************************
+ *  qla1280_isr
+ *      Calls I/O done on command completion.
+ *
+ * Input:
+ *      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
+        }
+    }
+
+    LEAVE("qla1280_isr");
+}
+
+/*
+ *  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;
+
+#ifdef QL_DEBUG_LEVEL_3
+    ENTER("qla1280_rst_aen");
+#endif
+
+    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 (!ha->flags.reset_marker)
+                    {
+#if QL1280_TARGET_MODE_SUPPORT
+                        /* Issue notify acknowledgement command. */
+                        bzero((caddr_t)&nentry, sizeof(notify_entry_t));
+
+                        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
+
+                        /* Asynchronous event notification */
+                    }
+                }
+            }
+        }
+    }
+
+#ifdef QL_DEBUG_LEVEL_3
+    LEAVE("qla1280_rst_aen");
+#endif
+}
+
+#if QL1280_TARGET_MODE_SUPPORT
+/*
+ *  qla1280_atio_entry
+ *      Processes received ISP accept target I/O entry.
+ *
+ * Input:
+ *      ha  = adapter block pointer.
+ *      pkt = entry pointer.
+ */
+STATIC void
+qla1280_atio_entry(scsi_qla_host_t *ha, atio_entry_t *pkt)
+{
+    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;
+    }
+
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_atio_entry: exiting normally\n\r");
+#endif
+}
+
+/*
+ *  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)
+{
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_notify_entry: entered\n\r");
+#endif
+
+    /* Acknowledge immediate notify */
+    qla1280_notify_ack(ha, pkt);
+
+    /* Issue notify entry to increment resource count */
+    qla1280_immed_notify(ha, pkt);
+
+#ifdef QL_DEBUG_LEVEL_3
+    qla1280_print("qla1280_notify_entry: exiting normally\n\r");
+#endif
+}
+
+#endif  /* QLA1280_TARGET_MODE_SUPPORT */
+/*
+ *  qla1280_status_entry
+ *      Processes received ISP status entry.
+ *
+ * Input:
+ *      ha           = adapter block pointer.
+ *      pkt          = entry pointer.
+ *      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
+}
+
+/*
+ *  qla1280_error_entry
+ *      Processes error entry.
+ *
+ * Input:
+ *      ha           = adapter block pointer.
+ *      pkt          = entry pointer.
+ *      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
+
+#ifdef QL_DEBUG_LEVEL_3
+    LEAVE("qla1280_error_entry");
+#endif
+}
+
+/*
+ *  qla1280_abort_isp
+ *      Resets ISP and aborts all outstanding commands.
+ *
+ * Input:
+ *      ha           = adapter block pointer.
+ *
+ * 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)
+{
+    scsi_lu_t *q;
+    uint32_t  b, t, l;
+
+#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);
+
+                    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
+}
+
+/*
+ *  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; 
+
+    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);
+
+        sp = q->q_first;
+        q->q_first = q->q_last = NULL;
+
+        QLA1280_SCSILU_UNLOCK(q);
+
+        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");
+}
+
+/*
+ *  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;
+
+    ENTER("qla1280_abort_queues");
+
+    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);
+
+            LEAVE("qla1280_abort_queues");
+}
+
+/*
+ * qla1280_debounce_register
+ *      Debounce register.
+ *
+ * Input:
+ *      port = register address.
+ *
+ * Returns:
+ *      register value.
+ */
+STATIC uint16_t
+qla1280_debounce_register(volatile uint16_t *addr)
+{
+    volatile uint16_t ret;
+    volatile uint16_t ret2;
+
+    do
+    {
+        ret = RD_REG_WORD(addr);
+        ret2 = RD_REG_WORD(addr);
+    }while (ret != ret2);
+
+    return(ret);
+}
+
+
+/*
+ * Declarations for load module
+ */
+#ifdef MODULE
+Scsi_Host_Template driver_template = QLA1280_LINUX_TEMPLATE;
+
+#include "scsi_module.c"
+#endif
+
+/************************************************************************
+ * qla1280_check_for_dead_scsi_bus                                      *
+ *                                                                      *
+ *    This routine checks for a dead SCSI bus                           *
+ ************************************************************************/
+#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 */
+}
+
+
+
+#ifdef QL_DEBUG_ROUTINES
+/****************************************************************************/
+/*                         Driver Debug Functions.                          */
+/****************************************************************************/
+
+/*
+ *  Get byte from I/O port
+ */
+STATIC uint8_t
+qla1280_getbyte(uint8_t *port)
+{
+    uint8_t ret;
+
+#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);
+}
+
+/*
+ *  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)
+{
+    uint32_t ret;
+
+#if MEMORY_MAPPED_IO
+    ret = *port;
+#else
+    ret = inl((int)port);
+#endif
+
+    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");
+    }
+
+    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);
+}
+
+/*
+ *  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)
+{
+    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%08x, Handle=0x%08x\n\r", (int)cmd,(int) (int)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%x, request buffer len=0x%x\n\r",(int)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%x\n\r", (int)cmd->pid, (int)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%lx, direction=0x%x, req.cmd=0x%x \n\r", cmd->underflow, sp->dir,cmd->request.cmd);    
+    qla1280_print(debug_buff);
+}
+/**************************************************************************
+ *   ql1280_dump_device
+ *
+ **************************************************************************/
+void
+ql1280_dump_device(scsi_qla_host_t *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);
+    }
+
+}
+#endif
+
+#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));
+}
+#endif
+
+
+
+#if  STOP_ON_ERROR 
+/**************************************************************************
+ *   ql1280_panic
+ *
+ **************************************************************************/
+static void qla1280_panic(char *cp, struct Scsi_Host *host)
+{
+    scsi_qla_host_t *ha;
+    long  *fp;
+
+    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();  
+    }
+    */
+}
+#endif
+
+#ifdef  QLA1280_UNUSED 
+static void qla1280_set_flags(char * s)
+{
+}
+#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;
+
+#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 );
+}
+
+/*
+ * Overrides for Emacs so that we almost follow Linus's tabbing style.
+ * Emacs will notice this stuff at the end of the file and automatically
+ * adjust the settings for this buffer only.  This must remain at the end
+ * of the file.
+ * ---------------------------------------------------------------------------
+ * Local variables:
+ * c-indent-level: 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
+ * tab-width: 8
+ * End:
+ */
+
diff -Naur linux.2210/drivers/scsi/qla1280.h linux.2210.vw/drivers/scsi/qla1280.h
--- linux.2210/drivers/scsi/qla1280.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/drivers/scsi/qla1280.h	Wed Jul 28 09:05:18 1999
@@ -0,0 +1,1334 @@
+/*
+ *  QLogic ISP1280 Linux Driver
+ *  Host Bus Adapter driver include file.
+ */
+
+/*************************************************************************
+**                                                                      **
+**                                NOTICE                                **
+**                COPYRIGHT (C) 1999 QLOGIC CORPORATION                 **
+**                         ALL RIGHTS RESERVED                          **
+**                                                                      **
+** This computer program is CONFIDENTIAL and contains TRADE SECRETS of  **
+** QLOGIC CORPORATION.  The receipt or possession of this program does  **
+** not convey any rights to reproduce or disclose its contents, or to   **
+** manufacture, use, or sell anything that it may describe, in whole or **
+** in part, without the specific written consent of QLOGIC CORPORATION. **
+** Any reproduction of this program without the express written consent **
+** of QLOGIC CORPORATION is a violation of the copyright laws and may   **
+** subject you to civil liability and criminal prosecution.             **
+**                                                                      **
+*************************************************************************/
+
+#ifndef _IO_HBA_QLA1280_H           /* wrapper symbol for kernel use */
+#define _IO_HBA_QLA1280_H           /* subject to change without notice */
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+/*
+ * 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 <asm/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
+
+/*
+ * 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)         (*((volatile uint8_t *)addr))
+       #define RD_REG_WORD(addr)         (*((volatile uint16_t *)addr))
+       #define RD_REG_DWORD(addr)        (*((volatile uint32_t *)addr))
+       #define WRT_REG_BYTE(addr, data)  (*((volatile uint8_t *)addr) = data)
+       #define WRT_REG_WORD(addr, data)  (*((volatile uint16_t *)addr) = data)
+       #define WRT_REG_DWORD(addr, data) (*((volatile uint32_t *)addr) = data) 
+#else   /* MEMORY_MAPPED_IO */
+#define RD_REG_BYTE(addr)         (inb((int)addr))
+#define RD_REG_WORD(addr)         (inw((int)addr))
+#define RD_REG_DWORD(addr)        (inl((int)addr))
+#ifdef LINUX_IOPORTS
+/* Parameters are reversed in Linux */
+#define WRT_REG_BYTE(addr, data)  (outb(data,(int)addr))
+#define WRT_REG_WORD(addr, data)  (outw(data,(int)addr))
+#define WRT_REG_DWORD(addr, data) (outl(data,(int)addr))
+#else
+#define WRT_REG_BYTE(addr, data)  (outb((int)addr, data))
+#define WRT_REG_WORD(addr, data)  (outw((int)addr, data))
+#define WRT_REG_DWORD(addr, data) (outl((int)addr, data))
+#endif
+#endif  /* MEMORY_MAPPED_IO */
+#endif    /* QL_DEBUG_LEVEL_1 */
+
+/*
+ * Host adapter default definitions.
+ */
+#define MAX_BUSES       2             /* 2 */
+#define MAX_B_BITS      1
+
+#define MAX_TARGETS     16             /* 16 */
+#define MAX_T_BITS      4              /* 4 */
+
+#define MAX_LUNS        8              /* 32 */
+#define MAX_L_BITS      3               /* 5 */
+
+/*
+ * Watchdog time quantum
+ */
+#define QLA1280_WDG_TIME_QUANTUM   5    /* In seconds */
+
+/* Command retry count (0-65535) */
+#define COMMAND_RETRY_COUNT   255
+
+/* Maximum outstanding commands in ISP queues (1-65535) */
+#define MAX_OUTSTANDING_COMMANDS   512
+
+/* 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)
+
+/* Number of segments 1 - 65535 */
+#define SG_SEGMENTS     32             /* Cmd entry + 6 continuations */
+
+
+typedef struct timer_list   timer_t;         /* timer */
+
+/*
+ * SCSI Request Block structure
+ */
+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;
+
+/*
+ * 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 */
+
+
+/*
+ * 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;
+
+/*
+ *  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;
+
+#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
+
+/*
+ * 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. */
+
+/*
+ * 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. */
+
+/*
+ * 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. */
+
+/*
+ * 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. */
+
+/*
+ * 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. */
+
+/*
+ * 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. */
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * ISP queue - extended command entry structure definition.
+ */
+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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * ISP queue - modify LUN entry structure definition.
+ */
+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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * 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;
+
+/*
+ * ISP request and response queue entry sizes
+ */
+#define RESPONSE_ENTRY_SIZE     (sizeof(response_t))
+#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 */
+
+/*
+ * ISP status entry - SCSI status byte bit definitions.
+ */
+#define SS_CHECK_CONDITION  BIT_1
+#define SS_CONDITION_MET    BIT_2
+#define SS_BUSY_CONDITION   BIT_3
+#define SS_RESERVE_CONFLICT (BIT_4 | BIT_3)
+
+/*
+ * 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_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
+
+/*
+ * 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_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;
+    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;
+
+    /* 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 */
+
+#ifdef UNUSED
+    /* Interrupt lock, and data */
+    uint8_t          intr_lock;         /* Lock for interrupt locking */
+#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];
+#endif
+
+    request_t       req[REQUEST_ENTRY_CNT+1];
+    response_t      res[RESPONSE_ENTRY_CNT+1];
+    uint32_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. */
+
+    uint32_t        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
+
+#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 */
+
+    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 */
+    }flags;
+
+}scsi_qla_host_t;
+
+/*
+ * 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 QLA1280_RING_LOCK(ha)  
+#define QLA1280_RING_UNLOCK(ha)   
+
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif /* _IO_HBA_QLA1280_H */
diff -Naur linux.2210/drivers/scsi/qla1280host.h linux.2210.vw/drivers/scsi/qla1280host.h
--- linux.2210/drivers/scsi/qla1280host.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/drivers/scsi/qla1280host.h	Wed Jul 28 08:56:41 1999
@@ -0,0 +1,46 @@
+/*
+ *  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[]); /* x86 only XXX BH */
+void qla1280_intr_handler(int, void *, struct pt_regs *);
+void qla1280_setup(char *s, int *dummy);
+
+#define QLA1280 {		                 \
+	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					        \
+}
diff -Naur linux.2210/drivers/sound/Config.in linux.2210.vw/drivers/sound/Config.in
--- linux.2210/drivers/sound/Config.in	Sun Mar  7 15:22:06 1999
+++ linux.2210.vw/drivers/sound/Config.in	Wed Jul 28 08:56:41 1999
@@ -9,6 +9,9 @@
 
 # Prompt user for primary drivers.
 
+if [ "$CONFIG_VISWS" = "y" ]; then
+    dep_tristate 'SGI Visual Workstation Sound' CONFIG_SOUND_VWSND $CONFIG_SOUND
+fi
 dep_tristate 'Ensoniq AudioPCI (ES1370)' CONFIG_SOUND_ES1370 $CONFIG_SOUND
 if [ "$CONFIG_SOUND_ES1370" = "y" ]; then
    bool 'Joystick support at boot time' CONFIG_SOUND_ES1370_JOYPORT_BOOT
diff -Naur linux.2210/drivers/sound/Makefile linux.2210.vw/drivers/sound/Makefile
--- linux.2210/drivers/sound/Makefile	Thu Jan 14 22:59:47 1999
+++ linux.2210.vw/drivers/sound/Makefile	Wed Jul 28 08:56:41 1999
@@ -72,6 +72,7 @@
 obj-$(CONFIG_SOUND_VMIDI)	+= v_midi.o
 obj-$(CONFIG_SOUND_YM3812)	+= adlib_card.o opl3.o
 obj-$(CONFIG_SOUND_VIDC)	+= vidc_mod.o
+obj-$(CONFIG_SOUND_VWSND)	+= vwsnd.o
 obj-$(CONFIG_SOUND_WAVEARTIST)	+= waveartist.o
 obj-$(CONFIG_SOUND_WAVEFRONT)   += wavefront.o
 
diff -Naur linux.2210/drivers/sound/sound_core.c linux.2210.vw/drivers/sound/sound_core.c
--- linux.2210/drivers/sound/sound_core.c	Mon Jun  7 11:06:06 1999
+++ linux.2210.vw/drivers/sound/sound_core.c	Wed Jul 28 08:56:41 1999
@@ -395,6 +395,9 @@
 	/*
 	 *	Now init non OSS drivers
 	 */
+#ifdef CONFIG_SOUND_VWSND
+	init_vwsnd();
+#endif
 #ifdef CONFIG_SOUND_SONICVIBES
 	init_sonicvibes();
 #endif
diff -Naur linux.2210/drivers/sound/vwsnd.c linux.2210.vw/drivers/sound/vwsnd.c
--- linux.2210/drivers/sound/vwsnd.c	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/drivers/sound/vwsnd.c	Wed Jul 28 08:56:42 1999
@@ -0,0 +1,3306 @@
+/*
+ * Sound driver for Silicon Graphics 320 and 540 Visual Workstations'
+ * onboard audio.  See notes in ../../Documentation/sound/vwsnd .
+ *
+ * Copyright 1999 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#undef VWSND_DEBUG			/* define for debugging */
+
+/*
+ * XXX to do -
+ *
+ *	Trigger.
+ *	Too many frags -- how to reduce frags, extra copying?
+ *	Sync.
+ *	What do SYNC, RESET, POST do on input?
+ *	Rename swbuf, hwbuf, u&i, hwptr&swptr to something rational.
+ *	Bug - if select() called before read(), pcm_setup() not called.
+ */
+
+/*
+ * XXX things to test -
+ *
+ *	Will readv/writev work?  Write a test.
+ *
+ *	insmod/rmmod 100 million times.
+ *
+ *	Run I/O until int ptrs wrap around (roughly 6.2 hours @ DAT
+ *	rate).
+ *
+ *	Concurrent threads banging on mixer simultaneously, both UP
+ *	and MP.  Especially, watch for thread A changing OUTSRC while
+ *	thread B changes gain.
+ *
+ *	What happens if a client opens /dev/audio then forks?
+ *	Do two procs have /dev/audio open?  Test.
+ *
+ *	Pump audio through the CD, MIC and line inputs and verify that
+ *	they mix/mute into the output.
+ *
+ *	Apps:
+ *		sndconfig
+ *		amp
+ *		mpg123
+ *		x11amp
+ *		mxv
+ *		kmedia
+ *		esound
+ *		need more input apps
+ *
+ *	Run tests while bombarding with signals.  setitimer(2) will do it...
+ */
+
+/*
+ * This driver is organized in nine sections.
+ * The nine sections are:
+ *
+ *	debug stuff
+ * 	low level lithium access
+ *	high level lithium access
+ *	AD1843 access
+ *	PCM I/O
+ *	audio driver
+ *	mixer driver
+ *	probe/attach/unload
+ *	initialization and loadable kernel module interface
+ *
+ * That is roughly the order of increasing abstraction, so forward
+ * dependencies are minimal.
+ */
+
+/*
+ * Locking Notes
+ *
+ *	INC_USE_COUNT and DEC_USE_COUNT keep track of the number of
+ *	open descriptors to this driver.  When the driver is compiled
+ *	as a module, they call MOD_{INC,DEC}_USE_COUNT; otherwise they
+ *	bump vwsnd_use_count.  The global device list, vwsnd_dev_list,
+ *	is immutable when the IN_USE is true.
+ *
+ *	devc->open_lock is a semaphore that is used to enforce the
+ *	single reader/single writer rule for /dev/audio.  The rule is
+ *	that each device may have at most one reader and one writer.
+ *	Open will block until the previous client has closed the
+ *	device, unless O_NONBLOCK is specified.
+ *
+ *	The semaphore devc->io_sema serializes PCM I/O syscalls.  This
+ *	is unnecessary in Linux 2.2, because the kernel lock
+ *	serializes read, write, and ioctl globally, but it's there,
+ *	ready for the brave, new post-kernel-lock world.
+ *
+ *	Locking between interrupt and baselevel is handled by the
+ *	"lock" spinlock in vwsnd_port (one lock each for read and
+ *	write).  Each half holds the lock just long enough to see what
+ *	area it owns and update its pointers.  See pcm_output() and
+ *	pcm_input() for most of the gory stuff.
+ *
+ *	devc->mix_sema serializes all mixer ioctls.  This is also
+ *	redundant because of the kernel lock.
+ *
+ *	The lowest level lock is lith->lithium_lock.  It is a
+ *	spinlock which is held during the two-register tango of
+ *	reading/writing an AD1843 register.  See
+ *	li_{read,write}_ad1843_reg().
+ */
+
+/*
+ * Sample Format Notes
+ *
+ *	Lithium's DMA engine has two formats: 16-bit 2's complement
+ *	and 8-bit unsigned .  16-bit transfers the data unmodified, 2
+ *	bytes per sample.  8-bit unsigned transfers 1 byte per sample
+ *	and XORs each byte with 0x80.  Lithium can input or output
+ *	either mono or stereo in either format.
+ *
+ *	The AD1843 has four formats: 16-bit 2's complement, 8-bit
+ *	unsigned, 8-bit mu-Law and 8-bit A-Law.
+ *
+ *	This driver supports five formats: AFMT_S8, AFMT_U8,
+ *	AFMT_MU_LAW, AFMT_A_LAW, and AFMT_S16_LE.
+ *
+ *	For AFMT_U8 output, we keep the AD1843 in 16-bit mode, and
+ *	rely on Lithium's XOR to translate between U8 and S8.
+ *
+ *	For AFMT_S8, AFMT_MU_LAW and AFMT_A_LAW output, we have to XOR
+ *	the 0x80 bit in software to compensate for Lithium's XOR.
+ *	This happens in pcm_copy_{in,out}().
+ */
+
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/stddef.h>
+#include <asm/fixmap.h>
+#include <asm/sgi-cobalt.h>
+#include <asm/spinlock.h>
+
+#include "sound_config.h"
+
+/*****************************************************************************/
+/* debug stuff */
+
+#ifdef VWSND_DEBUG
+
+#include <linux/interrupt.h>		/* for in_interrupt() */
+
+static int shut_up = 1;
+
+/*
+ * dbgassert - called when an assertion fails.
+ */
+
+static void dbgassert(const char *fcn, int line, const char *expr)
+{
+	if (in_interrupt())
+		panic("ASSERTION FAILED IN INTERRUPT, %s:%s:%d %s\n",
+		      __FILE__, fcn, line, expr);
+	else {
+		int x;
+		printk(KERN_ERR "ASSERTION FAILED, %s:%s:%d %s\n",
+		       __FILE__, fcn, line, expr);
+		x = * (volatile int *) 0; /* force proc to exit */
+	}
+}
+
+/*
+ * Bunch of useful debug macros:
+ *
+ *	ASSERT	- print unless e nonzero (panic if in interrupt)
+ *	DBGDO	- include arbitrary code if debugging
+ *	DBGX	- debug print raw (w/o function name)
+ *	DBGP	- debug print w/ function name
+ *	DBGE	- debug print function entry
+ *	DBGC	- debug print function call
+ *	DBGR	- debug print function return
+ *	DBGXV	- debug print raw when verbose
+ *	DBGPV	- debug print when verbose
+ *	DBGEV	- debug print function entry when verbose
+ *	DBGRV	- debug print function return when verbose
+ */
+
+#define ASSERT(e)      ((e) ? (void) 0 : dbgassert(__FUNCTION__, __LINE__, #e))
+#define DBGDO(x)            x
+#define DBGX(fmt, args...)  (in_interrupt() ? 0 : printk(KERN_ERR fmt, ##args))
+#define DBGP(fmt, args...)  (DBGX(__FUNCTION__ ": " fmt, ##args))
+#define DBGE(fmt, args...)  (DBGX(__FUNCTION__ fmt, ##args))
+#define DBGC(rtn)           (DBGP("calling %s\n", rtn))
+#define DBGR()              (DBGP("returning\n"))
+#define DBGXV(fmt, args...) (shut_up ? 0 : DBGX(fmt, ##args))
+#define DBGPV(fmt, args...) (shut_up ? 0 : DBGP(fmt, ##args))
+#define DBGEV(fmt, args...) (shut_up ? 0 : DBGE(fmt, ##args))
+#define DBGCV(rtn)          (shut_up ? 0 : DBGC(rtn))
+#define DBGRV()             (shut_up ? 0 : DBGR())
+
+#else /* !VWSND_DEBUG */
+
+#define ASSERT(e)           ((void) 0)
+#define DBGDO(x)            /* don't */
+#define DBGX(fmt, args...)  ((void) 0)
+#define DBGP(fmt, args...)  ((void) 0)
+#define DBGE(fmt, args...)  ((void) 0)
+#define DBGC(rtn)           ((void) 0)
+#define DBGR()              ((void) 0)
+#define DBGPV(fmt, args...) ((void) 0)
+#define DBGXV(fmt, args...) ((void) 0)
+#define DBGEV(fmt, args...) ((void) 0)
+#define DBGCV(rtn)          ((void) 0)
+#define DBGRV()             ((void) 0)
+
+#endif /* !VWSND_DEBUG */
+
+/*****************************************************************************/
+/* low level lithium access */
+
+/*
+ * We need to talk to Lithium registers on three pages.  Here are
+ * the pages' offsets from the base address (0xFF001000).
+ */
+
+enum {
+	LI_PAGE0_OFFSET = 0x01000 - 0x1000, /* FF001000 */
+	LI_PAGE1_OFFSET = 0x0F000 - 0x1000, /* FF00F000 */
+	LI_PAGE2_OFFSET = 0x10000 - 0x1000, /* FF010000 */
+};
+
+/* low-level lithium data */
+
+typedef struct lithium {
+	caddr_t		page0;		/* virtual addresses */
+	caddr_t		page1;
+	caddr_t		page2;
+	spinlock_t	lock;		/* protects codec and UST/MSC access */
+} lithium_t;
+
+/*
+ * li_create initializes the lithium_t structure and sets up vm mappings
+ * to access the registers.
+ * Returns 0 on success, -errno on failure.
+ */
+
+static int li_create(lithium_t *lith, unsigned long baseaddr)
+{
+	static void li_destroy(lithium_t *);
+
+	lith->lock = SPIN_LOCK_UNLOCKED;
+	lith->page0 = ioremap_nocache(baseaddr + LI_PAGE0_OFFSET, PAGE_SIZE);
+	lith->page1 = ioremap_nocache(baseaddr + LI_PAGE1_OFFSET, PAGE_SIZE);
+	lith->page2 = ioremap_nocache(baseaddr + LI_PAGE2_OFFSET, PAGE_SIZE);
+	if (!lith->page0 || !lith->page1 || !lith->page2) {
+		li_destroy(lith);
+		return -ENOMEM;
+	}
+	return 0;
+}
+
+/*
+ * li_destroy destroys the lithium_t structure and vm mappings.
+ */
+
+static void li_destroy(lithium_t *lith)
+{
+	if (lith->page0) {
+		iounmap(lith->page0);
+		lith->page0 = NULL;
+	}
+	if (lith->page1) {
+		iounmap(lith->page1);
+		lith->page1 = NULL;
+	}
+	if (lith->page2) {
+		iounmap(lith->page2);
+		lith->page2 = NULL;
+	}
+}
+
+/*
+ * basic register accessors - read/write long/byte
+ */
+
+static __inline__ unsigned long li_readl(lithium_t *lith, int off)
+{
+	return * (volatile unsigned long *) (lith->page0 + off);
+}
+
+static __inline__ unsigned char li_readb(lithium_t *lith, int off)
+{
+	return * (volatile unsigned char *) (lith->page0 + off);
+}
+
+static __inline__ void li_writel(lithium_t *lith, int off, unsigned long val)
+{
+	* (volatile unsigned long *) (lith->page0 + off) = val;
+}
+
+static __inline__ void li_writeb(lithium_t *lith, int off, unsigned char val)
+{
+	* (volatile unsigned char *) (lith->page0 + off) = val;
+}
+
+/*****************************************************************************/
+/* High Level Lithium Access */
+
+/*
+ * Lithium DMA Notes
+ *
+ * Lithium has two dedicated DMA channels for audio.  They are known
+ * as comm1 and comm2 (communication areas 1 and 2).  Comm1 is for
+ * input, and comm2 is for output.  Each is controlled by three
+ * registers: BASE (base address), CFG (config) and CCTL
+ * (config/control).
+ *
+ * Each DMA channel points to a physically contiguous ring buffer in
+ * main memory of up to 8 Kbytes.  (This driver always uses 8 Kb.)
+ * There are three pointers into the ring buffer: read, write, and
+ * trigger.  The pointers are 8 bits each.  Each pointer points to
+ * 32-byte "chunks" of data.  The DMA engine moves 32 bytes at a time,
+ * so there is no finer-granularity control.
+ *
+ * In comm1, the hardware updates the write ptr, and software updates
+ * the read ptr.  In comm2, it's the opposite: hardware updates the
+ * read ptr, and software updates the write ptr.  I designate the
+ * hardware-updated ptr as the hwptr, and the software-updated ptr as
+ * the swptr.
+ *
+ * The trigger ptr and trigger mask are used to trigger interrupts.
+ * From the Lithium spec, section 5.6.8, revision of 12/15/1998:
+ *
+ *	Trigger Mask Value
+ *
+ *	A three bit wide field that represents a power of two mask
+ *	that is used whenever the trigger pointer is compared to its
+ *	respective read or write pointer.  A value of zero here
+ *	implies a mask of 0xFF and a value of seven implies a mask
+ *	0x01.  This value can be used to sub-divide the ring buffer
+ *	into pie sections so that interrupts monitor the progress of
+ *	hardware from section to section.
+ *
+ * My interpretation of that is, whenever the hw ptr is updated, it is
+ * compared with the trigger ptr, and the result is masked by the
+ * trigger mask.  (Actually, by the complement of the trigger mask.)
+ * If the result is zero, an interrupt is triggered.  I.e., interrupt
+ * if ((hwptr & ~mask) == (trptr & ~mask)).  The mask is formed from
+ * the trigger register value as mask = (1 << (8 - tmreg)) - 1.
+ *
+ * In yet different words, setting tmreg to 0 causes an interrupt after
+ * every 256 DMA chunks (8192 bytes) or once per traversal of the
+ * ring buffer.  Setting it to 7 caues an interrupt every 2 DMA chunks
+ * (64 bytes) or 128 times per traversal of the ring buffer.
+ */
+
+/* Lithium register offsets and bit definitions */
+
+#define LI_HOST_CONTROLLER	0x000
+# define LI_HC_RESET		 0x00008000
+# define LI_HC_LINK_ENABLE	 0x00004000
+# define LI_HC_LINK_FAILURE	 0x00000004
+# define LI_HC_LINK_CODEC	 0x00000002
+# define LI_HC_LINK_READY	 0x00000001
+
+#define LI_INTR_STATUS		0x010
+#define LI_INTR_MASK		0x014
+# define LI_INTR_LINK_ERR	 0x00008000
+# define LI_INTR_COMM2_TRIG	 0x00000008
+# define LI_INTR_COMM2_UNDERFLOW 0x00000004
+# define LI_INTR_COMM1_TRIG	 0x00000002
+# define LI_INTR_COMM1_OVERFLOW  0x00000001
+
+#define LI_CODEC_COMMAND	0x018
+# define LI_CC_BUSY		 0x00008000
+# define LI_CC_DIR		 0x00000080
+#  define LI_CC_DIR_RD		  LI_CC_DIR
+#  define LI_CC_DIR_WR		(!LI_CC_DIR)
+# define LI_CC_ADDR_MASK	 0x0000007F
+
+#define LI_CODEC_DATA		0x01C
+
+#define LI_COMM1_BASE		0x100
+#define LI_COMM1_CTL		0x104
+# define LI_CCTL_RESET		 0x80000000
+# define LI_CCTL_SIZE		 0x70000000
+# define LI_CCTL_DMA_ENABLE	 0x08000000
+# define LI_CCTL_TMASK		 0x07000000 /* trigger mask */
+# define LI_CCTL_TPTR		 0x00FF0000 /* trigger pointer */
+# define LI_CCTL_RPTR		 0x0000FF00
+# define LI_CCTL_WPTR		 0x000000FF
+#define LI_COMM1_CFG		0x108
+# define LI_CCFG_LOCK		 0x00008000
+# define LI_CCFG_SLOT		 0x00000070
+# define LI_CCFG_DIRECTION	 0x00000008
+#  define LI_CCFG_DIR_IN	(!LI_CCFG_DIRECTION)
+#  define LI_CCFG_DIR_OUT	  LI_CCFG_DIRECTION
+# define LI_CCFG_MODE		 0x00000004
+#  define LI_CCFG_MODE_MONO	(!LI_CCFG_MODE)
+#  define LI_CCFG_MODE_STEREO	  LI_CCFG_MODE
+# define LI_CCFG_FORMAT		 0x00000003
+#  define LI_CCFG_FMT_8BIT	  0x00000000
+#  define LI_CCFG_FMT_16BIT	  0x00000001
+#define LI_COMM2_BASE		0x10C
+#define LI_COMM2_CTL		0x110
+ /* bit definitions are the same as LI_COMM1_CTL */
+#define LI_COMM2_CFG		0x114
+ /* bit definitions are the same as LI_COMM1_CFG */
+
+#define LI_UST_LOW		0x200	/* 64-bit Unadjusted System Time is */
+#define LI_UST_HIGH		0x204	/* microseconds since boot */
+
+#define LI_AUDIO1_UST		0x300	/* UST-MSC pairs */
+#define LI_AUDIO1_MSC		0x304	/* MSC (Media Stream Counter) */
+#define LI_AUDIO2_UST		0x308	/* counts samples actually */
+#define LI_AUDIO2_MSC		0x30C	/* processed as of time UST */
+
+/* 
+ * Lithium's DMA engine operates on chunks of 32 bytes.  We call that
+ * a DMACHUNK.
+ */
+
+#define DMACHUNK_SHIFT 5
+#define DMACHUNK_SIZE (1 << DMACHUNK_SHIFT)
+#define BYTES_TO_CHUNKS(bytes) ((bytes) >> DMACHUNK_SHIFT)
+#define CHUNKS_TO_BYTES(chunks) ((chunks) << DMACHUNK_SHIFT)
+
+/*
+ * Two convenient macros to shift bitfields into/out of position.
+ *
+ * Observe that (mask & -mask) is (1 << low_set_bit_of(mask)).
+ * As long as mask is constant, we trust the compiler will change the
+ * multipy and divide into shifts.
+ */
+
+#define SHIFT_FIELD(val, mask) (((val) * ((mask) & -(mask))) & (mask))
+#define UNSHIFT_FIELD(val, mask) (((val) & (mask)) / ((mask) & -(mask)))
+
+/*
+ * dma_chan_desc is invariant information about a Lithium
+ * DMA channel.  There are two instances, li_comm1 and li_comm2.
+ *
+ * Note that the CCTL register fields are write ptr and read ptr, but what
+ * we care about are which pointer is updated by software and which by
+ * hardware.
+ */
+
+typedef struct dma_chan_desc {
+	int basereg;
+	int cfgreg;
+	int ctlreg;
+	int hwptrreg;
+	int swptrreg;
+	unsigned long swptrmask;
+	int ad1843_slot;
+	int direction;			/* LI_CCTL_DIR_IN/OUT */
+} dma_chan_desc_t;
+
+static const dma_chan_desc_t li_comm1 = {
+	LI_COMM1_BASE,			/* base register offset */
+	LI_COMM1_CFG,			/* config register offset */
+	LI_COMM1_CTL,			/* control register offset */
+	LI_COMM1_CTL + 0,		/* hw ptr reg offset (write ptr) */
+	LI_COMM1_CTL + 1,		/* sw ptr reg offset (read ptr) */
+	LI_CCTL_RPTR,			/* sw ptr bitmask in ctlval */
+	2,				/* ad1843 serial slot */
+	LI_CCFG_DIR_IN			/* direction */
+};
+
+static const dma_chan_desc_t li_comm2 = {
+	LI_COMM2_BASE,			/* base register offset */
+	LI_COMM2_CFG,			/* config register offset */
+	LI_COMM2_CTL,			/* control register offset */
+	LI_COMM2_CTL + 1,		/* hw ptr reg offset (read ptr) */
+	LI_COMM2_CTL + 0,		/* sw ptr reg offset (writr ptr) */
+	LI_CCTL_WPTR,			/* sw ptr bitmask in ctlval */
+	2,				/* ad1843 serial slot */
+	LI_CCFG_DIR_OUT			/* direction */
+};
+
+/*
+ * dma_chan is variable information about a Lithium DMA channel.
+ *
+ * The desc field points to invariant information.
+ * The lith field points to a lithium_t which is passed
+ * to li_read* and li_write* to access the registers.
+ * The *val fields shadow the lithium registers' contents.
+ */
+
+typedef struct dma_chan {
+	const dma_chan_desc_t *desc;
+	lithium_t      *lith;
+	unsigned long   baseval;
+	unsigned long	cfgval;
+	unsigned long	ctlval;
+} dma_chan_t;
+
+/*
+ * li_ad1843_wait waits until lithium says the AD1843 register
+ * exchange is not busy.  Returns 0 on success, -EBUSY on timeout.
+ *
+ * Locking: must be called with lithium_lock held.
+ */
+
+static int li_ad1843_wait(lithium_t *lith)
+{
+	unsigned long later = jiffies + 2;
+	while (li_readl(lith, LI_CODEC_COMMAND) & LI_CC_BUSY)
+		if (jiffies >= later)
+			return -EBUSY;
+	return 0;
+}
+
+/*
+ * li_read_ad1843_reg returns the current contents of a 16 bit AD1843 register.
+ *
+ * Returns unsigned register value on success, -errno on failure.
+ */
+
+static int li_read_ad1843_reg(lithium_t *lith, int reg)
+{
+	int val;
+
+	ASSERT(!in_interrupt());
+	spin_lock(&lith->lock);
+	{
+		val = li_ad1843_wait(lith);
+		if (val == 0) {
+			li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_RD | reg);
+			val = li_ad1843_wait(lith);
+		}
+		if (val == 0)
+			val = li_readl(lith, LI_CODEC_DATA);
+	}
+	spin_unlock(&lith->lock);
+
+	DBGXV("li_read_ad1843_reg(lith=0x%p, reg=%d) returns 0x%04x\n",
+	      lith, reg, val);
+
+	return val;
+}
+
+/*
+ * li_write_ad1843_reg writes the specified value to a 16 bit AD1843 register.
+ */
+
+static void li_write_ad1843_reg(lithium_t *lith, int reg, int newval)
+{
+	spin_lock(&lith->lock);
+	{
+		if (li_ad1843_wait(lith) == 0) {
+			li_writel(lith, LI_CODEC_DATA, newval);
+			li_writel(lith, LI_CODEC_COMMAND, LI_CC_DIR_WR | reg);
+		}
+	}
+	spin_unlock(&lith->lock);
+}
+
+/*
+ * li_setup_dma calculates all the register settings for DMA in a particular
+ * mode.  It takes too many arguments.
+ */
+
+static void li_setup_dma(dma_chan_t *chan,
+			 const dma_chan_desc_t *desc,
+			 lithium_t *lith,
+			 unsigned long buffer_paddr,
+			 int bufshift,
+			 int fragshift,
+			 int channels,
+			 int sampsize)
+{
+	unsigned long mode, format;
+	unsigned long size, tmask;
+
+	DBGEV("(chan=0x%p, desc=0x%p, lith=0x%p, buffer_paddr=0x%lx, "
+	     "bufshift=%d, fragshift=%d, channels=%d, sampsize=%d)\n",
+	     chan, desc, lith, buffer_paddr,
+	     bufshift, fragshift, channels, sampsize);
+
+	/* Reset the channel first. */
+
+	li_writel(lith, desc->ctlreg, LI_CCTL_RESET);
+
+	ASSERT(channels == 1 || channels == 2);
+	if (channels == 2)
+		mode = LI_CCFG_MODE_STEREO;
+	else
+		mode = LI_CCFG_MODE_MONO;
+	ASSERT(sampsize == 1 || sampsize == 2);
+	if (sampsize == 2)
+		format = LI_CCFG_FMT_16BIT;
+	else
+		format = LI_CCFG_FMT_8BIT;
+	chan->desc = desc;
+	chan->lith = lith;
+
+	/*
+	 * Lithium DMA address register takes a 40-bit physical
+	 * address, right-shifted by 8 so it fits in 32 bits.  Bit 37
+	 * must be set -- it enables cache coherence.
+	 */
+
+	ASSERT(!(buffer_paddr & 0xFF));
+	chan->baseval = (buffer_paddr >> 8) | 1 << (37 - 8);
+
+	chan->cfgval = (!LI_CCFG_LOCK |
+			SHIFT_FIELD(desc->ad1843_slot, LI_CCFG_SLOT) |
+			desc->direction |
+			mode |
+			format);
+
+	size = bufshift - 6;
+	tmask = 13 - fragshift;		/* See Lithium DMA Notes above. */
+	ASSERT(size >= 2 && size <= 7);
+	ASSERT(tmask >= 1 && tmask <= 7);
+	chan->ctlval = (!LI_CCTL_RESET |
+			SHIFT_FIELD(size, LI_CCTL_SIZE) |
+			!LI_CCTL_DMA_ENABLE |
+			SHIFT_FIELD(tmask, LI_CCTL_TMASK) |
+			SHIFT_FIELD(0, LI_CCTL_TPTR));
+
+	DBGPV("basereg 0x%x = 0x%lx\n", desc->basereg, chan->baseval);
+	DBGPV("cfgreg 0x%x = 0x%lx\n", desc->cfgreg, chan->cfgval);
+	DBGPV("ctlreg 0x%x = 0x%lx\n", desc->ctlreg, chan->ctlval);
+
+	li_writel(lith, desc->basereg, chan->baseval);
+	li_writel(lith, desc->cfgreg, chan->cfgval);
+	li_writel(lith, desc->ctlreg, chan->ctlval);
+
+	DBGRV();
+}
+
+static void li_shutdown_dma(dma_chan_t *chan)
+{
+	lithium_t *lith = chan->lith;
+	caddr_t lith1 = lith->page1;
+
+	DBGEV("(chan=0x%p)\n", chan);
+	
+	chan->ctlval &= ~LI_CCTL_DMA_ENABLE;
+	DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval);
+	li_writel(lith, chan->desc->ctlreg, chan->ctlval);
+
+	/*
+	 * Offset 0x500 on Lithium page 1 is an undocumented,
+	 * unsupported register that holds the zero sample value.
+	 * Lithium is supposed to output zero samples when DMA is
+	 * inactive, and repeat the last sample when DMA underflows.
+	 * But it has a bug, where, after underflow occurs, the zero
+	 * sample is not reset.
+	 *
+	 * I expect this to break in a future rev of Lithium.
+	 */
+
+	if (lith1 && chan->desc->direction == LI_CCFG_DIR_OUT)
+		* (volatile unsigned long *) (lith1 + 0x500) = 0;
+}
+
+/*
+ * li_activate_dma always starts dma at the beginning of the buffer.
+ *
+ * N.B., these may be called from interrupt.
+ */
+
+static __inline__ void li_activate_dma(dma_chan_t *chan)
+{
+	chan->ctlval |= LI_CCTL_DMA_ENABLE;
+	DBGPV("ctlval = 0x%lx\n", chan->ctlval);
+	li_writel(chan->lith, chan->desc->ctlreg, chan->ctlval);
+}
+
+static void li_deactivate_dma(dma_chan_t *chan)
+{
+	lithium_t *lith = chan->lith;
+	caddr_t lith2 = lith->page2;
+
+	chan->ctlval &= ~(LI_CCTL_DMA_ENABLE | LI_CCTL_RPTR | LI_CCTL_WPTR);
+	DBGPV("ctlval = 0x%lx\n", chan->ctlval);
+	DBGPV("ctlreg 0x%x = 0x%lx\n", chan->desc->ctlreg, chan->ctlval);
+	li_writel(lith, chan->desc->ctlreg, chan->ctlval);
+
+	/*
+	 * Offsets 0x98 and 0x9C on Lithium page 2 are undocumented,
+	 * unsupported registers that are internal copies of the DMA
+	 * read and write pointers.  Because of a Lithium bug, these
+	 * registers aren't zeroed correctly when DMA is shut off.  So
+	 * we whack them directly.
+	 *
+	 * I expect this to break in a future rev of Lithium.
+	 */
+
+	if (lith2 && chan->desc->direction == LI_CCFG_DIR_OUT) {
+		* (volatile unsigned long *) (lith2 + 0x98) = 0;
+		* (volatile unsigned long *) (lith2 + 0x9C) = 0;
+	}
+}
+
+/*
+ * read/write the ring buffer pointers.  These routines' arguments and results
+ * are byte offsets from the beginning of the ring buffer.
+ */
+
+static __inline__ int li_read_swptr(dma_chan_t *chan)
+{
+	const unsigned long mask = chan->desc->swptrmask;
+
+	return CHUNKS_TO_BYTES(UNSHIFT_FIELD(chan->ctlval, mask));
+}
+
+static __inline__ int li_read_hwptr(dma_chan_t *chan)
+{
+	return CHUNKS_TO_BYTES(li_readb(chan->lith, chan->desc->hwptrreg));
+}
+
+static __inline__ void li_write_swptr(dma_chan_t *chan, int val)
+{
+	const unsigned long mask = chan->desc->swptrmask;
+
+	ASSERT(!(val & ~CHUNKS_TO_BYTES(0xFF)));
+	val = BYTES_TO_CHUNKS(val);
+	chan->ctlval = (chan->ctlval & ~mask) | SHIFT_FIELD(val, mask);
+	li_writeb(chan->lith, chan->desc->swptrreg, val);
+}
+
+static void li_enable_interrupts(lithium_t *lith, unsigned int mask)
+{
+	DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask);
+
+	/* clear any already-pending interrupts. */
+
+	li_writel(lith, LI_INTR_STATUS, mask);
+
+	/* enable the interrupts. */
+
+	mask |= li_readl(lith, LI_INTR_MASK);
+	li_writel(lith, LI_INTR_MASK, mask);
+}
+
+static void li_disable_interrupts(lithium_t *lith, unsigned int mask)
+{
+	unsigned int keepmask;
+
+	DBGEV("(lith=0x%p, mask=0x%x)\n", lith, mask);
+
+	/* disable the interrupts */
+
+	keepmask = li_readl(lith, LI_INTR_MASK) & ~mask;
+	li_writel(lith, LI_INTR_MASK, keepmask);
+
+	/* clear any pending interrupts. */
+
+	li_writel(lith, LI_INTR_STATUS, mask);
+}
+
+/* Get the interrupt status and clear all pending interrupts. */
+
+static unsigned int li_get_clear_intr_status(lithium_t *lith)
+{
+	unsigned int status;
+
+	status = li_readl(lith, LI_INTR_STATUS);
+	li_writel(lith, LI_INTR_STATUS, ~0);
+	return status & li_readl(lith, LI_INTR_MASK);
+}
+
+static int li_init(lithium_t *lith)
+{
+	/* 1. System power supplies stabilize. */
+
+	/* 2. Assert the ~RESET signal. */
+
+	li_writel(lith, LI_HOST_CONTROLLER, LI_HC_RESET);
+	udelay(1);
+
+	/* 3. Deassert the ~RESET signal and enter a wait period to allow
+	   the AD1843 internal clocks and the external crystal oscillator
+	   to stabilize. */
+
+	li_writel(lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
+	udelay(1);
+
+	return 0;
+}
+
+/*****************************************************************************/
+/* AD1843 access */
+
+/*
+ * AD1843 bitfield definitions.  All are named as in the AD1843 data
+ * sheet, with ad1843_ prepended and individual bit numbers removed.
+ *
+ * E.g., bits LSS0 through LSS2 become ad1843_LSS.
+ *
+ * Only the bitfields we need are defined.
+ */
+
+typedef struct ad1843_bitfield {
+	char reg;
+	char lo_bit;
+	char nbits;
+} ad1843_bitfield_t;
+
+static const ad1843_bitfield_t
+	ad1843_PDNO   = {  0, 14,  1 },	/* Converter Power-Down Flag */
+	ad1843_INIT   = {  0, 15,  1 },	/* Clock Initialization Flag */
+	ad1843_RIG    = {  2,  0,  4 },	/* Right ADC Input Gain */
+	ad1843_RMGE   = {  2,  4,  1 },	/* Right ADC Mic Gain Enable */
+	ad1843_RSS    = {  2,  5,  3 },	/* Right ADC Source Select */
+	ad1843_LIG    = {  2,  8,  4 },	/* Left ADC Input Gain */
+	ad1843_LMGE   = {  2, 12,  1 },	/* Left ADC Mic Gain Enable */
+	ad1843_LSS    = {  2, 13,  3 },	/* Left ADC Source Select */
+	ad1843_RX1M   = {  4,  0,  5 },	/* Right Aux 1 Mix Gain/Atten */
+	ad1843_RX1MM  = {  4,  7,  1 },	/* Right Aux 1 Mix Mute */
+	ad1843_LX1M   = {  4,  8,  5 },	/* Left Aux 1 Mix Gain/Atten */
+	ad1843_LX1MM  = {  4, 15,  1 },	/* Left Aux 1 Mix Mute */
+	ad1843_RX2M   = {  5,  0,  5 },	/* Right Aux 2 Mix Gain/Atten */
+	ad1843_RX2MM  = {  5,  7,  1 },	/* Right Aux 2 Mix Mute */
+	ad1843_LX2M   = {  5,  8,  5 },	/* Left Aux 2 Mix Gain/Atten */
+	ad1843_LX2MM  = {  5, 15,  1 },	/* Left Aux 2 Mix Mute */
+	ad1843_RMCM   = {  7,  0,  5 },	/* Right Mic Mix Gain/Atten */
+	ad1843_RMCMM  = {  7,  7,  1 },	/* Right Mic Mix Mute */
+	ad1843_LMCM   = {  7,  8,  5 },	/* Left Mic Mix Gain/Atten */
+	ad1843_LMCMM  = {  7, 15,  1 },	/* Left Mic Mix Mute */
+	ad1843_HPOS   = {  8,  4,  1 },	/* Headphone Output Voltage Swing */
+	ad1843_HPOM   = {  8,  5,  1 },	/* Headphone Output Mute */
+	ad1843_RDA1G  = {  9,  0,  6 },	/* Right DAC1 Analog/Digital Gain */
+	ad1843_RDA1GM = {  9,  7,  1 },	/* Right DAC1 Analog Mute */
+	ad1843_LDA1G  = {  9,  8,  6 },	/* Left DAC1 Analog/Digital Gain */
+	ad1843_LDA1GM = {  9, 15,  1 },	/* Left DAC1 Analog Mute */
+	ad1843_RDA1AM = { 11,  7,  1 },	/* Right DAC1 Digital Mute */
+	ad1843_LDA1AM = { 11, 15,  1 },	/* Left DAC1 Digital Mute */
+	ad1843_ADLC   = { 15,  0,  2 },	/* ADC Left Sample Rate Source */
+	ad1843_ADRC   = { 15,  2,  2 },	/* ADC Right Sample Rate Source */
+	ad1843_DA1C   = { 15,  8,  2 },	/* DAC1 Sample Rate Source */
+	ad1843_C1C    = { 17,  0, 16 },	/* Clock 1 Sample Rate Select */
+	ad1843_C2C    = { 20,  0, 16 },	/* Clock 1 Sample Rate Select */
+	ad1843_DAADL  = { 25,  4,  2 },	/* Digital ADC Left Source Select */
+	ad1843_DAADR  = { 25,  6,  2 },	/* Digital ADC Right Source Select */
+	ad1843_DRSFLT = { 25, 15,  1 },	/* Digital Reampler Filter Mode */
+	ad1843_ADLF   = { 26,  0,  2 }, /* ADC Left Channel Data Format */
+	ad1843_ADRF   = { 26,  2,  2 }, /* ADC Right Channel Data Format */
+	ad1843_ADTLK  = { 26,  4,  1 },	/* ADC Transmit Lock Mode Select */
+	ad1843_SCF    = { 26,  7,  1 },	/* SCLK Frequency Select */
+	ad1843_DA1F   = { 26,  8,  2 },	/* DAC1 Data Format Select */
+	ad1843_DA1SM  = { 26, 14,  1 },	/* DAC1 Stereo/Mono Mode Select */
+	ad1843_ADLEN  = { 27,  0,  1 },	/* ADC Left Channel Enable */
+	ad1843_ADREN  = { 27,  1,  1 },	/* ADC Right Channel Enable */
+	ad1843_AAMEN  = { 27,  4,  1 },	/* Analog to Analog Mix Enable */
+	ad1843_ANAEN  = { 27,  7,  1 },	/* Analog Channel Enable */
+	ad1843_DA1EN  = { 27,  8,  1 },	/* DAC1 Enable */
+	ad1843_DA2EN  = { 27,  9,  1 },	/* DAC2 Enable */
+	ad1843_C1EN   = { 28, 11,  1 },	/* Clock Generator 1 Enable */
+	ad1843_C2EN   = { 28, 12,  1 },	/* Clock Generator 2 Enable */
+	ad1843_PDNI   = { 28, 15,  1 };	/* Converter Power Down */
+
+/*
+ * The various registers of the AD1843 use three different formats for
+ * specifying gain.  The ad1843_gain structure parameterizes the
+ * formats.
+ */
+
+typedef struct ad1843_gain {
+
+	int	negative;		/* nonzero if gain is negative. */
+	const ad1843_bitfield_t *lfield;
+	const ad1843_bitfield_t *rfield;
+
+} ad1843_gain_t;
+
+static const ad1843_gain_t ad1843_gain_RECLEV
+				= { 0, &ad1843_LIG,   &ad1843_RIG };
+static const ad1843_gain_t ad1843_gain_LINE
+				= { 1, &ad1843_LX1M,  &ad1843_RX1M };
+static const ad1843_gain_t ad1843_gain_CD
+				= { 1, &ad1843_LX2M,  &ad1843_RX2M };
+static const ad1843_gain_t ad1843_gain_MIC
+				= { 1, &ad1843_LMCM,  &ad1843_RMCM };
+static const ad1843_gain_t ad1843_gain_PCM
+				= { 1, &ad1843_LDA1G, &ad1843_RDA1G };
+
+/* read the current value of an AD1843 bitfield. */
+
+static int ad1843_read_bits(lithium_t *lith, const ad1843_bitfield_t *field)
+{
+	int w = li_read_ad1843_reg(lith, field->reg);
+	int val = w >> field->lo_bit & ((1 << field->nbits) - 1);
+
+	DBGXV("ad1843_read_bits(lith=0x%p, field->{%d %d %d}) returns 0x%x\n",
+	      lith, field->reg, field->lo_bit, field->nbits, val);
+
+	return val;
+}
+
+/*
+ * write a new value to an AD1843 bitfield and return the old value.
+ */
+
+static int ad1843_write_bits(lithium_t *lith,
+			     const ad1843_bitfield_t *field,
+			     int newval)
+{
+	int w = li_read_ad1843_reg(lith, field->reg);
+	int mask = ((1 << field->nbits) - 1) << field->lo_bit;
+	int oldval = (w & mask) >> field->lo_bit;
+	int newbits = (newval << field->lo_bit) & mask;
+	w = (w & ~mask) | newbits;
+	(void) li_write_ad1843_reg(lith, field->reg, w);
+
+	DBGXV("ad1843_write_bits(lith=0x%p, field->{%d %d %d}, val=0x%x) "
+	      "returns 0x%x\n",
+	      lith, field->reg, field->lo_bit, field->nbits, newval,
+	      oldval);
+
+	return oldval;
+}
+
+/*
+ * ad1843_read_multi reads multiple bitfields from the same AD1843
+ * register.  It uses a single read cycle to do it.  (Reading the
+ * ad1843 requires 256 bit times at 12.288 MHz, or nearly 20
+ * microseconds.)
+ *
+ * Called ike this.
+ *
+ *  ad1843_read_multi(lith, nfields,
+ *		      &ad1843_FIELD1, &val1,
+ *		      &ad1843_FIELD2, &val2, ...);
+ */
+
+static void ad1843_read_multi(lithium_t *lith, int argcount, ...)
+{
+	va_list ap;
+	const ad1843_bitfield_t *fp;
+	int w = 0, mask, *value, reg = -1;
+
+	va_start(ap, argcount);
+	while (--argcount >= 0) {
+		fp = va_arg(ap, const ad1843_bitfield_t *);
+		value = va_arg(ap, int *);
+		if (reg == -1) {
+			reg = fp->reg;
+			w = li_read_ad1843_reg(lith, reg);
+		}
+		ASSERT(reg == fp->reg);
+		mask = (1 << fp->nbits) - 1;
+		*value = w >> fp->lo_bit & mask;
+	}
+	va_end(ap);
+}
+
+/*
+ * ad1843_write_multi stores multiple bitfields into the same AD1843
+ * register.  It uses one read and one write cycle to do it.
+ *
+ * Called like this.
+ *
+ *  ad1843_write_multi(lith, nfields,
+ *		       &ad1843_FIELD1, val1,
+ *		       &ad1843_FIELF2, val2, ...);
+ */
+
+static void ad1843_write_multi(lithium_t *lith, int argcount, ...)
+{
+	va_list ap;
+	int reg;
+	const ad1843_bitfield_t *fp;
+	int value;
+	int w, m, mask, bits;
+
+	mask = 0;
+	bits = 0;
+	reg = -1;
+
+	va_start(ap, argcount);
+	while (--argcount >= 0) {
+		fp = va_arg(ap, const ad1843_bitfield_t *);
+		value = va_arg(ap, int);
+		if (reg == -1)
+			reg = fp->reg;
+		ASSERT(fp->reg == reg);
+		m = ((1 << fp->nbits) - 1) << fp->lo_bit;
+		mask |= m;
+		bits |= (value << fp->lo_bit) & m;
+	}
+	va_end(ap);
+	ASSERT(!(bits & ~mask));
+	if (~mask & 0xFFFF)
+		w = li_read_ad1843_reg(lith, reg);
+	else
+		w = 0;
+	w = (w & ~mask) | bits;
+	(void) li_write_ad1843_reg(lith, reg, w);
+}
+
+/*
+ * ad1843_get_gain reads the specified register and extracts the gain value
+ * using the supplied gain type.  It returns the gain in OSS format.
+ */
+
+static int ad1843_get_gain(lithium_t *lith, const ad1843_gain_t *gp)
+{
+	int lg, rg;
+	unsigned short mask = (1 << gp->lfield->nbits) - 1;
+
+	ad1843_read_multi(lith, 2, gp->lfield, &lg, gp->rfield, &rg);
+	if (gp->negative) {
+		lg = mask - lg;
+		rg = mask - rg;
+	}
+	lg = (lg * 100 + (mask >> 1)) / mask;
+	rg = (rg * 100 + (mask >> 1)) / mask;
+	return lg << 0 | rg << 8;
+}
+
+/*
+ * Set an audio channel's gain. Converts from OSS format to AD1843's
+ * format.
+ *
+ * Returns the new gain, which may be lower than the old gain.
+ */
+
+static int ad1843_set_gain(lithium_t *lith,
+			   const ad1843_gain_t *gp,
+			   int newval)
+{
+	unsigned short mask = (1 << gp->lfield->nbits) - 1;
+
+	int lg = newval >> 0 & 0xFF;
+	int rg = newval >> 8;
+	if (lg < 0 || lg > 100 || rg < 0 || rg > 100)
+		return -EINVAL;
+	lg = (lg * mask + (mask >> 1)) / 100;
+	rg = (rg * mask + (mask >> 1)) / 100;
+	if (gp->negative) {
+		lg = mask - lg;
+		rg = mask - rg;
+	}
+	ad1843_write_multi(lith, 2, gp->lfield, lg, gp->rfield, rg);
+	return ad1843_get_gain(lith, gp);
+}
+
+/* Returns the current recording source, in OSS format. */
+
+static int ad1843_get_recsrc(lithium_t *lith)
+{
+	int ls = ad1843_read_bits(lith, &ad1843_LSS);
+
+	switch (ls) {
+	case 1:
+		return SOUND_MASK_MIC;
+	case 2:
+		return SOUND_MASK_LINE;
+	case 3:
+		return SOUND_MASK_CD;
+	case 6:
+		return SOUND_MASK_PCM;
+	default:
+		ASSERT(0);
+		return -1;
+	}
+}
+
+/*
+ * Enable/disable digital resample mode in the AD1843.
+ *
+ * The AD1843 requires that ADL, ADR, DA1 and DA2 be powered down
+ * while switching modes.  So we save DA1's state (DA2's state is not
+ * interesting), power them down, switch into/out of resample mode,
+ * power them up, and restore state.
+ *
+ * This will cause audible glitches if D/A or A/D is going on, so the
+ * driver disallows that (in mixer_write_ioctl()).
+ *
+ * The open question is, is this worth doing?  I'm leaving it in,
+ * because it's written, but...
+ */
+
+static void ad1843_set_resample_mode(lithium_t *lith, int onoff)
+{
+	/* Save DA1 mute and gain (addr 9 is DA1 analog gain/attenuation) */
+	int save_da1 = li_read_ad1843_reg(lith, 9);
+
+	/* Power down A/D and D/A. */
+	ad1843_write_multi(lith, 4,
+			   &ad1843_DA1EN, 0,
+			   &ad1843_DA2EN, 0,
+			   &ad1843_ADLEN, 0,
+			   &ad1843_ADREN, 0);
+
+	/* Switch mode */
+	ASSERT(onoff == 0 || onoff == 1);
+	ad1843_write_bits(lith, &ad1843_DRSFLT, onoff);
+
+ 	/* Power up A/D and D/A. */
+	ad1843_write_multi(lith, 3,
+			   &ad1843_DA1EN, 1,
+			   &ad1843_ADLEN, 1,
+			   &ad1843_ADREN, 1);
+
+	/* Restore DA1 mute and gain. */
+	li_write_ad1843_reg(lith, 9, save_da1);
+}
+
+/*
+ * Set recording source.  Arg newsrc specifies an OSS channel mask.
+ *
+ * The complication is that when we switch into/out of loopback mode
+ * (i.e., src = SOUND_MASK_PCM), we change the AD1843 into/out of
+ * digital resampling mode.
+ *
+ * Returns newsrc on success, -errno on failure.
+ */
+
+static int ad1843_set_recsrc(lithium_t *lith, int newsrc)
+{
+	int bits;
+	int oldbits;
+
+	switch (newsrc) {
+	case SOUND_MASK_PCM:
+		bits = 6;
+		break;
+
+	case SOUND_MASK_MIC:
+		bits = 1;
+		break;
+
+	case SOUND_MASK_LINE:
+		bits = 2;
+		break;
+
+	case SOUND_MASK_CD:
+		bits = 3;
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	oldbits = ad1843_read_bits(lith, &ad1843_LSS);
+	if (newsrc == SOUND_MASK_PCM && oldbits != 6) {
+		DBGP("enabling digital resample mode\n");
+		ad1843_set_resample_mode(lith, 1);
+		ad1843_write_multi(lith, 2,
+				   &ad1843_DAADL, 2,
+				   &ad1843_DAADR, 2);
+	} else if (newsrc != SOUND_MASK_PCM && oldbits == 6) {
+		DBGP("disabling digital resample mode\n");
+		ad1843_set_resample_mode(lith, 0);
+		ad1843_write_multi(lith, 2,
+				   &ad1843_DAADL, 0,
+				   &ad1843_DAADR, 0);
+	}
+	ad1843_write_multi(lith, 2, &ad1843_LSS, bits, &ad1843_RSS, bits);
+	return newsrc;
+}
+
+/*
+ * Return current output sources, in OSS format.
+ */
+
+static int ad1843_get_outsrc(lithium_t *lith)
+{
+	int pcm, line, mic, cd;
+
+	pcm  = ad1843_read_bits(lith, &ad1843_LDA1GM) ? 0 : SOUND_MASK_PCM;
+	line = ad1843_read_bits(lith, &ad1843_LX1MM)  ? 0 : SOUND_MASK_LINE;
+	cd   = ad1843_read_bits(lith, &ad1843_LX2MM)  ? 0 : SOUND_MASK_CD;
+	mic  = ad1843_read_bits(lith, &ad1843_LMCMM)  ? 0 : SOUND_MASK_MIC;
+
+	return pcm | line | cd | mic;
+}
+
+/*
+ * Set output sources.  Arg is a mask of active sources in OSS format.
+ *
+ * Returns source mask on success, -errno on failure.
+ */
+
+static int ad1843_set_outsrc(lithium_t *lith, int mask)
+{
+	int pcm, line, mic, cd;
+
+	if (mask & ~(SOUND_MASK_PCM | SOUND_MASK_LINE |
+		     SOUND_MASK_CD | SOUND_MASK_MIC))
+		return -EINVAL;
+	pcm  = (mask & SOUND_MASK_PCM)  ? 0 : 1;
+	line = (mask & SOUND_MASK_LINE) ? 0 : 1;
+	mic  = (mask & SOUND_MASK_MIC)  ? 0 : 1;
+	cd   = (mask & SOUND_MASK_CD)   ? 0 : 1;
+
+	ad1843_write_multi(lith, 2, &ad1843_LDA1GM, pcm, &ad1843_RDA1GM, pcm);
+	ad1843_write_multi(lith, 2, &ad1843_LX1MM, line, &ad1843_RX1MM, line);
+	ad1843_write_multi(lith, 2, &ad1843_LX2MM, cd,   &ad1843_RX2MM, cd);
+	ad1843_write_multi(lith, 2, &ad1843_LMCMM, mic,  &ad1843_RMCMM, mic);
+
+	return mask;
+}
+
+/* Setup ad1843 for D/A conversion. */
+
+static void ad1843_setup_dac(lithium_t *lith,
+			     int framerate,
+			     int fmt,
+			     int channels)
+{
+	int ad_fmt = 0, ad_mode = 0;
+
+	DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n",
+	      lith, framerate, fmt, channels);
+
+	switch (fmt) {
+	case AFMT_S8:		ad_fmt = 1; break;
+	case AFMT_U8:		ad_fmt = 1; break;
+	case AFMT_S16_LE:	ad_fmt = 1; break;
+	case AFMT_MU_LAW:	ad_fmt = 2; break;
+	case AFMT_A_LAW:	ad_fmt = 3; break;
+	default:		ASSERT(0);
+	}
+
+	switch (channels) {
+	case 2:			ad_mode = 0; break;
+	case 1:			ad_mode = 1; break;
+	default:		ASSERT(0);
+	}
+		
+	DBGPV("ad_mode = %d, ad_fmt = %d\n", ad_mode, ad_fmt);
+	ASSERT(framerate >= 4000 && framerate <= 49000);
+	ad1843_write_bits(lith, &ad1843_C1C, framerate);
+	ad1843_write_multi(lith, 2,
+			   &ad1843_DA1SM, ad_mode, &ad1843_DA1F, ad_fmt);
+}
+
+static void ad1843_shutdown_dac(lithium_t *lith)
+{
+	ad1843_write_bits(lith, &ad1843_DA1F, 1);
+}
+
+static void ad1843_setup_adc(lithium_t *lith, int framerate, int fmt, int channels)
+{
+	int da_fmt = 0;
+
+	DBGEV("(lith=0x%p, framerate=%d, fmt=%d, channels=%d)\n",
+	      lith, framerate, fmt, channels);
+
+	switch (fmt) {
+	case AFMT_S8:		da_fmt = 1; break;
+	case AFMT_U8:		da_fmt = 1; break;
+	case AFMT_S16_LE:	da_fmt = 1; break;
+	case AFMT_MU_LAW:	da_fmt = 2; break;
+	case AFMT_A_LAW:	da_fmt = 3; break;
+	default:		ASSERT(0);
+	}
+
+	DBGPV("da_fmt = %d\n", da_fmt);
+	ASSERT(framerate >= 4000 && framerate <= 49000);
+	ad1843_write_bits(lith, &ad1843_C2C, framerate);
+	ad1843_write_multi(lith, 2,
+			   &ad1843_ADLF, da_fmt, &ad1843_ADRF, da_fmt);
+}
+
+static void ad1843_shutdown_adc(lithium_t *lith)
+{
+	/* nothing to do */
+}
+
+/*
+ * Fully initialize the ad1843.  As described in the AD1843 data
+ * sheet, section "START-UP SEQUENCE".  The numbered comments are
+ * subsection headings from the data sheet.  See the data sheet, pages
+ * 52-54, for more info.
+ *
+ * return 0 on success, -errno on failure.  */
+
+static int ad1843_init(lithium_t *lith)
+{
+	unsigned long later;
+	int err;
+
+	err = li_init(lith);
+	if (err)
+		return err;
+
+	if (ad1843_read_bits(lith, &ad1843_INIT) != 0) {
+		printk(KERN_ERR "vwsnd sound: AD1843 won't initialize\n");
+		return -EIO;
+	}
+
+	ad1843_write_bits(lith, &ad1843_SCF, 1);
+
+	/* 4. Put the conversion resources into standby. */
+
+	ad1843_write_bits(lith, &ad1843_PDNI, 0);
+	later = jiffies + HZ / 2;	/* roughly half a second */
+	DBGDO(shut_up++);
+	while (ad1843_read_bits(lith, &ad1843_PDNO)) {
+		if (jiffies > later) {
+			printk(KERN_ERR
+			       "vwsnd audio: AD1843 won't power up\n");
+			return -EIO;
+		}
+		schedule();
+	}
+	DBGDO(shut_up--);
+
+	/* 5. Power up the clock generators and enable clock output pins. */
+
+	ad1843_write_multi(lith, 2, &ad1843_C1EN, 1, &ad1843_C2EN, 1);
+
+	/* 6. Configure conversion resources while they are in standby. */
+
+ 	/* DAC1 uses clock 1 as source, ADC uses clock 2.  Always. */
+
+	ad1843_write_multi(lith, 3,
+			   &ad1843_DA1C, 1,
+			   &ad1843_ADLC, 2,
+			   &ad1843_ADRC, 2);
+
+	/* 7. Enable conversion resources. */
+
+	ad1843_write_bits(lith, &ad1843_ADTLK, 1);
+	ad1843_write_multi(lith, 5,
+			   &ad1843_ANAEN, 1,
+			   &ad1843_AAMEN, 1,
+			   &ad1843_DA1EN, 1,
+			   &ad1843_ADLEN, 1,
+			   &ad1843_ADREN, 1);
+
+	/* 8. Configure conversion resources while they are enabled. */
+
+	ad1843_write_bits(lith, &ad1843_DA1C, 1);
+
+	/* Unmute all channels. */
+
+	ad1843_set_outsrc(lith,
+			  (SOUND_MASK_PCM | SOUND_MASK_LINE |
+			   SOUND_MASK_MIC | SOUND_MASK_CD));
+	ad1843_write_multi(lith, 2, &ad1843_LDA1AM, 0, &ad1843_RDA1AM, 0);
+
+	/* Set default recording source to Line In and set
+	 * mic gain to +20 dB.
+	 */
+
+	ad1843_set_recsrc(lith, SOUND_MASK_LINE);
+	ad1843_write_multi(lith, 2, &ad1843_LMGE, 1, &ad1843_RMGE, 1);
+
+	/* Set Speaker Out level to +/- 4V and unmute it. */
+
+	ad1843_write_multi(lith, 2, &ad1843_HPOS, 1, &ad1843_HPOM, 0);
+
+	return 0;
+}
+
+/*****************************************************************************/
+/* PCM I/O */
+
+#define READ_INTR_MASK  (LI_INTR_COMM1_TRIG | LI_INTR_COMM1_OVERFLOW)
+#define WRITE_INTR_MASK (LI_INTR_COMM2_TRIG | LI_INTR_COMM2_UNDERFLOW)
+
+typedef enum vwsnd_port_swstate {	/* software state */
+	SW_OFF,
+	SW_INITIAL,
+	SW_RUN,
+	SW_DRAIN,
+} vwsnd_port_swstate_t;
+
+typedef enum vwsnd_port_hwstate {	/* hardware state */
+	HW_STOPPED,
+	HW_RUNNING,
+} vwsnd_port_hwstate_t;
+
+/*
+ * These flags are read by ISR, but only written at baseline.
+ */
+
+typedef enum vwsnd_port_flags {
+	DISABLED = 1 << 0,
+	ERFLOWN  = 1 << 1,		/* overflown or underflown */
+	HW_BUSY  = 1 << 2,
+} vwsnd_port_flags_t;
+
+/*
+ * vwsnd_port is the per-port data structure.  Each device has two
+ * ports, one for input and one for output.
+ *
+ * Locking:
+ *
+ *	port->lock protects: hwstate, flags, swb_[iu]_avail.
+ *
+ *	devc->io_sema protects: swstate, sw_*, swb_[iu]_idx.
+ *
+ *	everything else is only written by open/release or
+ *	pcm_{setup,shutdown}(), which are serialized by a
+ *	combination of devc->open_sema and devc->io_sema.
+ */
+
+typedef struct vwsnd_port {
+
+	spinlock_t	lock;
+	struct wait_queue *queue;
+	vwsnd_port_swstate_t swstate;
+	vwsnd_port_hwstate_t hwstate;
+	vwsnd_port_flags_t flags;
+
+	int		sw_channels;
+	int		sw_samplefmt;
+	int		sw_framerate;
+	int		sample_size;
+	int		frame_size;
+	unsigned int	zero_word;	/* zero for the sample format */
+
+	int		sw_fragshift;
+	int		sw_fragcount;
+	int		sw_subdivshift;
+
+	unsigned int	hw_fragshift;
+	unsigned int	hw_fragsize;
+	unsigned int	hw_fragcount;
+
+	int		hwbuf_size;
+	unsigned long	hwbuf_paddr;
+	unsigned long	hwbuf_vaddr;
+	caddr_t		hwbuf;		/* hwbuf == hwbuf_vaddr */
+	int		hwbuf_max;	/* max bytes to preload */
+
+	caddr_t		swbuf;
+	unsigned int	swbuf_size;	/* size in bytes */
+	unsigned int	swb_u_idx;	/* index of next user byte */
+	unsigned int	swb_i_idx;	/* index of next intr byte */
+	unsigned int	swb_u_avail;	/* # bytes avail to user */
+	unsigned int	swb_i_avail;	/* # bytes avail to intr */
+
+	dma_chan_t	chan;
+
+} vwsnd_port_t;
+
+/* vwsnd_dev is the per-device data structure. */
+
+typedef struct vwsnd_dev {
+	struct vwsnd_dev *next_dev;
+	int		audio_minor;	/* minor number of audio device */
+	int		mixer_minor;	/* minor number of mixer device */
+
+	struct semaphore open_sema;
+	struct semaphore io_sema;
+	struct semaphore mix_sema;
+	mode_t		open_mode;
+	struct wait_queue *open_wait;
+
+	lithium_t	lith;
+
+	vwsnd_port_t	rport;
+	vwsnd_port_t	wport;
+} vwsnd_dev_t;
+
+static vwsnd_dev_t *vwsnd_dev_list;	/* linked list of all devices */
+
+#ifdef MODULE
+
+# define INC_USE_COUNT MOD_INC_USE_COUNT
+# define DEC_USE_COUNT MOD_DEC_USE_COUNT
+# define IN_USE        MOD_IN_USE
+
+#else
+
+static atomic_t vwsnd_use_count = ATOMIC_INIT(0);
+
+# define INC_USE_COUNT (atomic_inc(&vwsnd_use_count))
+# define DEC_USE_COUNT (atomic_dec(&vwsnd_use_count))
+# define IN_USE        (atomic_read(&vwsnd_use_count) != 0)
+
+#endif
+
+/*
+ * Lithium can only DMA multiples of 32 bytes.  Its DMA buffer may
+ * be up to 8 Kb.  This driver always uses 8 Kb.
+ *
+ * Memory bug workaround -- I'm not sure what's going on here, but
+ * somehow pcm_copy_out() was triggering segv's going on to the next
+ * page of the hw buffer.  So, I make the hw buffer one size bigger
+ * than we actually use.  That way, the following page is allocated
+ * and mapped, and no error.  I suspect that something is broken
+ * in Cobalt, but haven't really investigated.  HBO is the actual
+ * size of the buffer, and HWBUF_ORDER is what we allocate.
+ */
+
+#define HWBUF_SHIFT 13
+#define HWBUF_SIZE (1 << HWBUF_SHIFT)
+# define HBO         (HWBUF_SHIFT > PAGE_SHIFT ? HWBUF_SHIFT - PAGE_SHIFT : 0)
+# define HWBUF_ORDER (HBO + 1)		/* next size bigger */
+#define MIN_SPEED 4000
+#define MAX_SPEED 49000
+
+#define MIN_FRAGSHIFT			(DMACHUNK_SHIFT + 1)
+#define MAX_FRAGSHIFT			(PAGE_SHIFT)
+#define MIN_FRAGSIZE			(1 << MIN_FRAGSHIFT)
+#define MAX_FRAGSIZE			(1 << MAX_FRAGSHIFT)
+#define MIN_FRAGCOUNT(fragsize)		2
+#define MAX_FRAGCOUNT(fragsize)		(32 * PAGE_SIZE / (fragsize))
+#define DEFAULT_FRAGSHIFT		12
+#define DEFAULT_FRAGCOUNT		16
+#define DEFAULT_SUBDIVSHIFT		0
+
+/*
+ * The software buffer (swbuf) is a ring buffer shared between user
+ * level and interrupt level.  Each level owns some of the bytes in
+ * the buffer, and may give bytes away by calling swb_inc_{u,i}().
+ * User level calls _u for user, and interrupt level calls _i for
+ * interrupt.
+ *
+ * port->swb_{u,i}_avail is the number of bytes available to that level.
+ *
+ * port->swb_{u,i}_idx is the index of the first available byte in the
+ * buffer.
+ *
+ * Each level calls swb_inc_{u,i}() to atomically increment its index,
+ * recalculate the number of bytes available for both sides, and
+ * return the number of bytes available.  Since each side can only
+ * give away bytes, the other side can only increase the number of
+ * bytes available to this side.  Each side updates its own index
+ * variable, swb_{u,i}_idx, so no lock is needed to read it.
+ *
+ * To query the number of bytes available, call swb_inc_{u,i} with an
+ * increment of zero.
+ */
+
+static __inline__ unsigned int __swb_inc_u(vwsnd_port_t *port, int inc)
+{
+	if (inc) {
+		port->swb_u_idx += inc;
+		port->swb_u_idx %= port->swbuf_size;
+		port->swb_u_avail -= inc;
+		port->swb_i_avail += inc;
+	}
+	return port->swb_u_avail;
+}
+
+static __inline__ unsigned int swb_inc_u(vwsnd_port_t *port, int inc)
+{
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&port->lock, flags);
+	{
+		ret = __swb_inc_u(port, inc);
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+	return ret;
+}
+
+static __inline__ unsigned int __swb_inc_i(vwsnd_port_t *port, int inc)
+{
+	if (inc) {
+		port->swb_i_idx += inc;
+		port->swb_i_idx %= port->swbuf_size;
+		port->swb_i_avail -= inc;
+		port->swb_u_avail += inc;
+	}
+	return port->swb_i_avail;
+}
+
+static __inline__ unsigned int swb_inc_i(vwsnd_port_t *port, int inc)
+{
+	unsigned long flags;
+	unsigned int ret;
+
+	spin_lock_irqsave(&port->lock, flags);
+	{
+		ret = __swb_inc_i(port, inc);
+	}
+	spin_unlock_irqrestore(&port->lock, flags);
+	return ret;
+}
+
+/*
+ * pcm_setup - this routine initializes all port state after
+ * mode-setting ioctls have been done, but before the first I/O is
+ * done.
+ *
+ * Locking: called with devc->io_sema held.
+ *
+ * Returns 0 on success, -errno on failure.
+ */
+
+static int pcm_setup(vwsnd_dev_t *devc,
+		     vwsnd_port_t *rport,
+		     vwsnd_port_t *wport)
+{
+	vwsnd_port_t *aport = rport ? rport : wport;
+	int sample_size;
+	unsigned int zero_word;
+
+	DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport);
+
+	ASSERT(aport != NULL);
+	if (aport->swbuf != NULL)
+		return 0;
+	switch (aport->sw_samplefmt) {
+	case AFMT_MU_LAW:
+		sample_size = 1;
+		zero_word = 0xFFFFFFFF ^ 0x80808080;
+		break;
+
+	case AFMT_A_LAW:
+		sample_size = 1;
+		zero_word = 0xD5D5D5D5 ^ 0x80808080;
+		break;
+
+	case AFMT_U8:
+		sample_size = 1;
+		zero_word = 0x80808080;
+		break;
+
+	case AFMT_S8:
+		sample_size = 1;
+		zero_word = 0x00000000;
+		break;
+
+	case AFMT_S16_LE:
+		sample_size = 2;
+		zero_word = 0x00000000;
+		break;
+
+	default:
+		sample_size = 0;	/* prevent compiler warning */
+		zero_word = 0;
+		ASSERT(0);
+	}
+	aport->sample_size  = sample_size;
+	aport->zero_word    = zero_word;
+	aport->frame_size   = aport->sw_channels * aport->sample_size;
+	aport->hw_fragshift = aport->sw_fragshift - aport->sw_subdivshift;
+	aport->hw_fragsize  = 1 << aport->hw_fragshift;
+	aport->hw_fragcount = aport->sw_fragcount << aport->sw_subdivshift;
+	aport->swbuf_size   = aport->hw_fragcount * aport->hw_fragsize;
+	aport->hwbuf_max    = aport->hwbuf_size - DMACHUNK_SIZE;
+	aport->swb_u_idx    = 0;
+	aport->swb_i_idx    = 0;
+
+	/*
+	 * Is this a Cobalt bug?  We need to make this buffer extend one
+	 * page further than we actually use -- somehow memcpy fails
+	 * otherwise.  I suspect there's a bug in Cobalt (or somewhere)
+	 * where it's generating a fault on a speculative load or something.
+	 * Obviously, I haven't taken the time to track it down.
+	 */
+
+	aport->swbuf        = vmalloc(aport->swbuf_size + PAGE_SIZE);
+	if (!aport->swbuf)
+		return -ENOMEM;
+	if (rport && wport) {
+		ASSERT(aport == rport);
+		ASSERT(wport->swbuf == NULL);
+		/* One extra page - see comment above. */
+		wport->swbuf = vmalloc(aport->swbuf_size + PAGE_SIZE);
+		if (!wport->swbuf) {
+			vfree(aport->swbuf);
+			aport->swbuf = NULL;
+			return -ENOMEM;
+		}
+		wport->sample_size  = rport->sample_size;
+		wport->zero_word    = rport->zero_word;
+		wport->frame_size   = rport->frame_size;
+		wport->hw_fragshift = rport->hw_fragshift;
+		wport->hw_fragsize  = rport->hw_fragsize;
+		wport->hw_fragcount = rport->hw_fragcount;
+		wport->swbuf_size   = rport->swbuf_size;
+		wport->hwbuf_max    = rport->hwbuf_max;
+		wport->swb_u_idx    = rport->swb_u_idx;
+		wport->swb_i_idx    = rport->swb_i_idx;
+	}
+	if (rport) {
+		rport->swb_u_avail = 0;
+		rport->swb_i_avail = rport->swbuf_size;
+		rport->swstate = SW_RUN;
+		li_setup_dma(&rport->chan,
+			     &li_comm1,
+			     &devc->lith,
+			     rport->hwbuf_paddr,
+			     HWBUF_SHIFT,
+			     rport->hw_fragshift,
+			     rport->sw_channels,
+			     rport->sample_size);
+		ad1843_setup_adc(&devc->lith,
+				 rport->sw_framerate,
+				 rport->sw_samplefmt,
+				 rport->sw_channels);
+		li_enable_interrupts(&devc->lith, READ_INTR_MASK);
+		if (!(rport->flags & DISABLED)) {
+			rport->hwstate = HW_RUNNING;
+			li_activate_dma(&rport->chan);
+		}
+	}
+	if (wport) {
+		if (aport->hwbuf_max > aport->swbuf_size)
+			aport->hwbuf_max = aport->swbuf_size;
+		wport->flags &= ~ERFLOWN;
+		wport->swb_u_avail = wport->swbuf_size;
+		wport->swb_i_avail = 0;
+		wport->swstate = SW_RUN;
+		li_setup_dma(&wport->chan,
+			     &li_comm2,
+			     &devc->lith,
+			     wport->hwbuf_paddr,
+			     HWBUF_SHIFT,
+			     wport->hw_fragshift,
+			     wport->sw_channels,
+			     wport->sample_size);
+		ad1843_setup_dac(&devc->lith,
+				 wport->sw_framerate,
+				 wport->sw_samplefmt,
+				 wport->sw_channels);
+		li_enable_interrupts(&devc->lith, WRITE_INTR_MASK);
+	}
+	DBGRV();
+	return 0;
+}
+
+/*
+ * pcm_shutdown_port - shut down one port (direction) for PCM I/O.
+ * Only called from pcm_shutdown.
+ */
+
+static void pcm_shutdown_port(vwsnd_dev_t *devc,
+			      vwsnd_port_t *aport,
+			      unsigned int mask)
+{
+	unsigned long flags;
+	vwsnd_port_hwstate_t hwstate;
+	struct wait_queue wait = { current, NULL };
+
+	aport->swstate = SW_INITIAL;
+	add_wait_queue(&aport->queue, &wait);
+	current->state = TASK_UNINTERRUPTIBLE;
+	while (1) {
+		spin_lock_irqsave(&aport->lock, flags);
+		{
+			hwstate = aport->hwstate;
+		}		
+		spin_unlock_irqrestore(&aport->lock, flags);
+		if (hwstate == HW_STOPPED)
+			break;
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&aport->queue, &wait);
+	li_disable_interrupts(&devc->lith, mask);
+	if (aport == &devc->rport)
+		ad1843_shutdown_adc(&devc->lith);
+	else /* aport == &devc->wport) */
+		ad1843_shutdown_dac(&devc->lith);
+	li_shutdown_dma(&aport->chan);
+	vfree(aport->swbuf);
+	aport->swbuf = NULL;
+}
+
+/*
+ * pcm_shutdown undoes what pcm_setup did.
+ * Also sets the ports' swstate to newstate.
+ */
+
+static void pcm_shutdown(vwsnd_dev_t *devc,
+			 vwsnd_port_t *rport,
+			 vwsnd_port_t *wport)
+{
+	DBGEV("(devc=0x%p, rport=0x%p, wport=0x%p)\n", devc, rport, wport);
+
+	if (rport && rport->swbuf) {
+		DBGPV("shutting down rport\n");
+		pcm_shutdown_port(devc, rport, READ_INTR_MASK);
+	}
+	if (wport && wport->swbuf) {
+		DBGPV("shutting down wport\n");
+		pcm_shutdown_port(devc, wport, READ_INTR_MASK);
+	}
+	DBGRV();
+}
+
+static void pcm_copy_in(vwsnd_port_t *rport, int swidx, int hwidx, int nb)
+{
+	char *src = rport->hwbuf + hwidx;
+	char *dst = rport->swbuf + swidx;
+	int fmt = rport->sw_samplefmt;
+
+	DBGPV("swidx = %d, hwidx = %d\n", swidx, hwidx);
+	ASSERT(rport->hwbuf != NULL);
+	ASSERT(rport->swbuf != NULL);
+	ASSERT(nb > 0 && (nb % 32) == 0);
+	ASSERT(swidx % 32 == 0 && hwidx % 32 == 0);
+	ASSERT(swidx >= 0 && swidx + nb <= rport->swbuf_size);
+	ASSERT(hwidx >= 0 && hwidx + nb <= rport->hwbuf_size);
+
+	if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) {
+
+		/* See Sample Format Notes above. */
+
+		char *end = src + nb;
+		while (src < end)
+			*dst++ = *src++ ^ 0x80;
+	} else
+		memcpy(dst, src, nb);
+}
+
+static void pcm_copy_out(vwsnd_port_t *wport, int swidx, int hwidx, int nb)
+{
+	char *src = wport->swbuf + swidx;
+	char *dst = wport->hwbuf + hwidx;
+	int fmt = wport->sw_samplefmt;
+
+	ASSERT(nb > 0 && (nb % 32) == 0);
+	ASSERT(wport->hwbuf != NULL);
+	ASSERT(wport->swbuf != NULL);
+	ASSERT(swidx % 32 == 0 && hwidx % 32 == 0);
+	ASSERT(swidx >= 0 && swidx + nb <= wport->swbuf_size);
+	ASSERT(hwidx >= 0 && hwidx + nb <= wport->hwbuf_size);
+	if (fmt == AFMT_MU_LAW || fmt == AFMT_A_LAW || fmt == AFMT_S8) {
+
+		/* See Sample Format Notes above. */
+
+		char *end = src + nb;
+		while (src < end)
+			*dst++ = *src++ ^ 0x80;
+	} else
+		memcpy(dst, src, nb);
+}
+
+/*
+ * pcm_output() is called both from baselevel and from interrupt level.
+ * This is where audio frames are copied into the hardware-accessible
+ * ring buffer.
+ *
+ * Locking note: The part of this routine that figures out what to do
+ * holds wport->lock.  The longer part releases wport->lock, but sets
+ * wport->flags & HW_BUSY.  Afterward, it reacquires wport->lock, and
+ * checks for more work to do.
+ *
+ * If another thread calls pcm_output() while HW_BUSY is set, it
+ * returns immediately, knowing that the thread that set HW_BUSY will
+ * look for more work to do before returning.
+ *
+ * This has the advantage that port->lock is held for several short
+ * periods instead of one long period.  Also, when pcm_output is
+ * called from base level, it reenables interrupts.
+ */
+
+static void pcm_output(vwsnd_dev_t *devc, int erflown, int nb)
+{
+	vwsnd_port_t *wport = &devc->wport;
+	const int hwmax  = wport->hwbuf_max;
+	const int hwsize = wport->hwbuf_size;
+	const int swsize = wport->swbuf_size;
+	const int fragsize = wport->hw_fragsize;
+	unsigned long iflags;
+
+	DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb);
+	spin_lock_irqsave(&wport->lock, iflags);
+	if (erflown)
+		wport->flags |= ERFLOWN;
+	(void) __swb_inc_u(wport, nb);
+	if (wport->flags & HW_BUSY) {
+		spin_unlock_irqrestore(&wport->lock, iflags);
+		DBGPV("returning: HW BUSY\n");
+		return;
+	}
+	if (wport->flags & DISABLED) {
+		spin_unlock_irqrestore(&wport->lock, iflags);
+		DBGPV("returning: DISABLED\n");
+		return;
+	}
+	wport->flags |= HW_BUSY;
+	while (1) {
+		int swptr, hwptr, hw_avail, sw_avail, swidx;
+		vwsnd_port_hwstate_t hwstate = wport->hwstate;
+		vwsnd_port_swstate_t swstate = wport->swstate;
+		int hw_unavail;
+
+		hwptr = li_read_hwptr(&wport->chan);
+		swptr = li_read_swptr(&wport->chan);
+		hw_unavail = (swptr - hwptr + hwsize) % hwsize;
+		hw_avail = (hwmax - hw_unavail) & -fragsize;
+		sw_avail = wport->swb_i_avail & -fragsize;
+		if (sw_avail && swstate == SW_RUN)
+			wport->flags &= ~ERFLOWN;
+		else if (swstate == SW_INITIAL ||
+			 swstate == SW_OFF ||
+			 (swstate == SW_DRAIN &&
+			  !sw_avail &&
+			  (wport->flags & ERFLOWN))) {
+			DBGP("stopping.  hwstate = %d\n", hwstate);
+			if (hwstate != HW_STOPPED) {
+				li_deactivate_dma(&wport->chan);
+				wport->hwstate = HW_STOPPED;
+			}
+			wake_up(&wport->queue);
+			break;
+		}
+		if (!sw_avail || !hw_avail)
+			break;
+		spin_unlock_irqrestore(&wport->lock, iflags);
+
+		/*
+		 * We gave up the port lock, but we have the HW_BUSY flag.
+		 * Proceed without accessing any nonlocal state.
+		 * Do not exit the loop -- must check for more work.
+		 */
+
+		swidx = wport->swb_i_idx;
+		nb = hw_avail;
+		if (nb > sw_avail)
+			nb = sw_avail;
+		if (nb > hwsize - swptr)
+			nb = hwsize - swptr; /* don't overflow hwbuf */
+		if (nb > swsize - swidx)
+			nb = swsize - swidx; /* don't overflow swbuf */
+		ASSERT(nb > 0);
+		if (nb % fragsize) {
+			DBGP("nb = %d, fragsize = %d\n", nb, fragsize);
+			DBGP("hw_avail = %d\n", hw_avail);
+			DBGP("sw_avail = %d\n", sw_avail);
+			DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr);
+			DBGP("swsize = %d, swidx = %d\n", swsize, swidx);
+		}
+		ASSERT(!(nb % fragsize));
+		DBGPV("copying swb[%d..%d] to hwb[%d..%d]\n",
+		      swidx, swidx + nb, swptr, swptr + nb);
+		pcm_copy_out(wport, swidx, swptr, nb);
+		li_write_swptr(&wport->chan, (swptr + nb) % hwsize);
+		spin_lock_irqsave(&wport->lock, iflags);
+		if (hwstate == HW_STOPPED) {
+			DBGPV("starting\n");
+			li_activate_dma(&wport->chan);
+			wport->hwstate = HW_RUNNING;
+		}
+		__swb_inc_i(wport, nb);
+		wake_up(&wport->queue);
+	}
+	wport->flags &= ~HW_BUSY;
+	spin_unlock_irqrestore(&wport->lock, iflags);
+	DBGRV();
+}
+
+/*
+ * pcm_input() is called both from baselevel and from interrupt level.
+ * This is where audio frames are copied into the hardware-accessible
+ * ring buffer.
+ *
+ * Locking note: The part of this routine that figures out what to do
+ * holds rport->lock.  The longer part releases rport->lock, but sets
+ * rport->flags & HW_BUSY.  Afterward, it reacquires rport->lock, and
+ * checks for more work to do.
+ *
+ * If another thread calls pcm_input() while HW_BUSY is set, it
+ * returns immediately, knowing that the thread that set HW_BUSY will
+ * look for more work to do before returning.
+ *
+ * This has the advantage that port->lock is held for several short
+ * periods instead of one long period.  Also, when pcm_input is
+ * called from base level, it reenables interrupts.
+ */
+
+static void pcm_input(vwsnd_dev_t *devc, int erflown, int nb)
+{
+	vwsnd_port_t *rport = &devc->rport;
+	const int hwmax  = rport->hwbuf_max;
+	const int hwsize = rport->hwbuf_size;
+	const int swsize = rport->swbuf_size;
+	const int fragsize = rport->hw_fragsize;
+	unsigned long iflags;
+
+	DBGEV("(devc=0x%p, erflown=%d, nb=%d)\n", devc, erflown, nb);
+
+	spin_lock_irqsave(&rport->lock, iflags);
+	if (erflown)
+		rport->flags |= ERFLOWN;
+	(void) __swb_inc_u(rport, nb);
+	if (rport->flags & HW_BUSY || !rport->swbuf) {
+		spin_unlock_irqrestore(&rport->lock, iflags);
+		DBGPV("returning: HW BUSY or !swbuf\n");
+		return;
+	}
+	if (rport->flags & DISABLED) {
+		spin_unlock_irqrestore(&rport->lock, iflags);
+		DBGPV("returning: DISABLED\n");
+		return;
+	}
+	rport->flags |= HW_BUSY;
+	while (1) {
+		int swptr, hwptr, hw_avail, sw_avail, swidx;
+		vwsnd_port_hwstate_t hwstate = rport->hwstate;
+		vwsnd_port_swstate_t swstate = rport->swstate;
+
+		hwptr = li_read_hwptr(&rport->chan);
+		swptr = li_read_swptr(&rport->chan);
+		hw_avail = (hwptr - swptr + hwsize) % hwsize & -fragsize;
+		if (hw_avail > hwmax)
+			hw_avail = hwmax;
+		sw_avail = rport->swb_i_avail & -fragsize;
+		if (swstate != SW_RUN) {
+			DBGP("stopping.  hwstate = %d\n", hwstate);
+			if (hwstate != HW_STOPPED) {
+				li_deactivate_dma(&rport->chan);
+				rport->hwstate = HW_STOPPED;
+			}
+			wake_up(&rport->queue);
+			break;
+		}
+		if (!sw_avail || !hw_avail)
+			break;
+		spin_unlock_irqrestore(&rport->lock, iflags);
+
+		/*
+		 * We gave up the port lock, but we have the HW_BUSY flag.
+		 * Proceed without accessing any nonlocal state.
+		 * Do not exit the loop -- must check for more work.
+		 */
+
+		swidx = rport->swb_i_idx;
+		nb = hw_avail;
+		if (nb > sw_avail)
+			nb = sw_avail;
+		if (nb > hwsize - swptr)
+			nb = hwsize - swptr; /* don't overflow hwbuf */
+		if (nb > swsize - swidx)
+			nb = swsize - swidx; /* don't overflow swbuf */
+		ASSERT(nb > 0);
+		if (nb % fragsize) {
+			DBGP("nb = %d, fragsize = %d\n", nb, fragsize);
+			DBGP("hw_avail = %d\n", hw_avail);
+			DBGP("sw_avail = %d\n", sw_avail);
+			DBGP("hwsize = %d, swptr = %d\n", hwsize, swptr);
+			DBGP("swsize = %d, swidx = %d\n", swsize, swidx);
+		}
+		ASSERT(!(nb % fragsize));
+		DBGPV("copying hwb[%d..%d] to swb[%d..%d]\n",
+		      swptr, swptr + nb, swidx, swidx + nb);
+		pcm_copy_in(rport, swidx, swptr, nb);
+		li_write_swptr(&rport->chan, (swptr + nb) % hwsize);
+		spin_lock_irqsave(&rport->lock, iflags);
+		__swb_inc_i(rport, nb);
+		wake_up(&rport->queue);
+	}
+	rport->flags &= ~HW_BUSY;
+	spin_unlock_irqrestore(&rport->lock, iflags);
+	DBGRV();
+}
+
+/*
+ * pcm_flush_frag() writes zero samples to fill the current fragment,
+ * then flushes it to the hardware.
+ *
+ * It is only meaningful to flush output, not input.
+ */
+
+static void pcm_flush_frag(vwsnd_dev_t *devc)
+{
+	vwsnd_port_t *wport = &devc->wport;
+
+	DBGPV("swstate = %d\n", wport->swstate);
+	if (wport->swstate == SW_RUN) {
+		int idx = wport->swb_u_idx;
+		int end = (idx + wport->hw_fragsize - 1)
+			>> wport->hw_fragshift
+			<< wport->hw_fragshift;
+		int nb = end - idx;
+		DBGPV("clearing %d bytes\n", nb);
+		if (nb)
+			memset(wport->swbuf + idx,
+			       (char) wport->zero_word,
+			       nb);
+		wport->swstate = SW_DRAIN;
+		pcm_output(devc, 0, nb);
+	}
+	DBGRV();
+}
+
+/*
+ * Wait for output to drain.  This sleeps uninterruptibly because
+ * there is nothing intelligent we can do if interrupted.  This
+ * means the process will be delayed in responding to the signal.
+ */
+
+static void pcm_write_sync(vwsnd_dev_t *devc)
+{
+	vwsnd_port_t *wport = &devc->wport;
+	struct wait_queue wait = { current, NULL };
+	unsigned long flags;
+	vwsnd_port_hwstate_t hwstate;
+
+	DBGEV("(devc=0x%p)\n", devc);
+	add_wait_queue(&wport->queue, &wait);
+	current->state = TASK_UNINTERRUPTIBLE;
+	while (1) {
+		spin_lock_irqsave(&wport->lock, flags);
+		{
+			hwstate = wport->hwstate;
+		}
+		spin_unlock_irqrestore(&wport->lock, flags);
+		if (hwstate == HW_STOPPED)
+			break;
+		schedule();
+	}
+	current->state = TASK_RUNNING;
+	remove_wait_queue(&wport->queue, &wait);
+	DBGPV("swstate = %d, hwstate = %d\n", wport->swstate, wport->hwstate);
+	DBGRV();
+}
+
+/*****************************************************************************/
+/* audio driver */
+
+/*
+ * seek on an audio device always fails.
+ */
+
+static void vwsnd_audio_read_intr(vwsnd_dev_t *devc, unsigned int status)
+{
+	int overflown = status & LI_INTR_COMM1_OVERFLOW;
+
+	if (status & READ_INTR_MASK)
+		pcm_input(devc, overflown, 0);
+}
+
+static void vwsnd_audio_write_intr(vwsnd_dev_t *devc, unsigned int status)
+{
+	int underflown = status & LI_INTR_COMM2_UNDERFLOW;
+
+	if (status & WRITE_INTR_MASK)
+		pcm_output(devc, underflown, 0);
+}
+
+static void vwsnd_audio_intr(int irq, void *dev_id, struct pt_regs *regs)
+{
+	vwsnd_dev_t *devc = (vwsnd_dev_t *) dev_id;
+	unsigned int status;
+
+	DBGEV("(irq=%d, dev_id=0x%p, regs=0x%p)\n", irq, dev_id, regs);
+
+	status = li_get_clear_intr_status(&devc->lith);
+	vwsnd_audio_read_intr(devc, status);
+	vwsnd_audio_write_intr(devc, status);
+}
+
+static loff_t vwsnd_audio_llseek(struct file *file, loff_t offset, int whence)
+{
+	DBGEV("(file=0x%p, offset=%Ld, whence=%d)\n", file, offset, whence);
+	return -ESPIPE;
+}
+
+static ssize_t vwsnd_audio_do_read(struct file *file,
+				   char *buffer,
+				   size_t count,
+				   loff_t *ppos)
+{
+	vwsnd_dev_t *devc = file->private_data;
+	vwsnd_port_t *rport = ((file->f_mode & FMODE_READ) ?
+			       &devc->rport : NULL);
+	int ret, nb;
+
+	DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n",
+	     file, buffer, count, ppos);
+
+	if (!rport)
+		return -EINVAL;
+
+	if (rport->swbuf == NULL) {
+		vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
+			&devc->wport : NULL;
+		ret = pcm_setup(devc, rport, wport);
+		if (ret < 0)
+			return ret;
+	}
+
+	if (!access_ok(VERIFY_READ, buffer, count))
+		return -EFAULT;
+	ret = 0;
+	while (count) {
+		struct wait_queue wait = { current, NULL };
+		add_wait_queue(&rport->queue, &wait);
+		current->state = TASK_INTERRUPTIBLE;
+		while ((nb = swb_inc_u(rport, 0)) == 0) {
+			DBGPV("blocking\n");
+			if (rport->flags & DISABLED ||
+			    file->f_flags & O_NONBLOCK) {
+				current->state = TASK_RUNNING;
+				remove_wait_queue(&rport->queue, &wait);
+				return ret ? ret : -EAGAIN;
+			}
+			schedule();
+			if (signal_pending(current)) {
+				current->state = TASK_RUNNING;
+				remove_wait_queue(&rport->queue, &wait);
+				return ret ? ret : -ERESTARTSYS;
+			}
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&rport->queue, &wait);
+		pcm_input(devc, 0, 0);
+		/* nb bytes are available in userbuf. */
+		if (nb > count)
+			nb = count;
+		DBGPV("nb = %d\n", nb);
+		copy_to_user(buffer, rport->swbuf + rport->swb_u_idx, nb);
+		(void) swb_inc_u(rport, nb);
+		buffer += nb;
+		count -= nb;
+		ret += nb;
+	}
+	DBGPV("returning %d\n", ret);
+	return ret;
+}
+
+static ssize_t vwsnd_audio_read(struct file *file,
+				char *buffer,
+				size_t count,
+				loff_t *ppos)
+{
+	vwsnd_dev_t *devc = file->private_data;
+	ssize_t ret;
+
+	down(&devc->io_sema);
+	ret = vwsnd_audio_do_read(file, buffer, count, ppos);
+	up(&devc->io_sema);
+	return ret;
+}
+
+static ssize_t vwsnd_audio_do_write(struct file *file,
+				    const char *buffer,
+				    size_t count,
+				    loff_t *ppos)
+{
+	vwsnd_dev_t *devc = file->private_data;
+	vwsnd_port_t *wport = ((file->f_mode & FMODE_WRITE) ?
+			       &devc->wport : NULL);
+	int ret, nb;
+
+	DBGEV("(file=0x%p, buffer=0x%p, count=%d, ppos=0x%p)\n",
+	      file, buffer, count, ppos);
+
+	if (!wport)
+		return -EINVAL;
+
+	if (wport->swbuf == NULL) {
+		vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
+			&devc->rport : NULL;
+		ret = pcm_setup(devc, rport, wport);
+		if (ret < 0)
+			return ret;
+	}
+	if (!access_ok(VERIFY_WRITE, buffer, count))
+		return -EFAULT;
+	ret = 0;
+	while (count) {
+		struct wait_queue wait = { current, NULL };
+		add_wait_queue(&wport->queue, &wait);
+		current->state = TASK_INTERRUPTIBLE;
+		while ((nb = swb_inc_u(wport, 0)) == 0) {
+			if (wport->flags & DISABLED ||
+			    file->f_flags & O_NONBLOCK) {
+				current->state = TASK_RUNNING;
+				remove_wait_queue(&wport->queue, &wait);
+				return ret ? ret : -EAGAIN;
+			}
+			schedule();
+			if (signal_pending(current)) {
+				current->state = TASK_RUNNING;
+				remove_wait_queue(&wport->queue, &wait);
+				return ret ? ret : -ERESTARTSYS;
+			}
+		}
+		current->state = TASK_RUNNING;
+		remove_wait_queue(&wport->queue, &wait);
+		/* nb bytes are available in userbuf. */
+		if (nb > count)
+			nb = count;
+		DBGPV("nb = %d\n", nb);
+		copy_from_user(wport->swbuf + wport->swb_u_idx, buffer, nb);
+		pcm_output(devc, 0, nb);
+		buffer += nb;
+		count -= nb;
+		ret += nb;
+	}
+	DBGPV("returning %d\n", ret);
+	return ret;
+}
+
+static ssize_t vwsnd_audio_write(struct file *file,
+				 const char *buffer,
+				 size_t count,
+				 loff_t *ppos)
+{
+	vwsnd_dev_t *devc = file->private_data;
+	ssize_t ret;
+
+	down(&devc->io_sema);
+	ret = vwsnd_audio_do_write(file, buffer, count, ppos);
+	up(&devc->io_sema);
+	return ret;
+}
+
+static unsigned int vwsnd_audio_poll(struct file *file,
+				     struct poll_table_struct *wait)
+{
+	vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
+	vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
+		&devc->rport : NULL;
+	vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
+		&devc->wport : NULL;
+	unsigned int mask = 0;
+
+	DBGEV("(file=0x%p, wait=0x%p)\n", file, wait);
+
+	ASSERT(rport || wport);
+	if (rport) {
+		poll_wait(file, &rport->queue, wait);
+		if (swb_inc_u(rport, 0))
+			mask |= (POLLIN | POLLRDNORM);
+	}
+	if (wport) {
+		poll_wait(file, &wport->queue, wait);
+		if (wport->swbuf == NULL || swb_inc_u(wport, 0))
+			mask |= (POLLOUT | POLLWRNORM);
+	}
+
+	DBGPV("returning 0x%x\n", mask);
+	return mask;
+}
+
+static int vwsnd_audio_do_ioctl(struct inode *inode,
+				struct file *file,
+				unsigned int cmd,
+				unsigned long arg)
+{
+	vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
+	vwsnd_port_t *rport = (file->f_mode & FMODE_READ) ?
+		&devc->rport : NULL;
+	vwsnd_port_t *wport = (file->f_mode & FMODE_WRITE) ?
+		&devc->wport : NULL;
+	vwsnd_port_t *aport = rport ? rport : wport;
+	struct audio_buf_info buf_info;
+	int ival;
+
+	
+	DBGEV("(inode=0x%p, file=0x%p, cmd=0x%x, arg=0x%lx)\n",
+	      inode, file, cmd, arg);
+	switch (cmd) {
+	case OSS_GETVERSION:		/* _SIOR ('M', 118, int) */
+		ival = SOUND_VERSION;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_GETCAPS:	/* _SIOR ('P',15, int) */
+/* XXX		ival = DSP_CAP_DUPLEX | DSP_CAP_REALTIME | DSP_CAP_TRIGGER; */
+		ival = DSP_CAP_DUPLEX | DSP_CAP_TRIGGER;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_GETFMTS:	/* _SIOR ('P',11, int) */
+		ival = (AFMT_S16_LE | AFMT_MU_LAW | AFMT_A_LAW |
+			AFMT_U8 | AFMT_S8);
+		return put_user(ival, (int *) arg);
+		break;
+
+	case SOUND_PCM_READ_RATE:	/* _SIOR ('P', 2, int) */
+		ival = aport->sw_framerate;
+		return put_user(ival, (int *) arg);
+
+	case SOUND_PCM_READ_CHANNELS:	/* _SIOR ('P', 6, int) */
+		ival = aport->sw_channels;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_SPEED:		/* _SIOWR('P', 2, int) */
+		get_user_ret(ival, (int *) arg, -EFAULT);
+		DBGX("SNDCTL_DSP_SPEED %d\n", ival);
+		if (ival) {
+			if (aport->swstate != SW_INITIAL) {
+				DBGX("SNDCTL_DSP_SPEED failed: swstate = %d\n",
+				     aport->swstate);
+				return -EINVAL;
+			}
+			if (ival < MIN_SPEED)
+				ival = MIN_SPEED;
+			if (ival > MAX_SPEED)
+				ival = MAX_SPEED;
+			if (rport)
+				rport->sw_framerate = ival;
+			if (wport)
+				wport->sw_framerate = ival;
+		} else
+			ival = aport->sw_framerate;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_STEREO:		/* _SIOWR('P', 3, int) */
+		get_user_ret(ival, (int *) arg, -EFAULT);
+		DBGX("SNDCTL_DSP_STEREO %d\n", ival);
+		if (ival != 0 && ival != 1)
+			return -EINVAL;
+		if (aport->swstate != SW_INITIAL)
+			return -EINVAL;
+		if (rport)
+			rport->sw_channels = ival + 1;
+		if (wport)
+			wport->sw_channels = ival + 1;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_CHANNELS:	/* _SIOWR('P', 6, int) */
+		get_user_ret(ival, (int *) arg, -EFAULT);
+		DBGX("SNDCTL_DSP_CHANNELS %d\n", ival);
+		if (ival != 1 && ival != 2)
+			return -EINVAL;
+		if (aport->swstate != SW_INITIAL)
+			return -EINVAL;
+		if (rport)
+			rport->sw_channels = ival;
+		if (wport)
+			wport->sw_channels = ival;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_GETBLKSIZE:	/* _SIOWR('P', 4, int) */
+		ival = pcm_setup(devc, rport, wport);
+		if (ival < 0)
+			return ival;
+		ival = 1 << aport->sw_fragshift;
+		DBGX("SNDCTL_DSP_GETBLKSIZE returning %d\n", ival);
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_SETFRAGMENT:	/* _SIOWR('P',10, int) */
+		get_user_ret(ival, (int *) arg, -EFAULT);
+		DBGX("SNDCTL_DSP_SETFRAGMENT %d:%d\n",
+		     ival >> 16, ival & 0xFFFF);
+		DBGP("aport = 0x%p\n", aport);
+		if (aport->swstate != SW_INITIAL)
+			return -EINVAL;
+		{
+			int sw_fragshift = ival & 0xFFFF;
+			int sw_subdivshift = aport->sw_subdivshift;
+			int hw_fragshift = sw_fragshift - sw_subdivshift;
+			int sw_fragcount = (ival >> 16) & 0xFFFF;
+			int hw_fragsize;
+			if (hw_fragshift < MIN_FRAGSHIFT)
+				hw_fragshift = MIN_FRAGSHIFT;
+			if (hw_fragshift > MAX_FRAGSHIFT)
+				hw_fragshift = MAX_FRAGSHIFT;
+			sw_fragshift = hw_fragshift + aport->sw_subdivshift;
+			hw_fragsize = 1 << hw_fragshift;
+			if (sw_fragcount < MIN_FRAGCOUNT(hw_fragsize))
+				sw_fragcount = MIN_FRAGCOUNT(hw_fragsize);
+			if (sw_fragcount > MAX_FRAGCOUNT(hw_fragsize))
+				sw_fragcount = MAX_FRAGCOUNT(hw_fragsize);
+			DBGP("sw_fragshift = %d\n", sw_fragshift);
+			DBGP("rport = 0x%p, wport = 0x%p\n", rport, wport);
+			if (rport) {
+				rport->sw_fragshift = sw_fragshift;
+				rport->sw_fragcount = sw_fragcount;
+			}
+			if (wport) {
+				wport->sw_fragshift = sw_fragshift;
+				wport->sw_fragcount = sw_fragcount;
+			}
+			ival = sw_fragcount << 16 | sw_fragshift;
+		}
+		DBGX("SNDCTL_DSP_SETFRAGMENT returns %d:%d\n",
+		     ival >> 16, ival & 0xFFFF);
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_SUBDIVIDE:	/* _SIOWR('P', 9, int) */
+                get_user_ret(ival, (int *) arg, -EFAULT);
+		if (aport->swstate != SW_INITIAL)
+			return -EINVAL;
+		{
+			int subdivshift;
+			int hw_fragshift, hw_fragsize, hw_fragcount;
+			switch (ival) {
+			case 1: subdivshift = 0; break;
+			case 2: subdivshift = 1; break;
+			case 4: subdivshift = 2; break;
+			default: return -EINVAL;
+			}
+			hw_fragshift = aport->sw_fragshift - subdivshift;
+			if (hw_fragshift < MIN_FRAGSHIFT ||
+			    hw_fragshift > MAX_FRAGSHIFT)
+				return -EINVAL;
+			hw_fragsize = 1 << hw_fragshift;
+			hw_fragcount = aport->sw_fragcount >> subdivshift;
+			if (hw_fragcount < MIN_FRAGCOUNT(hw_fragsize) ||
+			    hw_fragcount > MAX_FRAGCOUNT(hw_fragsize))
+				return -EINVAL;
+			if (rport)
+				rport->sw_subdivshift = subdivshift;
+			if (wport)
+				wport->sw_subdivshift = subdivshift;
+		}
+		return 0;
+
+	case SNDCTL_DSP_SETFMT:		/* _SIOWR('P',5, int) */
+		get_user_ret(ival, (int *) arg, -EFAULT);
+		DBGX("SNDCTL_DSP_SETFMT %d\n", ival);
+		if (ival != AFMT_QUERY) {
+			if (aport->swstate != SW_INITIAL) {
+				DBGP("SETFMT failed, swstate = %d\n",
+				     aport->swstate);
+				return -EINVAL;
+			}
+			switch (ival) {
+			case AFMT_MU_LAW:
+			case AFMT_A_LAW:
+			case AFMT_U8:
+			case AFMT_S8:
+			case AFMT_S16_LE:
+				if (rport)
+					rport->sw_samplefmt = ival;
+				if (wport)
+					wport->sw_samplefmt = ival;
+				break;
+			default:
+				return -EINVAL;
+			}
+		}
+		ival = aport->sw_samplefmt;
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_GETOSPACE:	/* _SIOR ('P',12, audio_buf_info) */
+		if (!wport)
+			return -EINVAL;
+		ival = pcm_setup(devc, rport, wport);
+		if (ival < 0)
+			return ival;
+		ival = swb_inc_u(wport, 0);
+		buf_info.fragments = ival >> wport->sw_fragshift;
+		buf_info.fragstotal = wport->sw_fragcount;
+		buf_info.fragsize = 1 << wport->sw_fragshift;
+		buf_info.bytes = ival;
+		DBGXV("SNDCTL_DSP_GETOSPACE returns { %d %d %d %d }\n",
+		     buf_info.fragments, buf_info.fragstotal,
+		     buf_info.fragsize, buf_info.bytes);
+		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+
+	case SNDCTL_DSP_GETISPACE:	/* _SIOR ('P',13, audio_buf_info) */
+		if (!rport)
+			return -EINVAL;
+		ival = pcm_setup(devc, rport, wport);
+		if (ival < 0)
+			return ival;
+		ival = swb_inc_u(rport, 0);
+		buf_info.fragments = ival >> rport->sw_fragshift;
+		buf_info.fragstotal = rport->sw_fragcount;
+		buf_info.fragsize = 1 << rport->sw_fragshift;
+		buf_info.bytes = ival;
+		return copy_to_user((void *) arg, &buf_info, sizeof buf_info);
+
+	case SNDCTL_DSP_NONBLOCK:	/* _SIO  ('P',14) */
+		file->f_flags |= O_NONBLOCK;
+		return 0;
+
+	case SNDCTL_DSP_RESET:		/* _SIO  ('P', 0) */
+		DBGX("SNDCTL_DSP_RESET\n");
+		if (rport && rport->swbuf) {
+			/* XXX flush input */
+			/* XXX write me */
+		}
+		if (wport && wport->swbuf) {
+			wport->swstate = SW_INITIAL;
+			pcm_output(devc, 0, 0);
+			pcm_write_sync(devc);
+		}
+		pcm_shutdown(devc, rport, wport);
+		return 0;
+
+	case SNDCTL_DSP_SYNC:		/* _SIO  ('P', 1) */
+		DBGX("SNDCTL_DSP_SYNC\n");
+		if (wport) {
+			pcm_flush_frag(devc);
+			pcm_write_sync(devc);
+		}
+		pcm_shutdown(devc, rport, wport);
+		return 0;
+
+	case SNDCTL_DSP_POST:		/* _SIO  ('P', 8) */
+		DBGX("SNDCTL_DSP_POST\n");
+		if (!wport)
+			return -EINVAL;
+		pcm_flush_frag(devc);
+		return 0;
+
+	case SNDCTL_DSP_GETIPTR:	/* _SIOR ('P', 17, count_info) */
+		/* XXX write me */
+		break;
+
+	case SNDCTL_DSP_GETOPTR:	/* _SIOR ('P',18, count_info) */
+		/* XXX write me */
+		break;
+
+	case SNDCTL_DSP_GETODELAY:	/* _SIOR ('P', 23, int) */
+		/* XXX write me */
+		break;
+
+	case SNDCTL_DSP_PROFILE:	/* _SIOW ('P', 23, int) */
+		/* XXX write me */
+		break;
+
+	case SNDCTL_DSP_GETTRIGGER:	/* _SIOR ('P',16, int) */
+		ival = 0;
+		if (rport) {
+			unsigned long flags;
+			spin_lock_irqsave(&rport->lock, flags);
+			{
+				if (!(rport->flags & DISABLED))
+					ival |= PCM_ENABLE_INPUT;
+			}
+			spin_unlock_irqrestore(&rport->lock, flags);
+		}
+		if (wport) {
+			unsigned long flags;
+			spin_lock_irqsave(&wport->lock, flags);
+			{
+				if (!(wport->flags & DISABLED))
+					ival |= PCM_ENABLE_OUTPUT;
+			}
+			spin_unlock_irqrestore(&wport->lock, flags);
+		}
+		return put_user(ival, (int *) arg);
+
+	case SNDCTL_DSP_SETTRIGGER:	/* _SIOW ('P',16, int) */
+		get_user_ret(ival, (int *) arg, -EFAULT);
+
+		/*
+		 * If user is disabling I/O and port is not in initial
+		 * state, fail with EINVAL.
+		 */
+
+		if (((rport && !(ival & PCM_ENABLE_INPUT)) ||
+		     (wport && !(ival & PCM_ENABLE_OUTPUT))) &&
+		    aport->swstate != SW_INITIAL)
+			return -EINVAL;
+
+		if (rport) {
+			unsigned long iflags;
+			vwsnd_port_flags_t pflags;
+			spin_lock_irqsave(&rport->lock, iflags);
+			{
+				pflags = rport->flags;
+				if (ival & PCM_ENABLE_INPUT)
+					rport->flags &= ~DISABLED;
+				else
+					rport->flags |= DISABLED;
+			}
+			spin_unlock_irqrestore(&rport->lock, iflags);
+			if (pflags & DISABLED && ival & PCM_ENABLE_INPUT)
+				li_activate_dma(&rport->chan);
+		}
+		if (wport) {
+			unsigned long iflags;
+			vwsnd_port_flags_t pflags;
+			spin_lock_irqsave(&wport->lock, iflags);
+			{
+				pflags = wport->flags;
+				if (ival & PCM_ENABLE_OUTPUT)
+					wport->flags &= ~DISABLED;
+				else
+					wport->flags |= DISABLED;
+			}
+			spin_unlock_irqrestore(&wport->lock, iflags);
+			if (pflags & DISABLED && ival & PCM_ENABLE_OUTPUT)
+				pcm_output(devc, 0, 0);
+		}
+		return 0;
+
+	default:
+		DBGP("unknown ioctl 0x%x\n", cmd);
+		return -EINVAL;
+	}
+	DBGP("unimplemented ioctl 0x%x\n", cmd);
+	return -EINVAL;
+}
+
+static int vwsnd_audio_ioctl(struct inode *inode,
+				struct file *file,
+				unsigned int cmd,
+				unsigned long arg)
+{
+	vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
+	int ret;
+
+	down(&devc->io_sema);
+	ret = vwsnd_audio_do_ioctl(inode, file, cmd, arg);
+	up(&devc->io_sema);
+	return ret;
+}
+
+/* No mmap. */
+
+static int vwsnd_audio_mmap(struct file *file, struct vm_area_struct *vma)
+{
+	DBGE("(file=0x%p, vma=0x%p)\n", file, vma);
+	return -ENODEV;
+}
+
+/*
+ * Open the audio device for read and/or write.
+ *
+ * Returns 0 on success, -errno on failure.
+ */
+
+static int vwsnd_audio_open(struct inode *inode, struct file *file)
+{
+	vwsnd_dev_t *devc;
+	dev_t minor = MINOR(inode->i_rdev);
+	int sw_samplefmt;
+
+	DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
+
+	INC_USE_COUNT;
+	for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
+		if ((devc->audio_minor & ~0x0F) == (minor & ~0x0F))
+			break;
+
+	if (devc == NULL) {
+		DEC_USE_COUNT;
+		return -ENODEV;
+	}
+
+	down(&devc->open_sema);
+	while (devc->open_mode & file->f_mode) {
+		up(&devc->open_sema);
+		if (file->f_flags & O_NONBLOCK) {
+			DEC_USE_COUNT;
+			return -EBUSY;
+		}
+		interruptible_sleep_on(&devc->open_wait);
+		if (signal_pending(current)) {
+			DEC_USE_COUNT;
+			return -ERESTARTSYS;
+		}
+		down(&devc->open_sema);
+	}
+	devc->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE);
+	up(&devc->open_sema);
+
+	/* get default sample format from minor number. */
+
+	sw_samplefmt = 0;
+	if ((minor & 0xF) == SND_DEV_DSP)
+		sw_samplefmt = AFMT_U8;
+	else if ((minor & 0xF) == SND_DEV_AUDIO)
+		sw_samplefmt = AFMT_MU_LAW;
+	else if ((minor & 0xF) == SND_DEV_DSP16)
+		sw_samplefmt = AFMT_S16_LE;
+	else
+		ASSERT(0);
+
+	/* Initialize vwsnd_ports. */
+
+	down(&devc->io_sema);
+	{
+		if (file->f_mode & FMODE_READ) {
+			devc->rport.swstate = SW_INITIAL;
+			devc->rport.sw_channels = 1;
+			devc->rport.sw_samplefmt = sw_samplefmt;
+			devc->rport.sw_framerate = 8000;
+			devc->rport.sw_fragshift = DEFAULT_FRAGSHIFT;
+			devc->rport.sw_fragcount = DEFAULT_FRAGCOUNT;
+			devc->rport.sw_subdivshift = DEFAULT_SUBDIVSHIFT;
+		}
+		if (file->f_mode & FMODE_WRITE) {
+			devc->wport.swstate = SW_INITIAL;
+			devc->wport.sw_channels = 1;
+			devc->wport.sw_samplefmt = sw_samplefmt;
+			devc->wport.sw_framerate = 8000;
+			devc->wport.sw_fragshift = DEFAULT_FRAGSHIFT;
+			devc->wport.sw_fragcount = DEFAULT_FRAGCOUNT;
+			devc->wport.sw_subdivshift = DEFAULT_SUBDIVSHIFT;
+		}
+	}
+	up(&devc->io_sema);
+
+	file->private_data = devc;
+	DBGRV();
+	return 0;
+}
+
+/*
+ * Release (close) the audio device.
+ */
+
+static int vwsnd_audio_release(struct inode *inode, struct file *file)
+{
+	vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
+	vwsnd_port_t *wport = NULL, *rport = NULL;
+	int err = 0;
+
+	down(&devc->io_sema);
+	{
+		DBGE("(inode=0x%p, file=0x%p)\n", inode, file);
+
+		if (file->f_mode & FMODE_READ)
+			rport = &devc->rport;
+		if (file->f_mode & FMODE_WRITE) {
+			wport = &devc->wport;
+			pcm_flush_frag(devc);
+			pcm_write_sync(devc);
+		}
+		pcm_shutdown(devc, rport, wport);
+		if (rport)
+			rport->swstate = SW_OFF;
+		if (wport)
+			wport->swstate = SW_OFF;
+	}
+	up(&devc->io_sema);
+
+	down(&devc->open_sema);
+	{
+		devc->open_mode &= ~file->f_mode;
+	}
+	up(&devc->open_sema);
+	wake_up(&devc->open_wait);
+	DBGDO(if (IN_USE))		/* see hack in vwsnd_mixer_release() */
+		DEC_USE_COUNT;
+	DBGR();
+	return err;
+}
+
+static struct file_operations vwsnd_audio_fops = {
+	&vwsnd_audio_llseek,
+	&vwsnd_audio_read,
+	&vwsnd_audio_write,
+	NULL,				/* readdir */
+	&vwsnd_audio_poll,
+	&vwsnd_audio_ioctl,
+	&vwsnd_audio_mmap,
+	&vwsnd_audio_open,
+	NULL,				/* flush */
+	&vwsnd_audio_release,
+	NULL,				/* fsync */
+	NULL,				/* fasync */
+	NULL,				/* check_media_change */
+	NULL,				/* revalidate */
+	NULL,				/* lock */
+};
+
+/*****************************************************************************/
+/* mixer driver */
+
+/* open the mixer device. */
+
+static int vwsnd_mixer_open(struct inode *inode, struct file *file)
+{
+	vwsnd_dev_t *devc;
+
+	DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
+
+	INC_USE_COUNT;
+	for (devc = vwsnd_dev_list; devc; devc = devc->next_dev)
+		if (devc->mixer_minor == MINOR(inode->i_rdev))
+			break;
+
+	if (devc == NULL) {
+		DEC_USE_COUNT;
+		return -ENODEV;
+	}
+	file->private_data = devc;
+	return 0;
+}
+
+/* release (close) the mixer device. */
+
+static int vwsnd_mixer_release(struct inode *inode, struct file *file)
+{
+	DBGEV("(inode=0x%p, file=0x%p)\n", inode, file);
+
+	/*
+	 * hack -- opening/closing the mixer device zeroes use count
+	 * so driver can be unloaded.
+	 * Use only while debugging module, and then use it carefully.
+	 */
+
+	DBGDO(while (IN_USE))
+		DEC_USE_COUNT;
+	return 0;
+}
+
+/* seek is illegal on mixer. */
+
+static loff_t vwsnd_mixer_llseek(struct file *file, loff_t offset, int whence)
+{
+	return -ESPIPE;
+}
+
+/* mixer_read_ioctl handles all read ioctls on the mixer device. */
+
+static int mixer_read_ioctl(vwsnd_dev_t *devc, unsigned int nr, caddr_t arg)
+{
+	int val = -1;
+
+	DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg);
+
+	switch (nr) {
+	case SOUND_MIXER_CAPS:
+		val = SOUND_CAP_EXCL_INPUT;
+		break;
+
+	case SOUND_MIXER_DEVMASK:
+		val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
+		       SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV);
+		break;
+
+	case SOUND_MIXER_STEREODEVS:
+		val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
+		       SOUND_MASK_MIC | SOUND_MASK_CD | SOUND_MASK_RECLEV);
+		break;
+
+	case SOUND_MIXER_OUTMASK:
+		val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
+		       SOUND_MASK_MIC | SOUND_MASK_CD);
+		break;
+
+	case SOUND_MIXER_RECMASK:
+		val = (SOUND_MASK_PCM | SOUND_MASK_LINE |
+		       SOUND_MASK_MIC | SOUND_MASK_CD);
+		break;
+
+	case SOUND_MIXER_PCM:
+		val = ad1843_get_gain(&devc->lith, &ad1843_gain_PCM);
+		break;
+
+	case SOUND_MIXER_LINE:
+		val = ad1843_get_gain(&devc->lith, &ad1843_gain_LINE);
+		break;
+
+	case SOUND_MIXER_MIC:
+		val = ad1843_get_gain(&devc->lith, &ad1843_gain_MIC);
+		break;
+
+	case SOUND_MIXER_CD:
+		val = ad1843_get_gain(&devc->lith, &ad1843_gain_CD);
+		break;
+
+	case SOUND_MIXER_RECLEV:
+		val = ad1843_get_gain(&devc->lith, &ad1843_gain_RECLEV);
+		break;
+
+	case SOUND_MIXER_RECSRC:
+		val = ad1843_get_recsrc(&devc->lith);
+		break;
+
+	case SOUND_MIXER_OUTSRC:
+		val = ad1843_get_outsrc(&devc->lith);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	return put_user(val, (int *) arg);
+}
+
+/* mixer_write_ioctl handles all write ioctls on the mixer device. */
+
+static int mixer_write_ioctl(vwsnd_dev_t *devc, unsigned int nr, caddr_t arg)
+{
+	int val;
+	int err;
+
+	DBGEV("(devc=0x%p, nr=0x%x, arg=0x%p)\n", devc, nr, arg);
+
+	err = get_user(val, (int *) arg);
+	if (err)
+		return -EFAULT;
+	switch (nr) {
+	case SOUND_MIXER_PCM:
+		val = ad1843_set_gain(&devc->lith, &ad1843_gain_PCM, val);
+		break;
+
+	case SOUND_MIXER_LINE:
+		val = ad1843_set_gain(&devc->lith, &ad1843_gain_LINE, val);
+		break;
+
+	case SOUND_MIXER_MIC:
+		val = ad1843_set_gain(&devc->lith, &ad1843_gain_MIC, val);
+		break;
+
+	case SOUND_MIXER_CD:
+		val = ad1843_set_gain(&devc->lith, &ad1843_gain_CD, val);
+		break;
+
+	case SOUND_MIXER_RECLEV:
+		val = ad1843_set_gain(&devc->lith, &ad1843_gain_RECLEV, val);
+		break;
+
+	case SOUND_MIXER_RECSRC:
+		if (devc->rport.swbuf || devc->wport.swbuf)
+			return -EBUSY;	/* can't change recsrc while running */
+		val = ad1843_set_recsrc(&devc->lith, val);
+		break;
+
+	case SOUND_MIXER_OUTSRC:
+		val = ad1843_set_outsrc(&devc->lith, val);
+		break;
+
+	default:
+		return -EINVAL;
+	}
+	if (val < 0)
+		return val;
+	return put_user(val, (int *) arg);
+}
+
+/* This is the ioctl entry to the mixer driver. */
+
+static int vwsnd_mixer_ioctl(struct inode *ioctl,
+			      struct file *file,
+			      unsigned int cmd,
+			      unsigned long arg)
+{
+	vwsnd_dev_t *devc = (vwsnd_dev_t *) file->private_data;
+	const unsigned int nrmask = _IOC_NRMASK << _IOC_NRSHIFT;
+	const unsigned int nr = (cmd & nrmask) >> _IOC_NRSHIFT;
+	int retval;
+
+	DBGEV("(devc=0x%p, cmd=0x%x, arg=0x%lx)\n", devc, cmd, arg);
+
+	down(&devc->mix_sema);
+	{
+		if ((cmd & ~nrmask) == MIXER_READ(0))
+			retval = mixer_read_ioctl(devc, nr, (caddr_t) arg);
+		else if ((cmd & ~nrmask) == MIXER_WRITE(0))
+			retval = mixer_write_ioctl(devc, nr, (caddr_t) arg);
+		else
+			retval = -EINVAL;
+	}
+	up(&devc->mix_sema);
+	return retval;
+}
+
+static struct file_operations vwsnd_mixer_fops = {
+	&vwsnd_mixer_llseek,
+	NULL,				/* read */
+	NULL,				/* write */
+	NULL,				/* readdir */
+	NULL,				/* poll */
+	&vwsnd_mixer_ioctl,
+	NULL,				/* mmap */
+	&vwsnd_mixer_open,
+	NULL,				/* flush */
+	&vwsnd_mixer_release,
+	NULL,				/* fsync */
+	NULL,				/* fasync */
+	NULL,				/* check_media_change */
+	NULL,				/* revalidate */
+	NULL,				/* lock */
+};
+
+/*****************************************************************************/
+/* probe/attach/unload */
+
+/* driver probe routine.  Return nonzero if hardware is found. */
+
+static int probe_vwsnd(struct address_info *hw_config)
+{
+	lithium_t lith;
+	int w;
+	unsigned long later;
+
+	DBGEV("(hw_config=0x%p)\n", hw_config);
+
+	/* XXX verify lithium present (to prevent crash on non-vw) */
+
+	if (li_create(&lith, hw_config->io_base) != 0) {
+		printk(KERN_WARNING "probe_vwsnd: can't map lithium\n");
+		return 0;
+	}
+	later = jiffies + 2;
+	li_writel(&lith, LI_HOST_CONTROLLER, LI_HC_LINK_ENABLE);
+	do {
+		w = li_readl(&lith, LI_HOST_CONTROLLER);
+	} while (w == LI_HC_LINK_ENABLE && jiffies < later);
+	
+	li_destroy(&lith);
+
+	DBGPV("HC = 0x%04x\n", w);
+
+	if ((w == LI_HC_LINK_ENABLE) || (w & LI_HC_LINK_CODEC)) {
+
+		/* This may indicate a beta machine with no audio,
+		 * or a future machine with different audio.
+		 * On beta-release 320 w/ no audio, HC == 0x4000 */
+
+		printk(KERN_WARNING "probe_vwsnd: audio codec not found\n");
+		return 0;
+	}
+
+	if (w & LI_HC_LINK_FAILURE) {
+		printk(KERN_WARNING "probe_vwsnd: can't init audio codec\n");
+		return 0;
+	}
+
+	printk(KERN_INFO "probe_vwsnd: lithium audio found\n");
+
+	return 1;
+}
+
+/*
+ * driver attach routine.  Initialize driver data structures and
+ * initialize hardware.  A new vwsnd_dev_t is allocated and put
+ * onto the global list, vwsnd_dev_list.
+ *
+ * Return +minor_dev on success, -errno on failure.
+ */
+
+static int attach_vwsnd(struct address_info *hw_config)
+{
+	vwsnd_dev_t *devc = NULL;
+	int err = -ENOMEM;
+
+	DBGEV("(hw_config=0x%p)\n", hw_config);
+
+	devc = kmalloc(sizeof (vwsnd_dev_t), GFP_KERNEL);
+	if (devc == NULL)
+		goto fail0;
+
+	err = li_create(&devc->lith, hw_config->io_base);
+	if (err)
+		goto fail1;
+
+	init_waitqueue(&devc->open_wait);
+
+	devc->rport.hwbuf_size = HWBUF_SIZE;
+	devc->rport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER);
+	if (!devc->rport.hwbuf_vaddr)
+		goto fail2;
+	devc->rport.hwbuf = (caddr_t) devc->rport.hwbuf_vaddr;
+	devc->rport.hwbuf_paddr = virt_to_phys(devc->rport.hwbuf);
+
+	/*
+	 * Quote from the NT driver:
+	 *
+	 * // WARNING!!! HACK to setup output dma!!!
+	 * // This is required because even on output there is some data
+	 * // trickling into the input DMA channel.  This is a bug in the
+	 * // Lithium microcode.
+	 * // --sde
+	 *
+	 * We set the input side's DMA base address here.  It will remain
+	 * valid until the driver is unloaded.
+	 */
+
+	li_writel(&devc->lith, LI_COMM1_BASE,
+		  devc->rport.hwbuf_paddr >> 8 | 1 << (37 - 8));
+
+	devc->wport.hwbuf_size = HWBUF_SIZE;
+	devc->wport.hwbuf_vaddr = __get_free_pages(GFP_KERNEL, HWBUF_ORDER);
+	if (!devc->wport.hwbuf_vaddr)
+		goto fail3;
+	devc->wport.hwbuf = (caddr_t) devc->wport.hwbuf_vaddr;
+	devc->wport.hwbuf_paddr = virt_to_phys(devc->wport.hwbuf);
+	DBGP("wport hwbuf = 0x%p\n", devc->wport.hwbuf);
+
+	DBGDO(shut_up++);
+	err = ad1843_init(&devc->lith);
+	DBGDO(shut_up--);
+	if (err)
+		goto fail4;
+
+	/* install interrupt handler */
+
+	err = request_irq(hw_config->irq, vwsnd_audio_intr, 0, "vwsnd", devc);
+	if (err)
+		goto fail5;
+
+	/* register this device's drivers. */
+
+	devc->audio_minor = register_sound_dsp(&vwsnd_audio_fops, -1);
+	if ((err = devc->audio_minor) < 0) {
+		DBGDO(printk(KERN_WARNING
+			     "attach_vwsnd: register_sound_dsp error %d\n",
+			     err));
+		goto fail6;
+	}
+	devc->mixer_minor = register_sound_mixer(&vwsnd_mixer_fops,
+						 devc->audio_minor >> 4);
+	if ((err = devc->mixer_minor) < 0) {
+		DBGDO(printk(KERN_WARNING
+			     "attach_vwsnd: register_sound_mixer error %d\n",
+			     err));
+		goto fail7;
+	}
+
+	/* Squirrel away device indices for unload routine. */
+
+	hw_config->slots[0] = devc->audio_minor;
+
+	/* Initialize as much of *devc as possible */
+
+	devc->open_sema = MUTEX;
+	devc->io_sema = MUTEX;
+	devc->mix_sema = MUTEX;
+	devc->open_mode = 0;
+	devc->rport.lock = SPIN_LOCK_UNLOCKED;
+	init_waitqueue(&devc->rport.queue);
+	devc->rport.swstate = SW_OFF;
+	devc->rport.hwstate = HW_STOPPED;
+	devc->rport.flags = 0;
+	devc->rport.swbuf = NULL;
+	devc->wport.lock = SPIN_LOCK_UNLOCKED;
+	init_waitqueue(&devc->wport.queue);
+	devc->wport.swstate = SW_OFF;
+	devc->wport.hwstate = HW_STOPPED;
+	devc->wport.flags = 0;
+	devc->wport.swbuf = NULL;
+
+	/* Success.  Link us onto the local device list. */
+
+	devc->next_dev = vwsnd_dev_list;
+	vwsnd_dev_list = devc;
+	return devc->audio_minor;
+
+	/* So many ways to fail.  Undo what we did. */
+
+ fail7:
+	unregister_sound_dsp(devc->audio_minor);
+ fail6:
+	free_irq(hw_config->irq, devc);
+ fail5:
+ fail4:
+	free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER);
+ fail3:
+	free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER);
+ fail2:
+	li_destroy(&devc->lith);
+ fail1:
+	kfree(devc);
+ fail0:
+	return err;
+}
+
+static int unload_vwsnd(struct address_info *hw_config)
+{
+	vwsnd_dev_t *devc, **devcp;
+
+	DBGE("()\n");
+
+	if (IN_USE)
+		return -EBUSY;
+	devcp = &vwsnd_dev_list;
+	while ((devc = *devcp)) {
+		if (devc->audio_minor == hw_config->slots[0]) {
+			*devcp = devc->next_dev;
+			break;
+		}
+		devcp = &devc->next_dev;
+	}
+
+	if (!devc)
+		return -ENODEV;
+
+	unregister_sound_mixer(devc->mixer_minor);
+	unregister_sound_dsp(devc->audio_minor);
+	free_irq(hw_config->irq, devc);
+	free_pages(devc->wport.hwbuf_vaddr, HWBUF_ORDER);
+	free_pages(devc->rport.hwbuf_vaddr, HWBUF_ORDER);
+	li_destroy(&devc->lith);
+	kfree(devc);
+
+	return 0;
+}
+
+/*****************************************************************************/
+/* initialization and loadable kernel module interface */
+
+static struct address_info the_hw_config = {
+	0xFF001000,			/* lithium phys addr  */
+	CO_IRQ(CO_APIC_LI_AUDIO)	/* irq */
+};
+
+#ifdef MODULE
+
+MODULE_DESCRIPTION("SGI Visual Workstation sound module");
+MODULE_AUTHOR("Bob Miller <kbob@sgi.com>");
+
+extern int init_module(void)
+{
+	int err;
+
+	DBGXV("\n");
+	DBGXV("sound::vwsnd::init_module()\n");
+
+	if(!probe_vwsnd(&the_hw_config))
+		return -ENODEV;
+	err = attach_vwsnd(&the_hw_config);
+	if (err < 0)
+		return err;
+	return 0;
+}
+
+extern void cleanup_module(void)
+{
+	DBGX("sound::vwsnd::cleanup_module()\n");
+
+	unload_vwsnd(&the_hw_config);
+}
+
+#else
+
+extern void init_vwsnd(void)
+{
+	DBGX("sound::vwsnd::init_vwsnd()\n");
+	if (probe_vwsnd(&the_hw_config))
+		(void) attach_vwsnd(&the_hw_config);
+}
+
+#endif /* !MODULE */
+
+/*
+ * Local variables:
+ * compile-command: "cd ../..; make modules SUBDIRS=drivers/sound"
+ * c-basic-offset: 8
+ * End:
+ */
diff -Naur linux.2210/drivers/usb/uhci.c linux.2210.vw/drivers/usb/uhci.c
--- linux.2210/drivers/usb/uhci.c	Fri Apr 30 08:20:53 1999
+++ linux.2210.vw/drivers/usb/uhci.c	Wed Jul 28 08:56:42 1999
@@ -624,7 +624,9 @@
 	struct uhci_device *dev;
 	unsigned short status;
 
+#if 0
 	printk("uhci_connect_change: called for %d\n", nr);
+#endif
 
 	/*
 	 * Even if the status says we're connected,
diff -Naur linux.2210/drivers/usb/usb.c linux.2210.vw/drivers/usb/usb.c
--- linux.2210/drivers/usb/usb.c	Fri May  7 15:16:04 1999
+++ linux.2210.vw/drivers/usb/usb.c	Wed Jul 28 08:56:42 1999
@@ -124,22 +124,28 @@
 			
 		if (n_len < 2 || n_len > len)
 		{
+#if 0
 			printk("Short descriptor.\n");
+#endif
 			return -1;
 		}
+#if 0
 		printk(
 		"Expected descriptor %02X/%02X, got %02X/%02X - skipping\n",
 			desctype, descindex,
 			(n_desc >> 8) & 0xFF, n_desc & 0xFF);
 		for (i = 0 ; i < n_len; i++)
 			printk("   %d %02x\n", i, ptr[i]);
+#endif
 		len -= n_len;
 		ptr += n_len;
 		parsed += n_len;
 	}
 	
+#if 0
 	printk("Found %02X:%02X\n",
 		desctype, descindex);
+#endif
 	return parsed;
 }
 
@@ -154,7 +160,9 @@
 
 	if (n_len < 2 || n_len > len)
 	{
+#if 0
 		printk("Short descriptor.\n");
+#endif
 		return -1;
 	}
 
@@ -604,8 +612,10 @@
 {
 	int addr, i;
 
+#if 0
 	printk("USB new device connect, assigned device number %d\n",
 		dev->devnum);
+#endif
 
 	dev->maxpacketsize = 0;		/* Default to 8 byte max packet size */
 
diff -Naur linux.2210/drivers/video/Config.in linux.2210.vw/drivers/video/Config.in
--- linux.2210/drivers/video/Config.in	Tue May 11 16:30:36 1999
+++ linux.2210.vw/drivers/video/Config.in	Wed Jul 28 08:56:42 1999
@@ -78,6 +78,7 @@
   fi
   if [ "$CONFIG_VISWS" = "y" ]; then
     tristate 'SGI Visual Workstation framebuffer support' CONFIG_FB_SGIVW
+    define_bool CONFIG_BUS_I2C y
   fi
   if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
     if [ "$CONFIG_PCI" != "n" ]; then
diff -Naur linux.2210/drivers/video/Makefile linux.2210.vw/drivers/video/Makefile
--- linux.2210/drivers/video/Makefile	Tue May 11 16:30:36 1999
+++ linux.2210.vw/drivers/video/Makefile	Wed Jul 28 08:56:42 1999
@@ -141,10 +141,10 @@
 endif
 
 ifeq ($(CONFIG_FB_SGIVW),y)
-L_OBJS += sgivwfb.o
+LX_OBJS += sgivwfb.o
 else
   ifeq ($(CONFIG_FB_SGIVW),m)
-  M_OBJS += sgivwfb.o
+  MX_OBJS += sgivwfb.o
   endif
 endif
 
diff -Naur linux.2210/drivers/video/sgivwfb.c linux.2210.vw/drivers/video/sgivwfb.c
--- linux.2210/drivers/video/sgivwfb.c	Fri Apr 16 08:20:23 1999
+++ linux.2210.vw/drivers/video/sgivwfb.c	Wed Jul 28 08:56:42 1999
@@ -1,8 +1,8 @@
 /*
  *  linux/drivers/video/sgivwfb.c -- SGI DBE frame buffer device
  *
- *	Copyright (C) 1999 Silicon Graphics, Inc.
- *      Jeffrey Newquist, newquist@engr.sgi.som
+ *      Copyright (C) 1999 Silicon Graphics, Inc.
+ *      Jeffrey Newquist, newquist@engr.sgi.com
  *
  *  This file is subject to the terms and conditions of the GNU General Public
  *  License. See the file COPYING in the main directory of this archive for
@@ -25,32 +25,63 @@
 #include <linux/init.h>
 #include <asm/io.h>
 #include <asm/mtrr.h>
+#include <linux/i2c.h>
 
 #include <video/fbcon.h>
 #include <video/fbcon-cfb8.h>
 #include <video/fbcon-cfb16.h>
 #include <video/fbcon-cfb32.h>
 
-#define INCLUDE_TIMING_TABLE_DATA
 #define DBE_REG_BASE regs
-#include "sgivwfb.h"
+#include <asm/sgi-vwdbe.h>
+
+#define FLATPANEL_SGI_1600SW 5
+
+/*
+ * Video Timing Data Structure
+ */
+
+typedef struct dbe_timing_info
+{
+  int flags;
+  short width;              /* Monitor resolution               */
+  short height;
+  int cfreq;                /* pixel clock frequency (KHz) */
+  short htotal;             /* Horizontal total pixels  */
+  short hblank_start;   /* Horizontal blank start       */
+  short hblank_end;         /* Horizontal blank end             */
+  short hsync_start;    /* Horizontal sync start        */
+  short hsync_end;          /* Horizontal sync end              */
+  short vtotal;             /* Vertical total lines             */
+  short vblank_start;   /* Vertical blank start         */
+  short vblank_end;         /* Vertical blank end               */
+  short vsync_start;    /* Vertical sync start          */
+  short vsync_end;          /* Vertical sync end                */
+  short pll_m;              /* PLL M parameter          */
+  short pll_n;              /* PLL P parameter          */
+  short pll_p;              /* PLL N parameter          */
+} dbe_timing_info_t;
 
 struct sgivwfb_par {
   struct fb_var_screeninfo var;
-  u_long timing_num;
+  dbe_timing_info_t timing;
   int valid;
 };
 
+struct i2c_private {
+    int sda;
+    int scl;
+    volatile u32 *reg;
+};
+
 /*
  *  RAM we reserve for the frame buffer. This defines the maximum screen
  *  size
- *
- *  The default can be overridden if the driver is compiled as a module
  */
 
-/* set by arch/i386/kernel/setup.c */
-u_long                sgivwfb_mem_phys;
-u_long                sgivwfb_mem_size;
+/* setup by arch/i386/kernel/setup.c */
+extern u_long         sgivw_gfx_mem_phys;
+extern u_long         sgivw_gfx_mem_size;
 
 static volatile char  *fbmem;
 static asregs         *regs;
@@ -60,6 +91,7 @@
 static u32            cmap_fifo;
 static int            ypan       = 0;
 static int            ywrap      = 0;
+static int            flatpanel_id = -1;
 
 /* console related variables */
 static int currcon = 0;
@@ -75,15 +107,27 @@
 } fbcon_cmap;
 
 static struct sgivwfb_par par_current = {
-  {                             /* var (screeninfo) */
-    /* 640x480, 8 bpp */
-    640, 480, 640, 480, 0, 0, 8, 0,
+  { /* var (screeninfo) */
+    /* 800x600, 8 bpp */
+    800, 600, 800, 600, 0, 0, 8, 0,
     {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
-    0, 0, -1, -1, 0, 20000, 64, 64, 32, 32, 64, 2,
-    0, FB_VMODE_NONINTERLACED
+    0, 0, -1, -1, 0,
+    25000, 88, 40, 23, 1, 128, 4,
+    FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
+  },
+  { /* timing (dbe_timing_info_t) */
+    0,
   },
-  0,                            /* timing_num */
-  0				/* par not activated */
+  0     /* par not activated */
+};
+
+struct fb_var_screeninfo SGI_1600SW_TIMING = 
+{
+    1600, 1024, 1600, 1024, 0, 0, 8, 0,
+    {0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},
+    0, 0, -1, -1, 0,
+    9353, 20, 30, 37, 3, 20, 3,
+    0, FB_VMODE_NONINTERLACED
 };
 
 /*
@@ -94,19 +138,19 @@
 static int sgivwfb_open(struct fb_info *info, int user);
 static int sgivwfb_release(struct fb_info *info, int user);
 static int sgivwfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			   struct fb_info *info);
+                           struct fb_info *info);
 static int sgivwfb_get_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info);
+                           struct fb_info *info);
 static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info);
+                           struct fb_info *info);
 static int sgivwfb_pan_display(struct fb_var_screeninfo *var, int con,
-			       struct fb_info *info);
+                               struct fb_info *info);
 static int sgivwfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info);
+                            struct fb_info *info);
 static int sgivwfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info);
+                            struct fb_info *info);
 static int sgivwfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			 u_long arg, int con, struct fb_info *info);
+                         u_long arg, int con, struct fb_info *info);
 static int sgivwfb_mmap(struct fb_info *info, struct file *file,
                         struct vm_area_struct *vma);
 
@@ -123,6 +167,37 @@
   sgivwfb_mmap
 };
 
+/* i2c bus functions */
+static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data);
+static int i2c_getdataline(struct i2c_bus *bus);
+static int i2c_flatpanel_status(struct i2c_bus *bus);
+static int i2c_flatpanel_id(struct i2c_bus *bus);
+static int i2c_flatpanel_power(struct i2c_bus *bus, int flag);
+
+static struct i2c_bus sgivwfb_i2c_bus_template = 
+{
+        "sgivwfb",
+        I2C_BUSID_SGIVWFB,
+        NULL,
+
+#if LINUX_VERSION_CODE >= 0x020100
+        SPIN_LOCK_UNLOCKED,
+#endif
+
+        NULL,
+        NULL,
+        
+        i2c_setlines,
+        i2c_getdataline,
+        NULL,
+        NULL,
+};
+
+static struct i2c_private flatpanel_i2c =
+{
+    0, 0, NULL
+};
+
 /*
  *  Interface to the low level console driver
  */
@@ -138,11 +213,11 @@
 static unsigned long bytes_per_pixel(int bpp);
 static void activate_par(struct sgivwfb_par *par);
 static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
-			       struct fb_var_screeninfo *var);
+                               struct fb_var_screeninfo *var);
 static int sgivwfb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,
-			     u_int *transp, struct fb_info *info);
+                             u_int *transp, struct fb_info *info);
 static int sgivwfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
-			     u_int transp, struct fb_info *info);
+                             u_int transp, struct fb_info *info);
 static void do_install_cmap(int con, struct fb_info *info);
 
 static unsigned long get_line_length(int xres_virtual, int bpp)
@@ -158,6 +233,7 @@
   case 8:
     length = 1;
     break;
+  case 15:
   case 16:
     length = 2;
     break;
@@ -173,9 +249,52 @@
 }
 
 /*
- * Function:	dbe_TurnOffDma
- * Parameters:	(None)
- * Description:	This should turn off the monitor and dbe.  This is used
+ * Function:    dbe_CalcClock
+ * Parameters:  Target clock and pointers to PLL parameter destinations
+ * Description: Calculate DBE PLL parameters which give dot clock closest
+ *              to requested TargetClock.  Attempt to make this reasonably
+ *              efficient by skipping obviously wrong parameters.
+ */
+
+static int
+dbe_CalcClock(int TargetClock, short *M, short *N, short *P)
+{
+  short m, n, p;
+  int mBase, nBase, TestClock, PickClock=0, delta, minDelta=10000;
+
+  if (TargetClock > 256*DBE_CLOCK_REF_KHZ)
+    return 0;
+  
+  for (m=TargetClock/DBE_CLOCK_REF_KHZ; m<=256; m++) {
+    mBase = m * DBE_CLOCK_REF_KHZ;
+    for (n=1; n<=64; n++) {
+      nBase = mBase/n;
+      for (p=0; p<=3; p++) {
+        TestClock = nBase>>p;
+        delta = TestClock-TargetClock;
+        if (delta<0)
+          delta = -delta;
+        if (delta < minDelta) {
+          minDelta = delta;
+          PickClock = TestClock;
+          *M = m;
+          *N = n;
+          *P = p;
+        }
+        if (TestClock < TargetClock)
+          break; /* Only going to get smaller, so break this loop */
+      }
+      if (nBase < TargetClock)
+        break; /* Only going to get smaller, so break this loop */
+    }
+  }
+  return PickClock;
+}
+
+/*
+ * Function:    dbe_TurnOffDma
+ * Parameters:  (None)
+ * Description: This should turn off the monitor and dbe.  This is used
  *              when switching between the serial console and the graphics
  *              console.
  */
@@ -246,7 +365,7 @@
  */
 static void activate_par(struct sgivwfb_par *par)
 {
-  int i,j, htmp, temp;
+  int i,j, htmp, temp, fp_wid, fp_hgt, fp_vbs, fp_vbe;
   u32 readVal, outputVal;
   int wholeTilesX, maxPixelsPerTileX;
   int frmWrite1, frmWrite2, frmWrite3b;
@@ -254,7 +373,7 @@
   int xpmax, ypmax;                       // Monitor resolution
   int bytesPerPixel;                      // Bytes per pixel
 
-  currentTiming = &dbeVTimings[par->timing_num];
+  currentTiming = &par->timing;
   bytesPerPixel = bytes_per_pixel(par->var.bits_per_pixel);
   xpmax = currentTiming->width;
   ypmax = currentTiming->height;
@@ -271,9 +390,6 @@
   if (wholeTilesX*maxPixelsPerTileX < xpmax)
     wholeTilesX++;
 
-  printk("sgivwfb: pixPerTile=%d wholeTilesX=%d\n",
-	 maxPixelsPerTileX, wholeTilesX);
-
   /* dbe_InitGammaMap(); */
   udelay(10);
 
@@ -293,6 +409,7 @@
     dbe_TurnOffDma();
 
   /* dbe_Initdbe(); */
+  DBE_SETREG(config, DBE_CONFIG_FBDEV);
   for (i = 0; i < 256; i++)
     {
       for (j = 0; j < 100; j++)
@@ -332,7 +449,7 @@
   // Tell dbe about the framebuffer location and type
   // XXX What format is the FRM_TILE_PTR??  64K aligned address?
   frmWrite3b = 0;
-  SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b, sgivwfb_mem_phys>>9);
+  SET_DBE_FIELD(FRM_CONTROL, FRM_TILE_PTR, frmWrite3b, sgivw_gfx_mem_phys>>9);
   SET_DBE_FIELD(FRM_CONTROL, FRM_DMA_ENABLE, frmWrite3b, 1);
   SET_DBE_FIELD(FRM_CONTROL, FRM_LINEAR, frmWrite3b, 1);
 
@@ -345,7 +462,7 @@
         SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_I8);
         break;
       case 2:
-        SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGBA5);
+        SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_ARGB5);
         break;
       case 4:
         SET_DBE_FIELD(WID, TYP, outputVal, DBE_CMODE_RGB8);
@@ -392,6 +509,38 @@
   DBE_SETREG(vt_hcmap, outputVal);
 
   outputVal = 0;
+  SET_DBE_FIELD(VT_FLAGS, HDRV_INVERT, outputVal, 
+    (currentTiming->flags & FB_SYNC_HOR_HIGH_ACT) ? 0 : 1);
+  SET_DBE_FIELD(VT_FLAGS, VDRV_INVERT, outputVal, 
+    (currentTiming->flags & FB_SYNC_VERT_HIGH_ACT) ? 0 : 1);
+  DBE_SETREG(vt_flags, outputVal);
+
+  /* Turn on the flat panel */
+  switch(flatpanel_id) {
+    case FLATPANEL_SGI_1600SW:
+      fp_wid=1600; fp_hgt=1024; fp_vbs=0; fp_vbe=1600;
+      currentTiming->pll_m = 4;
+      currentTiming->pll_n = 1;
+      currentTiming->pll_p = 0;
+      break;
+    default:
+      fp_wid=0xfff; fp_hgt=0xfff; fp_vbs=0xfff; fp_vbe=0xfff;
+      break;
+  }
+
+  outputVal = 0;
+  SET_DBE_FIELD(FP_DE, FP_DE_ON, outputVal, fp_vbs);
+  SET_DBE_FIELD(FP_DE, FP_DE_OFF, outputVal, fp_vbe);
+  DBE_SETREG(fp_de, outputVal);
+  outputVal = 0;
+  SET_DBE_FIELD(FP_HDRV, FP_HDRV_OFF, outputVal, fp_wid);
+  DBE_SETREG(fp_hdrv, outputVal);
+  outputVal = 0;
+  SET_DBE_FIELD(FP_VDRV, FP_VDRV_ON, outputVal, 1);
+  SET_DBE_FIELD(FP_VDRV, FP_VDRV_OFF, outputVal, fp_hgt+1);
+  DBE_SETREG(fp_vdrv, outputVal);
+
+  outputVal = 0;
   temp = currentTiming->vblank_start - currentTiming->vblank_end - 1;
   if (temp > 0)
     temp = -temp;
@@ -490,6 +639,17 @@
   DBE_GETREG(ctrlstat, readVal);
   readVal &= 0x02000000;
 
+  if (flatpanel_id != -1) {
+    // Turn on half-phase & enable FP signals
+    DBE_GETREG(config, readVal);
+    readVal |= 1<<3;
+    DBE_SETREG(config, readVal);
+
+    DBE_GETREG(ctrlstat, readVal);
+    readVal |= 1<<26;
+    DBE_SETREG(ctrlstat, readVal);
+  }
+
   if (readVal != 0)
     {
       DBE_SETREG(ctrlstat, 0x30000000);
@@ -497,12 +657,12 @@
 }
 
 static void sgivwfb_encode_fix(struct fb_fix_screeninfo *fix,
-			       struct fb_var_screeninfo *var)
+                               struct fb_var_screeninfo *var)
 {
   memset(fix, 0, sizeof(struct fb_fix_screeninfo));
   strcpy(fix->id, sgivwfb_name);
-  fix->smem_start = (char *) sgivwfb_mem_phys;
-  fix->smem_len = sgivwfb_mem_size;
+  fix->smem_start = (char *) sgivw_gfx_mem_phys;
+  fix->smem_len = sgivw_gfx_mem_size;
   fix->type = FB_TYPE_PACKED_PIXELS;
   fix->type_aux = 0;
   switch (var->bits_per_pixel) {
@@ -561,19 +721,19 @@
     cmap_fifo = regs->cm_fifo;
 
   regs->cmap[regno] = (red << 24) | (green << 16) | (blue << 8);
-  cmap_fifo--;			/* assume FIFO is filling up */
+  cmap_fifo--;                  /* assume FIFO is filling up */
   return 0;
 }
 
 static void do_install_cmap(int con, struct fb_info *info)
 {
     if (con != currcon)
-	return;
+        return;
     if (fb_display[con].cmap.len)
-	fb_set_cmap(&fb_display[con].cmap, 1, sgivwfb_setcolreg, info);
+        fb_set_cmap(&fb_display[con].cmap, 1, sgivwfb_setcolreg, info);
     else
-	fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1,
-		    sgivwfb_setcolreg, info);
+        fb_set_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel), 1,
+                    sgivwfb_setcolreg, info);
 }
 
 /* ---------------------------------------------------- */
@@ -600,7 +760,7 @@
  *  Get the Fixed Part of the Display
  */
 static int sgivwfb_get_fix(struct fb_fix_screeninfo *fix, int con,
-			   struct fb_info *info)
+                           struct fb_info *info)
 {
   struct fb_var_screeninfo *var;
 
@@ -616,7 +776,7 @@
  *  Get the User Defined Part of the Display. If a real par get it form there
  */
 static int sgivwfb_get_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info)
+                           struct fb_info *info)
 {
   if (con == -1)
     *var = par_current.var;
@@ -630,23 +790,22 @@
  *  real video mode.
  */
 static int sgivwfb_set_var(struct fb_var_screeninfo *var, int con,
-			   struct fb_info *info)
+                           struct fb_info *info)
 {
   int err, activate = var->activate;
   int oldxres, oldyres, oldvxres, oldvyres, oldbpp;
   u_long line_length;
-  u_long min_mode;
   int req_dot;
-  int test_mode;
+  u32 bpp;
 
-  struct dbe_timing_info *timing;
+  struct dbe_timing_info timing;
 
   struct display *display;
 
   if (con >= 0)
     display = &fb_display[con];
   else
-    display = &disp;	/* used during initialization */
+    display = &disp;    /* used during initialization */
 
   /*
    *  FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal!
@@ -663,9 +822,11 @@
   var->xoffset = 0;
   var->yoffset = 0;
 
-  /* Limit bpp to 8, 16, and 32 */
+  /* Limit bpp to 8, 15/16, and 32 */
   if (var->bits_per_pixel <= 8)
     var->bits_per_pixel = 8;
+  else if (var->bits_per_pixel <= 15)
+    var->bits_per_pixel = 15;
   else if (var->bits_per_pixel <= 16)
     var->bits_per_pixel = 16;
   else if (var->bits_per_pixel <= 32)
@@ -676,31 +837,33 @@
   var->grayscale = 0;           /* No grayscale for now */
 
   /* determine valid resolution and timing */
-  for (min_mode=0; min_mode<DBE_VT_SIZE; min_mode++) {
-    if (dbeVTimings[min_mode].width >= var->xres &&
-        dbeVTimings[min_mode].height >= var->yres)
-      break;
-  }
-
-  if (min_mode == DBE_VT_SIZE)
-    return -EINVAL;             /* Resolution to high */
-
-  /* XXX FIXME - should try to pick best refresh rate */
-  /* for now, pick closest dot-clock within 3MHz*/
-  req_dot = (int)((1.0e3/1.0e6) / (1.0e-12 * (float)var->pixclock));
-  printk("sgivwfb: requested pixclock=%d ps (%d KHz)\n", var->pixclock,
-	 req_dot);
-  test_mode=min_mode;
-  while (dbeVTimings[min_mode].width == dbeVTimings[test_mode].width) {
-    if (dbeVTimings[test_mode].cfreq+3000 > req_dot)
+  /* XXX FIXME: Needs sanity check */
+  switch (flatpanel_id) {
+    case FLATPANEL_SGI_1600SW:
+      bpp = var->bits_per_pixel;
+      *var = SGI_1600SW_TIMING;
+      var->bits_per_pixel = bpp;
       break;
-    test_mode++;
+    default:
+      flatpanel_id = -1;
   }
-  if (dbeVTimings[min_mode].width != dbeVTimings[test_mode].width)
-    test_mode--;
-  min_mode = test_mode;
-  timing = &dbeVTimings[min_mode];
-  printk("sgivwfb: granted dot-clock=%d KHz\n", timing->cfreq);
+  req_dot = 1000000000 / var->pixclock;
+  req_dot = dbe_CalcClock(req_dot, &timing.pll_m, &timing.pll_n, &timing.pll_p);
+  var->pixclock = 1000000000 / req_dot;
+  timing.flags = var->sync;
+  timing.width = var->xres;
+  timing.height = var->yres;
+  timing.cfreq = req_dot;
+  timing.htotal = var->left_margin + var->xres + var->right_margin + var->hsync_len;
+  timing.hblank_start = var->xres;
+  timing.hblank_end = timing.htotal;
+  timing.hsync_start = var->xres + var->right_margin;
+  timing.hsync_end = timing.hsync_start + var->hsync_len;
+  timing.vtotal = var->upper_margin + var->yres + var->lower_margin + var->vsync_len;
+  timing.vblank_start = var->yres;
+  timing.vblank_end = timing.vtotal;
+  timing.vsync_start = var->yres + var->lower_margin;
+  timing.vsync_end = timing.vsync_start + var->vsync_len;
 
   /* Adjust virtual resolution, if necessary */
   if (var->xres > var->xres_virtual || (!ywrap && !ypan))
@@ -712,7 +875,7 @@
    *  Memory limit
    */
   line_length = get_line_length(var->xres_virtual, var->bits_per_pixel);
-  if (line_length*var->yres_virtual > sgivwfb_mem_size)
+  if (line_length*var->yres_virtual > sgivw_gfx_mem_size)
     return -ENOMEM;             /* Virtual resolution to high */
 
   switch (var->bits_per_pixel)
@@ -727,24 +890,25 @@
       var->transp.offset = 0;
       var->transp.length = 0;
       break;
-    case 16:	/* RGBA 5551 */
-      var->red.offset = 11;
+    case 15:    /* ARGB 1555 */
+    case 16:    /* ARGB 1555 */
+      var->red.offset = 10;
       var->red.length = 5;
-      var->green.offset = 6;
+      var->green.offset = 5;
       var->green.length = 5;
-      var->blue.offset = 1;
+      var->blue.offset = 0;
       var->blue.length = 5;
-      var->transp.offset = 0;
-      var->transp.length = 0;
+      var->transp.offset = 15;
+      var->transp.length = 1;
       break;
-    case 32:	/* RGB 8888 */
-      var->red.offset = 0;
+    case 32:    /* RGBA 8888 */
+      var->red.offset = 24;
       var->red.length = 8;
-      var->green.offset = 8;
+      var->green.offset = 16;
       var->green.length = 8;
-      var->blue.offset = 16;
+      var->blue.offset = 8;
       var->blue.length = 8;
-      var->transp.offset = 24;
+      var->transp.offset = 0;
       var->transp.length = 8;
       break;
     }
@@ -753,15 +917,6 @@
   var->blue.msb_right = 0;
   var->transp.msb_right = 0;
 
-  /* set video timing information */
-  var->pixclock = (__u32)(1.0e+9/(float)timing->cfreq);
-  var->left_margin = timing->htotal - timing->hsync_end;
-  var->right_margin = timing->hsync_start - timing->width;
-  var->upper_margin = timing->vtotal - timing->vsync_end;
-  var->lower_margin = timing->vsync_start - timing->height;
-  var->hsync_len = timing->hsync_end - timing->hsync_start;
-  var->vsync_len = timing->vsync_end -  timing->vsync_start;
-
   if ((activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) {
     oldxres = display->var.xres;
     oldyres = display->var.yres;
@@ -770,15 +925,15 @@
     oldbpp = display->var.bits_per_pixel;
     display->var = *var;
     par_current.var = *var;
-    par_current.timing_num = min_mode;
+    par_current.timing = timing;
     if (oldxres != var->xres || oldyres != var->yres ||
-	oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
-	oldbpp != var->bits_per_pixel || !par_current.valid) {
+        oldvxres != var->xres_virtual || oldvyres != var->yres_virtual ||
+        oldbpp != var->bits_per_pixel || !par_current.valid) {
       struct fb_fix_screeninfo fix;
       printk("sgivwfb: new video mode xres=%d yres=%d bpp=%d\n",
-	     var->xres, var->yres, var->bits_per_pixel);
+             var->xres, var->yres, var->bits_per_pixel);
       printk("         vxres=%d vyres=%d\n",
-	     var->xres_virtual, var->yres_virtual);
+             var->xres_virtual, var->yres_virtual);
       activate_par(&par_current);
       sgivwfb_encode_fix(&fix, var);
       display->screen_base = (char *)fbmem;
@@ -791,35 +946,35 @@
       display->can_soft_blank = 1;
       display->inverse = 0;
       if (oldbpp != var->bits_per_pixel || !par_current.valid) {
-	if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
-	  return err;
-	do_install_cmap(con, info);
+        if ((err = fb_alloc_cmap(&display->cmap, 0, 0)))
+          return err;
+        do_install_cmap(con, info);
       }
       switch (var->bits_per_pixel) {
 #ifdef FBCON_HAS_CFB8
       case 8:
-	display->dispsw = &fbcon_cfb8;
-	break;
+        display->dispsw = &fbcon_cfb8;
+        break;
 #endif
 #ifdef FBCON_HAS_CFB16
       case 16:
-	display->dispsw = &fbcon_cfb16;
-	display->dispsw_data = fbcon_cmap.cfb16;
-	break;
+        display->dispsw = &fbcon_cfb16;
+        display->dispsw_data = fbcon_cmap.cfb16;
+        break;
 #endif
 #ifdef FBCON_HAS_CFB32
       case 32:
-	display->dispsw = &fbcon_cfb32;
-	display->dispsw_data = fbcon_cmap.cfb32;
-	break;
+        display->dispsw = &fbcon_cfb32;
+        display->dispsw_data = fbcon_cmap.cfb32;
+        break;
 #endif
       default:
-	display->dispsw = &fbcon_dummy;
-	break;
+        display->dispsw = &fbcon_dummy;
+        break;
       }
       par_current.valid = 1;
       if (fb_info.changevar)
-	(*fb_info.changevar)(con);
+        (*fb_info.changevar)(con);
     }
   }
   return 0;
@@ -832,19 +987,19 @@
  */
 
 static int sgivwfb_pan_display(struct fb_var_screeninfo *var, int con,
-			       struct fb_info *info)
+                               struct fb_info *info)
 {
 #if 0
   if (var->vmode & FB_VMODE_YWRAP) {
     if (var->yoffset < 0 ||
-	var->yoffset >= fb_display[con].var.yres_virtual ||
-	var->xoffset)
+        var->yoffset >= fb_display[con].var.yres_virtual ||
+        var->xoffset)
       return -EINVAL;
   } else {
     if (var->xoffset+fb_display[con].var.xres >
-	fb_display[con].var.xres_virtual ||
-	var->yoffset+fb_display[con].var.yres >
-	fb_display[con].var.yres_virtual)
+        fb_display[con].var.xres_virtual ||
+        var->yoffset+fb_display[con].var.yres >
+        fb_display[con].var.yres_virtual)
       return -EINVAL;
   }
   fb_display[con].var.xoffset = var->xoffset;
@@ -862,7 +1017,7 @@
  *  Get the Colormap
  */
 static int sgivwfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info)
+                            struct fb_info *info)
 {
   if (con == currcon) /* current console? */
     return fb_get_cmap(cmap, kspc, sgivwfb_getcolreg, info);
@@ -870,7 +1025,7 @@
     fb_copy_cmap(&fb_display[con].cmap, cmap, kspc ? 0 : 2);
   else
     fb_copy_cmap(fb_default_cmap(1<<fb_display[con].var.bits_per_pixel),
-		 cmap, kspc ? 0 : 2);
+                 cmap, kspc ? 0 : 2);
   return 0;
 }
 
@@ -878,16 +1033,16 @@
  *  Set the Colormap
  */
 static int sgivwfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,
-			    struct fb_info *info)
+                            struct fb_info *info)
 {
   int err;
 
-  if (!fb_display[con].cmap.len) {	/* no colormap allocated? */
+  if (!fb_display[con].cmap.len) {      /* no colormap allocated? */
     if ((err = fb_alloc_cmap(&fb_display[con].cmap,
-			     1<<fb_display[con].var.bits_per_pixel, 0)))
+                             1<<fb_display[con].var.bits_per_pixel, 0)))
       return err;
   }
-  if (con == currcon)			/* current console? */
+  if (con == currcon)                   /* current console? */
     return fb_set_cmap(cmap, kspc, sgivwfb_setcolreg, info);
   else
     fb_copy_cmap(cmap, &fb_display[con].cmap, kspc ? 0 : 1);
@@ -898,7 +1053,7 @@
  *  Virtual Frame Buffer Specific ioctls
  */
 static int sgivwfb_ioctl(struct inode *inode, struct file *file, u_int cmd,
-			 u_long arg, int con, struct fb_info *info)
+                         u_long arg, int con, struct fb_info *info)
 {
   return -EINVAL;
 }
@@ -907,15 +1062,14 @@
                         struct vm_area_struct *vma)
 {
   unsigned long size = vma->vm_end - vma->vm_start;
-  unsigned long offset = sgivwfb_mem_phys + vma->vm_offset;
-  if (vma->vm_offset+size > sgivwfb_mem_size)
+  unsigned long offset = sgivw_gfx_mem_phys + vma->vm_offset;
+  if (vma->vm_offset+size > sgivw_gfx_mem_size)
     return -EINVAL;
   pgprot_val(vma->vm_page_prot) = pgprot_val(vma->vm_page_prot) | _PAGE_PCD;
   vma->vm_flags |= VM_IO;
   if (remap_page_range(vma->vm_start, offset, size, vma->vm_page_prot))
     return -EAGAIN;
   vma->vm_file = file;
-  printk("sgivwfb: mmap framebuffer P(%lx)->V(%lx)\n", offset, vma->vm_start);
   return 0;
 }
 
@@ -936,12 +1090,12 @@
 }
 
 /*
- *  Initialisation
+ *  Initialization
  */
 __initfunc(void sgivwfb_init(void))
 {
   printk("sgivwfb: framebuffer at 0x%lx, size %ldk\n",
-	 sgivwfb_mem_phys, sgivwfb_mem_size/1024);
+         sgivw_gfx_mem_phys, sgivw_gfx_mem_size/1024);
 
   regs = (asregs*)ioremap_nocache(DBE_REG_PHYS, DBE_REG_SIZE);
   if (!regs) {
@@ -950,7 +1104,7 @@
   }
 
 #ifdef CONFIG_MTRR
-  mtrr_add((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size, MTRR_TYPE_WRCOMB, 1);
+  mtrr_add((unsigned long)sgivw_gfx_mem_phys, sgivw_gfx_mem_size, MTRR_TYPE_WRCOMB, 1);
 #endif
 
   strcpy(fb_info.modename, sgivwfb_name);
@@ -963,12 +1117,37 @@
   fb_info.blank = &sgivwfbcon_blank;
   fb_info.flags = FBINFO_FLAG_DEFAULT;
 
-  fbmem = ioremap_nocache((unsigned long)sgivwfb_mem_phys, sgivwfb_mem_size);
+  fbmem = ioremap_nocache((unsigned long)sgivw_gfx_mem_phys, sgivw_gfx_mem_size);
   if (!fbmem) {
     printk("sgivwfb: couldn't ioremap fbmem\n");
     goto fail_ioremap_fbmem;
   }
+  
+  /* setup i2c support, set idle condition on i2c bus */
+  flatpanel_i2c.reg = &regs->i2cfp;
+  sgivwfb_i2c_bus_template.data = (void*)&flatpanel_i2c;
+  i2c_setlines(&sgivwfb_i2c_bus_template, 1, 1);
+  if (i2c_register_bus(&sgivwfb_i2c_bus_template)) {
+    printk("sgivwfb: couldn't register i2c bus\n");
+  }
 
+  /* query flatpanel */
+  flatpanel_id = i2c_flatpanel_id(&sgivwfb_i2c_bus_template);
+  if (flatpanel_id == -1)
+    printk("sgivwfb: flatpanel not detected.\n");
+  else {
+    switch (flatpanel_id) {
+      case FLATPANEL_SGI_1600SW:
+        printk("sgivwfb: SGI 1600SW flatpanel detected (excellent choice).\n");
+        break;
+      default:
+        // XXX TODO: query panel for resolution?
+        printk("sgivwfb: Unknown flatpanel type %d detected.\n", flatpanel_id);
+        flatpanel_id = -1; //ignore it for now
+        break;
+    }
+  }
+ 
   /* turn on default video mode */
   sgivwfb_set_var(&par_current.var, -1, &fb_info);
 
@@ -978,7 +1157,7 @@
   }
 
   printk("fb%d: Virtual frame buffer device, using %ldK of video memory\n",
-	 GET_FB_IDX(fb_info.node), sgivwfb_mem_size>>10);
+         GET_FB_IDX(fb_info.node), sgivw_gfx_mem_size>>10);
 
   return;
 
@@ -1030,8 +1209,78 @@
 {
   unregister_framebuffer(&fb_info);
   dbe_TurnOffDma();
+  i2c_unregister_bus(&flatpanel_i2c);
   iounmap(regs);
   iounmap(fbmem);
 }
 
 #endif /* MODULE */
+
+#define I2C_DELAY 1000
+#define I2C_FLATPANEL_BASE 0x70
+
+/* Apply clock and data state to the i2c bus */
+static void i2c_setlines(struct i2c_bus *bus,int ctrl,int data)
+{
+    struct i2c_private *info = (struct i2c_private*)bus->data;
+    int timeout = 10000; /* 10ms timeout */
+    
+    if (info->scl==1 && ctrl==0) {
+        /* data change lags falling clock edge */
+        *info->reg = ~(ctrl<<1 | info->sda);
+        info->scl = ctrl;
+        udelay(I2C_DELAY);
+    }
+    /* apply data change, if any */
+    if (data != info->sda) {
+        *info->reg = ~(info->scl<<1 | data);
+        info->sda = data;
+        udelay(I2C_DELAY);
+    }
+    if (info->scl==0 && ctrl==1) {
+        /* data change leads rising clock edge */
+        *info->reg = ~(ctrl<<1 | info->sda);
+        info->scl = ctrl;
+        udelay(I2C_DELAY);
+        
+        /* wait for slave to be ready */
+        while (((~*info->reg)&2) == 0 && timeout != 0) {
+            timeout--;
+            udelay(1);
+        }
+        if (timeout==0)
+            printk("sgivwfb: i2c wait-state timeout.\n");
+    }
+}
+
+/* Get the data line state */
+static int i2c_getdataline(struct i2c_bus *bus)
+{
+    struct i2c_private *info = (struct i2c_private*)bus->data;
+    return (int)((~*info->reg) & 1);
+}
+
+static int i2c_flatpanel_status(struct i2c_bus *bus)
+{
+    return i2c_read(bus, I2C_FLATPANEL_BASE | 1);
+}
+
+static int i2c_flatpanel_id(struct i2c_bus *bus)
+{
+    int id = i2c_flatpanel_status(bus);
+    if (id == -1)
+        return -1;
+    id = (id & 0xe0) >> 5;
+    return id;
+}
+
+static int i2c_flatpanel_power(struct i2c_bus *bus, int flag)
+{
+    int status = i2c_flatpanel_status(bus);
+    if (status == -1)
+        return -1;
+    if (flag == -1)
+        return status & (1<<2);
+    return 0;
+}
+
diff -Naur linux.2210/drivers/video/sgivwfb.h linux.2210.vw/drivers/video/sgivwfb.h
--- linux.2210/drivers/video/sgivwfb.h	Wed Mar 17 09:17:22 1999
+++ linux.2210.vw/drivers/video/sgivwfb.h	Wed Dec 31 16:00:00 1969
@@ -1,660 +0,0 @@
-/*
- *  linux/drivers/video/sgivwfb.h -- SGI DBE frame buffer device header
- *
- *      Copyright (C) 1999 Silicon Graphics, Inc.
- *      Jeffrey Newquist, newquist@engr.sgi.som
- *
- *  This file is subject to the terms and conditions of the GNU General Public
- *  License. See the file COPYING in the main directory of this archive for
- *  more details.
- */
-
-#ifndef __SGIVWFB_H__
-#define __SGIVWFB_H__
-
-#define DBE_GETREG(reg, dest)       ((dest) = DBE_REG_BASE->##reg)
-#define DBE_SETREG(reg, src)        DBE_REG_BASE->##reg = (src)
-#define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->##reg##[idx])
-#define DBE_ISETREG(reg, idx, src)  (DBE_REG_BASE->##reg##[idx] = (src))
-
-#define MASK(msb, lsb)          ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) )
-#define GET(v, msb, lsb)        ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) )
-#define SET(v, f, msb, lsb)     ( (v) = ((v)&~MASK(msb,lsb)) | (( (u32)(f)<<(lsb) ) & MASK(msb,lsb)) )
-
-#define GET_DBE_FIELD(reg, field, v)        GET((v), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
-#define SET_DBE_FIELD(reg, field, v, f)     SET((v), (f), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
-
-/* NOTE: All loads/stores must be 32 bits and uncached */
-
-#define DBE_REG_PHYS	0xd0000000
-#define DBE_REG_SIZE        0x01000000
-
-typedef struct {
-  volatile u32 ctrlstat;     /* 0x000000 general control */
-  volatile u32 dotclock;     /* 0x000004 dot clock PLL control */
-  volatile u32 i2c;          /* 0x000008 crt I2C control */
-  volatile u32 sysclk;       /* 0x00000c system clock PLL control */
-  volatile u32 i2cfp;        /* 0x000010 flat panel I2C control */
-  volatile u32 id;           /* 0x000014 device id/chip revision */
-  volatile u32 config;       /* 0x000018 power on configuration */
-  volatile u32 bist;         /* 0x00001c internal bist status */
-
-  char _pad0[ 0x010000 - 0x000020 ];
-
-  volatile u32 vt_xy;        /* 0x010000 current dot coords */
-  volatile u32 vt_xymax;     /* 0x010004 maximum dot coords */
-  volatile u32 vt_vsync;     /* 0x010008 vsync on/off */
-  volatile u32 vt_hsync;     /* 0x01000c hsync on/off */
-  volatile u32 vt_vblank;    /* 0x010010 vblank on/off */
-  volatile u32 vt_hblank;    /* 0x010014 hblank on/off */
-  volatile u32 vt_flags;     /* 0x010018 polarity of vt signals */
-  volatile u32 vt_f2rf_lock; /* 0x01001c f2rf & framelck y coord */
-  volatile u32 vt_intr01;    /* 0x010020 intr 0,1 y coords */
-  volatile u32 vt_intr23;    /* 0x010024 intr 2,3 y coords */
-  volatile u32 fp_hdrv;      /* 0x010028 flat panel hdrv on/off */
-  volatile u32 fp_vdrv;      /* 0x01002c flat panel vdrv on/off */
-  volatile u32 fp_de;        /* 0x010030 flat panel de on/off */
-  volatile u32 vt_hpixen;    /* 0x010034 intrnl horiz pixel on/off*/
-  volatile u32 vt_vpixen;    /* 0x010038 intrnl vert pixel on/off */
-  volatile u32 vt_hcmap;     /* 0x01003c cmap write (horiz) */
-  volatile u32 vt_vcmap;     /* 0x010040 cmap write (vert) */
-  volatile u32 did_start_xy; /* 0x010044 eol/f did/xy reset val */
-  volatile u32 crs_start_xy; /* 0x010048 eol/f crs/xy reset val */
-  volatile u32 vc_start_xy;  /* 0x01004c eol/f vc/xy reset val */
-
-  char _pad1[ 0x020000 - 0x010050 ];
-
-  volatile u32 ovr_width_tile; /* 0x020000 overlay plane ctrl 0 */
-  volatile u32 ovr_inhwctrl;   /* 0x020004 overlay plane ctrl 1 */
-  volatile u32 ovr_control;    /* 0x020008 overlay plane ctrl 1 */
-
-  char _pad2[ 0x030000 - 0x02000C ];
-
-  volatile u32 frm_size_tile;  /* 0x030000 normal plane ctrl 0 */
-  volatile u32 frm_size_pixel; /* 0x030004 normal plane ctrl 1 */
-  volatile u32 frm_inhwctrl;   /* 0x030008 normal plane ctrl 2 */
-  volatile u32 frm_control;	   /* 0x03000C normal plane ctrl 3 */
-
-  char _pad3[ 0x040000 - 0x030010 ];
-
-  volatile u32 did_inhwctrl;   /* 0x040000 DID control */
-  volatile u32 did_control;    /* 0x040004 DID shadow */
-
-  char _pad4[ 0x048000 - 0x040008 ];
-
-  volatile u32 mode_regs[32];  /* 0x048000 - 0x04807c WID table */
-
-  char _pad5[ 0x050000 - 0x048080 ];
-
-  volatile u32 cmap[6144];     /* 0x050000 - 0x055ffc color map */
-
-  char _pad6[ 0x058000 - 0x056000 ];
-
-  volatile u32 cm_fifo;        /* 0x058000 color map fifo status */
-
-  char _pad7[ 0x060000 - 0x058004 ];
-
-  volatile u32 gmap[256];      /* 0x060000 - 0x0603fc gamma map */
-
-  char _pad8[ 0x068000 - 0x060400 ];
-
-  volatile u32 gmap10[1024];   /* 0x068000 - 0x068ffc gamma map */
-
-  char _pad9[ 0x070000 - 0x069000 ];
-
-  volatile u32 crs_pos;        /* 0x070000 cusror control 0 */
-  volatile u32 crs_ctl;        /* 0x070004 cusror control 1 */
-  volatile u32 crs_cmap[3];    /* 0x070008 - 0x070010 crs cmap */
-
-  char _pad10[ 0x078000 - 0x070014 ];
-
-  volatile u32 crs_glyph[64];  /* 0x078000 - 0x0780fc crs glyph */
-
-  char _pad11[ 0x080000 - 0x078100 ];
-
-  volatile u32 vc_0;           /* 0x080000 video capture crtl 0 */
-  volatile u32 vc_1;           /* 0x080004 video capture crtl 1 */
-  volatile u32 vc_2;           /* 0x080008 video capture crtl 2 */
-  volatile u32 vc_3;           /* 0x08000c video capture crtl 3 */
-  volatile u32 vc_4;           /* 0x080010 video capture crtl 3 */
-  volatile u32 vc_5;           /* 0x080014 video capture crtl 3 */
-  volatile u32 vc_6;           /* 0x080018 video capture crtl 3 */
-  volatile u32 vc_7;           /* 0x08001c video capture crtl 3 */
-  volatile u32 vc_8;           /* 0x08000c video capture crtl 3 */
-} asregs;
-
-/* Bit mask information */
-
-#define DBE_CTRLSTAT_CHIPID_MSB     3
-#define DBE_CTRLSTAT_CHIPID_LSB     0
-#define DBE_CTRLSTAT_SENSE_N_MSB    4
-#define DBE_CTRLSTAT_SENSE_N_LSB    4
-#define DBE_CTRLSTAT_PCLKSEL_MSB    29
-#define DBE_CTRLSTAT_PCLKSEL_LSB    28
-
-#define DBE_DOTCLK_M_MSB            7
-#define DBE_DOTCLK_M_LSB            0
-#define DBE_DOTCLK_N_MSB            13
-#define DBE_DOTCLK_N_LSB            8
-#define DBE_DOTCLK_P_MSB            15
-#define DBE_DOTCLK_P_LSB            14
-#define DBE_DOTCLK_RUN_MSB          20
-#define DBE_DOTCLK_RUN_LSB          20
-
-#define DBE_VT_XY_VT_FREEZE_MSB     31
-#define DBE_VT_XY_VT_FREEZE_LSB     31
-
-#define DBE_VT_VSYNC_VT_VSYNC_ON_MSB        23
-#define DBE_VT_VSYNC_VT_VSYNC_ON_LSB        12
-#define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB       11
-#define DBE_VT_VSYNC_VT_VSYNC_OFF_LSB       0
-
-#define DBE_VT_HSYNC_VT_HSYNC_ON_MSB        23
-#define DBE_VT_HSYNC_VT_HSYNC_ON_LSB        12
-#define DBE_VT_HSYNC_VT_HSYNC_OFF_MSB       11
-#define DBE_VT_HSYNC_VT_HSYNC_OFF_LSB       0
-
-#define DBE_VT_VBLANK_VT_VBLANK_ON_MSB        23
-#define DBE_VT_VBLANK_VT_VBLANK_ON_LSB        12
-#define DBE_VT_VBLANK_VT_VBLANK_OFF_MSB       11
-#define DBE_VT_VBLANK_VT_VBLANK_OFF_LSB       0
-
-#define DBE_VT_HBLANK_VT_HBLANK_ON_MSB        23
-#define DBE_VT_HBLANK_VT_HBLANK_ON_LSB        12
-#define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB       11
-#define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB       0
-
-#define DBE_VT_VCMAP_VT_VCMAP_ON_MSB        23
-#define DBE_VT_VCMAP_VT_VCMAP_ON_LSB        12
-#define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB       11
-#define DBE_VT_VCMAP_VT_VCMAP_OFF_LSB       0
-
-#define DBE_VT_HCMAP_VT_HCMAP_ON_MSB        23
-#define DBE_VT_HCMAP_VT_HCMAP_ON_LSB        12
-#define DBE_VT_HCMAP_VT_HCMAP_OFF_MSB       11
-#define DBE_VT_HCMAP_VT_HCMAP_OFF_LSB       0
-
-#define DBE_VT_XYMAX_VT_MAXX_MSB    11
-#define DBE_VT_XYMAX_VT_MAXX_LSB    0
-#define DBE_VT_XYMAX_VT_MAXY_MSB    23
-#define DBE_VT_XYMAX_VT_MAXY_LSB    12
-
-#define DBE_VT_HPIXEN_VT_HPIXEN_ON_MSB      23
-#define DBE_VT_HPIXEN_VT_HPIXEN_ON_LSB      12
-#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_MSB     11
-#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_LSB     0
-
-#define DBE_VT_VPIXEN_VT_VPIXEN_ON_MSB      23
-#define DBE_VT_VPIXEN_VT_VPIXEN_ON_LSB      12
-#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_MSB     11
-#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_LSB     0
-
-#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_MSB  0
-#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_LSB  0
-
-#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_MSB 0
-#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_LSB 0
-
-#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_MSB       13
-#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_LSB       13
-
-#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_MSB  0
-#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_LSB  0
-#define DBE_FRM_CONTROL_FRM_TILE_PTR_MSB    31
-#define DBE_FRM_CONTROL_FRM_TILE_PTR_LSB    9
-#define DBE_FRM_CONTROL_FRM_LINEAR_MSB      1
-#define DBE_FRM_CONTROL_FRM_LINEAR_LSB      1
-
-#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_MSB 0
-#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_LSB 0
-
-#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_MSB        12
-#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_LSB        5
-#define DBE_FRM_SIZE_TILE_FRM_RHS_MSB       4
-#define DBE_FRM_SIZE_TILE_FRM_RHS_LSB       0
-#define DBE_FRM_SIZE_TILE_FRM_DEPTH_MSB     14
-#define DBE_FRM_SIZE_TILE_FRM_DEPTH_LSB     13
-#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_MSB        15
-#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_LSB        15
-
-#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_MSB        31
-#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_LSB        16
-
-#define DBE_DID_CONTROL_DID_DMA_ENABLE_MSB  0
-#define DBE_DID_CONTROL_DID_DMA_ENABLE_LSB  0
-#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_MSB 0
-#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_LSB 0
-
-#define DBE_DID_START_XY_DID_STARTY_MSB     23
-#define DBE_DID_START_XY_DID_STARTY_LSB     12
-#define DBE_DID_START_XY_DID_STARTX_MSB     11
-#define DBE_DID_START_XY_DID_STARTX_LSB     0
-
-#define DBE_CRS_START_XY_CRS_STARTY_MSB     23
-#define DBE_CRS_START_XY_CRS_STARTY_LSB     12
-#define DBE_CRS_START_XY_CRS_STARTX_MSB     11
-#define DBE_CRS_START_XY_CRS_STARTX_LSB     0
-
-#define DBE_WID_TYP_MSB     4
-#define DBE_WID_TYP_LSB     2
-#define DBE_WID_BUF_MSB     1
-#define DBE_WID_BUF_LSB     0
-
-#define DBE_VC_START_XY_VC_STARTY_MSB       23
-#define DBE_VC_START_XY_VC_STARTY_LSB       12
-#define DBE_VC_START_XY_VC_STARTX_MSB       11
-#define DBE_VC_START_XY_VC_STARTX_LSB       0
-
-/* Constants */
-
-#define DBE_FRM_DEPTH_8     0
-#define DBE_FRM_DEPTH_16    1
-#define DBE_FRM_DEPTH_32    2
-
-#define DBE_CMODE_I8        0
-#define DBE_CMODE_I12       1
-#define DBE_CMODE_RG3B2     2
-#define DBE_CMODE_RGB4      3
-#define DBE_CMODE_ARGB5     4
-#define DBE_CMODE_RGB8      5
-#define DBE_CMODE_RGBA5     6
-#define DBE_CMODE_RGB10     7
-
-#define DBE_BMODE_BOTH      3
-
-#define DBE_CRS_MAGIC       54
-
-/* Config Register (DBE Only) Definitions */
-
-#define DBE_CONFIG_VDAC_ENABLE       0x00000001
-#define DBE_CONFIG_VDAC_GSYNC        0x00000002
-#define DBE_CONFIG_VDAC_PBLANK       0x00000004
-#define DBE_CONFIG_FPENABLE          0x00000008
-#define DBE_CONFIG_LENDIAN           0x00000020
-#define DBE_CONFIG_TILEHIST          0x00000040
-#define DBE_CONFIG_EXT_ADDR          0x00000080
-
-#define DBE_CONFIG_FBDEV        ( DBE_CONFIG_VDAC_ENABLE | \
-                                      DBE_CONFIG_VDAC_GSYNC  | \
-                                      DBE_CONFIG_VDAC_PBLANK | \
-                                      DBE_CONFIG_LENDIAN     | \
-                                      DBE_CONFIG_EXT_ADDR )
-
-/*
- * Available Video Timings and Corresponding Indices
- */
-
-typedef enum {
-  DBE_VT_640_480_60,
-
-  DBE_VT_800_600_60,
-  DBE_VT_800_600_75,
-  DBE_VT_800_600_120,
-
-  DBE_VT_1024_768_50,
-  DBE_VT_1024_768_60,
-  DBE_VT_1024_768_75,
-  DBE_VT_1024_768_85,
-  DBE_VT_1024_768_120,
-
-  DBE_VT_1280_1024_50,
-  DBE_VT_1280_1024_60,
-  DBE_VT_1280_1024_75,
-  DBE_VT_1280_1024_85,
-
-  DBE_VT_1600_1024_53,
-  DBE_VT_1600_1024_60,
-
-  DBE_VT_1600_1200_50,
-  DBE_VT_1600_1200_60,
-  DBE_VT_1600_1200_75,
-
-  DBE_VT_1920_1080_50,
-  DBE_VT_1920_1080_60,
-  DBE_VT_1920_1080_72,
-
-  DBE_VT_1920_1200_50,
-  DBE_VT_1920_1200_60,
-  DBE_VT_1920_1200_66,
-
-  DBE_VT_UNKNOWN
-} dbe_timing_t;
-
-
-
-/*
- * Crime Video Timing Data Structure
- */
-
-typedef struct dbe_timing_info
-{
-  dbe_timing_t type;
-  int flags;				
-  short width;		    /* Monitor resolution		*/
-  short height;
-  int fields_sec;	    /* fields/sec  (Hz -3 dec. places */
-  int cfreq;		    /* pixel clock frequency (MHz -3 dec. places) */
-  short htotal;		    /* Horizontal total pixels	*/
-  short hblank_start;	    /* Horizontal blank start	*/
-  short hblank_end;	    /* Horizontal blank end		*/
-  short hsync_start;	    /* Horizontal sync start	*/
-  short hsync_end;	    /* Horizontal sync end		*/
-  short vtotal;		    /* Vertical total lines		*/
-  short vblank_start;	    /* Vertical blank start		*/
-  short vblank_end;	    /* Vertical blank end		*/
-  short vsync_start;	    /* Vertical sync start		*/
-  short vsync_end;	    /* Vertical sync end		*/
-  short pll_m;		    /* PLL M parameter		*/
-  short pll_n;		    /* PLL P parameter		*/
-  short pll_p;		    /* PLL N parameter		*/
-} dbe_timing_info_t;
-
-/* Defines for dbe_vof_info_t flags */
-
-#define DBE_VOF_UNKNOWNMON    1
-#define DBE_VOF_STEREO        2
-#define DBE_VOF_DO_GENSYNC    4          /* enable incoming sync */
-#define DBE_VOF_SYNC_ON_GREEN 8          /* sync on green */
-#define DBE_VOF_FLATPANEL     0x1000     /* FLATPANEL Timing */
-#define DBE_VOF_MAGICKEY      0x2000     /* Backdoor key */
-
-/*
- * DBE Timing Tables
- */
-
-#ifdef INCLUDE_TIMING_TABLE_DATA
-struct dbe_timing_info dbeVTimings[] = {
-  {
-    DBE_VT_640_480_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,  	640,			480,		59940,			25175,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    800,	640,		    800,		656,	    	752,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    525,	480,		    525,		490,		    492,
-    /*	pll_m,	pll_n,			pll_p */
-    15,	    2,				3
-  },
-
-  {
-    DBE_VT_800_600_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    800,			600,		60317,			40000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1056,	800,		    1056,		840,		    968,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    628,	600,		    628,		601,		    605,
-    /*	pll_m,	pll_n,			pll_p */
-    3,	    1,				1
-  },
-
-  {
-    DBE_VT_800_600_75,
-    /*	flags,	width,		    height,		fields_sec,	    cfreq */
-    0,	    800,		    600,		75000,		    49500,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1056,	800,		    1056,		816,		    896,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    625,	600,		    625,		601,		    604,
-    /*	pll_m,	pll_n,		    pll_p */
-    11,	    3,		        1
-  },
-
-  {
-    DBE_VT_800_600_120,
-    /*	flags,					width,		height,			fields_sec,	    cfreq */
-    DBE_VOF_STEREO,	    800,		600,			119800,		    82978,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1040,	800,		    1040,		856,		    976,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    666,	600,		    666,		637,		    643,
-    /*	pll_m,	pll_n,		    pll_p */
-    31,	    5,		        1
-  },
-
-  {
-    DBE_VT_1024_768_50,
-    /*	flags,	width,		    height,		fields_sec,	    cfreq */
-    0,	    1024,		    768,		50000,		    54163,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1344,	1024,		    1344,		1048,		    1184,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    806,	768,		    806,		771,		    777,
-    /*	pll_m,	pll_n,		    pll_p */
-    4,	    1,		        1
-  },
-
-  {
-    DBE_VT_1024_768_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1024,			768,		60004,			65000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1344,	1024,		    1344,		1048,		    1184,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    806,	768,		    806,		771,		    777,
-    /*	pll_m,	pll_n,			pll_p */
-    12,	    5,				0
-  },
-
-  {
-    DBE_VT_1024_768_75,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1024,			768,		75029,			78750,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1312,	1024,		    1312,		1040,		    1136,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    800,	768,		    800,		769,		    772,
-    /*	pll_m,	pll_n,			pll_p */
-    29,	    5,				1
-  },
-
-  {
-    DBE_VT_1024_768_85,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1024,			768,		84997,			94500,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1376,	1024,		    1376,		1072,		    1168,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    808,	768,		    808,		769,		    772,
-    /*	pll_m,	pll_n,			pll_p */
-    7,	    2,				0
-  },
-
-  {
-    DBE_VT_1024_768_120,
-    /*	flags,					width,		height,			fields_sec,		cfreq */
-    DBE_VOF_STEREO,	    1024,		768,			119800,			133195,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1376,	1024,		    1376,		1072,		    1168,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    808,	768,		    808,		769,		    772,
-    /*	pll_m,	pll_n,			pll_p */
-    5,	    1,				0
-  },
-
-  {
-    DBE_VT_1280_1024_50,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1280,			1024,		50000,			89460,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1680,	1280,		    1680,		1360,		    1480,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1065,	1024,		    1065,		1027,		    1030,
-    /*	pll_m,	pll_n,			pll_p */
-    10,	    3,				0
-  },
-
-  {
-    DBE_VT_1280_1024_60,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1280,			1024,		60020,			108000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1688,	1280,		    1688,		1328,		    1440,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1066,	1024,		    1066,		1025,		    1028,
-    /*	pll_m,	pll_n,			pll_p */
-    4,	    1,			    0
-  },
-
-  {
-    DBE_VT_1280_1024_75,
-    /*	flags,	width,			height,		fields_sec,		cfreq */
-    0,	    1280,			1024,		75025,			135000,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1688,	1280,		    1688,		1296,		    1440,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1066,	1024,		    1066,		1025,		    1028,
-    /*	pll_m,	pll_n,			pll_p */
-    5,	    1,				0
-  },
-
-  {
-    DBE_VT_1280_1024_85,
-    /*	flags,	width,		    height,		fields_sec,	    cfreq */
-    0,	    1280,		    1024,		85024,		    157500,
-    /*	htotal,	hblank_start,	hblank_end,	hsync_start,	hsync_end */
-    1728,	1280,		    1728,		1344,		    1504,
-    /*	vtotal,	vblank_start,	vblank_end,	vsync_start,	vsync_end */
-    1072,	1024,		    1072,		1025,		    1028,
-    /*	pll_m,	pll_n,		    pll_p */
-    29,	    5,		        0
-  },
-
-  {
-    DBE_VT_1600_1024_53,
-    /* flags,	width,			height,		fields_sec,     cfreq */
-    DBE_VOF_FLATPANEL | DBE_VOF_MAGICKEY,
-    1600,			1024,		53000,			107447,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    1900,   1600,           1900,           1630,           1730,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1067,   1024,           1067,           1027,           1030,
-    /* pll_m,  pll_n,          pll_p */
-    4,      1,              0
-  },
-
-  {
-    DBE_VT_1600_1024_60,
-    /* flags,					width,          height,			fields_sec,     cfreq */
-    DBE_VOF_FLATPANEL,   1600,           1024,			60000,          106913,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    1670,   1600,           1670,           1630,           1650,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1067,   1024,           1067,           1027,           1030,
-    /* pll_m,  pll_n,          pll_p */
-    4,      1,              0
-  },
-
-  {
-    DBE_VT_1600_1200_50,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1600,           1200,           50000,          130500,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2088,   1600,           2088,           1644,           1764,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1205,           1211,
-    /* pll_m,  pll_n,          pll_p */
-    24,     5,              0
-  },
-
-  {
-    DBE_VT_1600_1200_60,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1600,           1200,           59940,          162000,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2160,   1600,           2160,           1644,           1856,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1201,           1204,
-    /* pll_m,  pll_n,          pll_p */
-    6,		1,              0
-  },
-
-  {
-    DBE_VT_1600_1200_75,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1600,           1200,           75000,          202500,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2160,   1600,           2160,           1644,           1856,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1201,           1204,
-    /* pll_m,  pll_n,          pll_p */
-    15,		2,              0
-  },
-
-  {
-    DBE_VT_1920_1080_50,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1080,           50000,          133200,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2368,   1920,           2368,           1952,           2096,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1125,   1080,           1125,           1083,           1086,
-    /* pll_m,  pll_n,          pll_p */
-    5,      1,              0
-  },
-
-  {
-    DBE_VT_1920_1080_60,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1080,           59940,          159840,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2368,   1920,           2368,           1952,           2096,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1125,   1080,           1125,           1083,           1086,
-    /* pll_m,  pll_n,          pll_p */
-    6,      1,              0
-  },
-
-  {
-    DBE_VT_1920_1080_72,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1080,           72000,          216023,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2560,   1920,           2560,           1968,           2184,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1172,   1080,           1172,           1083,           1086,
-    /* pll_m,  pll_n,          pll_p */
-    8,      1,              0
-  },
-
-  {
-    DBE_VT_1920_1200_50,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1200,           50000,          161500,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2584,   1920,           2584,           1984,           2240,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1203,           1206,
-    /* pll_m,  pll_n,          pll_p */
-    6,      1,              0
-  },
-	
-  {
-    DBE_VT_1920_1200_60,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1200,           59940,          193800,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2584,   1920,           2584,           1984,           2240,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1203,           1206,
-    /* pll_m,  pll_n,          pll_p */
-    29,     4,              0
-  },
-
-  {
-    DBE_VT_1920_1200_66,
-    /* flags,  width,          height,         fields_sec,     cfreq */
-    0,      1920,           1200,           66000,          213180,
-    /* htotal, hblank_start,   hblank_end,     hsync_start,    hsync_end */
-    2584,   1920,           2584,           1984,           2240,
-    /* vtotal, vblank_start,   vblank_end,     vsync_start,    vsync_end */
-    1250,   1200,           1250,           1203,           1206,
-    /* pll_m,  pll_n,          pll_p */
-    8,      1,              0
-  }
-};
-
-#define DBE_VT_SIZE  (sizeof(dbeVTimings)/sizeof(dbeVTimings[0]))
-#endif // INCLUDE_TIMING_TABLE_DATA
-
-#endif // ! __SGIVWFB_H__
diff -Naur linux.2210/include/asm-i386/cobalt.h linux.2210.vw/include/asm-i386/cobalt.h
--- linux.2210/include/asm-i386/cobalt.h	Sun Jan 24 21:55:04 1999
+++ linux.2210.vw/include/asm-i386/cobalt.h	Wed Dec 31 16:00:00 1969
@@ -1,117 +0,0 @@
-#include <linux/config.h>
-#ifndef __I386_COBALT_H
-#define __I386_COBALT_H
-
-/*
- * Cobalt is the system ASIC on the SGI 320 and 540 Visual Workstations
- */ 
-
-#define	CO_CPU_PHYS		0xc2000000
-#define	CO_APIC_PHYS		0xc4000000
-
-/* see set_fixmap() and asm/fixmap.h */
-#define	CO_CPU_VADDR		(fix_to_virt(FIX_CO_CPU))
-#define	CO_APIC_VADDR		(fix_to_virt(FIX_CO_APIC))
-
-/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */
-#define	CO_CPU_REV		0x08
-#define	CO_CPU_CTRL		0x10
-#define	CO_CPU_STAT		0x20
-#define	CO_CPU_TIMEVAL		0x30
-
-/* CO_CPU_CTRL bits */
-#define	CO_CTRL_TIMERUN		0x04	/* 0 == disabled */
-#define	CO_CTRL_TIMEMASK	0x08	/* 0 == unmasked */
-
-/* CO_CPU_STATUS bits */
-#define	CO_STAT_TIMEINTR	0x02	/* (r) 1 == int pend, (w) 0 == clear */
-
-/* CO_CPU_TIMEVAL value */
-#define	CO_TIME_HZ		100000000 /* Cobalt core rate */
-
-/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */
-#define	CO_APIC_HI(n)		(((n) * 0x10) + 4)
-#define	CO_APIC_LO(n)		((n) * 0x10)
-#define	CO_APIC_ID		0x0ffc
-
-/* CO_APIC_ID bits */
-#define	CO_APIC_ENABLE		0x00000100
-
-/* CO_APIC_LO bits */
-#define	CO_APIC_LEVEL		0x08000		/* 0 = edge */
-
-/*
- * Where things are physically wired to Cobalt
- * #defines with no board _<type>_<rev>_ are common to all (thus far)
- */
-#define CO_APIC_0_5_IDE0	5
-#define	CO_APIC_0_5_SERIAL	13	 /* XXX not really...h/w bug! */
-#define CO_APIC_0_5_PARLL	4
-#define CO_APIC_0_5_FLOPPY	6
-
-#define	CO_APIC_0_6_IDE0	4
-#define	CO_APIC_0_6_USB	7	/* PIIX4 USB */
-
-#define	CO_APIC_1_2_IDE0	4
-
-#define CO_APIC_0_5_IDE1	2
-#define CO_APIC_0_6_IDE1	2
-
-/* XXX */
-#define	CO_APIC_IDE0	CO_APIC_0_5_IDE0
-#define	CO_APIC_IDE1	CO_APIC_0_5_IDE1
-#define	CO_APIC_SERIAL	CO_APIC_0_5_SERIAL
-/* XXX */
-
-#define CO_APIC_ENET	3	/* Lithium PCI Bridge A, Device 3 */
-#define	CO_APIC_8259	12	/* serial, floppy, par-l-l, audio */
-
-#define	CO_APIC_VIDOUT0	16
-#define	CO_APIC_VIDOUT1	17
-#define	CO_APIC_VIDIN0	18
-#define	CO_APIC_VIDIN1	19
-
-#define CO_APIC_CPU	28	/* Timer and Cache interrupt */
-
-/*
- * This is the "irq" arg to request_irq(), just a unique cookie.
- */
-#define	CO_IRQ_TIMER	0
-#define CO_IRQ_ENET	3
-#define CO_IRQ_SERIAL	4
-#define CO_IRQ_FLOPPY	6	/* Same as drivers/block/floppy.c:FLOPPY_IRQ */
-#define	CO_IRQ_PARLL	7
-#define	CO_IRQ_POWER	9
-#define CO_IRQ_IDE	14
-#define	CO_IRQ_8259	12
-
-#ifdef CONFIG_X86_VISWS_APIC
-extern __inline void co_cpu_write(unsigned long reg, unsigned long v)
-{
-	*((volatile unsigned long *)(CO_CPU_VADDR+reg))=v;
-}
-
-extern __inline unsigned long co_cpu_read(unsigned long reg)
-{
-	return *((volatile unsigned long *)(CO_CPU_VADDR+reg));
-}            
-             
-extern __inline void co_apic_write(unsigned long reg, unsigned long v)
-{
-	*((volatile unsigned long *)(CO_APIC_VADDR+reg))=v;
-}            
-             
-extern __inline unsigned long co_apic_read(unsigned long reg)
-{
-	return *((volatile unsigned long *)(CO_APIC_VADDR+reg));
-}
-#endif
-
-extern char visws_board_type;
-
-#define	VISWS_320	0
-#define	VISWS_540	1
-
-extern char visws_board_rev;
-
-#endif
diff -Naur linux.2210/include/asm-i386/lithium.h linux.2210.vw/include/asm-i386/lithium.h
--- linux.2210/include/asm-i386/lithium.h	Sun Jan 24 21:56:35 1999
+++ linux.2210.vw/include/asm-i386/lithium.h	Wed Dec 31 16:00:00 1969
@@ -1,45 +0,0 @@
-#ifndef __I386_LITHIUM_H
-#define __I386_LITHIUM_H
-
-#include <linux/config.h>
-
-/*
- * Lithium is the I/O ASIC on the SGI 320 and 540 Visual Workstations
- */
-
-#define	LI_PCI_A_PHYS		0xfc000000	/* Enet is dev 3 */
-#define	LI_PCI_B_PHYS		0xfd000000	/* PIIX4 is here */
-
-/* see set_fixmap() and asm/fixmap.h */
-#define LI_PCIA_VADDR   (fix_to_virt(FIX_LI_PCIA))
-#define LI_PCIB_VADDR   (fix_to_virt(FIX_LI_PCIB))
-
-/* Not a standard PCI? (not in linux/pci.h) */
-#define	LI_PCI_BUSNUM	0x44			/* lo8: primary, hi8: sub */
-#define LI_PCI_INTEN    0x46
-
-#ifdef CONFIG_X86_VISWS_APIC
-/* More special purpose macros... */
-extern __inline void li_pcia_write16(unsigned long reg, unsigned short v)
-{
-	*((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v;
-}
-
-extern __inline unsigned short li_pcia_read16(unsigned long reg)
-{
-	 return *((volatile unsigned short *)(LI_PCIA_VADDR+reg));
-}
-
-extern __inline void li_pcib_write16(unsigned long reg, unsigned short v)
-{
-	*((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v;
-}
-
-extern __inline unsigned short li_pcib_read16(unsigned long reg)
-{
-	return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
-}
-#endif
-
-#endif
-
diff -Naur linux.2210/include/asm-i386/sgi-cobalt.h linux.2210.vw/include/asm-i386/sgi-cobalt.h
--- linux.2210/include/asm-i386/sgi-cobalt.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/include/asm-i386/sgi-cobalt.h	Wed Jul 28 09:07:38 1999
@@ -0,0 +1,119 @@
+#include <linux/config.h>
+#ifndef __I386_SGI_COBALT_H
+#define __I386_SGI_COBALT_H
+
+/*
+ * Cobalt SGI Visual Workstation system ASIC
+ */ 
+
+#define	CO_CPU_PHYS		0xc2000000
+#define	CO_APIC_PHYS		0xc4000000
+
+/* see set_fixmap() and asm/fixmap.h */
+#define	CO_CPU_VADDR		(fix_to_virt(FIX_CO_CPU))
+#define	CO_APIC_VADDR		(fix_to_virt(FIX_CO_APIC))
+
+/* Cobalt CPU registers -- relative to CO_CPU_VADDR, use co_cpu_*() */
+#define	CO_CPU_REV		0x08
+#define	CO_CPU_CTRL		0x10
+#define	CO_CPU_STAT		0x20
+#define	CO_CPU_TIMEVAL		0x30
+
+/* CO_CPU_CTRL bits */
+#define	CO_CTRL_TIMERUN		0x04		/* 0 == disabled */
+#define	CO_CTRL_TIMEMASK	0x08		/* 0 == unmasked */
+
+/* CO_CPU_STATUS bits */
+#define	CO_STAT_TIMEINTR	0x02	/* (r) 1 == int pend, (w) 0 == clear */
+
+/* CO_CPU_TIMEVAL value */
+#define	CO_TIME_HZ		100000000	/* Cobalt core rate */
+
+/* Cobalt APIC registers -- relative to CO_APIC_VADDR, use co_apic_*() */
+#define	CO_APIC_HI(n)		(((n) * 0x10) + 4)
+#define	CO_APIC_LO(n)		((n) * 0x10)
+#define	CO_APIC_ID		0x0ffc
+
+/* CO_APIC_ID bits */
+#define	CO_APIC_ENABLE		0x00000100
+
+/* CO_APIC_LO bits */
+#define	CO_APIC_MASK		0x00010000	/* 0 = enabled */
+#define	CO_APIC_LEVEL		0x00008000	/* 0 = edge */
+
+/*
+ * Where things are physically wired to Cobalt
+ * #defines with no board _<type>_<rev>_ are common to all (thus far)
+ */
+#define	CO_APIC_IDE0		4
+#define CO_APIC_IDE1		2		/* Only on 320 */
+
+#define	CO_APIC_8259		12		/* serial, floppy, par-l-l */
+
+/* Lithium PCI Bridge A -- "the one with 82557 Ethernet" */
+#define	CO_APIC_PCIA_BASE0	0 /* and 1 */	/* slot 0, line 0 */
+#define	CO_APIC_PCIA_BASE123	5 /* and 6 */	/* slot 0, line 1 */
+
+#define	CO_APIC_PIIX4_USB	7		/* this one is wierd */
+
+/* Lithium PCI Bridge B -- "the one with PIIX4" */
+#define	CO_APIC_PCIB_BASE0	8 /* and 9-12 *//* slot 0, line 0 */
+#define	CO_APIC_PCIB_BASE123	13 /* 14.15 */	/* slot 0, line 1 */
+
+#define	CO_APIC_VIDOUT0		16
+#define	CO_APIC_VIDOUT1		17
+#define	CO_APIC_VIDIN0		18
+#define	CO_APIC_VIDIN1		19
+
+#define	CO_APIC_LI_AUDIO	22
+
+#define	CO_APIC_AS		24
+#define	CO_APIC_RE		25
+
+#define CO_APIC_CPU		28		/* Timer and Cache interrupt */
+#define	CO_APIC_NMI		29
+#define	CO_APIC_LAST		CO_APIC_NMI
+
+/*
+ * This is how irqs are assigned on the Visual Workstation.
+ * Legacy devices get irq's 1-15 (system clock is 0 and is CO_APIC_CPU).
+ * All other devices (including PCI) go to Cobalt and are irq's 16 on up.
+ */
+#define	CO_IRQ_APIC0	16			/* irq of apic entry 0 */
+#define	IS_CO_APIC(irq)	((irq) >= CO_IRQ_APIC0)
+#define	CO_IRQ(apic)	(CO_IRQ_APIC0 + (apic))	/* apic ent to irq */
+#define	CO_APIC(irq)	((irq) - CO_IRQ_APIC0)	/* irq to apic ent */
+#define CO_IRQ_IDE0	14			/* knowledge of... */
+#define CO_IRQ_IDE1	15			/* ... ide driver defaults! */
+#define	CO_IRQ_8259	CO_IRQ(CO_APIC_8259)
+
+#ifdef CONFIG_X86_VISWS_APIC
+extern __inline void co_cpu_write(unsigned long reg, unsigned long v)
+{
+	*((volatile unsigned long *)(CO_CPU_VADDR+reg))=v;
+}
+
+extern __inline unsigned long co_cpu_read(unsigned long reg)
+{
+	return *((volatile unsigned long *)(CO_CPU_VADDR+reg));
+}            
+             
+extern __inline void co_apic_write(unsigned long reg, unsigned long v)
+{
+	*((volatile unsigned long *)(CO_APIC_VADDR+reg))=v;
+}            
+             
+extern __inline unsigned long co_apic_read(unsigned long reg)
+{
+	return *((volatile unsigned long *)(CO_APIC_VADDR+reg));
+}
+#endif
+
+extern char visws_board_type;
+
+#define	VISWS_320	0
+#define	VISWS_540	1
+
+extern char visws_board_rev;
+
+#endif
diff -Naur linux.2210/include/asm-i386/sgi-lithium.h linux.2210.vw/include/asm-i386/sgi-lithium.h
--- linux.2210/include/asm-i386/sgi-lithium.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/include/asm-i386/sgi-lithium.h	Wed Jul 28 09:07:38 1999
@@ -0,0 +1,56 @@
+#ifndef __I386_SGI_LITHIUM_H
+#define __I386_SGI_LITHIUM_H
+
+#include <linux/config.h>
+
+/*
+ * Lithium is the SGI Visual Workstation I/O ASIC
+ */
+
+#define	LI_PCI_A_PHYS		0xfc000000	/* Enet is dev 3 */
+#define	LI_PCI_B_PHYS		0xfd000000	/* PIIX4 is here */
+
+/* see set_fixmap() and asm/fixmap.h */
+#define LI_PCIA_VADDR   (fix_to_virt(FIX_LI_PCIA))
+#define LI_PCIB_VADDR   (fix_to_virt(FIX_LI_PCIB))
+
+/* Not a standard PCI? (not in linux/pci.h) */
+#define	LI_PCI_BUSNUM	0x44			/* lo8: primary, hi8: sub */
+#define LI_PCI_INTEN    0x46
+
+/* LI_PCI_INTENT bits */
+#define	LI_INTA_0	0x0001
+#define	LI_INTA_1	0x0002
+#define	LI_INTA_2	0x0004
+#define	LI_INTA_3	0x0008
+#define	LI_INTA_4	0x0010
+#define	LI_INTB		0x0020
+#define	LI_INTC		0x0040
+#define	LI_INTD		0x0080
+
+
+#ifdef CONFIG_X86_VISWS_APIC
+/* More special purpose macros... */
+extern __inline void li_pcia_write16(unsigned long reg, unsigned short v)
+{
+	*((volatile unsigned short *)(LI_PCIA_VADDR+reg))=v;
+}
+
+extern __inline unsigned short li_pcia_read16(unsigned long reg)
+{
+	 return *((volatile unsigned short *)(LI_PCIA_VADDR+reg));
+}
+
+extern __inline void li_pcib_write16(unsigned long reg, unsigned short v)
+{
+	*((volatile unsigned short *)(LI_PCIB_VADDR+reg))=v;
+}
+
+extern __inline unsigned short li_pcib_read16(unsigned long reg)
+{
+	return *((volatile unsigned short *)(LI_PCIB_VADDR+reg));
+}
+#endif
+
+#endif
+
diff -Naur linux.2210/include/asm-i386/sgi-piix.h linux.2210.vw/include/asm-i386/sgi-piix.h
--- linux.2210/include/asm-i386/sgi-piix.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/include/asm-i386/sgi-piix.h	Wed Jul 28 08:56:42 1999
@@ -0,0 +1,113 @@
+#ifndef __I386_SGI_PIIX_H
+#define __I386_SGI_PIIX_H
+
+/*
+ * PIIX4 as used on SGI Visual Workstations
+ */
+
+/*
+ * The PCI bus with PIIX4.
+ * XXX bus numbering should be virtualized?!
+ */
+#define PIIX4_BUS		0
+
+#define	PIIX_PM_START		0x0F80
+
+#define	SIO_GPIO_START		0x0FC0
+
+#define	SIO_PM_START		0x0FC8
+
+#define	PMBASE			PIIX_PM_START
+#define	GPIREG0			(PMBASE+0x30)
+#define	GPIREG(x)		(GPIREG0+((x)/8))
+#define	GPIBIT(x)		(1 << ((x)%8))
+
+#define	PIIX_GPI_BD_ID1		18
+#define	PIIX_GPI_BD_ID2		19
+#define	PIIX_GPI_BD_ID3		20
+#define	PIIX_GPI_BD_ID4		21
+#define	PIIX_GPI_BD_REG		GPIREG(PIIX_GPI_BD_ID1)
+#define	PIIX_GPI_BD_MASK	(GPIBIT(PIIX_GPI_BD_ID1) | \
+				GPIBIT(PIIX_GPI_BD_ID2) | \
+				GPIBIT(PIIX_GPI_BD_ID3) | \
+				GPIBIT(PIIX_GPI_BD_ID4) )
+
+#define	PIIX_GPI_BD_SHIFT	(PIIX_GPI_BD_ID1 % 8)
+
+#define	SIO_INDEX		0x2e
+#define	SIO_DATA		0x2f
+
+#define	SIO_DEV_SEL		0x7
+#define	SIO_DEV_ENB		0x30
+#define	SIO_DEV_MSB		0x60
+#define	SIO_DEV_LSB		0x61
+
+#define	SIO_GP_DEV		0x7
+
+#define	SIO_GP_BASE		SIO_GPIO_START
+#define	SIO_GP_MSB		(SIO_GP_BASE>>8)
+#define	SIO_GP_LSB		(SIO_GP_BASE&0xff)
+
+#define	SIO_GP_DATA1		(SIO_GP_BASE+0)
+
+#define	SIO_PM_DEV		0x8
+
+#define	SIO_PM_BASE		SIO_PM_START
+#define	SIO_PM_MSB		(SIO_PM_BASE>>8)
+#define	SIO_PM_LSB		(SIO_PM_BASE&0xff)
+#define	SIO_PM_INDEX		(SIO_PM_BASE+0)
+#define	SIO_PM_DATA		(SIO_PM_BASE+1)
+
+#define	SIO_PM_FER2		0x1
+
+#define	SIO_PM_GP_EN		0x80
+
+
+
+/*
+ * This is the dev/reg where generating a config cycle will
+ * result in a PCI special cycle.
+ */
+#define SPECIAL_DEV		0xff
+#define SPECIAL_REG		0x00
+
+/*
+ * PIIX4 needs to see a special cycle with the following data
+ * to be convinced the processor has gone into the stop grant
+ * state.  PIIX4 insists on seeing this before it will power
+ * down a system.
+ */
+#define PIIX_SPECIAL_STOP		0x00120002
+
+#define PIIX4_RESET_PORT	0xcf9
+#define PIIX4_RESET_VAL		0x6
+
+#define PMSTS_PORT		0xf80	// 2 bytes	PM Status
+#define PMEN_PORT		0xf82	// 2 bytes	PM Enable
+#define	PMCNTRL_PORT		0xf84	// 2 bytes	PM Control
+
+#define PM_SUSPEND_ENABLE	0x2000	// start sequence to suspend state
+
+/*
+ * PMSTS and PMEN I/O bit definitions.
+ * (Bits are the same in both registers)
+ */
+#define PM_STS_RSM		(1<<15)	// Resume Status
+#define PM_STS_PWRBTNOR		(1<<11)	// Power Button Override
+#define PM_STS_RTC		(1<<10)	// RTC status
+#define PM_STS_PWRBTN		(1<<8)	// Power Button Pressed?
+#define PM_STS_GBL		(1<<5)	// Global Status
+#define PM_STS_BM		(1<<4)	// Bus Master Status
+#define PM_STS_TMROF		(1<<0)	// Timer Overflow Status.
+
+/*
+ * Stop clock GPI register
+ */
+#define PIIX_GPIREG0			(0xf80 + 0x30)
+
+/*
+ * Stop clock GPI bit in GPIREG0
+ */
+#define	PIIX_GPI_STPCLK		0x4	// STPCLK signal routed back in
+
+#endif
diff -Naur linux.2210/include/asm-i386/sgi-vwdbe.h linux.2210.vw/include/asm-i386/sgi-vwdbe.h
--- linux.2210/include/asm-i386/sgi-vwdbe.h	Wed Dec 31 16:00:00 1969
+++ linux.2210.vw/include/asm-i386/sgi-vwdbe.h	Wed Jul 28 08:56:42 1999
@@ -0,0 +1,305 @@
+/*
+ *  linux/asm-i386/sgi-vwdbe.h -- SGI DBE frame buffer device header
+ *
+ *      Copyright (C) 1999 Silicon Graphics, Inc.
+ *      Jeffrey Newquist, newquist@engr.sgi.com
+ *
+ *  This file is subject to the terms and conditions of the GNU General Public
+ *  License. See the file COPYING in the main directory of this archive for
+ *  more details.
+ */
+
+#ifndef __SGI_VWDBE_H__
+#define __SGI_VWDBE_H__
+
+#define DBE_GETREG(reg, dest)       ((dest) = DBE_REG_BASE->##reg)
+#define DBE_SETREG(reg, src)        DBE_REG_BASE->##reg = (src)
+#define DBE_IGETREG(reg, idx, dest) ((dest) = DBE_REG_BASE->##reg##[idx])
+#define DBE_ISETREG(reg, idx, src)  (DBE_REG_BASE->##reg##[idx] = (src))
+
+#define MASK(msb, lsb)          ( (((u32)1<<((msb)-(lsb)+1))-1) << (lsb) )
+#define GET(v, msb, lsb)        ( ((u32)(v) & MASK(msb,lsb)) >> (lsb) )
+#define SET(v, f, msb, lsb)     ( (v) = ((v)&~MASK(msb,lsb)) | (( (u32)(f)<<(lsb) ) & MASK(msb,lsb)) )
+
+#define GET_DBE_FIELD(reg, field, v)        GET((v), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
+#define SET_DBE_FIELD(reg, field, v, f)     SET((v), (f), DBE_##reg##_##field##_MSB, DBE_##reg##_##field##_LSB)
+
+/* NOTE: All loads/stores must be 32 bits and uncached */
+
+#define DBE_REG_PHYS    0xd0000000
+#define DBE_REG_SIZE        0x01000000
+
+typedef struct {
+  volatile u32 ctrlstat;     /* 0x000000 general control */
+  volatile u32 dotclock;     /* 0x000004 dot clock PLL control */
+  volatile u32 i2c;          /* 0x000008 crt I2C control */
+  volatile u32 sysclk;       /* 0x00000c system clock PLL control */
+  volatile u32 i2cfp;        /* 0x000010 flat panel I2C control */
+  volatile u32 id;           /* 0x000014 device id/chip revision */
+  volatile u32 config;       /* 0x000018 power on configuration */
+  volatile u32 bist;         /* 0x00001c internal bist status */
+
+  char _pad0[ 0x010000 - 0x000020 ];
+
+  volatile u32 vt_xy;        /* 0x010000 current dot coords */
+  volatile u32 vt_xymax;     /* 0x010004 maximum dot coords */
+  volatile u32 vt_vsync;     /* 0x010008 vsync on/off */
+  volatile u32 vt_hsync;     /* 0x01000c hsync on/off */
+  volatile u32 vt_vblank;    /* 0x010010 vblank on/off */
+  volatile u32 vt_hblank;    /* 0x010014 hblank on/off */
+  volatile u32 vt_flags;     /* 0x010018 polarity of vt signals */
+  volatile u32 vt_f2rf_lock; /* 0x01001c f2rf & framelck y coord */
+  volatile u32 vt_intr01;    /* 0x010020 intr 0,1 y coords */
+  volatile u32 vt_intr23;    /* 0x010024 intr 2,3 y coords */
+  volatile u32 fp_hdrv;      /* 0x010028 flat panel hdrv on/off */
+  volatile u32 fp_vdrv;      /* 0x01002c flat panel vdrv on/off */
+  volatile u32 fp_de;        /* 0x010030 flat panel de on/off */
+  volatile u32 vt_hpixen;    /* 0x010034 intrnl horiz pixel on/off*/
+  volatile u32 vt_vpixen;    /* 0x010038 intrnl vert pixel on/off */
+  volatile u32 vt_hcmap;     /* 0x01003c cmap write (horiz) */
+  volatile u32 vt_vcmap;     /* 0x010040 cmap write (vert) */
+  volatile u32 did_start_xy; /* 0x010044 eol/f did/xy reset val */
+  volatile u32 crs_start_xy; /* 0x010048 eol/f crs/xy reset val */
+  volatile u32 vc_start_xy;  /* 0x01004c eol/f vc/xy reset val */
+
+  char _pad1[ 0x020000 - 0x010050 ];
+
+  volatile u32 ovr_width_tile; /* 0x020000 overlay plane ctrl 0 */
+  volatile u32 ovr_inhwctrl;   /* 0x020004 overlay plane ctrl 1 */
+  volatile u32 ovr_control;    /* 0x020008 overlay plane ctrl 1 */
+
+  char _pad2[ 0x030000 - 0x02000C ];
+
+  volatile u32 frm_size_tile;  /* 0x030000 normal plane ctrl 0 */
+  volatile u32 frm_size_pixel; /* 0x030004 normal plane ctrl 1 */
+  volatile u32 frm_inhwctrl;   /* 0x030008 normal plane ctrl 2 */
+  volatile u32 frm_control;        /* 0x03000C normal plane ctrl 3 */
+
+  char _pad3[ 0x040000 - 0x030010 ];
+
+  volatile u32 did_inhwctrl;   /* 0x040000 DID control */
+  volatile u32 did_control;    /* 0x040004 DID shadow */
+
+  char _pad4[ 0x048000 - 0x040008 ];
+
+  volatile u32 mode_regs[32];  /* 0x048000 - 0x04807c WID table */
+
+  char _pad5[ 0x050000 - 0x048080 ];
+
+  volatile u32 cmap[6144];     /* 0x050000 - 0x055ffc color map */
+
+  char _pad6[ 0x058000 - 0x056000 ];
+
+  volatile u32 cm_fifo;        /* 0x058000 color map fifo status */
+
+  char _pad7[ 0x060000 - 0x058004 ];
+
+  volatile u32 gmap[256];      /* 0x060000 - 0x0603fc gamma map */
+
+  char _pad8[ 0x068000 - 0x060400 ];
+
+  volatile u32 gmap10[1024];   /* 0x068000 - 0x068ffc gamma map */
+
+  char _pad9[ 0x070000 - 0x069000 ];
+
+  volatile u32 crs_pos;        /* 0x070000 cusror control 0 */
+  volatile u32 crs_ctl;        /* 0x070004 cusror control 1 */
+  volatile u32 crs_cmap[3];    /* 0x070008 - 0x070010 crs cmap */
+
+  char _pad10[ 0x078000 - 0x070014 ];
+
+  volatile u32 crs_glyph[64];  /* 0x078000 - 0x0780fc crs glyph */
+
+  char _pad11[ 0x080000 - 0x078100 ];
+
+  volatile u32 vc_0;           /* 0x080000 video capture crtl 0 */
+  volatile u32 vc_1;           /* 0x080004 video capture crtl 1 */
+  volatile u32 vc_2;           /* 0x080008 video capture crtl 2 */
+  volatile u32 vc_3;           /* 0x08000c video capture crtl 3 */
+  volatile u32 vc_4;           /* 0x080010 video capture crtl 3 */
+  volatile u32 vc_5;           /* 0x080014 video capture crtl 3 */
+  volatile u32 vc_6;           /* 0x080018 video capture crtl 3 */
+  volatile u32 vc_7;           /* 0x08001c video capture crtl 3 */
+  volatile u32 vc_8;           /* 0x08000c video capture crtl 3 */
+} asregs;
+
+/* Bit mask information */
+
+#define DBE_CTRLSTAT_CHIPID_MSB     3
+#define DBE_CTRLSTAT_CHIPID_LSB     0
+#define DBE_CTRLSTAT_SENSE_N_MSB    4
+#define DBE_CTRLSTAT_SENSE_N_LSB    4
+#define DBE_CTRLSTAT_PCLKSEL_MSB    29
+#define DBE_CTRLSTAT_PCLKSEL_LSB    28
+
+#define DBE_DOTCLK_M_MSB            7
+#define DBE_DOTCLK_M_LSB            0
+#define DBE_DOTCLK_N_MSB            13
+#define DBE_DOTCLK_N_LSB            8
+#define DBE_DOTCLK_P_MSB            15
+#define DBE_DOTCLK_P_LSB            14
+#define DBE_DOTCLK_RUN_MSB          20
+#define DBE_DOTCLK_RUN_LSB          20
+
+#define DBE_VT_XY_VT_FREEZE_MSB     31
+#define DBE_VT_XY_VT_FREEZE_LSB     31
+
+#define DBE_FP_VDRV_FP_VDRV_ON_MSB        23
+#define DBE_FP_VDRV_FP_VDRV_ON_LSB        12
+#define DBE_FP_VDRV_FP_VDRV_OFF_MSB       11
+#define DBE_FP_VDRV_FP_VDRV_OFF_LSB       0
+
+#define DBE_FP_HDRV_FP_HDRV_ON_MSB        23
+#define DBE_FP_HDRV_FP_HDRV_ON_LSB        12
+#define DBE_FP_HDRV_FP_HDRV_OFF_MSB       11
+#define DBE_FP_HDRV_FP_HDRV_OFF_LSB       0
+
+#define DBE_FP_DE_FP_DE_ON_MSB        23
+#define DBE_FP_DE_FP_DE_ON_LSB        12
+#define DBE_FP_DE_FP_DE_OFF_MSB       11
+#define DBE_FP_DE_FP_DE_OFF_LSB       0
+
+#define DBE_VT_VSYNC_VT_VSYNC_ON_MSB        23
+#define DBE_VT_VSYNC_VT_VSYNC_ON_LSB        12
+#define DBE_VT_VSYNC_VT_VSYNC_OFF_MSB       11
+#define DBE_VT_VSYNC_VT_VSYNC_OFF_LSB       0
+
+#define DBE_VT_HSYNC_VT_HSYNC_ON_MSB        23
+#define DBE_VT_HSYNC_VT_HSYNC_ON_LSB        12
+#define DBE_VT_HSYNC_VT_HSYNC_OFF_MSB       11
+#define DBE_VT_HSYNC_VT_HSYNC_OFF_LSB       0
+
+#define DBE_VT_VBLANK_VT_VBLANK_ON_MSB        23
+#define DBE_VT_VBLANK_VT_VBLANK_ON_LSB        12
+#define DBE_VT_VBLANK_VT_VBLANK_OFF_MSB       11
+#define DBE_VT_VBLANK_VT_VBLANK_OFF_LSB       0
+
+#define DBE_VT_HBLANK_VT_HBLANK_ON_MSB        23
+#define DBE_VT_HBLANK_VT_HBLANK_ON_LSB        12
+#define DBE_VT_HBLANK_VT_HBLANK_OFF_MSB       11
+#define DBE_VT_HBLANK_VT_HBLANK_OFF_LSB       0
+
+#define DBE_VT_FLAGS_VDRV_INVERT_MSB  0
+#define DBE_VT_FLAGS_VDRV_INVERT_LSB  0
+#define DBE_VT_FLAGS_HDRV_INVERT_MSB  2
+#define DBE_VT_FLAGS_HDRV_INVERT_LSB  2
+
+#define DBE_VT_VCMAP_VT_VCMAP_ON_MSB        23
+#define DBE_VT_VCMAP_VT_VCMAP_ON_LSB        12
+#define DBE_VT_VCMAP_VT_VCMAP_OFF_MSB       11
+#define DBE_VT_VCMAP_VT_VCMAP_OFF_LSB       0
+
+#define DBE_VT_HCMAP_VT_HCMAP_ON_MSB        23
+#define DBE_VT_HCMAP_VT_HCMAP_ON_LSB        12
+#define DBE_VT_HCMAP_VT_HCMAP_OFF_MSB       11
+#define DBE_VT_HCMAP_VT_HCMAP_OFF_LSB       0
+
+#define DBE_VT_XYMAX_VT_MAXX_MSB    11
+#define DBE_VT_XYMAX_VT_MAXX_LSB    0
+#define DBE_VT_XYMAX_VT_MAXY_MSB    23
+#define DBE_VT_XYMAX_VT_MAXY_LSB    12
+
+#define DBE_VT_HPIXEN_VT_HPIXEN_ON_MSB      23
+#define DBE_VT_HPIXEN_VT_HPIXEN_ON_LSB      12
+#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_MSB     11
+#define DBE_VT_HPIXEN_VT_HPIXEN_OFF_LSB     0
+
+#define DBE_VT_VPIXEN_VT_VPIXEN_ON_MSB      23
+#define DBE_VT_VPIXEN_VT_VPIXEN_ON_LSB      12
+#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_MSB     11
+#define DBE_VT_VPIXEN_VT_VPIXEN_OFF_LSB     0
+
+#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_MSB  0
+#define DBE_OVR_CONTROL_OVR_DMA_ENABLE_LSB  0
+
+#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_MSB 0
+#define DBE_OVR_INHWCTRL_OVR_DMA_ENABLE_LSB 0
+
+#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_MSB       13
+#define DBE_OVR_WIDTH_TILE_OVR_FIFO_RESET_LSB       13
+
+#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_MSB  0
+#define DBE_FRM_CONTROL_FRM_DMA_ENABLE_LSB  0
+#define DBE_FRM_CONTROL_FRM_TILE_PTR_MSB    31
+#define DBE_FRM_CONTROL_FRM_TILE_PTR_LSB    9
+#define DBE_FRM_CONTROL_FRM_LINEAR_MSB      1
+#define DBE_FRM_CONTROL_FRM_LINEAR_LSB      1
+
+#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_MSB 0
+#define DBE_FRM_INHWCTRL_FRM_DMA_ENABLE_LSB 0
+
+#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_MSB        12
+#define DBE_FRM_SIZE_TILE_FRM_WIDTH_TILE_LSB        5
+#define DBE_FRM_SIZE_TILE_FRM_RHS_MSB       4
+#define DBE_FRM_SIZE_TILE_FRM_RHS_LSB       0
+#define DBE_FRM_SIZE_TILE_FRM_DEPTH_MSB     14
+#define DBE_FRM_SIZE_TILE_FRM_DEPTH_LSB     13
+#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_MSB        15
+#define DBE_FRM_SIZE_TILE_FRM_FIFO_RESET_LSB        15
+
+#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_MSB        31
+#define DBE_FRM_SIZE_PIXEL_FB_HEIGHT_PIX_LSB        16
+
+#define DBE_DID_CONTROL_DID_DMA_ENABLE_MSB  0
+#define DBE_DID_CONTROL_DID_DMA_ENABLE_LSB  0
+#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_MSB 0
+#define DBE_DID_INHWCTRL_DID_DMA_ENABLE_LSB 0
+
+#define DBE_DID_START_XY_DID_STARTY_MSB     23
+#define DBE_DID_START_XY_DID_STARTY_LSB     12
+#define DBE_DID_START_XY_DID_STARTX_MSB     11
+#define DBE_DID_START_XY_DID_STARTX_LSB     0
+
+#define DBE_CRS_START_XY_CRS_STARTY_MSB     23
+#define DBE_CRS_START_XY_CRS_STARTY_LSB     12
+#define DBE_CRS_START_XY_CRS_STARTX_MSB     11
+#define DBE_CRS_START_XY_CRS_STARTX_LSB     0
+
+#define DBE_WID_TYP_MSB     4
+#define DBE_WID_TYP_LSB     2
+#define DBE_WID_BUF_MSB     1
+#define DBE_WID_BUF_LSB     0
+
+#define DBE_VC_START_XY_VC_STARTY_MSB       23
+#define DBE_VC_START_XY_VC_STARTY_LSB       12
+#define DBE_VC_START_XY_VC_STARTX_MSB       11
+#define DBE_VC_START_XY_VC_STARTX_LSB       0
+
+/* Constants */
+
+#define DBE_FRM_DEPTH_8     0
+#define DBE_FRM_DEPTH_16    1
+#define DBE_FRM_DEPTH_32    2
+
+#define DBE_CMODE_I8        0
+#define DBE_CMODE_I12       1
+#define DBE_CMODE_RG3B2     2
+#define DBE_CMODE_RGB4      3
+#define DBE_CMODE_ARGB5     4
+#define DBE_CMODE_RGB8      5
+#define DBE_CMODE_RGBA5     6
+#define DBE_CMODE_RGB10     7
+
+#define DBE_BMODE_BOTH      3
+
+#define DBE_CRS_MAGIC       54
+
+#define DBE_CLOCK_REF_KHZ 27000
+
+/* Config Register (DBE Only) Definitions */
+
+#define DBE_CONFIG_VDAC_ENABLE       0x00000001
+#define DBE_CONFIG_VDAC_GSYNC        0x00000002
+#define DBE_CONFIG_VDAC_PBLANK       0x00000004
+#define DBE_CONFIG_FPENABLE          0x00000008
+#define DBE_CONFIG_LENDIAN           0x00000020
+#define DBE_CONFIG_TILEHIST          0x00000040
+#define DBE_CONFIG_EXT_ADDR          0x00000080
+
+#define DBE_CONFIG_FBDEV        ( DBE_CONFIG_VDAC_ENABLE | \
+                                      DBE_CONFIG_VDAC_GSYNC  | \
+                                      DBE_CONFIG_VDAC_PBLANK | \
+                                      DBE_CONFIG_LENDIAN     | \
+                                      DBE_CONFIG_EXT_ADDR )
+
+#endif
diff -Naur linux.2210/include/linux/i2c.h linux.2210.vw/include/linux/i2c.h
--- linux.2210/include/linux/i2c.h	Fri Jan 15 14:36:21 1999
+++ linux.2210.vw/include/linux/i2c.h	Wed Jul 28 08:56:42 1999
@@ -35,6 +35,7 @@
 #define I2C_DRIVERID_VIDEOTEXT	 3
 
 #define I2C_BUSID_BT848		1	/* I2C bus on a BT848 */
+#define I2C_BUSID_SGIVWFB	1	/* I2C bus on a SGI Visual Workstation */
 
 /*
  * struct for a driver for a i2c chip (tuner, soundprocessor,
diff -Naur linux.2210/init/main.c linux.2210.vw/init/main.c
--- linux.2210/init/main.c	Tue May 11 09:57:14 1999
+++ linux.2210.vw/init/main.c	Wed Jul 28 08:56:42 1999
@@ -502,6 +502,7 @@
 	{ NULL, 0 }
 };
 
+
 kdev_t __init name_to_kdev_t(char *line)
 {
 	int base = 0;
@@ -520,6 +521,7 @@
 	}
 	return to_kdev_t(base + simple_strtoul(line,NULL,base?10:16));
 }
+
 
 static void __init root_dev_setup(char *line, int *num)
 {
diff -Naur linux.2210/kernel/ksyms.c linux.2210.vw/kernel/ksyms.c
--- linux.2210/kernel/ksyms.c	Thu Apr 29 15:06:32 1999
+++ linux.2210.vw/kernel/ksyms.c	Wed Jul 28 08:56:42 1999
@@ -108,6 +108,7 @@
 EXPORT_SYMBOL(vmtruncate);
 EXPORT_SYMBOL(find_vma);
 EXPORT_SYMBOL(get_unmapped_area);
+EXPORT_SYMBOL(zap_page_range);
 
 /* filesystem internal functions */
 EXPORT_SYMBOL(in_group_p);